prisma-laravel-migrate 3.1.1 → 3.1.3

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/cli/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
- import fs8, { readFile } from 'fs/promises';
3
+ import fs7, { readFile } from 'fs/promises';
4
4
  import path13, { resolve, extname, dirname } from 'path';
5
5
  import { fileURLToPath, pathToFileURL } from 'url';
6
6
  import fs, { existsSync, readdirSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
@@ -9,8 +9,8 @@ import { Minimatch } from 'minimatch';
9
9
  import * as diff3 from 'node-diff3';
10
10
  import * as prettier from 'prettier';
11
11
  import * as prettierPhp from '@prettier/plugin-php';
12
- import * as dmf2 from '@prisma/internals';
13
12
  import { spawn } from 'child_process';
13
+ import * as dmf from '@prisma/internals';
14
14
 
15
15
  function nearestPkgType(fromPath) {
16
16
  try {
@@ -377,17 +377,19 @@ var listFrom = (doc, tag) => {
377
377
  }
378
378
  return cleaned;
379
379
  };
380
- var FOLDER = "prisma-to-laravel-migration";
381
- function getStubPath(pathString) {
380
+ var FOLDER = "prisma-laravel-migrate";
381
+ function getStubPath(pathString, folder) {
382
382
  const __filename = fileURLToPath(import.meta.url);
383
383
  const __dirname = path13.dirname(__filename);
384
+ const __file = folder ?? FOLDER;
384
385
  const normalised = pathString.replace(/\\/g, "/");
385
386
  const dir = __dirname.replace(/\\/g, "/");
386
- const idx = dir.lastIndexOf(FOLDER);
387
+ const idx = dir.lastIndexOf(__file);
387
388
  if (idx === -1) {
389
+ if (!folder) return getStubPath(pathString, "prisma-to-laravel-migration");
388
390
  return path13.resolve(process.cwd(), normalised);
389
391
  }
390
- const baseDir = dir.slice(0, idx + FOLDER.length);
392
+ const baseDir = dir.slice(0, idx + __file.length);
391
393
  return path13.join(baseDir, "stubs", normalised);
392
394
  }
393
395
 
@@ -2634,6 +2636,22 @@ var TsPrinter = class {
2634
2636
  // ---------------------------------------------------------------------------
2635
2637
  // IMPORTS
2636
2638
  // ---------------------------------------------------------------------------
2639
+ normalizeTsImports(imports) {
2640
+ const grouped = /* @__PURE__ */ new Map();
2641
+ for (const imp of imports) {
2642
+ if (!imp.from) continue;
2643
+ const set = grouped.get(imp.from) ?? /* @__PURE__ */ new Set();
2644
+ for (const t of imp.types ?? []) {
2645
+ if (!t) continue;
2646
+ set.add(t);
2647
+ }
2648
+ grouped.set(imp.from, set);
2649
+ }
2650
+ return Array.from(grouped.entries()).map(([from, set]) => ({
2651
+ from,
2652
+ types: Array.from(set).sort()
2653
+ })).sort((a, b) => a.from.localeCompare(b.from));
2654
+ }
2637
2655
  /**
2638
2656
  * Render import statements for a node that has an `imports` property:
2639
2657
  * node.imports?: { from: string; types: string[] }[];
@@ -2643,7 +2661,7 @@ var TsPrinter = class {
2643
2661
  renderImports(node) {
2644
2662
  const imports = node.imports ?? [];
2645
2663
  if (!imports.length) return "";
2646
- return imports.map((i) => {
2664
+ return this.normalizeTsImports(imports).map((i) => {
2647
2665
  const names = i.types.join(", ");
2648
2666
  return `import { ${names} } from ${JSON.stringify(i.from)};`;
2649
2667
  }).join("\n");
@@ -2881,22 +2899,6 @@ function indentBlock(text, indent = " ") {
2881
2899
  function getDefaultTsOutDir(generator) {
2882
2900
  return generator?.output?.value ?? "resources/ts/prisma";
2883
2901
  }
2884
- async function loadMergedDatamodel(schemaPrismaPath) {
2885
- const schemaDir = path13.dirname(schemaPrismaPath);
2886
- const entries = readdirSync(schemaDir).filter(
2887
- (f) => f.endsWith(".prisma")
2888
- );
2889
- const order = [
2890
- // schema.prisma first
2891
- ...entries.filter((f) => f === "schema.prisma"),
2892
- // then the rest alphabetically
2893
- ...entries.filter((f) => f !== "schema.prisma").sort()
2894
- ];
2895
- const chunks = await Promise.all(
2896
- order.map((f) => fs8.readFile(path13.join(schemaDir, f), "utf-8"))
2897
- );
2898
- return chunks.join("\n\n");
2899
- }
2900
2902
  function hasModelSpecificTsStub(model, cfg) {
2901
2903
  if (!cfg.stubDir) return false;
2902
2904
  const key = model.tableName && typeof model.tableName === "string" ? model.tableName : model.name;
@@ -2912,17 +2914,13 @@ function hasModelSpecificTsStub(model, cfg) {
2912
2914
  return path13.basename(stubPath) !== "index.stub";
2913
2915
  }
2914
2916
  async function generateTypesFromPrisma(options) {
2915
- const { generator } = options;
2917
+ const { dmmf, generator } = options;
2916
2918
  const raw = generator.config ?? {};
2917
- const schemaPrismaPath = options.schemaPath;
2918
- const schemaDir = path13.dirname(schemaPrismaPath);
2919
+ const schemaDir = path13.dirname(options.schemaPath);
2919
2920
  const shared = await loadSharedConfig(schemaDir);
2920
2921
  let groups = [];
2921
2922
  if (raw["groups"]) {
2922
- const groupsModulePath = path13.resolve(
2923
- process.cwd(),
2924
- raw["groups"]
2925
- );
2923
+ const groupsModulePath = path13.resolve(process.cwd(), raw["groups"]);
2926
2924
  const importedModule = await import(groupsModulePath);
2927
2925
  const imported = importedModule.default ?? importedModule;
2928
2926
  if (!Array.isArray(imported)) {
@@ -2933,14 +2931,14 @@ async function generateTypesFromPrisma(options) {
2933
2931
  groups = imported;
2934
2932
  }
2935
2933
  const pick = (key, fallback) => (
2936
- // prisma-laravel.config.ts -> ts: {}
2934
+ // shared.ts section (if present)
2937
2935
  shared.ts?.[key] ?? // shared root (if you keep ts props there)
2938
2936
  shared[key] ?? // generator block config
2939
2937
  raw[key] ?? // explicit fallback
2940
2938
  fallback
2941
2939
  );
2942
2940
  const cfg = {
2943
- // base Laravel-ish generator knobs
2941
+ // Laravel-ish generator knobs
2944
2942
  overwriteExisting: pick("overwriteExisting", true),
2945
2943
  prettier: pick("prettier", false),
2946
2944
  noEmit: pick("noEmit", false),
@@ -2952,6 +2950,11 @@ async function generateTypesFromPrisma(options) {
2952
2950
  groups,
2953
2951
  // TS-specific
2954
2952
  outputDir: pick("outputDir") ?? getDefaultTsOutDir(generator),
2953
+ /**
2954
+ * declaration now only affects enums:
2955
+ * - true → enums.d.ts
2956
+ * - false → enums.ts
2957
+ */
2955
2958
  declaration: pick("declaration", false),
2956
2959
  shape: pick("shape", "interface"),
2957
2960
  scalarMap: pick("scalarMap"),
@@ -2959,7 +2962,9 @@ async function generateTypesFromPrisma(options) {
2959
2962
  readonlyArrays: pick("readonlyArrays", false),
2960
2963
  namePrefix: pick("namePrefix", ""),
2961
2964
  nameSuffix: pick("nameSuffix", ""),
2962
- moduleName: pick("moduleName", "database/prisma")
2965
+ moduleName: pick("moduleName", "database/prisma"),
2966
+ modelsFileName: pick("modelsFileName", "index"),
2967
+ enumsFileName: pick("enumsFileName", "enums")
2963
2968
  };
2964
2969
  const tsOutDir = path13.resolve(process.cwd(), cfg.outputDir);
2965
2970
  if (!existsSync(tsOutDir)) {
@@ -2969,9 +2974,6 @@ async function generateTypesFromPrisma(options) {
2969
2974
  global._config.ts = {
2970
2975
  prettier: !!cfg.prettier
2971
2976
  };
2972
- const datamodel = await loadMergedDatamodel(schemaPrismaPath);
2973
- const sdk = dmf2.default ?? dmf2;
2974
- const { dmmf } = await sdk.getDMMF({ datamodel });
2975
2977
  const tsGen = new PrismaToTypesGenerator(dmmf, cfg);
2976
2978
  const {
2977
2979
  models,
@@ -2992,11 +2994,15 @@ async function generateTypesFromPrisma(options) {
2992
2994
  moduleName: cfg.moduleName,
2993
2995
  shape: cfg.shape
2994
2996
  });
2995
- const ext = cfg.declaration ? ".d.ts" : ".ts";
2997
+ const modelExt = ".d.ts";
2998
+ const enumExt = cfg.declaration ? ".d.ts" : ".ts";
2996
2999
  if (enums.length) {
2997
3000
  const enumsCode = printer.printEnums(enums);
2998
3001
  if (enumsCode.trim()) {
2999
- const enumsPath = path13.join(tsOutDir, `enums${ext}`);
3002
+ const enumsPath = path13.join(
3003
+ tsOutDir,
3004
+ `${cfg.enumsFileName ?? "enums"}${enumExt}`
3005
+ );
3000
3006
  await writeWithMerge(
3001
3007
  enumsPath,
3002
3008
  enumsCode,
@@ -3016,7 +3022,10 @@ async function generateTypesFromPrisma(options) {
3016
3022
  );
3017
3023
  }
3018
3024
  if (mainFile.trim()) {
3019
- const mainPath = path13.join(tsOutDir, `index${ext}`);
3025
+ const mainPath = path13.join(
3026
+ tsOutDir,
3027
+ `${cfg.modelsFileName ?? "index"}${modelExt}`
3028
+ );
3020
3029
  await writeWithMerge(
3021
3030
  mainPath,
3022
3031
  mainFile,
@@ -3030,7 +3039,7 @@ async function generateTypesFromPrisma(options) {
3030
3039
  const decoratedName = `${cfg.namePrefix ?? ""}${model.name}${cfg.nameSuffix ?? ""}`;
3031
3040
  const filePath = path13.join(
3032
3041
  tsOutDir,
3033
- `${decoratedName}${ext}`
3042
+ `${decoratedName}${modelExt}`
3034
3043
  );
3035
3044
  await writeWithMerge(
3036
3045
  filePath,
@@ -3041,18 +3050,18 @@ async function generateTypesFromPrisma(options) {
3041
3050
  });
3042
3051
  return { models, enums, config: cfg };
3043
3052
  }
3044
- async function loadMergedDatamodel2(schemaPrismaPath) {
3053
+ async function loadMergedDatamodel(schemaPrismaPath) {
3045
3054
  const schemaDir = path13.dirname(schemaPrismaPath);
3046
3055
  const entries = readdirSync(schemaDir).filter((f) => f.endsWith(".prisma"));
3047
3056
  const order = [
3048
3057
  ...entries.filter((f) => f === "schema.prisma"),
3049
3058
  ...entries.filter((f) => f !== "schema.prisma").sort()
3050
3059
  ];
3051
- const chunks = await Promise.all(order.map((f) => fs8.readFile(path13.join(schemaDir, f), "utf-8")));
3060
+ const chunks = await Promise.all(order.map((f) => fs7.readFile(path13.join(schemaDir, f), "utf-8")));
3052
3061
  return chunks.join("\n\n");
3053
3062
  }
3054
3063
  async function getLaravelGeneratorConfigs(datamodel) {
3055
- const sdk = dmf2.default ?? dmf2;
3064
+ const sdk = dmf.default ?? dmf;
3056
3065
  const { generators } = await sdk.getConfig({ datamodel });
3057
3066
  const findCfg = (provider) => (generators ?? []).find((g) => (g.provider?.value ?? "") === provider)?.config ?? {};
3058
3067
  const migCfg = findCfg("prisma-laravel-migrations");
@@ -3073,9 +3082,9 @@ async function runGenerators(configPath, skipPrismaGenerate = false) {
3073
3082
  throw new Error(`Schema not found: ${schemaPrismaPath}`);
3074
3083
  }
3075
3084
  const doRun = async () => {
3076
- const datamodel = await loadMergedDatamodel2(schemaPrismaPath);
3085
+ const datamodel = await loadMergedDatamodel(schemaPrismaPath);
3077
3086
  const { migCfg, modCfg, tsCfg } = await getLaravelGeneratorConfigs(datamodel);
3078
- const sdk = dmf2.default ?? dmf2;
3087
+ const sdk = dmf.default ?? dmf;
3079
3088
  const dmmf = await sdk.getDMMF({ datamodel });
3080
3089
  const config = (conf) => {
3081
3090
  return {
@@ -3133,7 +3142,7 @@ cli.command("init").description("Inject generators into schema.prisma and scaffo
3133
3142
  const stubDirRel = "./" + path13.relative(process.cwd(), userStubs).replace(/\\/g, "/");
3134
3143
  const __dirname = path13.dirname(fileURLToPath(import.meta.url));
3135
3144
  const pkgStubs = path13.resolve(__dirname, "../../stubs");
3136
- let schema = await fs8.readFile(schemaPath, "utf-8");
3145
+ let schema = await fs7.readFile(schemaPath, "utf-8");
3137
3146
  const hasGenBlock = (name) => new RegExp(`generator\\s+${name}\\s*\\{`).test(schema);
3138
3147
  const hasMigrationsGen = hasGenBlock("migrations");
3139
3148
  const hasModelsGen = hasGenBlock("models");
@@ -3159,24 +3168,24 @@ generator types {
3159
3168
  `;
3160
3169
  console.log("\u27A1\uFE0F Added types generator");
3161
3170
  }
3162
- await fs8.writeFile(schemaPath, schema, "utf-8");
3171
+ await fs7.writeFile(schemaPath, schema, "utf-8");
3163
3172
  console.log(`\u2705 Updated ${schemaPath}`);
3164
3173
  const stubTypes = ["migration", "model", "enum"];
3165
3174
  for (const type of stubTypes) {
3166
3175
  const targetDir = path13.join(userStubs, type);
3167
- await fs8.mkdir(targetDir, { recursive: true });
3176
+ await fs7.mkdir(targetDir, { recursive: true });
3168
3177
  const src = path13.join(pkgStubs, `${type}.stub`);
3169
3178
  const dst = path13.join(targetDir, "index.stub");
3170
3179
  try {
3171
- await fs8.access(dst);
3180
+ await fs7.access(dst);
3172
3181
  } catch {
3173
- await fs8.copyFile(src, dst);
3182
+ await fs7.copyFile(src, dst);
3174
3183
  console.log(`\u27A1\uFE0F Copied ${type}.stub \u2192 stubs/${type}/index.stub`);
3175
3184
  }
3176
3185
  }
3177
3186
  const cfgPath = path13.join(schemaDir, "prisma-laravel.config.js");
3178
3187
  try {
3179
- await fs8.access(cfgPath);
3188
+ await fs7.access(cfgPath);
3180
3189
  } catch {
3181
3190
  const cfgTemplate = `
3182
3191
  // prisma/prisma-laravel.config.js
@@ -3200,7 +3209,7 @@ module.exports = {
3200
3209
 
3201
3210
  };
3202
3211
  `;
3203
- await fs8.writeFile(cfgPath, cfgTemplate.trimStart(), "utf-8");
3212
+ await fs7.writeFile(cfgPath, cfgTemplate.trimStart(), "utf-8");
3204
3213
  console.log("\u27A1\uFE0F Created prisma-laravel.config.js");
3205
3214
  }
3206
3215
  console.log("\u{1F389} Initialization complete!");
@@ -3244,14 +3253,14 @@ cli.command("customize").alias("c").description("Scaffold per-table stub files f
3244
3253
  if (t === "enum") {
3245
3254
  const dir = path13.join(stubRoot, "enum");
3246
3255
  const idx = resolveStubIndex("enum");
3247
- await fs8.mkdir(dir, { recursive: true });
3256
+ await fs7.mkdir(dir, { recursive: true });
3248
3257
  for (const name of bases) {
3249
3258
  const dst = path13.join(dir, `${name}.stub`);
3250
3259
  try {
3251
- await fs8.access(dst);
3260
+ await fs7.access(dst);
3252
3261
  console.log(`\u{1F7E1} Skip enum/${name}.stub`);
3253
3262
  } catch {
3254
- await fs8.copyFile(idx, dst);
3263
+ await fs7.copyFile(idx, dst);
3255
3264
  console.log(`\u2705 Created enum/${name}.stub`);
3256
3265
  }
3257
3266
  }
@@ -3260,14 +3269,14 @@ cli.command("customize").alias("c").description("Scaffold per-table stub files f
3260
3269
  if (t === "ts") {
3261
3270
  const dir = path13.join(stubRoot, "ts");
3262
3271
  const idx = resolveStubIndex("ts");
3263
- await fs8.mkdir(dir, { recursive: true });
3272
+ await fs7.mkdir(dir, { recursive: true });
3264
3273
  for (const base of bases) {
3265
3274
  const dst = path13.join(dir, `${base}.stub`);
3266
3275
  try {
3267
- await fs8.access(dst);
3276
+ await fs7.access(dst);
3268
3277
  console.log(`\u{1F7E1} Skip ts/${base}.stub`);
3269
3278
  } catch {
3270
- await fs8.copyFile(idx, dst);
3279
+ await fs7.copyFile(idx, dst);
3271
3280
  console.log(`\u2705 Created ts/${base}.stub`);
3272
3281
  }
3273
3282
  }
@@ -3276,14 +3285,14 @@ cli.command("customize").alias("c").description("Scaffold per-table stub files f
3276
3285
  for (const kind of doBoth ? ["migration", "model"] : [t]) {
3277
3286
  const dir = path13.join(stubRoot, kind);
3278
3287
  const idx = resolveStubIndex(kind);
3279
- await fs8.mkdir(dir, { recursive: true });
3288
+ await fs7.mkdir(dir, { recursive: true });
3280
3289
  for (const base of bases) {
3281
3290
  const dst = path13.join(dir, `${base}.stub`);
3282
3291
  try {
3283
- await fs8.access(dst);
3292
+ await fs7.access(dst);
3284
3293
  console.log(`\u{1F7E1} Skip ${kind}/${base}.stub`);
3285
3294
  } catch {
3286
- await fs8.copyFile(idx, dst);
3295
+ await fs7.copyFile(idx, dst);
3287
3296
  console.log(`\u2705 Created ${kind}/${base}.stub`);
3288
3297
  }
3289
3298
  }
@@ -3456,7 +3465,7 @@ cli.command("clean").description(
3456
3465
  const rmIfExists = async (p) => {
3457
3466
  if (!p || !existsSync(p)) return false;
3458
3467
  try {
3459
- await fs8.unlink(p);
3468
+ await fs7.unlink(p);
3460
3469
  return true;
3461
3470
  } catch {
3462
3471
  return false;
@@ -3496,7 +3505,7 @@ cli.command("clean").description(
3496
3505
  }
3497
3506
  if (allRemoved) {
3498
3507
  try {
3499
- await fs8.rmdir(dir);
3508
+ await fs7.rmdir(dir);
3500
3509
  return true;
3501
3510
  } catch {
3502
3511
  return false;
@@ -288,17 +288,19 @@ var listFrom = (doc, tag) => {
288
288
  }
289
289
  return cleaned;
290
290
  };
291
- var FOLDER = "prisma-to-laravel-migration";
292
- function getStubPath(pathString) {
291
+ var FOLDER = "prisma-laravel-migrate";
292
+ function getStubPath(pathString, folder) {
293
293
  const __filename = fileURLToPath(import.meta.url);
294
294
  const __dirname = path7.dirname(__filename);
295
+ const __file = folder ?? FOLDER;
295
296
  const normalised = pathString.replace(/\\/g, "/");
296
297
  const dir = __dirname.replace(/\\/g, "/");
297
- const idx = dir.lastIndexOf(FOLDER);
298
+ const idx = dir.lastIndexOf(__file);
298
299
  if (idx === -1) {
300
+ if (!folder) return getStubPath(pathString, "prisma-to-laravel-migration");
299
301
  return path7.resolve(process.cwd(), normalised);
300
302
  }
301
- const baseDir = dir.slice(0, idx + FOLDER.length);
303
+ const baseDir = dir.slice(0, idx + __file.length);
302
304
  return path7.join(baseDir, "stubs", normalised);
303
305
  }
304
306
 
@@ -1270,10 +1272,26 @@ function formatLaravelTimestamp(date, seq, width) {
1270
1272
  var { generatorHandler } = helperPkg;
1271
1273
  generatorHandler({
1272
1274
  onGenerate: generateLaravelSchema,
1273
- onManifest: () => ({
1274
- defaultOutput: "./database/migrations",
1275
- prettyName: "Laravel Schema"
1276
- })
1275
+ async onManifest(options) {
1276
+ const cfg = options.config ?? {};
1277
+ let migrationsOutput;
1278
+ migrationsOutput = cfg.outputDir;
1279
+ if (!migrationsOutput && options.sourceFilePath) {
1280
+ try {
1281
+ const schemaDir = path7.dirname(options.sourceFilePath);
1282
+ const shared = await loadSharedConfig(schemaDir);
1283
+ migrationsOutput = shared?.migrate?.outputDir ?? shared?.output?.migrations ?? void 0;
1284
+ } catch {
1285
+ }
1286
+ }
1287
+ if (!migrationsOutput) {
1288
+ migrationsOutput = "database/migrations";
1289
+ }
1290
+ return {
1291
+ defaultOutput: migrationsOutput,
1292
+ prettyName: `Laravel Migration Schema (migrations \u2192 ${migrationsOutput})`
1293
+ };
1294
+ }
1277
1295
  });
1278
1296
  //# sourceMappingURL=migrator.index.js.map
1279
1297
  //# sourceMappingURL=migrator.index.js.map
@@ -125,17 +125,19 @@ var listFrom = (doc, tag) => {
125
125
  }
126
126
  return cleaned;
127
127
  };
128
- var FOLDER = "prisma-to-laravel-migration";
129
- function getStubPath(pathString) {
128
+ var FOLDER = "prisma-laravel-migrate";
129
+ function getStubPath(pathString, folder) {
130
130
  const __filename = fileURLToPath(import.meta.url);
131
131
  const __dirname = path7.dirname(__filename);
132
+ const __file = folder ?? FOLDER;
132
133
  const normalised = pathString.replace(/\\/g, "/");
133
134
  const dir = __dirname.replace(/\\/g, "/");
134
- const idx = dir.lastIndexOf(FOLDER);
135
+ const idx = dir.lastIndexOf(__file);
135
136
  if (idx === -1) {
137
+ if (!folder) return getStubPath(pathString, "prisma-to-laravel-migration");
136
138
  return path7.resolve(process.cwd(), normalised);
137
139
  }
138
- const baseDir = dir.slice(0, idx + FOLDER.length);
140
+ const baseDir = dir.slice(0, idx + __file.length);
139
141
  return path7.join(baseDir, "stubs", normalised);
140
142
  }
141
143
 
@@ -1340,10 +1342,34 @@ function getOutDir(generator) {
1340
1342
  var { generatorHandler } = helperPkg;
1341
1343
  generatorHandler({
1342
1344
  onGenerate: generateLaravelModels,
1343
- onManifest: () => ({
1344
- defaultOutput: "./database/migrations",
1345
- prettyName: "Laravel Schema"
1346
- })
1345
+ async onManifest(options) {
1346
+ const cfg = options.config ?? {};
1347
+ let modelOutput = cfg.outputDir;
1348
+ let enumOutput;
1349
+ if (options.sourceFilePath) {
1350
+ try {
1351
+ const schemaDir = path7.dirname(options.sourceFilePath);
1352
+ const shared = await loadSharedConfig(schemaDir);
1353
+ if (!modelOutput) {
1354
+ modelOutput = shared?.modeler?.outputDir ?? shared?.output?.models ?? void 0;
1355
+ }
1356
+ enumOutput = shared?.modeler?.outputEnumDir ?? shared?.output?.enums ?? void 0;
1357
+ } catch {
1358
+ }
1359
+ }
1360
+ if (!modelOutput) {
1361
+ modelOutput = "app/Models";
1362
+ }
1363
+ if (!enumOutput) {
1364
+ enumOutput = "app/Enums";
1365
+ }
1366
+ return {
1367
+ // Prisma can only use ONE path for the generator's output
1368
+ defaultOutput: modelOutput,
1369
+ // But we can loudly show BOTH model + enum destinations here
1370
+ prettyName: `Laravel Models & Enums (models \u2192 ${modelOutput}, enums \u2192 ${enumOutput})`
1371
+ };
1372
+ }
1347
1373
  });
1348
1374
  //# sourceMappingURL=models.index.js.map
1349
1375
  //# sourceMappingURL=models.index.js.map
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import path7, { resolve, extname, dirname } from 'path';
3
- import fs, { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
4
- import fs4, { readFile } from 'fs/promises';
5
- import * as dmf from '@prisma/internals';
3
+ import fs, { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
4
+ import { readFile } from 'fs/promises';
6
5
  import { createRequire } from 'module';
7
6
  import { pathToFileURL } from 'url';
8
7
  import { Minimatch } from 'minimatch';
@@ -481,6 +480,22 @@ var TsPrinter = class {
481
480
  // ---------------------------------------------------------------------------
482
481
  // IMPORTS
483
482
  // ---------------------------------------------------------------------------
483
+ normalizeTsImports(imports) {
484
+ const grouped = /* @__PURE__ */ new Map();
485
+ for (const imp of imports) {
486
+ if (!imp.from) continue;
487
+ const set = grouped.get(imp.from) ?? /* @__PURE__ */ new Set();
488
+ for (const t of imp.types ?? []) {
489
+ if (!t) continue;
490
+ set.add(t);
491
+ }
492
+ grouped.set(imp.from, set);
493
+ }
494
+ return Array.from(grouped.entries()).map(([from, set]) => ({
495
+ from,
496
+ types: Array.from(set).sort()
497
+ })).sort((a, b) => a.from.localeCompare(b.from));
498
+ }
484
499
  /**
485
500
  * Render import statements for a node that has an `imports` property:
486
501
  * node.imports?: { from: string; types: string[] }[];
@@ -490,7 +505,7 @@ var TsPrinter = class {
490
505
  renderImports(node) {
491
506
  const imports = node.imports ?? [];
492
507
  if (!imports.length) return "";
493
- return imports.map((i) => {
508
+ return this.normalizeTsImports(imports).map((i) => {
494
509
  const names = i.types.join(", ");
495
510
  return `import { ${names} } from ${JSON.stringify(i.from)};`;
496
511
  }).join("\n");
@@ -841,22 +856,6 @@ function safeUnlink(p) {
841
856
  function getDefaultTsOutDir(generator) {
842
857
  return generator?.output?.value ?? "resources/ts/prisma";
843
858
  }
844
- async function loadMergedDatamodel(schemaPrismaPath) {
845
- const schemaDir = path7.dirname(schemaPrismaPath);
846
- const entries = readdirSync(schemaDir).filter(
847
- (f) => f.endsWith(".prisma")
848
- );
849
- const order = [
850
- // schema.prisma first
851
- ...entries.filter((f) => f === "schema.prisma"),
852
- // then the rest alphabetically
853
- ...entries.filter((f) => f !== "schema.prisma").sort()
854
- ];
855
- const chunks = await Promise.all(
856
- order.map((f) => fs4.readFile(path7.join(schemaDir, f), "utf-8"))
857
- );
858
- return chunks.join("\n\n");
859
- }
860
859
  function hasModelSpecificTsStub(model, cfg) {
861
860
  if (!cfg.stubDir) return false;
862
861
  const key = model.tableName && typeof model.tableName === "string" ? model.tableName : model.name;
@@ -872,17 +871,13 @@ function hasModelSpecificTsStub(model, cfg) {
872
871
  return path7.basename(stubPath) !== "index.stub";
873
872
  }
874
873
  async function generateTypesFromPrisma(options) {
875
- const { generator } = options;
874
+ const { dmmf, generator } = options;
876
875
  const raw = generator.config ?? {};
877
- const schemaPrismaPath = options.schemaPath;
878
- const schemaDir = path7.dirname(schemaPrismaPath);
876
+ const schemaDir = path7.dirname(options.schemaPath);
879
877
  const shared = await loadSharedConfig(schemaDir);
880
878
  let groups = [];
881
879
  if (raw["groups"]) {
882
- const groupsModulePath = path7.resolve(
883
- process.cwd(),
884
- raw["groups"]
885
- );
880
+ const groupsModulePath = path7.resolve(process.cwd(), raw["groups"]);
886
881
  const importedModule = await import(groupsModulePath);
887
882
  const imported = importedModule.default ?? importedModule;
888
883
  if (!Array.isArray(imported)) {
@@ -893,14 +888,14 @@ async function generateTypesFromPrisma(options) {
893
888
  groups = imported;
894
889
  }
895
890
  const pick = (key, fallback) => (
896
- // prisma-laravel.config.ts -> ts: {}
891
+ // shared.ts section (if present)
897
892
  shared.ts?.[key] ?? // shared root (if you keep ts props there)
898
893
  shared[key] ?? // generator block config
899
894
  raw[key] ?? // explicit fallback
900
895
  fallback
901
896
  );
902
897
  const cfg = {
903
- // base Laravel-ish generator knobs
898
+ // Laravel-ish generator knobs
904
899
  overwriteExisting: pick("overwriteExisting", true),
905
900
  prettier: pick("prettier", false),
906
901
  noEmit: pick("noEmit", false),
@@ -912,6 +907,11 @@ async function generateTypesFromPrisma(options) {
912
907
  groups,
913
908
  // TS-specific
914
909
  outputDir: pick("outputDir") ?? getDefaultTsOutDir(generator),
910
+ /**
911
+ * declaration now only affects enums:
912
+ * - true → enums.d.ts
913
+ * - false → enums.ts
914
+ */
915
915
  declaration: pick("declaration", false),
916
916
  shape: pick("shape", "interface"),
917
917
  scalarMap: pick("scalarMap"),
@@ -919,7 +919,9 @@ async function generateTypesFromPrisma(options) {
919
919
  readonlyArrays: pick("readonlyArrays", false),
920
920
  namePrefix: pick("namePrefix", ""),
921
921
  nameSuffix: pick("nameSuffix", ""),
922
- moduleName: pick("moduleName", "database/prisma")
922
+ moduleName: pick("moduleName", "database/prisma"),
923
+ modelsFileName: pick("modelsFileName", "index"),
924
+ enumsFileName: pick("enumsFileName", "enums")
923
925
  };
924
926
  const tsOutDir = path7.resolve(process.cwd(), cfg.outputDir);
925
927
  if (!existsSync(tsOutDir)) {
@@ -929,9 +931,6 @@ async function generateTypesFromPrisma(options) {
929
931
  global._config.ts = {
930
932
  prettier: !!cfg.prettier
931
933
  };
932
- const datamodel = await loadMergedDatamodel(schemaPrismaPath);
933
- const sdk = dmf.default ?? dmf;
934
- const { dmmf } = await sdk.getDMMF({ datamodel });
935
934
  const tsGen = new PrismaToTypesGenerator(dmmf, cfg);
936
935
  const {
937
936
  models,
@@ -952,11 +951,15 @@ async function generateTypesFromPrisma(options) {
952
951
  moduleName: cfg.moduleName,
953
952
  shape: cfg.shape
954
953
  });
955
- const ext = cfg.declaration ? ".d.ts" : ".ts";
954
+ const modelExt = ".d.ts";
955
+ const enumExt = cfg.declaration ? ".d.ts" : ".ts";
956
956
  if (enums.length) {
957
957
  const enumsCode = printer.printEnums(enums);
958
958
  if (enumsCode.trim()) {
959
- const enumsPath = path7.join(tsOutDir, `enums${ext}`);
959
+ const enumsPath = path7.join(
960
+ tsOutDir,
961
+ `${cfg.enumsFileName ?? "enums"}${enumExt}`
962
+ );
960
963
  await writeWithMerge(
961
964
  enumsPath,
962
965
  enumsCode,
@@ -976,7 +979,10 @@ async function generateTypesFromPrisma(options) {
976
979
  );
977
980
  }
978
981
  if (mainFile.trim()) {
979
- const mainPath = path7.join(tsOutDir, `index${ext}`);
982
+ const mainPath = path7.join(
983
+ tsOutDir,
984
+ `${cfg.modelsFileName ?? "index"}${modelExt}`
985
+ );
980
986
  await writeWithMerge(
981
987
  mainPath,
982
988
  mainFile,
@@ -990,7 +996,7 @@ async function generateTypesFromPrisma(options) {
990
996
  const decoratedName = `${cfg.namePrefix ?? ""}${model.name}${cfg.nameSuffix ?? ""}`;
991
997
  const filePath = path7.join(
992
998
  tsOutDir,
993
- `${decoratedName}${ext}`
999
+ `${decoratedName}${modelExt}`
994
1000
  );
995
1001
  await writeWithMerge(
996
1002
  filePath,
@@ -1004,10 +1010,27 @@ async function generateTypesFromPrisma(options) {
1004
1010
  var { generatorHandler } = helperPkg;
1005
1011
  generatorHandler({
1006
1012
  onGenerate: generateTypesFromPrisma,
1007
- onManifest: () => ({
1008
- defaultOutput: "./resources/js/types",
1009
- prettyName: "Laravel Schema"
1010
- })
1013
+ async onManifest(options) {
1014
+ const cfg = options.config ?? {};
1015
+ let defaultOutput = cfg.outputDir;
1016
+ if (!defaultOutput && options.sourceFilePath) {
1017
+ try {
1018
+ const schemaDir = path7.dirname(options.sourceFilePath);
1019
+ const shared = await loadSharedConfig(schemaDir);
1020
+ if (shared && shared.ts) {
1021
+ defaultOutput = shared.ts.outputDir;
1022
+ }
1023
+ } catch {
1024
+ }
1025
+ }
1026
+ if (!defaultOutput) {
1027
+ defaultOutput = "resources/js/types";
1028
+ }
1029
+ return {
1030
+ defaultOutput,
1031
+ prettyName: "Typescript declarations"
1032
+ };
1033
+ }
1011
1034
  });
1012
1035
  //# sourceMappingURL=ts.index.js.map
1013
1036
  //# sourceMappingURL=ts.index.js.map
package/dist/index.js CHANGED
@@ -5,9 +5,8 @@ import { Minimatch } from 'minimatch';
5
5
  import * as diff3 from 'node-diff3';
6
6
  import * as prettier from 'prettier';
7
7
  import * as prettierPhp from '@prettier/plugin-php';
8
- import fs6, { readFile } from 'fs/promises';
8
+ import { readFile } from 'fs/promises';
9
9
  import { createRequire } from 'module';
10
- import * as dmf from '@prisma/internals';
11
10
 
12
11
  // src/generator/modeler/relationship/template-builder.ts
13
12
  var asArrayPhp = (xs) => `[${xs.map((x) => `'${x}'`).join(", ")}]`;
@@ -442,17 +441,19 @@ var listFrom = (doc, tag) => {
442
441
  }
443
442
  return cleaned;
444
443
  };
445
- var FOLDER = "prisma-to-laravel-migration";
446
- function getStubPath(pathString) {
444
+ var FOLDER = "prisma-laravel-migrate";
445
+ function getStubPath(pathString, folder) {
447
446
  const __filename = fileURLToPath(import.meta.url);
448
447
  const __dirname = path9.dirname(__filename);
448
+ const __file = folder ?? FOLDER;
449
449
  const normalised = pathString.replace(/\\/g, "/");
450
450
  const dir = __dirname.replace(/\\/g, "/");
451
- const idx = dir.lastIndexOf(FOLDER);
451
+ const idx = dir.lastIndexOf(__file);
452
452
  if (idx === -1) {
453
+ if (!folder) return getStubPath(pathString, "prisma-to-laravel-migration");
453
454
  return path9.resolve(process.cwd(), normalised);
454
455
  }
455
- const baseDir = dir.slice(0, idx + FOLDER.length);
456
+ const baseDir = dir.slice(0, idx + __file.length);
456
457
  return path9.join(baseDir, "stubs", normalised);
457
458
  }
458
459
 
@@ -2630,6 +2631,22 @@ var TsPrinter = class {
2630
2631
  // ---------------------------------------------------------------------------
2631
2632
  // IMPORTS
2632
2633
  // ---------------------------------------------------------------------------
2634
+ normalizeTsImports(imports) {
2635
+ const grouped = /* @__PURE__ */ new Map();
2636
+ for (const imp of imports) {
2637
+ if (!imp.from) continue;
2638
+ const set = grouped.get(imp.from) ?? /* @__PURE__ */ new Set();
2639
+ for (const t of imp.types ?? []) {
2640
+ if (!t) continue;
2641
+ set.add(t);
2642
+ }
2643
+ grouped.set(imp.from, set);
2644
+ }
2645
+ return Array.from(grouped.entries()).map(([from, set]) => ({
2646
+ from,
2647
+ types: Array.from(set).sort()
2648
+ })).sort((a, b) => a.from.localeCompare(b.from));
2649
+ }
2633
2650
  /**
2634
2651
  * Render import statements for a node that has an `imports` property:
2635
2652
  * node.imports?: { from: string; types: string[] }[];
@@ -2639,7 +2656,7 @@ var TsPrinter = class {
2639
2656
  renderImports(node) {
2640
2657
  const imports = node.imports ?? [];
2641
2658
  if (!imports.length) return "";
2642
- return imports.map((i) => {
2659
+ return this.normalizeTsImports(imports).map((i) => {
2643
2660
  const names = i.types.join(", ");
2644
2661
  return `import { ${names} } from ${JSON.stringify(i.from)};`;
2645
2662
  }).join("\n");
@@ -2877,22 +2894,6 @@ function indentBlock(text, indent = " ") {
2877
2894
  function getDefaultTsOutDir(generator) {
2878
2895
  return generator?.output?.value ?? "resources/ts/prisma";
2879
2896
  }
2880
- async function loadMergedDatamodel(schemaPrismaPath) {
2881
- const schemaDir = path9.dirname(schemaPrismaPath);
2882
- const entries = readdirSync(schemaDir).filter(
2883
- (f) => f.endsWith(".prisma")
2884
- );
2885
- const order = [
2886
- // schema.prisma first
2887
- ...entries.filter((f) => f === "schema.prisma"),
2888
- // then the rest alphabetically
2889
- ...entries.filter((f) => f !== "schema.prisma").sort()
2890
- ];
2891
- const chunks = await Promise.all(
2892
- order.map((f) => fs6.readFile(path9.join(schemaDir, f), "utf-8"))
2893
- );
2894
- return chunks.join("\n\n");
2895
- }
2896
2897
  function hasModelSpecificTsStub(model, cfg) {
2897
2898
  if (!cfg.stubDir) return false;
2898
2899
  const key = model.tableName && typeof model.tableName === "string" ? model.tableName : model.name;
@@ -2908,17 +2909,13 @@ function hasModelSpecificTsStub(model, cfg) {
2908
2909
  return path9.basename(stubPath) !== "index.stub";
2909
2910
  }
2910
2911
  async function generateTypesFromPrisma(options) {
2911
- const { generator } = options;
2912
+ const { dmmf, generator } = options;
2912
2913
  const raw = generator.config ?? {};
2913
- const schemaPrismaPath = options.schemaPath;
2914
- const schemaDir = path9.dirname(schemaPrismaPath);
2914
+ const schemaDir = path9.dirname(options.schemaPath);
2915
2915
  const shared = await loadSharedConfig(schemaDir);
2916
2916
  let groups = [];
2917
2917
  if (raw["groups"]) {
2918
- const groupsModulePath = path9.resolve(
2919
- process.cwd(),
2920
- raw["groups"]
2921
- );
2918
+ const groupsModulePath = path9.resolve(process.cwd(), raw["groups"]);
2922
2919
  const importedModule = await import(groupsModulePath);
2923
2920
  const imported = importedModule.default ?? importedModule;
2924
2921
  if (!Array.isArray(imported)) {
@@ -2929,14 +2926,14 @@ async function generateTypesFromPrisma(options) {
2929
2926
  groups = imported;
2930
2927
  }
2931
2928
  const pick = (key, fallback) => (
2932
- // prisma-laravel.config.ts -> ts: {}
2929
+ // shared.ts section (if present)
2933
2930
  shared.ts?.[key] ?? // shared root (if you keep ts props there)
2934
2931
  shared[key] ?? // generator block config
2935
2932
  raw[key] ?? // explicit fallback
2936
2933
  fallback
2937
2934
  );
2938
2935
  const cfg = {
2939
- // base Laravel-ish generator knobs
2936
+ // Laravel-ish generator knobs
2940
2937
  overwriteExisting: pick("overwriteExisting", true),
2941
2938
  prettier: pick("prettier", false),
2942
2939
  noEmit: pick("noEmit", false),
@@ -2948,6 +2945,11 @@ async function generateTypesFromPrisma(options) {
2948
2945
  groups,
2949
2946
  // TS-specific
2950
2947
  outputDir: pick("outputDir") ?? getDefaultTsOutDir(generator),
2948
+ /**
2949
+ * declaration now only affects enums:
2950
+ * - true → enums.d.ts
2951
+ * - false → enums.ts
2952
+ */
2951
2953
  declaration: pick("declaration", false),
2952
2954
  shape: pick("shape", "interface"),
2953
2955
  scalarMap: pick("scalarMap"),
@@ -2955,7 +2957,9 @@ async function generateTypesFromPrisma(options) {
2955
2957
  readonlyArrays: pick("readonlyArrays", false),
2956
2958
  namePrefix: pick("namePrefix", ""),
2957
2959
  nameSuffix: pick("nameSuffix", ""),
2958
- moduleName: pick("moduleName", "database/prisma")
2960
+ moduleName: pick("moduleName", "database/prisma"),
2961
+ modelsFileName: pick("modelsFileName", "index"),
2962
+ enumsFileName: pick("enumsFileName", "enums")
2959
2963
  };
2960
2964
  const tsOutDir = path9.resolve(process.cwd(), cfg.outputDir);
2961
2965
  if (!existsSync(tsOutDir)) {
@@ -2965,9 +2969,6 @@ async function generateTypesFromPrisma(options) {
2965
2969
  global._config.ts = {
2966
2970
  prettier: !!cfg.prettier
2967
2971
  };
2968
- const datamodel = await loadMergedDatamodel(schemaPrismaPath);
2969
- const sdk = dmf.default ?? dmf;
2970
- const { dmmf } = await sdk.getDMMF({ datamodel });
2971
2972
  const tsGen = new PrismaToTypesGenerator(dmmf, cfg);
2972
2973
  const {
2973
2974
  models,
@@ -2988,11 +2989,15 @@ async function generateTypesFromPrisma(options) {
2988
2989
  moduleName: cfg.moduleName,
2989
2990
  shape: cfg.shape
2990
2991
  });
2991
- const ext = cfg.declaration ? ".d.ts" : ".ts";
2992
+ const modelExt = ".d.ts";
2993
+ const enumExt = cfg.declaration ? ".d.ts" : ".ts";
2992
2994
  if (enums.length) {
2993
2995
  const enumsCode = printer.printEnums(enums);
2994
2996
  if (enumsCode.trim()) {
2995
- const enumsPath = path9.join(tsOutDir, `enums${ext}`);
2997
+ const enumsPath = path9.join(
2998
+ tsOutDir,
2999
+ `${cfg.enumsFileName ?? "enums"}${enumExt}`
3000
+ );
2996
3001
  await writeWithMerge(
2997
3002
  enumsPath,
2998
3003
  enumsCode,
@@ -3012,7 +3017,10 @@ async function generateTypesFromPrisma(options) {
3012
3017
  );
3013
3018
  }
3014
3019
  if (mainFile.trim()) {
3015
- const mainPath = path9.join(tsOutDir, `index${ext}`);
3020
+ const mainPath = path9.join(
3021
+ tsOutDir,
3022
+ `${cfg.modelsFileName ?? "index"}${modelExt}`
3023
+ );
3016
3024
  await writeWithMerge(
3017
3025
  mainPath,
3018
3026
  mainFile,
@@ -3026,7 +3034,7 @@ async function generateTypesFromPrisma(options) {
3026
3034
  const decoratedName = `${cfg.namePrefix ?? ""}${model.name}${cfg.nameSuffix ?? ""}`;
3027
3035
  const filePath = path9.join(
3028
3036
  tsOutDir,
3029
- `${decoratedName}${ext}`
3037
+ `${decoratedName}${modelExt}`
3030
3038
  );
3031
3039
  await writeWithMerge(
3032
3040
  filePath,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prisma-laravel-migrate",
3
- "version": "3.1.1",
3
+ "version": "3.1.3",
4
4
  "description": "Generate laravel migrations and/or models using prisma files",
5
5
  "bin": {
6
6
  "prisma-laravel-migrations": "./dist/cli/migrator.index.js",