@famgia/omnify-laravel 0.0.12 → 0.0.14

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.
@@ -266,11 +266,18 @@ function schemaToBlueprint(schema, allSchemas) {
266
266
  }
267
267
  if (schema.options?.indexes) {
268
268
  for (const index of schema.options.indexes) {
269
- indexes.push({
270
- name: index.name,
271
- columns: index.columns.map(toColumnName),
272
- unique: index.unique ?? false
273
- });
269
+ if (typeof index === "string") {
270
+ indexes.push({
271
+ columns: [toColumnName(index)],
272
+ unique: false
273
+ });
274
+ } else {
275
+ indexes.push({
276
+ name: index.name,
277
+ columns: index.columns.map(toColumnName),
278
+ unique: index.unique ?? false
279
+ });
280
+ }
274
281
  }
275
282
  }
276
283
  if (schema.options?.unique) {
@@ -988,503 +995,611 @@ function generateMigrationsFromChanges(changes, options = {}) {
988
995
  return migrations;
989
996
  }
990
997
 
991
- // src/typescript/interface-generator.ts
992
- var TYPE_MAP = {
993
- String: "string",
994
- Int: "number",
995
- BigInt: "number",
996
- Float: "number",
997
- Boolean: "boolean",
998
- Text: "string",
999
- LongText: "string",
1000
- Date: "string",
1001
- Time: "string",
1002
- Timestamp: "string",
1003
- Json: "unknown",
1004
- Email: "string",
1005
- Password: "string",
1006
- Enum: "string",
1007
- Select: "string",
1008
- Lookup: "number"
1009
- };
1010
- var FILE_INTERFACE_NAME = "File";
1011
- var PK_TYPE_MAP = {
1012
- Int: "number",
1013
- BigInt: "number",
1014
- Uuid: "string",
1015
- String: "string"
1016
- };
1017
- function toPropertyName(name) {
1018
- return name;
998
+ // src/utils.ts
999
+ function toSnakeCase(str) {
1000
+ return str.replace(/([A-Z])/g, "_$1").replace(/^_/, "").toLowerCase();
1019
1001
  }
1020
- function toInterfaceName(schemaName) {
1021
- return schemaName;
1002
+ function toPascalCase(str) {
1003
+ return str.replace(/[-_](.)/g, (_, c) => c.toUpperCase()).replace(/^(.)/, (_, c) => c.toUpperCase());
1022
1004
  }
1023
- function getPropertyType(property, _allSchemas) {
1024
- if (property.type === "File") {
1025
- const fileProp = property;
1026
- if (fileProp.multiple) {
1027
- return `${FILE_INTERFACE_NAME}[]`;
1028
- }
1029
- return `${FILE_INTERFACE_NAME} | null`;
1030
- }
1031
- if (property.type === "Association") {
1032
- const assocProp = property;
1033
- const targetName = assocProp.target ?? "unknown";
1034
- switch (assocProp.relation) {
1035
- // Standard relations
1036
- case "OneToOne":
1037
- case "ManyToOne":
1038
- return targetName;
1039
- case "OneToMany":
1040
- case "ManyToMany":
1041
- return `${targetName}[]`;
1042
- // Polymorphic relations
1043
- case "MorphTo":
1044
- if (assocProp.targets && assocProp.targets.length > 0) {
1045
- return assocProp.targets.join(" | ");
1046
- }
1047
- return "unknown";
1048
- case "MorphOne":
1049
- return targetName;
1050
- case "MorphMany":
1051
- case "MorphToMany":
1052
- case "MorphedByMany":
1053
- return `${targetName}[]`;
1054
- default:
1055
- return "unknown";
1056
- }
1057
- }
1058
- if (property.type === "Enum") {
1059
- const enumProp = property;
1060
- if (typeof enumProp.enum === "string") {
1061
- return enumProp.enum;
1062
- }
1063
- if (Array.isArray(enumProp.enum)) {
1064
- return enumProp.enum.map((v) => `'${v}'`).join(" | ");
1065
- }
1005
+ function toCamelCase(str) {
1006
+ const pascal = toPascalCase(str);
1007
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
1008
+ }
1009
+ function pluralize(word) {
1010
+ if (word.endsWith("y") && !["ay", "ey", "iy", "oy", "uy"].some((v) => word.endsWith(v))) {
1011
+ return word.slice(0, -1) + "ies";
1066
1012
  }
1067
- if (property.type === "Select") {
1068
- const selectProp = property;
1069
- if (selectProp.options && selectProp.options.length > 0) {
1070
- return selectProp.options.map((v) => `'${v}'`).join(" | ");
1071
- }
1013
+ if (word.endsWith("s") || word.endsWith("x") || word.endsWith("z") || word.endsWith("ch") || word.endsWith("sh")) {
1014
+ return word + "es";
1072
1015
  }
1073
- return TYPE_MAP[property.type] ?? "unknown";
1016
+ return word + "s";
1074
1017
  }
1075
- function propertyToTSProperties(propertyName, property, allSchemas, options = {}) {
1076
- const baseProp = property;
1077
- const isReadonly = options.readonly ?? true;
1078
- if (property.type === "Association") {
1079
- const assocProp = property;
1080
- if (assocProp.relation === "MorphTo" && assocProp.targets && assocProp.targets.length > 0) {
1081
- const propBaseName = toPropertyName(propertyName);
1082
- const targetUnion = assocProp.targets.map((t) => `'${t}'`).join(" | ");
1083
- const relationUnion = assocProp.targets.join(" | ");
1084
- return [
1085
- {
1086
- name: `${propBaseName}Type`,
1087
- type: targetUnion,
1088
- optional: true,
1089
- // Polymorphic columns are nullable
1090
- readonly: isReadonly,
1091
- comment: `Polymorphic type for ${propertyName}`
1092
- },
1093
- {
1094
- name: `${propBaseName}Id`,
1095
- type: "number",
1096
- optional: true,
1097
- readonly: isReadonly,
1098
- comment: `Polymorphic ID for ${propertyName}`
1099
- },
1100
- {
1101
- name: propBaseName,
1102
- type: `${relationUnion} | null`,
1103
- optional: true,
1104
- readonly: isReadonly,
1105
- comment: baseProp.displayName ?? `Polymorphic relation to ${assocProp.targets.join(", ")}`
1018
+
1019
+ // src/model/generator.ts
1020
+ var DEFAULT_OPTIONS = {
1021
+ baseModelNamespace: "App\\Models\\OmnifyBase",
1022
+ modelNamespace: "App\\Models",
1023
+ baseModelClassName: "BaseModel",
1024
+ baseModelPath: "app/Models/OmnifyBase",
1025
+ modelPath: "app/Models"
1026
+ };
1027
+ function resolveOptions(options) {
1028
+ return {
1029
+ baseModelNamespace: options?.baseModelNamespace ?? DEFAULT_OPTIONS.baseModelNamespace,
1030
+ modelNamespace: options?.modelNamespace ?? DEFAULT_OPTIONS.modelNamespace,
1031
+ baseModelClassName: options?.baseModelClassName ?? DEFAULT_OPTIONS.baseModelClassName,
1032
+ baseModelPath: options?.baseModelPath ?? DEFAULT_OPTIONS.baseModelPath,
1033
+ modelPath: options?.modelPath ?? DEFAULT_OPTIONS.modelPath
1034
+ };
1035
+ }
1036
+ function getCastType(propDef) {
1037
+ switch (propDef.type) {
1038
+ case "Boolean":
1039
+ return "boolean";
1040
+ case "Int":
1041
+ case "BigInt":
1042
+ return "integer";
1043
+ case "Float":
1044
+ return "float";
1045
+ case "Decimal":
1046
+ return "decimal:" + (propDef.scale ?? 2);
1047
+ case "Json":
1048
+ return "array";
1049
+ case "Date":
1050
+ return "date";
1051
+ case "Timestamp":
1052
+ return "datetime";
1053
+ case "Password":
1054
+ return "hashed";
1055
+ default:
1056
+ return null;
1057
+ }
1058
+ }
1059
+ function isNullable(propDef) {
1060
+ return "nullable" in propDef && propDef.nullable === true;
1061
+ }
1062
+ function getPhpDocType(propDef, schemas) {
1063
+ const nullable = isNullable(propDef);
1064
+ switch (propDef.type) {
1065
+ case "String":
1066
+ case "Text":
1067
+ case "LongText":
1068
+ case "Email":
1069
+ case "Password":
1070
+ return "string" + (nullable ? "|null" : "");
1071
+ case "Int":
1072
+ case "BigInt":
1073
+ return "int" + (nullable ? "|null" : "");
1074
+ case "Float":
1075
+ case "Decimal":
1076
+ return "float" + (nullable ? "|null" : "");
1077
+ case "Boolean":
1078
+ return "bool" + (nullable ? "|null" : "");
1079
+ case "Date":
1080
+ case "Time":
1081
+ case "Timestamp":
1082
+ return "\\Carbon\\Carbon" + (nullable ? "|null" : "");
1083
+ case "Json":
1084
+ return "array" + (nullable ? "|null" : "");
1085
+ case "Enum":
1086
+ case "EnumRef":
1087
+ return "string" + (nullable ? "|null" : "");
1088
+ case "Association": {
1089
+ const assoc = propDef;
1090
+ if (assoc.target) {
1091
+ const className = toPascalCase(assoc.target);
1092
+ switch (assoc.relation) {
1093
+ case "OneToMany":
1094
+ case "ManyToMany":
1095
+ case "MorphMany":
1096
+ case "MorphToMany":
1097
+ case "MorphedByMany":
1098
+ return `\\Illuminate\\Database\\Eloquent\\Collection<${className}>`;
1099
+ default:
1100
+ return className + "|null";
1106
1101
  }
1107
- ];
1108
- }
1109
- }
1110
- const type = getPropertyType(property, allSchemas);
1111
- return [{
1112
- name: toPropertyName(propertyName),
1113
- type,
1114
- optional: baseProp.nullable ?? false,
1115
- readonly: isReadonly,
1116
- comment: baseProp.displayName
1117
- }];
1118
- }
1119
- function propertyToTSProperty(propertyName, property, allSchemas, options = {}) {
1120
- return propertyToTSProperties(propertyName, property, allSchemas, options)[0];
1121
- }
1122
- function schemaToInterface(schema, allSchemas, options = {}) {
1123
- const properties = [];
1124
- if (schema.options?.id !== false) {
1125
- const pkType = schema.options?.idType ?? "BigInt";
1126
- properties.push({
1127
- name: "id",
1128
- type: PK_TYPE_MAP[pkType] ?? "number",
1129
- optional: false,
1130
- readonly: options.readonly ?? true,
1131
- comment: "Primary key"
1132
- });
1133
- }
1134
- if (schema.properties) {
1135
- for (const [propName, property] of Object.entries(schema.properties)) {
1136
- properties.push(...propertyToTSProperties(propName, property, allSchemas, options));
1137
- }
1138
- }
1139
- if (schema.options?.timestamps !== false) {
1140
- properties.push(
1141
- {
1142
- name: "createdAt",
1143
- type: "string",
1144
- optional: true,
1145
- readonly: options.readonly ?? true,
1146
- comment: "Creation timestamp"
1147
- },
1148
- {
1149
- name: "updatedAt",
1150
- type: "string",
1151
- optional: true,
1152
- readonly: options.readonly ?? true,
1153
- comment: "Last update timestamp"
1154
1102
  }
1155
- );
1156
- }
1157
- if (schema.options?.softDelete) {
1158
- properties.push({
1159
- name: "deletedAt",
1160
- type: "string",
1161
- optional: true,
1162
- readonly: options.readonly ?? true,
1163
- comment: "Soft delete timestamp"
1164
- });
1103
+ return "mixed";
1104
+ }
1105
+ default:
1106
+ return "mixed";
1165
1107
  }
1108
+ }
1109
+ function generateBaseModel(schemas, options, stubContent) {
1110
+ const modelMap = Object.values(schemas).filter((s) => s.kind !== "enum").map((s) => {
1111
+ const className = toPascalCase(s.name);
1112
+ return ` '${s.name}' => \\${options.modelNamespace}\\${className}::class,`;
1113
+ }).join("\n");
1114
+ const content = stubContent.replace(/\{\{BASE_MODEL_NAMESPACE\}\}/g, options.baseModelNamespace).replace(/\{\{BASE_MODEL_CLASS\}\}/g, options.baseModelClassName).replace(/\{\{MODEL_MAP\}\}/g, modelMap);
1166
1115
  return {
1167
- name: toInterfaceName(schema.name),
1168
- properties,
1169
- comment: schema.displayName ?? schema.name
1116
+ path: `${options.baseModelPath}/${options.baseModelClassName}.php`,
1117
+ content,
1118
+ type: "base-model",
1119
+ overwrite: true,
1120
+ schemaName: "__base__"
1170
1121
  };
1171
1122
  }
1172
- function formatProperty(property) {
1173
- const readonly = property.readonly ? "readonly " : "";
1174
- const optional = property.optional ? "?" : "";
1175
- const comment = property.comment ? ` /** ${property.comment} */
1176
- ` : "";
1177
- return `${comment} ${readonly}${property.name}${optional}: ${property.type};`;
1178
- }
1179
- function formatInterface(iface) {
1180
- const comment = iface.comment ? `/**
1181
- * ${iface.comment}
1182
- */
1183
- ` : "";
1184
- const extendsClause = iface.extends && iface.extends.length > 0 ? ` extends ${iface.extends.join(", ")}` : "";
1185
- const properties = iface.properties.map(formatProperty).join("\n");
1186
- return `${comment}export interface ${iface.name}${extendsClause} {
1187
- ${properties}
1188
- }`;
1189
- }
1190
- function generateInterfaces(schemas, options = {}) {
1191
- const interfaces = [];
1192
- for (const schema of Object.values(schemas)) {
1193
- if (schema.kind === "enum") {
1194
- continue;
1123
+ function generateEntityBaseModel(schema, schemas, options, stubContent, authStubContent) {
1124
+ const className = toPascalCase(schema.name);
1125
+ const tableName = schema.options?.tableName ?? pluralize(toSnakeCase(schema.name));
1126
+ const isAuth = schema.options?.authenticatable ?? false;
1127
+ const primaryKey = "id";
1128
+ const idType = schema.options?.idType ?? "BigInt";
1129
+ const isUuid = idType === "Uuid";
1130
+ const isStringKey = idType === "Uuid" || idType === "String";
1131
+ const imports = [];
1132
+ const traits = [];
1133
+ const fillable = [];
1134
+ const hidden = [];
1135
+ const appends = [];
1136
+ const casts = [];
1137
+ const relations = [];
1138
+ const docProperties = [];
1139
+ if (schema.options?.softDelete) {
1140
+ imports.push("use Illuminate\\Database\\Eloquent\\SoftDeletes;");
1141
+ traits.push(" use SoftDeletes;");
1142
+ }
1143
+ const properties = schema.properties ?? {};
1144
+ for (const [propName, propDef] of Object.entries(properties)) {
1145
+ const snakeName = toSnakeCase(propName);
1146
+ const phpType = getPhpDocType(propDef, schemas);
1147
+ docProperties.push(` * @property ${phpType} $${snakeName}`);
1148
+ if (propDef.type === "Association") {
1149
+ const assoc = propDef;
1150
+ if (assoc.target) {
1151
+ imports.push(`use ${options.modelNamespace}\\${toPascalCase(assoc.target)};`);
1152
+ }
1153
+ relations.push(generateRelation(propName, assoc, options));
1154
+ if (assoc.relation === "ManyToOne" || assoc.relation === "OneToOne") {
1155
+ if (!assoc.mappedBy) {
1156
+ const fkName = toSnakeCase(propName) + "_id";
1157
+ fillable.push(` '${fkName}',`);
1158
+ docProperties.push(` * @property int|null $${fkName}`);
1159
+ }
1160
+ }
1161
+ } else if (propDef.type === "Password") {
1162
+ fillable.push(` '${snakeName}',`);
1163
+ hidden.push(` '${snakeName}',`);
1164
+ const cast = getCastType(propDef);
1165
+ if (cast) {
1166
+ casts.push(` '${snakeName}' => '${cast}',`);
1167
+ }
1168
+ } else if (propDef.type === "File") {
1169
+ const relMethod = generateFileRelation(propName, propDef);
1170
+ relations.push(relMethod);
1171
+ } else {
1172
+ fillable.push(` '${snakeName}',`);
1173
+ const cast = getCastType(propDef);
1174
+ if (cast) {
1175
+ casts.push(` '${snakeName}' => '${cast}',`);
1176
+ }
1195
1177
  }
1196
- interfaces.push(schemaToInterface(schema, schemas, options));
1197
1178
  }
1198
- return interfaces;
1199
- }
1179
+ const docComment = `/**
1180
+ * ${className}BaseModel
1181
+ *
1182
+ ${docProperties.join("\n")}
1183
+ */`;
1184
+ const stub = isAuth ? authStubContent : stubContent;
1185
+ const keyType = isStringKey ? ` /**
1186
+ * The "type" of the primary key ID.
1187
+ */
1188
+ protected $keyType = 'string';
1200
1189
 
1201
- // src/typescript/enum-generator.ts
1202
- function toEnumMemberName(value) {
1203
- return value.split(/[-_\s]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("").replace(/[^a-zA-Z0-9]/g, "");
1204
- }
1205
- function toEnumName(schemaName) {
1206
- return schemaName;
1207
- }
1208
- function schemaToEnum(schema) {
1209
- if (schema.kind !== "enum" || !schema.values) {
1210
- return null;
1190
+ ` : "";
1191
+ const incrementing = isUuid ? ` /**
1192
+ * Indicates if the IDs are auto-incrementing.
1193
+ */
1194
+ public $incrementing = false;
1195
+
1196
+ ` : "";
1197
+ if (isUuid) {
1198
+ imports.push("use Illuminate\\Database\\Eloquent\\Concerns\\HasUuids;");
1199
+ traits.push(" use HasUuids;");
1211
1200
  }
1212
- const values = schema.values.map((value) => ({
1213
- name: toEnumMemberName(value),
1214
- value
1215
- }));
1201
+ const content = stub.replace(/\{\{BASE_MODEL_NAMESPACE\}\}/g, options.baseModelNamespace).replace(/\{\{BASE_MODEL_CLASS\}\}/g, options.baseModelClassName).replace(/\{\{CLASS_NAME\}\}/g, className).replace(/\{\{TABLE_NAME\}\}/g, tableName).replace(/\{\{PRIMARY_KEY\}\}/g, primaryKey).replace(/\{\{KEY_TYPE\}\}/g, keyType).replace(/\{\{INCREMENTING\}\}/g, incrementing).replace(/\{\{TIMESTAMPS\}\}/g, schema.options?.timestamps !== false ? "true" : "false").replace(/\{\{IMPORTS\}\}/g, [...new Set(imports)].sort().join("\n")).replace(/\{\{TRAITS\}\}/g, traits.join("\n")).replace(/\{\{DOC_COMMENT\}\}/g, docComment).replace(/\{\{FILLABLE\}\}/g, fillable.join("\n")).replace(/\{\{HIDDEN\}\}/g, hidden.join("\n")).replace(/\{\{APPENDS\}\}/g, appends.join("\n")).replace(/\{\{CASTS\}\}/g, casts.join("\n")).replace(/\{\{RELATIONS\}\}/g, relations.join("\n\n"));
1216
1202
  return {
1217
- name: toEnumName(schema.name),
1218
- values,
1219
- comment: schema.displayName ?? schema.name
1203
+ path: `${options.baseModelPath}/${className}BaseModel.php`,
1204
+ content,
1205
+ type: "entity-base",
1206
+ overwrite: true,
1207
+ schemaName: schema.name
1220
1208
  };
1221
1209
  }
1222
- function generateEnums(schemas) {
1223
- const enums = [];
1224
- for (const schema of Object.values(schemas)) {
1225
- if (schema.kind === "enum") {
1226
- const enumDef = schemaToEnum(schema);
1227
- if (enumDef) {
1228
- enums.push(enumDef);
1210
+ function generateRelation(propName, assoc, options) {
1211
+ const methodName = toCamelCase(propName);
1212
+ const targetClass = assoc.target ? toPascalCase(assoc.target) : "";
1213
+ const fkName = toSnakeCase(propName) + "_id";
1214
+ switch (assoc.relation) {
1215
+ case "ManyToOne":
1216
+ return ` /**
1217
+ * Get the ${propName} that owns this model.
1218
+ */
1219
+ public function ${methodName}(): BelongsTo
1220
+ {
1221
+ return $this->belongsTo(${targetClass}::class, '${fkName}');
1222
+ }`;
1223
+ case "OneToOne":
1224
+ if (assoc.mappedBy) {
1225
+ return ` /**
1226
+ * Get the ${propName} for this model.
1227
+ */
1228
+ public function ${methodName}(): HasOne
1229
+ {
1230
+ return $this->hasOne(${targetClass}::class, '${toSnakeCase(assoc.mappedBy)}_id');
1231
+ }`;
1229
1232
  }
1233
+ return ` /**
1234
+ * Get the ${propName} that owns this model.
1235
+ */
1236
+ public function ${methodName}(): BelongsTo
1237
+ {
1238
+ return $this->belongsTo(${targetClass}::class, '${fkName}');
1239
+ }`;
1240
+ case "OneToMany":
1241
+ return ` /**
1242
+ * Get the ${propName} for this model.
1243
+ */
1244
+ public function ${methodName}(): HasMany
1245
+ {
1246
+ return $this->hasMany(${targetClass}::class, '${toSnakeCase(assoc.inversedBy ?? propName)}_id');
1247
+ }`;
1248
+ case "ManyToMany": {
1249
+ const pivotTable = assoc.joinTable ?? `${toSnakeCase(propName)}_pivot`;
1250
+ return ` /**
1251
+ * The ${propName} that belong to this model.
1252
+ */
1253
+ public function ${methodName}(): BelongsToMany
1254
+ {
1255
+ return $this->belongsToMany(${targetClass}::class, '${pivotTable}')
1256
+ ->withTimestamps();
1257
+ }`;
1230
1258
  }
1231
- }
1232
- return enums;
1233
- }
1234
- function formatEnum(enumDef) {
1235
- const comment = enumDef.comment ? `/**
1236
- * ${enumDef.comment}
1237
- */
1238
- ` : "";
1239
- const values = enumDef.values.map((v) => ` ${v.name} = '${v.value}',`).join("\n");
1240
- return `${comment}export enum ${enumDef.name} {
1241
- ${values}
1242
- }`;
1259
+ case "MorphTo":
1260
+ return ` /**
1261
+ * Get the parent ${propName} model.
1262
+ */
1263
+ public function ${methodName}(): MorphTo
1264
+ {
1265
+ return $this->morphTo('${methodName}');
1266
+ }`;
1267
+ case "MorphOne":
1268
+ return ` /**
1269
+ * Get the ${propName} for this model.
1270
+ */
1271
+ public function ${methodName}(): MorphOne
1272
+ {
1273
+ return $this->morphOne(${targetClass}::class, '${assoc.morphName ?? propName}');
1274
+ }`;
1275
+ case "MorphMany":
1276
+ return ` /**
1277
+ * Get the ${propName} for this model.
1278
+ */
1279
+ public function ${methodName}(): MorphMany
1280
+ {
1281
+ return $this->morphMany(${targetClass}::class, '${assoc.morphName ?? propName}');
1282
+ }`;
1283
+ default:
1284
+ return ` // TODO: Implement ${assoc.relation} relation for ${propName}`;
1285
+ }
1286
+ }
1287
+ function generateFileRelation(propName, propDef) {
1288
+ const methodName = toCamelCase(propName);
1289
+ const relationType = propDef.multiple ? "MorphMany" : "MorphOne";
1290
+ const relationMethod = propDef.multiple ? "morphMany" : "morphOne";
1291
+ return ` /**
1292
+ * Get the ${propName} file(s) for this model.
1293
+ */
1294
+ public function ${methodName}(): ${relationType}
1295
+ {
1296
+ return $this->${relationMethod}(FileUpload::class, 'uploadable')
1297
+ ->where('attribute_name', '${propName}');
1298
+ }`;
1243
1299
  }
1244
- function enumToUnionType(enumDef) {
1245
- const type = enumDef.values.map((v) => `'${v.value}'`).join(" | ");
1300
+ function generateEntityModel(schema, options, stubContent) {
1301
+ const className = toPascalCase(schema.name);
1302
+ const content = stubContent.replace(/\{\{BASE_MODEL_NAMESPACE\}\}/g, options.baseModelNamespace).replace(/\{\{MODEL_NAMESPACE\}\}/g, options.modelNamespace).replace(/\{\{CLASS_NAME\}\}/g, className);
1246
1303
  return {
1247
- name: enumDef.name,
1248
- type,
1249
- comment: enumDef.comment
1304
+ path: `${options.modelPath}/${className}.php`,
1305
+ content,
1306
+ type: "entity",
1307
+ overwrite: false,
1308
+ // Never overwrite user models
1309
+ schemaName: schema.name
1250
1310
  };
1251
1311
  }
1252
- function formatTypeAlias(alias) {
1253
- const comment = alias.comment ? `/**
1254
- * ${alias.comment}
1312
+ function getStubContent(stubName) {
1313
+ const stubs = {
1314
+ "base-model": `<?php
1315
+
1316
+ namespace {{BASE_MODEL_NAMESPACE}};
1317
+
1318
+ /**
1319
+ * Base model class for all Omnify-generated models.
1320
+ * Contains model mapping for polymorphic relations.
1321
+ *
1322
+ * DO NOT EDIT - This file is auto-generated by Omnify.
1323
+ * Any changes will be overwritten on next generation.
1324
+ *
1325
+ * @generated by @famgia/omnify-laravel
1255
1326
  */
1256
- ` : "";
1257
- return `${comment}export type ${alias.name} = ${alias.type};`;
1258
- }
1259
- function extractInlineEnums(schemas) {
1260
- const typeAliases = [];
1261
- for (const schema of Object.values(schemas)) {
1262
- if (schema.kind === "enum" || !schema.properties) {
1263
- continue;
1327
+
1328
+ use Illuminate\\Database\\Eloquent\\Model;
1329
+ use Illuminate\\Database\\Eloquent\\Relations\\Relation;
1330
+
1331
+ abstract class {{BASE_MODEL_CLASS}} extends Model
1332
+ {
1333
+ /**
1334
+ * Model class map for polymorphic relations.
1335
+ */
1336
+ protected static array $modelMap = [
1337
+ {{MODEL_MAP}}
1338
+ ];
1339
+
1340
+ /**
1341
+ * Boot the model and register morph map.
1342
+ */
1343
+ protected static function boot(): void
1344
+ {
1345
+ parent::boot();
1346
+
1347
+ // Register morph map for polymorphic relations
1348
+ Relation::enforceMorphMap(static::$modelMap);
1264
1349
  }
1265
- for (const [propName, property] of Object.entries(schema.properties)) {
1266
- if (property.type === "Enum") {
1267
- const enumProp = property;
1268
- if (Array.isArray(enumProp.enum) && enumProp.enum.length > 0) {
1269
- const typeName = `${schema.name}${propName.charAt(0).toUpperCase() + propName.slice(1)}`;
1270
- typeAliases.push({
1271
- name: typeName,
1272
- type: enumProp.enum.map((v) => `'${v}'`).join(" | "),
1273
- comment: enumProp.displayName ?? `${schema.name} ${propName} enum`
1274
- });
1275
- }
1276
- }
1277
- if (property.type === "Select") {
1278
- const selectProp = property;
1279
- if (selectProp.options && selectProp.options.length > 0) {
1280
- const typeName = `${schema.name}${propName.charAt(0).toUpperCase() + propName.slice(1)}`;
1281
- typeAliases.push({
1282
- name: typeName,
1283
- type: selectProp.options.map((v) => `'${v}'`).join(" | "),
1284
- comment: selectProp.displayName ?? `${schema.name} ${propName} options`
1285
- });
1286
- }
1287
- }
1350
+
1351
+ /**
1352
+ * Get the model class for a given morph type.
1353
+ */
1354
+ public static function getModelClass(string $morphType): ?string
1355
+ {
1356
+ return static::$modelMap[$morphType] ?? null;
1288
1357
  }
1289
- }
1290
- return typeAliases;
1291
1358
  }
1359
+ `,
1360
+ "entity-base": `<?php
1292
1361
 
1293
- // src/typescript/generator.ts
1294
- var DEFAULT_OPTIONS = {
1295
- singleFile: true,
1296
- fileName: "types.ts",
1297
- readonly: true,
1298
- strictNullChecks: true
1299
- };
1300
- function generateHeader() {
1301
- return `/**
1302
- * Auto-generated TypeScript types from Omnify schemas.
1303
- * DO NOT EDIT - This file is automatically generated.
1362
+ namespace {{BASE_MODEL_NAMESPACE}};
1363
+
1364
+ /**
1365
+ * DO NOT EDIT - This file is auto-generated by Omnify.
1366
+ * Any changes will be overwritten on next generation.
1367
+ *
1368
+ * @generated by @famgia/omnify-laravel
1304
1369
  */
1305
1370
 
1306
- `;
1307
- }
1308
- function generateTypeScriptFile(schemas, options = {}) {
1309
- const opts = { ...DEFAULT_OPTIONS, ...options };
1310
- const parts = [generateHeader()];
1311
- const types = [];
1312
- const enums = generateEnums(schemas);
1313
- if (enums.length > 0) {
1314
- parts.push("// Enums\n");
1315
- for (const enumDef of enums) {
1316
- parts.push(formatEnum(enumDef));
1317
- parts.push("\n\n");
1318
- types.push(enumDef.name);
1319
- }
1320
- }
1321
- const inlineEnums = extractInlineEnums(schemas);
1322
- if (inlineEnums.length > 0) {
1323
- parts.push("// Type Aliases\n");
1324
- for (const alias of inlineEnums) {
1325
- parts.push(formatTypeAlias(alias));
1326
- parts.push("\n\n");
1327
- types.push(alias.name);
1328
- }
1329
- }
1330
- const interfaces = generateInterfaces(schemas, opts);
1331
- if (interfaces.length > 0) {
1332
- parts.push("// Interfaces\n");
1333
- for (const iface of interfaces) {
1334
- parts.push(formatInterface(iface));
1335
- parts.push("\n\n");
1336
- types.push(iface.name);
1371
+ use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;
1372
+ use Illuminate\\Database\\Eloquent\\Relations\\HasMany;
1373
+ use Illuminate\\Database\\Eloquent\\Relations\\HasOne;
1374
+ use Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;
1375
+ use Illuminate\\Database\\Eloquent\\Relations\\MorphTo;
1376
+ use Illuminate\\Database\\Eloquent\\Relations\\MorphOne;
1377
+ use Illuminate\\Database\\Eloquent\\Relations\\MorphMany;
1378
+ use Illuminate\\Database\\Eloquent\\Relations\\MorphToMany;
1379
+ use Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;
1380
+ {{IMPORTS}}
1381
+
1382
+ {{DOC_COMMENT}}
1383
+ class {{CLASS_NAME}}BaseModel extends {{BASE_MODEL_CLASS}}
1384
+ {
1385
+ {{TRAITS}}
1386
+ /**
1387
+ * The table associated with the model.
1388
+ */
1389
+ protected $table = '{{TABLE_NAME}}';
1390
+
1391
+ /**
1392
+ * The primary key for the model.
1393
+ */
1394
+ protected $primaryKey = '{{PRIMARY_KEY}}';
1395
+
1396
+ {{KEY_TYPE}}
1397
+ {{INCREMENTING}}
1398
+ /**
1399
+ * Indicates if the model should be timestamped.
1400
+ */
1401
+ public $timestamps = {{TIMESTAMPS}};
1402
+
1403
+ /**
1404
+ * The attributes that are mass assignable.
1405
+ */
1406
+ protected $fillable = [
1407
+ {{FILLABLE}}
1408
+ ];
1409
+
1410
+ /**
1411
+ * The attributes that should be hidden for serialization.
1412
+ */
1413
+ protected $hidden = [
1414
+ {{HIDDEN}}
1415
+ ];
1416
+
1417
+ /**
1418
+ * The accessors to append to the model's array form.
1419
+ */
1420
+ protected $appends = [
1421
+ {{APPENDS}}
1422
+ ];
1423
+
1424
+ /**
1425
+ * Get the attributes that should be cast.
1426
+ */
1427
+ protected function casts(): array
1428
+ {
1429
+ return [
1430
+ {{CASTS}}
1431
+ ];
1337
1432
  }
1338
- }
1339
- return {
1340
- fileName: opts.fileName ?? "types.ts",
1341
- content: parts.join("").trim() + "\n",
1342
- types
1343
- };
1433
+
1434
+ {{RELATIONS}}
1344
1435
  }
1345
- function generateTypeScriptFiles(schemas, options = {}) {
1346
- const opts = { ...DEFAULT_OPTIONS, ...options };
1347
- const files = [];
1348
- const enums = generateEnums(schemas);
1349
- if (enums.length > 0) {
1350
- const content = generateHeader() + enums.map(formatEnum).join("\n\n") + "\n";
1351
- files.push({
1352
- fileName: "enums.ts",
1353
- content,
1354
- types: enums.map((e) => e.name)
1355
- });
1356
- }
1357
- const inlineEnums = extractInlineEnums(schemas);
1358
- if (inlineEnums.length > 0) {
1359
- const content = generateHeader() + inlineEnums.map(formatTypeAlias).join("\n\n") + "\n";
1360
- files.push({
1361
- fileName: "type-aliases.ts",
1362
- content,
1363
- types: inlineEnums.map((a) => a.name)
1364
- });
1365
- }
1366
- const interfaces = generateInterfaces(schemas, opts);
1367
- for (const iface of interfaces) {
1368
- const imports = collectImports(iface, enums, inlineEnums, interfaces);
1369
- const importStatement = formatImports(imports);
1370
- const content = generateHeader() + (importStatement ? importStatement + "\n\n" : "") + formatInterface(iface) + "\n";
1371
- files.push({
1372
- fileName: `${toKebabCase(iface.name)}.ts`,
1373
- content,
1374
- types: [iface.name]
1375
- });
1376
- }
1377
- const indexContent = generateIndexFile(files);
1378
- files.push({
1379
- fileName: "index.ts",
1380
- content: indexContent,
1381
- types: []
1382
- });
1383
- return files;
1384
- }
1385
- function toKebabCase(name) {
1386
- return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
1387
- }
1388
- function collectImports(iface, enums, typeAliases, allInterfaces) {
1389
- const imports = /* @__PURE__ */ new Map();
1390
- const enumNames = new Set(enums.map((e) => e.name));
1391
- const aliasNames = new Set(typeAliases.map((a) => a.name));
1392
- const interfaceNames = new Set(allInterfaces.map((i) => i.name));
1393
- for (const prop of iface.properties) {
1394
- if (enumNames.has(prop.type)) {
1395
- const existing = imports.get("./enums.js") ?? [];
1396
- if (!existing.includes(prop.type)) {
1397
- imports.set("./enums.js", [...existing, prop.type]);
1398
- }
1399
- }
1400
- if (aliasNames.has(prop.type)) {
1401
- const existing = imports.get("./type-aliases.js") ?? [];
1402
- if (!existing.includes(prop.type)) {
1403
- imports.set("./type-aliases.js", [...existing, prop.type]);
1404
- }
1405
- }
1406
- const baseType = prop.type.replace("[]", "");
1407
- if (interfaceNames.has(baseType) && baseType !== iface.name) {
1408
- const fileName = `./${toKebabCase(baseType)}.js`;
1409
- const existing = imports.get(fileName) ?? [];
1410
- if (!existing.includes(baseType)) {
1411
- imports.set(fileName, [...existing, baseType]);
1412
- }
1436
+ `,
1437
+ "entity-base-auth": `<?php
1438
+
1439
+ namespace {{BASE_MODEL_NAMESPACE}};
1440
+
1441
+ /**
1442
+ * DO NOT EDIT - This file is auto-generated by Omnify.
1443
+ * Any changes will be overwritten on next generation.
1444
+ *
1445
+ * @generated by @famgia/omnify-laravel
1446
+ */
1447
+
1448
+ use Illuminate\\Foundation\\Auth\\User as Authenticatable;
1449
+ use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;
1450
+ use Illuminate\\Database\\Eloquent\\Relations\\HasMany;
1451
+ use Illuminate\\Database\\Eloquent\\Relations\\HasOne;
1452
+ use Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;
1453
+ use Illuminate\\Database\\Eloquent\\Relations\\MorphTo;
1454
+ use Illuminate\\Database\\Eloquent\\Relations\\MorphOne;
1455
+ use Illuminate\\Database\\Eloquent\\Relations\\MorphMany;
1456
+ use Illuminate\\Database\\Eloquent\\Relations\\MorphToMany;
1457
+ use Illuminate\\Database\\Eloquent\\Collection as EloquentCollection;
1458
+ use Illuminate\\Notifications\\Notifiable;
1459
+ {{IMPORTS}}
1460
+
1461
+ {{DOC_COMMENT}}
1462
+ class {{CLASS_NAME}}BaseModel extends Authenticatable
1463
+ {
1464
+ use Notifiable;
1465
+ {{TRAITS}}
1466
+ /**
1467
+ * The table associated with the model.
1468
+ */
1469
+ protected $table = '{{TABLE_NAME}}';
1470
+
1471
+ /**
1472
+ * The primary key for the model.
1473
+ */
1474
+ protected $primaryKey = '{{PRIMARY_KEY}}';
1475
+
1476
+ {{KEY_TYPE}}
1477
+ {{INCREMENTING}}
1478
+ /**
1479
+ * Indicates if the model should be timestamped.
1480
+ */
1481
+ public $timestamps = {{TIMESTAMPS}};
1482
+
1483
+ /**
1484
+ * The attributes that are mass assignable.
1485
+ */
1486
+ protected $fillable = [
1487
+ {{FILLABLE}}
1488
+ ];
1489
+
1490
+ /**
1491
+ * The attributes that should be hidden for serialization.
1492
+ */
1493
+ protected $hidden = [
1494
+ {{HIDDEN}}
1495
+ ];
1496
+
1497
+ /**
1498
+ * The accessors to append to the model's array form.
1499
+ */
1500
+ protected $appends = [
1501
+ {{APPENDS}}
1502
+ ];
1503
+
1504
+ /**
1505
+ * Get the attributes that should be cast.
1506
+ */
1507
+ protected function casts(): array
1508
+ {
1509
+ return [
1510
+ {{CASTS}}
1511
+ ];
1413
1512
  }
1414
- }
1415
- return imports;
1513
+
1514
+ {{RELATIONS}}
1416
1515
  }
1417
- function formatImports(imports) {
1418
- if (imports.size === 0) return "";
1419
- const lines = [];
1420
- for (const [path, names] of imports) {
1421
- lines.push(`import type { ${names.join(", ")} } from '${path}';`);
1422
- }
1423
- return lines.join("\n");
1516
+ `,
1517
+ "entity": `<?php
1518
+
1519
+ namespace {{MODEL_NAMESPACE}};
1520
+
1521
+ use {{BASE_MODEL_NAMESPACE}}\\{{CLASS_NAME}}BaseModel;
1522
+ use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
1523
+
1524
+ /**
1525
+ * {{CLASS_NAME}} Model
1526
+ *
1527
+ * This file is generated once and can be customized.
1528
+ * Add your custom methods and logic here.
1529
+ */
1530
+ class {{CLASS_NAME}} extends {{CLASS_NAME}}BaseModel
1531
+ {
1532
+ use HasFactory;
1533
+
1534
+ /**
1535
+ * Create a new model instance.
1536
+ */
1537
+ public function __construct(array $attributes = [])
1538
+ {
1539
+ parent::__construct($attributes);
1540
+ }
1541
+
1542
+ // Add your custom methods here
1424
1543
  }
1425
- function generateIndexFile(files) {
1426
- const exports = [generateHeader().trim(), ""];
1427
- for (const file of files) {
1428
- if (file.fileName === "index.ts") continue;
1429
- const moduleName = file.fileName.replace(".ts", ".js");
1430
- exports.push(`export * from './${moduleName}';`);
1431
- }
1432
- return exports.join("\n") + "\n";
1544
+ `
1545
+ };
1546
+ return stubs[stubName] ?? "";
1433
1547
  }
1434
- function generateTypeScript(schemas, options = {}) {
1435
- const opts = { ...DEFAULT_OPTIONS, ...options };
1436
- if (opts.singleFile) {
1437
- return [generateTypeScriptFile(schemas, opts)];
1548
+ function generateModels(schemas, options) {
1549
+ const resolved = resolveOptions(options);
1550
+ const models = [];
1551
+ models.push(generateBaseModel(schemas, resolved, getStubContent("base-model")));
1552
+ for (const schema of Object.values(schemas)) {
1553
+ if (schema.kind === "enum") {
1554
+ continue;
1555
+ }
1556
+ models.push(generateEntityBaseModel(
1557
+ schema,
1558
+ schemas,
1559
+ resolved,
1560
+ getStubContent("entity-base"),
1561
+ getStubContent("entity-base-auth")
1562
+ ));
1563
+ models.push(generateEntityModel(schema, resolved, getStubContent("entity")));
1438
1564
  }
1439
- return generateTypeScriptFiles(schemas, opts);
1565
+ return models;
1440
1566
  }
1441
- function getTypeScriptPath(file, outputDir = "src/types") {
1442
- return `${outputDir}/${file.fileName}`;
1567
+ function getModelPath(model) {
1568
+ return model.path;
1443
1569
  }
1444
1570
 
1445
1571
  // src/plugin.ts
1446
1572
  var LARAVEL_CONFIG_SCHEMA = {
1447
1573
  fields: [
1448
- // Paths group
1449
1574
  {
1450
1575
  key: "migrationsPath",
1451
1576
  type: "path",
1452
1577
  label: "Migrations Path",
1453
1578
  description: "Directory for Laravel migration files",
1454
1579
  default: "database/migrations",
1455
- group: "paths"
1580
+ group: "output"
1456
1581
  },
1457
1582
  {
1458
- key: "typesPath",
1583
+ key: "modelsPath",
1459
1584
  type: "path",
1460
- label: "TypeScript Types Path",
1461
- description: "Directory for generated TypeScript type files",
1462
- default: "types",
1463
- group: "paths"
1464
- },
1465
- // Generators group
1466
- {
1467
- key: "generateMigrations",
1468
- type: "boolean",
1469
- label: "Generate Migrations",
1470
- description: "Generate Laravel migration files",
1471
- default: true,
1472
- group: "generators"
1585
+ label: "Models Path",
1586
+ description: "Directory for user-editable model files",
1587
+ default: "app/Models",
1588
+ group: "output"
1473
1589
  },
1474
1590
  {
1475
- key: "generateTypes",
1476
- type: "boolean",
1477
- label: "Generate TypeScript Types",
1478
- description: "Generate TypeScript type definitions",
1479
- default: true,
1480
- group: "generators"
1591
+ key: "baseModelsPath",
1592
+ type: "path",
1593
+ label: "Base Models Path",
1594
+ description: "Directory for auto-generated base model files",
1595
+ default: "app/Models/OmnifyBase",
1596
+ group: "output"
1481
1597
  },
1482
- // Options group
1483
1598
  {
1484
- key: "singleFile",
1599
+ key: "generateModels",
1485
1600
  type: "boolean",
1486
- label: "Single File Output",
1487
- description: "Generate all types in a single file",
1601
+ label: "Generate Models",
1602
+ description: "Generate Eloquent model classes",
1488
1603
  default: true,
1489
1604
  group: "options"
1490
1605
  },
@@ -1498,69 +1613,69 @@ var LARAVEL_CONFIG_SCHEMA = {
1498
1613
  }
1499
1614
  ]
1500
1615
  };
1501
- function resolveOptions(options) {
1616
+ function resolveOptions2(options) {
1502
1617
  return {
1503
1618
  migrationsPath: options?.migrationsPath ?? "database/migrations",
1504
- typesPath: options?.typesPath ?? "types",
1505
- singleFile: options?.singleFile ?? true,
1619
+ modelsPath: options?.modelsPath ?? "app/Models",
1620
+ baseModelsPath: options?.baseModelsPath ?? "app/Models/OmnifyBase",
1621
+ modelNamespace: options?.modelNamespace ?? "App\\Models",
1622
+ baseModelNamespace: options?.baseModelNamespace ?? "App\\Models\\OmnifyBase",
1623
+ generateModels: options?.generateModels ?? true,
1506
1624
  connection: options?.connection,
1507
- timestamp: options?.timestamp,
1508
- generateTypes: options?.generateTypes ?? true,
1509
- generateMigrations: options?.generateMigrations ?? true
1625
+ timestamp: options?.timestamp
1510
1626
  };
1511
1627
  }
1512
1628
  function laravelPlugin(options) {
1513
- const resolved = resolveOptions(options);
1629
+ const resolved = resolveOptions2(options);
1630
+ const migrationGenerator = {
1631
+ name: "laravel-migrations",
1632
+ description: "Generate Laravel migration files",
1633
+ generate: async (ctx) => {
1634
+ const migrationOptions = {
1635
+ connection: resolved.connection,
1636
+ timestamp: resolved.timestamp
1637
+ };
1638
+ const migrations = generateMigrations(ctx.schemas, migrationOptions);
1639
+ return migrations.map((migration) => ({
1640
+ path: getMigrationPath(migration, resolved.migrationsPath),
1641
+ content: migration.content,
1642
+ type: "migration",
1643
+ metadata: {
1644
+ tableName: migration.tables[0],
1645
+ migrationType: migration.type
1646
+ }
1647
+ }));
1648
+ }
1649
+ };
1650
+ const modelGenerator = {
1651
+ name: "laravel-models",
1652
+ description: "Generate Eloquent model classes",
1653
+ generate: async (ctx) => {
1654
+ const modelOptions = {
1655
+ modelNamespace: resolved.modelNamespace,
1656
+ baseModelNamespace: resolved.baseModelNamespace,
1657
+ modelPath: resolved.modelsPath,
1658
+ baseModelPath: resolved.baseModelsPath
1659
+ };
1660
+ const models = generateModels(ctx.schemas, modelOptions);
1661
+ return models.map((model) => ({
1662
+ path: getModelPath(model),
1663
+ content: model.content,
1664
+ type: "model",
1665
+ // Skip writing user models if they already exist
1666
+ skipIfExists: !model.overwrite,
1667
+ metadata: {
1668
+ modelType: model.type,
1669
+ schemaName: model.schemaName
1670
+ }
1671
+ }));
1672
+ }
1673
+ };
1514
1674
  return {
1515
1675
  name: "@famgia/omnify-laravel",
1516
- version: "0.0.12",
1676
+ version: "0.0.14",
1517
1677
  configSchema: LARAVEL_CONFIG_SCHEMA,
1518
- generators: [
1519
- // Laravel Migrations Generator
1520
- ...resolved.generateMigrations ? [
1521
- {
1522
- name: "laravel-migrations",
1523
- description: "Generate Laravel migration files",
1524
- generate: async (ctx) => {
1525
- const migrationOptions = {
1526
- connection: resolved.connection,
1527
- timestamp: resolved.timestamp
1528
- };
1529
- const migrations = generateMigrations(ctx.schemas, migrationOptions);
1530
- return migrations.map((migration) => ({
1531
- path: getMigrationPath(migration, resolved.migrationsPath),
1532
- content: migration.content,
1533
- type: "migration",
1534
- metadata: {
1535
- tableName: migration.tables[0],
1536
- migrationType: migration.type
1537
- }
1538
- }));
1539
- }
1540
- }
1541
- ] : [],
1542
- // TypeScript Types Generator
1543
- ...resolved.generateTypes ? [
1544
- {
1545
- name: "typescript-types",
1546
- description: "Generate TypeScript type definitions",
1547
- generate: async (ctx) => {
1548
- const tsOptions = {
1549
- singleFile: resolved.singleFile
1550
- };
1551
- const files = generateTypeScript(ctx.schemas, tsOptions);
1552
- return files.map((file) => ({
1553
- path: `${resolved.typesPath}/${file.fileName}`,
1554
- content: file.content,
1555
- type: "type",
1556
- metadata: {
1557
- types: file.types
1558
- }
1559
- }));
1560
- }
1561
- }
1562
- ] : []
1563
- ]
1678
+ generators: resolved.generateModels ? [migrationGenerator, modelGenerator] : [migrationGenerator]
1564
1679
  };
1565
1680
  }
1566
1681
 
@@ -1584,26 +1699,6 @@ export {
1584
1699
  generateAlterMigration,
1585
1700
  generateDropTableMigration,
1586
1701
  generateMigrationsFromChanges,
1587
- toPropertyName,
1588
- toInterfaceName,
1589
- getPropertyType,
1590
- propertyToTSProperty,
1591
- schemaToInterface,
1592
- formatProperty,
1593
- formatInterface,
1594
- generateInterfaces,
1595
- toEnumMemberName,
1596
- toEnumName,
1597
- schemaToEnum,
1598
- generateEnums,
1599
- formatEnum,
1600
- enumToUnionType,
1601
- formatTypeAlias,
1602
- extractInlineEnums,
1603
- generateTypeScriptFile,
1604
- generateTypeScriptFiles,
1605
- generateTypeScript,
1606
- getTypeScriptPath,
1607
1702
  laravelPlugin
1608
1703
  };
1609
- //# sourceMappingURL=chunk-2JWTIYRL.js.map
1704
+ //# sourceMappingURL=chunk-UVF7W2J2.js.map