create-prisma 0.13.1 → 0.13.2-pr.111.376.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
@@ -21,8 +21,8 @@ does not include this runtime itself. MongoDB and Deno-only apps do not need it.
21
21
 
22
22
  For npm, use 11.6.0 or newer, which includes the [upstream resolver fix](https://github.com/npm/cli/pull/8448).
23
23
  Older npm releases can crash resolving the dependency tree (`Cannot read properties of null (reading 'edgesOut')`). Run
24
- `npm install --global npm@11` to update. create-prisma checks the selected npm
25
- version before writing project files and never upgrades your package manager automatically.
24
+ `npm install --global npm@11` to update. create-prisma checks the selected package manager
25
+ before writing project files and never upgrades your package manager automatically. Yarn 1 is not supported.
26
26
 
27
27
  The deployment prompt is:
28
28
 
@@ -110,4 +110,4 @@ bun run build
110
110
 
111
111
  ## Telemetry
112
112
 
113
- Published builds may send anonymous usage telemetry. It never includes project names, file paths, or database URLs. Disable it with `DO_NOT_TRACK`, `CREATE_PRISMA_DISABLE_TELEMETRY`, or `CREATE_PRISMA_TELEMETRY_DISABLED`.
113
+ Published builds may send anonymous usage telemetry. It never includes project names, file paths, or database URLs. Failure events carry only stable identifiers such as exit codes and tool error codes, never messages or command output. Disable it with `DO_NOT_TRACK`, `CREATE_PRISMA_DISABLE_TELEMETRY`, or `CREATE_PRISMA_TELEMETRY_DISABLED`.
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as ApplicationLayer } from "./json-output-CPdx9Prn.mjs";
2
+ import { a as ApplicationLayer } from "./json-output-wzlPfgC6.mjs";
3
3
  import { runCreatePrismaCli } from "./index.mjs";
4
4
  import { Effect } from "effect";
5
5
  import { NodeRuntime } from "@effect/platform-node-shared";
package/dist/index.d.mts CHANGED
@@ -68,7 +68,7 @@ type CreateCommandInput = typeof CreateCommandInputSchema.Type;
68
68
  //#region src/create-outcome.d.ts
69
69
  declare const CreateFailureStageSchema: Schema.Literals<readonly ["validate_input", "collect_context", "scaffold_template", "initialize_prisma", "configure_project", "install_dependencies", "initialize_agent_skills", "emit_contract", "plan_migration", "initialize_git", "authenticate", "select_workspace", "check_project_name", "build", "composer_deploy", "unknown"]>;
70
70
  type CreateFailureStage = typeof CreateFailureStageSchema.Type;
71
- declare const CreateCancellationStageSchema: Schema.Literals<readonly ["project_name", "template", "database_provider", "authoring_style", "package_manager", "agent_skills", "deployment_intent", "select_workspace"]>;
71
+ declare const CreateCancellationStageSchema: Schema.Literals<readonly ["project_name", "template", "database_provider", "authoring_style", "package_manager", "agent_skills", "deployment_intent", "authenticate", "select_workspace"]>;
72
72
  type CreateCancellationStage = typeof CreateCancellationStageSchema.Type;
73
73
  //#endregion
74
74
  //#region src/result.d.ts
@@ -124,7 +124,7 @@ declare const CreateCommandFailureResultSchema: Schema.Struct<{
124
124
  readonly schemaVersion: Schema.Literal<1>;
125
125
  readonly ok: Schema.Literal<false>;
126
126
  readonly error: Schema.Struct<{
127
- readonly stage: Schema.Union<readonly [Schema.Literals<readonly ["validate_input", "collect_context", "scaffold_template", "initialize_prisma", "configure_project", "install_dependencies", "initialize_agent_skills", "emit_contract", "plan_migration", "initialize_git", "authenticate", "select_workspace", "check_project_name", "build", "composer_deploy", "unknown"]>, Schema.Literals<readonly ["project_name", "template", "database_provider", "authoring_style", "package_manager", "agent_skills", "deployment_intent", "select_workspace"]>, Schema.Literal<"parse_arguments">]>;
127
+ readonly stage: Schema.Union<readonly [Schema.Literals<readonly ["validate_input", "collect_context", "scaffold_template", "initialize_prisma", "configure_project", "install_dependencies", "initialize_agent_skills", "emit_contract", "plan_migration", "initialize_git", "authenticate", "select_workspace", "check_project_name", "build", "composer_deploy", "unknown"]>, Schema.Literals<readonly ["project_name", "template", "database_provider", "authoring_style", "package_manager", "agent_skills", "deployment_intent", "authenticate", "select_workspace"]>, Schema.Literal<"parse_arguments">]>;
128
128
  readonly message: Schema.String;
129
129
  }>;
130
130
  readonly project: Schema.optionalKey<Schema.Struct<{
@@ -171,7 +171,7 @@ declare const CreateCommandResultSchema: Schema.Union<readonly [Schema.Struct<{
171
171
  readonly schemaVersion: Schema.Literal<1>;
172
172
  readonly ok: Schema.Literal<false>;
173
173
  readonly error: Schema.Struct<{
174
- readonly stage: Schema.Union<readonly [Schema.Literals<readonly ["validate_input", "collect_context", "scaffold_template", "initialize_prisma", "configure_project", "install_dependencies", "initialize_agent_skills", "emit_contract", "plan_migration", "initialize_git", "authenticate", "select_workspace", "check_project_name", "build", "composer_deploy", "unknown"]>, Schema.Literals<readonly ["project_name", "template", "database_provider", "authoring_style", "package_manager", "agent_skills", "deployment_intent", "select_workspace"]>, Schema.Literal<"parse_arguments">]>;
174
+ readonly stage: Schema.Union<readonly [Schema.Literals<readonly ["validate_input", "collect_context", "scaffold_template", "initialize_prisma", "configure_project", "install_dependencies", "initialize_agent_skills", "emit_contract", "plan_migration", "initialize_git", "authenticate", "select_workspace", "check_project_name", "build", "composer_deploy", "unknown"]>, Schema.Literals<readonly ["project_name", "template", "database_provider", "authoring_style", "package_manager", "agent_skills", "deployment_intent", "authenticate", "select_workspace"]>, Schema.Literal<"parse_arguments">]>;
175
175
  readonly message: Schema.String;
176
176
  }>;
177
177
  readonly project: Schema.optionalKey<Schema.Struct<{
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { _ as authoringStyles, b as normalizeDatabaseProvider, c as CreateCommandResultSchema, d as AuthoringStyleSchema, f as CreateCommandInputSchema, g as agentSkillTargets, h as PackageManagerSchema, i as getErrorMessage, l as createCommandFailureResult, m as DatabaseProviderSchema, n as writeJsonResult, o as applicationRuntime, p as CreateTemplateSchema, r as runCreateCommandEffect, s as CREATE_PRISMA_RESULT_SCHEMA_VERSION, t as isJsonOutputRequested, u as AgentSkillTargetSchema, v as createTemplates, x as packageManagers, y as databaseProviderInputs } from "./json-output-CPdx9Prn.mjs";
2
+ import { _ as authoringStyles, b as normalizeDatabaseProvider, c as CreateCommandResultSchema, d as AuthoringStyleSchema, f as CreateCommandInputSchema, g as agentSkillTargets, h as PackageManagerSchema, i as getErrorMessage, l as createCommandFailureResult, m as DatabaseProviderSchema, n as writeJsonResult, o as applicationRuntime, p as CreateTemplateSchema, r as runCreateCommandEffect, s as CREATE_PRISMA_RESULT_SCHEMA_VERSION, t as isJsonOutputRequested, u as AgentSkillTargetSchema, v as createTemplates, x as packageManagers, y as databaseProviderInputs } from "./json-output-wzlPfgC6.mjs";
3
3
  import { Console, Effect, Option } from "effect";
4
4
  import { Argument, CliError, Command, Flag } from "effect/unstable/cli";
5
5
 
6
6
  //#region src/index.ts
7
- const CLI_VERSION = "0.13.1";
7
+ const CLI_VERSION = "0.13.2-pr.111.376.1";
8
8
  const optionalArgument = (name, description) => Argument.string(name).pipe(Argument.withDescription(description), Argument.optional, Argument.map(Option.getOrUndefined));
9
9
  const optionalBoolean = (name, description) => Flag.boolean(name).pipe(Flag.withDescription(description), Flag.optional, Flag.map(Option.getOrUndefined));
10
10
  const optionalString = (name, description) => Flag.string(name).pipe(Flag.withDescription(description), Flag.optional, Flag.map(Option.getOrUndefined));
@@ -1,17 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import { Cause, Clock, Context, Effect, Exit, FileSystem, Layer, ManagedRuntime, Option, Ref, Result, Schema, SchemaTransformation } from "effect";
3
3
  import { cancel, confirm, intro, isCancel, log, note, outro, select, spinner, taskLog, text } from "@clack/prompts";
4
+ import { statSync } from "node:fs";
5
+ import path from "node:path";
4
6
  import { NodeChildProcessSpawner, NodeFileSystem, NodePath, NodeStdio, NodeTerminal } from "@effect/platform-node-shared";
5
7
  import { execa } from "execa";
6
8
  import { createInterface } from "node:readline";
9
+ import { stripVTControlCharacters, styleText } from "node:util";
7
10
  import { randomUUID } from "node:crypto";
8
11
  import os from "node:os";
9
- import path from "node:path";
10
12
  import { PostHog } from "posthog-node";
11
13
  import Handlebars from "handlebars";
12
14
  import { fileURLToPath } from "node:url";
13
15
  import { Writable } from "node:stream";
14
- import { styleText } from "node:util";
15
16
 
16
17
  //#region src/utils/child-process-failure.ts
17
18
  const ChildProcessFailureSchema = Schema.Literals([
@@ -41,6 +42,27 @@ function getChildProcessFailure(error) {
41
42
  if (typeof exitCode === "number") return "non_zero_exit";
42
43
  return "spawn_failed";
43
44
  }
45
+ function isFile(filePath) {
46
+ try {
47
+ return statSync(filePath, { throwIfNoEntry: false })?.isFile() === true;
48
+ } catch {
49
+ return false;
50
+ }
51
+ }
52
+ function isCommandOnWindowsPath({ command, cwd, env }) {
53
+ const environment = {
54
+ ...process.env,
55
+ ...env
56
+ };
57
+ const pathKey = Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH");
58
+ const directories = /[\\/]/.test(command) ? [""] : [cwd, ...(pathKey ? environment[pathKey] ?? "" : "").split(";")];
59
+ const extensions = ["", ...(environment.PATHEXT || ".EXE;.CMD;.BAT;.COM").split(";")];
60
+ return directories.some((directory) => extensions.some((extension) => isFile(path.resolve(cwd, directory.replace(/^"(.*)"$/, "$1"), command + extension))));
61
+ }
62
+ function getSpawnedCommandFailure(error, spawned) {
63
+ const failure = getChildProcessFailure(error);
64
+ return failure === "non_zero_exit" && (spawned.platform ?? process.platform) === "win32" && !isCommandOnWindowsPath(spawned) ? "command_not_found" : failure;
65
+ }
44
66
 
45
67
  //#endregion
46
68
  //#region src/create-outcome.ts
@@ -66,6 +88,8 @@ const CreateFailureReasonSchema = Schema.Literals([
66
88
  "invalid_input",
67
89
  "unsupported_node_version",
68
90
  "unsupported_package_manager_version",
91
+ "package_manager_not_found",
92
+ "package_manager_check_failed",
69
93
  "invalid_project_name",
70
94
  "target_path_not_directory",
71
95
  "target_directory_not_empty",
@@ -99,6 +123,7 @@ const CreateCancellationStageSchema = Schema.Literals([
99
123
  "package_manager",
100
124
  "agent_skills",
101
125
  "deployment_intent",
126
+ "authenticate",
102
127
  "select_workspace"
103
128
  ]);
104
129
  var CreateCancellationError = class extends Schema.TaggedError()("CreateCancellationError", {
@@ -119,16 +144,22 @@ var CreateFailure = class extends Schema.TaggedError()("CreateFailure", {
119
144
  cause: Schema.optionalKey(Schema.Defect()),
120
145
  errorReported: Schema.optionalKey(Schema.Boolean)
121
146
  }) {};
147
+ const STRUCTURED_ERROR_CODE_PATTERN = /^[A-Z][A-Z0-9_]*(\.[A-Z0-9_]+)+$/;
148
+ function isStructuredErrorCode(value) {
149
+ return typeof value === "string" && STRUCTURED_ERROR_CODE_PATTERN.test(value);
150
+ }
122
151
  var PrismaCliCommandError = class extends Schema.TaggedError()("PrismaCliCommandError", {
123
152
  message: Schema.String,
124
153
  command: Schema.optionalKey(Schema.String),
125
154
  code: Schema.optionalKey(Schema.String),
155
+ causeCode: Schema.optionalKey(Schema.String),
126
156
  stderr: Schema.optionalKey(Schema.String),
127
157
  exitCode: Schema.optionalKey(Schema.Number),
128
158
  childProcessFailure: Schema.optional(ChildProcessFailureSchema)
129
159
  }) {
130
160
  prismaCliCommand = this.command;
131
161
  prismaCliErrorCode = this.code;
162
+ prismaCliCauseCode = this.causeCode;
132
163
  };
133
164
 
134
165
  //#endregion
@@ -353,7 +384,7 @@ var CommandRunner = class CommandRunner extends Context.Service()("create-prisma
353
384
  exitCode: result.exitCode ?? 1,
354
385
  stdout: typeof result.stdout === "string" ? result.stdout : "",
355
386
  stderr: typeof result.stderr === "string" ? result.stderr : "",
356
- childProcessFailure: getChildProcessFailure(result)
387
+ childProcessFailure: getSpawnedCommandFailure(result, spec)
357
388
  };
358
389
  },
359
390
  catch: (cause) => new CommandExecutionError({
@@ -386,22 +417,47 @@ const NodeCliLayer = Layer.provideMerge(NodeChildProcessSpawner.layer, Layer.mer
386
417
  const ApplicationLayer = Layer.merge(NodeCliLayer, CommandRunner.layer);
387
418
  const applicationRuntime = ManagedRuntime.make(ApplicationLayer);
388
419
 
420
+ //#endregion
421
+ //#region src/utils/package-manager-error-code.ts
422
+ const grammars = {
423
+ npm: {
424
+ line: /^npm (?:error|ERR!) code (\S+)$/,
425
+ allow: /^E[A-Z0-9_]{2,40}$/
426
+ },
427
+ pnpm: {
428
+ line: /^(?:\[([A-Z0-9_]+)\] |\u2009([A-Z0-9_]+)\u2009 )/,
429
+ allow: /^(?:ERR_PNPM_[A-Z0-9_]{1,60}|E[A-Z0-9_]{2,40})$/
430
+ },
431
+ yarn: {
432
+ line: /^(?:➤ )?(YN\d{4}): /,
433
+ allow: /^YN(?!0000)\d{4}$/
434
+ }
435
+ };
436
+ function getGrammar(command) {
437
+ const name = command.replace(/^.*[\\/]/, "").replace(/\.(?:cmd|exe)$/i, "").toLowerCase();
438
+ return Object.hasOwn(grammars, name) ? grammars[name] : void 0;
439
+ }
440
+ function getPackageManagerErrorCode(command, output) {
441
+ const grammar = getGrammar(command);
442
+ if (!grammar) return void 0;
443
+ const lines = stripVTControlCharacters(`${output.stdout}\n${output.stderr}`).split(/\r?\n/);
444
+ for (const line of lines.reverse()) {
445
+ const match = grammar.line.exec(line);
446
+ const candidate = match?.[1] ?? match?.[2];
447
+ if (candidate !== void 0 && grammar.allow.test(candidate)) return candidate;
448
+ }
449
+ }
450
+
389
451
  //#endregion
390
452
  //#region src/telemetry/client.ts
391
- const TELEMETRY_API_KEY = "phc_cmc85avbWyuJ2JyKdGPdv7dxXli8xLdWDBPbvIXWJfs";
453
+ const TELEMETRY_API_KEY = "";
392
454
  const TELEMETRY_HOST = "https://us.i.posthog.com";
393
455
  const TELEMETRY_CONFIG_FILE = "telemetry.json";
394
456
  const TELEMETRY_TIMEOUT_MS = 2e3;
395
457
  const AnonymousId = Schema.String.check(Schema.isUUID(4));
396
458
  const decodeAnonymousId = Schema.decodeUnknownExit(AnonymousId);
397
- const isTruthyEnvValue = (value) => [
398
- "1",
399
- "true",
400
- "yes",
401
- "on"
402
- ].includes(String(value ?? "").trim().toLowerCase());
403
459
  function shouldDisableTelemetry() {
404
- return isTruthyEnvValue(process.env.CI) || isTruthyEnvValue(process.env.GITHUB_ACTIONS) || process.env.CREATE_PRISMA_DISABLE_TELEMETRY !== void 0 || process.env.CREATE_PRISMA_TELEMETRY_DISABLED !== void 0 || process.env.DO_NOT_TRACK !== void 0;
460
+ return true;
405
461
  }
406
462
  function getTelemetryConfigDir() {
407
463
  if (process.platform === "darwin") return path.join(os.homedir(), "Library", "Application Support", "create-prisma");
@@ -424,7 +480,7 @@ const getAnonymousIdEffect = Effect.fn("Telemetry.getAnonymousId")(function* ()
424
480
  return anonymousId;
425
481
  });
426
482
  const getCommonProperties = () => ({
427
- "cli-version": "0.13.1",
483
+ "cli-version": "0.13.2-pr.111.376.1",
428
484
  "node-version": process.version,
429
485
  platform: process.platform,
430
486
  arch: process.arch
@@ -464,6 +520,7 @@ const expectedRejectionReasons = new Set([
464
520
  "invalid_input",
465
521
  "unsupported_node_version",
466
522
  "unsupported_package_manager_version",
523
+ "package_manager_not_found",
467
524
  "invalid_project_name",
468
525
  "target_path_not_directory",
469
526
  "target_directory_not_empty",
@@ -513,11 +570,18 @@ function getErrorCode(error) {
513
570
  function getChildProcessFailureProperty(error) {
514
571
  return error instanceof CommandExecutionError || error instanceof PrismaCliCommandError ? error.childProcessFailure ?? null : null;
515
572
  }
573
+ function getPackageManagerErrorCodeProperty(error) {
574
+ return error instanceof CommandExecutionError ? getPackageManagerErrorCode(error.command, error) ?? null : null;
575
+ }
516
576
  function getPrismaCliFailureProperty(error, property) {
517
577
  if (typeof error !== "object" || error === null) return null;
518
578
  const value = Reflect.get(error, property);
519
579
  return typeof value === "string" && value.length > 0 ? value : null;
520
580
  }
581
+ function getPrismaCliCauseCodeProperty(error) {
582
+ const causeCode = getPrismaCliFailureProperty(error, "prismaCliCauseCode");
583
+ return isStructuredErrorCode(causeCode) ? causeCode : null;
584
+ }
521
585
  const trackCreateCompletedEffect = Effect.fn("Telemetry.createCompleted")(function* (params) {
522
586
  yield* trackCliTelemetryEffect(CREATE_PRISMA_NEXT_COMPLETED_EVENT, {
523
587
  ...getBaseCreateProperties(params.input, params.context),
@@ -535,7 +599,9 @@ const trackCreateFailedEffect = Effect.fn("Telemetry.createFailed")(function* (p
535
599
  "error-code": getErrorCode(params.error),
536
600
  "child-process-failure": getChildProcessFailureProperty(params.error),
537
601
  "prisma-cli-command": getPrismaCliFailureProperty(params.error, "prismaCliCommand"),
538
- "prisma-cli-error-code": getPrismaCliFailureProperty(params.error, "prismaCliErrorCode")
602
+ "prisma-cli-error-code": getPrismaCliFailureProperty(params.error, "prismaCliErrorCode"),
603
+ "prisma-cli-cause-code": getPrismaCliCauseCodeProperty(params.error),
604
+ "package-manager-error-code": params.stage === "install_dependencies" ? getPackageManagerErrorCodeProperty(params.error) : null
539
605
  }).pipe(Effect.scoped, Effect.timeout(TELEMETRY_TIMEOUT_MS), Effect.catch(() => Effect.void));
540
606
  });
541
607
  const trackCreateCancelledEffect = Effect.fn("Telemetry.createCancelled")(function* (params) {
@@ -626,6 +692,20 @@ function getCreateTemplateDependencies(template, packageManager) {
626
692
  return targets;
627
693
  }
628
694
 
695
+ //#endregion
696
+ //#region src/utils/errors.ts
697
+ function redactSecrets(message) {
698
+ 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>");
699
+ }
700
+ function getErrorMessage(error) {
701
+ if (error instanceof PrismaCliCommandError) return redactSecrets(error.message);
702
+ if (error instanceof Error && "stderr" in error) {
703
+ const stderr = String(error.stderr ?? "").trim();
704
+ if (stderr) return redactSecrets(stderr);
705
+ }
706
+ return redactSecrets(error instanceof Error ? error.message : String(error));
707
+ }
708
+
629
709
  //#endregion
630
710
  //#region src/utils/package-manager.ts
631
711
  const DENO_ALLOW_FRESH_DEPENDENCIES = "--minimum-dependency-age=0";
@@ -635,22 +715,108 @@ const packageManagerManifestValues = {
635
715
  yarn: "yarn@4.13.0",
636
716
  bun: "bun@1.4.1"
637
717
  };
638
- const verifyPackageManagerEffect = Effect.fn("PackageManager.verify")(function* (packageManager) {
639
- if (packageManager !== "npm") return;
640
- const version = (yield* (yield* CommandRunner).runChecked({
641
- command: "npm",
642
- args: ["--version"],
643
- cwd: process.cwd()
644
- })).stdout.trim();
645
- const parts = version.split(".").map(Number);
646
- if (!/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.test(version) || parts.some((part) => !Number.isInteger(part))) return yield* Effect.fail(/* @__PURE__ */ new Error(`Could not determine the installed npm version: ${version}`));
647
- const [major, minor] = parts;
648
- if (major < 11 || major === 11 && minor < 6) return yield* new CreateFailure({
718
+ const packageManagerChecks = {
719
+ npm: {
720
+ name: "npm",
721
+ versionArgs: ["--version"],
722
+ install: "Install Node.js from https://nodejs.org to get npm",
723
+ minimum: {
724
+ version: [
725
+ 11,
726
+ 6,
727
+ 0
728
+ ],
729
+ guidance: "Older npm releases can crash while resolving Prisma dependencies. Run npm install --global npm@11, then retry create-prisma."
730
+ }
731
+ },
732
+ pnpm: {
733
+ name: "pnpm",
734
+ versionArgs: ["--version"],
735
+ install: "Install it from https://pnpm.io/installation"
736
+ },
737
+ yarn: {
738
+ name: "Yarn",
739
+ versionArgs: ["--version"],
740
+ install: "Install it with Corepack (https://yarnpkg.com/corepack)",
741
+ minimum: {
742
+ version: [
743
+ 2,
744
+ 0,
745
+ 0
746
+ ],
747
+ guidance: `Generated projects use ${packageManagerManifestValues.yarn}, which Yarn 1 refuses to install. Enable Corepack (https://yarnpkg.com/corepack) or install Yarn 4, then retry create-prisma, or choose another package manager with --package-manager.`
748
+ }
749
+ },
750
+ bun: {
751
+ name: "Bun",
752
+ versionArgs: ["--version"],
753
+ install: "Install it from https://bun.sh"
754
+ },
755
+ deno: {
756
+ name: "Deno",
757
+ versionArgs: ["-V"],
758
+ install: "Install it from https://docs.deno.com/runtime/getting_started/installation"
759
+ }
760
+ };
761
+ const PACKAGE_MANAGER_VERSION_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
762
+ function parsePackageManagerVersion(packageManager, version) {
763
+ const prefix = `${packageManager} `;
764
+ const match = PACKAGE_MANAGER_VERSION_PATTERN.exec(version.startsWith(prefix) ? version.slice(prefix.length) : version);
765
+ if (!match) return void 0;
766
+ const parts = [
767
+ Number(match[1]),
768
+ Number(match[2]),
769
+ Number(match[3])
770
+ ];
771
+ return parts.every(Number.isSafeInteger) ? parts : void 0;
772
+ }
773
+ function isOlderVersion(version, minimum) {
774
+ for (const [index, part] of version.entries()) if (part !== minimum[index]) return part < minimum[index];
775
+ return false;
776
+ }
777
+ const probePackageManagerEffect = Effect.fn("PackageManager.probe")(function* (packageManager, cwd) {
778
+ const runner = yield* CommandRunner;
779
+ const { name, versionArgs, install, minimum } = packageManagerChecks[packageManager];
780
+ const output = (yield* runner.runChecked({
781
+ command: packageManager,
782
+ args: versionArgs,
783
+ cwd
784
+ }).pipe(Effect.mapError((cause) => cause.childProcessFailure === "command_not_found" ? new CreateFailure({
785
+ stage: "validate_input",
786
+ reason: "package_manager_not_found",
787
+ message: `${name} is not installed or is not on your PATH. ${install}, then retry create-prisma, or choose another package manager with --package-manager.`,
788
+ cause
789
+ }) : new CreateFailure({
790
+ stage: "validate_input",
791
+ reason: "package_manager_check_failed",
792
+ message: `Could not run ${[packageManager, ...versionArgs].join(" ")}: ${getErrorMessage(cause)}`,
793
+ cause
794
+ })))).stdout.trim();
795
+ const version = parsePackageManagerVersion(packageManager, output);
796
+ if (!version) return yield* new CreateFailure({
797
+ stage: "validate_input",
798
+ reason: "package_manager_check_failed",
799
+ message: `Could not determine the installed ${name} version: ${output}`
800
+ });
801
+ if (minimum && isOlderVersion(version, minimum.version)) return yield* new CreateFailure({
649
802
  stage: "validate_input",
650
803
  reason: "unsupported_package_manager_version",
651
- message: `npm ${version} is unsupported. Required: npm 11.6.0 or newer. Older npm releases can crash while resolving Prisma dependencies. Run npm install --global npm@11, then retry create-prisma.`
804
+ message: `${name} ${version.join(".")} is unsupported. Required: ${name} ${minimum.version.join(".")} or newer. ${minimum.guidance}`
652
805
  });
653
806
  });
807
+ const verifyPackageManagerEffect = Effect.fn("PackageManager.verify")(function* (packageManager) {
808
+ const fs = yield* FileSystem.FileSystem;
809
+ yield* probePackageManagerEffect(packageManager, yield* fs.makeTempDirectoryScoped({ prefix: "create-prisma-" }).pipe(Effect.tap((directory) => fs.writeFileString(path.join(directory, "package.json"), JSON.stringify({
810
+ name: "create-prisma-probe",
811
+ private: true,
812
+ packageManager: getPackageManagerManifestValue(packageManager)
813
+ }))), Effect.mapError((cause) => new CreateFailure({
814
+ stage: "validate_input",
815
+ reason: "package_manager_check_failed",
816
+ message: `Could not prepare a directory to check ${packageManagerChecks[packageManager].name}: ${getErrorMessage(cause)}`,
817
+ cause
818
+ }))));
819
+ }, Effect.scoped);
654
820
  function parseUserAgent(userAgent) {
655
821
  if (userAgent?.startsWith("pnpm")) return "pnpm";
656
822
  if (userAgent?.startsWith("yarn")) return "yarn";
@@ -1127,20 +1293,6 @@ const installProjectDependenciesEffect = Effect.fn("Dependencies.install")(funct
1127
1293
  });
1128
1294
  });
1129
1295
 
1130
- //#endregion
1131
- //#region src/utils/errors.ts
1132
- function redactSecrets(message) {
1133
- 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>");
1134
- }
1135
- function getErrorMessage(error) {
1136
- if (error instanceof PrismaCliCommandError) return redactSecrets(error.message);
1137
- if (error instanceof Error && "stderr" in error) {
1138
- const stderr = String(error.stderr ?? "").trim();
1139
- if (stderr) return redactSecrets(stderr);
1140
- }
1141
- return redactSecrets(error instanceof Error ? error.message : String(error));
1142
- }
1143
-
1144
1296
  //#endregion
1145
1297
  //#region src/workflow/failure.ts
1146
1298
  const atCreateStage = (effect, stage, reason) => effect.pipe(Effect.mapError((error) => error instanceof CreateFailure || error instanceof CreateCancellationError ? error : new CreateFailure({
@@ -1256,7 +1408,7 @@ const ensureAuthentication = Effect.fn("Deployment.ensureAuthentication")(functi
1256
1408
  cwd: options.projectDir,
1257
1409
  env: process.env,
1258
1410
  stdio: "inherit"
1259
- });
1411
+ }).pipe(Effect.mapError((error) => error.childProcessFailure === "interrupted" || error.childProcessFailure === "cancelled" ? new CreateCancellationError({ stage: "authenticate" }) : error));
1260
1412
  const authenticatedState = yield* whoami();
1261
1413
  if (!authenticatedState.authenticated) return yield* new CreateFailure({
1262
1414
  stage: "authenticate",
@@ -1321,10 +1473,7 @@ const selectDeploymentWorkspace = Effect.fn("Deployment.selectWorkspace")(functi
1321
1473
  })),
1322
1474
  output: options.output
1323
1475
  }));
1324
- if (isCancel(selectedWorkspaceId)) {
1325
- yield* Effect.sync(() => cancel("Operation cancelled.", { output: options.output }));
1326
- return yield* new CreateCancellationError({ stage: "select_workspace" });
1327
- }
1476
+ if (isCancel(selectedWorkspaceId)) return yield* new CreateCancellationError({ stage: "select_workspace" });
1328
1477
  yield* Effect.sync(() => options.afterPrompt?.());
1329
1478
  if (selectedWorkspaceId === activeWorkspace.id) return activeWorkspace;
1330
1479
  return yield* useWorkspace({
@@ -1354,6 +1503,49 @@ function parseComposerDeployResult(result) {
1354
1503
  };
1355
1504
  }
1356
1505
 
1506
+ //#endregion
1507
+ //#region src/tasks/composer/deploy-report.ts
1508
+ const ComposerRunReportSchema = Schema.fromJsonString(Schema.Struct({
1509
+ version: Schema.Literal(1),
1510
+ failure: Schema.NullOr(Schema.Struct({ code: Schema.String }))
1511
+ }));
1512
+ const decodeComposerRunReport = Schema.decodeUnknownOption(ComposerRunReportSchema);
1513
+ function parseComposerDeployFailureCode(report) {
1514
+ const code = Option.getOrUndefined(decodeComposerRunReport(report))?.failure?.code;
1515
+ return isStructuredErrorCode(code) ? code : void 0;
1516
+ }
1517
+ function withCauseCode(error, causeCode) {
1518
+ return new PrismaCliCommandError({
1519
+ message: error.message,
1520
+ ...error.command === void 0 ? {} : { command: error.command },
1521
+ ...error.code === void 0 ? {} : { code: error.code },
1522
+ causeCode,
1523
+ ...error.stderr === void 0 ? {} : { stderr: error.stderr },
1524
+ ...error.exitCode === void 0 ? {} : { exitCode: error.exitCode },
1525
+ childProcessFailure: error.childProcessFailure
1526
+ });
1527
+ }
1528
+ const readComposerDeployFailureCode = Effect.fn("Deployment.readFailureCode")(function* (reportPath) {
1529
+ const report = yield* (yield* FileSystem.FileSystem).readFileString(reportPath).pipe(Effect.option);
1530
+ return Option.isSome(report) ? parseComposerDeployFailureCode(report.value) : void 0;
1531
+ });
1532
+ const runComposerDeployEffect = Effect.fn("Deployment.runComposerDeploy")(function* (options) {
1533
+ const reportPath = yield* (yield* FileSystem.FileSystem).makeTempDirectoryScoped({ prefix: "create-prisma-deploy-" }).pipe(Effect.map((directory) => path.join(directory, "report.json")), Effect.option, Effect.map(Option.getOrUndefined));
1534
+ return yield* runPrismaJsonCommandEffect({
1535
+ packageManager: options.packageManager,
1536
+ projectDir: options.projectDir,
1537
+ args: [
1538
+ "deploy",
1539
+ "module.ts",
1540
+ ...reportPath ? ["--report", reportPath] : []
1541
+ ],
1542
+ ...options.onStderrLine ? { onStderrLine: options.onStderrLine } : {}
1543
+ }).pipe(Effect.catchTag("PrismaCliCommandError", (error) => Effect.gen(function* () {
1544
+ const causeCode = reportPath ? yield* readComposerDeployFailureCode(reportPath) : void 0;
1545
+ return yield* Effect.fail(causeCode ? withCauseCode(error, causeCode) : error);
1546
+ })));
1547
+ }, Effect.scoped);
1548
+
1357
1549
  //#endregion
1358
1550
  //#region src/tasks/composer/projects.ts
1359
1551
  const ProjectShowResultSchema = Schema.Struct({
@@ -1493,10 +1685,9 @@ const deployNewProjectWithComposerEffect = Effect.fn("Deployment.deploy")(functi
1493
1685
  deploymentLog.message(`$ ${deployCommand}`);
1494
1686
  }
1495
1687
  });
1496
- const deployment = parseComposerDeployResult(yield* atCreateStage(decodePrismaCommandResult(ComposerDeployCommandResultSchema, yield* atCreateStage(runPrismaJsonCommandEffect({
1688
+ const deployment = parseComposerDeployResult(yield* atCreateStage(decodePrismaCommandResult(ComposerDeployCommandResultSchema, yield* atCreateStage(runComposerDeployEffect({
1497
1689
  packageManager: options.packageManager,
1498
1690
  projectDir: options.projectDir,
1499
- args: ["deploy", "module.ts"],
1500
1691
  onStderrLine: (line) => {
1501
1692
  const redacted = redactSecrets(line);
1502
1693
  if (options.verbose) output.write(`${redacted}\n`);
@@ -1528,12 +1719,17 @@ const deployNewProjectWithComposerEffect = Effect.fn("Deployment.deploy")(functi
1528
1719
  };
1529
1720
  }).pipe(Effect.tapCause((cause) => Effect.sync(() => {
1530
1721
  const error = Cause.squash(cause);
1722
+ if (error instanceof CreateCancellationError) {
1723
+ clearProgress();
1724
+ cancel(error.message ?? "Operation cancelled.", { output });
1725
+ return;
1726
+ }
1531
1727
  if (deploymentLog) {
1532
1728
  deploymentLog.error("Deployment failed.");
1533
1729
  deploymentLog = void 0;
1534
1730
  } else progress?.error("Deployment failed.");
1535
1731
  progressRunning = false;
1536
- if (!(error instanceof CreateCancellationError)) log.error(`Deploy failed: ${getErrorMessage(error)}`, { output });
1732
+ log.error(`Deploy failed: ${getErrorMessage(error)}`, { output });
1537
1733
  })), Effect.mapError((error) => error instanceof CreateFailure ? new CreateFailure({
1538
1734
  stage: error.stage,
1539
1735
  reason: error.reason,
@@ -2285,7 +2481,7 @@ const createProjectEffect = Effect.fn("Create.project")(function* (rawInput, inp
2285
2481
  yield* Effect.sync(() => intro(getCreatePrismaIntro(), { output }));
2286
2482
  const context = yield* atCreateStage(collectCreateContext(input), "collect_context", "unexpected_error");
2287
2483
  yield* Ref.set(contextRef, Option.some(context));
2288
- yield* atCreateStage(verifyPackageManagerEffect(context.prismaSetupContext.packageManager), "install_dependencies", "dependency_install_failed");
2484
+ yield* atCreateStage(verifyPackageManagerEffect(context.prismaSetupContext.packageManager), "validate_input", "package_manager_check_failed");
2289
2485
  return {
2290
2486
  input,
2291
2487
  context,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-prisma",
3
- "version": "0.13.1",
3
+ "version": "0.13.2-pr.111.376.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/json-output.test.ts ./tests/node-version.test.ts ./tests/setup-prisma.test.ts ./tests/telemetry-client.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/package-manager-error-code.test.ts ./tests/setup-prisma.test.ts ./tests/telemetry-client.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",