@prisma-next/cli 0.5.0-dev.4 → 0.5.0-dev.5

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.
Files changed (99) hide show
  1. package/dist/agent-skill-mongo.md +63 -31
  2. package/dist/agent-skill-postgres.md +1 -1
  3. package/dist/cli.mjs +119 -13
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/{client-TG7rbCWT.mjs → client-CrsnY58k.mjs} +4 -4
  6. package/dist/{client-TG7rbCWT.mjs.map → client-CrsnY58k.mjs.map} +1 -1
  7. package/dist/commands/contract-emit.mjs +2 -2
  8. package/dist/commands/contract-infer.mjs +2 -2
  9. package/dist/commands/db-init.mjs +7 -7
  10. package/dist/commands/db-schema.mjs +5 -5
  11. package/dist/commands/db-sign.mjs +7 -7
  12. package/dist/commands/db-update.mjs +7 -7
  13. package/dist/commands/db-verify.mjs +7 -7
  14. package/dist/commands/migration-apply.mjs +6 -6
  15. package/dist/commands/migration-new.mjs +5 -5
  16. package/dist/commands/migration-plan.mjs +6 -6
  17. package/dist/commands/migration-ref.d.mts +1 -1
  18. package/dist/commands/migration-ref.mjs +4 -4
  19. package/dist/commands/migration-show.d.mts +1 -1
  20. package/dist/commands/migration-show.mjs +6 -6
  21. package/dist/commands/migration-status.mjs +2 -2
  22. package/dist/{config-loader-_W4T21X1.mjs → config-loader-C25b63rJ.mjs} +1 -1
  23. package/dist/{config-loader-_W4T21X1.mjs.map → config-loader-C25b63rJ.mjs.map} +1 -1
  24. package/dist/config-loader.mjs +1 -1
  25. package/dist/contract-emit--feXyNd7.mjs +4 -0
  26. package/dist/{contract-emit-DpPjuFy-.mjs → contract-emit-NJ01hiiv.mjs} +8 -8
  27. package/dist/{contract-emit-DpPjuFy-.mjs.map → contract-emit-NJ01hiiv.mjs.map} +1 -1
  28. package/dist/{contract-emit-CQfj7xJn.mjs → contract-emit-V5SSitUT.mjs} +6 -6
  29. package/dist/{contract-emit-CQfj7xJn.mjs.map → contract-emit-V5SSitUT.mjs.map} +1 -1
  30. package/dist/{contract-enrichment-CGW6mm-E.mjs → contract-enrichment-CAOELa-H.mjs} +1 -1
  31. package/dist/{contract-enrichment-CGW6mm-E.mjs.map → contract-enrichment-CAOELa-H.mjs.map} +1 -1
  32. package/dist/{contract-infer-BS4kIX9c.mjs → contract-infer-D9cC3rJm.mjs} +4 -4
  33. package/dist/{contract-infer-BS4kIX9c.mjs.map → contract-infer-D9cC3rJm.mjs.map} +1 -1
  34. package/dist/exports/control-api.mjs +4 -4
  35. package/dist/exports/index.mjs +2 -2
  36. package/dist/exports/init-output.d.mts +39 -0
  37. package/dist/exports/init-output.d.mts.map +1 -0
  38. package/dist/exports/init-output.mjs +3 -0
  39. package/dist/{extract-operation-statements-DZUJNmL3.mjs → extract-operation-statements-DsFfxXVZ.mjs} +2 -2
  40. package/dist/{extract-operation-statements-DZUJNmL3.mjs.map → extract-operation-statements-DsFfxXVZ.mjs.map} +1 -1
  41. package/dist/{extract-sql-ddl-DDMX-9mz.mjs → extract-sql-ddl-D9UbZDyz.mjs} +1 -1
  42. package/dist/{extract-sql-ddl-DDMX-9mz.mjs.map → extract-sql-ddl-D9UbZDyz.mjs.map} +1 -1
  43. package/dist/{framework-components-DfZKQBQ2.mjs → framework-components-Cr--XBKy.mjs} +2 -2
  44. package/dist/{framework-components-DfZKQBQ2.mjs.map → framework-components-Cr--XBKy.mjs.map} +1 -1
  45. package/dist/init-C5220SY9.mjs +2062 -0
  46. package/dist/init-C5220SY9.mjs.map +1 -0
  47. package/dist/{inspect-live-schema-BsoFVoS1.mjs → inspect-live-schema-yrHAvG71.mjs} +6 -6
  48. package/dist/{inspect-live-schema-BsoFVoS1.mjs.map → inspect-live-schema-yrHAvG71.mjs.map} +1 -1
  49. package/dist/migration-cli.mjs +1 -1
  50. package/dist/{migration-command-scaffold-DOXnheFa.mjs → migration-command-scaffold-B3B09et6.mjs} +6 -6
  51. package/dist/{migration-command-scaffold-DOXnheFa.mjs.map → migration-command-scaffold-B3B09et6.mjs.map} +1 -1
  52. package/dist/{migration-status-Ry3TnEya.mjs → migration-status-DUMiH8_G.mjs} +6 -6
  53. package/dist/{migration-status-Ry3TnEya.mjs.map → migration-status-DUMiH8_G.mjs.map} +1 -1
  54. package/dist/{migrations-fU0xoKjS.mjs → migrations-Bo5WtTla.mjs} +2 -2
  55. package/dist/{migrations-fU0xoKjS.mjs.map → migrations-Bo5WtTla.mjs.map} +1 -1
  56. package/dist/output-BpcQrnnq.mjs +103 -0
  57. package/dist/output-BpcQrnnq.mjs.map +1 -0
  58. package/dist/{progress-adapter-B-YvmcDu.mjs → progress-adapter-DvQWB1nK.mjs} +1 -1
  59. package/dist/{progress-adapter-B-YvmcDu.mjs.map → progress-adapter-DvQWB1nK.mjs.map} +1 -1
  60. package/dist/quick-reference-mongo.md +34 -13
  61. package/dist/quick-reference-postgres.md +11 -9
  62. package/dist/{result-handler-BJwA7ufw.mjs → result-handler-Ba3zWQsI.mjs} +4 -77
  63. package/dist/result-handler-Ba3zWQsI.mjs.map +1 -0
  64. package/dist/{terminal-ui-C5k88MmW.mjs → terminal-ui-C3ZLwQxK.mjs} +76 -2
  65. package/dist/terminal-ui-C3ZLwQxK.mjs.map +1 -0
  66. package/dist/{validate-contract-deps-esa-VQ0h.mjs → validate-contract-deps-B_Cs29TL.mjs} +1 -1
  67. package/dist/{validate-contract-deps-esa-VQ0h.mjs.map → validate-contract-deps-B_Cs29TL.mjs.map} +1 -1
  68. package/dist/{verify-bl__PkXk.mjs → verify-Bkycc-Tf.mjs} +2 -2
  69. package/dist/{verify-bl__PkXk.mjs.map → verify-Bkycc-Tf.mjs.map} +1 -1
  70. package/package.json +20 -15
  71. package/src/commands/init/detect-pnpm-catalog.ts +141 -0
  72. package/src/commands/init/errors.ts +254 -0
  73. package/src/commands/init/exit-codes.ts +62 -0
  74. package/src/commands/init/hygiene-gitattributes.ts +97 -0
  75. package/src/commands/init/hygiene-gitignore.ts +48 -0
  76. package/src/commands/init/hygiene-package-scripts.ts +91 -0
  77. package/src/commands/init/index.ts +112 -7
  78. package/src/commands/init/init.ts +766 -144
  79. package/src/commands/init/inputs.ts +421 -0
  80. package/src/commands/init/output.ts +147 -0
  81. package/src/commands/init/probe-db.ts +308 -0
  82. package/src/commands/init/reinit-cleanup.ts +83 -0
  83. package/src/commands/init/templates/agent-skill-mongo.md +63 -31
  84. package/src/commands/init/templates/agent-skill-postgres.md +1 -1
  85. package/src/commands/init/templates/agent-skill.ts +25 -3
  86. package/src/commands/init/templates/code-templates.ts +125 -32
  87. package/src/commands/init/templates/env.ts +80 -0
  88. package/src/commands/init/templates/quick-reference-mongo.md +34 -13
  89. package/src/commands/init/templates/quick-reference-postgres.md +11 -9
  90. package/src/commands/init/templates/quick-reference.ts +42 -3
  91. package/src/commands/init/templates/tsconfig.ts +167 -5
  92. package/src/exports/init-output.ts +10 -0
  93. package/dist/contract-emit-fhNwwhkQ.mjs +0 -4
  94. package/dist/init-CQfo_4Ro.mjs +0 -430
  95. package/dist/init-CQfo_4Ro.mjs.map +0 -1
  96. package/dist/result-handler-BJwA7ufw.mjs.map +0 -1
  97. package/dist/terminal-ui-C5k88MmW.mjs.map +0 -1
  98. /package/dist/{cli-errors-C0JhVj0c.d.mts → cli-errors-BFYgBH3L.d.mts} +0 -0
  99. /package/dist/{cli-errors-DHq6GQGu.mjs → cli-errors-Cd79vmTH.mjs} +0 -0
@@ -1,430 +0,0 @@
1
- import { t as TerminalUI } from "./terminal-ui-C5k88MmW.mjs";
2
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
- import { dirname, extname, isAbsolute, join, normalize } from "pathe";
4
- import * as clack from "@clack/prompts";
5
- import { execFile } from "node:child_process";
6
- import { promisify } from "node:util";
7
- import { detect } from "package-manager-detector/detect";
8
-
9
- //#region src/commands/init/detect-package-manager.ts
10
- const KNOWN = new Set([
11
- "pnpm",
12
- "npm",
13
- "yarn",
14
- "bun",
15
- "deno"
16
- ]);
17
- async function detectPackageManager(cwd) {
18
- const result = await detect({ cwd });
19
- if (result && KNOWN.has(result.name)) return result.name;
20
- return "npm";
21
- }
22
- function hasProjectManifest(cwd) {
23
- return existsSync(join(cwd, "package.json")) || existsSync(join(cwd, "deno.json")) || existsSync(join(cwd, "deno.jsonc"));
24
- }
25
- function formatRunCommand(pm, bin, args) {
26
- if (pm === "npm") return `npx ${bin} ${args}`;
27
- if (pm === "deno") return `deno run npm:${bin} ${args}`;
28
- return `${pm} ${bin} ${args}`;
29
- }
30
- function formatAddArgs(pm, packages) {
31
- if (pm === "deno") return ["add", ...packages.map((p) => `npm:${p}`)];
32
- return ["add", ...packages];
33
- }
34
- function formatAddDevArgs(pm, packages) {
35
- if (pm === "deno") return [
36
- "add",
37
- "--dev",
38
- ...packages.map((p) => `npm:${p}`)
39
- ];
40
- return [
41
- "add",
42
- "-D",
43
- ...packages
44
- ];
45
- }
46
-
47
- //#endregion
48
- //#region src/commands/init/templates/render.ts
49
- function renderTemplate(templateFile, variableNames, vars) {
50
- let result = readFileSync(join(import.meta.dirname, templateFile), "utf-8");
51
- for (const key of variableNames) {
52
- const value = vars[key];
53
- if (value === void 0) throw new Error(`Template variable '${key}' is not defined`);
54
- result = result.replaceAll(`{{${key}}}`, value);
55
- }
56
- return result;
57
- }
58
-
59
- //#endregion
60
- //#region src/commands/init/templates/agent-skill.ts
61
- const variables$1 = [
62
- "schemaPath",
63
- "schemaDir",
64
- "dbImportPath",
65
- "pkgRun"
66
- ];
67
- function agentSkillMd(target, schemaPath, pkgRun) {
68
- const schemaDir = dirname(schemaPath);
69
- const vars = {
70
- schemaPath,
71
- schemaDir,
72
- dbImportPath: `./${schemaDir}/db`,
73
- pkgRun
74
- };
75
- return renderTemplate(`agent-skill-${target}.md`, variables$1, vars);
76
- }
77
-
78
- //#endregion
79
- //#region src/commands/init/templates/code-templates.ts
80
- function targetPackageName(target) {
81
- return target === "postgres" ? "@prisma-next/postgres" : "@prisma-next/mongo";
82
- }
83
- function defaultSchemaPath(authoring) {
84
- if (authoring === "typescript") return "prisma/contract.ts";
85
- return "prisma/contract.prisma";
86
- }
87
- function starterSchema(target, authoring) {
88
- if (authoring === "typescript") return target === "mongo" ? starterSchemaTsMongo() : starterSchemaTsPostgres();
89
- return target === "mongo" ? starterSchemaPslMongo() : starterSchemaPslPostgres();
90
- }
91
- function starterSchemaPslPostgres() {
92
- return `model User {
93
- id Int @id @default(autoincrement())
94
- email String @unique
95
- name String?
96
- posts Post[]
97
- createdAt DateTime @default(now())
98
- }
99
-
100
- model Post {
101
- id Int @id @default(autoincrement())
102
- title String
103
- content String?
104
- author User @relation(fields: [authorId], references: [id])
105
- authorId Int
106
- createdAt DateTime @default(now())
107
- }
108
- `;
109
- }
110
- function starterSchemaPslMongo() {
111
- return `model User {
112
- id ObjectId @id @map("_id")
113
- email String @unique
114
- name String?
115
- posts Post[]
116
- @@map("users")
117
- }
118
-
119
- model Post {
120
- id ObjectId @id @map("_id")
121
- title String
122
- content String?
123
- author User @relation(fields: [authorId], references: [id])
124
- authorId ObjectId
125
- @@map("posts")
126
- }
127
- `;
128
- }
129
- function starterSchemaTsPostgres() {
130
- return `import sqlFamily from '@prisma-next/family-sql/pack';
131
- import { defineContract } from '@prisma-next/sql-contract-ts/contract-builder';
132
- import postgresPack from '@prisma-next/target-postgres/pack';
133
-
134
- export const contract = defineContract(
135
- { family: sqlFamily, target: postgresPack },
136
- ({ field, model, rel }) => ({
137
- models: {
138
- User: model('User', {
139
- fields: {
140
- id: field.id.uuidv7(),
141
- email: field.text().unique(),
142
- name: field.text().optional(),
143
- createdAt: field.createdAt(),
144
- },
145
- }).relations({
146
- posts: rel.hasMany('Post', { by: 'authorId' }),
147
- }),
148
-
149
- Post: model('Post', {
150
- fields: {
151
- id: field.id.uuidv7(),
152
- title: field.text(),
153
- content: field.text().optional(),
154
- authorId: field.uuid(),
155
- createdAt: field.createdAt(),
156
- },
157
- }).relations({
158
- author: rel.belongsTo('User', { from: 'authorId', to: 'id' }),
159
- }),
160
- },
161
- }),
162
- );
163
- `;
164
- }
165
- function starterSchemaTsMongo() {
166
- return `import mongoFamily from '@prisma-next/family-mongo/pack';
167
- import { defineContract, field, model, rel } from '@prisma-next/mongo-contract-ts/contract-builder';
168
- import mongoTarget from '@prisma-next/target-mongo/pack';
169
-
170
- const User = model('User', {
171
- collection: 'users',
172
- fields: {
173
- _id: field.objectId(),
174
- email: field.string(),
175
- name: field.string().optional(),
176
- },
177
- });
178
-
179
- const Post = model('Post', {
180
- collection: 'posts',
181
- fields: {
182
- _id: field.objectId(),
183
- title: field.string(),
184
- content: field.string().optional(),
185
- authorId: field.objectId(),
186
- },
187
- relations: {
188
- author: rel.belongsTo(User, { from: 'authorId', to: User.ref('_id') }),
189
- },
190
- });
191
-
192
- export const contract = defineContract({
193
- family: mongoFamily,
194
- target: mongoTarget,
195
- models: { User, Post },
196
- });
197
- `;
198
- }
199
- function configFile(target, contractPath) {
200
- return `import 'dotenv/config';
201
- import { defineConfig } from '${targetPackageName(target)}/config';
202
-
203
- export default defineConfig({
204
- contract: ${JSON.stringify(contractPath)},
205
- db: {
206
- connection: process.env['DATABASE_URL']!,
207
- },
208
- });
209
- `;
210
- }
211
- function dbFile(target) {
212
- if (target === "postgres") return `import postgres from '@prisma-next/postgres/runtime';
213
- import type { Contract } from './contract.d';
214
- import contractJson from './contract.json' with { type: 'json' };
215
-
216
- export const db = postgres<Contract>({ contractJson });
217
- `;
218
- return `import mongo from '@prisma-next/mongo/runtime';
219
- import type { Contract } from './contract.d';
220
- import contractJson from './contract.json' with { type: 'json' };
221
-
222
- export const db = mongo<Contract>({ contractJson });
223
- `;
224
- }
225
-
226
- //#endregion
227
- //#region src/commands/init/templates/quick-reference.ts
228
- const variables = [
229
- "schemaPath",
230
- "schemaDir",
231
- "dbImportPath",
232
- "pkgRun"
233
- ];
234
- function quickReferenceMd(target, schemaPath, pkgRun) {
235
- const schemaDir = dirname(schemaPath);
236
- const vars = {
237
- schemaPath,
238
- schemaDir,
239
- dbImportPath: `./${schemaDir}/db`,
240
- pkgRun
241
- };
242
- return renderTemplate(`quick-reference-${target}.md`, variables, vars);
243
- }
244
-
245
- //#endregion
246
- //#region src/commands/init/templates/tsconfig.ts
247
- const REQUIRED_COMPILER_OPTIONS = {
248
- module: "preserve",
249
- moduleResolution: "bundler",
250
- resolveJsonModule: true
251
- };
252
- function defaultTsConfig() {
253
- return JSON.stringify({
254
- compilerOptions: {
255
- target: "ES2022",
256
- ...REQUIRED_COMPILER_OPTIONS,
257
- strict: true,
258
- skipLibCheck: true,
259
- esModuleInterop: true,
260
- outDir: "dist"
261
- },
262
- include: ["**/*.ts"]
263
- }, null, 2);
264
- }
265
- function mergeTsConfig(existing) {
266
- const config = JSON.parse(existing);
267
- const compilerOptions = config["compilerOptions"] ?? {};
268
- for (const [key, value] of Object.entries(REQUIRED_COMPILER_OPTIONS)) compilerOptions[key] = value;
269
- config["compilerOptions"] = compilerOptions;
270
- return JSON.stringify(config, null, 2);
271
- }
272
-
273
- //#endregion
274
- //#region src/commands/init/init.ts
275
- async function runInit(baseDir, options) {
276
- const ui = new TerminalUI();
277
- clack.intro("prisma-next init", { output: process.stderr });
278
- if (!hasProjectManifest(baseDir)) {
279
- ui.error("No package.json or deno.json found. Initialize your project first (e.g. npm init or deno init), then re-run prisma-next init.");
280
- process.exit(1);
281
- }
282
- const pm = await detectPackageManager(baseDir);
283
- const pkgRun = formatRunCommand(pm, "prisma-next", "").trimEnd();
284
- if (existsSync(join(baseDir, "prisma-next.config.ts"))) {
285
- const reinit = await clack.confirm({
286
- message: "This project is already initialized. Re-initialize? This will overwrite all generated files.",
287
- initialValue: false,
288
- output: process.stderr
289
- });
290
- if (clack.isCancel(reinit) || !reinit) {
291
- clack.cancel("Init cancelled.", { output: process.stderr });
292
- process.exit(0);
293
- }
294
- }
295
- const targetResult = await clack.select({
296
- message: "What database are you using?",
297
- options: [{
298
- value: "postgres",
299
- label: "PostgreSQL"
300
- }, {
301
- value: "mongo",
302
- label: "MongoDB"
303
- }],
304
- output: process.stderr
305
- });
306
- if (clack.isCancel(targetResult)) {
307
- clack.cancel("Init cancelled.", { output: process.stderr });
308
- process.exit(0);
309
- }
310
- const target = targetResult;
311
- const authoringResult = await clack.select({
312
- message: "How do you want to write your schema?",
313
- options: [{
314
- value: "psl",
315
- label: "Prisma Schema Language (.prisma)"
316
- }, {
317
- value: "typescript",
318
- label: "TypeScript (.ts)"
319
- }],
320
- output: process.stderr
321
- });
322
- if (clack.isCancel(authoringResult)) {
323
- clack.cancel("Init cancelled.", { output: process.stderr });
324
- process.exit(0);
325
- }
326
- const authoring = authoringResult;
327
- const schemaPathResult = await clack.text({
328
- message: "Where should the schema file go?",
329
- initialValue: defaultSchemaPath(authoring),
330
- validate(value = "") {
331
- const trimmed = value.trim();
332
- if (trimmed.length === 0) return "Path cannot be empty";
333
- if (trimmed.endsWith("/") || trimmed.endsWith("\\")) return "Path must be a file, not a directory";
334
- if (!extname(trimmed)) return "Path must include a file extension (e.g. .prisma or .ts)";
335
- },
336
- output: process.stderr
337
- });
338
- if (clack.isCancel(schemaPathResult)) {
339
- clack.cancel("Init cancelled.", { output: process.stderr });
340
- process.exit(0);
341
- }
342
- const schemaPath = normalize(schemaPathResult.trim());
343
- const schemaDir = dirname(schemaPath);
344
- const configPath = isAbsolute(schemaPath) ? schemaPath : `./${schemaPath}`;
345
- const files = [
346
- {
347
- path: schemaPath,
348
- content: starterSchema(target, authoring)
349
- },
350
- {
351
- path: "prisma-next.config.ts",
352
- content: configFile(target, configPath)
353
- },
354
- {
355
- path: join(schemaDir, "db.ts"),
356
- content: dbFile(target)
357
- },
358
- {
359
- path: "prisma-next.md",
360
- content: quickReferenceMd(target, schemaPath, pkgRun)
361
- },
362
- {
363
- path: ".agents/skills/prisma-next/SKILL.md",
364
- content: agentSkillMd(target, schemaPath, pkgRun)
365
- }
366
- ];
367
- for (const file of files) {
368
- const fullPath = join(baseDir, file.path);
369
- mkdirSync(dirname(fullPath), { recursive: true });
370
- writeFileSync(fullPath, file.content, "utf-8");
371
- }
372
- const tsconfigPath = join(baseDir, "tsconfig.json");
373
- if (existsSync(tsconfigPath)) {
374
- writeFileSync(tsconfigPath, mergeTsConfig(readFileSync(tsconfigPath, "utf-8")), "utf-8");
375
- ui.log("Updated tsconfig.json with required compiler options.");
376
- } else writeFileSync(tsconfigPath, defaultTsConfig(), "utf-8");
377
- const emitCommand = formatRunCommand(pm, "prisma-next", "contract emit");
378
- if (options.noInstall) {
379
- const pkg = targetPackageName(target);
380
- ui.note([
381
- "Run the following commands to complete setup:",
382
- "",
383
- " 1. Install dependencies:",
384
- ` ${pm} ${formatAddArgs(pm, [pkg, "dotenv"]).join(" ")}`,
385
- ` ${pm} ${formatAddDevArgs(pm, ["prisma-next"]).join(" ")}`,
386
- "",
387
- " 2. Emit the contract:",
388
- ` ${emitCommand}`
389
- ].join("\n"), "Manual steps");
390
- } else {
391
- const pkg = targetPackageName(target);
392
- const spinner = ui.spinner();
393
- let installSucceeded = false;
394
- const exec = promisify(execFile);
395
- spinner.start(`Installing ${pkg}, dotenv, and prisma-next...`);
396
- try {
397
- await exec(pm, formatAddArgs(pm, [pkg, "dotenv"]), { cwd: baseDir });
398
- await exec(pm, formatAddDevArgs(pm, ["prisma-next"]), { cwd: baseDir });
399
- spinner.stop(`Installed ${pkg}, dotenv, and prisma-next`);
400
- installSucceeded = true;
401
- } catch (err) {
402
- spinner.stop("Installation failed");
403
- const stderr = err instanceof Error && "stderr" in err ? err.stderr : "";
404
- ui.warn([
405
- "Could not install dependencies automatically.",
406
- ...stderr ? [` ${stderr.trim()}`] : [],
407
- "",
408
- "Run manually:",
409
- ` ${pm} ${formatAddArgs(pm, [pkg, "dotenv"]).join(" ")}`,
410
- ` ${pm} ${formatAddDevArgs(pm, ["prisma-next"]).join(" ")}`
411
- ].join("\n"));
412
- }
413
- if (installSucceeded) {
414
- spinner.start("Emitting contract...");
415
- try {
416
- const { executeContractEmit } = await import("./contract-emit-fhNwwhkQ.mjs");
417
- await executeContractEmit({ configPath: join(baseDir, "prisma-next.config.ts") });
418
- spinner.stop("Contract emitted");
419
- } catch {
420
- spinner.stop("Contract emission failed");
421
- ui.warn(["Could not emit contract automatically. Run manually:", ` ${emitCommand}`].join("\n"));
422
- }
423
- }
424
- }
425
- clack.outro("Done! Open prisma-next.md to get started.", { output: process.stderr });
426
- }
427
-
428
- //#endregion
429
- export { runInit };
430
- //# sourceMappingURL=init-CQfo_4Ro.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"init-CQfo_4Ro.mjs","names":["KNOWN: ReadonlySet<string>","variables","vars: TemplateVars","vars: TemplateVars","REQUIRED_COMPILER_OPTIONS: Record<string, string | boolean>","files: FileEntry[]"],"sources":["../src/commands/init/detect-package-manager.ts","../src/commands/init/templates/render.ts","../src/commands/init/templates/agent-skill.ts","../src/commands/init/templates/code-templates.ts","../src/commands/init/templates/quick-reference.ts","../src/commands/init/templates/tsconfig.ts","../src/commands/init/init.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { detect } from 'package-manager-detector/detect';\nimport { join } from 'pathe';\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun' | 'deno';\n\nconst KNOWN: ReadonlySet<string> = new Set<PackageManager>(['pnpm', 'npm', 'yarn', 'bun', 'deno']);\n\nexport async function detectPackageManager(cwd: string): Promise<PackageManager> {\n const result = await detect({ cwd });\n if (result && KNOWN.has(result.name)) {\n return result.name as PackageManager;\n }\n return 'npm';\n}\n\nexport function hasProjectManifest(cwd: string): boolean {\n return (\n existsSync(join(cwd, 'package.json')) ||\n existsSync(join(cwd, 'deno.json')) ||\n existsSync(join(cwd, 'deno.jsonc'))\n );\n}\n\nexport function formatRunCommand(pm: PackageManager, bin: string, args: string): string {\n if (pm === 'npm') {\n return `npx ${bin} ${args}`;\n }\n if (pm === 'deno') {\n return `deno run npm:${bin} ${args}`;\n }\n return `${pm} ${bin} ${args}`;\n}\n\nexport function formatAddArgs(pm: PackageManager, packages: string[]): string[] {\n if (pm === 'deno') {\n return ['add', ...packages.map((p) => `npm:${p}`)];\n }\n return ['add', ...packages];\n}\n\nexport function formatAddDevArgs(pm: PackageManager, packages: string[]): string[] {\n if (pm === 'deno') {\n return ['add', '--dev', ...packages.map((p) => `npm:${p}`)];\n }\n return ['add', '-D', ...packages];\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'pathe';\n\nexport function renderTemplate(\n templateFile: string,\n variableNames: readonly string[],\n vars: Record<string, string>,\n): string {\n const templatePath = join(import.meta.dirname, templateFile);\n const raw = readFileSync(templatePath, 'utf-8');\n let result = raw;\n for (const key of variableNames) {\n const value = vars[key];\n if (value === undefined) {\n throw new Error(`Template variable '${key}' is not defined`);\n }\n result = result.replaceAll(`{{${key}}}`, value);\n }\n return result;\n}\n","import { dirname } from 'pathe';\nimport type { TargetId } from './code-templates';\nimport { renderTemplate } from './render';\n\nexport const variables = ['schemaPath', 'schemaDir', 'dbImportPath', 'pkgRun'] as const;\n\ntype TemplateVars = Record<(typeof variables)[number], string>;\n\nexport function agentSkillMd(target: TargetId, schemaPath: string, pkgRun: string): string {\n const schemaDir = dirname(schemaPath);\n const vars: TemplateVars = {\n schemaPath,\n schemaDir,\n dbImportPath: `./${schemaDir}/db`,\n pkgRun,\n };\n const templateFile = `agent-skill-${target}.md`;\n return renderTemplate(templateFile, variables, vars);\n}\n","export type TargetId = 'postgres' | 'mongo';\nexport type AuthoringId = 'psl' | 'typescript';\n\nexport function targetPackageName(target: TargetId): string {\n return target === 'postgres' ? '@prisma-next/postgres' : '@prisma-next/mongo';\n}\n\nexport function targetLabel(target: TargetId): string {\n return target === 'postgres' ? 'PostgreSQL' : 'MongoDB';\n}\n\nexport function defaultSchemaPath(authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return 'prisma/contract.ts';\n }\n return 'prisma/contract.prisma';\n}\n\nexport function starterSchema(target: TargetId, authoring: AuthoringId): string {\n if (authoring === 'typescript') {\n return target === 'mongo' ? starterSchemaTsMongo() : starterSchemaTsPostgres();\n }\n return target === 'mongo' ? starterSchemaPslMongo() : starterSchemaPslPostgres();\n}\n\nfunction starterSchemaPslPostgres(): string {\n return `model User {\n id Int @id @default(autoincrement())\n email String @unique\n name String?\n posts Post[]\n createdAt DateTime @default(now())\n}\n\nmodel Post {\n id Int @id @default(autoincrement())\n title String\n content String?\n author User @relation(fields: [authorId], references: [id])\n authorId Int\n createdAt DateTime @default(now())\n}\n`;\n}\n\nfunction starterSchemaPslMongo(): string {\n return `model User {\n id ObjectId @id @map(\"_id\")\n email String @unique\n name String?\n posts Post[]\n @@map(\"users\")\n}\n\nmodel Post {\n id ObjectId @id @map(\"_id\")\n title String\n content String?\n author User @relation(fields: [authorId], references: [id])\n authorId ObjectId\n @@map(\"posts\")\n}\n`;\n}\n\nfunction starterSchemaTsPostgres(): string {\n return `import sqlFamily from '@prisma-next/family-sql/pack';\nimport { defineContract } from '@prisma-next/sql-contract-ts/contract-builder';\nimport postgresPack from '@prisma-next/target-postgres/pack';\n\nexport const contract = defineContract(\n { family: sqlFamily, target: postgresPack },\n ({ field, model, rel }) => ({\n models: {\n User: model('User', {\n fields: {\n id: field.id.uuidv7(),\n email: field.text().unique(),\n name: field.text().optional(),\n createdAt: field.createdAt(),\n },\n }).relations({\n posts: rel.hasMany('Post', { by: 'authorId' }),\n }),\n\n Post: model('Post', {\n fields: {\n id: field.id.uuidv7(),\n title: field.text(),\n content: field.text().optional(),\n authorId: field.uuid(),\n createdAt: field.createdAt(),\n },\n }).relations({\n author: rel.belongsTo('User', { from: 'authorId', to: 'id' }),\n }),\n },\n }),\n);\n`;\n}\n\nfunction starterSchemaTsMongo(): string {\n return `import mongoFamily from '@prisma-next/family-mongo/pack';\nimport { defineContract, field, model, rel } from '@prisma-next/mongo-contract-ts/contract-builder';\nimport mongoTarget from '@prisma-next/target-mongo/pack';\n\nconst User = model('User', {\n collection: 'users',\n fields: {\n _id: field.objectId(),\n email: field.string(),\n name: field.string().optional(),\n },\n});\n\nconst Post = model('Post', {\n collection: 'posts',\n fields: {\n _id: field.objectId(),\n title: field.string(),\n content: field.string().optional(),\n authorId: field.objectId(),\n },\n relations: {\n author: rel.belongsTo(User, { from: 'authorId', to: User.ref('_id') }),\n },\n});\n\nexport const contract = defineContract({\n family: mongoFamily,\n target: mongoTarget,\n models: { User, Post },\n});\n`;\n}\n\nexport function configFile(target: TargetId, contractPath: string): string {\n const pkg = targetPackageName(target);\n return `import 'dotenv/config';\nimport { defineConfig } from '${pkg}/config';\n\nexport default defineConfig({\n contract: ${JSON.stringify(contractPath)},\n db: {\n connection: process.env['DATABASE_URL']!,\n },\n});\n`;\n}\n\nexport function dbFile(target: TargetId): string {\n if (target === 'postgres') {\n return `import postgres from '@prisma-next/postgres/runtime';\nimport type { Contract } from './contract.d';\nimport contractJson from './contract.json' with { type: 'json' };\n\nexport const db = postgres<Contract>({ contractJson });\n`;\n }\n\n return `import mongo from '@prisma-next/mongo/runtime';\nimport type { Contract } from './contract.d';\nimport contractJson from './contract.json' with { type: 'json' };\n\nexport const db = mongo<Contract>({ contractJson });\n`;\n}\n","import { dirname } from 'pathe';\nimport type { TargetId } from './code-templates';\nimport { renderTemplate } from './render';\n\nexport const variables = ['schemaPath', 'schemaDir', 'dbImportPath', 'pkgRun'] as const;\n\ntype TemplateVars = Record<(typeof variables)[number], string>;\n\nexport function quickReferenceMd(target: TargetId, schemaPath: string, pkgRun: string): string {\n const schemaDir = dirname(schemaPath);\n const vars: TemplateVars = {\n schemaPath,\n schemaDir,\n dbImportPath: `./${schemaDir}/db`,\n pkgRun,\n };\n const templateFile = `quick-reference-${target}.md`;\n return renderTemplate(templateFile, variables, vars);\n}\n","export const REQUIRED_COMPILER_OPTIONS: Record<string, string | boolean> = {\n module: 'preserve',\n moduleResolution: 'bundler',\n resolveJsonModule: true,\n};\n\nexport function defaultTsConfig(): string {\n return JSON.stringify(\n {\n compilerOptions: {\n target: 'ES2022',\n ...REQUIRED_COMPILER_OPTIONS,\n strict: true,\n skipLibCheck: true,\n esModuleInterop: true,\n outDir: 'dist',\n },\n include: ['**/*.ts'],\n },\n null,\n 2,\n );\n}\n\nexport function mergeTsConfig(existing: string): string {\n const config = JSON.parse(existing) as Record<string, unknown>;\n const compilerOptions = (config['compilerOptions'] ?? {}) as Record<string, unknown>;\n\n for (const [key, value] of Object.entries(REQUIRED_COMPILER_OPTIONS)) {\n compilerOptions[key] = value;\n }\n\n config['compilerOptions'] = compilerOptions;\n return JSON.stringify(config, null, 2);\n}\n","import { execFile } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { promisify } from 'node:util';\nimport * as clack from '@clack/prompts';\nimport { dirname, extname, isAbsolute, join, normalize } from 'pathe';\nimport { TerminalUI } from '../../utils/terminal-ui';\nimport {\n detectPackageManager,\n formatAddArgs,\n formatAddDevArgs,\n formatRunCommand,\n hasProjectManifest,\n} from './detect-package-manager';\nimport { agentSkillMd } from './templates/agent-skill';\nimport {\n type AuthoringId,\n configFile,\n dbFile,\n defaultSchemaPath,\n starterSchema,\n type TargetId,\n targetPackageName,\n} from './templates/code-templates';\nimport { quickReferenceMd } from './templates/quick-reference';\nimport { defaultTsConfig, mergeTsConfig } from './templates/tsconfig';\n\nexport interface InitOptions {\n readonly noInstall?: boolean;\n}\n\ninterface FileEntry {\n readonly path: string;\n readonly content: string;\n}\n\nexport async function runInit(baseDir: string, options: InitOptions): Promise<void> {\n const ui = new TerminalUI();\n\n clack.intro('prisma-next init', { output: process.stderr });\n\n if (!hasProjectManifest(baseDir)) {\n ui.error(\n 'No package.json or deno.json found. Initialize your project first (e.g. npm init or deno init), then re-run prisma-next init.',\n );\n process.exit(1);\n }\n\n const pm = await detectPackageManager(baseDir);\n const pkgRun = formatRunCommand(pm, 'prisma-next', '').trimEnd();\n\n if (existsSync(join(baseDir, 'prisma-next.config.ts'))) {\n const reinit = await clack.confirm({\n message:\n 'This project is already initialized. Re-initialize? This will overwrite all generated files.',\n initialValue: false,\n output: process.stderr,\n });\n if (clack.isCancel(reinit) || !reinit) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n }\n\n const targetResult = await clack.select({\n message: 'What database are you using?',\n options: [\n { value: 'postgres' as TargetId, label: 'PostgreSQL' },\n { value: 'mongo' as TargetId, label: 'MongoDB' },\n ],\n output: process.stderr,\n });\n if (clack.isCancel(targetResult)) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n const target = targetResult as TargetId;\n\n const authoringResult = await clack.select({\n message: 'How do you want to write your schema?',\n options: [\n { value: 'psl' as AuthoringId, label: 'Prisma Schema Language (.prisma)' },\n { value: 'typescript' as AuthoringId, label: 'TypeScript (.ts)' },\n ],\n output: process.stderr,\n });\n if (clack.isCancel(authoringResult)) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n const authoring = authoringResult as AuthoringId;\n\n const schemaPathResult = await clack.text({\n message: 'Where should the schema file go?',\n initialValue: defaultSchemaPath(authoring),\n validate(value = '') {\n const trimmed = value.trim();\n if (trimmed.length === 0) return 'Path cannot be empty';\n if (trimmed.endsWith('/') || trimmed.endsWith('\\\\'))\n return 'Path must be a file, not a directory';\n if (!extname(trimmed)) return 'Path must include a file extension (e.g. .prisma or .ts)';\n return undefined;\n },\n output: process.stderr,\n });\n if (clack.isCancel(schemaPathResult)) {\n clack.cancel('Init cancelled.', { output: process.stderr });\n process.exit(0);\n }\n const schemaPath = normalize((schemaPathResult as string).trim());\n\n const schemaDir = dirname(schemaPath);\n const configPath = isAbsolute(schemaPath) ? schemaPath : `./${schemaPath}`;\n\n const files: FileEntry[] = [\n { path: schemaPath, content: starterSchema(target, authoring) },\n { path: 'prisma-next.config.ts', content: configFile(target, configPath) },\n { path: join(schemaDir, 'db.ts'), content: dbFile(target) },\n { path: 'prisma-next.md', content: quickReferenceMd(target, schemaPath, pkgRun) },\n {\n path: '.agents/skills/prisma-next/SKILL.md',\n content: agentSkillMd(target, schemaPath, pkgRun),\n },\n ];\n\n for (const file of files) {\n const fullPath = join(baseDir, file.path);\n mkdirSync(dirname(fullPath), { recursive: true });\n writeFileSync(fullPath, file.content, 'utf-8');\n }\n\n const tsconfigPath = join(baseDir, 'tsconfig.json');\n if (existsSync(tsconfigPath)) {\n const existing = readFileSync(tsconfigPath, 'utf-8');\n writeFileSync(tsconfigPath, mergeTsConfig(existing), 'utf-8');\n ui.log('Updated tsconfig.json with required compiler options.');\n } else {\n writeFileSync(tsconfigPath, defaultTsConfig(), 'utf-8');\n }\n\n const emitCommand = formatRunCommand(pm, 'prisma-next', 'contract emit');\n\n if (options.noInstall) {\n const pkg = targetPackageName(target);\n ui.note(\n [\n 'Run the following commands to complete setup:',\n '',\n ' 1. Install dependencies:',\n ` ${pm} ${formatAddArgs(pm, [pkg, 'dotenv']).join(' ')}`,\n ` ${pm} ${formatAddDevArgs(pm, ['prisma-next']).join(' ')}`,\n '',\n ' 2. Emit the contract:',\n ` ${emitCommand}`,\n ].join('\\n'),\n 'Manual steps',\n );\n } else {\n const pkg = targetPackageName(target);\n const spinner = ui.spinner();\n let installSucceeded = false;\n\n const exec = promisify(execFile);\n\n spinner.start(`Installing ${pkg}, dotenv, and prisma-next...`);\n try {\n await exec(pm, formatAddArgs(pm, [pkg, 'dotenv']), { cwd: baseDir });\n await exec(pm, formatAddDevArgs(pm, ['prisma-next']), { cwd: baseDir });\n spinner.stop(`Installed ${pkg}, dotenv, and prisma-next`);\n installSucceeded = true;\n } catch (err) {\n spinner.stop('Installation failed');\n const stderr =\n err instanceof Error && 'stderr' in err ? (err as { stderr: string }).stderr : '';\n ui.warn(\n [\n 'Could not install dependencies automatically.',\n ...(stderr ? [` ${stderr.trim()}`] : []),\n '',\n 'Run manually:',\n ` ${pm} ${formatAddArgs(pm, [pkg, 'dotenv']).join(' ')}`,\n ` ${pm} ${formatAddDevArgs(pm, ['prisma-next']).join(' ')}`,\n ].join('\\n'),\n );\n }\n\n if (installSucceeded) {\n spinner.start('Emitting contract...');\n try {\n const { executeContractEmit } = await import('../../control-api/operations/contract-emit');\n const configFilePath = join(baseDir, 'prisma-next.config.ts');\n await executeContractEmit({ configPath: configFilePath });\n spinner.stop('Contract emitted');\n } catch {\n spinner.stop('Contract emission failed');\n ui.warn(\n ['Could not emit contract automatically. Run manually:', ` ${emitCommand}`].join('\\n'),\n );\n }\n }\n }\n\n clack.outro('Done! Open prisma-next.md to get started.', { output: process.stderr });\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"result-handler-BJwA7ufw.mjs","names":["LEFT_COLUMN_WIDTH","createPrismaNextBadge","formatHeaderLine","formatReadMoreLine","lines: string[]","lines: string[]","parts: string[]","current: Command | undefined","flags: {\n json?: boolean;\n quiet?: boolean;\n verbose?: number;\n color?: boolean;\n interactive?: boolean;\n yes?: boolean;\n }","lines: string[]"],"sources":["../src/utils/formatters/helpers.ts","../src/utils/formatters/styled.ts","../src/utils/formatters/help.ts","../src/utils/global-flags.ts","../src/utils/command-helpers.ts","../src/utils/formatters/errors.ts","../src/utils/result-handler.ts"],"sourcesContent":["import { dim } from 'colorette';\n\nimport type { GlobalFlags } from '../global-flags';\n\n/**\n * Checks if verbose output is enabled at the specified level.\n */\nexport function isVerbose(flags: GlobalFlags, level: 1 | 2): boolean {\n return (flags.verbose ?? 0) >= level;\n}\n\n/**\n * Creates a color-aware formatter function.\n * Returns a function that applies the color only if colors are enabled.\n */\nexport function createColorFormatter<T extends (text: string) => string>(\n useColor: boolean,\n colorFn: T,\n): (text: string) => string {\n return useColor ? colorFn : (text: string) => text;\n}\n\n/**\n * Formats text with dim styling if colors are enabled.\n */\nexport function formatDim(useColor: boolean, text: string): string {\n return useColor ? dim(text) : text;\n}\n","import { blue, bold, cyan, green } from 'colorette';\nimport type { Command } from 'commander';\nimport stringWidth from 'string-width';\nimport stripAnsi from 'strip-ansi';\n\nimport type { GlobalFlags } from '../global-flags';\nimport { createColorFormatter, formatDim } from './helpers';\n\n// ============================================================================\n// Styled Output Formatters\n// ============================================================================\n\n/**\n * Fixed width for left column in help output.\n */\nconst LEFT_COLUMN_WIDTH = 20;\n\n/**\n * Creates an arrow segment badge with green background and white text.\n * Body: green background with white \"prisma-next\" text\n * Tip: dark grey arrow pointing right (Powerline separator)\n */\nfunction createPrismaNextBadge(useColor: boolean): string {\n if (!useColor) {\n return 'prisma-next';\n }\n return bold('prisma-next');\n}\n\n/**\n * Creates a padding function.\n */\nfunction createPadFunction(): (s: string, w: number) => string {\n return (s: string, w: number) => s + ' '.repeat(Math.max(0, w - s.length));\n}\n\n/**\n * Formats a header line: brand + operation + intent\n */\nfunction formatHeaderLine(options: {\n readonly brand: string;\n readonly operation: string;\n readonly intent: string;\n}): string {\n if (options.operation) {\n return `${options.brand} ${options.operation} → ${options.intent}`;\n }\n return `${options.brand} ${options.intent}`;\n}\n\n/**\n * Formats a \"Read more\" URL line.\n * The \"Read more\" label is in default color (not cyan), and the URL is blue.\n */\nfunction formatReadMoreLine(options: {\n readonly url: string;\n readonly maxLabelWidth: number;\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n}): string {\n const pad = createPadFunction();\n const labelPadded = pad('Read more', options.maxLabelWidth);\n // Label is default color (not cyan)\n const valueColored = options.useColor ? blue(options.url) : options.url;\n return `${options.formatDimText('│')} ${labelPadded} ${valueColored}`;\n}\n\n/**\n * Pads text to a fixed width, accounting for ANSI escape codes.\n * Uses string-width to measure the actual display width.\n */\nexport function padToFixedWidth(text: string, width: number): string {\n const actualWidth = stringWidth(text);\n const padding = Math.max(0, width - actualWidth);\n return text + ' '.repeat(padding);\n}\n\n/**\n * Renders a command tree structure.\n * Handles both single-level (subcommands of a command) and multi-level (top-level commands with subcommands) trees.\n */\nexport function renderCommandTree(options: {\n readonly commands: readonly Command[];\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n readonly hasItemsAfter: boolean;\n readonly continuationPrefix?: string;\n}): string[] {\n const { commands, useColor, formatDimText, hasItemsAfter, continuationPrefix } = options;\n const lines: string[] = [];\n\n if (commands.length === 0) {\n return lines;\n }\n\n // Format each command\n for (let i = 0; i < commands.length; i++) {\n const cmd = commands[i];\n if (!cmd) continue;\n\n const subcommands = cmd.commands.filter((subcmd) => !subcmd.name().startsWith('_'));\n const isLastCommand = i === commands.length - 1;\n\n if (subcommands.length > 0) {\n // Command with subcommands - show command name, then tree-structured subcommands\n const treeChar = isLastCommand && !hasItemsAfter ? formatDimText('└') : formatDimText('├');\n // For top-level command, pad name to fixed width (accounting for \"| |-- \" = 5 chars)\n const treePrefix = `${treeChar}─ `;\n const treePrefixWidth = stringWidth(stripAnsi(treePrefix));\n const remainingWidth = LEFT_COLUMN_WIDTH - treePrefixWidth;\n const commandNamePadded = padToFixedWidth(cmd.name(), remainingWidth);\n const commandNameColored = useColor ? cyan(commandNamePadded) : commandNamePadded;\n lines.push(`${formatDimText('│')} ${treePrefix}${commandNameColored}`);\n\n for (let j = 0; j < subcommands.length; j++) {\n const subcmd = subcommands[j];\n if (!subcmd) continue;\n\n const isLastSubcommand = j === subcommands.length - 1;\n const shortDescription = subcmd.description() || '';\n\n // Use tree characters: -- for last subcommand, |-- for others\n const treeChar = isLastSubcommand ? '└' : '├';\n const continuation =\n continuationPrefix ??\n (isLastCommand && isLastSubcommand && !hasItemsAfter ? ' ' : formatDimText('│'));\n // For subcommands, account for \"| | -- \" = 7 chars (or \"| -- \" = 6 chars if continuation is space)\n const continuationStr = continuation === ' ' ? ' ' : continuation;\n const subTreePrefix = `${continuationStr} ${formatDimText(treeChar)}─ `;\n const subTreePrefixWidth = stringWidth(stripAnsi(subTreePrefix));\n const subRemainingWidth = LEFT_COLUMN_WIDTH - subTreePrefixWidth;\n const subcommandNamePadded = padToFixedWidth(subcmd.name(), subRemainingWidth);\n const subcommandNameColored = useColor ? cyan(subcommandNamePadded) : subcommandNamePadded;\n lines.push(\n `${formatDimText('│')} ${subTreePrefix}${subcommandNameColored} ${shortDescription}`,\n );\n }\n } else {\n // Standalone command - show command name and description on same line\n const treeChar = isLastCommand && !hasItemsAfter ? formatDimText('└') : formatDimText('├');\n const treePrefix = `${treeChar}─ `;\n const treePrefixWidth = stringWidth(stripAnsi(treePrefix));\n const remainingWidth = LEFT_COLUMN_WIDTH - treePrefixWidth;\n const commandNamePadded = padToFixedWidth(cmd.name(), remainingWidth);\n const commandNameColored = useColor ? cyan(commandNamePadded) : commandNamePadded;\n const shortDescription = cmd.description() || '';\n lines.push(`${formatDimText('│')} ${treePrefix}${commandNameColored} ${shortDescription}`);\n }\n }\n\n return lines;\n}\n\n/**\n * Formats the header in the new experimental visual style.\n * This header appears at the start of command output, showing the operation,\n * intent, documentation link, and parameters.\n */\nexport function formatStyledHeader(options: {\n readonly command: string;\n readonly description: string;\n readonly url?: string;\n readonly details: ReadonlyArray<{ readonly label: string; readonly value: string }>;\n readonly flags: GlobalFlags;\n}): string {\n const lines: string[] = [];\n const useColor = options.flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Header: arrow + operation badge + intent\n const brand = createPrismaNextBadge(useColor);\n // Use full command path (e.g., \"contract emit\" not just \"emit\")\n const operation = useColor ? bold(options.command) : options.command;\n const intent = formatDimText(options.description);\n lines.push(formatHeaderLine({ brand, operation, intent }));\n lines.push(formatDimText('│')); // Vertical line separator between command and params\n\n // Format details using fixed left column width (same style as help text options)\n for (const detail of options.details) {\n // Add colon to label, then pad to fixed width using padToFixedWidth for ANSI-aware padding\n const labelWithColon = `${detail.label}:`;\n const labelPadded = padToFixedWidth(labelWithColon, LEFT_COLUMN_WIDTH);\n const labelColored = useColor ? cyan(labelPadded) : labelPadded;\n lines.push(`${formatDimText('│')} ${labelColored} ${detail.value}`);\n }\n\n // Add \"Read more\" URL if present (same style as help text)\n if (options.url) {\n lines.push(formatDimText('│')); // Separator line before \"Read more\"\n lines.push(\n formatReadMoreLine({\n url: options.url,\n maxLabelWidth: LEFT_COLUMN_WIDTH,\n useColor,\n formatDimText,\n }),\n );\n }\n\n lines.push(formatDimText('└'));\n\n return `${lines.join('\\n')}\\n`;\n}\n\n/**\n * Formats a success message in the styled output format.\n */\nexport function formatSuccessMessage(flags: GlobalFlags): string {\n const useColor = flags.color !== false;\n const formatGreen = createColorFormatter(useColor, green);\n return `${formatGreen('✔')} Success`;\n}\n","import { blue, bold, cyan, dim, green, magenta } from 'colorette';\nimport type { Command } from 'commander';\nimport wrapAnsi from 'wrap-ansi';\n\nimport { getCommandExamples, getLongDescription } from '../command-helpers';\nimport type { GlobalFlags } from '../global-flags';\nimport { formatDim } from './helpers';\nimport { padToFixedWidth, renderCommandTree } from './styled';\n\n// ============================================================================\n// Help Output Formatters\n// ============================================================================\n\n/**\n * Fixed width for left column in help output.\n * Must match the value in styled.ts.\n */\nconst LEFT_COLUMN_WIDTH = 20;\n\n/**\n * Minimum width for right column wrapping in help output.\n */\nconst RIGHT_COLUMN_MIN_WIDTH = 40;\n\n/**\n * Maximum width for right column wrapping in help output (when terminal is wide enough).\n */\nconst RIGHT_COLUMN_MAX_WIDTH = 90;\n\n/**\n * Gets the terminal width, or returns a default if not available.\n */\nfunction getTerminalWidth(): number {\n // Help text goes to stderr, so prefer stderr columns. Fall back to stdout, then CLI_WIDTH env.\n const terminalWidth = process.stderr.columns || process.stdout.columns;\n const envWidth = Number.parseInt(process.env['CLI_WIDTH'] || '', 10);\n return terminalWidth || (Number.isFinite(envWidth) ? envWidth : 80);\n}\n\n/**\n * Calculates the available width for the right column based on terminal width.\n */\nfunction calculateRightColumnWidth(): number {\n const terminalWidth = getTerminalWidth();\n const availableWidth = terminalWidth - 2 - LEFT_COLUMN_WIDTH - 2;\n return Math.max(RIGHT_COLUMN_MIN_WIDTH, Math.min(availableWidth, RIGHT_COLUMN_MAX_WIDTH));\n}\n\n/**\n * Creates the CLI brand badge.\n */\nfunction createPrismaNextBadge(useColor: boolean): string {\n return useColor ? bold('prisma-next') : 'prisma-next';\n}\n\n/**\n * Formats a header line: brand + operation + intent\n */\nfunction formatHeaderLine(options: {\n readonly brand: string;\n readonly operation: string;\n readonly intent: string;\n}): string {\n if (options.operation) {\n return `${options.brand} ${options.operation} → ${options.intent}`;\n }\n return `${options.brand} ${options.intent}`;\n}\n\n/**\n * Wraps text to fit within a specified width using wrap-ansi.\n */\nfunction wrapTextAnsi(text: string, width: number): string[] {\n const wrapped = wrapAnsi(text, width, { hard: false, trim: true });\n return wrapped.split('\\n');\n}\n\n/**\n * Formats a default value as \"default: <value>\" with dimming.\n */\nfunction formatDefaultValue(value: unknown, useColor: boolean): string {\n const valueStr = String(value);\n const defaultText = `default: ${valueStr}`;\n return useColor ? dim(defaultText) : defaultText;\n}\n\n/**\n * Formats a \"Read more\" URL line.\n */\nfunction formatReadMoreLine(options: {\n readonly url: string;\n readonly maxLabelWidth: number;\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n}): string {\n const labelPadded = `Read more${' '.repeat(Math.max(0, options.maxLabelWidth - 'Read more'.length))}`;\n const valueColored = options.useColor ? blue(options.url) : options.url;\n return `${options.formatDimText('│')} ${labelPadded} ${valueColored}`;\n}\n\n/**\n * Formats multiline description with \"Prisma Next\" in green.\n */\nfunction formatMultilineDescription(options: {\n readonly descriptionLines: readonly string[];\n readonly useColor: boolean;\n readonly formatDimText: (text: string) => string;\n}): string[] {\n const lines: string[] = [];\n const formatGreen = (text: string) => (options.useColor ? green(text) : text);\n\n const rightColumnWidth = calculateRightColumnWidth();\n const totalWidth = 2 + LEFT_COLUMN_WIDTH + 2 + rightColumnWidth;\n const wrapWidth = totalWidth - 2;\n\n for (const descLine of options.descriptionLines) {\n const formattedLine = descLine.replace(/Prisma Next/g, (match) => formatGreen(match));\n const wrappedLines = wrapTextAnsi(formattedLine, wrapWidth);\n for (const wrappedLine of wrappedLines) {\n lines.push(`${options.formatDimText('│')} ${wrappedLine}`);\n }\n }\n return lines;\n}\n\n/**\n * Maps command paths to their documentation URLs.\n */\nfunction getCommandDocsUrl(commandPath: string): string | undefined {\n const docsMap: Record<string, string> = {\n 'contract emit': 'https://pris.ly/contract-emit',\n 'contract infer': 'https://pris.ly/contract-infer',\n 'db schema': 'https://pris.ly/db-schema',\n 'db verify': 'https://pris.ly/db-verify',\n 'db update': 'https://pris.ly/db-update',\n 'migration plan': 'https://pris.ly/migration-plan',\n 'migration apply': 'https://pris.ly/migration-apply',\n 'migration show': 'https://pris.ly/migration-show',\n 'migration status': 'https://pris.ly/migration-status',\n };\n return docsMap[commandPath];\n}\n\n/**\n * Builds the full command path from a command and its parents.\n */\nfunction buildCommandPath(command: Command): string {\n const parts: string[] = [];\n let current: Command | undefined = command;\n while (current && current.name() !== 'prisma-next') {\n parts.unshift(current.name());\n current = current.parent ?? undefined;\n }\n return parts.join(' ');\n}\n\n/**\n * Formats help output for a command using the styled format.\n */\nexport function formatCommandHelp(options: {\n readonly command: Command;\n readonly flags: GlobalFlags;\n}): string {\n const { command, flags } = options;\n const lines: string[] = [];\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Build full command path (e.g., \"db verify\")\n const commandPath = buildCommandPath(command);\n const shortDescription = command.description() || '';\n const longDescription = getLongDescription(command);\n\n // Include positional arguments in the header line\n const argsSuffix = command.registeredArguments\n .map((arg) => (arg.required ? `<${arg.name()}>` : `[${arg.name()}]`))\n .join(' ');\n const brand = createPrismaNextBadge(useColor);\n const commandWithArgs = argsSuffix ? `${commandPath} ${argsSuffix}` : commandPath;\n const operation = useColor ? bold(commandWithArgs) : commandWithArgs;\n const intent = formatDimText(shortDescription);\n lines.push(formatHeaderLine({ brand, operation, intent }));\n lines.push(formatDimText('│'));\n\n // Extract options and format them\n const optionsList = command.options.map((opt) => {\n const description = opt.description || '';\n // Commander.js stores default value in defaultValue property\n const defaultValue = (opt as { defaultValue?: unknown }).defaultValue;\n return { flags: opt.flags, description, defaultValue };\n });\n\n // Extract subcommands if any\n const subcommands = command.commands.filter((cmd) => !cmd.name().startsWith('_'));\n\n // Format subcommands as a tree if present\n if (subcommands.length > 0) {\n const hasItemsAfter = optionsList.length > 0;\n const treeLines = renderCommandTree({\n commands: subcommands,\n useColor,\n formatDimText,\n hasItemsAfter,\n });\n lines.push(...treeLines);\n }\n\n // Add separator between subcommands and options if both exist\n if (subcommands.length > 0 && optionsList.length > 0) {\n lines.push(formatDimText('│'));\n }\n\n // Format options with fixed width, wrapping, and default values\n if (optionsList.length > 0) {\n for (const opt of optionsList) {\n // Format flag with fixed 30-char width\n const flagsPadded = padToFixedWidth(opt.flags, LEFT_COLUMN_WIDTH);\n let flagsColored = flagsPadded;\n if (useColor) {\n // Color placeholders in magenta, then wrap in cyan\n flagsColored = flagsPadded.replace(/(<[^>]+>)/g, (match: string) => magenta(match));\n flagsColored = cyan(flagsColored);\n }\n\n // Wrap description based on terminal width\n const rightColumnWidth = calculateRightColumnWidth();\n const wrappedDescription = wrapTextAnsi(opt.description, rightColumnWidth);\n\n // First line: flag + first line of description\n lines.push(`${formatDimText('│')} ${flagsColored} ${wrappedDescription[0] || ''}`);\n\n // Continuation lines: empty label (30 spaces) + wrapped lines\n for (let i = 1; i < wrappedDescription.length; i++) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${wrappedDescription[i] || ''}`);\n }\n\n // Default value line (if present)\n if (opt.defaultValue !== undefined) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n const defaultText = formatDefaultValue(opt.defaultValue, useColor);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${defaultText}`);\n }\n }\n }\n\n // Add docs URL if available (with separator line before it)\n const docsUrl = getCommandDocsUrl(commandPath);\n if (docsUrl) {\n lines.push(formatDimText('│')); // Separator line between params and docs\n lines.push(\n formatReadMoreLine({\n url: docsUrl,\n maxLabelWidth: LEFT_COLUMN_WIDTH,\n useColor,\n formatDimText,\n }),\n );\n }\n\n // Examples (copy-pastable)\n const examples = getCommandExamples(command);\n if (examples && examples.length > 0) {\n lines.push(formatDimText('│'));\n lines.push(`${formatDimText('│')} ${formatDimText('Examples:')}`);\n for (const example of examples) {\n lines.push(`${formatDimText('│')} ${useColor ? dim('$') : '$'} ${example}`);\n }\n }\n\n // Multi-line description (if present) - shown after all other content\n if (longDescription) {\n lines.push(formatDimText('│'));\n const descriptionLines = longDescription.split('\\n').filter((line) => line.trim().length > 0);\n lines.push(...formatMultilineDescription({ descriptionLines, useColor, formatDimText }));\n }\n\n lines.push(formatDimText('└'));\n\n return `${lines.join('\\n')}\\n`;\n}\n\n/**\n * Formats help output for the root program using the styled format.\n */\nexport function formatRootHelp(options: {\n readonly program: Command;\n readonly flags: GlobalFlags;\n}): string {\n const { program, flags } = options;\n const lines: string[] = [];\n const useColor = flags.color !== false;\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n // Header: \"prisma-next -> Manage your data layer\"\n const brand = createPrismaNextBadge(useColor);\n const shortDescription = 'Manage your data layer';\n const intent = formatDimText(shortDescription);\n lines.push(formatHeaderLine({ brand, operation: '', intent }));\n lines.push(formatDimText('│')); // Vertical line separator after header\n\n // Extract top-level commands (exclude hidden commands starting with '_' and the 'help' command)\n const topLevelCommands = program.commands.filter(\n (cmd) => !cmd.name().startsWith('_') && cmd.name() !== 'help',\n );\n\n // Extract global options (needed to determine if last command)\n const globalOptions = program.options.map((opt) => {\n const description = opt.description || '';\n // Commander.js stores default value in defaultValue property\n const defaultValue = (opt as { defaultValue?: unknown }).defaultValue;\n return { flags: opt.flags, description, defaultValue };\n });\n\n // Build command tree\n if (topLevelCommands.length > 0) {\n const hasItemsAfter = globalOptions.length > 0;\n const treeLines = renderCommandTree({\n commands: topLevelCommands,\n useColor,\n formatDimText,\n hasItemsAfter,\n });\n lines.push(...treeLines);\n }\n\n // Add separator between commands and options if both exist\n if (topLevelCommands.length > 0 && globalOptions.length > 0) {\n lines.push(formatDimText('│'));\n }\n\n // Format global options with fixed width, wrapping, and default values\n if (globalOptions.length > 0) {\n for (const opt of globalOptions) {\n // Format flag with fixed 30-char width\n const flagsPadded = padToFixedWidth(opt.flags, LEFT_COLUMN_WIDTH);\n let flagsColored = flagsPadded;\n if (useColor) {\n // Color placeholders in magenta, then wrap in cyan\n flagsColored = flagsPadded.replace(/(<[^>]+>)/g, (match: string) => magenta(match));\n flagsColored = cyan(flagsColored);\n }\n\n // Wrap description based on terminal width\n const rightColumnWidth = calculateRightColumnWidth();\n const wrappedDescription = wrapTextAnsi(opt.description, rightColumnWidth);\n\n // First line: flag + first line of description\n lines.push(`${formatDimText('│')} ${flagsColored} ${wrappedDescription[0] || ''}`);\n\n // Continuation lines: empty label (30 spaces) + wrapped lines\n for (let i = 1; i < wrappedDescription.length; i++) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${wrappedDescription[i] || ''}`);\n }\n\n // Default value line (if present)\n if (opt.defaultValue !== undefined) {\n const emptyLabel = ' '.repeat(LEFT_COLUMN_WIDTH);\n const defaultText = formatDefaultValue(opt.defaultValue, useColor);\n lines.push(`${formatDimText('│')} ${emptyLabel} ${defaultText}`);\n }\n }\n }\n\n // Multi-line description (white, not dimmed, with \"Prisma Next\" in green) - shown at bottom\n const formatGreen = (text: string) => (useColor ? green(text) : text);\n const descriptionLines = [\n `Use ${formatGreen('Prisma Next')} to define your data layer as a contract. Sign your database and application with the same contract to guarantee compatibility. Plan and apply migrations to safely evolve your schema.`,\n ];\n if (descriptionLines.length > 0) {\n lines.push(formatDimText('│')); // Separator line before description\n lines.push(...formatMultilineDescription({ descriptionLines, useColor, formatDimText }));\n }\n\n lines.push(formatDimText('└'));\n\n return `${lines.join('\\n')}\\n`;\n}\n","export interface GlobalFlags {\n readonly json?: boolean;\n readonly quiet?: boolean;\n readonly verbose?: number; // 0, 1, or 2\n readonly color?: boolean;\n readonly interactive?: boolean;\n readonly yes?: boolean;\n}\n\n/**\n * Common options parsed by Commander.js for every command.\n * Extend this for command-specific options instead of duplicating these fields.\n */\nexport interface CommonCommandOptions {\n readonly json?: string | boolean;\n readonly quiet?: boolean;\n readonly q?: boolean;\n readonly verbose?: boolean;\n readonly v?: boolean;\n readonly trace?: boolean;\n readonly color?: boolean;\n readonly 'no-color'?: boolean;\n readonly interactive?: boolean;\n readonly 'no-interactive'?: boolean;\n readonly yes?: boolean;\n readonly y?: boolean;\n}\n\n/**\n * Parses global flags from CLI options.\n * Handles verbosity flags (-v, --trace), JSON output, quiet mode, color,\n * interactivity (--interactive/--no-interactive), and auto-accept (-y/--yes).\n */\nexport function parseGlobalFlags(options: CommonCommandOptions): GlobalFlags {\n const flags: {\n json?: boolean;\n quiet?: boolean;\n verbose?: number;\n color?: boolean;\n interactive?: boolean;\n yes?: boolean;\n } = {};\n\n // JSON output: explicit --json flag or auto-detect piped stdout (Unix convention)\n if (options.json || !process.stdout.isTTY) {\n flags.json = true;\n }\n\n // Quiet mode\n if (options.quiet || options.q) {\n flags.quiet = true;\n }\n\n // Verbosity: -v = 1, --trace = 2\n // Env toggles: PRISMA_NEXT_TRACE=1 ≅ --trace, PRISMA_NEXT_DEBUG=1 ≅ -v\n if (options.trace || process.env['PRISMA_NEXT_TRACE'] === '1') {\n flags.verbose = 2;\n } else if (options.verbose || options.v || process.env['PRISMA_NEXT_DEBUG'] === '1') {\n flags.verbose = 1;\n } else {\n flags.verbose = 0;\n }\n\n // Color: respect NO_COLOR env var, --color/--no-color flags\n // When JSON output is enabled, disable color to ensure clean JSON output\n if (process.env['NO_COLOR'] || flags.json) {\n flags.color = false;\n } else if (options['no-color']) {\n flags.color = false;\n } else if (options.color !== undefined) {\n flags.color = options.color;\n } else {\n // Default: enable color if TTY\n flags.color = process.stdout.isTTY && !process.env['CI'];\n }\n\n // Interactivity: --interactive/--no-interactive\n // Default: interactive when stdout is a TTY\n if (options['no-interactive']) {\n flags.interactive = false;\n } else if (options.interactive !== undefined) {\n flags.interactive = options.interactive;\n } else {\n flags.interactive = !!process.stdout.isTTY;\n }\n\n // Auto-accept prompts: -y/--yes\n if (options.yes || options.y) {\n flags.yes = true;\n }\n\n return flags as GlobalFlags;\n}\n","import { readFile } from 'node:fs/promises';\nimport type { ControlTargetDescriptor } from '@prisma-next/framework-components/control';\nimport { hasMigrations } from '@prisma-next/framework-components/control';\nimport type { PathDecision } from '@prisma-next/migration-tools/dag';\nimport { reconstructGraph } from '@prisma-next/migration-tools/dag';\nimport { readMigrationsDir } from '@prisma-next/migration-tools/io';\nimport type { MigrationBundle, MigrationGraph } from '@prisma-next/migration-tools/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { Command } from 'commander';\nimport { relative, resolve } from 'pathe';\nimport { formatCommandHelp } from './formatters/help';\nimport type { CommonCommandOptions } from './global-flags';\nimport { parseGlobalFlags } from './global-flags';\n\nconst longDescriptions = new WeakMap<Command, string>();\nconst commandExamples = new WeakMap<Command, readonly string[]>();\n\n/**\n * Sets both short and long descriptions for a command.\n * The short description is used in command trees and headers.\n * The long description is shown at the bottom of help output.\n */\nexport function setCommandDescriptions(\n command: Command,\n shortDescription: string,\n longDescription?: string,\n): Command {\n command.description(shortDescription);\n if (longDescription) {\n longDescriptions.set(command, longDescription);\n }\n return command;\n}\n\n/**\n * Sets copy-pastable examples for a command, shown in help text.\n */\nexport function setCommandExamples(command: Command, examples: readonly string[]): Command {\n commandExamples.set(command, examples);\n return command;\n}\n\n/**\n * Gets the long description from a command if it was set via setCommandDescriptions.\n */\nexport function getLongDescription(command: Command): string | undefined {\n return longDescriptions.get(command);\n}\n\n/**\n * Gets examples from a command if set via setCommandExamples.\n */\nexport function getCommandExamples(command: Command): readonly string[] | undefined {\n return commandExamples.get(command);\n}\n\n/**\n * Shared CLI options interface for migration commands (db init, db update).\n * These are the Commander.js parsed options common to both commands.\n */\nexport interface MigrationCommandOptions extends CommonCommandOptions {\n readonly db?: string;\n readonly config?: string;\n readonly dryRun?: boolean;\n}\n\n/**\n * Resolves the absolute path to contract.json from the config.\n * Centralises the fallback logic shared by every command that reads the contract.\n */\nexport function resolveContractPath(config: { contract?: { output?: string } }): string {\n return config.contract?.output\n ? resolve(config.contract.output)\n : resolve('src/prisma/contract.json');\n}\n\n/**\n * Resolves the migrations directory and config path from CLI options.\n * Shared by migration-apply, migration-plan, and migration-status.\n */\nexport function resolveMigrationPaths(\n configOption: string | undefined,\n config: { migrations?: { dir?: string } },\n): {\n configPath: string;\n migrationsDir: string;\n migrationsRelative: string;\n refsDir: string;\n} {\n const configPath = configOption\n ? relative(process.cwd(), resolve(configOption))\n : 'prisma-next.config.ts';\n const migrationsDir = resolve(\n configOption ? resolve(configOption, '..') : process.cwd(),\n config.migrations?.dir ?? 'migrations',\n );\n const migrationsRelative = relative(process.cwd(), migrationsDir);\n const refsDir = resolve(migrationsDir, 'refs');\n return { configPath, migrationsDir, migrationsRelative, refsDir };\n}\n\n/**\n * Slim representation of a PathDecision for CLI JSON output.\n * Strips internal fields (createdAt, labels) from path entries.\n */\nexport interface PathDecisionResult {\n readonly fromHash: string;\n readonly toHash: string;\n readonly alternativeCount: number;\n readonly tieBreakReasons: readonly string[];\n readonly refName?: string;\n readonly selectedPath: readonly {\n readonly dirName: string;\n readonly migrationId: string;\n readonly from: string;\n readonly to: string;\n }[];\n}\n\n/**\n * Maps a PathDecision to the slim CLI output representation.\n */\nexport function toPathDecisionResult(decision: PathDecision): PathDecisionResult {\n return {\n fromHash: decision.fromHash,\n toHash: decision.toHash,\n alternativeCount: decision.alternativeCount,\n tieBreakReasons: decision.tieBreakReasons,\n ...ifDefined('refName', decision.refName),\n selectedPath: decision.selectedPath.map((entry) => ({\n dirName: entry.dirName,\n migrationId: entry.migrationId,\n from: entry.from,\n to: entry.to,\n })),\n };\n}\n\nexport function targetSupportsMigrations(target: ControlTargetDescriptor<string, string>): boolean {\n return hasMigrations(target);\n}\n\nexport function getTargetMigrations(target: ControlTargetDescriptor<string, string>) {\n return hasMigrations(target) ? target.migrations : undefined;\n}\n\n/**\n * Reads the migrations directory and builds the migration graph from all\n * bundles. Throws on I/O or graph errors — callers handle error mapping.\n *\n * Every on-disk bundle is content-addressed (`migrationId` is always a\n * string); there is no draft state to filter out.\n */\nexport async function loadMigrationBundles(migrationsDir: string): Promise<{\n bundles: readonly MigrationBundle[];\n graph: MigrationGraph;\n}> {\n const bundles = await readMigrationsDir(migrationsDir);\n const graph = reconstructGraph(bundles);\n return { bundles, graph };\n}\n\nexport interface MigrationBundleSet {\n readonly bundles: readonly MigrationBundle[];\n readonly graph: MigrationGraph;\n}\n\n/**\n * Alias of `loadMigrationBundles` retained for naming-clarity in commands\n * that previously needed both attested and draft splits. With the\n * collapse of the draft state, both helpers do the same thing.\n */\nexport async function loadAllBundles(migrationsDir: string): Promise<MigrationBundleSet> {\n return loadMigrationBundles(migrationsDir);\n}\n\n/**\n * The subset of the emitted contract.json that the framework layer can\n * safely type. The emitter adds these fields on top of the family-specific\n * storage/models/relations. Other fields exist in the JSON but are opaque\n * at this layer — the index signature preserves them for downstream\n * consumers that operate at the family level (e.g., the control client).\n */\nexport interface ContractEnvelope {\n readonly storageHash: string;\n readonly schemaVersion: string;\n readonly target: string;\n readonly targetFamily: string;\n readonly profileHash?: string;\n readonly [key: string]: unknown;\n}\n\n/**\n * Reads and parses contract.json, validating the framework-level envelope\n * fields (storageHash, schemaVersion, target, targetFamily).\n *\n * Family-specific validation (storage structure, codec mappings, etc.)\n * happens downstream in the control client via the family instance.\n */\nexport async function readContractEnvelope(config: {\n contract?: { output?: string };\n}): Promise<ContractEnvelope> {\n const contractPath = resolveContractPath(config);\n const content = await readFile(contractPath, 'utf-8');\n const json = JSON.parse(content) as Record<string, unknown>;\n\n const { schemaVersion, target, targetFamily, profileHash } = json;\n const storage = json['storage'] as Record<string, unknown> | undefined;\n const storageHash = storage?.['storageHash'];\n\n if (typeof storageHash !== 'string') {\n throw new Error(\n `Contract at ${relative(process.cwd(), contractPath)} is missing a valid storage.storageHash. Run \\`prisma-next contract emit\\` to regenerate.`,\n );\n }\n if (typeof schemaVersion !== 'string') {\n throw new Error(\n `Contract at ${relative(process.cwd(), contractPath)} is missing schemaVersion.`,\n );\n }\n if (typeof target !== 'string') {\n throw new Error(`Contract at ${relative(process.cwd(), contractPath)} is missing target.`);\n }\n if (typeof targetFamily !== 'string') {\n throw new Error(\n `Contract at ${relative(process.cwd(), contractPath)} is missing targetFamily.`,\n );\n }\n\n return {\n ...json,\n storageHash,\n schemaVersion,\n target,\n targetFamily,\n ...(typeof profileHash === 'string' ? { profileHash } : {}),\n };\n}\n\n/**\n * Masks credentials in a database connection URL.\n * Handles standard URLs (username + password + query params) and libpq-style key=value strings.\n */\nexport function maskConnectionUrl(url: string): string {\n try {\n const parsed = new URL(url);\n if (parsed.username) {\n parsed.username = '****';\n }\n if (parsed.password) {\n parsed.password = '****';\n }\n // Also mask password in query parameters (e.g., ?password=secret, ?sslpassword=secret)\n for (const key of [...parsed.searchParams.keys()]) {\n if (/password/i.test(key)) {\n parsed.searchParams.set(key, '****');\n }\n }\n return parsed.toString();\n } catch {\n // Fallback for libpq-style key=value connection strings (e.g., \"host=localhost password=secret user=admin\")\n return url\n .replace(/password\\s*=\\s*\\S+/gi, 'password=****')\n .replace(/user\\s*=\\s*\\S+/gi, 'user=****');\n }\n}\n\n/**\n * Strips raw connection URL fragments from an error message to prevent credential leakage.\n * Call this before surfacing driver errors to the user.\n */\nexport function sanitizeErrorMessage(message: string, connectionUrl?: string): string {\n if (!connectionUrl) {\n return message;\n }\n try {\n const parsed = new URL(connectionUrl);\n // Replace the full URL (with and without trailing slash)\n let sanitized = message;\n sanitized = sanitized.replaceAll(connectionUrl, maskConnectionUrl(connectionUrl));\n // Also replace the password and username individually if they appear\n if (parsed.password) {\n sanitized = sanitized.replaceAll(parsed.password, '****');\n }\n if (parsed.username) {\n sanitized = sanitized.replaceAll(parsed.username, '****');\n }\n return sanitized;\n } catch {\n // For libpq-style strings, mask password and user values in the message\n return message\n .replace(/password\\s*=\\s*\\S+/gi, 'password=****')\n .replace(/user\\s*=\\s*\\S+/gi, 'user=****');\n }\n}\n\n/**\n * Registers the global CLI options shared by every command:\n * --json, -q/--quiet, -v/--verbose, --trace, --color, --no-color,\n * --interactive, --no-interactive, -y/--yes.\n *\n * Also sets up the styled help formatter.\n */\nexport function addGlobalOptions(command: Command): Command {\n return command\n .configureHelp({\n formatHelp: (cmd) => {\n const flags = parseGlobalFlags({});\n return formatCommandHelp({ command: cmd, flags });\n },\n })\n .option('--json', 'Output as JSON')\n .option('-q, --quiet', 'Quiet mode: errors only')\n .option('-v, --verbose', 'Verbose output: debug info, timings')\n .option('--trace', 'Trace output: deep internals, stack traces')\n .option('--color', 'Force color output')\n .option('--no-color', 'Disable color output')\n .option('--interactive', 'Force interactive mode')\n .option('--no-interactive', 'Disable interactive prompts')\n .option('-y, --yes', 'Auto-accept prompts');\n}\n","import { red } from 'colorette';\n\nimport type { CliErrorConflict, CliErrorEnvelope } from '../cli-errors';\nimport type { GlobalFlags } from '../global-flags';\nimport { createColorFormatter, formatDim, isVerbose } from './helpers';\n\n/**\n * Formats error output for human-readable display.\n */\nexport function formatErrorOutput(error: CliErrorEnvelope, flags: GlobalFlags): string {\n const lines: string[] = [];\n\n const useColor = flags.color !== false;\n const formatRed = createColorFormatter(useColor, red);\n const formatDimText = (text: string) => formatDim(useColor, text);\n\n lines.push(`${formatRed('✖')} ${error.summary} (${error.code})`);\n\n if (error.why) {\n lines.push(`${formatDimText(` Why: ${error.why}`)}`);\n }\n if (error.fix) {\n lines.push(`${formatDimText(` Fix: ${error.fix}`)}`);\n }\n if (error.where?.path) {\n const whereLine = error.where.line\n ? `${error.where.path}:${error.where.line}`\n : error.where.path;\n lines.push(`${formatDimText(` Where: ${whereLine}`)}`);\n }\n // Show conflicts list if present (always show a short list; show full list when verbose)\n if (error.meta?.['conflicts']) {\n const conflicts = error.meta['conflicts'] as readonly CliErrorConflict[];\n if (conflicts.length > 0) {\n const maxToShow = isVerbose(flags, 1) ? conflicts.length : Math.min(3, conflicts.length);\n const header = isVerbose(flags, 1)\n ? ' Conflicts:'\n : ` Conflicts (showing ${maxToShow} of ${conflicts.length}):`;\n lines.push(`${formatDimText(header)}`);\n for (const conflict of conflicts.slice(0, maxToShow)) {\n lines.push(`${formatDimText(` - [${conflict.kind}] ${conflict.summary}`)}`);\n }\n if (!isVerbose(flags, 1) && conflicts.length > maxToShow) {\n lines.push(`${formatDimText(' Re-run with -v/--verbose to see all conflicts')}`);\n }\n }\n }\n // Show issues list if present (always show a short list; show full list when verbose)\n if (error.meta?.['issues']) {\n const issues = error.meta['issues'] as readonly { kind?: string; message?: string }[];\n if (issues.length > 0) {\n const maxToShow = isVerbose(flags, 1) ? issues.length : Math.min(3, issues.length);\n const header = isVerbose(flags, 1)\n ? ' Issues:'\n : ` Issues (showing ${maxToShow} of ${issues.length}):`;\n lines.push(`${formatDimText(header)}`);\n for (const issue of issues.slice(0, maxToShow)) {\n const kind = issue.kind ?? 'issue';\n const message = issue.message ?? '';\n lines.push(`${formatDimText(` - [${kind}] ${message}`)}`);\n }\n if (!isVerbose(flags, 1) && issues.length > maxToShow) {\n lines.push(`${formatDimText(' Re-run with -v/--verbose to see all issues')}`);\n }\n }\n }\n if (error.docsUrl && isVerbose(flags, 1)) {\n lines.push(formatDimText(error.docsUrl));\n }\n if (isVerbose(flags, 2) && error.meta) {\n lines.push(`${formatDimText(` Meta: ${JSON.stringify(error.meta, null, 2)}`)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Formats error output as JSON.\n */\nexport function formatErrorJson(error: CliErrorEnvelope): string {\n return JSON.stringify(error, null, 2);\n}\n","import type { Result } from '@prisma-next/utils/result';\nimport type { CliStructuredError } from './cli-errors';\nimport { formatErrorJson, formatErrorOutput } from './formatters/errors';\nimport type { GlobalFlags } from './global-flags';\nimport type { TerminalUI } from './terminal-ui';\n\n/**\n * Processes a CLI command result, handling both success and error cases.\n * Formats output appropriately and returns the exit code.\n * Never throws - returns exit code for commands to use with process.exit().\n *\n * Error output:\n * - JSON mode: JSON error to stdout (piped) via ui.output(), human sees nothing on stderr.\n * - Interactive: human-readable error to stderr.\n */\nexport function handleResult<T>(\n result: Result<T, CliStructuredError>,\n flags: GlobalFlags,\n ui: TerminalUI,\n onSuccess?: (value: T) => void,\n): number {\n if (result.ok) {\n if (onSuccess) {\n onSuccess(result.value);\n }\n return 0;\n }\n\n // Convert to CLI envelope\n const envelope = result.failure.toEnvelope();\n\n if (flags.json) {\n // JSON error → stdout only\n ui.output(formatErrorJson(envelope));\n } else {\n // Human-readable error → stderr\n ui.error(formatErrorOutput(envelope, flags));\n }\n\n // Infer exit code from error domain: CLI errors = 2, RUN errors = 1\n const exitCode = result.failure.domain === 'CLI' ? 2 : 1;\n return exitCode;\n}\n"],"mappings":"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"}