@famgia/omnify-laravel 0.0.9 → 0.0.11

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
@@ -91,6 +91,12 @@ var PK_METHOD_MAP = {
91
91
  Uuid: "uuid",
92
92
  String: "string"
93
93
  };
94
+ function getIdType(schema) {
95
+ return schema.options?.idType ?? "BigInt";
96
+ }
97
+ function hasAutoId(schema) {
98
+ return schema.options?.id !== false;
99
+ }
94
100
  function toColumnName(propertyName) {
95
101
  return propertyName.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
96
102
  }
@@ -198,6 +204,54 @@ function generateSoftDeleteColumn() {
198
204
  modifiers: [{ method: "nullable" }]
199
205
  };
200
206
  }
207
+ function generatePolymorphicColumns(propertyName, property, allSchemas) {
208
+ if (property.type !== "Association") {
209
+ return null;
210
+ }
211
+ const assocProp = property;
212
+ if (assocProp.relation !== "MorphTo") {
213
+ return null;
214
+ }
215
+ const targets = assocProp.targets;
216
+ if (!targets || targets.length === 0) {
217
+ return null;
218
+ }
219
+ const columnBaseName = toColumnName(propertyName);
220
+ const typeColumnName = `${columnBaseName}_type`;
221
+ const idColumnName = `${columnBaseName}_id`;
222
+ const typeColumn = {
223
+ name: typeColumnName,
224
+ method: "enum",
225
+ args: [typeColumnName, targets],
226
+ modifiers: [{ method: "nullable" }]
227
+ };
228
+ let idMethod = "unsignedBigInteger";
229
+ for (const targetName of targets) {
230
+ const targetSchema = allSchemas[targetName];
231
+ if (targetSchema) {
232
+ const targetIdType = targetSchema.options?.idType ?? "BigInt";
233
+ if (targetIdType === "Uuid") {
234
+ idMethod = "uuid";
235
+ break;
236
+ } else if (targetIdType === "String") {
237
+ idMethod = "string";
238
+ }
239
+ }
240
+ }
241
+ const idColumn = {
242
+ name: idColumnName,
243
+ method: idMethod,
244
+ args: idMethod === "string" ? [idColumnName, 255] : [idColumnName],
245
+ modifiers: [{ method: "nullable" }]
246
+ };
247
+ const indexes = [
248
+ {
249
+ columns: [typeColumnName, idColumnName],
250
+ unique: false
251
+ }
252
+ ];
253
+ return { typeColumn, idColumn, indexes };
254
+ }
201
255
  function generateForeignKey(propertyName, property, allSchemas) {
202
256
  if (property.type !== "Association") {
203
257
  return null;
@@ -212,7 +266,7 @@ function generateForeignKey(propertyName, property, allSchemas) {
212
266
  const columnName = toColumnName(propertyName) + "_id";
213
267
  const targetSchema = assocProp.target ? allSchemas[assocProp.target] : void 0;
214
268
  const targetTable = assocProp.target ? toTableName(assocProp.target) : "unknown";
215
- const targetPkType = targetSchema?.options?.primaryKeyType ?? "BigInt";
269
+ const targetPkType = targetSchema ? getIdType(targetSchema) : "BigInt";
216
270
  let method = "unsignedBigInteger";
217
271
  if (targetPkType === "Int") {
218
272
  method = "unsignedInteger";
@@ -245,8 +299,10 @@ function schemaToBlueprint(schema, allSchemas) {
245
299
  const columns = [];
246
300
  const foreignKeys = [];
247
301
  const indexes = [];
248
- const pkType = schema.options?.primaryKeyType ?? "BigInt";
249
- columns.push(generatePrimaryKeyColumn(pkType));
302
+ if (hasAutoId(schema)) {
303
+ const pkType = getIdType(schema);
304
+ columns.push(generatePrimaryKeyColumn(pkType));
305
+ }
250
306
  if (schema.properties) {
251
307
  for (const [propName, property] of Object.entries(schema.properties)) {
252
308
  const columnMethod = propertyToColumnMethod(propName, property);
@@ -259,6 +315,12 @@ function schemaToBlueprint(schema, allSchemas) {
259
315
  foreignKeys.push(fkResult.foreignKey);
260
316
  indexes.push(fkResult.index);
261
317
  }
318
+ const polyResult = generatePolymorphicColumns(propName, property, allSchemas);
319
+ if (polyResult) {
320
+ columns.push(polyResult.typeColumn);
321
+ columns.push(polyResult.idColumn);
322
+ indexes.push(...polyResult.indexes);
323
+ }
262
324
  }
263
325
  }
264
326
  if (schema.options?.timestamps !== false) {
@@ -352,7 +414,7 @@ function extractManyToManyRelations(schema, allSchemas) {
352
414
  return pivotTables;
353
415
  }
354
416
  const sourceTable = toTableName(schema.name);
355
- const sourcePkType = schema.options?.primaryKeyType ?? "BigInt";
417
+ const sourcePkType = getIdType(schema);
356
418
  for (const [, property] of Object.entries(schema.properties)) {
357
419
  if (property.type !== "Association") {
358
420
  continue;
@@ -367,7 +429,7 @@ function extractManyToManyRelations(schema, allSchemas) {
367
429
  }
368
430
  const targetSchema = allSchemas[targetName];
369
431
  const targetTable = toTableName(targetName);
370
- const targetPkType = targetSchema?.options?.primaryKeyType ?? "BigInt";
432
+ const targetPkType = targetSchema ? getIdType(targetSchema) : "BigInt";
371
433
  const isOwningSide = assocProp.owning ?? schema.name < targetName;
372
434
  if (!isOwningSide) {
373
435
  continue;
@@ -1029,12 +1091,25 @@ function getPropertyType(property, _allSchemas) {
1029
1091
  const assocProp = property;
1030
1092
  const targetName = assocProp.target ?? "unknown";
1031
1093
  switch (assocProp.relation) {
1094
+ // Standard relations
1032
1095
  case "OneToOne":
1033
1096
  case "ManyToOne":
1034
1097
  return targetName;
1035
1098
  case "OneToMany":
1036
1099
  case "ManyToMany":
1037
1100
  return `${targetName}[]`;
1101
+ // Polymorphic relations
1102
+ case "MorphTo":
1103
+ if (assocProp.targets && assocProp.targets.length > 0) {
1104
+ return assocProp.targets.join(" | ");
1105
+ }
1106
+ return "unknown";
1107
+ case "MorphOne":
1108
+ return targetName;
1109
+ case "MorphMany":
1110
+ case "MorphToMany":
1111
+ case "MorphedByMany":
1112
+ return `${targetName}[]`;
1038
1113
  default:
1039
1114
  return "unknown";
1040
1115
  }
@@ -1056,30 +1131,68 @@ function getPropertyType(property, _allSchemas) {
1056
1131
  }
1057
1132
  return TYPE_MAP[property.type] ?? "unknown";
1058
1133
  }
1059
- function propertyToTSProperty(propertyName, property, allSchemas, options = {}) {
1060
- const type = getPropertyType(property, allSchemas);
1134
+ function propertyToTSProperties(propertyName, property, allSchemas, options = {}) {
1061
1135
  const baseProp = property;
1062
- return {
1136
+ const isReadonly = options.readonly ?? true;
1137
+ if (property.type === "Association") {
1138
+ const assocProp = property;
1139
+ if (assocProp.relation === "MorphTo" && assocProp.targets && assocProp.targets.length > 0) {
1140
+ const propBaseName = toPropertyName(propertyName);
1141
+ const targetUnion = assocProp.targets.map((t) => `'${t}'`).join(" | ");
1142
+ const relationUnion = assocProp.targets.join(" | ");
1143
+ return [
1144
+ {
1145
+ name: `${propBaseName}Type`,
1146
+ type: targetUnion,
1147
+ optional: true,
1148
+ // Polymorphic columns are nullable
1149
+ readonly: isReadonly,
1150
+ comment: `Polymorphic type for ${propertyName}`
1151
+ },
1152
+ {
1153
+ name: `${propBaseName}Id`,
1154
+ type: "number",
1155
+ optional: true,
1156
+ readonly: isReadonly,
1157
+ comment: `Polymorphic ID for ${propertyName}`
1158
+ },
1159
+ {
1160
+ name: propBaseName,
1161
+ type: `${relationUnion} | null`,
1162
+ optional: true,
1163
+ readonly: isReadonly,
1164
+ comment: baseProp.displayName ?? `Polymorphic relation to ${assocProp.targets.join(", ")}`
1165
+ }
1166
+ ];
1167
+ }
1168
+ }
1169
+ const type = getPropertyType(property, allSchemas);
1170
+ return [{
1063
1171
  name: toPropertyName(propertyName),
1064
1172
  type,
1065
1173
  optional: baseProp.nullable ?? false,
1066
- readonly: options.readonly ?? true,
1174
+ readonly: isReadonly,
1067
1175
  comment: baseProp.displayName
1068
- };
1176
+ }];
1177
+ }
1178
+ function propertyToTSProperty(propertyName, property, allSchemas, options = {}) {
1179
+ return propertyToTSProperties(propertyName, property, allSchemas, options)[0];
1069
1180
  }
1070
1181
  function schemaToInterface(schema, allSchemas, options = {}) {
1071
1182
  const properties = [];
1072
- const pkType = schema.options?.primaryKeyType ?? "BigInt";
1073
- properties.push({
1074
- name: "id",
1075
- type: PK_TYPE_MAP[pkType] ?? "number",
1076
- optional: false,
1077
- readonly: options.readonly ?? true,
1078
- comment: "Primary key"
1079
- });
1183
+ if (schema.options?.id !== false) {
1184
+ const pkType = schema.options?.idType ?? "BigInt";
1185
+ properties.push({
1186
+ name: "id",
1187
+ type: PK_TYPE_MAP[pkType] ?? "number",
1188
+ optional: false,
1189
+ readonly: options.readonly ?? true,
1190
+ comment: "Primary key"
1191
+ });
1192
+ }
1080
1193
  if (schema.properties) {
1081
1194
  for (const [propName, property] of Object.entries(schema.properties)) {
1082
- properties.push(propertyToTSProperty(propName, property, allSchemas, options));
1195
+ properties.push(...propertyToTSProperties(propName, property, allSchemas, options));
1083
1196
  }
1084
1197
  }
1085
1198
  if (schema.options?.timestamps !== false) {