@famgia/omnify-laravel 0.0.12 → 0.0.13

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.
@@ -988,505 +988,16 @@ function generateMigrationsFromChanges(changes, options = {}) {
988
988
  return migrations;
989
989
  }
990
990
 
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;
1019
- }
1020
- function toInterfaceName(schemaName) {
1021
- return schemaName;
1022
- }
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
- }
1066
- }
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
- }
1072
- }
1073
- return TYPE_MAP[property.type] ?? "unknown";
1074
- }
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(", ")}`
1106
- }
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
- }
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
- });
1165
- }
1166
- return {
1167
- name: toInterfaceName(schema.name),
1168
- properties,
1169
- comment: schema.displayName ?? schema.name
1170
- };
1171
- }
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;
1195
- }
1196
- interfaces.push(schemaToInterface(schema, schemas, options));
1197
- }
1198
- return interfaces;
1199
- }
1200
-
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;
1211
- }
1212
- const values = schema.values.map((value) => ({
1213
- name: toEnumMemberName(value),
1214
- value
1215
- }));
1216
- return {
1217
- name: toEnumName(schema.name),
1218
- values,
1219
- comment: schema.displayName ?? schema.name
1220
- };
1221
- }
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);
1229
- }
1230
- }
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
- }`;
1243
- }
1244
- function enumToUnionType(enumDef) {
1245
- const type = enumDef.values.map((v) => `'${v.value}'`).join(" | ");
1246
- return {
1247
- name: enumDef.name,
1248
- type,
1249
- comment: enumDef.comment
1250
- };
1251
- }
1252
- function formatTypeAlias(alias) {
1253
- const comment = alias.comment ? `/**
1254
- * ${alias.comment}
1255
- */
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;
1264
- }
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
- }
1288
- }
1289
- }
1290
- return typeAliases;
1291
- }
1292
-
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.
1304
- */
1305
-
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);
1337
- }
1338
- }
1339
- return {
1340
- fileName: opts.fileName ?? "types.ts",
1341
- content: parts.join("").trim() + "\n",
1342
- types
1343
- };
1344
- }
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
- }
1413
- }
1414
- }
1415
- return imports;
1416
- }
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");
1424
- }
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";
1433
- }
1434
- function generateTypeScript(schemas, options = {}) {
1435
- const opts = { ...DEFAULT_OPTIONS, ...options };
1436
- if (opts.singleFile) {
1437
- return [generateTypeScriptFile(schemas, opts)];
1438
- }
1439
- return generateTypeScriptFiles(schemas, opts);
1440
- }
1441
- function getTypeScriptPath(file, outputDir = "src/types") {
1442
- return `${outputDir}/${file.fileName}`;
1443
- }
1444
-
1445
991
  // src/plugin.ts
1446
992
  var LARAVEL_CONFIG_SCHEMA = {
1447
993
  fields: [
1448
- // Paths group
1449
994
  {
1450
995
  key: "migrationsPath",
1451
996
  type: "path",
1452
997
  label: "Migrations Path",
1453
998
  description: "Directory for Laravel migration files",
1454
999
  default: "database/migrations",
1455
- group: "paths"
1456
- },
1457
- {
1458
- key: "typesPath",
1459
- 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"
1473
- },
1474
- {
1475
- key: "generateTypes",
1476
- type: "boolean",
1477
- label: "Generate TypeScript Types",
1478
- description: "Generate TypeScript type definitions",
1479
- default: true,
1480
- group: "generators"
1481
- },
1482
- // Options group
1483
- {
1484
- key: "singleFile",
1485
- type: "boolean",
1486
- label: "Single File Output",
1487
- description: "Generate all types in a single file",
1488
- default: true,
1489
- group: "options"
1000
+ group: "output"
1490
1001
  },
1491
1002
  {
1492
1003
  key: "connection",
@@ -1501,65 +1012,37 @@ var LARAVEL_CONFIG_SCHEMA = {
1501
1012
  function resolveOptions(options) {
1502
1013
  return {
1503
1014
  migrationsPath: options?.migrationsPath ?? "database/migrations",
1504
- typesPath: options?.typesPath ?? "types",
1505
- singleFile: options?.singleFile ?? true,
1506
1015
  connection: options?.connection,
1507
- timestamp: options?.timestamp,
1508
- generateTypes: options?.generateTypes ?? true,
1509
- generateMigrations: options?.generateMigrations ?? true
1016
+ timestamp: options?.timestamp
1510
1017
  };
1511
1018
  }
1512
1019
  function laravelPlugin(options) {
1513
1020
  const resolved = resolveOptions(options);
1514
1021
  return {
1515
1022
  name: "@famgia/omnify-laravel",
1516
- version: "0.0.12",
1023
+ version: "0.0.13",
1517
1024
  configSchema: LARAVEL_CONFIG_SCHEMA,
1518
1025
  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
- }
1026
+ {
1027
+ name: "laravel-migrations",
1028
+ description: "Generate Laravel migration files",
1029
+ generate: async (ctx) => {
1030
+ const migrationOptions = {
1031
+ connection: resolved.connection,
1032
+ timestamp: resolved.timestamp
1033
+ };
1034
+ const migrations = generateMigrations(ctx.schemas, migrationOptions);
1035
+ return migrations.map((migration) => ({
1036
+ path: getMigrationPath(migration, resolved.migrationsPath),
1037
+ content: migration.content,
1038
+ type: "migration",
1039
+ metadata: {
1040
+ tableName: migration.tables[0],
1041
+ migrationType: migration.type
1042
+ }
1043
+ }));
1561
1044
  }
1562
- ] : []
1045
+ }
1563
1046
  ]
1564
1047
  };
1565
1048
  }
@@ -1584,26 +1067,6 @@ export {
1584
1067
  generateAlterMigration,
1585
1068
  generateDropTableMigration,
1586
1069
  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
1070
  laravelPlugin
1608
1071
  };
1609
- //# sourceMappingURL=chunk-2JWTIYRL.js.map
1072
+ //# sourceMappingURL=chunk-G4UAJVC2.js.map