@invect/cli 0.1.1 → 0.1.2

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.
@@ -3,18 +3,169 @@ import {
3
3
  generateAppendSchema,
4
4
  generatePrismaSchema
5
5
  } from "./chunk-K4RRNATQ.js";
6
- import {
7
- findConfigPath,
8
- loadConfig
9
- } from "./chunk-Q6JKV7VX.js";
10
6
 
11
7
  // src/commands/generate.ts
12
8
  import { Command } from "commander";
9
+ import path2 from "path";
10
+ import fs2 from "fs";
11
+ import pc2 from "picocolors";
12
+ import prompts from "prompts";
13
+ import { execSync } from "child_process";
14
+
15
+ // src/utils/config-loader.ts
13
16
  import path from "path";
14
17
  import fs from "fs";
15
18
  import pc from "picocolors";
16
- import prompts from "prompts";
17
- import { execSync } from "child_process";
19
+ var CONFIG_FILENAMES = [
20
+ "invect.config.ts",
21
+ "invect.config.js",
22
+ "invect.config.mjs"
23
+ ];
24
+ var CONFIG_DIRECTORIES = [".", "src", "lib", "config", "utils"];
25
+ function findConfigPath(explicitPath) {
26
+ if (explicitPath) {
27
+ const resolved = path.resolve(process.cwd(), explicitPath);
28
+ if (fs.existsSync(resolved)) {
29
+ return resolved;
30
+ }
31
+ return null;
32
+ }
33
+ for (const dir of CONFIG_DIRECTORIES) {
34
+ for (const filename of CONFIG_FILENAMES) {
35
+ const candidate = path.resolve(process.cwd(), dir, filename);
36
+ if (fs.existsSync(candidate)) {
37
+ return candidate;
38
+ }
39
+ }
40
+ }
41
+ return null;
42
+ }
43
+ function stripJsonComments(jsonString) {
44
+ return jsonString.replace(
45
+ /\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g,
46
+ (m, g) => g ? "" : m
47
+ ).replace(/,(?=\s*[}\]])/g, "");
48
+ }
49
+ function getPathAliases(cwd) {
50
+ let tsConfigPath = path.join(cwd, "tsconfig.json");
51
+ if (!fs.existsSync(tsConfigPath)) {
52
+ tsConfigPath = path.join(cwd, "jsconfig.json");
53
+ }
54
+ if (!fs.existsSync(tsConfigPath)) {
55
+ return null;
56
+ }
57
+ try {
58
+ const result = getPathAliasesRecursive(tsConfigPath, /* @__PURE__ */ new Set());
59
+ return Object.keys(result).length > 0 ? result : null;
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
64
+ function getPathAliasesRecursive(configPath, visited) {
65
+ const resolvedPath = path.resolve(configPath);
66
+ if (visited.has(resolvedPath)) return {};
67
+ visited.add(resolvedPath);
68
+ if (!fs.existsSync(resolvedPath)) return {};
69
+ let tsConfig;
70
+ try {
71
+ const text = fs.readFileSync(resolvedPath, "utf-8");
72
+ tsConfig = JSON.parse(stripJsonComments(text));
73
+ } catch {
74
+ return {};
75
+ }
76
+ const result = {};
77
+ const compilerOptions = tsConfig.compilerOptions;
78
+ const paths = compilerOptions?.paths;
79
+ const baseUrl = compilerOptions?.baseUrl;
80
+ const configDir = path.dirname(resolvedPath);
81
+ if (paths) {
82
+ for (const [alias, targets] of Object.entries(paths)) {
83
+ if (typeof alias === "string" && alias.endsWith("/*") && Array.isArray(targets) && targets.length > 0) {
84
+ const aliasPrefix = alias.slice(0, -2);
85
+ const targetDir = targets[0].replace(/\/\*$/, "");
86
+ const resolvedTarget = baseUrl ? path.resolve(configDir, baseUrl, targetDir) : path.resolve(configDir, targetDir);
87
+ result[aliasPrefix] = resolvedTarget;
88
+ }
89
+ }
90
+ }
91
+ const references = tsConfig.references;
92
+ if (references) {
93
+ for (const ref of references) {
94
+ const refPath = path.resolve(configDir, ref.path);
95
+ const refConfigPath = refPath.endsWith(".json") ? refPath : path.join(refPath, "tsconfig.json");
96
+ const refAliases = getPathAliasesRecursive(refConfigPath, visited);
97
+ Object.assign(result, refAliases);
98
+ }
99
+ }
100
+ return result;
101
+ }
102
+ async function loadConfig(configPath) {
103
+ const aliases = getPathAliases(process.cwd()) || {};
104
+ const { createJiti } = await import("jiti");
105
+ const jiti = createJiti(import.meta.url, {
106
+ interopDefault: true,
107
+ // Pass resolved path aliases so @/ imports work
108
+ alias: aliases
109
+ });
110
+ let configModule;
111
+ try {
112
+ configModule = await jiti.import(configPath);
113
+ } catch (error) {
114
+ const message = error instanceof Error ? error.message : String(error);
115
+ if (message.includes("Cannot find module") || message.includes("Cannot resolve")) {
116
+ console.error(pc.red("\n\u2717 Failed to load config file."));
117
+ console.error(pc.dim(" If your config uses import aliases (e.g., @/ or ~/),"));
118
+ console.error(pc.dim(" try using relative paths instead, then run the CLI again."));
119
+ console.error(pc.dim(`
120
+ Error: ${message}
121
+ `));
122
+ }
123
+ throw new Error(`Failed to load config from ${configPath}: ${message}`);
124
+ }
125
+ const raw = resolveConfigExport(configModule);
126
+ if (!raw || typeof raw !== "object") {
127
+ throw new Error(
128
+ `Config file at ${configPath} does not export a valid Invect config object.
129
+ Expected: export default { baseDatabaseConfig: ..., plugins: [...] }`
130
+ );
131
+ }
132
+ const config = raw;
133
+ const plugins = Array.isArray(config.plugins) ? config.plugins : [];
134
+ for (let i = 0; i < plugins.length; i++) {
135
+ const plugin = plugins[i];
136
+ if (!plugin || typeof plugin !== "object" || !("id" in plugin)) {
137
+ console.warn(
138
+ pc.yellow(`\u26A0 Plugin at index ${i} does not have an 'id' property \u2014 skipping`)
139
+ );
140
+ }
141
+ }
142
+ const validPlugins = plugins.filter(
143
+ (p) => p !== null && typeof p === "object" && "id" in p
144
+ );
145
+ return {
146
+ plugins: validPlugins,
147
+ baseDatabaseConfig: config.baseDatabaseConfig,
148
+ raw: config,
149
+ configPath
150
+ };
151
+ }
152
+ function resolveConfigExport(module) {
153
+ if (!module || typeof module !== "object") return module;
154
+ const mod = module;
155
+ if ("default" in mod) {
156
+ const def = mod.default;
157
+ if (def && typeof def === "object" && "default" in def) {
158
+ return def.default;
159
+ }
160
+ return def;
161
+ }
162
+ if ("config" in mod) return mod.config;
163
+ if ("invectConfig" in mod) return mod.invectConfig;
164
+ if ("baseDatabaseConfig" in mod || "plugins" in mod) return mod;
165
+ return mod;
166
+ }
167
+
168
+ // src/commands/generate.ts
18
169
  var generateCommand = new Command("generate").description("Generate Drizzle or Prisma schema files from core + plugin schemas").option(
19
170
  "--config <path>",
20
171
  "Path to your Invect config file. Defaults to the first config found."
@@ -33,37 +184,37 @@ var generateCommand = new Command("generate").description("Generate Drizzle or P
33
184
  "Database dialect (sqlite, postgresql, mysql). Required when using --schema. Auto-detected from drizzle.config.ts when possible."
34
185
  ).option("-y, --yes", "Skip confirmation prompt and generate directly", false).action(generateAction);
35
186
  async function generateAction(options) {
36
- console.log(pc.bold("\n\u{1F527} Invect Schema Generator\n"));
187
+ console.log(pc2.bold("\n\u{1F527} Invect Schema Generator\n"));
37
188
  const adapter = (options.adapter || "drizzle").toLowerCase();
38
189
  if (adapter !== "drizzle" && adapter !== "prisma") {
39
190
  console.error(
40
- pc.red(`\u2717 Unknown adapter "${options.adapter}".`) + "\n" + pc.dim(" Supported adapters: drizzle (default), prisma\n")
191
+ pc2.red(`\u2717 Unknown adapter "${options.adapter}".`) + "\n" + pc2.dim(" Supported adapters: drizzle (default), prisma\n")
41
192
  );
42
193
  process.exit(1);
43
194
  }
44
195
  const configPath = findConfigPath(options.config);
45
196
  if (!configPath) {
46
197
  console.error(
47
- pc.red("\u2717 Could not find Invect config file.") + "\n\n" + pc.dim(" Searched for: invect.config.ts in ./, src/, lib/, config/") + "\n" + pc.dim(" Use --config <path> to specify the config file explicitly.") + "\n\n" + pc.dim(" You can create one with: " + pc.cyan("npx invect-cli init")) + "\n"
198
+ pc2.red("\u2717 Could not find Invect config file.") + "\n\n" + pc2.dim(" Searched for: invect.config.ts in ./, src/, lib/, config/") + "\n" + pc2.dim(" Use --config <path> to specify the config file explicitly.") + "\n\n" + pc2.dim(" You can create one with: " + pc2.cyan("npx invect-cli init")) + "\n"
48
199
  );
49
200
  process.exit(1);
50
201
  }
51
- console.log(pc.dim(` Config: ${path.relative(process.cwd(), configPath)}`));
202
+ console.log(pc2.dim(` Config: ${path2.relative(process.cwd(), configPath)}`));
52
203
  let config;
53
204
  try {
54
205
  config = await loadConfig(configPath);
55
206
  } catch (error) {
56
207
  console.error(
57
- pc.red(`
58
- \u2717 Failed to load config.`) + "\n" + pc.dim(` ${error instanceof Error ? error.message : String(error)}`) + "\n\n" + pc.dim(" If your config uses import aliases (e.g., @/ or ~/),") + "\n" + pc.dim(" try using relative paths instead, then run the CLI again.\n")
208
+ pc2.red(`
209
+ \u2717 Failed to load config.`) + "\n" + pc2.dim(` ${error instanceof Error ? error.message : String(error)}`) + "\n\n" + pc2.dim(" If your config uses import aliases (e.g., @/ or ~/),") + "\n" + pc2.dim(" try using relative paths instead, then run the CLI again.\n")
59
210
  );
60
211
  process.exit(1);
61
212
  }
62
213
  if (adapter === "prisma") {
63
214
  await runPrismaMode(config, options);
64
- process.exit(0);
215
+ return;
65
216
  }
66
- let schemaFile = options.schema ? path.resolve(process.cwd(), options.schema) : void 0;
217
+ let schemaFile = options.schema ? path2.resolve(process.cwd(), options.schema) : void 0;
67
218
  let dialect = normalizeDialect(options.dialect);
68
219
  if (!schemaFile) {
69
220
  const detected = detectDrizzleSchema();
@@ -71,16 +222,16 @@ async function generateAction(options) {
71
222
  schemaFile = detected.schemaPath;
72
223
  dialect = dialect || detected.dialect;
73
224
  console.log(
74
- pc.dim(` Schema: ${path.relative(process.cwd(), schemaFile)}`) + pc.dim(` (auto-detected from ${detected.configFile})`)
225
+ pc2.dim(` Schema: ${path2.relative(process.cwd(), schemaFile)}`) + pc2.dim(` (auto-detected from ${detected.configFile})`)
75
226
  );
76
227
  }
77
228
  } else {
78
- console.log(pc.dim(` Schema: ${path.relative(process.cwd(), schemaFile)}`));
229
+ console.log(pc2.dim(` Schema: ${path2.relative(process.cwd(), schemaFile)}`));
79
230
  }
80
231
  const useAppendMode = !!schemaFile;
81
232
  if (useAppendMode && !dialect) {
82
233
  console.error(
83
- pc.red("\u2717 Cannot determine database dialect.") + "\n\n" + pc.dim(" When using --schema, provide --dialect (sqlite, postgresql, or mysql).") + "\n" + pc.dim(" Or ensure your drizzle.config.ts specifies a dialect.\n")
234
+ pc2.red("\u2717 Cannot determine database dialect.") + "\n\n" + pc2.dim(" When using --schema, provide --dialect (sqlite, postgresql, or mysql).") + "\n" + pc2.dim(" Or ensure your drizzle.config.ts specifies a dialect.\n")
84
235
  );
85
236
  process.exit(1);
86
237
  }
@@ -89,14 +240,13 @@ async function generateAction(options) {
89
240
  } else {
90
241
  await runSeparateFilesMode(config, options);
91
242
  }
92
- process.exit(0);
93
243
  }
94
244
  async function runPrismaMode(config, options) {
95
245
  const provider = normalizePrismaProvider(options.dialect) || "postgresql";
96
- const schemaFile = options.schema ? path.resolve(process.cwd(), options.schema) : path.resolve(process.cwd(), "prisma/schema.prisma");
97
- console.log(pc.dim(` Adapter: ${pc.cyan("Prisma")}`));
98
- console.log(pc.dim(` Provider: ${pc.white(provider)}`));
99
- console.log(pc.dim(` Schema: ${path.relative(process.cwd(), schemaFile)}`));
246
+ const schemaFile = options.schema ? path2.resolve(process.cwd(), options.schema) : path2.resolve(process.cwd(), "prisma/schema.prisma");
247
+ console.log(pc2.dim(` Adapter: ${pc2.cyan("Prisma")}`));
248
+ console.log(pc2.dim(` Provider: ${pc2.white(provider)}`));
249
+ console.log(pc2.dim(` Schema: ${path2.relative(process.cwd(), schemaFile)}`));
100
250
  let result;
101
251
  try {
102
252
  result = await generatePrismaSchema({
@@ -105,51 +255,51 @@ async function runPrismaMode(config, options) {
105
255
  provider
106
256
  });
107
257
  } catch (error) {
108
- console.error(pc.red(`
258
+ console.error(pc2.red(`
109
259
  \u2717 Prisma schema generation failed:`));
110
- console.error(pc.dim(` ${error instanceof Error ? error.message : String(error)}
260
+ console.error(pc2.dim(` ${error instanceof Error ? error.message : String(error)}
111
261
  `));
112
262
  process.exit(1);
113
263
  }
114
264
  if (result.code === void 0) {
115
- console.log(pc.bold(pc.green("\n\u2713 Prisma schema is already up to date.\n")));
116
- process.exit(0);
265
+ console.log(pc2.bold(pc2.green("\n\u2713 Prisma schema is already up to date.\n")));
266
+ return;
117
267
  }
118
- const rel = path.relative(process.cwd(), result.fileName);
268
+ const rel = path2.relative(process.cwd(), result.fileName);
119
269
  console.log("");
120
- console.log(pc.bold(" Files:"));
270
+ console.log(pc2.bold(" Files:"));
121
271
  if (result.overwrite) {
122
- console.log(pc.yellow(` ~ ${rel}`) + pc.dim(" (will update)"));
272
+ console.log(pc2.yellow(` ~ ${rel}`) + pc2.dim(" (will update)"));
123
273
  } else {
124
- console.log(pc.green(` + ${rel}`) + pc.dim(" (will create)"));
274
+ console.log(pc2.green(` + ${rel}`) + pc2.dim(" (will create)"));
125
275
  }
126
276
  if (!options.yes) {
127
277
  console.log("");
128
278
  const response = await prompts({
129
279
  type: "confirm",
130
280
  name: "proceed",
131
- message: result.overwrite ? `Update ${pc.cyan(rel)}?` : `Create ${pc.cyan(rel)}?`,
281
+ message: result.overwrite ? `Update ${pc2.cyan(rel)}?` : `Create ${pc2.cyan(rel)}?`,
132
282
  initial: true
133
283
  });
134
284
  if (!response.proceed) {
135
- console.log(pc.dim("\n Cancelled.\n"));
136
- process.exit(0);
285
+ console.log(pc2.dim("\n Cancelled.\n"));
286
+ return;
137
287
  }
138
288
  }
139
- const dir = path.dirname(result.fileName);
140
- fs.mkdirSync(dir, { recursive: true });
141
- fs.writeFileSync(result.fileName, result.code, "utf-8");
289
+ const dir = path2.dirname(result.fileName);
290
+ fs2.mkdirSync(dir, { recursive: true });
291
+ fs2.writeFileSync(result.fileName, result.code, "utf-8");
142
292
  console.log(
143
- pc.bold(pc.green(`
293
+ pc2.bold(pc2.green(`
144
294
  \u2713 Prisma schema ${result.overwrite ? "updated" : "created"}: ${rel}
145
295
  `))
146
296
  );
147
- console.log(pc.dim(" Next steps:"));
297
+ console.log(pc2.dim(" Next steps:"));
148
298
  console.log(
149
- pc.dim(" 1. Run ") + pc.cyan("npx prisma db push") + pc.dim(" to apply schema changes")
299
+ pc2.dim(" 1. Run ") + pc2.cyan("npx prisma db push") + pc2.dim(" to apply schema changes")
150
300
  );
151
301
  console.log(
152
- pc.dim(" 2. Run ") + pc.cyan("npx prisma generate") + pc.dim(" to regenerate the Prisma client")
302
+ pc2.dim(" 2. Run ") + pc2.cyan("npx prisma generate") + pc2.dim(" to regenerate the Prisma client")
153
303
  );
154
304
  console.log("");
155
305
  }
@@ -169,16 +319,16 @@ async function runAppendMode(config, schemaFile, dialect, options) {
169
319
  dialect
170
320
  });
171
321
  } catch (error) {
172
- console.error(pc.red(`
322
+ console.error(pc2.red(`
173
323
  \u2717 Schema generation failed:`));
174
- console.error(pc.dim(` ${error instanceof Error ? error.message : String(error)}
324
+ console.error(pc2.dim(` ${error instanceof Error ? error.message : String(error)}
175
325
  `));
176
326
  process.exit(1);
177
327
  }
178
328
  const { result, stats } = appendResult;
179
329
  await printSummary(config, stats);
180
- const fileExists = fs.existsSync(schemaFile);
181
- const currentFileContent = fileExists ? fs.readFileSync(schemaFile, "utf-8") : "";
330
+ const fileExists = fs2.existsSync(schemaFile);
331
+ const currentFileContent = fileExists ? fs2.readFileSync(schemaFile, "utf-8") : "";
182
332
  let existingContent = currentFileContent;
183
333
  const marker = "// Invect tables \u2014 AUTO-GENERATED by @invect/cli";
184
334
  const markerIndex = existingContent.indexOf(marker);
@@ -233,40 +383,40 @@ async function runAppendMode(config, schemaFile, dialect, options) {
233
383
  finalContent = finalContent.trimEnd() + "\n" + result.code + "\n";
234
384
  if (currentFileContent === finalContent) {
235
385
  printSummaryAlreadyUpToDate();
236
- process.exit(0);
386
+ return;
237
387
  }
238
- const rel = path.relative(process.cwd(), schemaFile);
388
+ const rel = path2.relative(process.cwd(), schemaFile);
239
389
  console.log("");
240
- console.log(pc.bold(" Files:"));
390
+ console.log(pc2.bold(" Files:"));
241
391
  if (fileExists) {
242
392
  if (markerIndex !== -1) {
243
- console.log(pc.yellow(` ~ ${rel}`) + pc.dim(" (Invect tables will be regenerated)"));
393
+ console.log(pc2.yellow(` ~ ${rel}`) + pc2.dim(" (Invect tables will be regenerated)"));
244
394
  } else {
245
- console.log(pc.green(` ~ ${rel}`) + pc.dim(" (Invect tables will be appended)"));
395
+ console.log(pc2.green(` ~ ${rel}`) + pc2.dim(" (Invect tables will be appended)"));
246
396
  }
247
397
  } else {
248
- console.log(pc.green(` + ${rel}`) + pc.dim(" (will create)"));
398
+ console.log(pc2.green(` + ${rel}`) + pc2.dim(" (will create)"));
249
399
  }
250
400
  if (!options.yes) {
251
401
  console.log("");
252
402
  const response = await prompts({
253
403
  type: "confirm",
254
404
  name: "proceed",
255
- message: fileExists ? `Append Invect tables to ${pc.cyan(rel)}?` : `Create ${pc.cyan(rel)} with Invect tables?`,
405
+ message: fileExists ? `Append Invect tables to ${pc2.cyan(rel)}?` : `Create ${pc2.cyan(rel)} with Invect tables?`,
256
406
  initial: true
257
407
  });
258
408
  if (!response.proceed) {
259
- console.log(pc.dim("\n Cancelled.\n"));
260
- process.exit(0);
409
+ console.log(pc2.dim("\n Cancelled.\n"));
410
+ return;
261
411
  }
262
412
  }
263
- const dir = path.dirname(schemaFile);
264
- fs.mkdirSync(dir, { recursive: true });
265
- fs.writeFileSync(schemaFile, finalContent, "utf-8");
413
+ const dir = path2.dirname(schemaFile);
414
+ fs2.mkdirSync(dir, { recursive: true });
415
+ fs2.writeFileSync(schemaFile, finalContent, "utf-8");
266
416
  const schemaFileChanged = currentFileContent !== finalContent;
267
417
  console.log(
268
- pc.bold(
269
- pc.green(
418
+ pc2.bold(
419
+ pc2.green(
270
420
  `
271
421
  \u2713 Invect tables ${markerIndex !== -1 ? "updated" : "appended"} in ${rel}
272
422
  `
@@ -275,20 +425,20 @@ async function runAppendMode(config, schemaFile, dialect, options) {
275
425
  );
276
426
  if (!schemaFileChanged) {
277
427
  console.log(
278
- pc.dim(" Schema file unchanged after regeneration \u2014 skipping drizzle-kit push.\n") + pc.dim(" The database is already up to date.\n")
428
+ pc2.dim(" Schema file unchanged after regeneration \u2014 skipping drizzle-kit push.\n") + pc2.dim(" The database is already up to date.\n")
279
429
  );
280
430
  } else if (!options.yes) {
281
431
  const { runPush } = await prompts({
282
432
  type: "confirm",
283
433
  name: "runPush",
284
- message: `Run ${pc.cyan("drizzle-kit push")} to apply schema changes?`,
434
+ message: `Run ${pc2.cyan("drizzle-kit push")} to apply schema changes?`,
285
435
  initial: true
286
436
  });
287
437
  if (runPush) {
288
438
  await runDrizzleKitPush();
289
439
  } else {
290
440
  console.log(
291
- pc.dim("\n Next: run ") + pc.cyan("npx drizzle-kit push") + pc.dim(" to apply schema changes.\n")
441
+ pc2.dim("\n Next: run ") + pc2.cyan("npx drizzle-kit push") + pc2.dim(" to apply schema changes.\n")
292
442
  );
293
443
  }
294
444
  } else {
@@ -296,7 +446,7 @@ async function runAppendMode(config, schemaFile, dialect, options) {
296
446
  }
297
447
  }
298
448
  async function runSeparateFilesMode(config, options) {
299
- const outputDir = path.resolve(process.cwd(), options.output);
449
+ const outputDir = path2.resolve(process.cwd(), options.output);
300
450
  let generated;
301
451
  try {
302
452
  generated = await generateAllDrizzleSchemas({
@@ -304,9 +454,9 @@ async function runSeparateFilesMode(config, options) {
304
454
  outputDir
305
455
  });
306
456
  } catch (error) {
307
- console.error(pc.red(`
457
+ console.error(pc2.red(`
308
458
  \u2717 Schema generation failed:`));
309
- console.error(pc.dim(` ${error instanceof Error ? error.message : String(error)}
459
+ console.error(pc2.dim(` ${error instanceof Error ? error.message : String(error)}
310
460
  `));
311
461
  process.exit(1);
312
462
  }
@@ -322,19 +472,19 @@ async function runSeparateFilesMode(config, options) {
322
472
  }) : results;
323
473
  const hasChanges = filteredResults.some((r) => r.code !== void 0);
324
474
  if (!hasChanges) {
325
- console.log(pc.bold(pc.green("\n\u2713 Schema files are already up to date.\n")));
326
- process.exit(0);
475
+ console.log(pc2.bold(pc2.green("\n\u2713 Schema files are already up to date.\n")));
476
+ return;
327
477
  }
328
478
  console.log("");
329
- console.log(pc.bold(" Files:"));
479
+ console.log(pc2.bold(" Files:"));
330
480
  for (const result of filteredResults) {
331
- const rel = path.relative(process.cwd(), result.fileName);
481
+ const rel = path2.relative(process.cwd(), result.fileName);
332
482
  if (result.code === void 0) {
333
- console.log(pc.dim(` \xB7 ${rel} (unchanged)`));
483
+ console.log(pc2.dim(` \xB7 ${rel} (unchanged)`));
334
484
  } else if (result.overwrite) {
335
- console.log(pc.yellow(` ~ ${rel}`) + pc.dim(" (will update)"));
485
+ console.log(pc2.yellow(` ~ ${rel}`) + pc2.dim(" (will update)"));
336
486
  } else {
337
- console.log(pc.green(` + ${rel}`) + pc.dim(" (will create)"));
487
+ console.log(pc2.green(` + ${rel}`) + pc2.dim(" (will create)"));
338
488
  }
339
489
  }
340
490
  if (!options.yes) {
@@ -346,21 +496,21 @@ async function runSeparateFilesMode(config, options) {
346
496
  initial: true
347
497
  });
348
498
  if (!response.proceed) {
349
- console.log(pc.dim("\n Cancelled.\n"));
350
- process.exit(0);
499
+ console.log(pc2.dim("\n Cancelled.\n"));
500
+ return;
351
501
  }
352
502
  }
353
503
  let writtenCount = 0;
354
504
  for (const result of filteredResults) {
355
505
  if (result.code === void 0) continue;
356
- const dir = path.dirname(result.fileName);
357
- fs.mkdirSync(dir, { recursive: true });
358
- fs.writeFileSync(result.fileName, result.code, "utf-8");
506
+ const dir = path2.dirname(result.fileName);
507
+ fs2.mkdirSync(dir, { recursive: true });
508
+ fs2.writeFileSync(result.fileName, result.code, "utf-8");
359
509
  writtenCount++;
360
510
  }
361
511
  console.log(
362
- pc.bold(
363
- pc.green(`
512
+ pc2.bold(
513
+ pc2.green(`
364
514
  \u2713 Generated ${writtenCount} schema file${writtenCount !== 1 ? "s" : ""}.
365
515
  `)
366
516
  )
@@ -369,7 +519,7 @@ async function runSeparateFilesMode(config, options) {
369
519
  const { runDrizzleKit } = await prompts({
370
520
  type: "confirm",
371
521
  name: "runDrizzleKit",
372
- message: `Run ${pc.cyan("drizzle-kit generate")} to create SQL migrations?`,
522
+ message: `Run ${pc2.cyan("drizzle-kit generate")} to create SQL migrations?`,
373
523
  initial: true
374
524
  });
375
525
  if (runDrizzleKit) {
@@ -382,7 +532,7 @@ async function runSeparateFilesMode(config, options) {
382
532
  }
383
533
  }
384
534
  function printSummaryAlreadyUpToDate() {
385
- console.log(pc.bold(pc.green("\n\u2713 Schema is already up to date. Nothing to do.\n")));
535
+ console.log(pc2.bold(pc2.green("\n\u2713 Schema is already up to date. Nothing to do.\n")));
386
536
  }
387
537
  async function printSummary(config, stats) {
388
538
  const pluginsWithSchema = config.plugins.filter((p) => p.schema);
@@ -390,13 +540,13 @@ async function printSummary(config, stats) {
390
540
  (p) => !p.schema && Array.isArray(p.requiredTables) && p.requiredTables.length > 0
391
541
  );
392
542
  console.log(
393
- pc.dim(
394
- ` Plugins: ${pc.white(String(config.plugins.length))} loaded` + (pluginsWithSchema.length > 0 ? `, ${pc.cyan(String(pluginsWithSchema.length))} with schema` : "")
543
+ pc2.dim(
544
+ ` Plugins: ${pc2.white(String(config.plugins.length))} loaded` + (pluginsWithSchema.length > 0 ? `, ${pc2.cyan(String(pluginsWithSchema.length))} with schema` : "")
395
545
  )
396
546
  );
397
547
  console.log(
398
- pc.dim(
399
- ` Tables: ${pc.white(String(stats.totalTables))} total (${stats.coreTableCount} core` + (stats.pluginTableCount > 0 ? ` + ${pc.cyan(String(stats.pluginTableCount))} plugin` : "") + ")"
548
+ pc2.dim(
549
+ ` Tables: ${pc2.white(String(stats.totalTables))} total (${stats.coreTableCount} core` + (stats.pluginTableCount > 0 ? ` + ${pc2.cyan(String(stats.pluginTableCount))} plugin` : "") + ")"
400
550
  )
401
551
  );
402
552
  if (pluginsWithSchema.length > 0) {
@@ -412,13 +562,13 @@ async function printSummary(config, stats) {
412
562
  const tableNames = Object.keys(plugin.schema);
413
563
  const newTables = tableNames.filter((t) => !(t in coreSchema));
414
564
  const extendedTables = tableNames.filter((t) => t in coreSchema);
415
- console.log(pc.dim(` Plugin ${pc.cyan(plugin.id)}:`));
565
+ console.log(pc2.dim(` Plugin ${pc2.cyan(plugin.id)}:`));
416
566
  for (const t of newTables) {
417
567
  const fields = Object.keys(
418
568
  plugin.schema[t]?.fields || {}
419
569
  );
420
570
  console.log(
421
- pc.green(` + ${t}`) + pc.dim(` (new table, ${fields.length} field${fields.length !== 1 ? "s" : ""})`)
571
+ pc2.green(` + ${t}`) + pc2.dim(` (new table, ${fields.length} field${fields.length !== 1 ? "s" : ""})`)
422
572
  );
423
573
  }
424
574
  for (const t of extendedTables) {
@@ -426,7 +576,7 @@ async function printSummary(config, stats) {
426
576
  plugin.schema[t]?.fields || {}
427
577
  );
428
578
  console.log(
429
- pc.yellow(` ~ ${t}`) + pc.dim(` (${fields.length} field${fields.length !== 1 ? "s" : ""} added)`)
579
+ pc2.yellow(` ~ ${t}`) + pc2.dim(` (${fields.length} field${fields.length !== 1 ? "s" : ""} added)`)
430
580
  );
431
581
  }
432
582
  }
@@ -434,19 +584,19 @@ async function printSummary(config, stats) {
434
584
  if (pluginsWithRequiredTablesOnly.length > 0) {
435
585
  console.log("");
436
586
  console.log(
437
- pc.yellow(" \u26A0 Some plugins require tables but do not provide schema definitions:")
587
+ pc2.yellow(" \u26A0 Some plugins require tables but do not provide schema definitions:")
438
588
  );
439
589
  for (const plugin of pluginsWithRequiredTablesOnly) {
440
590
  const tables = plugin.requiredTables.join(", ");
441
591
  console.log(
442
- pc.dim(` ${pc.yellow(plugin.id)}: requires `) + pc.white(tables)
592
+ pc2.dim(` ${pc2.yellow(plugin.id)}: requires `) + pc2.white(tables)
443
593
  );
444
594
  if (plugin.setupInstructions) {
445
- console.log(pc.dim(` \u2192 ${plugin.setupInstructions}`));
595
+ console.log(pc2.dim(` \u2192 ${plugin.setupInstructions}`));
446
596
  }
447
597
  }
448
598
  console.log(
449
- pc.dim(
599
+ pc2.dim(
450
600
  "\n These tables must be added to your schema manually (or via the plugin's own tooling).\n The generated schema files will NOT include them automatically.\n"
451
601
  )
452
602
  );
@@ -455,10 +605,10 @@ async function printSummary(config, stats) {
455
605
  function detectDrizzleSchema() {
456
606
  const configFile = findDrizzleConfig();
457
607
  if (!configFile) return null;
458
- const configPath = path.resolve(process.cwd(), configFile);
608
+ const configPath = path2.resolve(process.cwd(), configFile);
459
609
  let content;
460
610
  try {
461
- content = fs.readFileSync(configPath, "utf-8");
611
+ content = fs2.readFileSync(configPath, "utf-8");
462
612
  } catch {
463
613
  return null;
464
614
  }
@@ -468,7 +618,7 @@ function detectDrizzleSchema() {
468
618
  if (!schemaPath.endsWith(".ts") && !schemaPath.endsWith(".js")) {
469
619
  schemaPath += ".ts";
470
620
  }
471
- schemaPath = path.resolve(process.cwd(), schemaPath);
621
+ schemaPath = path2.resolve(process.cwd(), schemaPath);
472
622
  let dialect;
473
623
  const dialectMatch = content.match(/dialect\s*:\s*['"]([^'"]+)['"]/);
474
624
  if (dialectMatch) {
@@ -488,22 +638,22 @@ function normalizeDialect(dialect) {
488
638
  return void 0;
489
639
  }
490
640
  async function runDrizzleKitGenerate() {
491
- console.log(pc.dim("\n Running drizzle-kit generate...\n"));
641
+ console.log(pc2.dim("\n Running drizzle-kit generate...\n"));
492
642
  try {
493
643
  const configFile = findDrizzleConfig();
494
644
  const cmd = configFile ? `npx drizzle-kit generate --config ${configFile}` : "npx drizzle-kit generate";
495
645
  execSync(cmd, { stdio: "inherit", cwd: process.cwd() });
496
646
  console.log(
497
- pc.bold(pc.green("\n\u2713 SQL migrations generated.\n")) + pc.dim(" Run ") + pc.cyan("npx invect-cli migrate") + pc.dim(" to apply them.\n")
647
+ pc2.bold(pc2.green("\n\u2713 SQL migrations generated.\n")) + pc2.dim(" Run ") + pc2.cyan("npx invect-cli migrate") + pc2.dim(" to apply them.\n")
498
648
  );
499
649
  } catch {
500
650
  console.error(
501
- pc.yellow("\n\u26A0 drizzle-kit generate failed.") + "\n" + pc.dim(" Make sure drizzle-kit is installed and drizzle.config.ts exists.") + "\n" + pc.dim(" You can run it manually: ") + pc.cyan("npx drizzle-kit generate") + "\n"
651
+ pc2.yellow("\n\u26A0 drizzle-kit generate failed.") + "\n" + pc2.dim(" Make sure drizzle-kit is installed and drizzle.config.ts exists.") + "\n" + pc2.dim(" You can run it manually: ") + pc2.cyan("npx drizzle-kit generate") + "\n"
502
652
  );
503
653
  }
504
654
  }
505
655
  async function runDrizzleKitPush() {
506
- console.log(pc.dim("\n Running drizzle-kit push...\n"));
656
+ console.log(pc2.dim("\n Running drizzle-kit push...\n"));
507
657
  try {
508
658
  const configFile = findDrizzleConfig();
509
659
  const cmd = configFile ? `npx drizzle-kit push --config ${configFile}` : "npx drizzle-kit push";
@@ -514,7 +664,7 @@ async function runDrizzleKitPush() {
514
664
  });
515
665
  if (output) process.stdout.write(output);
516
666
  console.log(
517
- pc.bold(pc.green("\n\u2713 Schema pushed to database.\n"))
667
+ pc2.bold(pc2.green("\n\u2713 Schema pushed to database.\n"))
518
668
  );
519
669
  } catch (error) {
520
670
  const execError = error;
@@ -525,13 +675,13 @@ async function runDrizzleKitPush() {
525
675
  ].join("\n");
526
676
  if (/already exists/i.test(combinedOutput)) {
527
677
  console.log(
528
- pc.bold(pc.green("\n\u2713 Schema is already applied to the database.\n"))
678
+ pc2.bold(pc2.green("\n\u2713 Schema is already applied to the database.\n"))
529
679
  );
530
680
  } else {
531
681
  if (execError.stderr) process.stderr.write(execError.stderr);
532
682
  if (execError.stdout) process.stdout.write(execError.stdout);
533
683
  console.error(
534
- pc.yellow("\n\u26A0 drizzle-kit push failed.") + "\n" + pc.dim(" Make sure drizzle-kit is installed and drizzle.config.ts exists.") + "\n" + pc.dim(" You can run it manually: ") + pc.cyan("npx drizzle-kit push") + "\n"
684
+ pc2.yellow("\n\u26A0 drizzle-kit push failed.") + "\n" + pc2.dim(" Make sure drizzle-kit is installed and drizzle.config.ts exists.") + "\n" + pc2.dim(" You can run it manually: ") + pc2.cyan("npx drizzle-kit push") + "\n"
535
685
  );
536
686
  }
537
687
  }
@@ -545,25 +695,27 @@ function findDrizzleConfig() {
545
695
  "drizzle.config.mysql.ts"
546
696
  ];
547
697
  for (const file of candidates) {
548
- if (fs.existsSync(path.resolve(process.cwd(), file))) {
698
+ if (fs2.existsSync(path2.resolve(process.cwd(), file))) {
549
699
  return file;
550
700
  }
551
701
  }
552
702
  return null;
553
703
  }
554
704
  function printNextSteps() {
555
- console.log(pc.dim("\n Next steps:"));
556
- console.log(pc.dim(" 1. Review the generated schema files"));
705
+ console.log(pc2.dim("\n Next steps:"));
706
+ console.log(pc2.dim(" 1. Review the generated schema files"));
557
707
  console.log(
558
- pc.dim(" 2. Run ") + pc.cyan("npx drizzle-kit generate") + pc.dim(" to create SQL migrations")
708
+ pc2.dim(" 2. Run ") + pc2.cyan("npx drizzle-kit generate") + pc2.dim(" to create SQL migrations")
559
709
  );
560
710
  console.log(
561
- pc.dim(" 3. Run ") + pc.cyan("npx invect-cli migrate") + pc.dim(" to apply them")
711
+ pc2.dim(" 3. Run ") + pc2.cyan("npx invect-cli migrate") + pc2.dim(" to apply them")
562
712
  );
563
713
  console.log("");
564
714
  }
565
715
 
566
716
  export {
717
+ findConfigPath,
718
+ loadConfig,
567
719
  generateCommand,
568
720
  generateAction
569
721
  };