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

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 (165) hide show
  1. package/README.md +56 -21
  2. package/dist/agent-skill-mongo.md +63 -31
  3. package/dist/agent-skill-postgres.md +1 -1
  4. package/dist/cli-errors-By1iVE3z.mjs +34 -0
  5. package/dist/cli-errors-By1iVE3z.mjs.map +1 -0
  6. package/dist/{cli-errors-C0JhVj0c.d.mts → cli-errors-DDeVsP2Y.d.mts} +1 -0
  7. package/dist/cli.mjs +123 -15
  8. package/dist/cli.mjs.map +1 -1
  9. package/dist/{client-TG7rbCWT.mjs → client-1JqqkiC7.mjs} +45 -20
  10. package/dist/client-1JqqkiC7.mjs.map +1 -0
  11. package/dist/commands/contract-emit.d.mts.map +1 -1
  12. package/dist/commands/contract-emit.mjs +2 -2
  13. package/dist/commands/contract-infer.d.mts.map +1 -1
  14. package/dist/commands/contract-infer.mjs +2 -2
  15. package/dist/commands/db-init.d.mts.map +1 -1
  16. package/dist/commands/db-init.mjs +10 -9
  17. package/dist/commands/db-init.mjs.map +1 -1
  18. package/dist/commands/db-schema.mjs +5 -5
  19. package/dist/commands/db-sign.mjs +7 -7
  20. package/dist/commands/db-update.mjs +9 -9
  21. package/dist/commands/db-update.mjs.map +1 -1
  22. package/dist/commands/db-verify.mjs +9 -9
  23. package/dist/commands/migration-apply.d.mts +5 -2
  24. package/dist/commands/migration-apply.d.mts.map +1 -1
  25. package/dist/commands/migration-apply.mjs +55 -56
  26. package/dist/commands/migration-apply.mjs.map +1 -1
  27. package/dist/commands/migration-new.d.mts.map +1 -1
  28. package/dist/commands/migration-new.mjs +26 -32
  29. package/dist/commands/migration-new.mjs.map +1 -1
  30. package/dist/commands/migration-plan.d.mts +14 -5
  31. package/dist/commands/migration-plan.d.mts.map +1 -1
  32. package/dist/commands/migration-plan.mjs +45 -48
  33. package/dist/commands/migration-plan.mjs.map +1 -1
  34. package/dist/commands/migration-ref.d.mts +1 -1
  35. package/dist/commands/migration-ref.d.mts.map +1 -1
  36. package/dist/commands/migration-ref.mjs +6 -10
  37. package/dist/commands/migration-ref.mjs.map +1 -1
  38. package/dist/commands/migration-show.d.mts +13 -7
  39. package/dist/commands/migration-show.d.mts.map +1 -1
  40. package/dist/commands/migration-show.mjs +27 -29
  41. package/dist/commands/migration-show.mjs.map +1 -1
  42. package/dist/commands/migration-status.d.mts +23 -5
  43. package/dist/commands/migration-status.d.mts.map +1 -1
  44. package/dist/commands/migration-status.mjs +3 -3
  45. package/dist/{config-loader-_W4T21X1.mjs → config-loader-ih8ViDb_.mjs} +2 -2
  46. package/dist/config-loader-ih8ViDb_.mjs.map +1 -0
  47. package/dist/config-loader.mjs +1 -1
  48. package/dist/contract-emit-LjzCoicC.mjs +4 -0
  49. package/dist/contract-emit-RZBWzkop.mjs +329 -0
  50. package/dist/contract-emit-RZBWzkop.mjs.map +1 -0
  51. package/dist/contract-emit-rt_Nmdwq.mjs +150 -0
  52. package/dist/contract-emit-rt_Nmdwq.mjs.map +1 -0
  53. package/dist/{contract-enrichment-CGW6mm-E.mjs → contract-enrichment-4Ptgw3Pe.mjs} +1 -1
  54. package/dist/{contract-enrichment-CGW6mm-E.mjs.map → contract-enrichment-4Ptgw3Pe.mjs.map} +1 -1
  55. package/dist/{contract-infer-BS4kIX9c.mjs → contract-infer-Cf5J2wVg.mjs} +11 -19
  56. package/dist/contract-infer-Cf5J2wVg.mjs.map +1 -0
  57. package/dist/exports/control-api.d.mts +86 -21
  58. package/dist/exports/control-api.d.mts.map +1 -1
  59. package/dist/exports/control-api.mjs +5 -5
  60. package/dist/exports/index.mjs +3 -3
  61. package/dist/exports/init-output.d.mts +39 -0
  62. package/dist/exports/init-output.d.mts.map +1 -0
  63. package/dist/exports/init-output.mjs +3 -0
  64. package/dist/{framework-components-DfZKQBQ2.mjs → framework-components-Bgcre3Z6.mjs} +2 -2
  65. package/dist/{framework-components-DfZKQBQ2.mjs.map → framework-components-Bgcre3Z6.mjs.map} +1 -1
  66. package/dist/init-C7dE9KOJ.mjs +2062 -0
  67. package/dist/init-C7dE9KOJ.mjs.map +1 -0
  68. package/dist/{inspect-live-schema-BsoFVoS1.mjs → inspect-live-schema-LWtXfxm_.mjs} +9 -9
  69. package/dist/inspect-live-schema-LWtXfxm_.mjs.map +1 -0
  70. package/dist/migration-cli.d.mts +41 -11
  71. package/dist/migration-cli.d.mts.map +1 -1
  72. package/dist/migration-cli.mjs +308 -84
  73. package/dist/migration-cli.mjs.map +1 -1
  74. package/dist/{migration-command-scaffold-DOXnheFa.mjs → migration-command-scaffold-CU452v9h.mjs} +7 -7
  75. package/dist/{migration-command-scaffold-DOXnheFa.mjs.map → migration-command-scaffold-CU452v9h.mjs.map} +1 -1
  76. package/dist/{migration-status-Ry3TnEya.mjs → migration-status-DoPrFIOQ.mjs} +114 -57
  77. package/dist/migration-status-DoPrFIOQ.mjs.map +1 -0
  78. package/dist/{migrations-fU0xoKjS.mjs → migrations-MEoKMiV5.mjs} +42 -21
  79. package/dist/migrations-MEoKMiV5.mjs.map +1 -0
  80. package/dist/output-BpcQrnnq.mjs +103 -0
  81. package/dist/output-BpcQrnnq.mjs.map +1 -0
  82. package/dist/{progress-adapter-B-YvmcDu.mjs → progress-adapter-DgRGldpT.mjs} +1 -1
  83. package/dist/{progress-adapter-B-YvmcDu.mjs.map → progress-adapter-DgRGldpT.mjs.map} +1 -1
  84. package/dist/quick-reference-mongo.md +34 -13
  85. package/dist/quick-reference-postgres.md +11 -9
  86. package/dist/{result-handler-BJwA7ufw.mjs → result-handler-Ch6hVnOo.mjs} +35 -93
  87. package/dist/result-handler-Ch6hVnOo.mjs.map +1 -0
  88. package/dist/{terminal-ui-C5k88MmW.mjs → terminal-ui-u2YgKghu.mjs} +76 -2
  89. package/dist/terminal-ui-u2YgKghu.mjs.map +1 -0
  90. package/dist/{verify-bl__PkXk.mjs → verify-BT9tgCOH.mjs} +2 -2
  91. package/dist/{verify-bl__PkXk.mjs.map → verify-BT9tgCOH.mjs.map} +1 -1
  92. package/package.json +22 -16
  93. package/src/cli.ts +32 -6
  94. package/src/commands/contract-emit.ts +67 -163
  95. package/src/commands/contract-infer.ts +7 -20
  96. package/src/commands/db-init.ts +1 -0
  97. package/src/commands/db-update.ts +1 -1
  98. package/src/commands/init/detect-pnpm-catalog.ts +141 -0
  99. package/src/commands/init/errors.ts +254 -0
  100. package/src/commands/init/exit-codes.ts +62 -0
  101. package/src/commands/init/hygiene-gitattributes.ts +97 -0
  102. package/src/commands/init/hygiene-gitignore.ts +48 -0
  103. package/src/commands/init/hygiene-package-scripts.ts +91 -0
  104. package/src/commands/init/index.ts +112 -7
  105. package/src/commands/init/init.ts +766 -144
  106. package/src/commands/init/inputs.ts +421 -0
  107. package/src/commands/init/output.ts +147 -0
  108. package/src/commands/init/probe-db.ts +308 -0
  109. package/src/commands/init/reinit-cleanup.ts +83 -0
  110. package/src/commands/init/templates/agent-skill-mongo.md +63 -31
  111. package/src/commands/init/templates/agent-skill-postgres.md +1 -1
  112. package/src/commands/init/templates/agent-skill.ts +25 -3
  113. package/src/commands/init/templates/code-templates.ts +125 -32
  114. package/src/commands/init/templates/env.ts +80 -0
  115. package/src/commands/init/templates/quick-reference-mongo.md +34 -13
  116. package/src/commands/init/templates/quick-reference-postgres.md +11 -9
  117. package/src/commands/init/templates/quick-reference.ts +42 -3
  118. package/src/commands/init/templates/tsconfig.ts +167 -5
  119. package/src/commands/inspect-live-schema.ts +10 -5
  120. package/src/commands/migration-apply.ts +84 -63
  121. package/src/commands/migration-new.ts +28 -34
  122. package/src/commands/migration-plan.ts +80 -56
  123. package/src/commands/migration-ref.ts +8 -7
  124. package/src/commands/migration-show.ts +53 -36
  125. package/src/commands/migration-status.ts +194 -58
  126. package/src/config-path-validation.ts +0 -1
  127. package/src/control-api/client.ts +21 -0
  128. package/src/control-api/operations/contract-emit.ts +198 -115
  129. package/src/control-api/operations/db-init.ts +10 -6
  130. package/src/control-api/operations/db-update.ts +10 -6
  131. package/src/control-api/operations/migration-apply.ts +30 -9
  132. package/src/control-api/types.ts +69 -7
  133. package/src/exports/control-api.ts +2 -1
  134. package/src/exports/init-output.ts +10 -0
  135. package/src/migration-cli.ts +445 -122
  136. package/src/utils/cli-errors.ts +49 -2
  137. package/src/utils/command-helpers.ts +45 -23
  138. package/src/utils/emit-queue.ts +26 -0
  139. package/src/utils/formatters/graph-migration-mapper.ts +7 -3
  140. package/src/utils/formatters/migrations.ts +62 -26
  141. package/src/utils/publish-contract-artifact-pair.ts +134 -0
  142. package/dist/cli-errors-DHq6GQGu.mjs +0 -5
  143. package/dist/client-TG7rbCWT.mjs.map +0 -1
  144. package/dist/config-loader-_W4T21X1.mjs.map +0 -1
  145. package/dist/contract-emit-CQfj7xJn.mjs +0 -122
  146. package/dist/contract-emit-CQfj7xJn.mjs.map +0 -1
  147. package/dist/contract-emit-DpPjuFy-.mjs +0 -195
  148. package/dist/contract-emit-DpPjuFy-.mjs.map +0 -1
  149. package/dist/contract-emit-fhNwwhkQ.mjs +0 -4
  150. package/dist/contract-infer-BS4kIX9c.mjs.map +0 -1
  151. package/dist/extract-operation-statements-DZUJNmL3.mjs +0 -13
  152. package/dist/extract-operation-statements-DZUJNmL3.mjs.map +0 -1
  153. package/dist/extract-sql-ddl-DDMX-9mz.mjs +0 -26
  154. package/dist/extract-sql-ddl-DDMX-9mz.mjs.map +0 -1
  155. package/dist/init-CQfo_4Ro.mjs +0 -430
  156. package/dist/init-CQfo_4Ro.mjs.map +0 -1
  157. package/dist/inspect-live-schema-BsoFVoS1.mjs.map +0 -1
  158. package/dist/migration-status-Ry3TnEya.mjs.map +0 -1
  159. package/dist/migrations-fU0xoKjS.mjs.map +0 -1
  160. package/dist/result-handler-BJwA7ufw.mjs.map +0 -1
  161. package/dist/terminal-ui-C5k88MmW.mjs.map +0 -1
  162. package/dist/validate-contract-deps-esa-VQ0h.mjs +0 -37
  163. package/dist/validate-contract-deps-esa-VQ0h.mjs.map +0 -1
  164. package/src/control-api/operations/extract-operation-statements.ts +0 -14
  165. package/src/control-api/operations/extract-sql-ddl.ts +0 -47
@@ -0,0 +1,91 @@
1
+ /**
2
+ * The package.json `scripts` entries `init` adds idempotently (FR3.5).
3
+ * The script *name* mirrors the CLI subcommand path (`contract:emit` →
4
+ * `prisma-next contract emit`) so the script is greppable: a user
5
+ * encountering `npm run contract:emit` in CI logs can navigate
6
+ * straight to the equivalent CLI invocation.
7
+ *
8
+ * No watch-mode entry is included (Spec Decision 9) — file-watching is
9
+ * the build tool's job (Vite plugin, `tsc --watch`, etc.).
10
+ */
11
+ export interface RequiredScript {
12
+ readonly name: string;
13
+ readonly command: string;
14
+ }
15
+
16
+ export const REQUIRED_SCRIPTS: readonly RequiredScript[] = [
17
+ { name: 'contract:emit', command: 'prisma-next contract emit' },
18
+ ];
19
+
20
+ export interface PackageScriptsMergeResult {
21
+ /**
22
+ * The new package.json content. `null` when no changes are required
23
+ * (every required script is already present with the correct
24
+ * command).
25
+ */
26
+ readonly content: string | null;
27
+ /**
28
+ * Structured warnings raised when an existing script of the same
29
+ * name maps to a different command. Each warning names the script,
30
+ * the existing command, and the command we wanted to write — the
31
+ * user can decide whether to keep their override or update it.
32
+ */
33
+ readonly warnings: readonly string[];
34
+ }
35
+
36
+ /**
37
+ * Idempotent `package.json#scripts` merge with collision detection
38
+ * (FR3.5 / FR9.3):
39
+ *
40
+ * - If a required script is **missing**, append it.
41
+ * - If a required script is **already present and identical**, leave
42
+ * the file alone (idempotency).
43
+ * - If a required script is **present but maps to a different command**,
44
+ * skip the write for that script and surface a structured warning.
45
+ * The user's override is sacred — `init` should never silently
46
+ * overwrite a custom build pipeline.
47
+ *
48
+ * Preserves the existing key order (so a user who has alphabetised
49
+ * their scripts does not see them reshuffled) and appends new entries
50
+ * at the end.
51
+ *
52
+ * The `package.json` is parsed and re-stringified through `JSON` —
53
+ * comments are not preserved (package.json does not support them per
54
+ * spec). Trailing newline matches the original input's trailing
55
+ * newline behaviour.
56
+ */
57
+ export function mergePackageScripts(
58
+ existing: string,
59
+ required: readonly RequiredScript[] = REQUIRED_SCRIPTS,
60
+ ): PackageScriptsMergeResult {
61
+ const parsed = JSON.parse(existing) as Record<string, unknown>;
62
+ const scripts: Record<string, string> =
63
+ typeof parsed['scripts'] === 'object' && parsed['scripts'] !== null
64
+ ? { ...(parsed['scripts'] as Record<string, string>) }
65
+ : {};
66
+
67
+ const warnings: string[] = [];
68
+ let mutated = false;
69
+
70
+ for (const { name, command } of required) {
71
+ const existingValue = scripts[name];
72
+ if (existingValue === undefined) {
73
+ scripts[name] = command;
74
+ mutated = true;
75
+ continue;
76
+ }
77
+ if (existingValue !== command) {
78
+ warnings.push(
79
+ `package.json already has a "${name}" script with a different command — keeping yours.\n existing: ${existingValue}\n expected: ${command}\nIf you want the default, remove your "${name}" script and re-run \`init\`.`,
80
+ );
81
+ }
82
+ }
83
+
84
+ if (!mutated) {
85
+ return { content: null, warnings };
86
+ }
87
+
88
+ parsed['scripts'] = scripts;
89
+ const trailingNewline = existing.endsWith('\n') ? '\n' : '';
90
+ return { content: `${JSON.stringify(parsed, null, 2)}${trailingNewline}`, warnings };
91
+ }
@@ -1,5 +1,39 @@
1
1
  import { Command } from 'commander';
2
- import { setCommandDescriptions, setCommandExamples } from '../../utils/command-helpers';
2
+ import {
3
+ addGlobalOptions,
4
+ setCommandDescriptions,
5
+ setCommandExamples,
6
+ } from '../../utils/command-helpers';
7
+ import { type CommonCommandOptions, parseGlobalFlags } from '../../utils/global-flags';
8
+ import {
9
+ INIT_EXIT_EMIT_FAILED,
10
+ INIT_EXIT_INSTALL_FAILED,
11
+ INIT_EXIT_INTERNAL_ERROR,
12
+ INIT_EXIT_OK,
13
+ INIT_EXIT_PRECONDITION,
14
+ INIT_EXIT_USER_ABORTED,
15
+ } from './exit-codes';
16
+
17
+ /**
18
+ * Commander.js parsed options for `init`. The init-specific options live
19
+ * alongside the inherited `CommonCommandOptions` global flags.
20
+ *
21
+ * `target` and `authoring` are typed as plain `string` here because
22
+ * Commander.js does not enforce enums at parse time — the validation /
23
+ * normalisation happens in `inputs.ts::resolveInitInputs`, which can
24
+ * raise a structured `errorInitInvalidFlagValue` with the full set of
25
+ * allowed values.
26
+ */
27
+ interface InitCommandOptions extends CommonCommandOptions {
28
+ readonly target?: string;
29
+ readonly authoring?: string;
30
+ readonly schemaPath?: string;
31
+ readonly force?: boolean;
32
+ readonly writeEnv?: boolean;
33
+ readonly probeDb?: boolean;
34
+ readonly strictProbe?: boolean;
35
+ readonly install?: boolean;
36
+ }
3
37
 
4
38
  export function createInitCommand(): Command {
5
39
  const command = new Command('init');
@@ -7,15 +41,86 @@ export function createInitCommand(): Command {
7
41
  command,
8
42
  'Initialize a new Prisma Next project',
9
43
  'Scaffolds config, schema, and runtime files, installs dependencies,\n' +
10
- 'and emits the contract. Gets you from zero to typed queries in one step.',
44
+ 'and emits the contract. Gets you from zero to typed queries in one step.\n' +
45
+ '\n' +
46
+ 'Run interactively for a guided experience, or supply --target / --authoring\n' +
47
+ 'and --yes for a fully scriptable run (CI, AI coding agents, automation).\n' +
48
+ '\n' +
49
+ 'Exit codes (see CLI Style Guide § Exit Codes):\n' +
50
+ ` ${INIT_EXIT_OK} OK Init succeeded.\n` +
51
+ ` ${INIT_EXIT_INTERNAL_ERROR} INTERNAL_ERROR Unexpected bug in prisma-next (please report).\n` +
52
+ ` ${INIT_EXIT_PRECONDITION} PRECONDITION Bad flags / missing prerequisite (e.g. no package.json).\n` +
53
+ ` ${INIT_EXIT_USER_ABORTED} USER_ABORTED User cancelled an interactive prompt.\n` +
54
+ ` ${INIT_EXIT_INSTALL_FAILED} INSTALL_FAILED Dependency installation failed (init-specific).\n` +
55
+ ` ${INIT_EXIT_EMIT_FAILED} EMIT_FAILED \`contract emit\` failed after install (init-specific).`,
11
56
  );
12
- setCommandExamples(command, ['prisma-next init', 'prisma-next init --no-install']);
13
- command
57
+ setCommandExamples(command, [
58
+ 'prisma-next init',
59
+ 'prisma-next init --yes --target postgres --authoring psl',
60
+ 'prisma-next init --yes --target mongodb --authoring typescript --json',
61
+ 'prisma-next init --yes --force --target postgres --authoring psl # overwrite an existing scaffold',
62
+ 'prisma-next init --no-install # skip pnpm/npm install + emit',
63
+ ]);
64
+
65
+ return addGlobalOptions(command)
66
+ .option('--target <db>', 'Database target: postgres or mongodb')
67
+ .option('--authoring <style>', 'Schema authoring style: psl or typescript')
68
+ .option(
69
+ '--schema-path <path>',
70
+ 'Where to write the starter schema (default: prisma/contract.prisma)',
71
+ )
72
+ .option('--force', 'Overwrite an existing scaffold without prompting')
73
+ .option(
74
+ '--write-env',
75
+ 'Write a .env file from .env.example (gitignored; default: only .env.example)',
76
+ )
77
+ .option(
78
+ '--probe-db',
79
+ 'Connect to DATABASE_URL once and check the server version against the target minimum (opt-in; off by default)',
80
+ )
81
+ .option(
82
+ '--strict-probe',
83
+ 'Treat a failed --probe-db as fatal (no-op without --probe-db; init is offline-by-default)',
84
+ )
14
85
  .option('--no-install', 'Skip dependency installation and contract emission')
15
- .action(async (options: { readonly install?: boolean }) => {
86
+ .action(async (options: InitCommandOptions) => {
16
87
  const { runInit } = await import('./init');
17
- await runInit(process.cwd(), { noInstall: !options.install });
88
+ const flags = parseGlobalFlags(options);
89
+ const canPrompt = deriveCanPrompt({
90
+ flagsInteractive: flags.interactive,
91
+ optionInteractive: options.interactive,
92
+ stdinIsTTY: Boolean(process.stdin.isTTY),
93
+ });
94
+ const exitCode = await runInit(process.cwd(), { options, flags, canPrompt });
95
+ process.exit(exitCode);
18
96
  });
97
+ }
19
98
 
20
- return command;
99
+ /**
100
+ * Bridges the action handler's two TTY checks (stdout via `flags`, stdin
101
+ * via `process.stdin.isTTY`) into the `canPrompt` boolean `runInit`
102
+ * consumes.
103
+ *
104
+ * Per the [Style Guide § Interactivity](../../../../../../../docs/CLI%20Style%20Guide.md#interactivity):
105
+ *
106
+ * - `flags.interactive` governs *decoration* (TerminalUI, intro/outro,
107
+ * spinners) and is derived from stdout-TTY by `parseGlobalFlags`,
108
+ * honouring `--interactive` / `--no-interactive`.
109
+ * - Prompting additionally requires a stdin TTY — closing stdin is a
110
+ * common signal in CI / agent environments even when stdout stays
111
+ * attached.
112
+ * - `--interactive` is the explicit override: when the user passes it,
113
+ * we honour it (e.g. testing flows where stdin is stubbed).
114
+ *
115
+ * Exported so callers and tests can derive the same value without
116
+ * touching `process` globals — F14 of the M1/M2 review.
117
+ */
118
+ export function deriveCanPrompt(opts: {
119
+ readonly flagsInteractive: boolean | undefined;
120
+ readonly optionInteractive: boolean | undefined;
121
+ readonly stdinIsTTY: boolean;
122
+ }): boolean {
123
+ if (opts.optionInteractive === true) return true;
124
+ if (opts.flagsInteractive === false) return false;
125
+ return opts.stdinIsTTY;
21
126
  }