Skip to content

Commit 1406d24

Browse files
feat(cli): add JSON compute config format to init
init gains --format <ts|json>. The json format writes a dependency-free prisma.compute.json through the SDK's serializeComputeConfigJson with a $schema-first document, pins the same resolved values as the TypeScript path, and keeps the wx no-overwrite semantics. Because the format exists to be dependency-free, the types install step never runs with it and --install becomes a usage error; the custom framework is refused since strict JSON cannot carry the commented build stub init relies on. An explicit --format ts with an existing prisma.compute.json is the graduation path: the JSON config is validated, rewritten as prisma.compute.ts wrapping the same object in defineComputeConfig, the JSON file is deleted in the same operation, and the types install step runs. The reverse direction fails with INIT_CONVERT_UNSUPPORTED because TypeScript configs may contain logic a static file cannot express. Plain init still refuses every existing config with INIT_CONFIG_EXISTS. The result envelope now reports format and converted alongside configPath. The product decision asked for a --json boolean; that name is the global JSON-output flag on every command, so the config format rides a dedicated --format option instead.
1 parent e9b491a commit 1406d24

8 files changed

Lines changed: 699 additions & 22 deletions

File tree

docs/product/command-spec.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,17 +384,22 @@ prisma-cli --version --json
384384

385385
`prisma-cli version` is the richer environment report; `prisma-cli --version` is the terse one-liner. Both report the same `cli.version`. Use the flag for quick checks, the subcommand for support tickets and bug reports.
386386

387-
## `prisma-cli init --framework <nextjs|nuxt|astro|hono|nestjs|tanstack-start|bun|custom> --entry <path> --http-port <port> --region <region> --name <app-name> --link --no-link --project <id-or-name> --install --no-install`
387+
## `prisma-cli init --framework <nextjs|nuxt|astro|hono|nestjs|tanstack-start|bun|custom> --entry <path> --http-port <port> --region <region> --name <app-name> --link --no-link --project <id-or-name> --install --no-install --format <ts|json>`
388388

389389
Purpose:
390390

391-
- write a committed `prisma.compute.ts` for the app in this directory
391+
- write a committed `prisma.compute.ts` (or, with `--format json`, a dependency-free `prisma.compute.json`) for the app in this directory
392392

393393
Behavior:
394394

395395
- init is the config formalizer: `app deploy` works with zero config, and init writes down what deploy would infer so the setup is committed, reviewable, and stable for teammates and CI
396396
- writing the config requires no auth and no network; linking is the only remote step
397397
- fails with `INIT_CONFIG_EXISTS` when a compute config already exists in the invocation directory or any ancestor up to the repository or workspace root; the error names the existing file, and init never overwrites or merges — editing a committed config is the user's editor's job
398+
- `--format <ts|json>` selects the config serialization; `ts` (alias `typescript`) is the default and writes `prisma.compute.ts`, `json` writes `prisma.compute.json` via the shared SDK serializer with a `$schema`-first document that validates in editors without any local dependency; both formats pin exactly the same resolved values, and the CLI's global `--json` output flag is unrelated to the config format
399+
- with `--format json`, the types install step never runs: the JSON format exists to be dependency-free, so `--install` is a usage error and the result reports the step as skipped with no install hint
400+
- with `--format json` and the custom framework, init fails with a usage error: custom needs `build.outputDirectory` and `build.entrypoint`, which init does not collect, and strict JSON cannot carry the commented build stub the TypeScript format uses; the fix is the TypeScript format or a hand-written `build` object
401+
- graduation path: an explicit `--format ts` with an existing `prisma.compute.json` converts it in place; the JSON config is loaded and validated, the equivalent `prisma.compute.ts` wrapping the same object in `defineComputeConfig` is written next to it, the JSON file is deleted in the same operation, and the types install step runs as usual (skippable with `--no-install`); values are transported, never re-resolved, and the conversion is reported with `converted: true`
402+
- conversion is one-way and explicit: plain `init` with any existing config still fails with `INIT_CONFIG_EXISTS`, and `--format json` with an existing TypeScript config fails with `INIT_CONVERT_UNSUPPORTED` because TypeScript configs may contain logic that a static JSON file cannot express; a fully static config can be rewritten by hand
398403
- detects the framework from the same registry and signals `app deploy` uses; explicit `--framework` wins over detection
399404
- `--entry` sets the source entrypoint for entrypoint frameworks (Bun, Hono); `--http-port` overrides the framework default port; `--name` overrides the app name inferred from `package.json#name` or the directory name
400405
- previews the resolved values with per-value source annotations (`detected`, `framework default`, `package.json`, `flag`) before writing; in interactive mode the preview is followed by an optional adjust step for framework and HTTP port, and `--yes` accepts the preview as shown
@@ -415,7 +420,7 @@ Behavior:
415420
- link failures and cancellations after the config is written downgrade to warnings and `nextSteps`; the config write stands and init exits 0
416421
- `nextSteps` includes the deploy command, plus the project link command when the directory is still unlinked
417422
- user-facing command hints in init output (next steps, link hints, error recovery commands) use the package runner detected from the project, such as `pnpm dlx @prisma/cli@latest project link` or `npx -y @prisma/cli@latest app deploy`, matching the `agent` group's convention
418-
- in `--json`, `result` includes `configPath`, the written `app` values, per-value `settings` sources, and `link` state; `--json` never prompts
423+
- in `--json`, `result` includes `configPath`, `format` (`typescript` or `json`), `converted` (true only for the `--format ts` conversion path), the written `app` values (null when a conversion transported a config that does not pin a single fully-resolved app), per-value `settings` sources, and `link` state; `--json` never prompts
419424

420425
Examples:
421426

@@ -424,6 +429,8 @@ prisma-cli init
424429
prisma-cli init --framework hono --entry src/index.ts
425430
prisma-cli init --name api --http-port 8080 --no-link
426431
prisma-cli init --project proj_123
432+
prisma-cli init --format json
433+
prisma-cli init --format ts
427434
prisma-cli init --json
428435
```
429436

docs/product/error-conventions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ These codes are the minimum stable set for the MVP:
188188
- `BUILD_SETTINGS_UNSUPPORTED`
189189
- `FRAMEWORK_NOT_DETECTED`
190190
- `INIT_CONFIG_EXISTS`
191+
- `INIT_CONVERT_UNSUPPORTED`
191192
- `INIT_DETECTION_FAILED`
192193
- `DEPLOYMENT_NOT_FOUND`
193194
- `NO_DEPLOYMENTS`
@@ -261,6 +262,7 @@ Recommended meanings:
261262
- `BUILD_SETTINGS_UNSUPPORTED`: a compute config `build` block targets a framework whose SDK strategy does not consume committed build settings
262263
- `FRAMEWORK_NOT_DETECTED`: app deploy could not detect a supported Beta framework and no explicit framework/build type was provided
263264
- `INIT_CONFIG_EXISTS`: a compute config already exists in this directory or an ancestor; init never overwrites or merges
265+
- `INIT_CONVERT_UNSUPPORTED`: `init --format json` found an existing TypeScript config; TypeScript configs may contain logic, so converting them to JSON automatically would be lossy and the rewrite is manual
264266
- `INIT_DETECTION_FAILED`: no supported framework detected and no --framework passed; `meta.frameworks` lists the valid values
265267
- `DEPLOYMENT_NOT_FOUND`: requested deployment id does not exist
266268
- `NO_DEPLOYMENTS`: command resolved a branch or app but found no deployments

packages/cli/src/commands/init/index.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ export function createInitCommand(runtime: CliRuntime): Command {
4343
.addOption(
4444
new Option("--install", "Install @prisma/compute-sdk for config types"),
4545
)
46-
.addOption(new Option("--no-install", "Skip the types install step"));
46+
.addOption(new Option("--no-install", "Skip the types install step"))
47+
.addOption(
48+
new Option(
49+
"--format <ts|json>",
50+
"Config file format: ts (default) writes prisma.compute.ts, json writes dependency-free prisma.compute.json; --format ts converts an existing prisma.compute.json",
51+
),
52+
);
4753
addGlobalFlags(command);
4854

4955
command.action(async (options) => {
@@ -56,6 +62,7 @@ export function createInitCommand(runtime: CliRuntime): Command {
5662
link?: boolean;
5763
project?: string;
5864
install?: boolean;
65+
format?: string;
5966
};
6067

6168
await runCommand<InitResult>(
@@ -72,6 +79,7 @@ export function createInitCommand(runtime: CliRuntime): Command {
7279
link: flags.link,
7380
project: flags.project,
7481
install: flags.install,
82+
format: flags.format,
7583
}),
7684
{
7785
renderHuman: (context, descriptor, result) =>

0 commit comments

Comments
 (0)