Skip to content

feat(cli): add --format json to init and JSON-to-TS conversion#114

Merged
AmanVarshney01 merged 8 commits into
mainfrom
feat/init-json-config
Jul 9, 2026
Merged

feat(cli): add --format json to init and JSON-to-TS conversion#114
AmanVarshney01 merged 8 commits into
mainfrom
feat/init-json-config

Conversation

@AmanVarshney01

Copy link
Copy Markdown
Member

Overview

prisma init gains a config format choice: --format <ts|json>. TypeScript stays the default (local dev environments get the fully typed experience, and init already installs the SDK); --format json writes a dependency-free prisma.compute.json with a $schema reference for editor validation, the same format the Console setup PR commits (prisma/project-compute#103).

Named --format, not --json: --json is the global machine-readable-envelope flag on every command and cannot be repurposed.

Changes

  • --format json: writes via serializeComputeConfigJson with the same resolved values and wx no-overwrite semantics as the TS path. The SDK types install step never runs (the whole point is a dependency-free file); --install alongside it is a USAGE_ERROR. Custom framework requires the TS format (its commented build stub cannot exist in strict JSON); fails with a structured error, nothing written.
  • Graduation path: --format ts with an existing sole prisma.compute.json converts it losslessly (validates through the shared normalizer, writes defineComputeConfig TS, deletes the JSON; a failed delete rolls back the write so two configs never coexist), then runs the usual install step.
  • The reverse (TS exists + --format json) is refused with INIT_CONVERT_UNSUPPORTED: TS configs may contain logic; converting is lossy.
  • Plain init with any existing config still refuses with INIT_CONFIG_EXISTS; conversion is always explicit.
  • Envelope: result.format and result.converted added to InitResult; command spec and error conventions docs updated.

Merge order

Draft until @prisma/compute-sdk 0.33 ships from prisma/project-compute#103. The last commit (chore: link local compute-sdk pending 0.33 release) is a pnpm-workspace.yaml link: override for local dev and must be replaced by the real version bump before merge.

Verification

  • pnpm --filter @prisma/cli test: 619 tests pass (10 new: json happy path with SDK-loader round-trip, conversion both directions, guard errors, custom+json, existing-config refusals)
  • pnpm --recursive exec tsc --noEmit: clean; pnpm lint: clean
  • Live drive: init --format json then init --format ts conversion then init refusal, all via the built CLI in a scratch dir

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.
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c31b1639-2a23-4778-aeb4-07f2b67aaa0b

📥 Commits

Reviewing files that changed from the base of the PR and between 23b796d and 92637ce.

📒 Files selected for processing (1)
  • docs/product/command-spec.md

Summary by CodeRabbit

  • New Features

    • Added --format <ts|json> to init to generate either prisma.compute.ts or prisma.compute.json.
    • JSON output creates a dependency-free config and skips the types installation step.
    • Added one-way in-place conversion of an existing prisma.compute.json to TypeScript via --format ts.
  • Bug Fixes

    • Improved validation for unsupported flag combinations and format/framework limitations (e.g., JSON not supported for custom frameworks).
    • Clearer, conversion-aware success messaging and dedicated structured error codes when conversion is unsupported or incomplete.
  • Documentation

    • Updated command specs and error-code conventions for the new init format and conversion behaviors.

Walkthrough

This PR adds a --format <ts|json> option to init. It introduces InitConfigFormat, extends InitResult with format, converted, and a nullable app, and updates controller logic to write either prisma.compute.ts or prisma.compute.json. It also adds conversion from existing JSON to TypeScript, new conversion-specific error codes, updated presenter output, documentation changes, a dependency bump, and expanded tests.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately highlights the main change: adding --format json and JSON-to-TS conversion for init.
Description check ✅ Passed The description is directly aligned with the changeset and summarizes the new format and conversion behavior well.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/init-json-config
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/init-json-config

Comment @coderabbitai help to get the list of available commands.

…double-fault

Review findings: init --format ts with an existing prisma.compute.json
silently ignored --framework/--entry/--name/--http-port/--region; they
now fail as a usage error since conversion transports values and never
re-resolves them. If the post-write JSON delete fails AND the rollback
delete also fails, the raw fs error escaped while two config files were
left coexisting; that now surfaces as structured INIT_CONVERT_INCOMPLETE
naming both files. Adds conversion tests for full field preservation
(env, build, root, project region) and multi-app configs including a
null build command.
Follows the SDK default flip: the schema URL does not resolve yet, so
generated configs no longer reference it. The loader still strips a
hand-added $schema, and emission returns as opt-in once the schema is
hosted.
Drops the local link override now that 0.33.0 is published with the
JSON config contract.
@AmanVarshney01 AmanVarshney01 marked this pull request as ready for review July 8, 2026 08:15

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cli/src/controllers/init.ts`:
- Around line 468-489: The conversion flag guard in
rejectConversionResolutionFlags currently only rejects
framework/entry/httpPort/name/region, so link-related flags are still accepted
during --format ts conversion even though they are ignored. Update
rejectConversionResolutionFlags in init.ts to include --link, --no-link, and
--project in the passed list (or alternatively plumb them through
resolveInitLink), so runInitConversion consistently rejects unsupported link
resolution options when converting an existing config.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f5fa744f-86a8-46c9-b35f-ab1647f76572

📥 Commits

Reviewing files that changed from the base of the PR and between e9b491a and 0c1dbf0.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • docs/product/command-spec.md
  • docs/product/error-conventions.md
  • packages/cli/package.json
  • packages/cli/src/commands/init/index.ts
  • packages/cli/src/controllers/init.ts
  • packages/cli/src/presenters/init.ts
  • packages/cli/src/shell/command-meta.ts
  • packages/cli/src/types/init.ts
  • packages/cli/tests/init.test.ts

Comment thread packages/cli/src/controllers/init.ts
Review follow-up: conversion already ran the install step like fresh
init but silently ignored --link/--no-link/--project. The side-effect
steps now behave identically to fresh init (resolveInitLink handles the
already-linked short-circuit and non-interactive skip), while the
value-resolution flags stay rejected since conversion transports values.
Spec updated to state both rules.
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 8, 2026

@luanvdw luanvdw left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AmanVarshney01 thanks for this!

One edge I think we should look at before merging, conversion can find a prisma.compute.json in an ancestor directory, but the follow-up steps still seem to run from the directory where the command was invoked.

For example, if the repo root has prisma.compute.json and I run this from apps/api:

prisma-cli init --format ts --install --no-link --json

the command correctly writes ../../prisma.compute.ts, but the types/link side effects still use apps/api as the working directory. That means --install can miss the root package.json, and --project could write .prisma/local.json in the nested app directory even though deploy later reads the project binding from the config directory.

Could we make the conversion side-effect steps run against the discovered config directory, or pass that directory explicitly into the types/link helpers?

Review finding (Luan): conversion can discover prisma.compute.json in an
ancestor directory, but the types install and project link still acted
on the invocation directory, so --install could target the wrong
package.json and --project could pin .prisma/local.json in a nested app
dir while the config lives at the root. The side-effect steps now run
against the discovered config directory via a context whose runtime cwd
is the config's home; fresh init is unaffected since it writes at cwd.
The reported configPath stays relative to the invocation directory.
@AmanVarshney01

Copy link
Copy Markdown
Member Author

@luanvdw good catch, fixed in 23b796d. The side-effect steps now run against the discovered config directory: conversion builds a derived command context whose runtime cwd is the config's home, so --install reads/targets the root package.json (package-manager detection included) and --project writes .prisma/local.json next to the config instead of in the nested app dir. Fresh init is unchanged (it writes at the invocation directory, so the two never diverge there), and the reported configPath stays relative to where you ran the command.

Covered by a new test that converts from apps/api with the config at the repo root and asserts the fake installer's working directory and the pin location both land at the root and neither lands in apps/api (624 tests green). Spec updated to state the directory rule.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/product/command-spec.md`:
- Line 399: Clarify the `--format json` behavior in the command spec by
separating the failure case from the successful skipped-install case. In the
sentence describing the types install step, use the same `--format json` and
`--install` wording but make it explicit that `--install` is a usage error when
JSON output is requested, and separately state that when `--install` is not used
the result reports the step as skipped with no install hint.
- Line 401: The graduation-path description overstates atomicity for the
`runInitConversion` flow. Reword the `--format ts` conversion behavior so it
reflects the actual sequence in `runInitConversion`: write `prisma.compute.ts`,
then delete `prisma.compute.json`, with rollback and `INIT_CONVERT_INCOMPLETE`
on partial failure. Keep the rest of the behavior description unchanged, but
avoid phrasing like “in the same operation” that implies the write and delete
are atomic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3eec133c-c8bc-4141-9d87-e5929e3c35c4

📥 Commits

Reviewing files that changed from the base of the PR and between 0c1dbf0 and 23b796d.

📒 Files selected for processing (3)
  • docs/product/command-spec.md
  • packages/cli/src/controllers/init.ts
  • packages/cli/tests/init.test.ts

Comment thread docs/product/command-spec.md Outdated
Comment thread docs/product/command-spec.md Outdated
…rsion delete semantics

Review nits: the --format json sentence conflated the --install usage
error with the skipped-step report, and "deleted in the same operation"
overstated atomicity the INIT_CONVERT_INCOMPLETE error exists to handle.
@AmanVarshney01 AmanVarshney01 merged commit 2c63aa7 into main Jul 9, 2026
10 checks passed
@AmanVarshney01 AmanVarshney01 deleted the feat/init-json-config branch July 9, 2026 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants