@famgia/omnify-laravel 0.0.16 → 0.0.18

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.
@@ -1,5 +1,5 @@
1
1
  // src/plugin.ts
2
- import { readFileSync, existsSync } from "fs";
2
+ import { readFileSync, existsSync, readdirSync } from "fs";
3
3
  import { join } from "path";
4
4
 
5
5
  // src/migration/schema-builder.ts
@@ -14,6 +14,7 @@ var TYPE_METHOD_MAP = {
14
14
  LongText: "longText",
15
15
  Date: "date",
16
16
  Time: "time",
17
+ DateTime: "dateTime",
17
18
  Timestamp: "timestamp",
18
19
  Json: "json",
19
20
  Email: "string",
@@ -86,6 +87,10 @@ function propertyToColumnMethod(propertyName, property) {
86
87
  if (baseProp.unsigned && (method === "integer" || method === "bigInteger")) {
87
88
  modifiers.push({ method: "unsigned" });
88
89
  }
90
+ const displayName = property.displayName;
91
+ if (displayName) {
92
+ modifiers.push({ method: "comment", args: [displayName] });
93
+ }
89
94
  return {
90
95
  name: columnName,
91
96
  method,
@@ -214,12 +219,15 @@ function generateForeignKey(propertyName, property, allSchemas) {
214
219
  method = "string";
215
220
  }
216
221
  const modifiers = [];
217
- if (assocProp.nullable || assocProp.relation === "ManyToOne") {
222
+ if (assocProp.nullable === true) {
218
223
  modifiers.push({ method: "nullable" });
219
224
  }
220
225
  if (assocProp.default !== void 0 && assocProp.default !== null) {
221
226
  modifiers.push({ method: "default", args: [assocProp.default] });
222
227
  }
228
+ if (assocProp.displayName) {
229
+ modifiers.push({ method: "comment", args: [assocProp.displayName] });
230
+ }
223
231
  const column = {
224
232
  name: columnName,
225
233
  method,
@@ -239,7 +247,65 @@ function generateForeignKey(propertyName, property, allSchemas) {
239
247
  };
240
248
  return { column, foreignKey, index };
241
249
  }
242
- function schemaToBlueprint(schema, allSchemas) {
250
+ function expandCompoundType(propName, property, customTypes) {
251
+ const typeDef = customTypes.get(property.type);
252
+ if (!typeDef || !typeDef.compound || !typeDef.expand) {
253
+ return null;
254
+ }
255
+ const expanded = [];
256
+ const baseProp = property;
257
+ for (const field of typeDef.expand) {
258
+ const suffixSnake = toColumnName(field.suffix);
259
+ const columnName = `${propName}_${suffixSnake}`;
260
+ const expandedProp = {
261
+ type: "String"
262
+ // Default type, will be overridden by sql definition
263
+ };
264
+ if (field.sql) {
265
+ const sqlType = field.sql.sqlType.toUpperCase();
266
+ if (sqlType === "VARCHAR" || sqlType === "CHAR" || sqlType === "STRING") {
267
+ expandedProp.type = "String";
268
+ if (field.sql.length) {
269
+ expandedProp.length = field.sql.length;
270
+ }
271
+ } else if (sqlType === "INT" || sqlType === "INTEGER") {
272
+ expandedProp.type = "Int";
273
+ } else if (sqlType === "BIGINT") {
274
+ expandedProp.type = "BigInt";
275
+ } else if (sqlType === "TEXT") {
276
+ expandedProp.type = "Text";
277
+ } else if (sqlType === "BOOLEAN" || sqlType === "BOOL") {
278
+ expandedProp.type = "Boolean";
279
+ } else if (sqlType === "DECIMAL") {
280
+ expandedProp.type = "Decimal";
281
+ if (field.sql.precision) expandedProp.precision = field.sql.precision;
282
+ if (field.sql.scale) expandedProp.scale = field.sql.scale;
283
+ } else if (sqlType === "DATE") {
284
+ expandedProp.type = "Date";
285
+ } else if (sqlType === "TIMESTAMP" || sqlType === "DATETIME") {
286
+ expandedProp.type = "Timestamp";
287
+ }
288
+ if (field.sql.nullable !== void 0) {
289
+ expandedProp.nullable = field.sql.nullable;
290
+ } else if (baseProp.nullable !== void 0) {
291
+ expandedProp.nullable = baseProp.nullable;
292
+ }
293
+ if (field.sql.default !== void 0) {
294
+ expandedProp.default = field.sql.default;
295
+ }
296
+ }
297
+ if (baseProp.displayName) {
298
+ expandedProp.displayName = `${baseProp.displayName} (${field.suffix})`;
299
+ }
300
+ expanded.push({
301
+ name: columnName,
302
+ property: expandedProp
303
+ });
304
+ }
305
+ return expanded;
306
+ }
307
+ function schemaToBlueprint(schema, allSchemas, options = {}) {
308
+ const { customTypes = /* @__PURE__ */ new Map() } = options;
243
309
  const tableName = toTableName(schema.name);
244
310
  const columns = [];
245
311
  const foreignKeys = [];
@@ -250,6 +316,16 @@ function schemaToBlueprint(schema, allSchemas) {
250
316
  }
251
317
  if (schema.properties) {
252
318
  for (const [propName, property] of Object.entries(schema.properties)) {
319
+ const expandedProps = expandCompoundType(propName, property, customTypes);
320
+ if (expandedProps) {
321
+ for (const { name: expandedName, property: expandedProp } of expandedProps) {
322
+ const columnMethod2 = propertyToColumnMethod(expandedName, expandedProp);
323
+ if (columnMethod2) {
324
+ columns.push(columnMethod2);
325
+ }
326
+ }
327
+ continue;
328
+ }
253
329
  const columnMethod = propertyToColumnMethod(propName, property);
254
330
  if (columnMethod) {
255
331
  columns.push(columnMethod);
@@ -275,36 +351,67 @@ function schemaToBlueprint(schema, allSchemas) {
275
351
  columns.push(generateSoftDeleteColumn());
276
352
  }
277
353
  if (schema.options?.indexes) {
354
+ const propToColName = (propName) => {
355
+ const colName = toColumnName(propName);
356
+ const prop = schema.properties?.[propName];
357
+ if (prop?.type === "Association") {
358
+ const assoc = prop;
359
+ if ((assoc.relation === "ManyToOne" || assoc.relation === "OneToOne") && !assoc.mappedBy) {
360
+ return colName + "_id";
361
+ }
362
+ }
363
+ return colName;
364
+ };
278
365
  for (const index of schema.options.indexes) {
279
366
  if (typeof index === "string") {
280
367
  indexes.push({
281
- columns: [toColumnName(index)],
368
+ columns: [propToColName(index)],
282
369
  unique: false
283
370
  });
284
371
  } else {
285
372
  indexes.push({
286
373
  name: index.name,
287
- columns: index.columns.map(toColumnName),
374
+ columns: index.columns.map(propToColName),
288
375
  unique: index.unique ?? false
289
376
  });
290
377
  }
291
378
  }
292
379
  }
293
380
  if (schema.options?.unique) {
381
+ const propToColName = (propName) => {
382
+ const colName = toColumnName(propName);
383
+ const prop = schema.properties?.[propName];
384
+ if (prop?.type === "Association") {
385
+ const assoc = prop;
386
+ if ((assoc.relation === "ManyToOne" || assoc.relation === "OneToOne") && !assoc.mappedBy) {
387
+ return colName + "_id";
388
+ }
389
+ }
390
+ return colName;
391
+ };
294
392
  const uniqueConstraints = Array.isArray(schema.options.unique[0]) ? schema.options.unique : [schema.options.unique];
295
393
  for (const constraint of uniqueConstraints) {
296
394
  indexes.push({
297
- columns: constraint.map(toColumnName),
395
+ columns: constraint.map(propToColName),
298
396
  unique: true
299
397
  });
300
398
  }
301
399
  }
400
+ const seenIndexes = /* @__PURE__ */ new Set();
401
+ const uniqueIndexes = indexes.filter((idx) => {
402
+ const key = idx.columns.join(",") + (idx.unique ? ":unique" : "");
403
+ if (seenIndexes.has(key)) {
404
+ return false;
405
+ }
406
+ seenIndexes.add(key);
407
+ return true;
408
+ });
302
409
  return {
303
410
  tableName,
304
411
  columns,
305
412
  primaryKey: ["id"],
306
413
  foreignKeys,
307
- indexes
414
+ indexes: uniqueIndexes
308
415
  };
309
416
  }
310
417
  function formatColumnMethod(column) {
@@ -665,7 +772,9 @@ function generateMigrations(schemas, options = {}) {
665
772
  const timestamp = options.timestamp ?? generateTimestamp();
666
773
  const offsetTimestamp = incrementTimestamp(timestamp, timestampOffset);
667
774
  timestampOffset++;
668
- const blueprint = schemaToBlueprint(schema, schemas);
775
+ const blueprint = schemaToBlueprint(schema, schemas, {
776
+ customTypes: options.customTypes
777
+ });
669
778
  const migration = generateCreateMigration(blueprint, {
670
779
  ...options,
671
780
  timestamp: offsetTimestamp
@@ -743,6 +852,7 @@ var TYPE_METHOD_MAP2 = {
743
852
  LongText: "longText",
744
853
  Date: "date",
745
854
  Time: "time",
855
+ DateTime: "dateTime",
746
856
  Timestamp: "timestamp",
747
857
  Json: "json",
748
858
  Email: "string",
@@ -2023,6 +2133,24 @@ function getFactoryPath(factory) {
2023
2133
  }
2024
2134
 
2025
2135
  // src/plugin.ts
2136
+ function getExistingMigrationTables(migrationsDir) {
2137
+ const existingTables = /* @__PURE__ */ new Set();
2138
+ if (!existsSync(migrationsDir)) {
2139
+ return existingTables;
2140
+ }
2141
+ try {
2142
+ const files = readdirSync(migrationsDir);
2143
+ const createMigrationPattern = /^\d{4}_\d{2}_\d{2}_\d{6}_create_(.+)_table\.php$/;
2144
+ for (const file of files) {
2145
+ const match = file.match(createMigrationPattern);
2146
+ if (match) {
2147
+ existingTables.add(match[1]);
2148
+ }
2149
+ }
2150
+ } catch {
2151
+ }
2152
+ return existingTables;
2153
+ }
2026
2154
  var LARAVEL_CONFIG_SCHEMA = {
2027
2155
  fields: [
2028
2156
  {
@@ -2106,18 +2234,81 @@ function laravelPlugin(options) {
2106
2234
  generate: async (ctx) => {
2107
2235
  const migrationOptions = {
2108
2236
  connection: resolved.connection,
2109
- timestamp: resolved.timestamp
2237
+ timestamp: resolved.timestamp,
2238
+ customTypes: ctx.customTypes
2110
2239
  };
2111
- const migrations = generateMigrations(ctx.schemas, migrationOptions);
2112
- return migrations.map((migration) => ({
2113
- path: getMigrationPath(migration, resolved.migrationsPath),
2114
- content: migration.content,
2115
- type: "migration",
2116
- metadata: {
2117
- tableName: migration.tables[0],
2118
- migrationType: migration.type
2240
+ const outputs = [];
2241
+ const migrationsDir = join(ctx.cwd, resolved.migrationsPath);
2242
+ const existingTables = getExistingMigrationTables(migrationsDir);
2243
+ if (ctx.changes !== void 0) {
2244
+ if (ctx.changes.length === 0) {
2245
+ return outputs;
2119
2246
  }
2120
- }));
2247
+ const addedSchemaNames = new Set(
2248
+ ctx.changes.filter((c) => c.changeType === "added").map((c) => c.schemaName)
2249
+ );
2250
+ if (addedSchemaNames.size > 0) {
2251
+ const addedSchemas = Object.fromEntries(
2252
+ Object.entries(ctx.schemas).filter(([name]) => addedSchemaNames.has(name))
2253
+ );
2254
+ const createMigrations = generateMigrations(addedSchemas, migrationOptions);
2255
+ for (const migration of createMigrations) {
2256
+ const tableName = migration.tables[0];
2257
+ if (existingTables.has(tableName)) {
2258
+ ctx.logger.debug(`Skipping CREATE for ${tableName} (already exists)`);
2259
+ continue;
2260
+ }
2261
+ outputs.push({
2262
+ path: getMigrationPath(migration, resolved.migrationsPath),
2263
+ content: migration.content,
2264
+ type: "migration",
2265
+ metadata: {
2266
+ tableName,
2267
+ migrationType: "create"
2268
+ }
2269
+ });
2270
+ }
2271
+ }
2272
+ const alterChanges = ctx.changes.filter(
2273
+ (c) => c.changeType === "modified" || c.changeType === "removed"
2274
+ );
2275
+ if (alterChanges.length > 0) {
2276
+ const alterMigrations = generateMigrationsFromChanges(
2277
+ alterChanges,
2278
+ migrationOptions
2279
+ );
2280
+ for (const migration of alterMigrations) {
2281
+ outputs.push({
2282
+ path: getMigrationPath(migration, resolved.migrationsPath),
2283
+ content: migration.content,
2284
+ type: "migration",
2285
+ metadata: {
2286
+ tableName: migration.tables[0],
2287
+ migrationType: migration.type
2288
+ }
2289
+ });
2290
+ }
2291
+ }
2292
+ } else {
2293
+ const migrations = generateMigrations(ctx.schemas, migrationOptions);
2294
+ for (const migration of migrations) {
2295
+ const tableName = migration.tables[0];
2296
+ if (migration.type === "create" && existingTables.has(tableName)) {
2297
+ ctx.logger.debug(`Skipping migration for ${tableName} (already exists)`);
2298
+ continue;
2299
+ }
2300
+ outputs.push({
2301
+ path: getMigrationPath(migration, resolved.migrationsPath),
2302
+ content: migration.content,
2303
+ type: "migration",
2304
+ metadata: {
2305
+ tableName,
2306
+ migrationType: migration.type
2307
+ }
2308
+ });
2309
+ }
2310
+ }
2311
+ return outputs;
2121
2312
  }
2122
2313
  };
2123
2314
  const modelGenerator = {
@@ -2243,4 +2434,4 @@ export {
2243
2434
  generateMigrationsFromChanges,
2244
2435
  laravelPlugin
2245
2436
  };
2246
- //# sourceMappingURL=chunk-CAWNYSF3.js.map
2437
+ //# sourceMappingURL=chunk-H37M25AK.js.map