@famgia/omnify-typescript 0.0.64 → 0.0.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -951,11 +951,460 @@ function generateRulesFiles(schemas, options = {}) {
951
951
  return files;
952
952
  }
953
953
 
954
+ // src/zod-generator.ts
955
+ function getMultiLocaleDisplayName2(value, locales, fallbackLocale, defaultValue) {
956
+ if (!value) {
957
+ const result2 = {};
958
+ for (const locale of locales) {
959
+ result2[locale] = defaultValue;
960
+ }
961
+ return result2;
962
+ }
963
+ if (typeof value === "string") {
964
+ const result2 = {};
965
+ for (const locale of locales) {
966
+ result2[locale] = value;
967
+ }
968
+ return result2;
969
+ }
970
+ const result = {};
971
+ for (const locale of locales) {
972
+ result[locale] = value[locale] ?? value[fallbackLocale] ?? value["en"] ?? defaultValue;
973
+ }
974
+ return result;
975
+ }
976
+ function getZodSchemaForType(propDef, fieldName, customTypes) {
977
+ const def = propDef;
978
+ const isNullable = def.nullable ?? false;
979
+ let schema = "";
980
+ if (customTypes) {
981
+ const customType = customTypes.get(propDef.type);
982
+ if (customType && !customType.compound) {
983
+ const sqlType = customType.sql?.sqlType || "VARCHAR";
984
+ schema = "z.string()";
985
+ if (customType.sql?.length) {
986
+ schema += `.max(${customType.sql.length})`;
987
+ }
988
+ if (isNullable) {
989
+ schema += ".optional().nullable()";
990
+ }
991
+ return schema;
992
+ }
993
+ }
994
+ switch (propDef.type) {
995
+ case "String":
996
+ case "Text":
997
+ case "MediumText":
998
+ case "LongText":
999
+ case "Password":
1000
+ schema = "z.string()";
1001
+ if (!isNullable) {
1002
+ schema += ".min(1)";
1003
+ }
1004
+ if (def.maxLength || def.length) {
1005
+ schema += `.max(${def.maxLength ?? def.length})`;
1006
+ }
1007
+ if (def.minLength && def.minLength > 1) {
1008
+ schema = schema.replace(".min(1)", `.min(${def.minLength})`);
1009
+ }
1010
+ break;
1011
+ case "Email":
1012
+ schema = "z.string().email()";
1013
+ if (def.maxLength || def.length) {
1014
+ schema += `.max(${def.maxLength ?? def.length ?? 255})`;
1015
+ }
1016
+ break;
1017
+ case "TinyInt":
1018
+ case "Int":
1019
+ case "BigInt":
1020
+ schema = "z.number().int()";
1021
+ if (def.min !== void 0) {
1022
+ schema += `.gte(${def.min})`;
1023
+ }
1024
+ if (def.max !== void 0) {
1025
+ schema += `.lte(${def.max})`;
1026
+ }
1027
+ break;
1028
+ case "Float":
1029
+ schema = "z.number()";
1030
+ if (def.min !== void 0) {
1031
+ schema += `.gte(${def.min})`;
1032
+ }
1033
+ if (def.max !== void 0) {
1034
+ schema += `.lte(${def.max})`;
1035
+ }
1036
+ break;
1037
+ case "Boolean":
1038
+ schema = "z.boolean()";
1039
+ break;
1040
+ case "Date":
1041
+ schema = "z.string().date()";
1042
+ break;
1043
+ case "DateTime":
1044
+ case "Timestamp":
1045
+ schema = "z.string().datetime({ offset: true })";
1046
+ break;
1047
+ case "Time":
1048
+ schema = "z.string().time()";
1049
+ break;
1050
+ case "Json":
1051
+ schema = "z.unknown()";
1052
+ break;
1053
+ case "Enum":
1054
+ if (typeof def.enum === "string") {
1055
+ schema = `${def.enum}Schema`;
1056
+ } else if (Array.isArray(def.enum)) {
1057
+ const values = def.enum.map((v) => `'${v}'`).join(", ");
1058
+ schema = `z.enum([${values}])`;
1059
+ } else {
1060
+ schema = "z.string()";
1061
+ }
1062
+ break;
1063
+ case "Select":
1064
+ if (def.options && def.options.length > 0) {
1065
+ const values = def.options.map((v) => `'${v}'`).join(", ");
1066
+ schema = `z.enum([${values}])`;
1067
+ } else {
1068
+ schema = "z.string()";
1069
+ }
1070
+ break;
1071
+ case "Lookup":
1072
+ schema = "z.number().int().positive()";
1073
+ break;
1074
+ case "Association":
1075
+ return "";
1076
+ case "File":
1077
+ return "";
1078
+ default:
1079
+ schema = "z.string()";
1080
+ }
1081
+ if (isNullable && schema) {
1082
+ schema += ".optional().nullable()";
1083
+ }
1084
+ if (def.pattern && schema) {
1085
+ schema += `.regex(/${def.pattern}/)`;
1086
+ }
1087
+ return schema;
1088
+ }
1089
+ function generateCompoundTypeSchemas(propName, propDef, customType, options) {
1090
+ const schemas = [];
1091
+ const propFields = propDef.fields;
1092
+ const locales = options.localeConfig?.locales ?? ["en"];
1093
+ const fallbackLocale = options.localeConfig?.fallbackLocale ?? "en";
1094
+ if (!customType.expand) return schemas;
1095
+ for (const field of customType.expand) {
1096
+ const fieldName = `${toSnakeCase(propName)}_${toSnakeCase(field.suffix)}`;
1097
+ const fieldOverride = propFields?.[field.suffix];
1098
+ const isNullable = fieldOverride?.nullable ?? propDef.nullable ?? false;
1099
+ const length = fieldOverride?.length ?? field.sql?.length;
1100
+ let schema = "z.string()";
1101
+ if (!isNullable) {
1102
+ schema += ".min(1)";
1103
+ }
1104
+ if (length) {
1105
+ schema += `.max(${length})`;
1106
+ }
1107
+ if (isNullable) {
1108
+ schema += ".optional().nullable()";
1109
+ }
1110
+ const propDisplayName = getMultiLocaleDisplayName2(
1111
+ propDef.displayName,
1112
+ locales,
1113
+ fallbackLocale,
1114
+ propName
1115
+ );
1116
+ schemas.push({
1117
+ fieldName,
1118
+ schema,
1119
+ inCreate: true,
1120
+ inUpdate: true,
1121
+ comment: `${propDisplayName["en"] ?? propName} (${field.suffix})`
1122
+ });
1123
+ }
1124
+ return schemas;
1125
+ }
1126
+ function generateZodSchemas(schema, options) {
1127
+ const schemas = [];
1128
+ const customTypes = options.customTypes;
1129
+ if (!schema.properties) return schemas;
1130
+ for (const [propName, propDef] of Object.entries(schema.properties)) {
1131
+ if (customTypes) {
1132
+ const customType = customTypes.get(propDef.type);
1133
+ if (customType?.compound) {
1134
+ schemas.push(...generateCompoundTypeSchemas(propName, propDef, customType, options));
1135
+ continue;
1136
+ }
1137
+ }
1138
+ const zodSchema = getZodSchemaForType(propDef, propName, customTypes);
1139
+ if (!zodSchema) continue;
1140
+ const fieldName = toSnakeCase(propName);
1141
+ schemas.push({
1142
+ fieldName,
1143
+ schema: zodSchema,
1144
+ inCreate: true,
1145
+ inUpdate: true,
1146
+ comment: void 0
1147
+ });
1148
+ }
1149
+ return schemas;
1150
+ }
1151
+ function generateDisplayNames(schema, options) {
1152
+ const locales = options.localeConfig?.locales ?? ["en"];
1153
+ const fallbackLocale = options.localeConfig?.fallbackLocale ?? "en";
1154
+ const customTypes = options.customTypes;
1155
+ const displayName = getMultiLocaleDisplayName2(
1156
+ schema.displayName,
1157
+ locales,
1158
+ fallbackLocale,
1159
+ schema.name
1160
+ );
1161
+ const propertyDisplayNames = {};
1162
+ if (schema.properties) {
1163
+ for (const [propName, propDef] of Object.entries(schema.properties)) {
1164
+ const prop = propDef;
1165
+ const fieldName = toSnakeCase(propName);
1166
+ if (customTypes) {
1167
+ const customType = customTypes.get(propDef.type);
1168
+ if (customType?.compound && customType.expand) {
1169
+ for (const field of customType.expand) {
1170
+ const expandedFieldName = `${fieldName}_${toSnakeCase(field.suffix)}`;
1171
+ propertyDisplayNames[expandedFieldName] = getMultiLocaleDisplayName2(
1172
+ prop.displayName,
1173
+ locales,
1174
+ fallbackLocale,
1175
+ propName
1176
+ );
1177
+ for (const locale of locales) {
1178
+ propertyDisplayNames[expandedFieldName] = {
1179
+ ...propertyDisplayNames[expandedFieldName],
1180
+ [locale]: `${propertyDisplayNames[expandedFieldName][locale]} (${field.suffix})`
1181
+ };
1182
+ }
1183
+ }
1184
+ continue;
1185
+ }
1186
+ }
1187
+ propertyDisplayNames[fieldName] = getMultiLocaleDisplayName2(
1188
+ prop.displayName,
1189
+ locales,
1190
+ fallbackLocale,
1191
+ propName
1192
+ );
1193
+ }
1194
+ }
1195
+ return { displayName, propertyDisplayNames };
1196
+ }
1197
+ function getExcludedFields(schema, customTypes) {
1198
+ const createExclude = /* @__PURE__ */ new Set();
1199
+ const updateExclude = /* @__PURE__ */ new Set();
1200
+ if (schema.options?.id !== false) {
1201
+ createExclude.add("id");
1202
+ updateExclude.add("id");
1203
+ }
1204
+ if (schema.options?.timestamps !== false) {
1205
+ createExclude.add("created_at");
1206
+ createExclude.add("updated_at");
1207
+ updateExclude.add("created_at");
1208
+ updateExclude.add("updated_at");
1209
+ }
1210
+ if (schema.options?.softDelete) {
1211
+ createExclude.add("deleted_at");
1212
+ updateExclude.add("deleted_at");
1213
+ }
1214
+ if (schema.properties) {
1215
+ if (schema.properties["emailVerifiedAt"] || schema.properties["email_verified_at"]) {
1216
+ createExclude.add("email_verified_at");
1217
+ updateExclude.add("email_verified_at");
1218
+ }
1219
+ }
1220
+ if (schema.properties && customTypes) {
1221
+ for (const [propName, propDef] of Object.entries(schema.properties)) {
1222
+ const customType = customTypes.get(propDef.type);
1223
+ if (customType?.accessors) {
1224
+ for (const accessor of customType.accessors) {
1225
+ const fieldName = `${toSnakeCase(propName)}_${toSnakeCase(accessor.name)}`;
1226
+ createExclude.add(fieldName);
1227
+ updateExclude.add(fieldName);
1228
+ }
1229
+ }
1230
+ }
1231
+ }
1232
+ return { create: createExclude, update: updateExclude };
1233
+ }
1234
+ function formatZodSchemasSection(schemaName, zodSchemas, displayNames, excludedFields) {
1235
+ const parts = [];
1236
+ const lowerName = schemaName.charAt(0).toLowerCase() + schemaName.slice(1);
1237
+ parts.push(`// ============================================================================
1238
+ `);
1239
+ parts.push(`// Display Names
1240
+ `);
1241
+ parts.push(`// ============================================================================
1242
+
1243
+ `);
1244
+ parts.push(`/** Display name for ${schemaName} */
1245
+ `);
1246
+ parts.push(`export const ${schemaName}DisplayName = ${JSON.stringify(displayNames.displayName, null, 2)} as const;
1247
+
1248
+ `);
1249
+ parts.push(`/** Property display names for ${schemaName} */
1250
+ `);
1251
+ parts.push(`export const ${schemaName}PropertyDisplayNames = {
1252
+ `);
1253
+ for (const [propName, localeMap] of Object.entries(displayNames.propertyDisplayNames)) {
1254
+ parts.push(` ${propName}: ${JSON.stringify(localeMap)},
1255
+ `);
1256
+ }
1257
+ parts.push(`} as const;
1258
+
1259
+ `);
1260
+ parts.push(`// ============================================================================
1261
+ `);
1262
+ parts.push(`// Zod Schemas
1263
+ `);
1264
+ parts.push(`// ============================================================================
1265
+
1266
+ `);
1267
+ parts.push(`/** Field schemas for ${schemaName} */
1268
+ `);
1269
+ parts.push(`export const base${schemaName}Schemas = {
1270
+ `);
1271
+ for (const prop of zodSchemas) {
1272
+ if (prop.comment) {
1273
+ parts.push(` /** ${prop.comment} */
1274
+ `);
1275
+ }
1276
+ parts.push(` ${prop.fieldName}: ${prop.schema},
1277
+ `);
1278
+ }
1279
+ parts.push(`} as const;
1280
+
1281
+ `);
1282
+ const createFields = zodSchemas.filter((p) => p.inCreate && !excludedFields.create.has(p.fieldName));
1283
+ parts.push(`/** Create schema for ${schemaName} (POST requests) */
1284
+ `);
1285
+ parts.push(`export const base${schemaName}CreateSchema = z.object({
1286
+ `);
1287
+ for (const prop of createFields) {
1288
+ parts.push(` ${prop.fieldName}: base${schemaName}Schemas.${prop.fieldName},
1289
+ `);
1290
+ }
1291
+ parts.push(`});
1292
+
1293
+ `);
1294
+ parts.push(`/** Update schema for ${schemaName} (PUT/PATCH requests) */
1295
+ `);
1296
+ parts.push(`export const base${schemaName}UpdateSchema = base${schemaName}CreateSchema.partial();
1297
+
1298
+ `);
1299
+ parts.push(`// ============================================================================
1300
+ `);
1301
+ parts.push(`// Inferred Types
1302
+ `);
1303
+ parts.push(`// ============================================================================
1304
+
1305
+ `);
1306
+ parts.push(`export type Base${schemaName}Create = z.infer<typeof base${schemaName}CreateSchema>;
1307
+ `);
1308
+ parts.push(`export type Base${schemaName}Update = z.infer<typeof base${schemaName}UpdateSchema>;
1309
+
1310
+ `);
1311
+ parts.push(`// ============================================================================
1312
+ `);
1313
+ parts.push(`// Helper Functions
1314
+ `);
1315
+ parts.push(`// ============================================================================
1316
+
1317
+ `);
1318
+ parts.push(`/** Get display name for a specific locale */
1319
+ `);
1320
+ parts.push(`export function get${schemaName}DisplayName(locale: string): string {
1321
+ `);
1322
+ parts.push(` return ${schemaName}DisplayName[locale as keyof typeof ${schemaName}DisplayName] ?? ${schemaName}DisplayName['en'] ?? '${schemaName}';
1323
+ `);
1324
+ parts.push(`}
1325
+
1326
+ `);
1327
+ parts.push(`/** Get property display name for a specific locale */
1328
+ `);
1329
+ parts.push(`export function get${schemaName}PropertyDisplayName(property: string, locale: string): string {
1330
+ `);
1331
+ parts.push(` const names = ${schemaName}PropertyDisplayNames[property as keyof typeof ${schemaName}PropertyDisplayNames];
1332
+ `);
1333
+ parts.push(` if (!names) return property;
1334
+ `);
1335
+ parts.push(` return names[locale as keyof typeof names] ?? names['en'] ?? property;
1336
+ `);
1337
+ parts.push(`}
1338
+ `);
1339
+ return parts.join("");
1340
+ }
1341
+ function formatZodModelFile(schemaName) {
1342
+ const lowerName = schemaName.charAt(0).toLowerCase() + schemaName.slice(1);
1343
+ return `/**
1344
+ * ${schemaName} Model
1345
+ *
1346
+ * This file extends the auto-generated base interface.
1347
+ * You can add custom methods, computed properties, or override types/schemas here.
1348
+ * This file will NOT be overwritten by the generator.
1349
+ */
1350
+
1351
+ import { z } from 'zod';
1352
+ import type { ${schemaName} as ${schemaName}Base } from './base/${schemaName}.js';
1353
+ import {
1354
+ base${schemaName}Schemas,
1355
+ base${schemaName}CreateSchema,
1356
+ base${schemaName}UpdateSchema,
1357
+ ${schemaName}DisplayName,
1358
+ ${schemaName}PropertyDisplayNames,
1359
+ get${schemaName}DisplayName,
1360
+ get${schemaName}PropertyDisplayName,
1361
+ } from './base/${schemaName}.js';
1362
+
1363
+ // ============================================================================
1364
+ // Types (extend or re-export)
1365
+ // ============================================================================
1366
+
1367
+ export interface ${schemaName} extends ${schemaName}Base {
1368
+ // Add custom properties here
1369
+ }
1370
+
1371
+ // ============================================================================
1372
+ // Schemas (extend or re-export)
1373
+ // ============================================================================
1374
+
1375
+ export const ${lowerName}Schemas = { ...base${schemaName}Schemas };
1376
+ export const ${lowerName}CreateSchema = base${schemaName}CreateSchema;
1377
+ export const ${lowerName}UpdateSchema = base${schemaName}UpdateSchema;
1378
+
1379
+ // ============================================================================
1380
+ // Types
1381
+ // ============================================================================
1382
+
1383
+ export type ${schemaName}Create = z.infer<typeof ${lowerName}CreateSchema>;
1384
+ export type ${schemaName}Update = z.infer<typeof ${lowerName}UpdateSchema>;
1385
+
1386
+ // Re-export display names and helpers
1387
+ export {
1388
+ ${schemaName}DisplayName,
1389
+ ${schemaName}PropertyDisplayNames,
1390
+ get${schemaName}DisplayName,
1391
+ get${schemaName}PropertyDisplayName,
1392
+ };
1393
+
1394
+ // Re-export base type for internal use
1395
+ export type { ${schemaName}Base };
1396
+ `;
1397
+ }
1398
+
954
1399
  // src/generator.ts
955
1400
  var DEFAULT_OPTIONS = {
956
1401
  readonly: false,
957
1402
  // Changed: interfaces should be mutable for forms/mutations
958
- strictNullChecks: true
1403
+ strictNullChecks: true,
1404
+ generateZodSchemas: true,
1405
+ // Generate Zod schemas by default
1406
+ generateRules: false
1407
+ // Legacy Ant Design rules (deprecated, ignored when generateZodSchemas=true)
959
1408
  };
960
1409
  function generateBaseHeader() {
961
1410
  return `/**
@@ -976,7 +1425,21 @@ function generateModelHeader(schemaName) {
976
1425
 
977
1426
  `;
978
1427
  }
979
- function generateUtilityTypes(schemaName, schema) {
1428
+ function getComputedFields(schema, customTypes) {
1429
+ const computedFields = [];
1430
+ if (!schema.properties) return computedFields;
1431
+ for (const [propName, propDef] of Object.entries(schema.properties)) {
1432
+ const snakeName = toSnakeCase(propName);
1433
+ const customType = customTypes?.get(propDef.type);
1434
+ if (customType?.accessors) {
1435
+ for (const accessor of customType.accessors) {
1436
+ computedFields.push(`${snakeName}_${toSnakeCase(accessor.name)}`);
1437
+ }
1438
+ }
1439
+ }
1440
+ return computedFields;
1441
+ }
1442
+ function generateUtilityTypes(schemaName, schema, customTypes) {
980
1443
  const parts = [];
981
1444
  const excludeFields = [];
982
1445
  if (schema.options?.id !== false) {
@@ -988,6 +1451,13 @@ function generateUtilityTypes(schemaName, schema) {
988
1451
  if (schema.options?.softDelete) {
989
1452
  excludeFields.push("'deleted_at'");
990
1453
  }
1454
+ if (schema.properties?.["emailVerifiedAt"] || schema.properties?.["email_verified_at"]) {
1455
+ excludeFields.push("'email_verified_at'");
1456
+ }
1457
+ const computedFields = getComputedFields(schema, customTypes);
1458
+ for (const field of computedFields) {
1459
+ excludeFields.push(`'${field}'`);
1460
+ }
991
1461
  const omitType = excludeFields.length > 0 ? `Omit<${schemaName}, ${excludeFields.join(" | ")}>` : schemaName;
992
1462
  parts.push(`
993
1463
  /** For creating new ${schemaName} (POST requests) */`);
@@ -1022,6 +1492,10 @@ function generateBaseInterfaceFile(schemaName, schemas, options) {
1022
1492
  throw new Error(`Interface not found for schema: ${schemaName}`);
1023
1493
  }
1024
1494
  const parts = [generateBaseHeader()];
1495
+ if (options.generateZodSchemas) {
1496
+ parts.push(`import { z } from 'zod';
1497
+ `);
1498
+ }
1025
1499
  const dateImports = needsDateTimeImports(iface);
1026
1500
  const commonImports = [];
1027
1501
  if (dateImports.dateTime) commonImports.push("DateTimeString");
@@ -1036,12 +1510,20 @@ function generateBaseInterfaceFile(schemaName, schemas, options) {
1036
1510
  `);
1037
1511
  }
1038
1512
  parts.push("\n");
1039
- } else if (commonImports.length > 0) {
1513
+ } else if (commonImports.length > 0 || options.generateZodSchemas) {
1040
1514
  parts.push("\n");
1041
1515
  }
1042
1516
  parts.push(formatInterface(iface));
1043
1517
  parts.push("\n");
1044
- parts.push(generateUtilityTypes(schemaName, schema));
1518
+ if (options.generateZodSchemas) {
1519
+ const zodSchemas = generateZodSchemas(schema, options);
1520
+ const displayNames = generateDisplayNames(schema, options);
1521
+ const excludedFields = getExcludedFields(schema, options.customTypes);
1522
+ parts.push("\n");
1523
+ parts.push(formatZodSchemasSection(schemaName, zodSchemas, displayNames, excludedFields));
1524
+ } else {
1525
+ parts.push(generateUtilityTypes(schemaName, schema, options.customTypes));
1526
+ }
1045
1527
  return {
1046
1528
  filePath: `base/${schemaName}.ts`,
1047
1529
  content: parts.join(""),
@@ -1071,7 +1553,16 @@ function generateTypeAliasFile(alias) {
1071
1553
  overwrite: true
1072
1554
  };
1073
1555
  }
1074
- function generateModelFile(schemaName) {
1556
+ function generateModelFile(schemaName, options) {
1557
+ if (options.generateZodSchemas) {
1558
+ return {
1559
+ filePath: `${schemaName}.ts`,
1560
+ content: formatZodModelFile(schemaName),
1561
+ types: [schemaName],
1562
+ overwrite: false
1563
+ // Never overwrite user models
1564
+ };
1565
+ }
1075
1566
  const parts = [generateModelHeader(schemaName)];
1076
1567
  parts.push(`import type { ${schemaName} as ${schemaName}Base } from './base/${schemaName}.js';
1077
1568
 
@@ -1191,33 +1682,63 @@ function generateIndexFile(schemas, enums, typeAliases, options) {
1191
1682
  }
1192
1683
  parts.push("\n");
1193
1684
  }
1194
- parts.push(`// Models (with Create/Update utility types)
1195
- `);
1196
- for (const schema of Object.values(schemas)) {
1197
- if (schema.kind === "enum") continue;
1198
- if (schema.options?.hidden === true) continue;
1199
- parts.push(`export type { ${schema.name} } from './${schema.name}.js';
1200
- `);
1201
- parts.push(`export type { ${schema.name}Create, ${schema.name}Update } from './base/${schema.name}.js';
1202
- `);
1203
- }
1204
- if (options.generateRules) {
1205
- parts.push(`
1206
- // Validation Rules
1685
+ if (options.generateZodSchemas) {
1686
+ parts.push(`// Models (with Zod schemas and Create/Update types)
1207
1687
  `);
1208
1688
  for (const schema of Object.values(schemas)) {
1209
1689
  if (schema.kind === "enum") continue;
1210
1690
  if (schema.options?.hidden === true) continue;
1691
+ const lowerName = schema.name.charAt(0).toLowerCase() + schema.name.slice(1);
1692
+ parts.push(`export type { ${schema.name}, ${schema.name}Create, ${schema.name}Update } from './${schema.name}.js';
1693
+ `);
1211
1694
  parts.push(`export {
1212
1695
  `);
1213
- parts.push(` get${schema.name}Rules,
1696
+ parts.push(` ${lowerName}Schemas,
1697
+ `);
1698
+ parts.push(` ${lowerName}CreateSchema,
1699
+ `);
1700
+ parts.push(` ${lowerName}UpdateSchema,
1701
+ `);
1702
+ parts.push(` ${schema.name}DisplayName,
1703
+ `);
1704
+ parts.push(` ${schema.name}PropertyDisplayNames,
1214
1705
  `);
1215
1706
  parts.push(` get${schema.name}DisplayName,
1216
1707
  `);
1217
1708
  parts.push(` get${schema.name}PropertyDisplayName,
1218
1709
  `);
1219
- parts.push(`} from './rules/${schema.name}.rules.js';
1710
+ parts.push(`} from './${schema.name}.js';
1711
+ `);
1712
+ }
1713
+ } else {
1714
+ parts.push(`// Models (with Create/Update utility types)
1715
+ `);
1716
+ for (const schema of Object.values(schemas)) {
1717
+ if (schema.kind === "enum") continue;
1718
+ if (schema.options?.hidden === true) continue;
1719
+ parts.push(`export type { ${schema.name} } from './${schema.name}.js';
1720
+ `);
1721
+ parts.push(`export type { ${schema.name}Create, ${schema.name}Update } from './base/${schema.name}.js';
1722
+ `);
1723
+ }
1724
+ if (options.generateRules) {
1725
+ parts.push(`
1726
+ // Validation Rules
1220
1727
  `);
1728
+ for (const schema of Object.values(schemas)) {
1729
+ if (schema.kind === "enum") continue;
1730
+ if (schema.options?.hidden === true) continue;
1731
+ parts.push(`export {
1732
+ `);
1733
+ parts.push(` get${schema.name}Rules,
1734
+ `);
1735
+ parts.push(` get${schema.name}DisplayName,
1736
+ `);
1737
+ parts.push(` get${schema.name}PropertyDisplayName,
1738
+ `);
1739
+ parts.push(`} from './rules/${schema.name}.rules.js';
1740
+ `);
1741
+ }
1221
1742
  }
1222
1743
  }
1223
1744
  return {
@@ -1246,9 +1767,9 @@ function generateTypeScript(schemas, options = {}) {
1246
1767
  for (const schema of Object.values(schemas)) {
1247
1768
  if (schema.kind === "enum") continue;
1248
1769
  if (schema.options?.hidden === true) continue;
1249
- files.push(generateModelFile(schema.name));
1770
+ files.push(generateModelFile(schema.name, opts));
1250
1771
  }
1251
- if (opts.generateRules) {
1772
+ if (!opts.generateZodSchemas && opts.generateRules) {
1252
1773
  const rulesFiles = generateRulesFiles(schemas, opts);
1253
1774
  files.push(...rulesFiles);
1254
1775
  }