create-prisma 0.9.5 → 0.10.0-pr.72.261.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 CHANGED
@@ -63,6 +63,22 @@ older cached version. Prisma Compute does not support Deno deployments yet.
63
63
  - `--yes`
64
64
  - `--force`
65
65
  - `--verbose`
66
+ - `--json`
67
+
68
+ ### JSON output for agents and automation
69
+
70
+ Use `--json` when another program is driving `create-prisma`:
71
+
72
+ ```bash
73
+ bunx create-prisma@latest my-app --template next --package-manager bun --no-deploy --json
74
+ ```
75
+
76
+ JSON mode is non-interactive and deploys by default; pass `--no-deploy` to generate locally only. It
77
+ writes exactly one compact result object to stdout and suppresses all human UI and subprocess output.
78
+ Successful results include the generated project, deployment metadata, next steps, and warnings.
79
+ Errors use the same envelope with `ok: false`, an actionable message, and the stage that failed.
80
+ `--verbose` is intentionally incompatible with `--json` so the machine-readable contract stays
81
+ deterministic.
66
82
 
67
83
  This branch intentionally targets Prisma 8 only. It does not generate a Prisma 7 compatibility path.
68
84
 
package/dist/cli.mjs CHANGED
@@ -1,12 +1,63 @@
1
1
  #!/usr/bin/env node
2
- import "./create-C2fGwZxV.mjs";
2
+ import { c as createCommandFailureResult } from "./create-JgaDOyzC.mjs";
3
3
  import { createCreatePrismaCli } from "./index.mjs";
4
4
 
5
+ //#region src/ui/json-output.ts
6
+ function isCreateCommandResult(value) {
7
+ if (typeof value !== "object" || value === null) return false;
8
+ return Reflect.get(value, "schemaVersion") === 1 && typeof Reflect.get(value, "ok") === "boolean";
9
+ }
10
+ function formatLoggerMessage(values) {
11
+ return values.map((value) => {
12
+ if (value instanceof Error) return value.message;
13
+ if (typeof value === "string") return value.trim();
14
+ try {
15
+ return JSON.stringify(value);
16
+ } catch {
17
+ return String(value);
18
+ }
19
+ }).filter(Boolean).join(" ");
20
+ }
21
+ function isJsonOutputRequested(argv) {
22
+ let requested = false;
23
+ for (const [index, argument] of argv.entries()) {
24
+ if (argument === "--json") requested = argv[index + 1]?.toLowerCase() !== "false";
25
+ if (argument.startsWith("--json=")) requested = argument.slice(7).toLowerCase() !== "false";
26
+ if (argument === "--no-json") requested = false;
27
+ }
28
+ return requested;
29
+ }
30
+ function createJsonOutputLogger(write = (output) => process.stdout.write(output)) {
31
+ let didWrite = false;
32
+ const writeResult = (result) => {
33
+ if (didWrite) return;
34
+ didWrite = true;
35
+ write(`${JSON.stringify(result)}\n`);
36
+ };
37
+ return {
38
+ info(...values) {
39
+ const result = values.length === 1 ? values[0] : void 0;
40
+ if (isCreateCommandResult(result)) {
41
+ writeResult(result);
42
+ return;
43
+ }
44
+ writeResult(createCommandFailureResult("parse_arguments", formatLoggerMessage(values) || "The CLI returned an unexpected result."));
45
+ },
46
+ error(...values) {
47
+ writeResult(createCommandFailureResult("parse_arguments", formatLoggerMessage(values) || "Could not parse command arguments."));
48
+ }
49
+ };
50
+ }
51
+
52
+ //#endregion
5
53
  //#region src/cli.ts
6
- createCreatePrismaCli().run({ process: { exit(code) {
7
- const commandExitCode = typeof process.exitCode === "number" && process.exitCode !== 0 ? process.exitCode : code;
8
- process.exit(commandExitCode);
9
- } } });
54
+ createCreatePrismaCli().run({
55
+ ...isJsonOutputRequested(process.argv) ? { logger: createJsonOutputLogger() } : {},
56
+ process: { exit(code) {
57
+ const commandExitCode = typeof process.exitCode === "number" && process.exitCode !== 0 ? process.exitCode : code;
58
+ process.exit(commandExitCode);
59
+ } }
60
+ });
10
61
 
11
62
  //#endregion
12
63
  export { };
@@ -10,25 +10,32 @@ import Handlebars from "handlebars";
10
10
  import { existsSync } from "node:fs";
11
11
  import { fileURLToPath } from "node:url";
12
12
  import { execa } from "execa";
13
+ import { Writable } from "node:stream";
13
14
  import { createInterface } from "node:readline";
14
15
  import { styleText } from "node:util";
15
16
 
17
+ //#region src/result.ts
18
+ const CREATE_PRISMA_RESULT_SCHEMA_VERSION = 1;
19
+ function createCommandFailureResult(stage, message, project) {
20
+ return {
21
+ schemaVersion: CREATE_PRISMA_RESULT_SCHEMA_VERSION,
22
+ ok: false,
23
+ error: {
24
+ stage,
25
+ message
26
+ },
27
+ ...project ? { project } : {}
28
+ };
29
+ }
30
+
31
+ //#endregion
16
32
  //#region src/telemetry/client.ts
17
- const TELEMETRY_API_KEY = "phc_cmc85avbWyuJ2JyKdGPdv7dxXli8xLdWDBPbvIXWJfs";
33
+ const TELEMETRY_API_KEY = "";
18
34
  const TELEMETRY_HOST = "https://us.i.posthog.com";
19
35
  const TELEMETRY_CONFIG_FILE = "telemetry.json";
20
36
  const UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
21
- function isTruthyEnvValue(value) {
22
- return [
23
- "1",
24
- "true",
25
- "yes",
26
- "on"
27
- ].includes(String(value ?? "").trim().toLowerCase());
28
- }
29
37
  function shouldDisableTelemetry() {
30
- if (isTruthyEnvValue(process.env.CI) || isTruthyEnvValue(process.env.GITHUB_ACTIONS)) return true;
31
- return process.env.CREATE_PRISMA_DISABLE_TELEMETRY !== void 0 || process.env.CREATE_PRISMA_TELEMETRY_DISABLED !== void 0 || process.env.DO_NOT_TRACK !== void 0;
38
+ return true;
32
39
  }
33
40
  function getTelemetryConfigDir() {
34
41
  if (process.platform === "darwin") return path.join(os.homedir(), "Library", "Application Support", "create-prisma");
@@ -50,7 +57,7 @@ async function getAnonymousId() {
50
57
  }
51
58
  function getCommonProperties() {
52
59
  return {
53
- "cli-version": "0.9.5",
60
+ "cli-version": "0.10.0-pr.72.261.1",
54
61
  "node-version": process.version,
55
62
  platform: process.platform,
56
63
  arch: process.arch
@@ -98,7 +105,8 @@ function getTargetDirectoryState(context) {
98
105
  function getBaseCreateProperties(input, context) {
99
106
  return {
100
107
  command: "create",
101
- "uses-defaults": input.yes === true,
108
+ "uses-defaults": input.yes === true || input.json === true,
109
+ json: input.json === true,
102
110
  verbose: input.verbose === true,
103
111
  force: input.force === true,
104
112
  template: context?.template ?? input.template ?? null,
@@ -174,7 +182,8 @@ const AuthoringStyleSchema = z.enum(authoringStyles);
174
182
  const CreateTemplateSchema = z.enum(createTemplates);
175
183
  const CommonCommandOptionsSchema = z.object({
176
184
  yes: z.boolean().optional().describe("Skip prompts and accept default choices"),
177
- verbose: z.boolean().optional().describe("Show verbose command output during setup")
185
+ verbose: z.boolean().optional().describe("Show verbose command output during setup"),
186
+ json: z.boolean().optional().describe("Emit one quiet JSON result for agents and automation (non-interactive; deploys unless --no-deploy)")
178
187
  });
179
188
  const PrismaSetupOptionsSchema = z.object({
180
189
  provider: DatabaseProviderSchema.optional().describe("Prisma 8 database target: PostgreSQL relational models or MongoDB document models"),
@@ -482,8 +491,8 @@ async function scaffoldCreateFrameworkTemplate(opts) {
482
491
  const dependencyVersionMap = {
483
492
  "@astrojs/node": "^10.0.2",
484
493
  "@elysiajs/node": "^1.4.5",
485
- "@prisma/composer": "0.15.0",
486
- "@prisma/composer-prisma-cloud": "0.15.0",
494
+ "@prisma/composer": "0.16.0",
495
+ "@prisma/composer-prisma-cloud": "0.16.0",
487
496
  "@prisma/orm-mongo": "8.0.0-rc.8",
488
497
  "@prisma/orm-postgres": "8.0.0-rc.8",
489
498
  "@sveltejs/adapter-node": "^5.3.2",
@@ -496,11 +505,12 @@ const dependencyVersionMap = {
496
505
  mongodb: "^7.1.0",
497
506
  "mongodb-memory-server": "^11.1.0",
498
507
  nitro: "^3.0.260610-beta",
499
- prisma: "8.0.0-rc.11",
508
+ prisma: "8.0.0-rc.12",
509
+ "temporal-polyfill": "^1.0.4",
500
510
  tsx: "^4.21.0",
501
511
  typescript: "^5.9.3"
502
512
  };
503
- const PRISMA_PLATFORM_CLI_PACKAGE = "prisma@8.0.0-rc.11";
513
+ const PRISMA_PLATFORM_CLI_PACKAGE = "prisma@8.0.0-rc.12";
504
514
  const PRISMA_DENO_CLI_PACKAGE = PRISMA_PLATFORM_CLI_PACKAGE;
505
515
  function getDependencyVersion(packageName) {
506
516
  return dependencyVersionMap[packageName];
@@ -541,6 +551,21 @@ function getDbPackages(provider) {
541
551
  }
542
552
  }
543
553
 
554
+ //#endregion
555
+ //#region src/utils/run-command.ts
556
+ /**
557
+ * Runs a setup command without allowing child output to corrupt structured CLI output.
558
+ * Human verbose mode keeps native streaming; JSON mode always captures child output.
559
+ */
560
+ async function runSetupCommand(options) {
561
+ const shouldInheritOutput = options.verbose && !options.json;
562
+ await execa(options.command, options.args, {
563
+ cwd: options.cwd,
564
+ env: options.env,
565
+ stdio: shouldInheritOutput ? "inherit" : "pipe"
566
+ });
567
+ }
568
+
544
569
  //#endregion
545
570
  //#region src/tasks/install.ts
546
571
  function getPrismaScriptMap(packageManager) {
@@ -625,6 +650,7 @@ async function addPackageDependency(opts) {
625
650
  }
626
651
  async function writePrismaDependencies(provider, packageManager, _authoring, projectDir = process.cwd()) {
627
652
  const dependencies = [getDbPackages(provider)];
653
+ if (provider === "postgres" && packageManager !== "deno") dependencies.push("temporal-polyfill");
628
654
  if (provider === "mongo") dependencies.push("arktype", "mongodb");
629
655
  if (packageManager === "deno") dependencies.push("dotenv");
630
656
  await addPackageDependency({
@@ -661,22 +687,46 @@ async function writeCreateTemplateDependencies(opts) {
661
687
  async function installProjectDependencies(packageManager, projectDir = process.cwd(), options = {}) {
662
688
  const installCommand = getInstallArgs(packageManager);
663
689
  const env = packageManager === "yarn" ? { YARN_ENABLE_IMMUTABLE_INSTALLS: "false" } : void 0;
664
- await execa(installCommand.command, installCommand.args, {
690
+ await runSetupCommand({
691
+ command: installCommand.command,
692
+ args: installCommand.args,
665
693
  cwd: projectDir,
666
694
  env,
667
- stdio: options.verbose === true ? "inherit" : "pipe"
695
+ verbose: options.verbose === true,
696
+ json: options.json === true
668
697
  });
669
698
  }
670
699
 
671
700
  //#endregion
672
- //#region src/tasks/deploy-with-composer.ts
701
+ //#region src/ui/output.ts
702
+ const silentOutput = new Writable({ write(_chunk, _encoding, callback) {
703
+ callback();
704
+ } });
705
+ /** Resolves the shared interaction policy for human and machine-readable modes. */
706
+ function resolveExecutionSettings(options) {
707
+ const json = options.json === true;
708
+ return {
709
+ json,
710
+ output: json ? silentOutput : process.stdout,
711
+ useDefaults: options.yes === true || json
712
+ };
713
+ }
714
+
715
+ //#endregion
716
+ //#region src/utils/errors.ts
673
717
  function redactSecrets(message) {
674
718
  return message.replace(/\b((?:(?:prisma\+)?postgres(?:ql)?|mongodb(?:\+srv)?):\/\/)[^\s'"]+/gi, "$1<redacted>").replace(/\b([A-Z0-9_]*(?:MONGODB_(?:URL|URI)|DATABASE_URL|TOKEN|SECRET|PASSWORD|API_KEY|PRIVATE_KEY)[A-Z0-9_]*\s*=\s*)(?:"[^"]*"|'[^']*'|[^\s]+)/gi, "$1<redacted>").replace(/(\bAuthorization\s*:\s*Bearer\s+)[^\s'"]+/gi, "$1<redacted>");
675
719
  }
676
720
  function getErrorMessage(error) {
677
- if (error instanceof Error) return redactSecrets(error.message);
678
- return redactSecrets(String(error));
721
+ if (error instanceof Error && "stderr" in error) {
722
+ const stderr = String(error.stderr ?? "").trim();
723
+ if (stderr) return redactSecrets(stderr);
724
+ }
725
+ return redactSecrets(error instanceof Error ? error.message : String(error));
679
726
  }
727
+
728
+ //#endregion
729
+ //#region src/tasks/deploy-with-composer.ts
680
730
  function stripResourcePrefix(id, prefix) {
681
731
  const marker = `${prefix}_`;
682
732
  return id.startsWith(marker) ? id.slice(marker.length) : id;
@@ -742,25 +792,25 @@ async function ensureProjectNameAvailable(options) {
742
792
  const projectIds = collisions.map((project) => project.id).join(", ");
743
793
  throw new Error(`A Prisma project named "${options.appName}" already exists in workspace ${workspaceLabel(options.workspace)} (${options.workspace.id}). Choose a different project name or delete the existing project (${projectIds}) in Prisma Console, then retry.`);
744
794
  }
745
- async function ensureAuthentication(packageManager, projectDir, beforeInteractiveLogin) {
795
+ async function ensureAuthentication(options) {
746
796
  const whoami = () => runPrismaJsonCommand({
747
- packageManager,
748
- projectDir,
797
+ packageManager: options.packageManager,
798
+ projectDir: options.projectDir,
749
799
  args: ["auth", "whoami"]
750
800
  });
751
801
  const authState = await whoami();
752
802
  if (authState.authenticated) return authState;
753
- const loginCommand = getPackageExecutionCommand(packageManager, [
803
+ const loginCommand = getPackageExecutionCommand(options.packageManager, [
754
804
  PRISMA_PLATFORM_CLI_PACKAGE,
755
805
  "auth",
756
806
  "login"
757
807
  ]);
758
- if (process.stdin.isTTY !== true) throw new Error(`Sign in first with ${loginCommand}, then run ${getRunScriptCommand(packageManager, "deploy")}.`);
759
- beforeInteractiveLogin?.();
760
- log.info("Sign in to Prisma to deploy.");
761
- const login = getPrismaCliArgs(packageManager, ["auth", "login"]);
808
+ if (!options.allowInteractiveLogin || process.stdin.isTTY !== true) throw new Error(`Sign in first with ${loginCommand}, then run ${getRunScriptCommand(options.packageManager, "deploy")}.`);
809
+ options.beforeInteractiveLogin?.();
810
+ log.info("Sign in to Prisma to deploy.", { output: options.output });
811
+ const login = getPrismaCliArgs(options.packageManager, ["auth", "login"]);
762
812
  await execa(login.command, login.args, {
763
- cwd: projectDir,
813
+ cwd: options.projectDir,
764
814
  env: process.env,
765
815
  stdio: "inherit"
766
816
  });
@@ -816,10 +866,11 @@ async function selectDeploymentWorkspace(options) {
816
866
  value: workspace.workspaceId,
817
867
  label: workspace.workspaceName ?? workspace.workspaceId,
818
868
  hint: workspace.current ? `${workspace.workspaceId}, current` : workspace.workspaceId
819
- }))
869
+ })),
870
+ output: options.output
820
871
  });
821
872
  if (isCancel(selectedWorkspaceId)) {
822
- cancel("Operation cancelled.");
873
+ cancel("Operation cancelled.", { output: options.output });
823
874
  return;
824
875
  }
825
876
  options.afterPrompt?.();
@@ -836,6 +887,7 @@ function parseComposerDeployResult(result) {
836
887
  const computeService = summary.nodes.flatMap((node) => node.entities).find((entity) => entity.kind === "compute-service");
837
888
  return {
838
889
  appName: summary.app,
890
+ ...computeService?.id ? { serviceId: computeService.id } : {},
839
891
  ...computeService?.url ? { appUrl: computeService.url.replace(/\/$/, "") } : {}
840
892
  };
841
893
  }
@@ -868,7 +920,8 @@ async function getProjectDetails(options) {
868
920
  * Generated projects use their own `deploy` script for every subsequent deployment.
869
921
  */
870
922
  async function deployNewProjectWithComposer(options) {
871
- const progress = options.verbose ? void 0 : spinner();
923
+ const output = options.output ?? process.stdout;
924
+ const progress = options.verbose ? void 0 : spinner({ output });
872
925
  let deploymentLog;
873
926
  let progressRunning = false;
874
927
  const showProgress = (message) => {
@@ -886,22 +939,29 @@ async function deployNewProjectWithComposer(options) {
886
939
  };
887
940
  try {
888
941
  showProgress("Checking Prisma account...");
889
- if (options.verbose) log.step("Checking Prisma account.");
890
- const authState = await ensureAuthentication(options.packageManager, options.projectDir, clearProgress);
942
+ if (options.verbose) log.step("Checking Prisma account.", { output });
943
+ const authState = await ensureAuthentication({
944
+ packageManager: options.packageManager,
945
+ projectDir: options.projectDir,
946
+ output,
947
+ allowInteractiveLogin: options.allowInteractiveLogin ?? true,
948
+ beforeInteractiveLogin: clearProgress
949
+ });
891
950
  showProgress("Checking Prisma workspace...");
892
- if (options.verbose) log.step("Checking Prisma workspace.");
951
+ if (options.verbose) log.step("Checking Prisma workspace.", { output });
893
952
  const selectedWorkspace = await selectDeploymentWorkspace({
894
953
  packageManager: options.packageManager,
895
954
  projectDir: options.projectDir,
896
955
  shouldPrompt: options.shouldPromptForWorkspace,
897
956
  authState,
957
+ output,
898
958
  beforePrompt: clearProgress,
899
959
  afterPrompt: () => showProgress("Selecting Prisma workspace..."),
900
960
  ...options.workspace ? { workspace: options.workspace } : {}
901
961
  });
902
962
  if (!selectedWorkspace) return;
903
963
  showProgress("Checking Prisma project name...");
904
- if (options.verbose) log.step("Checking Prisma project name.");
964
+ if (options.verbose) log.step("Checking Prisma project name.", { output });
905
965
  await ensureProjectNameAvailable({
906
966
  appName: options.appName,
907
967
  packageManager: options.packageManager,
@@ -909,12 +969,15 @@ async function deployNewProjectWithComposer(options) {
909
969
  workspace: selectedWorkspace
910
970
  });
911
971
  showProgress("Building for deployment...");
912
- if (options.verbose) log.step("Building for deployment.");
972
+ if (options.verbose) log.step("Building for deployment.", { output });
913
973
  const build = getRunScriptArgs(options.packageManager, "build");
914
- await execa(build.command, build.args, {
974
+ await runSetupCommand({
975
+ command: build.command,
976
+ args: build.args,
915
977
  cwd: options.projectDir,
916
978
  env: process.env,
917
- stdio: options.verbose ? "inherit" : "pipe"
979
+ verbose: options.verbose,
980
+ json: options.json === true
918
981
  });
919
982
  clearProgress();
920
983
  const deployCommand = getPackageExecutionCommand(options.packageManager, [
@@ -922,11 +985,12 @@ async function deployNewProjectWithComposer(options) {
922
985
  "deploy",
923
986
  "module.ts"
924
987
  ]);
925
- if (options.verbose) log.step(`Deploying to Prisma with ${deployCommand}.`);
988
+ if (options.verbose) log.step(`Deploying to Prisma with ${deployCommand}.`, { output });
926
989
  else {
927
990
  deploymentLog = taskLog({
928
991
  title: "Deploying to Prisma...",
929
- limit: 10
992
+ limit: 10,
993
+ output
930
994
  });
931
995
  deploymentLog.message(`$ ${deployCommand}`);
932
996
  }
@@ -936,12 +1000,12 @@ async function deployNewProjectWithComposer(options) {
936
1000
  args: ["deploy", "module.ts"],
937
1001
  onStderrLine: (line) => {
938
1002
  const redactedLine = redactSecrets(line);
939
- if (options.verbose) process.stderr.write(`${redactedLine}\n`);
1003
+ if (options.verbose) output.write(`${redactedLine}\n`);
940
1004
  else deploymentLog?.message(redactedLine);
941
1005
  }
942
1006
  }));
943
1007
  const appName = deployment?.appName ?? options.appName;
944
- if (options.verbose) log.step("Loading deployment details.");
1008
+ if (options.verbose) log.step("Loading deployment details.", { output });
945
1009
  else deploymentLog?.message("Loading deployment details...");
946
1010
  const details = await getProjectDetails({
947
1011
  packageManager: options.packageManager,
@@ -951,11 +1015,12 @@ async function deployNewProjectWithComposer(options) {
951
1015
  deploymentLog?.success("Deployed to Prisma.");
952
1016
  deploymentLog = void 0;
953
1017
  progressRunning = false;
954
- if (options.verbose) log.success("Deployed to Prisma.");
1018
+ if (options.verbose) log.success("Deployed to Prisma.", { output });
955
1019
  const workspace = details?.workspace ?? selectedWorkspace;
956
1020
  return {
957
1021
  appName,
958
1022
  ...deployment?.appUrl ? { appUrl: deployment.appUrl } : {},
1023
+ ...deployment?.serviceId ? { serviceId: deployment.serviceId } : {},
959
1024
  ...workspace ? { workspace } : {},
960
1025
  project: details?.project ?? { name: appName }
961
1026
  };
@@ -965,7 +1030,8 @@ async function deployNewProjectWithComposer(options) {
965
1030
  deploymentLog = void 0;
966
1031
  } else progress?.error("Deployment failed.");
967
1032
  progressRunning = false;
968
- log.error(`Deploy failed: ${getErrorMessage(error)}`);
1033
+ log.error(`Deploy failed: ${getErrorMessage(error)}`, { output });
1034
+ if (options.throwOnError) throw error;
969
1035
  return;
970
1036
  }
971
1037
  }
@@ -1031,7 +1097,7 @@ async function initializeGitRepository(projectDir, env = process.env) {
1031
1097
  //#region src/tasks/setup-prisma.ts
1032
1098
  const DEFAULT_DATABASE_PROVIDER = "postgres";
1033
1099
  const DEFAULT_AUTHORING = "psl";
1034
- async function promptForDatabaseProvider() {
1100
+ async function promptForDatabaseProvider(output) {
1035
1101
  const databaseProvider = await select({
1036
1102
  message: "Select your database",
1037
1103
  initialValue: DEFAULT_DATABASE_PROVIDER,
@@ -1043,15 +1109,16 @@ async function promptForDatabaseProvider() {
1043
1109
  value: "mongo",
1044
1110
  label: "MongoDB",
1045
1111
  hint: "Connect an existing MongoDB database"
1046
- }]
1112
+ }],
1113
+ output
1047
1114
  });
1048
1115
  if (isCancel(databaseProvider)) {
1049
- cancel("Operation cancelled.");
1116
+ cancel("Operation cancelled.", { output });
1050
1117
  return;
1051
1118
  }
1052
1119
  return DatabaseProviderSchema.parse(databaseProvider);
1053
1120
  }
1054
- async function promptForAuthoringStyle() {
1121
+ async function promptForAuthoringStyle(output) {
1055
1122
  const authoring = await select({
1056
1123
  message: "Choose contract authoring style",
1057
1124
  initialValue: DEFAULT_AUTHORING,
@@ -1063,10 +1130,11 @@ async function promptForAuthoringStyle() {
1063
1130
  value: "typescript",
1064
1131
  label: "TypeScript",
1065
1132
  hint: "TypeScript contract builder"
1066
- }]
1133
+ }],
1134
+ output
1067
1135
  });
1068
1136
  if (isCancel(authoring)) {
1069
- cancel("Operation cancelled.");
1137
+ cancel("Operation cancelled.", { output });
1070
1138
  return;
1071
1139
  }
1072
1140
  return AuthoringStyleSchema.parse(authoring);
@@ -1081,7 +1149,7 @@ function getPackageManagerHint(option, detected) {
1081
1149
  };
1082
1150
  return option === detected ? `Detected; ${hints[option]}` : hints[option];
1083
1151
  }
1084
- async function promptForPackageManager(detected) {
1152
+ async function promptForPackageManager(detected, output) {
1085
1153
  const packageManager = await select({
1086
1154
  message: "Choose package manager",
1087
1155
  initialValue: detected,
@@ -1089,43 +1157,47 @@ async function promptForPackageManager(detected) {
1089
1157
  value,
1090
1158
  label: value,
1091
1159
  hint: getPackageManagerHint(value, detected)
1092
- }))
1160
+ })),
1161
+ output
1093
1162
  });
1094
1163
  if (isCancel(packageManager)) {
1095
- cancel("Operation cancelled.");
1164
+ cancel("Operation cancelled.", { output });
1096
1165
  return;
1097
1166
  }
1098
1167
  return PackageManagerSchema.parse(packageManager);
1099
1168
  }
1100
- async function promptForDeployment() {
1169
+ async function promptForDeployment(output) {
1101
1170
  const shouldDeploy = await confirm({
1102
1171
  message: "Deploy to Prisma now?",
1103
- initialValue: true
1172
+ initialValue: true,
1173
+ output
1104
1174
  });
1105
1175
  if (isCancel(shouldDeploy)) {
1106
- cancel("Operation cancelled.");
1176
+ cancel("Operation cancelled.", { output });
1107
1177
  return;
1108
1178
  }
1109
1179
  return Boolean(shouldDeploy);
1110
1180
  }
1111
1181
  async function collectPrismaSetupContext(input, options = {}) {
1112
1182
  const projectDir = path.resolve(options.projectDir ?? process.cwd());
1113
- const useDefaults = input.yes === true;
1114
- const databaseProvider = input.provider ?? (useDefaults ? DEFAULT_DATABASE_PROVIDER : await promptForDatabaseProvider());
1183
+ const { json, output, useDefaults } = resolveExecutionSettings(input);
1184
+ const databaseProvider = input.provider ?? (useDefaults ? DEFAULT_DATABASE_PROVIDER : await promptForDatabaseProvider(output));
1115
1185
  if (!databaseProvider) return;
1116
- const authoring = input.authoring ?? (useDefaults ? DEFAULT_AUTHORING : await promptForAuthoringStyle());
1186
+ const authoring = input.authoring ?? (useDefaults ? DEFAULT_AUTHORING : await promptForAuthoringStyle(output));
1117
1187
  if (!authoring) return;
1118
1188
  const detectedPackageManager = await detectPackageManager(projectDir);
1119
- const packageManager = input.packageManager ?? (useDefaults ? detectedPackageManager : await promptForPackageManager(detectedPackageManager));
1189
+ const packageManager = input.packageManager ?? (useDefaults ? detectedPackageManager : await promptForPackageManager(detectedPackageManager, output));
1120
1190
  if (!packageManager) return;
1121
1191
  if (packageManager === "deno" && databaseProvider !== "postgres") throw new Error("Deno support currently requires PostgreSQL.");
1122
1192
  if (packageManager === "deno" && options.template && options.template !== "minimal") throw new Error("Deno support currently requires the minimal template.");
1123
1193
  if (packageManager === "deno" && input.deploy === true) throw new Error("Prisma Compute does not support Deno deployments yet. Use --no-deploy.");
1124
- const shouldDeploy = packageManager === "deno" ? false : input.deploy ?? (useDefaults ? false : await promptForDeployment());
1194
+ const shouldDeploy = packageManager === "deno" ? false : input.deploy ?? (json ? true : useDefaults ? false : await promptForDeployment(output));
1125
1195
  if (shouldDeploy === void 0) return;
1126
1196
  return {
1127
1197
  projectDir,
1128
1198
  verbose: input.verbose === true,
1199
+ json,
1200
+ output,
1129
1201
  databaseProvider,
1130
1202
  authoring,
1131
1203
  packageManager,
@@ -1134,13 +1206,6 @@ async function collectPrismaSetupContext(input, options = {}) {
1134
1206
  ...input.workspace ? { workspace: input.workspace } : {}
1135
1207
  };
1136
1208
  }
1137
- function getCommandErrorMessage(error) {
1138
- if (error instanceof Error && "stderr" in error) {
1139
- const stderr = String(error.stderr ?? "").trim();
1140
- if (stderr) return stderr;
1141
- }
1142
- return error instanceof Error ? error.message : String(error);
1143
- }
1144
1209
  function getContractPath(authoring) {
1145
1210
  return `src/prisma/contract${authoring === "typescript" ? ".ts" : ".prisma"}`;
1146
1211
  }
@@ -1165,14 +1230,17 @@ async function runPrismaInit(context, projectDir) {
1165
1230
  "--skip-install"
1166
1231
  ];
1167
1232
  const invocation = getPrismaCliInvocation(context.packageManager, args);
1168
- if (context.verbose) log.step(`Running ${[invocation.command, ...invocation.args].join(" ")}`);
1169
- await execa(invocation.command, invocation.args, {
1233
+ if (context.verbose) log.step(`Running ${[invocation.command, ...invocation.args].join(" ")}`, { output: context.output });
1234
+ await runSetupCommand({
1235
+ command: invocation.command,
1236
+ args: invocation.args,
1170
1237
  cwd: projectDir,
1171
- stdio: context.verbose ? "inherit" : "pipe",
1172
1238
  env: {
1173
1239
  ...process.env,
1174
1240
  CI: "1"
1175
- }
1241
+ },
1242
+ verbose: context.verbose,
1243
+ json: context.json
1176
1244
  });
1177
1245
  if (context.packageManager === "deno") await fs.remove(path.join(projectDir, "prisma-next.md"));
1178
1246
  }
@@ -1183,14 +1251,17 @@ async function initializeAgentSkills(context, projectDir) {
1183
1251
  "--yes",
1184
1252
  "--no-interactive"
1185
1253
  ]);
1186
- if (context.verbose) log.step(`Running ${[invocation.command, ...invocation.args].join(" ")}`);
1187
- await execa(invocation.command, invocation.args, {
1254
+ if (context.verbose) log.step(`Running ${[invocation.command, ...invocation.args].join(" ")}`, { output: context.output });
1255
+ await runSetupCommand({
1256
+ command: invocation.command,
1257
+ args: invocation.args,
1188
1258
  cwd: projectDir,
1189
- stdio: context.verbose ? "inherit" : "pipe",
1190
1259
  env: {
1191
1260
  ...process.env,
1192
1261
  CI: "1"
1193
- }
1262
+ },
1263
+ verbose: context.verbose,
1264
+ json: context.json
1194
1265
  });
1195
1266
  }
1196
1267
  async function ensureGitignoreEntry(projectDir, entry) {
@@ -1219,14 +1290,17 @@ async function ensureComposerTypeScriptOptions(projectDir) {
1219
1290
  }
1220
1291
  async function runPrismaCli(context, projectDir, args) {
1221
1292
  const invocation = getPrismaCliInvocation(context.packageManager, args);
1222
- if (context.verbose) log.step([invocation.command, ...invocation.args].join(" "));
1223
- await execa(invocation.command, invocation.args, {
1293
+ if (context.verbose) log.step([invocation.command, ...invocation.args].join(" "), { output: context.output });
1294
+ await runSetupCommand({
1295
+ command: invocation.command,
1296
+ args: invocation.args,
1224
1297
  cwd: projectDir,
1225
- stdio: context.verbose ? "inherit" : "pipe",
1226
1298
  env: {
1227
1299
  ...process.env,
1228
1300
  CI: "1"
1229
- }
1301
+ },
1302
+ verbose: context.verbose,
1303
+ json: context.json
1230
1304
  });
1231
1305
  }
1232
1306
  async function emitContract(context, projectDir) {
@@ -1278,7 +1352,7 @@ async function executePrismaSetupContext(context, options = {}) {
1278
1352
  const projectDir = path.resolve(options.projectDir ?? context.projectDir);
1279
1353
  const projectName = options.projectName ?? path.basename(projectDir);
1280
1354
  const template = options.template ?? "minimal";
1281
- const progress = context.verbose ? void 0 : options.progressSpinner ?? spinner();
1355
+ const progress = context.verbose ? void 0 : options.progressSpinner ?? spinner({ output: context.output });
1282
1356
  const ownsProgress = progress !== void 0 && !options.progressSpinner;
1283
1357
  let gitInitialization;
1284
1358
  if (ownsProgress) progress.start("Creating Prisma 8 project...");
@@ -1301,7 +1375,10 @@ async function executePrismaSetupContext(context, options = {}) {
1301
1375
  await ensureGitignoreEntry(projectDir, "/.prisma-composer");
1302
1376
  }
1303
1377
  progress?.message(`Installing dependencies with ${getInstallCommand(context.packageManager)}...`);
1304
- await installProjectDependencies(context.packageManager, projectDir, { verbose: context.verbose });
1378
+ await installProjectDependencies(context.packageManager, projectDir, {
1379
+ verbose: context.verbose,
1380
+ json: context.json
1381
+ });
1305
1382
  progress?.message("Installing Prisma agent skills...");
1306
1383
  await initializeAgentSkills(context, projectDir);
1307
1384
  progress?.message("Generating Prisma 8 contract artifacts...");
@@ -1315,12 +1392,16 @@ async function executePrismaSetupContext(context, options = {}) {
1315
1392
  gitInitialization = await initializeGitRepository(projectDir);
1316
1393
  }
1317
1394
  progress?.stop("Prisma 8 project ready.");
1318
- if (gitInitialization?.status === "initialized" && context.verbose) log.success("Initialized Git repository with an initial commit.");
1319
- else if (gitInitialization?.status === "skipped") log.warn(`Could not initialize Git repository: ${gitInitialization.reason}`);
1395
+ if (gitInitialization?.status === "initialized" && context.verbose) log.success("Initialized Git repository with an initial commit.", { output: context.output });
1396
+ else if (gitInitialization?.status === "skipped") log.warn(`Could not initialize Git repository: ${gitInitialization.reason}`, { output: context.output });
1320
1397
  } catch (error) {
1321
1398
  progress?.error("Could not create Prisma 8 project.");
1322
- cancel(getCommandErrorMessage(error));
1323
- return false;
1399
+ cancel(getErrorMessage(error), { output: context.output });
1400
+ return {
1401
+ ok: false,
1402
+ error,
1403
+ errorReported: true
1404
+ };
1324
1405
  }
1325
1406
  let deployment;
1326
1407
  if (context.shouldDeploy) {
@@ -1330,18 +1411,33 @@ async function executePrismaSetupContext(context, options = {}) {
1330
1411
  projectDir,
1331
1412
  shouldPromptForWorkspace: context.shouldPromptForWorkspace,
1332
1413
  verbose: context.verbose,
1414
+ output: context.output,
1415
+ allowInteractiveLogin: !context.json,
1416
+ json: context.json,
1417
+ throwOnError: context.json,
1333
1418
  ...context.workspace ? { workspace: context.workspace } : {}
1334
1419
  });
1335
- if (!deployment) return false;
1420
+ if (!deployment) return {
1421
+ ok: false,
1422
+ errorReported: true
1423
+ };
1336
1424
  }
1425
+ const nextSteps = buildNextSteps(context, options);
1426
+ const warnings = gitInitialization?.status === "skipped" ? [`Could not initialize Git repository: ${gitInitialization.reason}`] : [];
1337
1427
  const projectSummary = formatProjectSummary({
1338
1428
  createdProjectPath: options.createdProjectPath,
1339
1429
  deployment
1340
1430
  });
1341
- if (projectSummary) note(projectSummary, context.shouldDeploy ? "Deployment" : "Project");
1342
- note(formatNextSteps(buildNextSteps(context, options)), "Next steps");
1343
- outro(context.shouldDeploy ? "Prisma 8 app deployed." : "Prisma 8 project ready.");
1344
- return true;
1431
+ if (projectSummary) note(projectSummary, context.shouldDeploy ? "Deployment" : "Project", { output: context.output });
1432
+ note(formatNextSteps(nextSteps), "Next steps", { output: context.output });
1433
+ outro(context.shouldDeploy ? "Prisma 8 app deployed." : "Prisma 8 project ready.", { output: context.output });
1434
+ return {
1435
+ ok: true,
1436
+ deployment: deployment ?? null,
1437
+ nextSteps,
1438
+ ...gitInitialization ? { gitInitialization } : {},
1439
+ warnings
1440
+ };
1345
1441
  }
1346
1442
 
1347
1443
  //#endregion
@@ -1366,7 +1462,7 @@ function parseVersion(version) {
1366
1462
  Number.parseInt(patch, 10)
1367
1463
  ];
1368
1464
  }
1369
- function supportsPrismaNext(nodeVersion = process.versions.node) {
1465
+ function supportsPrisma(nodeVersion = process.versions.node) {
1370
1466
  const current = parseVersion(nodeVersion);
1371
1467
  for (let index = 0; index < MINIMUM_NODE_VERSION.length; index += 1) {
1372
1468
  if (current[index] > MINIMUM_NODE_VERSION[index]) return true;
@@ -1398,20 +1494,31 @@ function validateProjectName(value) {
1398
1494
  if (trimmed === "..") return "Project name cannot be '..'.";
1399
1495
  if (path.isAbsolute(trimmed)) return "Use a relative project name instead of an absolute path.";
1400
1496
  }
1401
- async function promptForProjectName() {
1497
+ function getProjectResult(context) {
1498
+ return {
1499
+ name: context.projectPackageName,
1500
+ path: context.targetDirectory,
1501
+ template: context.template,
1502
+ databaseProvider: context.prismaSetupContext.databaseProvider,
1503
+ authoring: context.prismaSetupContext.authoring,
1504
+ packageManager: context.prismaSetupContext.packageManager
1505
+ };
1506
+ }
1507
+ async function promptForProjectName(output) {
1402
1508
  const projectName = await text({
1403
1509
  message: "Project name",
1404
1510
  placeholder: DEFAULT_PROJECT_NAME,
1405
1511
  initialValue: DEFAULT_PROJECT_NAME,
1406
- validate: validateProjectName
1512
+ validate: validateProjectName,
1513
+ output
1407
1514
  });
1408
1515
  if (isCancel(projectName)) {
1409
- cancel("Operation cancelled.");
1516
+ cancel("Operation cancelled.", { output });
1410
1517
  return;
1411
1518
  }
1412
1519
  return String(projectName).trim();
1413
1520
  }
1414
- async function promptForCreateTemplate() {
1521
+ async function promptForCreateTemplate(output) {
1415
1522
  const template = await select({
1416
1523
  message: "Select template",
1417
1524
  initialValue: DEFAULT_TEMPLATE,
@@ -1461,10 +1568,11 @@ async function promptForCreateTemplate() {
1461
1568
  label: "TanStack Start",
1462
1569
  hint: "React app with file routes and server functions"
1463
1570
  }
1464
- ]
1571
+ ],
1572
+ output
1465
1573
  });
1466
1574
  if (isCancel(template)) {
1467
- cancel("Operation cancelled.");
1575
+ cancel("Operation cancelled.", { output });
1468
1576
  return;
1469
1577
  }
1470
1578
  return CreateTemplateSchema.parse(template);
@@ -1491,22 +1599,36 @@ async function runCreateCommand(rawInput = {}) {
1491
1599
  let input = {};
1492
1600
  let context;
1493
1601
  let failureStage = "validate_input";
1602
+ const { output } = resolveExecutionSettings(rawInput);
1494
1603
  try {
1495
1604
  input = CreateCommandInputSchema.parse(rawInput);
1496
- if (!supportsPrismaNext()) {
1497
- cancel(getUnsupportedNodeMessage());
1605
+ if (input.json && input.verbose) throw new Error("--verbose cannot be used with --json because JSON mode is output-only.");
1606
+ if (!supportsPrisma()) {
1607
+ const message = getUnsupportedNodeMessage();
1608
+ cancel(message, { output });
1498
1609
  process.exitCode = 1;
1499
- return;
1610
+ return createCommandFailureResult(failureStage, message);
1500
1611
  }
1501
- intro(getCreatePrismaIntro());
1612
+ intro(getCreatePrismaIntro(), { output });
1502
1613
  failureStage = "collect_context";
1503
- context = await collectCreateContext(input);
1504
- if (!context) return;
1614
+ const collected = await collectCreateContext(input);
1615
+ if (!collected.ok) {
1616
+ process.exitCode = 1;
1617
+ const result = createCommandFailureResult(failureStage, collected.message);
1618
+ await trackCreateFailed({
1619
+ input,
1620
+ durationMs: Date.now() - startedAt,
1621
+ stage: failureStage
1622
+ });
1623
+ return result;
1624
+ }
1625
+ context = collected.context;
1505
1626
  failureStage = "unknown";
1506
1627
  const executionResult = await executeCreateContext(context);
1507
1628
  if (!executionResult.ok) {
1508
1629
  process.exitCode = 1;
1509
- if (executionResult.error) cancel(`Create command failed: ${executionResult.error instanceof Error ? executionResult.error.message : String(executionResult.error)}`);
1630
+ const message = executionResult.error ? getErrorMessage(executionResult.error) : "Project setup did not complete.";
1631
+ if (executionResult.error && !executionResult.errorReported) cancel(`Create command failed: ${message}`, { output });
1510
1632
  await trackCreateFailed({
1511
1633
  input,
1512
1634
  context,
@@ -1514,16 +1636,18 @@ async function runCreateCommand(rawInput = {}) {
1514
1636
  error: executionResult.error,
1515
1637
  stage: executionResult.stage
1516
1638
  });
1517
- return;
1639
+ return createCommandFailureResult(executionResult.stage, message, getProjectResult(context));
1518
1640
  }
1519
1641
  await trackCreateCompleted({
1520
1642
  input,
1521
1643
  context,
1522
1644
  durationMs: Date.now() - startedAt
1523
1645
  });
1646
+ return executionResult.result;
1524
1647
  } catch (error) {
1525
1648
  process.exitCode = 1;
1526
- cancel(`Create command failed: ${error instanceof Error ? error.message : String(error)}`);
1649
+ const message = getErrorMessage(error);
1650
+ cancel(`Create command failed: ${message}`, { output });
1527
1651
  await trackCreateFailed({
1528
1652
  input,
1529
1653
  context,
@@ -1531,50 +1655,75 @@ async function runCreateCommand(rawInput = {}) {
1531
1655
  error,
1532
1656
  stage: failureStage
1533
1657
  });
1658
+ return createCommandFailureResult(failureStage, message, context ? getProjectResult(context) : void 0);
1534
1659
  }
1535
1660
  }
1536
1661
  async function collectCreateContext(input) {
1537
1662
  const force = input.force === true;
1538
- const useDefaults = input.yes === true;
1539
- const projectNameInput = input.name ?? (useDefaults ? DEFAULT_PROJECT_NAME : await promptForProjectName());
1540
- if (projectNameInput === void 0) return;
1663
+ const { output, useDefaults } = resolveExecutionSettings(input);
1664
+ const projectNameInput = input.name ?? (useDefaults ? DEFAULT_PROJECT_NAME : await promptForProjectName(output));
1665
+ if (projectNameInput === void 0) return {
1666
+ ok: false,
1667
+ message: "Operation cancelled."
1668
+ };
1541
1669
  const projectName = String(projectNameInput).trim();
1542
1670
  const projectNameValidationError = validateProjectName(projectName);
1543
1671
  if (projectNameValidationError) {
1544
- cancel(projectNameValidationError);
1545
- return;
1672
+ cancel(projectNameValidationError, { output });
1673
+ return {
1674
+ ok: false,
1675
+ message: projectNameValidationError
1676
+ };
1546
1677
  }
1547
- const template = input.template ?? (useDefaults ? DEFAULT_TEMPLATE : await promptForCreateTemplate());
1548
- if (!template) return;
1678
+ const template = input.template ?? (useDefaults ? DEFAULT_TEMPLATE : await promptForCreateTemplate(output));
1679
+ if (!template) return {
1680
+ ok: false,
1681
+ message: "Operation cancelled."
1682
+ };
1549
1683
  const targetDirectory = path.resolve(process.cwd(), projectName);
1550
1684
  const targetPathState = await inspectTargetPath(targetDirectory);
1551
1685
  if (targetPathState.exists && !targetPathState.isDirectory) {
1552
- cancel(`Target path ${formatPathForDisplay(targetDirectory)} already exists and is not a directory. Choose a different project name.`);
1553
- return;
1686
+ const message = `Target path ${formatPathForDisplay(targetDirectory)} already exists and is not a directory. Choose a different project name.`;
1687
+ cancel(message, { output });
1688
+ return {
1689
+ ok: false,
1690
+ message
1691
+ };
1554
1692
  }
1555
1693
  if (targetPathState.exists && !targetPathState.isEmptyDirectory && !force) {
1556
- cancel(`Target directory ${formatPathForDisplay(targetDirectory)} is not empty. Use --force to continue.`);
1557
- return;
1694
+ const message = `Target directory ${formatPathForDisplay(targetDirectory)} is not empty. Use --force to continue.`;
1695
+ cancel(message, { output });
1696
+ return {
1697
+ ok: false,
1698
+ message
1699
+ };
1558
1700
  }
1559
1701
  const prismaSetupContext = await collectPrismaSetupContext(input, {
1560
1702
  projectDir: targetDirectory,
1561
1703
  template
1562
1704
  });
1563
- if (!prismaSetupContext) return;
1705
+ if (!prismaSetupContext) return {
1706
+ ok: false,
1707
+ message: "Operation cancelled."
1708
+ };
1564
1709
  return {
1565
- targetDirectory,
1566
- targetPathState,
1567
- force,
1568
- template,
1569
- projectPackageName: toPackageName(path.basename(targetDirectory)),
1570
- prismaSetupContext
1710
+ ok: true,
1711
+ context: {
1712
+ targetDirectory,
1713
+ targetPathState,
1714
+ force,
1715
+ template,
1716
+ projectPackageName: toPackageName(path.basename(targetDirectory)),
1717
+ prismaSetupContext
1718
+ }
1571
1719
  };
1572
1720
  }
1573
1721
  async function executeCreateContext(context) {
1574
- const createSpinner = context.prismaSetupContext.verbose ? void 0 : spinner();
1722
+ const output = context.prismaSetupContext.output;
1723
+ const createSpinner = context.prismaSetupContext.verbose ? void 0 : spinner({ output });
1575
1724
  createSpinner?.start("Creating Prisma 8 project...");
1576
1725
  try {
1577
- if (context.prismaSetupContext.verbose) log.step(`Scaffolding ${context.template} starter.`);
1726
+ if (context.prismaSetupContext.verbose) log.step(`Scaffolding ${context.template} starter.`, { output });
1578
1727
  await scaffoldCreateFrameworkTemplate({
1579
1728
  projectDir: context.targetDirectory,
1580
1729
  projectName: context.projectPackageName,
@@ -1583,7 +1732,7 @@ async function executeCreateContext(context) {
1583
1732
  authoring: context.prismaSetupContext.authoring,
1584
1733
  packageManager: context.prismaSetupContext.packageManager
1585
1734
  });
1586
- if (context.prismaSetupContext.verbose) log.success("Starter files scaffolded.");
1735
+ if (context.prismaSetupContext.verbose) log.success("Starter files scaffolded.", { output });
1587
1736
  } catch (error) {
1588
1737
  createSpinner?.error("Could not create Prisma 8 project.");
1589
1738
  return {
@@ -1606,13 +1755,14 @@ async function executeCreateContext(context) {
1606
1755
  error
1607
1756
  };
1608
1757
  }
1609
- if (context.targetPathState.exists && !context.targetPathState.isEmptyDirectory && context.force) log.warn(`Used --force in non-empty directory ${formatPathForDisplay(context.targetDirectory)}.`);
1758
+ const forceWarning = context.targetPathState.exists && !context.targetPathState.isEmptyDirectory && context.force ? `Used --force in non-empty directory ${formatPathForDisplay(context.targetDirectory)}.` : void 0;
1759
+ if (forceWarning) log.warn(forceWarning, { output });
1610
1760
  const nextSteps = formatPathForDisplay(context.targetDirectory) === "." ? [] : [{
1611
1761
  command: `cd ${formatPathForDisplay(context.targetDirectory)}`,
1612
1762
  description: "Enter your new project directory."
1613
1763
  }];
1614
1764
  try {
1615
- if (!await executePrismaSetupContext(context.prismaSetupContext, {
1765
+ const setupResult = await executePrismaSetupContext(context.prismaSetupContext, {
1616
1766
  prependNextSteps: nextSteps,
1617
1767
  projectDir: context.targetDirectory,
1618
1768
  projectName: context.projectPackageName,
@@ -1621,9 +1771,25 @@ async function executeCreateContext(context) {
1621
1771
  includeDevNextStep: true,
1622
1772
  initializeGit: !context.targetPathState.exists || context.targetPathState.isEmptyDirectory,
1623
1773
  progressSpinner: createSpinner
1624
- })) return {
1774
+ });
1775
+ if (!setupResult.ok) return {
1625
1776
  ok: false,
1626
- stage: "prisma_setup"
1777
+ stage: "prisma_setup",
1778
+ error: setupResult.error,
1779
+ errorReported: setupResult.errorReported
1780
+ };
1781
+ const warnings = [...setupResult.warnings];
1782
+ if (forceWarning) warnings.unshift(forceWarning);
1783
+ return {
1784
+ ok: true,
1785
+ result: {
1786
+ schemaVersion: CREATE_PRISMA_RESULT_SCHEMA_VERSION,
1787
+ ok: true,
1788
+ project: getProjectResult(context),
1789
+ deployment: setupResult.deployment,
1790
+ nextSteps: setupResult.nextSteps,
1791
+ warnings
1792
+ }
1627
1793
  };
1628
1794
  } catch (error) {
1629
1795
  createSpinner?.error("Could not create Prisma 8 project.");
@@ -1633,8 +1799,7 @@ async function executeCreateContext(context) {
1633
1799
  error
1634
1800
  };
1635
1801
  }
1636
- return { ok: true };
1637
1802
  }
1638
1803
 
1639
1804
  //#endregion
1640
- export { DatabaseProviderSchema as a, CreateTemplateSchema as i, AuthoringStyleSchema as n, PackageManagerSchema as o, CreateCommandInputSchema as r, runCreateCommand as t };
1805
+ export { DatabaseProviderSchema as a, createCommandFailureResult as c, CreateTemplateSchema as i, AuthoringStyleSchema as n, PackageManagerSchema as o, CreateCommandInputSchema as r, CREATE_PRISMA_RESULT_SCHEMA_VERSION as s, runCreateCommand as t };
package/dist/index.d.mts CHANGED
@@ -2,7 +2,135 @@
2
2
  import * as _orpc_server0 from "@orpc/server";
3
3
  import * as trpc_cli0 from "trpc-cli";
4
4
  import { z } from "zod";
5
+ import { spinner } from "@clack/prompts";
6
+ import { Writable } from "node:stream";
5
7
 
8
+ //#region src/types.d.ts
9
+ declare const DatabaseProviderSchema: z.ZodPipe<z.ZodEnum<{
10
+ postgres: "postgres";
11
+ postgresql: "postgresql";
12
+ mongo: "mongo";
13
+ mongodb: "mongodb";
14
+ }>, z.ZodTransform<"postgres" | "mongo", "postgres" | "postgresql" | "mongo" | "mongodb">>;
15
+ type DatabaseProvider = z.infer<typeof DatabaseProviderSchema>;
16
+ declare const PackageManagerSchema: z.ZodEnum<{
17
+ npm: "npm";
18
+ pnpm: "pnpm";
19
+ yarn: "yarn";
20
+ bun: "bun";
21
+ deno: "deno";
22
+ }>;
23
+ type PackageManager = z.infer<typeof PackageManagerSchema>;
24
+ declare const AuthoringStyleSchema: z.ZodEnum<{
25
+ psl: "psl";
26
+ typescript: "typescript";
27
+ }>;
28
+ type AuthoringStyle = z.infer<typeof AuthoringStyleSchema>;
29
+ declare const CreateTemplateSchema: z.ZodEnum<{
30
+ minimal: "minimal";
31
+ hono: "hono";
32
+ elysia: "elysia";
33
+ nest: "nest";
34
+ next: "next";
35
+ svelte: "svelte";
36
+ astro: "astro";
37
+ nuxt: "nuxt";
38
+ "tanstack-start": "tanstack-start";
39
+ }>;
40
+ type CreateTemplate = z.infer<typeof CreateTemplateSchema>;
41
+ declare const CreateCommandInputSchema: z.ZodObject<{
42
+ yes: z.ZodOptional<z.ZodBoolean>;
43
+ verbose: z.ZodOptional<z.ZodBoolean>;
44
+ json: z.ZodOptional<z.ZodBoolean>;
45
+ provider: z.ZodOptional<z.ZodPipe<z.ZodEnum<{
46
+ postgres: "postgres";
47
+ postgresql: "postgresql";
48
+ mongo: "mongo";
49
+ mongodb: "mongodb";
50
+ }>, z.ZodTransform<"postgres" | "mongo", "postgres" | "postgresql" | "mongo" | "mongodb">>>;
51
+ authoring: z.ZodOptional<z.ZodEnum<{
52
+ psl: "psl";
53
+ typescript: "typescript";
54
+ }>>;
55
+ packageManager: z.ZodOptional<z.ZodEnum<{
56
+ npm: "npm";
57
+ pnpm: "pnpm";
58
+ yarn: "yarn";
59
+ bun: "bun";
60
+ deno: "deno";
61
+ }>>;
62
+ deploy: z.ZodOptional<z.ZodBoolean>;
63
+ workspace: z.ZodOptional<z.ZodString>;
64
+ name: z.ZodOptional<z.ZodString>;
65
+ template: z.ZodOptional<z.ZodEnum<{
66
+ minimal: "minimal";
67
+ hono: "hono";
68
+ elysia: "elysia";
69
+ nest: "nest";
70
+ next: "next";
71
+ svelte: "svelte";
72
+ astro: "astro";
73
+ nuxt: "nuxt";
74
+ "tanstack-start": "tanstack-start";
75
+ }>>;
76
+ force: z.ZodOptional<z.ZodBoolean>;
77
+ }, z.core.$strip>;
78
+ type CreateCommandInput = z.infer<typeof CreateCommandInputSchema>;
79
+ //#endregion
80
+ //#region src/tasks/deploy-with-composer.d.ts
81
+ type PrismaWorkspace = {
82
+ id: string;
83
+ name: string | null;
84
+ };
85
+ type ComposerDeployResult = {
86
+ appName: string;
87
+ appUrl?: string;
88
+ serviceId?: string;
89
+ workspace?: PrismaWorkspace;
90
+ project: {
91
+ id?: string;
92
+ name: string;
93
+ consoleUrl?: string;
94
+ };
95
+ };
96
+ //#endregion
97
+ //#region src/telemetry/create.d.ts
98
+ type CreateTelemetryFailureStage = "validate_input" | "collect_context" | "scaffold_template" | "prisma_setup" | "unknown";
99
+ //#endregion
100
+ //#region src/result.d.ts
101
+ declare const CREATE_PRISMA_RESULT_SCHEMA_VERSION: 1;
102
+ type CreateNextStep = {
103
+ command: string;
104
+ description: string;
105
+ };
106
+ type CreateProjectResult = {
107
+ name: string;
108
+ path: string;
109
+ template: CreateTemplate;
110
+ databaseProvider: DatabaseProvider;
111
+ authoring: AuthoringStyle;
112
+ packageManager: PackageManager;
113
+ };
114
+ type CreateCommandFailureStage = CreateTelemetryFailureStage | "parse_arguments";
115
+ type CreateCommandSuccessResult = {
116
+ schemaVersion: typeof CREATE_PRISMA_RESULT_SCHEMA_VERSION;
117
+ ok: true;
118
+ project: CreateProjectResult;
119
+ deployment: ComposerDeployResult | null;
120
+ nextSteps: CreateNextStep[];
121
+ warnings: string[];
122
+ };
123
+ type CreateCommandFailureResult = {
124
+ schemaVersion: typeof CREATE_PRISMA_RESULT_SCHEMA_VERSION;
125
+ ok: false;
126
+ error: {
127
+ stage: CreateCommandFailureStage;
128
+ message: string;
129
+ };
130
+ project?: CreateProjectResult;
131
+ };
132
+ type CreateCommandResult = CreateCommandSuccessResult | CreateCommandFailureResult;
133
+ //#endregion
6
134
  //#region node_modules/@orpc/client/dist/index.d.mts
7
135
  declare const COMMON_ORPC_ERROR_DEFS: {
8
136
  readonly BAD_REQUEST: {
@@ -174,78 +302,12 @@ interface ErrorMapItem<TDataSchema extends AnySchema> {
174
302
  type ErrorMap = { [key in ORPCErrorCode]?: ErrorMapItem<AnySchema> };
175
303
  type MergedErrorMap<T1 extends ErrorMap, T2 extends ErrorMap> = Omit<T1, keyof T2> & T2;
176
304
  //#endregion
177
- //#region src/types.d.ts
178
- declare const DatabaseProviderSchema: z.ZodPipe<z.ZodEnum<{
179
- postgres: "postgres";
180
- postgresql: "postgresql";
181
- mongo: "mongo";
182
- mongodb: "mongodb";
183
- }>, z.ZodTransform<"postgres" | "mongo", "postgres" | "postgresql" | "mongo" | "mongodb">>;
184
- declare const PackageManagerSchema: z.ZodEnum<{
185
- npm: "npm";
186
- pnpm: "pnpm";
187
- yarn: "yarn";
188
- bun: "bun";
189
- deno: "deno";
190
- }>;
191
- declare const AuthoringStyleSchema: z.ZodEnum<{
192
- psl: "psl";
193
- typescript: "typescript";
194
- }>;
195
- declare const CreateTemplateSchema: z.ZodEnum<{
196
- minimal: "minimal";
197
- hono: "hono";
198
- elysia: "elysia";
199
- nest: "nest";
200
- next: "next";
201
- svelte: "svelte";
202
- astro: "astro";
203
- nuxt: "nuxt";
204
- "tanstack-start": "tanstack-start";
205
- }>;
206
- declare const CreateCommandInputSchema: z.ZodObject<{
207
- yes: z.ZodOptional<z.ZodBoolean>;
208
- verbose: z.ZodOptional<z.ZodBoolean>;
209
- provider: z.ZodOptional<z.ZodPipe<z.ZodEnum<{
210
- postgres: "postgres";
211
- postgresql: "postgresql";
212
- mongo: "mongo";
213
- mongodb: "mongodb";
214
- }>, z.ZodTransform<"postgres" | "mongo", "postgres" | "postgresql" | "mongo" | "mongodb">>>;
215
- authoring: z.ZodOptional<z.ZodEnum<{
216
- psl: "psl";
217
- typescript: "typescript";
218
- }>>;
219
- packageManager: z.ZodOptional<z.ZodEnum<{
220
- npm: "npm";
221
- pnpm: "pnpm";
222
- yarn: "yarn";
223
- bun: "bun";
224
- deno: "deno";
225
- }>>;
226
- deploy: z.ZodOptional<z.ZodBoolean>;
227
- workspace: z.ZodOptional<z.ZodString>;
228
- name: z.ZodOptional<z.ZodString>;
229
- template: z.ZodOptional<z.ZodEnum<{
230
- minimal: "minimal";
231
- hono: "hono";
232
- elysia: "elysia";
233
- nest: "nest";
234
- next: "next";
235
- svelte: "svelte";
236
- astro: "astro";
237
- nuxt: "nuxt";
238
- "tanstack-start": "tanstack-start";
239
- }>>;
240
- force: z.ZodOptional<z.ZodBoolean>;
241
- }, z.core.$strip>;
242
- type CreateCommandInput = z.infer<typeof CreateCommandInputSchema>;
243
- //#endregion
244
305
  //#region src/index.d.ts
245
306
  declare const router: {
246
307
  create: _orpc_server0.Procedure<_orpc_server0.MergedInitialContext<Record<never, never>, Record<never, never>, Record<never, never>>, Record<never, never>, z.ZodTuple<[z.ZodOptional<z.ZodString>, z.ZodObject<{
247
308
  yes: z.ZodOptional<z.ZodBoolean>;
248
309
  verbose: z.ZodOptional<z.ZodBoolean>;
310
+ json: z.ZodOptional<z.ZodBoolean>;
249
311
  provider: z.ZodOptional<z.ZodPipe<z.ZodEnum<{
250
312
  postgres: "postgres";
251
313
  postgresql: "postgresql";
@@ -278,9 +340,9 @@ declare const router: {
278
340
  "tanstack-start": "tanstack-start";
279
341
  }>>;
280
342
  force: z.ZodOptional<z.ZodBoolean>;
281
- }, z.core.$strip>], null>, Schema<void, void>, MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
343
+ }, z.core.$strip>], null>, Schema<CreateCommandResult | undefined, CreateCommandResult | undefined>, MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
282
344
  };
283
345
  declare function createCreatePrismaCli(): trpc_cli0.TrpcCli;
284
346
  declare function create(input?: CreateCommandInput): Promise<void>;
285
347
  //#endregion
286
- export { AuthoringStyleSchema, type CreateCommandInput, CreateCommandInputSchema, CreateTemplateSchema, DatabaseProviderSchema, PackageManagerSchema, create, createCreatePrismaCli, router };
348
+ export { AuthoringStyleSchema, CREATE_PRISMA_RESULT_SCHEMA_VERSION, type CreateCommandFailureResult, type CreateCommandFailureStage, type CreateCommandInput, CreateCommandInputSchema, type CreateCommandResult, type CreateCommandSuccessResult, type CreateNextStep, type CreateProjectResult, CreateTemplateSchema, DatabaseProviderSchema, PackageManagerSchema, create, createCreatePrismaCli, router };
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { a as DatabaseProviderSchema, i as CreateTemplateSchema, n as AuthoringStyleSchema, o as PackageManagerSchema, r as CreateCommandInputSchema, t as runCreateCommand } from "./create-C2fGwZxV.mjs";
2
+ import { a as DatabaseProviderSchema, i as CreateTemplateSchema, n as AuthoringStyleSchema, o as PackageManagerSchema, r as CreateCommandInputSchema, s as CREATE_PRISMA_RESULT_SCHEMA_VERSION, t as runCreateCommand } from "./create-JgaDOyzC.mjs";
3
3
  import { os } from "@orpc/server";
4
4
  import { createCli } from "trpc-cli";
5
5
  import { z } from "zod";
6
6
 
7
7
  //#region src/index.ts
8
- const CLI_VERSION = "0.9.5";
8
+ const CLI_VERSION = "0.10.0-pr.72.261.1";
9
9
  const CreateCliInputSchema = z.tuple([z.string().trim().min(1, "Please enter a valid project name").optional().describe("Project name / directory"), CreateCommandInputSchema]);
10
10
  function normalizeCreateCliInput(input) {
11
11
  const [projectName, options] = input;
@@ -19,7 +19,9 @@ const router = os.router({ create: os.meta({
19
19
  default: true,
20
20
  negateBooleans: true
21
21
  }).input(CreateCliInputSchema).handler(async ({ input }) => {
22
- await runCreateCommand(normalizeCreateCliInput(input));
22
+ const createInput = normalizeCreateCliInput(input);
23
+ const result = await runCreateCommand(createInput);
24
+ return createInput.json ? result : void 0;
23
25
  }) });
24
26
  function createCreatePrismaCli() {
25
27
  return createCli({
@@ -33,4 +35,4 @@ async function create(input = {}) {
33
35
  }
34
36
 
35
37
  //#endregion
36
- export { AuthoringStyleSchema, CreateCommandInputSchema, CreateTemplateSchema, DatabaseProviderSchema, PackageManagerSchema, create, createCreatePrismaCli, router };
38
+ export { AuthoringStyleSchema, CREATE_PRISMA_RESULT_SCHEMA_VERSION, CreateCommandInputSchema, CreateTemplateSchema, DatabaseProviderSchema, PackageManagerSchema, create, createCreatePrismaCli, router };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-prisma",
3
- "version": "0.9.5",
3
+ "version": "0.10.0-pr.72.261.1",
4
4
  "private": false,
5
5
  "description": "Create Prisma 8 projects with first-party templates and great DX.",
6
6
  "homepage": "https://github.com/prisma/create-prisma",
@@ -37,7 +37,7 @@
37
37
  "dev": "tsdown --watch",
38
38
  "start": "bun run ./dist/cli.mjs",
39
39
  "test": "bun run test:unit && bun run test:e2e",
40
- "test:unit": "bun test ./tests/dependencies.test.ts ./tests/deploy-with-composer.test.ts ./tests/initialize-git.test.ts ./tests/install.test.ts ./tests/node-version.test.ts ./tests/setup-prisma.test.ts ./tests/telemetry.test.ts",
40
+ "test:unit": "bun test ./tests/dependencies.test.ts ./tests/deploy-with-composer.test.ts ./tests/initialize-git.test.ts ./tests/install.test.ts ./tests/json-output.test.ts ./tests/node-version.test.ts ./tests/setup-prisma.test.ts ./tests/telemetry.test.ts",
41
41
  "test:e2e": "bun test --timeout 180000 ./tests/e2e/create-prisma.e2e.test.ts",
42
42
  "check": "bun run format:check && bun run lint",
43
43
  "lint": "oxlint . --deny-warnings",
@@ -1,7 +1,7 @@
1
1
  {{#unless (eq packageManager "deno")}}
2
2
  import { module } from "@prisma/composer";
3
3
  {{#if (eq provider "postgres")}}
4
- import { pnPostgres } from "@prisma/composer-prisma-cloud/prisma-next";
4
+ import { postgres } from "@prisma/composer-prisma-cloud/orm";
5
5
 
6
6
  import { appContract } from "./src/prisma/composer.ts";
7
7
  {{else}}
@@ -12,7 +12,7 @@ import app from "./service.ts";
12
12
  export default module("{{projectName}}", ({ provision }) => {
13
13
  {{#if (eq provider "postgres")}}
14
14
  const database = provision(
15
- pnPostgres({
15
+ postgres({
16
16
  name: "database",
17
17
  contract: appContract,
18
18
  config: "./prisma.config.ts",
@@ -10,7 +10,7 @@ import { type } from "arktype";
10
10
  {{/if}}
11
11
  import { compute } from "@prisma/composer-prisma-cloud";
12
12
  {{#if (eq provider "postgres")}}
13
- import { pnPostgres } from "@prisma/composer-prisma-cloud/prisma-next";
13
+ import { postgres } from "@prisma/composer-prisma-cloud/orm";
14
14
 
15
15
  import { appContract } from "./src/prisma/composer.ts";
16
16
  {{/if}}
@@ -19,7 +19,7 @@ export default compute({
19
19
  name: "app",
20
20
  deps: {
21
21
  {{#if (eq provider "postgres")}}
22
- database: pnPostgres(appContract),
22
+ database: postgres(appContract),
23
23
  {{/if}}
24
24
  },
25
25
  {{#if (eq provider "mongo")}}
@@ -1,10 +1,10 @@
1
1
  {{#unless (eq packageManager "deno")}}
2
2
  {{#if (eq provider "postgres")}}
3
- import { pnContract } from "@prisma/composer-prisma-cloud/prisma-next";
3
+ import { dataContract } from "@prisma/composer-prisma-cloud/orm";
4
4
 
5
5
  import type { Contract } from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.d.ts";
6
6
  import contractJson from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.json" with { type: "json" };
7
7
 
8
- export const appContract = pnContract<Contract>(contractJson);
8
+ export const appContract = dataContract<Contract>(contractJson);
9
9
  {{/if}}
10
10
  {{/unless}}
@@ -12,6 +12,8 @@ if (!databaseUrl) {
12
12
 
13
13
  export const db = postgres<Contract>({ contractJson, url: databaseUrl });
14
14
  {{else}}
15
+ import "temporal-polyfill/global";
16
+
15
17
  import service from "../../service.ts";
16
18
  import type { Contract } from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.d.ts";
17
19
  import contractJson from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.json" with { type: "json" };