create-prisma 0.12.0 → 0.12.1-pr.79.344.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
@@ -15,6 +15,11 @@ bunx create-prisma@latest my-app
15
15
 
16
16
  The CLI initializes Prisma 8 with `prisma@latest`, installs dependencies, emits the contract, and generates a deployable Composer app. PostgreSQL projects use Composer's native Prisma Postgres provider, including migrations and a typed runtime client.
17
17
 
18
+ For npm, use 11.6.0 or newer, which includes the [upstream resolver fix](https://github.com/npm/cli/pull/8448).
19
+ Older npm releases can crash resolving the dependency tree (`Cannot read properties of null (reading 'edgesOut')`). Run
20
+ `npm install --global npm@11` to update. create-prisma checks the selected npm
21
+ version before writing project files and never upgrades your package manager automatically.
22
+
18
23
  The deployment prompt is:
19
24
 
20
25
  ```text
@@ -23,6 +28,11 @@ Deploy to Prisma now?
23
28
 
24
29
  Choose no to deploy later with the generated `deploy` script.
25
30
 
31
+ New apps explicitly use `us-east-1` in `prisma-composer.config.ts`. Change the
32
+ `prismaCloud({ region })` option before deploying if you need another region.
33
+ Composer requires a region when creating a new project; leaving it unspecified
34
+ only works when deploying into an existing project whose region can be inherited.
35
+
26
36
  When multiple Prisma workspace sessions are available, the CLI asks which workspace should receive
27
37
  the deployment. For unattended usage, pass `--workspace <id-or-name>` or omit it to use the active
28
38
  workspace. Choosing another workspace also updates the Prisma CLI's active workspace session.
@@ -34,6 +44,7 @@ workspace. Choosing another workspace also updates the Prisma CLI's active works
34
44
  - `elysia`
35
45
  - `nest`
36
46
  - `next`
47
+ - `turborepo` (Next.js in `apps/web`, shared Prisma package in `packages/database`)
37
48
  - `svelte` (SvelteKit)
38
49
  - `astro`
39
50
  - `nuxt`
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as ApplicationLayer } from "./json-output-CH9M3gTl.mjs";
2
+ import { a as ApplicationLayer } from "./json-output--NEJN266.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
@@ -42,10 +42,10 @@ declare const DatabaseProviderSchema: Schema.Literals<readonly ["postgres", "mon
42
42
  declare const PackageManagerSchema: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
43
43
  declare const AuthoringStyleSchema: Schema.Literals<readonly ["psl", "typescript"]>;
44
44
  declare const AgentSkillTargetSchema: Schema.Literals<readonly ["claude", "cursor", "agents", "devin"]>;
45
- declare const CreateTemplateSchema: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
45
+ declare const CreateTemplateSchema: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
46
46
  declare const CreateCommandInputSchema: Schema.Struct<{
47
47
  readonly name: Schema.optionalKey<Schema.Trim>;
48
- readonly template: Schema.optionalKey<Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>>;
48
+ readonly template: Schema.optionalKey<Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>>;
49
49
  readonly force: Schema.optionalKey<Schema.Boolean>;
50
50
  readonly provider: Schema.optionalKey<Schema.Literals<readonly ["postgres", "mongo"]>>;
51
51
  readonly authoring: Schema.optionalKey<Schema.Literals<readonly ["psl", "typescript"]>>;
@@ -75,7 +75,7 @@ type CreateNextStep = typeof CreateNextStepSchema.Type;
75
75
  declare const CreateProjectResultSchema: Schema.Struct<{
76
76
  readonly name: Schema.String;
77
77
  readonly path: Schema.String;
78
- readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
78
+ readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
79
79
  readonly databaseProvider: Schema.Literals<readonly ["postgres", "mongo"]>;
80
80
  readonly authoring: Schema.Literals<readonly ["psl", "typescript"]>;
81
81
  readonly packageManager: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
@@ -88,7 +88,7 @@ declare const CreateCommandSuccessResultSchema: Schema.Struct<{
88
88
  readonly project: Schema.Struct<{
89
89
  readonly name: Schema.String;
90
90
  readonly path: Schema.String;
91
- readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
91
+ readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
92
92
  readonly databaseProvider: Schema.Literals<readonly ["postgres", "mongo"]>;
93
93
  readonly authoring: Schema.Literals<readonly ["psl", "typescript"]>;
94
94
  readonly packageManager: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
@@ -124,7 +124,7 @@ declare const CreateCommandFailureResultSchema: Schema.Struct<{
124
124
  readonly project: Schema.optionalKey<Schema.Struct<{
125
125
  readonly name: Schema.String;
126
126
  readonly path: Schema.String;
127
- readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
127
+ readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
128
128
  readonly databaseProvider: Schema.Literals<readonly ["postgres", "mongo"]>;
129
129
  readonly authoring: Schema.Literals<readonly ["psl", "typescript"]>;
130
130
  readonly packageManager: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
@@ -137,7 +137,7 @@ declare const CreateCommandResultSchema: Schema.Union<readonly [Schema.Struct<{
137
137
  readonly project: Schema.Struct<{
138
138
  readonly name: Schema.String;
139
139
  readonly path: Schema.String;
140
- readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
140
+ readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
141
141
  readonly databaseProvider: Schema.Literals<readonly ["postgres", "mongo"]>;
142
142
  readonly authoring: Schema.Literals<readonly ["psl", "typescript"]>;
143
143
  readonly packageManager: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
@@ -171,7 +171,7 @@ declare const CreateCommandResultSchema: Schema.Union<readonly [Schema.Struct<{
171
171
  readonly project: Schema.optionalKey<Schema.Struct<{
172
172
  readonly name: Schema.String;
173
173
  readonly path: Schema.String;
174
- readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "svelte", "astro", "nuxt", "tanstack-start"]>;
174
+ readonly template: Schema.Literals<readonly ["minimal", "hono", "elysia", "nest", "next", "turborepo", "svelte", "astro", "nuxt", "tanstack-start"]>;
175
175
  readonly databaseProvider: Schema.Literals<readonly ["postgres", "mongo"]>;
176
176
  readonly authoring: Schema.Literals<readonly ["psl", "typescript"]>;
177
177
  readonly packageManager: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun", "deno"]>;
@@ -183,7 +183,7 @@ type CreateCommandResult = typeof CreateCommandResultSchema.Type;
183
183
  declare const createPrismaCommand: Command.Command<"create-prisma", {
184
184
  readonly projectName: string | undefined;
185
185
  readonly name: string | undefined;
186
- readonly template: "minimal" | "hono" | "elysia" | "nest" | "next" | "svelte" | "astro" | "nuxt" | "tanstack-start" | undefined;
186
+ readonly template: "minimal" | "hono" | "elysia" | "nest" | "next" | "turborepo" | "svelte" | "astro" | "nuxt" | "tanstack-start" | undefined;
187
187
  readonly provider: "postgres" | "mongo" | undefined;
188
188
  readonly authoring: "psl" | "typescript" | undefined;
189
189
  readonly packageManager: "npm" | "pnpm" | "yarn" | "bun" | "deno" | undefined;
@@ -198,7 +198,7 @@ declare const createPrismaCommand: Command.Command<"create-prisma", {
198
198
  declare function createCreatePrismaCli(): Command.Command<"create-prisma", {
199
199
  readonly projectName: string | undefined;
200
200
  readonly name: string | undefined;
201
- readonly template: "minimal" | "hono" | "elysia" | "nest" | "next" | "svelte" | "astro" | "nuxt" | "tanstack-start" | undefined;
201
+ readonly template: "minimal" | "hono" | "elysia" | "nest" | "next" | "turborepo" | "svelte" | "astro" | "nuxt" | "tanstack-start" | undefined;
202
202
  readonly provider: "postgres" | "mongo" | undefined;
203
203
  readonly authoring: "psl" | "typescript" | undefined;
204
204
  readonly packageManager: "npm" | "pnpm" | "yarn" | "bun" | "deno" | undefined;
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-CH9M3gTl.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--NEJN266.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.12.0";
7
+ const CLI_VERSION = "0.12.1-pr.79.344.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));
@@ -35,6 +35,7 @@ const CreateFailureStageSchema = Schema.Literals([
35
35
  const CreateFailureReasonSchema = Schema.Literals([
36
36
  "invalid_input",
37
37
  "unsupported_node_version",
38
+ "unsupported_package_manager_version",
38
39
  "invalid_project_name",
39
40
  "target_path_not_directory",
40
41
  "target_directory_not_empty",
@@ -129,6 +130,7 @@ const createTemplates = [
129
130
  "elysia",
130
131
  "nest",
131
132
  "next",
133
+ "turborepo",
132
134
  "svelte",
133
135
  "astro",
134
136
  "nuxt",
@@ -351,20 +353,14 @@ const applicationRuntime = ManagedRuntime.make(ApplicationLayer);
351
353
 
352
354
  //#endregion
353
355
  //#region src/telemetry/client.ts
354
- const TELEMETRY_API_KEY = "phc_cmc85avbWyuJ2JyKdGPdv7dxXli8xLdWDBPbvIXWJfs";
356
+ const TELEMETRY_API_KEY = "";
355
357
  const TELEMETRY_HOST = "https://us.i.posthog.com";
356
358
  const TELEMETRY_CONFIG_FILE = "telemetry.json";
357
359
  const TELEMETRY_TIMEOUT_MS = 2e3;
358
360
  const AnonymousId = Schema.String.check(Schema.isUUID(4));
359
361
  const decodeAnonymousId = Schema.decodeUnknownExit(AnonymousId);
360
- const isTruthyEnvValue = (value) => [
361
- "1",
362
- "true",
363
- "yes",
364
- "on"
365
- ].includes(String(value ?? "").trim().toLowerCase());
366
362
  function shouldDisableTelemetry() {
367
- 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;
363
+ return true;
368
364
  }
369
365
  function getTelemetryConfigDir() {
370
366
  if (process.platform === "darwin") return path.join(os.homedir(), "Library", "Application Support", "create-prisma");
@@ -387,7 +383,7 @@ const getAnonymousIdEffect = Effect.fn("Telemetry.getAnonymousId")(function* ()
387
383
  return anonymousId;
388
384
  });
389
385
  const getCommonProperties = () => ({
390
- "cli-version": "0.12.0",
386
+ "cli-version": "0.12.1-pr.79.344.1",
391
387
  "node-version": process.version,
392
388
  platform: process.platform,
393
389
  arch: process.arch
@@ -426,6 +422,7 @@ const CREATE_PRISMA_NEXT_CANCELLED_EVENT = "cli:create_prisma_next_command_cance
426
422
  const expectedRejectionReasons = new Set([
427
423
  "invalid_input",
428
424
  "unsupported_node_version",
425
+ "unsupported_package_manager_version",
429
426
  "invalid_project_name",
430
427
  "target_path_not_directory",
431
428
  "target_directory_not_empty",
@@ -508,11 +505,27 @@ const trackCreateCancelledEffect = Effect.fn("Telemetry.createCancelled")(functi
508
505
  //#region src/utils/package-manager.ts
509
506
  const DENO_ALLOW_FRESH_DEPENDENCIES = "--minimum-dependency-age=0";
510
507
  const packageManagerManifestValues = {
511
- npm: "npm@10.9.0",
508
+ npm: "npm@11.6.0",
512
509
  pnpm: "pnpm@11.21.0",
513
510
  yarn: "yarn@4.13.0",
514
- bun: "bun@1.3.9"
511
+ bun: "bun@1.4.1"
515
512
  };
513
+ const verifyPackageManagerEffect = Effect.fn("PackageManager.verify")(function* (packageManager) {
514
+ if (packageManager !== "npm") return;
515
+ const version = (yield* (yield* CommandRunner).runChecked({
516
+ command: "npm",
517
+ args: ["--version"],
518
+ cwd: process.cwd()
519
+ })).stdout.trim();
520
+ const parts = version.split(".").map(Number);
521
+ 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}`));
522
+ const [major, minor] = parts;
523
+ if (major < 11 || major === 11 && minor < 6) return yield* new CreateFailure({
524
+ stage: "validate_input",
525
+ reason: "unsupported_package_manager_version",
526
+ 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.`
527
+ });
528
+ });
516
529
  function parseUserAgent(userAgent) {
517
530
  if (userAgent?.startsWith("pnpm")) return "pnpm";
518
531
  if (userAgent?.startsWith("yarn")) return "yarn";
@@ -703,6 +716,7 @@ function getRunScriptArgs(packageManager, scriptName) {
703
716
  //#endregion
704
717
  //#region src/templates/shared.ts
705
718
  Handlebars.registerHelper("eq", (left, right) => left === right);
719
+ Handlebars.registerHelper("or", (...args) => args.slice(0, -1).some(Boolean));
706
720
  Handlebars.registerHelper("runScriptCommand", (packageManager, scriptName) => packageManager ? getRunScriptCommand(packageManager, scriptName) : "");
707
721
  Handlebars.registerHelper("packageManagerManifestValue", (packageManager) => getPackageManagerManifestValue(packageManager) ?? "");
708
722
  Handlebars.registerHelper("runtimeScript", (packageManager, kind, sourceEntrypoint, builtEntrypoint, _options) => packageManager ? getRuntimeScriptCommand(packageManager, kind, {
@@ -749,9 +763,10 @@ const renderTemplateTreeEffect = Effect.fn("Templates.renderTree")(function* (op
749
763
  for (const relativePath of entries) {
750
764
  const templateFilePath = path.join(opts.templateRoot, relativePath);
751
765
  if ((yield* fs.stat(templateFilePath)).type !== "File") continue;
766
+ const renderedRelativePath = stripHbsExtension(relativePath);
752
767
  yield* renderTemplateFileEffect({
753
768
  templateFilePath,
754
- outputPath: path.join(opts.outputDir, stripHbsExtension(relativePath)),
769
+ outputPath: path.join(opts.outputDir, opts.mapRelativeOutputPath?.(renderedRelativePath) ?? renderedRelativePath),
755
770
  context: opts.context
756
771
  });
757
772
  }
@@ -759,6 +774,11 @@ const renderTemplateTreeEffect = Effect.fn("Templates.renderTree")(function* (op
759
774
 
760
775
  //#endregion
761
776
  //#region src/templates/render-create-template.ts
777
+ const DEFAULT_PRISMA_SOURCE_DIR = "src/prisma";
778
+ const TURBOREPO_PRISMA_SOURCE_DIR = "packages/database/src";
779
+ function getCreatePrismaSourceDir(template) {
780
+ return template === "turborepo" ? TURBOREPO_PRISMA_SOURCE_DIR : DEFAULT_PRISMA_SOURCE_DIR;
781
+ }
762
782
  const tsdownEntries = {
763
783
  minimal: "src/index.ts",
764
784
  hono: "src/index.ts",
@@ -780,7 +800,13 @@ const scaffoldCreateSharedTemplatesEffect = Effect.fn("Templates.scaffoldShared"
780
800
  yield* renderTemplateTreeEffect({
781
801
  templateRoot: yield* resolveTemplatesDirEffect("templates/create/_shared"),
782
802
  outputDir: options.projectDir,
783
- context: createTemplateContext(options)
803
+ context: createTemplateContext(options),
804
+ mapRelativeOutputPath(relativePath) {
805
+ if (options.template !== "turborepo") return relativePath;
806
+ const relativePrismaPath = path.relative(DEFAULT_PRISMA_SOURCE_DIR, relativePath);
807
+ if (relativePrismaPath === ".." || relativePrismaPath.startsWith(`..${path.sep}`) || path.isAbsolute(relativePrismaPath)) return relativePath;
808
+ return path.join(TURBOREPO_PRISMA_SOURCE_DIR, relativePrismaPath);
809
+ }
784
810
  });
785
811
  });
786
812
  const scaffoldCreatePackageManagerTemplatesEffect = Effect.fn("Templates.scaffoldPackageManager")(function* (options) {
@@ -796,6 +822,11 @@ const scaffoldCreateFrameworkTemplateEffect = Effect.fn("Templates.scaffoldFrame
796
822
  outputDir: options.projectDir,
797
823
  context: createTemplateContext(options)
798
824
  });
825
+ if (options.template === "turborepo") yield* renderTemplateTreeEffect({
826
+ templateRoot: yield* resolveTemplatesDirEffect("templates/create/next"),
827
+ outputDir: path.join(options.projectDir, "apps/web"),
828
+ context: createTemplateContext(options)
829
+ });
799
830
  });
800
831
  const scaffoldCreateTemplateEffect = Effect.fn("Templates.scaffold")(function* (options) {
801
832
  yield* scaffoldCreateFrameworkTemplateEffect(options);
@@ -824,6 +855,7 @@ const dependencyVersionMap = {
824
855
  prisma: "latest",
825
856
  "temporal-polyfill": "^1.0.4",
826
857
  tsdown: "^0.22.14",
858
+ turbo: "2.10.12",
827
859
  tsx: "^4.21.0",
828
860
  typescript: "^5.9.3"
829
861
  };
@@ -854,11 +886,18 @@ function getCreateTemplateDependencies(template, _packageManager) {
854
886
  if (template === "svelte") devDependencies.push("@sveltejs/adapter-node");
855
887
  if (template === "astro") dependencies.push("@astrojs/node");
856
888
  if (template === "tanstack-start") devDependencies.push("nitro");
857
- return [{
889
+ if (template === "turborepo") devDependencies.push("turbo");
890
+ const targets = [{
858
891
  packageJsonPath: "package.json",
859
892
  dependencies,
860
893
  devDependencies
861
894
  }];
895
+ if (template === "turborepo") targets.push({
896
+ packageJsonPath: "packages/database/package.json",
897
+ dependencies: [],
898
+ devDependencies: ["typescript"]
899
+ });
900
+ return targets;
862
901
  }
863
902
 
864
903
  //#endregion
@@ -978,7 +1017,7 @@ const addPackageDependencyEffect = Effect.fn("Dependencies.add")(function* (opts
978
1017
  });
979
1018
  const writePrismaDependenciesEffect = Effect.fn("Dependencies.writePrisma")(function* (provider, packageManager, _authoring, projectDir = process.cwd(), options = {}) {
980
1019
  const dependencies = [getDbPackages(provider)];
981
- if (provider === "postgres" && packageManager !== "deno") dependencies.push("temporal-polyfill");
1020
+ if (provider === "postgres" && packageManager !== "deno" && options.template !== "turborepo") dependencies.push("temporal-polyfill");
982
1021
  if (provider === "mongo") dependencies.push("arktype", "mongodb");
983
1022
  if (packageManager === "deno") dependencies.push("dotenv");
984
1023
  yield* addPackageDependencyEffect({
@@ -987,6 +1026,10 @@ const writePrismaDependenciesEffect = Effect.fn("Dependencies.writePrisma")(func
987
1026
  scripts: getPrismaScriptMap(packageManager, options.skillsSync ?? true),
988
1027
  projectDir
989
1028
  });
1029
+ if (options.template === "turborepo") yield* addPackageDependencyEffect({
1030
+ dependencies: [getDbPackages(provider), ...provider === "postgres" ? ["temporal-polyfill"] : []],
1031
+ projectDir: path.join(projectDir, "packages/database")
1032
+ });
990
1033
  });
991
1034
  const writeCreateTemplateDependenciesEffect = Effect.fn("Dependencies.writeTemplate")(function* (opts) {
992
1035
  const projectDir = opts.projectDir ?? process.cwd();
@@ -995,7 +1038,7 @@ const writeCreateTemplateDependenciesEffect = Effect.fn("Dependencies.writeTempl
995
1038
  dependencies: target.dependencies,
996
1039
  devDependencies: target.devDependencies,
997
1040
  customDependencies: target.customDependencies,
998
- scripts: getComposerScriptMap(opts.packageManager),
1041
+ scripts: target.packageJsonPath === "package.json" ? getComposerScriptMap(opts.packageManager) : void 0,
999
1042
  projectDir: path.join(projectDir, path.dirname(target.packageJsonPath))
1000
1043
  });
1001
1044
  const packageJsonPath = path.join(projectDir, "package.json");
@@ -1490,7 +1533,7 @@ const initializeGitRepositoryEffect = Effect.fn("Git.initialize")(function* (pro
1490
1533
 
1491
1534
  //#endregion
1492
1535
  //#region src/tasks/prisma-setup/commands.ts
1493
- const getContractPath = (authoring) => `src/prisma/contract${authoring === "typescript" ? ".ts" : ".prisma"}`;
1536
+ const getContractPath = (authoring, template) => `${getCreatePrismaSourceDir(template)}/contract${authoring === "typescript" ? ".ts" : ".prisma"}`;
1494
1537
  const getInitTarget = (provider) => provider === "mongo" ? "mongodb" : "postgres";
1495
1538
  const runPrismaCli = Effect.fn("PrismaSetup.runCli")(function* (context, projectDir, args) {
1496
1539
  const invocation = getLocalPackageBinaryArgs(context.packageManager, "prisma", args);
@@ -1508,7 +1551,7 @@ const runPrismaCli = Effect.fn("PrismaSetup.runCli")(function* (context, project
1508
1551
  ...context.verbose ? { onStderrLine: (line) => log.message(redactSecrets(line), { output: context.output }) } : {}
1509
1552
  });
1510
1553
  });
1511
- const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectDir, force = false) {
1554
+ const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectDir, force = false, template = "minimal") {
1512
1555
  yield* runPrismaCli(context, projectDir, [
1513
1556
  "orm",
1514
1557
  "init",
@@ -1519,7 +1562,7 @@ const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectD
1519
1562
  "--authoring",
1520
1563
  context.authoring,
1521
1564
  "--schema-path",
1522
- getContractPath(context.authoring),
1565
+ getContractPath(context.authoring, template),
1523
1566
  "--skip-install"
1524
1567
  ]);
1525
1568
  if (context.packageManager === "deno") {
@@ -1787,14 +1830,17 @@ const executePrismaSetupContextEffect = Effect.fn("PrismaSetup.execute")(functio
1787
1830
  packageManager: context.packageManager,
1788
1831
  skillAgents: context.skillAgents
1789
1832
  }), "configure_project", "project_configuration_failed");
1790
- yield* atCreateStage(writePrismaDependenciesEffect(context.databaseProvider, context.packageManager, context.authoring, projectDir, { skillsSync: context.skillAgents.length > 0 }), "configure_project", "project_configuration_failed");
1833
+ yield* atCreateStage(writePrismaDependenciesEffect(context.databaseProvider, context.packageManager, context.authoring, projectDir, {
1834
+ skillsSync: context.skillAgents.length > 0,
1835
+ template
1836
+ }), "configure_project", "project_configuration_failed");
1791
1837
  yield* Effect.sync(() => progress?.message(`Installing dependencies with ${getInstallCommand(context.packageManager)}...`));
1792
1838
  yield* atCreateStage(installProjectDependenciesEffect(context.packageManager, projectDir, {
1793
1839
  verbose: context.verbose,
1794
1840
  json: context.json
1795
1841
  }), "install_dependencies", "dependency_install_failed");
1796
1842
  yield* Effect.sync(() => progress?.message("Preparing Prisma 8 project files..."));
1797
- yield* atCreateStage(runPrismaInit(context, projectDir, options.force), "initialize_prisma", "prisma_init_failed");
1843
+ yield* atCreateStage(runPrismaInit(context, projectDir, options.force, template), "initialize_prisma", "prisma_init_failed");
1798
1844
  yield* atCreateStage(Effect.gen(function* () {
1799
1845
  yield* scaffoldCreateSharedTemplatesEffect({
1800
1846
  projectDir,
@@ -1977,6 +2023,11 @@ const promptForCreateTemplate = Effect.fn("Prompts.template")(function* (output)
1977
2023
  label: "Next.js",
1978
2024
  hint: "Full-stack React app with App Router"
1979
2025
  },
2026
+ {
2027
+ value: "turborepo",
2028
+ label: "Monorepo (Turborepo)",
2029
+ hint: "Next.js app with a shared Prisma database package"
2030
+ },
1980
2031
  {
1981
2032
  value: "svelte",
1982
2033
  label: "SvelteKit",
@@ -2172,6 +2223,7 @@ const createProjectEffect = Effect.fn("Create.project")(function* (rawInput, inp
2172
2223
  yield* Effect.sync(() => intro(getCreatePrismaIntro(), { output }));
2173
2224
  const context = yield* atCreateStage(collectCreateContext(input), "collect_context", "unexpected_error");
2174
2225
  yield* Ref.set(contextRef, Option.some(context));
2226
+ yield* atCreateStage(verifyPackageManagerEffect(context.prismaSetupContext.packageManager), "install_dependencies", "dependency_install_failed");
2175
2227
  return {
2176
2228
  input,
2177
2229
  context,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-prisma",
3
- "version": "0.12.0",
3
+ "version": "0.12.1-pr.79.344.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",
@@ -72,5 +72,5 @@
72
72
  "bun": ">=1.3.0",
73
73
  "node": ">=22.18.0"
74
74
  },
75
- "packageManager": "bun@1.3.9"
75
+ "packageManager": "bun@1.4.1"
76
76
  }
@@ -1,8 +1,13 @@
1
1
  {{#if (eq packageManager "pnpm")}}
2
+ {{#if (eq template "turborepo")}}
3
+ packages:
4
+ - "apps/*"
5
+ - "packages/*"
6
+ {{/if}}
2
7
  allowBuilds:
3
8
  esbuild: true
4
9
  msgpackr-extract: true
5
- {{#if (eq template "next")}}
10
+ {{#if (or (eq template "next") (eq template "turborepo"))}}
6
11
  sharp: true
7
12
  unrs-resolver: true
8
13
  {{else if (eq template "astro")}}
@@ -1,11 +1,11 @@
1
1
  {{#if (eq authoring "typescript")}}
2
- src/prisma/generated/contract.json linguist-generated
3
- src/prisma/generated/contract.d.ts linguist-generated
2
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/generated/contract.json linguist-generated
3
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/generated/contract.d.ts linguist-generated
4
4
  {{else}}
5
- src/prisma/contract.json linguist-generated
6
- src/prisma/contract.d.ts linguist-generated
5
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/contract.json linguist-generated
6
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/contract.d.ts linguist-generated
7
7
  {{/if}}
8
- src/prisma/ops.json linguist-generated
9
- src/prisma/migration.json linguist-generated
8
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/ops.json linguist-generated
9
+ {{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/migration.json linguist-generated
10
10
  migrations/snapshots/**/contract.json linguist-generated
11
11
  migrations/snapshots/**/contract.d.ts linguist-generated
@@ -31,6 +31,50 @@ deno task contract:emit
31
31
  ```
32
32
 
33
33
  Prisma Compute does not support Deno deployments yet.
34
+ {{else if (eq template "turborepo")}}
35
+ A Prisma 8 monorepo powered by Turborepo, Next.js, and Prisma Composer.
36
+
37
+ ## Workspace layout
38
+
39
+ - `apps/web` — Next.js application
40
+ - `packages/database` — Prisma contract, generated artifacts, runtime client, and seed data
41
+ - `module.ts` and `service.ts` — Composer deployment topology
42
+
43
+ ## Run locally
44
+
45
+ ```bash
46
+ {{runScriptCommand packageManager "dev:composer"}}
47
+ ```
48
+
49
+ This builds the workspace and starts it with Composer. PostgreSQL projects get a local Prisma Postgres database and apply the committed migrations automatically.
50
+
51
+ ## Deploy
52
+
53
+ ```bash
54
+ {{runScriptCommand packageManager "deploy"}}
55
+ ```
56
+
57
+ The deploy script runs the Turborepo build, provisions Prisma Postgres when selected, applies migrations, and deploys the Next.js app to Prisma Compute.
58
+
59
+ The starter users are inserted idempotently from `packages/database/src/seed.ts` on the first database query through the Composer service binding.
60
+
61
+ {{#if (eq provider "mongo")}}
62
+ MongoDB is not provisioned by Composer. Set `MONGODB_URL` before running Composer locally or deploying.
63
+ {{/if}}
64
+
65
+ ## Prisma
66
+
67
+ - Contract: `packages/database/src/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}`
68
+ - Prisma and Composer config: `prisma.config.ts`
69
+ - Composer app: `module.ts` and `service.ts`
70
+
71
+ After changing the contract, run:
72
+
73
+ ```bash
74
+ {{runScriptCommand packageManager "contract:emit"}}
75
+ ```
76
+
77
+ To run the workspace's development tasks directly, use `{{runScriptCommand packageManager "dev"}}`. This direct mode requires `{{#if (eq provider "postgres")}}DATABASE_URL{{else}}MONGODB_URL{{/if}}`.
34
78
  {{else}}
35
79
  A minimal {{template}} app with Prisma 8 and Prisma Composer.
36
80
 
@@ -3,7 +3,7 @@ import { module } from "@prisma/composer";
3
3
  {{#if (eq provider "postgres")}}
4
4
  import { postgres } from "@prisma/composer-prisma-cloud/orm";
5
5
 
6
- import { appContract } from "./src/prisma/composer.ts";
6
+ import { appContract } from "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/composer.ts";
7
7
  {{else}}
8
8
  import { envSecret } from "@prisma/composer-prisma-cloud";
9
9
  {{/if}}
@@ -1,13 +1,13 @@
1
1
  {{#unless (eq packageManager "deno")}}
2
2
  import { defineConfig } from "@prisma/composer/config";
3
3
  import { nodeBuild } from "@prisma/composer/node/control";
4
- {{#if (eq template "next")}}
4
+ {{#if (or (eq template "next") (eq template "turborepo"))}}
5
5
  import { nextjsBuild } from "@prisma/composer/nextjs/control";
6
6
  {{/if}}
7
7
  import { prismaCloud, prismaState } from "@prisma/composer-prisma-cloud/control";
8
8
 
9
9
  export default defineConfig({
10
- extensions: [prismaCloud(), nodeBuild(){{#if (eq template "next")}}, nextjsBuild(){{/if}}],
10
+ extensions: [prismaCloud({ region: "us-east-1" }), nodeBuild(){{#if (or (eq template "next") (eq template "turborepo"))}}, nextjsBuild(){{/if}}],
11
11
  state: prismaState(),
12
12
  });
13
13
  {{/unless}}
@@ -5,9 +5,9 @@ import { defineConfig as ormConfig } from "@prisma/orm-{{#if (eq provider "postg
5
5
 
6
6
  export default definePrismaConfig({
7
7
  orm: ormConfig({
8
- contract: "./src/prisma/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}",
8
+ contract: "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}",
9
9
  {{#if (eq authoring "typescript")}}
10
- output: "./src/prisma/generated",
10
+ output: "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/generated",
11
11
  {{/if}}
12
12
  db: {
13
13
  connection: process.env.{{#if (eq provider "postgres")}}DATABASE_URL{{else}}MONGODB_URL{{/if}}!,
@@ -23,9 +23,9 @@ export default definePrismaConfig({
23
23
  agents: [{{#each skillAgents}}"{{this}}"{{#unless @last}}, {{/unless}}{{/each}}],
24
24
  },
25
25
  orm: ormConfig({
26
- contract: "./src/prisma/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}",
26
+ contract: "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/contract{{#if (eq authoring "typescript")}}.ts{{else}}.prisma{{/if}}",
27
27
  {{#if (eq authoring "typescript")}}
28
- output: "./src/prisma/generated",
28
+ output: "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/generated",
29
29
  {{/if}}
30
30
  db: {
31
31
  connection: process.env.{{#if (eq provider "postgres")}}DATABASE_URL{{else}}MONGODB_URL{{/if}}!,
@@ -1,5 +1,5 @@
1
1
  {{#unless (eq packageManager "deno")}}
2
- {{#if (eq template "next")}}
2
+ {{#if (or (eq template "next") (eq template "turborepo"))}}
3
3
  import nextjs from "@prisma/composer/nextjs";
4
4
  {{else}}
5
5
  import node from "@prisma/composer/node";
@@ -12,7 +12,7 @@ import { compute } from "@prisma/composer-prisma-cloud";
12
12
  {{#if (eq provider "postgres")}}
13
13
  import { postgres } from "@prisma/composer-prisma-cloud/orm";
14
14
 
15
- import { appContract } from "./src/prisma/composer.ts";
15
+ import { appContract } from "./{{#if (eq template "turborepo")}}packages/database/src{{else}}src/prisma{{/if}}/composer.ts";
16
16
  {{/if}}
17
17
 
18
18
  export default compute({
@@ -29,6 +29,8 @@ export default compute({
29
29
  {{/if}}
30
30
  {{#if (eq template "next")}}
31
31
  build: nextjs({ module: import.meta.url, appDir: "." }),
32
+ {{else if (eq template "turborepo")}}
33
+ build: nextjs({ module: import.meta.url, appDir: "./apps/web" }),
32
34
  {{else if (eq template "svelte")}}
33
35
  build: node({ module: import.meta.url, dir: "./build", entry: "index.js" }),
34
36
  {{else if (eq template "astro")}}
@@ -14,7 +14,7 @@ export const db = postgres<Contract>({ contractJson, url: databaseUrl });
14
14
  {{else}}
15
15
  import "temporal-polyfill/global";
16
16
 
17
- import service from "../../service.ts";
17
+ import service from "{{#if (eq template "turborepo")}}../../../service.ts{{else}}../../service.ts{{/if}}";
18
18
  import type { Contract } from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.d.ts";
19
19
  import contractJson from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.json" with { type: "json" };
20
20
 
@@ -35,7 +35,7 @@ export const db =
35
35
  {{else}}
36
36
  import mongo from "@prisma/orm-mongo/runtime";
37
37
 
38
- import service from "../../service.ts";
38
+ import service from "{{#if (eq template "turborepo")}}../../../service.ts{{else}}../../service.ts{{/if}}";
39
39
  import type { Contract } from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.d.ts";
40
40
  import contractJson from "./{{#if (eq authoring "typescript")}}generated/{{/if}}contract.json" with { type: "json" };
41
41
 
@@ -1,3 +1,5 @@
1
1
  {{#if (eq packageManager "yarn")}}
2
+ {{#unless (eq template "turborepo")}}
2
3
  nodeLinker: node-modules
4
+ {{/unless}}
3
5
  {{/if}}
@@ -0,0 +1,19 @@
1
+ {{#if (eq template "turborepo")}}
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ {{/if}}
5
+ import type { NextConfig } from "next";
6
+
7
+ {{#if (eq template "turborepo")}}
8
+ const monorepoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
9
+ {{/if}}
10
+
11
+ const nextConfig: NextConfig = {
12
+ output: "standalone",
13
+ {{#if (eq template "turborepo")}}
14
+ outputFileTracingRoot: monorepoRoot,
15
+ transpilePackages: ["@repo/database"],
16
+ {{/if}}
17
+ };
18
+
19
+ export default nextConfig;
@@ -1,18 +1,24 @@
1
1
  {
2
- "name": "{{projectName}}",
2
+ "name": "{{#if (eq template "turborepo")}}@repo/web{{else}}{{projectName}}{{/if}}",
3
3
  "version": "0.1.0",
4
4
  "private": true,
5
+ {{#unless (eq template "turborepo")}}
5
6
  {{#if (packageManagerManifestValue packageManager)}}
6
7
  "packageManager": "{{packageManagerManifestValue packageManager}}",
7
8
  {{/if}}
9
+ {{/unless}}
8
10
  "type": "module",
9
11
  "scripts": {
10
12
  "dev": "next dev",
11
13
  "build": "next build",
12
14
  "start": "next start",
13
- "lint": "eslint"
15
+ "lint": "eslint",
16
+ "typecheck": "tsc --noEmit"
14
17
  },
15
18
  "dependencies": {
19
+ {{#if (eq template "turborepo")}}
20
+ "@repo/database": "{{#if (eq packageManager "npm")}}*{{else}}workspace:*{{/if}}",
21
+ {{/if}}
16
22
  "next": "16.1.6",
17
23
  "react": "19.2.3",
18
24
  "react-dom": "19.2.3"
@@ -2,7 +2,7 @@ export const dynamic = "force-dynamic";
2
2
 
3
3
  export default async function Home() {
4
4
 
5
- const { listUsers } = await import("../prisma/users");
5
+ const { listUsers } = await import("{{#if (eq template "turborepo")}}@repo/database{{else}}../prisma/users{{/if}}");
6
6
  const formatter = new Intl.DateTimeFormat("en", {
7
7
  dateStyle: "medium",
8
8
  timeStyle: "short",
@@ -12,12 +12,12 @@ export default async function Home() {
12
12
  return (
13
13
  <main className="shell">
14
14
  <div className="hero">
15
- <p className="eyebrow">Next.js + Prisma 8</p>
15
+ <p className="eyebrow">{{#if (eq template "turborepo")}}Turborepo + {{/if}}Next.js + Prisma 8</p>
16
16
 
17
17
  <h1>Users from your database, loaded on the server.</h1>
18
18
  <p className="lede">
19
- This page reads from <code>src/app/page.tsx</code> using the Prisma 8 helper in{" "}
20
- <code>src/prisma/users.ts</code>.
19
+ This page reads from <code>{{#if (eq template "turborepo")}}apps/web/{{/if}}src/app/page.tsx</code> using the Prisma 8 helper in{" "}
20
+ <code>{{#if (eq template "turborepo")}}packages/database/src/users.ts{{else}}src/prisma/users.ts{{/if}}</code>.
21
21
  </p>
22
22
  </div>
23
23
 
@@ -0,0 +1,3 @@
1
+ {{#if (eq packageManager "yarn")}}
2
+ nodeLinker: node-modules
3
+ {{/if}}
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ {{#if (packageManagerManifestValue packageManager)}}
6
+ "packageManager": "{{packageManagerManifestValue packageManager}}",
7
+ {{/if}}
8
+ "type": "module",
9
+ "workspaces": [
10
+ "apps/*",
11
+ "packages/*"
12
+ ],
13
+ "scripts": {
14
+ "build": "turbo run build",
15
+ "dev": "turbo run dev --parallel",
16
+ "lint": "turbo run lint",
17
+ "start": "turbo run start --parallel",
18
+ "typecheck": "turbo run typecheck"
19
+ },
20
+ "devDependencies": {}
21
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "@repo/database",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./src/users.ts",
8
+ "./db": "./src/db.ts"
9
+ },
10
+ "scripts": {
11
+ "typecheck": "tsc --noEmit --project tsconfig.json"
12
+ }
13
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "include": ["src/**/*.ts"]
4
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "allowImportingTsExtensions": true,
8
+ "noEmit": true,
9
+ "resolveJsonModule": true,
10
+ "skipLibCheck": true,
11
+ "strict": true,
12
+ "types": ["node"]
13
+ },
14
+ "include": [
15
+ "module.ts",
16
+ "service.ts",
17
+ "prisma.config.ts",
18
+ "prisma-composer.config.ts",
19
+ "packages/**/*.ts"
20
+ ],
21
+ "exclude": ["node_modules"]
22
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "tasks": {
4
+ "build": {
5
+ "dependsOn": ["^build"],
6
+ "outputs": [".next/**", "!.next/cache/**", "dist/**"]
7
+ },
8
+ "dev": {
9
+ "cache": false,
10
+ "persistent": true
11
+ },
12
+ "lint": {
13
+ "dependsOn": ["^lint"]
14
+ },
15
+ "start": {
16
+ "cache": false,
17
+ "dependsOn": ["build"],
18
+ "persistent": true
19
+ },
20
+ "typecheck": {
21
+ "dependsOn": ["^typecheck"]
22
+ }
23
+ }
24
+ }
@@ -1,7 +0,0 @@
1
- import type { NextConfig } from "next";
2
-
3
- const nextConfig: NextConfig = {
4
- output: "standalone",
5
- };
6
-
7
- export default nextConfig;