@famgia/omnify-typescript 0.0.53 → 0.0.55

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
@@ -62,10 +62,10 @@ var TYPE_MAP = {
62
62
  Text: "string",
63
63
  MediumText: "string",
64
64
  LongText: "string",
65
- Date: "string",
65
+ Date: "DateString",
66
66
  Time: "string",
67
- DateTime: "string",
68
- Timestamp: "string",
67
+ DateTime: "DateTimeString",
68
+ Timestamp: "DateTimeString",
69
69
  Json: "unknown",
70
70
  Email: "string",
71
71
  Password: "string",
@@ -272,14 +272,14 @@ function schemaToInterface(schema, allSchemas, options = {}) {
272
272
  properties.push(
273
273
  {
274
274
  name: "created_at",
275
- type: "string",
275
+ type: "DateTimeString",
276
276
  optional: true,
277
277
  readonly: options.readonly ?? true,
278
278
  comment: "Creation timestamp"
279
279
  },
280
280
  {
281
281
  name: "updated_at",
282
- type: "string",
282
+ type: "DateTimeString",
283
283
  optional: true,
284
284
  readonly: options.readonly ?? true,
285
285
  comment: "Last update timestamp"
@@ -289,7 +289,7 @@ function schemaToInterface(schema, allSchemas, options = {}) {
289
289
  if (schema.options?.softDelete) {
290
290
  properties.push({
291
291
  name: "deleted_at",
292
- type: "string",
292
+ type: "DateTimeString",
293
293
  optional: true,
294
294
  readonly: options.readonly ?? true,
295
295
  comment: "Soft delete timestamp"
@@ -850,19 +850,7 @@ function formatRulesFile(schemaName, rules) {
850
850
  * DO NOT EDIT - This file is automatically generated and will be overwritten.
851
851
  */
852
852
 
853
- `);
854
- parts.push(`export interface LocaleMap { [locale: string]: string; }
855
-
856
- `);
857
- parts.push(`export interface ValidationRule {
858
- required?: boolean;
859
- type?: 'string' | 'number' | 'email' | 'url' | 'integer';
860
- min?: number;
861
- max?: number;
862
- len?: number;
863
- pattern?: RegExp;
864
- message: LocaleMap;
865
- }
853
+ import type { LocaleMap, ValidationRule } from '../common.js';
866
854
 
867
855
  `);
868
856
  parts.push(`/** Display name for ${schemaName} */
@@ -964,7 +952,8 @@ function generateRulesFiles(schemas, options = {}) {
964
952
 
965
953
  // src/generator.ts
966
954
  var DEFAULT_OPTIONS = {
967
- readonly: true,
955
+ readonly: false,
956
+ // Changed: interfaces should be mutable for forms/mutations
968
957
  strictNullChecks: true
969
958
  };
970
959
  function generateBaseHeader() {
@@ -986,26 +975,76 @@ function generateModelHeader(schemaName) {
986
975
 
987
976
  `;
988
977
  }
978
+ function generateUtilityTypes(schemaName, schema) {
979
+ const parts = [];
980
+ const excludeFields = [];
981
+ if (schema.options?.id !== false) {
982
+ excludeFields.push("'id'");
983
+ }
984
+ if (schema.options?.timestamps !== false) {
985
+ excludeFields.push("'created_at'", "'updated_at'");
986
+ }
987
+ if (schema.options?.softDelete) {
988
+ excludeFields.push("'deleted_at'");
989
+ }
990
+ const omitType = excludeFields.length > 0 ? `Omit<${schemaName}, ${excludeFields.join(" | ")}>` : schemaName;
991
+ parts.push(`
992
+ /** For creating new ${schemaName} (POST requests) */`);
993
+ parts.push(`
994
+ export type ${schemaName}Create = ${omitType};
995
+ `);
996
+ parts.push(`
997
+ /** For updating ${schemaName} (PUT/PATCH requests) */`);
998
+ parts.push(`
999
+ export type ${schemaName}Update = Partial<${schemaName}Create>;
1000
+ `);
1001
+ return parts.join("");
1002
+ }
1003
+ function needsDateTimeImports(iface) {
1004
+ let dateTime = false;
1005
+ let date = false;
1006
+ for (const prop of iface.properties) {
1007
+ if (prop.type === "DateTimeString" || prop.type.includes("DateTimeString")) {
1008
+ dateTime = true;
1009
+ }
1010
+ if (prop.type === "DateString" || prop.type.includes("DateString")) {
1011
+ date = true;
1012
+ }
1013
+ }
1014
+ return { dateTime, date };
1015
+ }
989
1016
  function generateBaseInterfaceFile(schemaName, schemas, options) {
990
1017
  const interfaces = generateInterfaces(schemas, options);
991
1018
  const iface = interfaces.find((i) => i.name === schemaName);
992
- if (!iface) {
1019
+ const schema = schemas[schemaName];
1020
+ if (!iface || !schema) {
993
1021
  throw new Error(`Interface not found for schema: ${schemaName}`);
994
1022
  }
995
1023
  const parts = [generateBaseHeader()];
1024
+ const dateImports = needsDateTimeImports(iface);
1025
+ const commonImports = [];
1026
+ if (dateImports.dateTime) commonImports.push("DateTimeString");
1027
+ if (dateImports.date) commonImports.push("DateString");
1028
+ if (commonImports.length > 0) {
1029
+ parts.push(`import type { ${commonImports.join(", ")} } from '../common.js';
1030
+ `);
1031
+ }
996
1032
  if (iface.dependencies && iface.dependencies.length > 0) {
997
1033
  for (const dep of iface.dependencies) {
998
1034
  parts.push(`import type { ${dep} } from './${dep}.js';
999
1035
  `);
1000
1036
  }
1001
1037
  parts.push("\n");
1038
+ } else if (commonImports.length > 0) {
1039
+ parts.push("\n");
1002
1040
  }
1003
1041
  parts.push(formatInterface(iface));
1004
1042
  parts.push("\n");
1043
+ parts.push(generateUtilityTypes(schemaName, schema));
1005
1044
  return {
1006
1045
  filePath: `base/${schemaName}.ts`,
1007
1046
  content: parts.join(""),
1008
- types: [schemaName],
1047
+ types: [schemaName, `${schemaName}Create`, `${schemaName}Update`],
1009
1048
  overwrite: true
1010
1049
  };
1011
1050
  }
@@ -1060,8 +1099,59 @@ function generateModelFile(schemaName) {
1060
1099
  // Never overwrite user models
1061
1100
  };
1062
1101
  }
1063
- function generateIndexFile(schemas, enums, typeAliases) {
1102
+ function generateCommonFile(options) {
1103
+ const locales = options.localeConfig?.locales ?? ["ja", "en"];
1104
+ const localeUnion = locales.map((l) => `'${l}'`).join(" | ");
1105
+ const content = `${generateBaseHeader()}
1106
+ /**
1107
+ * Locale map for multi-language support.
1108
+ */
1109
+ export interface LocaleMap {
1110
+ [locale: string]: string;
1111
+ }
1112
+
1113
+ /**
1114
+ * Supported locales in this project.
1115
+ */
1116
+ export type Locale = ${localeUnion};
1117
+
1118
+ /**
1119
+ * Ant Design compatible validation rule.
1120
+ */
1121
+ export interface ValidationRule {
1122
+ required?: boolean;
1123
+ type?: 'string' | 'number' | 'email' | 'url' | 'integer' | 'array' | 'object';
1124
+ min?: number;
1125
+ max?: number;
1126
+ len?: number;
1127
+ pattern?: RegExp;
1128
+ message: string;
1129
+ }
1130
+
1131
+ /**
1132
+ * ISO 8601 date-time string.
1133
+ */
1134
+ export type DateTimeString = string;
1135
+
1136
+ /**
1137
+ * ISO 8601 date string (YYYY-MM-DD).
1138
+ */
1139
+ export type DateString = string;
1140
+ `;
1141
+ return {
1142
+ filePath: "common.ts",
1143
+ content,
1144
+ types: ["LocaleMap", "Locale", "ValidationRule", "DateTimeString", "DateString"],
1145
+ overwrite: true
1146
+ };
1147
+ }
1148
+ function generateIndexFile(schemas, enums, typeAliases, options) {
1064
1149
  const parts = [generateBaseHeader()];
1150
+ parts.push(`// Common Types
1151
+ `);
1152
+ parts.push(`export type { LocaleMap, Locale, ValidationRule, DateTimeString, DateString } from './common.js';
1153
+
1154
+ `);
1065
1155
  if (enums.length > 0 || typeAliases.length > 0) {
1066
1156
  parts.push(`// Enums
1067
1157
  `);
@@ -1099,13 +1189,34 @@ function generateIndexFile(schemas, enums, typeAliases) {
1099
1189
  }
1100
1190
  parts.push("\n");
1101
1191
  }
1102
- parts.push(`// Models
1192
+ parts.push(`// Models (with Create/Update utility types)
1103
1193
  `);
1104
1194
  for (const schema of Object.values(schemas)) {
1105
1195
  if (schema.kind === "enum") continue;
1106
1196
  if (schema.options?.hidden === true) continue;
1107
1197
  parts.push(`export type { ${schema.name} } from './${schema.name}.js';
1108
1198
  `);
1199
+ parts.push(`export type { ${schema.name}Create, ${schema.name}Update } from './base/${schema.name}.js';
1200
+ `);
1201
+ }
1202
+ if (options.generateRules) {
1203
+ parts.push(`
1204
+ // Validation Rules
1205
+ `);
1206
+ for (const schema of Object.values(schemas)) {
1207
+ if (schema.kind === "enum") continue;
1208
+ if (schema.options?.hidden === true) continue;
1209
+ parts.push(`export {
1210
+ `);
1211
+ parts.push(` get${schema.name}Rules,
1212
+ `);
1213
+ parts.push(` get${schema.name}DisplayName,
1214
+ `);
1215
+ parts.push(` get${schema.name}PropertyDisplayName,
1216
+ `);
1217
+ parts.push(`} from './rules/${schema.name}.rules.js';
1218
+ `);
1219
+ }
1109
1220
  }
1110
1221
  return {
1111
1222
  filePath: "index.ts",
@@ -1139,7 +1250,8 @@ function generateTypeScript(schemas, options = {}) {
1139
1250
  const rulesFiles = generateRulesFiles(schemas, opts);
1140
1251
  files.push(...rulesFiles);
1141
1252
  }
1142
- files.push(generateIndexFile(schemas, enums, typeAliases));
1253
+ files.push(generateCommonFile(opts));
1254
+ files.push(generateIndexFile(schemas, enums, typeAliases, opts));
1143
1255
  return files;
1144
1256
  }
1145
1257
  // Annotate the CommonJS export names for ESM import in node: