@famgia/omnify-laravel 0.0.8 → 0.0.10

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
@@ -69,6 +69,7 @@ var TYPE_METHOD_MAP = {
69
69
  Int: "integer",
70
70
  BigInt: "bigInteger",
71
71
  Float: "double",
72
+ Decimal: "decimal",
72
73
  Boolean: "boolean",
73
74
  Text: "text",
74
75
  LongText: "longText",
@@ -90,6 +91,12 @@ var PK_METHOD_MAP = {
90
91
  Uuid: "uuid",
91
92
  String: "string"
92
93
  };
94
+ function getIdType(schema) {
95
+ return schema.options?.idType ?? "BigInt";
96
+ }
97
+ function hasAutoId(schema) {
98
+ return schema.options?.id !== false;
99
+ }
93
100
  function toColumnName(propertyName) {
94
101
  return propertyName.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
95
102
  }
@@ -115,6 +122,12 @@ function propertyToColumnMethod(propertyName, property) {
115
122
  if (method === "string" && propWithLength.length) {
116
123
  args.push(propWithLength.length);
117
124
  }
125
+ if (property.type === "Decimal") {
126
+ const decimalProp = property;
127
+ const precision = decimalProp.precision ?? 8;
128
+ const scale = decimalProp.scale ?? 2;
129
+ args.push(precision, scale);
130
+ }
118
131
  if (property.type === "Enum") {
119
132
  const enumProp = property;
120
133
  if (enumProp.enum && enumProp.enum.length > 0) {
@@ -191,6 +204,54 @@ function generateSoftDeleteColumn() {
191
204
  modifiers: [{ method: "nullable" }]
192
205
  };
193
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
+ }
194
255
  function generateForeignKey(propertyName, property, allSchemas) {
195
256
  if (property.type !== "Association") {
196
257
  return null;
@@ -205,7 +266,7 @@ function generateForeignKey(propertyName, property, allSchemas) {
205
266
  const columnName = toColumnName(propertyName) + "_id";
206
267
  const targetSchema = assocProp.target ? allSchemas[assocProp.target] : void 0;
207
268
  const targetTable = assocProp.target ? toTableName(assocProp.target) : "unknown";
208
- const targetPkType = targetSchema?.options?.primaryKeyType ?? "BigInt";
269
+ const targetPkType = targetSchema ? getIdType(targetSchema) : "BigInt";
209
270
  let method = "unsignedBigInteger";
210
271
  if (targetPkType === "Int") {
211
272
  method = "unsignedInteger";
@@ -238,8 +299,10 @@ function schemaToBlueprint(schema, allSchemas) {
238
299
  const columns = [];
239
300
  const foreignKeys = [];
240
301
  const indexes = [];
241
- const pkType = schema.options?.primaryKeyType ?? "BigInt";
242
- columns.push(generatePrimaryKeyColumn(pkType));
302
+ if (hasAutoId(schema)) {
303
+ const pkType = getIdType(schema);
304
+ columns.push(generatePrimaryKeyColumn(pkType));
305
+ }
243
306
  if (schema.properties) {
244
307
  for (const [propName, property] of Object.entries(schema.properties)) {
245
308
  const columnMethod = propertyToColumnMethod(propName, property);
@@ -252,6 +315,12 @@ function schemaToBlueprint(schema, allSchemas) {
252
315
  foreignKeys.push(fkResult.foreignKey);
253
316
  indexes.push(fkResult.index);
254
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
+ }
255
324
  }
256
325
  }
257
326
  if (schema.options?.timestamps !== false) {
@@ -345,7 +414,7 @@ function extractManyToManyRelations(schema, allSchemas) {
345
414
  return pivotTables;
346
415
  }
347
416
  const sourceTable = toTableName(schema.name);
348
- const sourcePkType = schema.options?.primaryKeyType ?? "BigInt";
417
+ const sourcePkType = getIdType(schema);
349
418
  for (const [, property] of Object.entries(schema.properties)) {
350
419
  if (property.type !== "Association") {
351
420
  continue;
@@ -360,7 +429,7 @@ function extractManyToManyRelations(schema, allSchemas) {
360
429
  }
361
430
  const targetSchema = allSchemas[targetName];
362
431
  const targetTable = toTableName(targetName);
363
- const targetPkType = targetSchema?.options?.primaryKeyType ?? "BigInt";
432
+ const targetPkType = targetSchema ? getIdType(targetSchema) : "BigInt";
364
433
  const isOwningSide = assocProp.owning ?? schema.name < targetName;
365
434
  if (!isOwningSide) {
366
435
  continue;
@@ -709,6 +778,7 @@ var TYPE_METHOD_MAP2 = {
709
778
  Int: "integer",
710
779
  BigInt: "bigInteger",
711
780
  Float: "double",
781
+ Decimal: "decimal",
712
782
  Boolean: "boolean",
713
783
  Text: "text",
714
784
  LongText: "longText",
@@ -737,7 +807,14 @@ function generateTimestamp2() {
737
807
  function formatAddColumn(columnName, prop) {
738
808
  const snakeColumn = toColumnName(columnName);
739
809
  const method = TYPE_METHOD_MAP2[prop.type] ?? "string";
740
- let code = `$table->${method}('${snakeColumn}')`;
810
+ let code;
811
+ if (prop.type === "Decimal") {
812
+ const precision = prop.precision ?? 8;
813
+ const scale = prop.scale ?? 2;
814
+ code = `$table->${method}('${snakeColumn}', ${precision}, ${scale})`;
815
+ } else {
816
+ code = `$table->${method}('${snakeColumn}')`;
817
+ }
741
818
  if (prop.nullable) code += "->nullable()";
742
819
  if (prop.unique) code += "->unique()";
743
820
  if (prop.default !== void 0) {
@@ -758,7 +835,14 @@ function formatRenameColumn(oldName, newName) {
758
835
  function formatModifyColumn(columnName, _prevProp, currProp) {
759
836
  const snakeColumn = toColumnName(columnName);
760
837
  const method = TYPE_METHOD_MAP2[currProp.type] ?? "string";
761
- let code = `$table->${method}('${snakeColumn}')`;
838
+ let code;
839
+ if (currProp.type === "Decimal") {
840
+ const precision = currProp.precision ?? 8;
841
+ const scale = currProp.scale ?? 2;
842
+ code = `$table->${method}('${snakeColumn}', ${precision}, ${scale})`;
843
+ } else {
844
+ code = `$table->${method}('${snakeColumn}')`;
845
+ }
762
846
  if (currProp.nullable) code += "->nullable()";
763
847
  if (currProp.unique) code += "->unique()";
764
848
  if (currProp.default !== void 0) {
@@ -1007,12 +1091,25 @@ function getPropertyType(property, _allSchemas) {
1007
1091
  const assocProp = property;
1008
1092
  const targetName = assocProp.target ?? "unknown";
1009
1093
  switch (assocProp.relation) {
1094
+ // Standard relations
1010
1095
  case "OneToOne":
1011
1096
  case "ManyToOne":
1012
1097
  return targetName;
1013
1098
  case "OneToMany":
1014
1099
  case "ManyToMany":
1015
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}[]`;
1016
1113
  default:
1017
1114
  return "unknown";
1018
1115
  }
@@ -1034,30 +1131,68 @@ function getPropertyType(property, _allSchemas) {
1034
1131
  }
1035
1132
  return TYPE_MAP[property.type] ?? "unknown";
1036
1133
  }
1037
- function propertyToTSProperty(propertyName, property, allSchemas, options = {}) {
1038
- const type = getPropertyType(property, allSchemas);
1134
+ function propertyToTSProperties(propertyName, property, allSchemas, options = {}) {
1039
1135
  const baseProp = property;
1040
- 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 [{
1041
1171
  name: toPropertyName(propertyName),
1042
1172
  type,
1043
1173
  optional: baseProp.nullable ?? false,
1044
- readonly: options.readonly ?? true,
1174
+ readonly: isReadonly,
1045
1175
  comment: baseProp.displayName
1046
- };
1176
+ }];
1177
+ }
1178
+ function propertyToTSProperty(propertyName, property, allSchemas, options = {}) {
1179
+ return propertyToTSProperties(propertyName, property, allSchemas, options)[0];
1047
1180
  }
1048
1181
  function schemaToInterface(schema, allSchemas, options = {}) {
1049
1182
  const properties = [];
1050
- const pkType = schema.options?.primaryKeyType ?? "BigInt";
1051
- properties.push({
1052
- name: "id",
1053
- type: PK_TYPE_MAP[pkType] ?? "number",
1054
- optional: false,
1055
- readonly: options.readonly ?? true,
1056
- comment: "Primary key"
1057
- });
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
+ }
1058
1193
  if (schema.properties) {
1059
1194
  for (const [propName, property] of Object.entries(schema.properties)) {
1060
- properties.push(propertyToTSProperty(propName, property, allSchemas, options));
1195
+ properties.push(...propertyToTSProperties(propName, property, allSchemas, options));
1061
1196
  }
1062
1197
  }
1063
1198
  if (schema.options?.timestamps !== false) {