@prisma-next/cli 0.10.0-dev.9 → 0.11.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{cli-errors-CF60g2cG.mjs → cli-errors-Djtz98Vm.mjs} +3 -3
- package/dist/cli-errors-Djtz98Vm.mjs.map +1 -0
- package/dist/cli.mjs +296 -53
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-Brv4qlfB.mjs → client-oXO2WCPD.mjs} +6 -5
- package/dist/client-oXO2WCPD.mjs.map +1 -0
- package/dist/{command-helpers-Dvgul7UA.mjs → command-helpers-DtavI0wJ.mjs} +108 -11
- package/dist/command-helpers-DtavI0wJ.mjs.map +1 -0
- package/dist/commands/contract-emit.mjs +1 -1
- package/dist/commands/contract-infer.mjs +1 -1
- package/dist/commands/db-init.d.mts.map +1 -1
- package/dist/commands/db-init.mjs +19 -20
- package/dist/commands/db-init.mjs.map +1 -1
- package/dist/commands/db-schema.mjs +6 -10
- package/dist/commands/db-schema.mjs.map +1 -1
- package/dist/commands/db-sign.mjs +7 -11
- package/dist/commands/db-sign.mjs.map +1 -1
- package/dist/commands/db-update.d.mts.map +1 -1
- package/dist/commands/db-update.mjs +16 -17
- package/dist/commands/db-update.mjs.map +1 -1
- package/dist/commands/db-verify.mjs +1 -1
- package/dist/commands/migrate.d.mts +1 -1
- package/dist/commands/migrate.mjs +7 -11
- package/dist/commands/migrate.mjs.map +1 -1
- package/dist/commands/migration-check.mjs +4 -7
- package/dist/commands/migration-check.mjs.map +1 -1
- package/dist/commands/migration-graph.d.mts +1 -1
- package/dist/commands/migration-graph.mjs +6 -10
- package/dist/commands/migration-graph.mjs.map +1 -1
- package/dist/commands/migration-list.mjs +5 -9
- package/dist/commands/migration-list.mjs.map +1 -1
- package/dist/commands/migration-log.d.mts.map +1 -1
- package/dist/commands/migration-log.mjs +7 -10
- package/dist/commands/migration-log.mjs.map +1 -1
- package/dist/commands/migration-new.mjs +6 -10
- package/dist/commands/migration-new.mjs.map +1 -1
- package/dist/commands/migration-plan.d.mts +1 -1
- package/dist/commands/migration-plan.mjs +1 -1
- package/dist/commands/migration-show.d.mts +1 -1
- package/dist/commands/migration-show.mjs +8 -12
- package/dist/commands/migration-show.mjs.map +1 -1
- package/dist/commands/migration-status.d.mts +1 -1
- package/dist/commands/migration-status.d.mts.map +1 -1
- package/dist/commands/migration-status.mjs +36 -14
- package/dist/commands/migration-status.mjs.map +1 -1
- package/dist/commands/ref.d.mts +1 -1
- package/dist/commands/ref.mjs +9 -19
- package/dist/commands/ref.mjs.map +1 -1
- package/dist/{contract-emit-iynA3BCA.mjs → contract-emit-bcrpT-wD.mjs} +3 -3
- package/dist/{contract-emit-iynA3BCA.mjs.map → contract-emit-bcrpT-wD.mjs.map} +1 -1
- package/dist/{contract-emit-BDBzHlaC.mjs → contract-emit-uwT-Mj8-.mjs} +7 -12
- package/dist/contract-emit-uwT-Mj8-.mjs.map +1 -0
- package/dist/{contract-infer-Dm8pBZMR.mjs → contract-infer-pKkiCt7C.mjs} +9 -14
- package/dist/contract-infer-pKkiCt7C.mjs.map +1 -0
- package/dist/{contract-space-aggregate-loader-pAc8CDfY.mjs → contract-space-aggregate-loader-BmNQwlws.mjs} +2 -2
- package/dist/{contract-space-aggregate-loader-pAc8CDfY.mjs.map → contract-space-aggregate-loader-BmNQwlws.mjs.map} +1 -1
- package/dist/{db-verify-CW8DR5Ei.mjs → db-verify-AoIUriL4.mjs} +9 -13
- package/dist/db-verify-AoIUriL4.mjs.map +1 -0
- package/dist/exports/control-api.d.mts +1 -1
- package/dist/exports/control-api.mjs +2 -2
- package/dist/exports/index.mjs +1 -1
- package/dist/exports/init-output.mjs +1 -1
- package/dist/{framework-components-xFLFpZUO.mjs → framework-components-65gOHkHB.mjs} +2 -2
- package/dist/{framework-components-xFLFpZUO.mjs.map → framework-components-65gOHkHB.mjs.map} +1 -1
- package/dist/{global-flags-DGmw6Kqg.d.mts → global-flags-CdE7M0d9.d.mts} +4 -1
- package/dist/global-flags-CdE7M0d9.d.mts.map +1 -0
- package/dist/{graph-render-eJDcLWny.mjs → graph-render-DJVv0_uf.mjs} +1 -1
- package/dist/{graph-render-eJDcLWny.mjs.map → graph-render-DJVv0_uf.mjs.map} +1 -1
- package/dist/{init-CxS9eqbQ.mjs → init-YX6lCJpG.mjs} +140 -301
- package/dist/init-YX6lCJpG.mjs.map +1 -0
- package/dist/{inspect-live-schema-iETRZ_59.mjs → inspect-live-schema-LeWvkZVz.mjs} +4 -4
- package/dist/{inspect-live-schema-iETRZ_59.mjs.map → inspect-live-schema-LeWvkZVz.mjs.map} +1 -1
- package/dist/{migration-command-scaffold-BlgVj_Pn.mjs → migration-command-scaffold-BtkunvFQ.mjs} +4 -4
- package/dist/{migration-command-scaffold-BlgVj_Pn.mjs.map → migration-command-scaffold-BtkunvFQ.mjs.map} +1 -1
- package/dist/{migration-plan-BSzcWsvm.mjs → migration-plan-C2jeH1J5.mjs} +8 -12
- package/dist/migration-plan-C2jeH1J5.mjs.map +1 -0
- package/dist/{migration-types-D2FW63pr.d.mts → migration-types-BXWvz12q.d.mts} +1 -1
- package/dist/{migration-types-D2FW63pr.d.mts.map → migration-types-BXWvz12q.d.mts.map} +1 -1
- package/dist/{migrations-CgANWI0w.mjs → migrations-CwZMa1Ck.mjs} +2 -2
- package/dist/{migrations-CgANWI0w.mjs.map → migrations-CwZMa1Ck.mjs.map} +1 -1
- package/dist/{output-B60Gw5fu.mjs → output-BlsrGMEF.mjs} +1 -1
- package/dist/{output-B60Gw5fu.mjs.map → output-BlsrGMEF.mjs.map} +1 -1
- package/dist/readme-mongo.md +35 -0
- package/dist/readme-postgres.md +34 -0
- package/dist/{terminal-ui-XtOQsqe9.mjs → terminal-ui-BiB_8KNo.mjs} +131 -24
- package/dist/terminal-ui-BiB_8KNo.mjs.map +1 -0
- package/dist/{types-0aS865QN.d.mts → types--CqjMdk0.d.mts} +2 -2
- package/dist/{types-0aS865QN.d.mts.map → types--CqjMdk0.d.mts.map} +1 -1
- package/dist/{verify-nlzO0uIY.mjs → verify-Bom75OYI.mjs} +2 -2
- package/dist/{verify-nlzO0uIY.mjs.map → verify-Bom75OYI.mjs.map} +1 -1
- package/package.json +18 -18
- package/src/cli.ts +36 -9
- package/src/commands/contract-emit.ts +4 -4
- package/src/commands/contract-infer.ts +7 -7
- package/src/commands/db-init.ts +13 -5
- package/src/commands/db-schema.ts +4 -4
- package/src/commands/db-sign.ts +4 -4
- package/src/commands/db-update.ts +13 -5
- package/src/commands/db-verify.ts +5 -5
- package/src/commands/init/detect-package-manager.ts +15 -0
- package/src/commands/init/errors.ts +31 -0
- package/src/commands/init/hygiene-gitattributes.ts +2 -2
- package/src/commands/init/index.ts +4 -3
- package/src/commands/init/init.ts +33 -17
- package/src/commands/init/inputs.ts +6 -4
- package/src/commands/init/output.ts +1 -1
- package/src/commands/init/skill-install.ts +37 -26
- package/src/commands/init/templates/code-templates.ts +8 -14
- package/src/commands/init/templates/env.ts +8 -1
- package/src/commands/init/templates/readme-mongo.md +35 -0
- package/src/commands/init/templates/readme-postgres.md +34 -0
- package/src/commands/init/templates/readme.ts +62 -0
- package/src/commands/migrate.ts +4 -7
- package/src/commands/migration-check.ts +4 -4
- package/src/commands/migration-graph.ts +4 -4
- package/src/commands/migration-list.ts +4 -4
- package/src/commands/migration-log.ts +6 -5
- package/src/commands/migration-new.ts +4 -4
- package/src/commands/migration-plan.ts +4 -4
- package/src/commands/migration-show.ts +4 -4
- package/src/commands/migration-status.ts +49 -6
- package/src/commands/ref.ts +8 -8
- package/src/control-api/operations/apply-aggregate.ts +1 -0
- package/src/utils/cli-errors.ts +4 -0
- package/src/utils/command-helpers.ts +14 -6
- package/src/utils/global-flags.ts +102 -17
- package/src/utils/telemetry.ts +27 -52
- package/src/utils/terminal-ui.ts +44 -23
- package/dist/cli-errors-CF60g2cG.mjs.map +0 -1
- package/dist/client-Brv4qlfB.mjs.map +0 -1
- package/dist/command-helpers-Dvgul7UA.mjs.map +0 -1
- package/dist/contract-emit-BDBzHlaC.mjs.map +0 -1
- package/dist/contract-infer-Dm8pBZMR.mjs.map +0 -1
- package/dist/db-verify-CW8DR5Ei.mjs.map +0 -1
- package/dist/errors-BYAXmyRJ.mjs +0 -56
- package/dist/errors-BYAXmyRJ.mjs.map +0 -1
- package/dist/global-flags-DGmw6Kqg.d.mts.map +0 -1
- package/dist/init-CxS9eqbQ.mjs.map +0 -1
- package/dist/is-ci-YyvQBBke.mjs +0 -44
- package/dist/is-ci-YyvQBBke.mjs.map +0 -1
- package/dist/migration-plan-BSzcWsvm.mjs.map +0 -1
- package/dist/result-handler-CG3vVoKf.mjs +0 -25
- package/dist/result-handler-CG3vVoKf.mjs.map +0 -1
- package/dist/terminal-ui-XtOQsqe9.mjs.map +0 -1
- /package/dist/{cli-errors-DdcjVLJV.d.mts → cli-errors-Czmx92Zy.d.mts} +0 -0
package/README.md
CHANGED
|
@@ -1060,7 +1060,7 @@ run `migration.ts` directly with Node to produce `ops.json` and attest
|
|
|
1060
1060
|
node migrations/<dir>/migration.ts
|
|
1061
1061
|
```
|
|
1062
1062
|
|
|
1063
|
-
The scaffolded `migration.ts` calls `MigrationCLI.run(import.meta.url, ...)` from `@prisma-next/cli/migration-cli` when invoked as the entrypoint. (Postgres scaffolds re-export `MigrationCLI` through `@prisma-next/
|
|
1063
|
+
The scaffolded `migration.ts` calls `MigrationCLI.run(import.meta.url, ...)` from `@prisma-next/cli/migration-cli` when invoked as the entrypoint. (Postgres and SQLite scaffolds re-export `MigrationCLI` through `@prisma-next/postgres/migration` or `@prisma-next/sqlite/migration` so a `migration.ts` only needs the single facade import; Mongo scaffolds still pull from `@prisma-next/cli/migration-cli` directly.) The CLI entrypoint loads `prisma-next.config.ts`, assembles a `ControlStack`, instantiates the migration with that stack (so `dataTransform` and other adapter-aware helpers can materialize a real adapter), and serializes operations to `ops.json` while writing the content-addressed `migrationHash` into `migration.json`. If `migration.ts` contains unfilled `placeholder()` slots, the script exits with `PN-MIG-2001` and reports the slot to fill in.
|
|
1064
1064
|
|
|
1065
1065
|
`MigrationCLI.run` accepts an optional third argument `{ argv?, stdout?, stderr? }` for in-process testability (default: `process.argv` / `process.stdout` / `process.stderr`) and returns the exit code as a `Promise<number>`. The flag surface is `--help` / `--dry-run` / `--config <path>`, parsed by [`clipanion`](https://github.com/arcanis/clipanion). The main multi-command surface (`prisma-next contract emit`, `db verify`, etc.) uses Commander; the per-migration `MigrationCLI.run` entrypoint uses clipanion to keep authored migration files lightweight and in-process testable.
|
|
1066
1066
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CliStructuredError as CliStructuredError$1, errorConfigValidation as errorConfigValidation$1, errorContractConfigMissing as errorContractConfigMissing$1, errorContractValidationFailed, errorDatabaseConnectionRequired, errorDriverRequired, errorFileNotFound, errorMigrationPlanningFailed, errorTargetMigrationNotSupported, errorUnexpected as errorUnexpected$1 } from "@prisma-next/errors/control";
|
|
1
|
+
import { CliStructuredError as CliStructuredError$1, errorConfigValidation as errorConfigValidation$1, errorContractConfigMissing as errorContractConfigMissing$1, errorContractValidationFailed, errorDatabaseConnectionRequired, errorDriverRequired, errorFileNotFound, errorInvalidOutputFormat, errorMigrationPlanningFailed, errorOutputFormatMutex, errorTargetMigrationNotSupported, errorUnexpected as errorUnexpected$1 } from "@prisma-next/errors/control";
|
|
2
2
|
import { ERROR_CODE_DESTRUCTIVE_CHANGES, errorDestructiveChanges, errorHashMismatch, errorMarkerMissing, errorRunnerFailed, errorRuntime, errorRuntime as errorRuntime$1, errorTargetMismatch } from "@prisma-next/errors/execution";
|
|
3
3
|
import "@prisma-next/errors/migration";
|
|
4
4
|
//#region src/utils/cli-errors.ts
|
|
@@ -66,6 +66,6 @@ function mapRefResolutionError(error) {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
//#endregion
|
|
69
|
-
export {
|
|
69
|
+
export { errorTargetMigrationNotSupported as _, errorContractValidationFailed as a, mapMigrationToolsError as b, errorDriverRequired as c, errorInvalidOutputFormat as d, errorMarkerMissing as f, errorRuntime$1 as g, errorRunnerFailed as h, errorContractConfigMissing$1 as i, errorFileNotFound as l, errorOutputFormatMutex as m, ERROR_CODE_DESTRUCTIVE_CHANGES as n, errorDatabaseConnectionRequired as o, errorMigrationPlanningFailed as p, errorConfigValidation$1 as r, errorDestructiveChanges as s, CliStructuredError$1 as t, errorHashMismatch as u, errorTargetMismatch as v, mapRefResolutionError as x, errorUnexpected$1 as y };
|
|
70
70
|
|
|
71
|
-
//# sourceMappingURL=cli-errors-
|
|
71
|
+
//# sourceMappingURL=cli-errors-Djtz98Vm.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-errors-Djtz98Vm.mjs","names":[],"sources":["../src/utils/cli-errors.ts"],"sourcesContent":["/**\n * Re-export all domain error factories from @prisma-next/errors for convenience.\n * CLI-specific errors (e.g., Commander argument validation in the main CLI, or\n * clipanion parse errors in the migration-file CLI) can be added here if needed.\n */\nexport type { CliErrorConflict, CliErrorEnvelope } from '@prisma-next/errors/control';\n\nimport {\n CliStructuredError,\n errorConfigFileNotFound,\n errorConfigValidation,\n errorContractConfigMissing,\n errorContractMissingExtensionPacks,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFamilyReadMarkerSqlRequired,\n errorFileNotFound,\n errorInvalidOutputFormat,\n errorMigrationCliInvalidConfigArg,\n errorMigrationCliUnknownFlag,\n errorMigrationPlanningFailed,\n errorOutputFormatMutex,\n errorQueryRunnerFactoryRequired,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n} from '@prisma-next/errors/control';\nimport { errorRuntime } from '@prisma-next/errors/execution';\nimport type { MigrationToolsError } from '@prisma-next/migration-tools/errors';\nimport type { RefResolutionError } from '@prisma-next/migration-tools/ref-resolution';\n\nexport {\n ERROR_CODE_DESTRUCTIVE_CHANGES,\n errorDestructiveChanges,\n errorHashMismatch,\n errorMarkerMissing,\n errorMarkerRequired,\n errorRunnerFailed,\n errorRuntime,\n errorSchemaVerificationFailed,\n errorTargetMismatch,\n} from '@prisma-next/errors/execution';\nexport {\n errorMigrationFileMissing,\n errorMigrationInvalidDefaultExport,\n errorMigrationPlanNotArray,\n errorUnfilledPlaceholder,\n placeholder,\n} from '@prisma-next/errors/migration';\nexport {\n CliStructuredError,\n errorConfigFileNotFound,\n errorConfigValidation,\n errorContractConfigMissing,\n errorContractMissingExtensionPacks,\n errorContractValidationFailed,\n errorDatabaseConnectionRequired,\n errorDriverRequired,\n errorFamilyReadMarkerSqlRequired,\n errorFileNotFound,\n errorInvalidOutputFormat,\n errorMigrationCliInvalidConfigArg,\n errorMigrationCliUnknownFlag,\n errorMigrationPlanningFailed,\n errorOutputFormatMutex,\n errorQueryRunnerFactoryRequired,\n errorTargetMigrationNotSupported,\n errorUnexpected,\n};\n\n/**\n * Maps a `MigrationToolsError` raised by the migration-tools loader/graph\n * surface (`readMigrationPackage`, `readMigrationsDir`, `readRefs`,\n * `resolveRef`, `reconstructGraph`, ...) into a CLI `errorRuntime` envelope.\n *\n * The full `error.details` payload is forwarded into `meta` so machine\n * consumers (`--json`) see structural fields like `dir`, `storedHash`,\n * `computedHash` (for `MIGRATION.HASH_MISMATCH`) alongside the stable\n * `code`. The user-visible `summary`/`why`/`fix` text is unchanged.\n *\n * Callers are expected to gate on `MigrationToolsError.is(error)` first\n * (mirroring the original inline pattern); non-`MigrationToolsError`\n * values are caller-classified (rethrow, wrap with command-specific\n * `errorUnexpected`, etc.).\n */\nexport function mapMigrationToolsError(error: MigrationToolsError): CliStructuredError {\n return errorRuntime(error.message, {\n why: error.why,\n fix: error.fix,\n meta: { code: error.code, ...(error.details ?? {}) },\n });\n}\n\n/**\n * Maps a `RefResolutionError` from the contract/migration reference\n * resolver into a CLI structured error envelope.\n */\nexport function mapRefResolutionError(error: RefResolutionError): CliStructuredError {\n switch (error.kind) {\n case 'not-found':\n return errorRuntime(`Not a known ${error.grammar} reference: \"${error.input}\"`, {\n why: `No ${error.grammar} matching \"${error.input}\" exists in the migration graph or refs index.`,\n fix:\n error.grammar === 'contract'\n ? 'Provide a valid contract hash, ref name, or migration directory name.'\n : 'Provide a valid migration directory name or migration hash.',\n meta: { input: error.input, grammar: error.grammar },\n });\n case 'ambiguous':\n return errorRuntime(`Ambiguous ${error.grammar} reference: \"${error.input}\"`, {\n why: `\"${error.input}\" matches multiple ${error.grammar}s: ${error.candidates.join(', ')}`,\n fix: 'Provide a longer prefix or use the full hash to disambiguate.',\n meta: { input: error.input, candidates: error.candidates, grammar: error.grammar },\n });\n case 'wrong-grammar':\n return errorRuntime(error.message, {\n why: error.message,\n fix: error.fix,\n meta: { input: error.input, expectedGrammar: error.expectedGrammar },\n });\n case 'invalid-format':\n return errorRuntime(`Invalid reference format: \"${error.input}\"`, {\n why: error.reason,\n fix: 'Provide a valid contract hash, ref name, or migration directory name.',\n meta: { input: error.input },\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqFA,SAAgB,uBAAuB,OAAgD;CACrF,OAAO,aAAa,MAAM,SAAS;EACjC,KAAK,MAAM;EACX,KAAK,MAAM;EACX,MAAM;GAAE,MAAM,MAAM;GAAM,GAAI,MAAM,WAAW,EAAE;GAAG;EACrD,CAAC;;;;;;AAOJ,SAAgB,sBAAsB,OAA+C;CACnF,QAAQ,MAAM,MAAd;EACE,KAAK,aACH,OAAO,aAAa,eAAe,MAAM,QAAQ,eAAe,MAAM,MAAM,IAAI;GAC9E,KAAK,MAAM,MAAM,QAAQ,aAAa,MAAM,MAAM;GAClD,KACE,MAAM,YAAY,aACd,0EACA;GACN,MAAM;IAAE,OAAO,MAAM;IAAO,SAAS,MAAM;IAAS;GACrD,CAAC;EACJ,KAAK,aACH,OAAO,aAAa,aAAa,MAAM,QAAQ,eAAe,MAAM,MAAM,IAAI;GAC5E,KAAK,IAAI,MAAM,MAAM,qBAAqB,MAAM,QAAQ,KAAK,MAAM,WAAW,KAAK,KAAK;GACxF,KAAK;GACL,MAAM;IAAE,OAAO,MAAM;IAAO,YAAY,MAAM;IAAY,SAAS,MAAM;IAAS;GACnF,CAAC;EACJ,KAAK,iBACH,OAAO,aAAa,MAAM,SAAS;GACjC,KAAK,MAAM;GACX,KAAK,MAAM;GACX,MAAM;IAAE,OAAO,MAAM;IAAO,iBAAiB,MAAM;IAAiB;GACrE,CAAC;EACJ,KAAK,kBACH,OAAO,aAAa,8BAA8B,MAAM,MAAM,IAAI;GAChE,KAAK,MAAM;GACX,KAAK;GACL,MAAM,EAAE,OAAO,MAAM,OAAO;GAC7B,CAAC"}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { t as
|
|
4
|
-
import {
|
|
5
|
-
import { t as
|
|
6
|
-
import { n as installShutdownHandlers } from "./terminal-ui-XtOQsqe9.mjs";
|
|
7
|
-
import { t as createContractInferCommand } from "./contract-infer-Dm8pBZMR.mjs";
|
|
2
|
+
import { a as isCI, n as installShutdownHandlers } from "./terminal-ui-BiB_8KNo.mjs";
|
|
3
|
+
import { _ as parseGlobalFlags, b as formatCommandHelp, d as setCommandDescriptions, f as setCommandExamples, t as addGlobalOptions, v as parseGlobalFlagsOrExit, x as formatRootHelp } from "./command-helpers-DtavI0wJ.mjs";
|
|
4
|
+
import { t as createContractEmitCommand } from "./contract-emit-uwT-Mj8-.mjs";
|
|
5
|
+
import { t as createContractInferCommand } from "./contract-infer-pKkiCt7C.mjs";
|
|
8
6
|
import { createDbInitCommand } from "./commands/db-init.mjs";
|
|
9
7
|
import { createDbSchemaCommand } from "./commands/db-schema.mjs";
|
|
10
8
|
import { createDbSignCommand } from "./commands/db-sign.mjs";
|
|
11
9
|
import { createDbUpdateCommand } from "./commands/db-update.mjs";
|
|
12
|
-
import { t as createDbVerifyCommand } from "./db-verify-
|
|
10
|
+
import { t as createDbVerifyCommand } from "./db-verify-AoIUriL4.mjs";
|
|
13
11
|
import { createMigrateCommand } from "./commands/migrate.mjs";
|
|
14
12
|
import { createMigrationCheckCommand } from "./commands/migration-check.mjs";
|
|
15
13
|
import { createMigrationGraphCommand } from "./commands/migration-graph.mjs";
|
|
16
14
|
import { createMigrationListCommand } from "./commands/migration-list.mjs";
|
|
17
15
|
import { createMigrationLogCommand } from "./commands/migration-log.mjs";
|
|
18
16
|
import { createMigrationNewCommand } from "./commands/migration-new.mjs";
|
|
19
|
-
import { t as createMigrationPlanCommand } from "./migration-plan-
|
|
17
|
+
import { t as createMigrationPlanCommand } from "./migration-plan-C2jeH1J5.mjs";
|
|
20
18
|
import { createMigrationShowCommand } from "./commands/migration-show.mjs";
|
|
21
19
|
import { createMigrationStatusCommand } from "./commands/migration-status.mjs";
|
|
22
20
|
import { createRefCommand } from "./commands/ref.mjs";
|
|
23
21
|
import { Command } from "commander";
|
|
22
|
+
import { ifDefined } from "@prisma-next/utils/defined";
|
|
23
|
+
import { DEFAULT_CONTRACT_SOURCE_DIR } from "@prisma-next/config/config-types";
|
|
24
24
|
import { fileURLToPath } from "node:url";
|
|
25
25
|
import { readUserConfig, resolveGating, runTelemetry } from "@prisma-next/cli-telemetry";
|
|
26
26
|
import { distance } from "closest-match";
|
|
27
27
|
//#region package.json
|
|
28
|
-
var version = "0.
|
|
28
|
+
var version = "0.11.0-dev.1";
|
|
29
29
|
//#endregion
|
|
30
30
|
//#region src/utils/telemetry.ts
|
|
31
31
|
/**
|
|
@@ -89,29 +89,6 @@ function resolveTelemetryGate() {
|
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
|
-
* Best-effort extraction of `databaseTarget` and `extensions` from the
|
|
93
|
-
* project config. Loads via the same `c12`-backed loader the action
|
|
94
|
-
* handlers use so we honour the same lookup rules. Every failure mode
|
|
95
|
-
* (no config file, malformed config, async load reject) collapses to
|
|
96
|
-
* `(null, [])` because telemetry is non-blocking and may fire for
|
|
97
|
-
* commands that legitimately don't have a config (e.g. `init`).
|
|
98
|
-
*/
|
|
99
|
-
async function loadConfigForTelemetry() {
|
|
100
|
-
try {
|
|
101
|
-
const config = await loadConfig();
|
|
102
|
-
const target = config.target;
|
|
103
|
-
return {
|
|
104
|
-
databaseTarget: target !== void 0 && typeof target.targetId === "string" ? target.targetId : null,
|
|
105
|
-
extensions: (config.extensionPacks ?? []).map((pack) => pack.id).filter((id) => typeof id === "string")
|
|
106
|
-
};
|
|
107
|
-
} catch {
|
|
108
|
-
return {
|
|
109
|
-
databaseTarget: null,
|
|
110
|
-
extensions: []
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
92
|
* Path to the compiled sender script inside `@prisma-next/cli-telemetry`'s
|
|
116
93
|
* `dist/`. Resolved off this module's `import.meta.url` via the package
|
|
117
94
|
* specifier `@prisma-next/cli-telemetry/sender`, so the consumer pays
|
|
@@ -120,30 +97,34 @@ async function loadConfigForTelemetry() {
|
|
|
120
97
|
function senderPath() {
|
|
121
98
|
return fileURLToPath(new URL(import.meta.resolve("@prisma-next/cli-telemetry/sender")));
|
|
122
99
|
}
|
|
123
|
-
function
|
|
100
|
+
function fireTelemetry(actionCommand, userConfig, overrides = {}) {
|
|
124
101
|
return runTelemetry({
|
|
125
102
|
command: commanderSnapshotForTelemetry(actionCommand),
|
|
126
103
|
version,
|
|
127
|
-
databaseTarget: fields.databaseTarget,
|
|
128
|
-
extensions: fields.extensions,
|
|
129
104
|
projectRoot: process.cwd(),
|
|
130
105
|
senderPath: senderPath(),
|
|
131
106
|
isCI: isCI(),
|
|
132
107
|
env: process.env,
|
|
133
|
-
userConfig
|
|
108
|
+
userConfig,
|
|
109
|
+
...ifDefined("databaseTarget", overrides.databaseTarget)
|
|
134
110
|
});
|
|
135
111
|
}
|
|
136
112
|
/**
|
|
137
|
-
* preAction-stage entry point
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
113
|
+
* preAction-stage entry point. Synchronous by construction: resolve
|
|
114
|
+
* env/CI/user-consent gates (cheap, all in-memory and a single tiny
|
|
115
|
+
* user-config read), then — only when enabled — `fork()` the detached
|
|
116
|
+
* sender script. The forked child loads `prisma-next.config.*` via
|
|
117
|
+
* c12 on its own (see `loadProjectConfig` in cli-telemetry); the
|
|
118
|
+
* parent does no project-config I/O on the command's hot path.
|
|
119
|
+
*
|
|
120
|
+
* Privacy invariant: gate resolution always happens before any project
|
|
121
|
+
* config touches disk. The child loading user TS code is acceptable
|
|
122
|
+
* only because it's gated behind the same resolved-enabled signal.
|
|
142
123
|
*/
|
|
143
|
-
|
|
124
|
+
function fireTelemetryFromPreAction(actionCommand) {
|
|
144
125
|
const gate = resolveTelemetryGate();
|
|
145
126
|
if (!gate.enabled) return gate.outcome;
|
|
146
|
-
return
|
|
127
|
+
return fireTelemetry(actionCommand, gate.userConfig);
|
|
147
128
|
}
|
|
148
129
|
/**
|
|
149
130
|
* Manual one-shot telemetry path for the first `init` run where the user
|
|
@@ -152,13 +133,264 @@ async function fireTelemetryFromPreAction(actionCommand) {
|
|
|
152
133
|
* default-off. After consent is persisted, `runInit` calls this helper
|
|
153
134
|
* exactly for that first affirmative answer; subsequent init runs skip
|
|
154
135
|
* it because the prompt is not shown again.
|
|
136
|
+
*
|
|
137
|
+
* The child's c12 load would return `databaseTarget: null` for this
|
|
138
|
+
* specific invocation because `prisma-next.config.*` is not yet on
|
|
139
|
+
* disk (init writes it later in the same run). To preserve the
|
|
140
|
+
* prompt-chosen target in the first-init telemetry event, this
|
|
141
|
+
* helper forwards the value as a parent-side IPC override on
|
|
142
|
+
* `ParentToSenderPayload.databaseTarget` — the child consults the
|
|
143
|
+
* override first and falls back to its c12 result when absent.
|
|
155
144
|
*/
|
|
156
145
|
function fireTelemetryAfterInitConsent(actionCommand, inputs) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
146
|
+
return fireTelemetry(actionCommand, readUserConfig(), { databaseTarget: inputs.databaseTarget });
|
|
147
|
+
}
|
|
148
|
+
//#endregion
|
|
149
|
+
//#region src/commands/init/templates/code-templates.ts
|
|
150
|
+
function targetPackageName(target) {
|
|
151
|
+
return target === "postgres" ? "@prisma-next/postgres" : "@prisma-next/mongo";
|
|
152
|
+
}
|
|
153
|
+
function targetLabel(target) {
|
|
154
|
+
return target === "postgres" ? "PostgreSQL" : "MongoDB";
|
|
155
|
+
}
|
|
156
|
+
function defaultSchemaPath(authoring) {
|
|
157
|
+
if (authoring === "typescript") return `${DEFAULT_CONTRACT_SOURCE_DIR}/contract.ts`;
|
|
158
|
+
return `${DEFAULT_CONTRACT_SOURCE_DIR}/contract.prisma`;
|
|
159
|
+
}
|
|
160
|
+
function starterSchema(target, authoring) {
|
|
161
|
+
if (authoring === "typescript") return target === "mongo" ? starterSchemaTsMongo() : starterSchemaTsPostgres();
|
|
162
|
+
return target === "mongo" ? starterSchemaPslMongo() : starterSchemaPslPostgres();
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Renders a short authoring-appropriate schema sample (FR5.1) for embedding
|
|
166
|
+
* in `prisma-next.md`. Returns a complete fenced markdown code block.
|
|
167
|
+
*
|
|
168
|
+
* The sample intentionally shows just one model: it's illustrative, not
|
|
169
|
+
* a substitute for the full scaffolded contract file. The TS samples use
|
|
170
|
+
* the same outer shape as `starterSchemaTs*` (FR5.3) so a user reading
|
|
171
|
+
* the doc and the file side-by-side sees the same structure.
|
|
172
|
+
*/
|
|
173
|
+
function schemaSample(target, authoring) {
|
|
174
|
+
if (authoring === "typescript") return target === "mongo" ? schemaSampleTsMongo() : schemaSampleTsPostgres();
|
|
175
|
+
return target === "mongo" ? schemaSamplePslMongo() : schemaSamplePslPostgres();
|
|
176
|
+
}
|
|
177
|
+
function schemaSamplePslPostgres() {
|
|
178
|
+
return `\`\`\`prisma
|
|
179
|
+
model User {
|
|
180
|
+
id Int @id @default(autoincrement())
|
|
181
|
+
email String @unique
|
|
182
|
+
username String?
|
|
183
|
+
name String?
|
|
184
|
+
}
|
|
185
|
+
\`\`\``;
|
|
186
|
+
}
|
|
187
|
+
function schemaSamplePslMongo() {
|
|
188
|
+
return `\`\`\`prisma
|
|
189
|
+
model User {
|
|
190
|
+
id ObjectId @id @map("_id")
|
|
191
|
+
email String @unique
|
|
192
|
+
username String?
|
|
193
|
+
name String?
|
|
194
|
+
@@map("users")
|
|
195
|
+
}
|
|
196
|
+
\`\`\``;
|
|
197
|
+
}
|
|
198
|
+
function schemaSampleTsPostgres() {
|
|
199
|
+
return `\`\`\`typescript
|
|
200
|
+
import { defineContract } from '@prisma-next/postgres/contract-builder';
|
|
201
|
+
|
|
202
|
+
export const contract = defineContract(
|
|
203
|
+
{},
|
|
204
|
+
({ field, model }) => ({
|
|
205
|
+
models: {
|
|
206
|
+
User: model('User', {
|
|
207
|
+
fields: {
|
|
208
|
+
id: field.id.uuidv7(),
|
|
209
|
+
email: field.text().unique(),
|
|
210
|
+
username: field.text().optional(),
|
|
211
|
+
name: field.text().optional(),
|
|
212
|
+
},
|
|
213
|
+
}),
|
|
214
|
+
},
|
|
215
|
+
}),
|
|
216
|
+
);
|
|
217
|
+
\`\`\``;
|
|
218
|
+
}
|
|
219
|
+
function schemaSampleTsMongo() {
|
|
220
|
+
return `\`\`\`typescript
|
|
221
|
+
import { defineContract } from '@prisma-next/mongo/contract-builder';
|
|
222
|
+
|
|
223
|
+
export const contract = defineContract(
|
|
224
|
+
{},
|
|
225
|
+
({ field, model }) => ({
|
|
226
|
+
models: {
|
|
227
|
+
User: model('User', {
|
|
228
|
+
collection: 'users',
|
|
229
|
+
fields: {
|
|
230
|
+
_id: field.objectId(),
|
|
231
|
+
email: field.string(),
|
|
232
|
+
username: field.string().optional(),
|
|
233
|
+
name: field.string().optional(),
|
|
234
|
+
},
|
|
235
|
+
}),
|
|
236
|
+
},
|
|
237
|
+
}),
|
|
238
|
+
);
|
|
239
|
+
\`\`\``;
|
|
240
|
+
}
|
|
241
|
+
function starterSchemaPslPostgres() {
|
|
242
|
+
return `// use prisma-next
|
|
243
|
+
|
|
244
|
+
model User {
|
|
245
|
+
id Int @id @default(autoincrement())
|
|
246
|
+
email String @unique
|
|
247
|
+
username String?
|
|
248
|
+
name String?
|
|
249
|
+
posts Post[]
|
|
250
|
+
createdAt DateTime @default(now())
|
|
251
|
+
updatedAt temporal.updatedAt()
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
model Post {
|
|
255
|
+
id Int @id @default(autoincrement())
|
|
256
|
+
title String
|
|
257
|
+
content String?
|
|
258
|
+
author User @relation(fields: [authorId], references: [id])
|
|
259
|
+
authorId Int
|
|
260
|
+
createdAt DateTime @default(now())
|
|
261
|
+
updatedAt temporal.updatedAt()
|
|
262
|
+
}
|
|
263
|
+
`;
|
|
264
|
+
}
|
|
265
|
+
function starterSchemaPslMongo() {
|
|
266
|
+
return `// use prisma-next
|
|
267
|
+
|
|
268
|
+
model User {
|
|
269
|
+
id ObjectId @id @map("_id")
|
|
270
|
+
email String @unique
|
|
271
|
+
username String?
|
|
272
|
+
name String?
|
|
273
|
+
posts Post[]
|
|
274
|
+
@@map("users")
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
model Post {
|
|
278
|
+
id ObjectId @id @map("_id")
|
|
279
|
+
title String
|
|
280
|
+
content String?
|
|
281
|
+
author User @relation(fields: [authorId], references: [id])
|
|
282
|
+
authorId ObjectId
|
|
283
|
+
@@map("posts")
|
|
284
|
+
}
|
|
285
|
+
`;
|
|
286
|
+
}
|
|
287
|
+
function starterSchemaTsPostgres() {
|
|
288
|
+
return `import { defineContract } from '@prisma-next/postgres/contract-builder';
|
|
289
|
+
|
|
290
|
+
export const contract = defineContract(
|
|
291
|
+
{},
|
|
292
|
+
({ field, model, rel }) => ({
|
|
293
|
+
models: {
|
|
294
|
+
User: model('User', {
|
|
295
|
+
fields: {
|
|
296
|
+
id: field.id.uuidv7(),
|
|
297
|
+
email: field.text().unique(),
|
|
298
|
+
username: field.text().optional(),
|
|
299
|
+
name: field.text().optional(),
|
|
300
|
+
createdAt: field.temporal.createdAt(),
|
|
301
|
+
updatedAt: field.temporal.updatedAt(),
|
|
302
|
+
},
|
|
303
|
+
relations: {
|
|
304
|
+
posts: rel.hasMany('Post', { by: 'authorId' }),
|
|
305
|
+
},
|
|
306
|
+
}),
|
|
307
|
+
|
|
308
|
+
Post: model('Post', {
|
|
309
|
+
fields: {
|
|
310
|
+
id: field.id.uuidv7(),
|
|
311
|
+
title: field.text(),
|
|
312
|
+
content: field.text().optional(),
|
|
313
|
+
authorId: field.uuid(),
|
|
314
|
+
createdAt: field.temporal.createdAt(),
|
|
315
|
+
updatedAt: field.temporal.updatedAt(),
|
|
316
|
+
},
|
|
317
|
+
relations: {
|
|
318
|
+
author: rel.belongsTo('User', { from: 'authorId', to: 'id' }),
|
|
319
|
+
},
|
|
320
|
+
}),
|
|
321
|
+
},
|
|
322
|
+
}),
|
|
323
|
+
);
|
|
324
|
+
`;
|
|
325
|
+
}
|
|
326
|
+
function starterSchemaTsMongo() {
|
|
327
|
+
return `import { defineContract } from '@prisma-next/mongo/contract-builder';
|
|
328
|
+
|
|
329
|
+
export const contract = defineContract(
|
|
330
|
+
{},
|
|
331
|
+
({ field, model, rel }) => ({
|
|
332
|
+
models: {
|
|
333
|
+
User: model('User', {
|
|
334
|
+
collection: 'users',
|
|
335
|
+
fields: {
|
|
336
|
+
_id: field.objectId(),
|
|
337
|
+
email: field.string(),
|
|
338
|
+
username: field.string().optional(),
|
|
339
|
+
name: field.string().optional(),
|
|
340
|
+
},
|
|
341
|
+
relations: {
|
|
342
|
+
posts: rel.hasMany('Post', { from: '_id', to: 'authorId' }),
|
|
343
|
+
},
|
|
344
|
+
}),
|
|
345
|
+
|
|
346
|
+
Post: model('Post', {
|
|
347
|
+
collection: 'posts',
|
|
348
|
+
fields: {
|
|
349
|
+
_id: field.objectId(),
|
|
350
|
+
title: field.string(),
|
|
351
|
+
content: field.string().optional(),
|
|
352
|
+
authorId: field.objectId(),
|
|
353
|
+
},
|
|
354
|
+
relations: {
|
|
355
|
+
author: rel.belongsTo('User', { from: 'authorId', to: '_id' }),
|
|
356
|
+
},
|
|
357
|
+
}),
|
|
358
|
+
},
|
|
359
|
+
}),
|
|
360
|
+
);
|
|
361
|
+
`;
|
|
362
|
+
}
|
|
363
|
+
function configFile(target, contractPath) {
|
|
364
|
+
return `import 'dotenv/config';
|
|
365
|
+
import { defineConfig } from '${targetPackageName(target)}/config';
|
|
366
|
+
|
|
367
|
+
export default defineConfig({
|
|
368
|
+
contract: ${JSON.stringify(contractPath)},
|
|
369
|
+
db: {
|
|
370
|
+
connection: process.env['DATABASE_URL']!,
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
`;
|
|
374
|
+
}
|
|
375
|
+
function dbFile(target) {
|
|
376
|
+
if (target === "postgres") return `import postgres from '@prisma-next/postgres/runtime';
|
|
377
|
+
import type { Contract } from './contract.d';
|
|
378
|
+
import contractJson from './contract.json' with { type: 'json' };
|
|
379
|
+
|
|
380
|
+
export const db = postgres<Contract>({
|
|
381
|
+
contractJson,
|
|
382
|
+
url: process.env['DATABASE_URL']!,
|
|
383
|
+
});
|
|
384
|
+
`;
|
|
385
|
+
return `import mongo from '@prisma-next/mongo/runtime';
|
|
386
|
+
import type { Contract } from './contract.d';
|
|
387
|
+
import contractJson from './contract.json' with { type: 'json' };
|
|
388
|
+
|
|
389
|
+
export const db = mongo<Contract>({
|
|
390
|
+
contractJson,
|
|
391
|
+
url: process.env['DATABASE_URL']!,
|
|
392
|
+
});
|
|
393
|
+
`;
|
|
162
394
|
}
|
|
163
395
|
//#endregion
|
|
164
396
|
//#region src/commands/init/index.ts
|
|
@@ -180,9 +412,9 @@ Exit codes (see CLI Style Guide § Exit Codes):
|
|
|
180
412
|
"prisma-next init --no-install # skip pnpm/npm install + emit",
|
|
181
413
|
"prisma-next init --no-skill # skip the skills install (air-gapped / restricted env)"
|
|
182
414
|
]);
|
|
183
|
-
return addGlobalOptions(command).option("--target <db>", "Database target: postgres or mongodb").option("--authoring <style>", "Schema authoring style: psl or typescript").option("--schema-path <path>",
|
|
184
|
-
const { runInit } = await import("./init-
|
|
185
|
-
const flags =
|
|
415
|
+
return addGlobalOptions(command).option("--target <db>", "Database target: postgres or mongodb").option("--authoring <style>", "Schema authoring style: psl or typescript").option("--schema-path <path>", `Where to write the starter schema (default: ${defaultSchemaPath("psl")})`).option("--force", "Overwrite an existing scaffold without prompting").option("--write-env", "Write a .env file from .env.example (gitignored; default: only .env.example)").option("--probe-db", "Connect to DATABASE_URL once and check the server version against the target minimum (opt-in; off by default)").option("--strict-probe", "Treat a failed --probe-db as fatal (no-op without --probe-db; init is offline-by-default)").option("--no-install", "Skip dependency installation and contract emission").option("--no-skill", "Skip Prisma Next skills install (air-gapped CI, restricted registries, etc.)").action(async (options, actionCommand) => {
|
|
416
|
+
const { runInit } = await import("./init-YX6lCJpG.mjs");
|
|
417
|
+
const flags = parseGlobalFlagsOrExit(options);
|
|
186
418
|
const canPrompt = deriveCanPrompt({
|
|
187
419
|
flagsInteractive: flags.interactive,
|
|
188
420
|
optionInteractive: options.interactive,
|
|
@@ -279,7 +511,9 @@ function formatSuggestion(input, candidates) {
|
|
|
279
511
|
const program = new Command();
|
|
280
512
|
program.name("prisma-next").description("Prisma Next CLI").version(version);
|
|
281
513
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
282
|
-
|
|
514
|
+
try {
|
|
515
|
+
fireTelemetryFromPreAction(actionCommand);
|
|
516
|
+
} catch {}
|
|
283
517
|
});
|
|
284
518
|
const versionOption = program.options.find((opt) => opt.flags.includes("--version"));
|
|
285
519
|
if (versionOption) versionOption.description = "Output the version number";
|
|
@@ -416,6 +650,15 @@ program.addCommand(contractCommand);
|
|
|
416
650
|
program.addCommand(dbCommand);
|
|
417
651
|
program.addCommand(migrationCommand);
|
|
418
652
|
program.addCommand(refCommand);
|
|
653
|
+
const TELEMETRY_CRASH_TEST_SLEEP_MS = 200;
|
|
654
|
+
if (process.env["PRISMA_NEXT_ENABLE_TEST_COMMANDS"] === "1") {
|
|
655
|
+
const telemetryCrashTestCommand = new Command("__telemetry-crash-test").description("Internal: deliberately throw for the telemetry e2e suite.").action(async () => {
|
|
656
|
+
await new Promise((settle) => setTimeout(settle, TELEMETRY_CRASH_TEST_SLEEP_MS));
|
|
657
|
+
throw new Error("__telemetry-crash-test: intentional crash for e2e coverage");
|
|
658
|
+
});
|
|
659
|
+
telemetryCrashTestCommand.configureHelp({ visibleCommands: () => [] });
|
|
660
|
+
program.addCommand(telemetryCrashTestCommand, { hidden: true });
|
|
661
|
+
}
|
|
419
662
|
const helpCommand = new Command("help").description("Show usage instructions").configureHelp({ formatHelp: (cmd) => {
|
|
420
663
|
return formatCommandHelp({
|
|
421
664
|
command: cmd,
|
|
@@ -486,6 +729,6 @@ if (args.length > 0) {
|
|
|
486
729
|
}
|
|
487
730
|
program.parse();
|
|
488
731
|
//#endregion
|
|
489
|
-
export { version as t };
|
|
732
|
+
export { starterSchema as a, version as c, schemaSample as i, dbFile as n, targetLabel as o, defaultSchemaPath as r, targetPackageName as s, configFile as t };
|
|
490
733
|
|
|
491
734
|
//# sourceMappingURL=cli.mjs.map
|