create-prisma 0.12.0 → 0.12.1-pr.102.352.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,15 @@ 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
+ PostgreSQL apps with Composer include `@prisma/dev` as a project devDependency for
19
+ local Postgres. In a monorepo it belongs at the root, where Composer runs. Prisma 8
20
+ does not include this runtime itself. MongoDB and Deno-only apps do not need it.
21
+
22
+ For npm, use 11.6.0 or newer, which includes the [upstream resolver fix](https://github.com/npm/cli/pull/8448).
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.
26
+
18
27
  The deployment prompt is:
19
28
 
20
29
  ```text
@@ -23,6 +32,11 @@ Deploy to Prisma now?
23
32
 
24
33
  Choose no to deploy later with the generated `deploy` script.
25
34
 
35
+ New apps explicitly use `us-east-1` in `prisma-composer.config.ts`. Change the
36
+ `prismaCloud({ region })` option before deploying if you need another region.
37
+ Composer requires a region when creating a new project; leaving it unspecified
38
+ only works when deploying into an existing project whose region can be inherited.
39
+
26
40
  When multiple Prisma workspace sessions are available, the CLI asks which workspace should receive
27
41
  the deployment. For unattended usage, pass `--workspace <id-or-name>` or omit it to use the active
28
42
  workspace. Choosing another workspace also updates the Prisma CLI's active workspace session.
@@ -34,6 +48,7 @@ workspace. Choosing another workspace also updates the Prisma CLI's active works
34
48
  - `elysia`
35
49
  - `nest`
36
50
  - `next`
51
+ - `turborepo` (Hello World Node.js server in `apps/server`, shared Prisma package in `packages/database`)
37
52
  - `svelte` (SvelteKit)
38
53
  - `astro`
39
54
  - `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-DAgUJFy1.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-DAgUJFy1.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.102.352.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.102.352.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";
@@ -749,9 +762,10 @@ const renderTemplateTreeEffect = Effect.fn("Templates.renderTree")(function* (op
749
762
  for (const relativePath of entries) {
750
763
  const templateFilePath = path.join(opts.templateRoot, relativePath);
751
764
  if ((yield* fs.stat(templateFilePath)).type !== "File") continue;
765
+ const renderedRelativePath = stripHbsExtension(relativePath);
752
766
  yield* renderTemplateFileEffect({
753
767
  templateFilePath,
754
- outputPath: path.join(opts.outputDir, stripHbsExtension(relativePath)),
768
+ outputPath: path.join(opts.outputDir, opts.mapRelativeOutputPath?.(renderedRelativePath) ?? renderedRelativePath),
755
769
  context: opts.context
756
770
  });
757
771
  }
@@ -759,11 +773,17 @@ const renderTemplateTreeEffect = Effect.fn("Templates.renderTree")(function* (op
759
773
 
760
774
  //#endregion
761
775
  //#region src/templates/render-create-template.ts
776
+ const DEFAULT_PRISMA_SOURCE_DIR = "src/prisma";
777
+ const TURBOREPO_PRISMA_SOURCE_DIR = "packages/database/src";
778
+ function getCreatePrismaSourceDir(template) {
779
+ return template === "turborepo" ? TURBOREPO_PRISMA_SOURCE_DIR : DEFAULT_PRISMA_SOURCE_DIR;
780
+ }
762
781
  const tsdownEntries = {
763
782
  minimal: "src/index.ts",
764
783
  hono: "src/index.ts",
765
784
  elysia: "src/index.ts",
766
- nest: "src/main.ts"
785
+ nest: "src/main.ts",
786
+ turborepo: "src/index.ts"
767
787
  };
768
788
  function createTemplateContext(options) {
769
789
  return {
@@ -780,7 +800,14 @@ 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
+ if (relativePath === "tsdown.config.ts") return path.join("apps/server", relativePath);
807
+ const relativePrismaPath = path.relative(DEFAULT_PRISMA_SOURCE_DIR, relativePath);
808
+ if (relativePrismaPath === ".." || relativePrismaPath.startsWith(`..${path.sep}`) || path.isAbsolute(relativePrismaPath)) return relativePath;
809
+ return path.join(TURBOREPO_PRISMA_SOURCE_DIR, relativePrismaPath);
810
+ }
784
811
  });
785
812
  });
786
813
  const scaffoldCreatePackageManagerTemplatesEffect = Effect.fn("Templates.scaffoldPackageManager")(function* (options) {
@@ -810,6 +837,7 @@ const dependencyVersionMap = {
810
837
  "@elysiajs/node": "^1.4.5",
811
838
  "@prisma/composer": "0.19.0",
812
839
  "@prisma/composer-prisma-cloud": "0.19.0",
840
+ "@prisma/dev": "0.25.2",
813
841
  "@prisma/orm-mongo": "8.0.0-rc.10",
814
842
  "@prisma/orm-postgres": "8.0.0-rc.10",
815
843
  "@sveltejs/adapter-node": "^5.3.2",
@@ -824,6 +852,7 @@ const dependencyVersionMap = {
824
852
  prisma: "latest",
825
853
  "temporal-polyfill": "^1.0.4",
826
854
  tsdown: "^0.22.14",
855
+ turbo: "2.10.12",
827
856
  tsx: "^4.21.0",
828
857
  typescript: "^5.9.3"
829
858
  };
@@ -835,7 +864,7 @@ function getDependencyVersion(packageName) {
835
864
  function usesTsdown(template) {
836
865
  return template === "minimal" || template === "hono" || template === "elysia" || template === "nest";
837
866
  }
838
- function getCreateTemplateDependencies(template, _packageManager) {
867
+ function getCreateTemplateDependencies(template, packageManager) {
839
868
  const dependencies = [
840
869
  "@prisma/composer",
841
870
  "@prisma/composer-prisma-cloud",
@@ -854,11 +883,31 @@ function getCreateTemplateDependencies(template, _packageManager) {
854
883
  if (template === "svelte") devDependencies.push("@sveltejs/adapter-node");
855
884
  if (template === "astro") dependencies.push("@astrojs/node");
856
885
  if (template === "tanstack-start") devDependencies.push("nitro");
857
- return [{
886
+ if (template === "turborepo") devDependencies.push("turbo", "typescript");
887
+ const targets = [{
858
888
  packageJsonPath: "package.json",
859
889
  dependencies,
860
890
  devDependencies
861
891
  }];
892
+ if (template === "turborepo") {
893
+ targets.push({
894
+ packageJsonPath: "apps/server/package.json",
895
+ dependencies: [],
896
+ devDependencies: [
897
+ "@types/node",
898
+ "tsdown",
899
+ "tsx",
900
+ "typescript"
901
+ ],
902
+ customDependencies: { "@repo/database": packageManager === "npm" ? "*" : "workspace:*" }
903
+ });
904
+ targets.push({
905
+ packageJsonPath: "packages/database/package.json",
906
+ dependencies: [],
907
+ devDependencies: ["typescript"]
908
+ });
909
+ }
910
+ return targets;
862
911
  }
863
912
 
864
913
  //#endregion
@@ -977,16 +1026,25 @@ const addPackageDependencyEffect = Effect.fn("Dependencies.add")(function* (opts
977
1026
  yield* writePackageJson(packageJsonPath, packageJson);
978
1027
  });
979
1028
  const writePrismaDependenciesEffect = Effect.fn("Dependencies.writePrisma")(function* (provider, packageManager, _authoring, projectDir = process.cwd(), options = {}) {
980
- const dependencies = [getDbPackages(provider)];
981
- if (provider === "postgres" && packageManager !== "deno") dependencies.push("temporal-polyfill");
982
- if (provider === "mongo") dependencies.push("arktype", "mongodb");
1029
+ const databaseDependencies = [getDbPackages(provider)];
1030
+ const devDependencies = ["@types/node", "prisma"];
1031
+ if (provider === "postgres" && packageManager !== "deno") {
1032
+ databaseDependencies.push("temporal-polyfill");
1033
+ devDependencies.push("@prisma/dev");
1034
+ }
1035
+ if (provider === "mongo") databaseDependencies.push("arktype", "mongodb");
1036
+ const dependencies = options.template === "turborepo" ? [getDbPackages(provider), ...provider === "mongo" ? ["arktype"] : []] : [...databaseDependencies];
983
1037
  if (packageManager === "deno") dependencies.push("dotenv");
984
1038
  yield* addPackageDependencyEffect({
985
1039
  dependencies,
986
- devDependencies: ["@types/node", "prisma"],
1040
+ devDependencies,
987
1041
  scripts: getPrismaScriptMap(packageManager, options.skillsSync ?? true),
988
1042
  projectDir
989
1043
  });
1044
+ if (options.template === "turborepo") yield* addPackageDependencyEffect({
1045
+ dependencies: databaseDependencies,
1046
+ projectDir: path.join(projectDir, "packages/database")
1047
+ });
990
1048
  });
991
1049
  const writeCreateTemplateDependenciesEffect = Effect.fn("Dependencies.writeTemplate")(function* (opts) {
992
1050
  const projectDir = opts.projectDir ?? process.cwd();
@@ -995,7 +1053,7 @@ const writeCreateTemplateDependenciesEffect = Effect.fn("Dependencies.writeTempl
995
1053
  dependencies: target.dependencies,
996
1054
  devDependencies: target.devDependencies,
997
1055
  customDependencies: target.customDependencies,
998
- scripts: getComposerScriptMap(opts.packageManager),
1056
+ scripts: target.packageJsonPath === "package.json" ? getComposerScriptMap(opts.packageManager) : void 0,
999
1057
  projectDir: path.join(projectDir, path.dirname(target.packageJsonPath))
1000
1058
  });
1001
1059
  const packageJsonPath = path.join(projectDir, "package.json");
@@ -1490,7 +1548,7 @@ const initializeGitRepositoryEffect = Effect.fn("Git.initialize")(function* (pro
1490
1548
 
1491
1549
  //#endregion
1492
1550
  //#region src/tasks/prisma-setup/commands.ts
1493
- const getContractPath = (authoring) => `src/prisma/contract${authoring === "typescript" ? ".ts" : ".prisma"}`;
1551
+ const getContractPath = (authoring, template) => `${getCreatePrismaSourceDir(template)}/contract${authoring === "typescript" ? ".ts" : ".prisma"}`;
1494
1552
  const getInitTarget = (provider) => provider === "mongo" ? "mongodb" : "postgres";
1495
1553
  const runPrismaCli = Effect.fn("PrismaSetup.runCli")(function* (context, projectDir, args) {
1496
1554
  const invocation = getLocalPackageBinaryArgs(context.packageManager, "prisma", args);
@@ -1508,7 +1566,7 @@ const runPrismaCli = Effect.fn("PrismaSetup.runCli")(function* (context, project
1508
1566
  ...context.verbose ? { onStderrLine: (line) => log.message(redactSecrets(line), { output: context.output }) } : {}
1509
1567
  });
1510
1568
  });
1511
- const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectDir, force = false) {
1569
+ const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectDir, force = false, template = "minimal") {
1512
1570
  yield* runPrismaCli(context, projectDir, [
1513
1571
  "orm",
1514
1572
  "init",
@@ -1519,7 +1577,7 @@ const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectD
1519
1577
  "--authoring",
1520
1578
  context.authoring,
1521
1579
  "--schema-path",
1522
- getContractPath(context.authoring),
1580
+ getContractPath(context.authoring, template),
1523
1581
  "--skip-install"
1524
1582
  ]);
1525
1583
  if (context.packageManager === "deno") {
@@ -1787,14 +1845,17 @@ const executePrismaSetupContextEffect = Effect.fn("PrismaSetup.execute")(functio
1787
1845
  packageManager: context.packageManager,
1788
1846
  skillAgents: context.skillAgents
1789
1847
  }), "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");
1848
+ yield* atCreateStage(writePrismaDependenciesEffect(context.databaseProvider, context.packageManager, context.authoring, projectDir, {
1849
+ skillsSync: context.skillAgents.length > 0,
1850
+ template
1851
+ }), "configure_project", "project_configuration_failed");
1791
1852
  yield* Effect.sync(() => progress?.message(`Installing dependencies with ${getInstallCommand(context.packageManager)}...`));
1792
1853
  yield* atCreateStage(installProjectDependenciesEffect(context.packageManager, projectDir, {
1793
1854
  verbose: context.verbose,
1794
1855
  json: context.json
1795
1856
  }), "install_dependencies", "dependency_install_failed");
1796
1857
  yield* Effect.sync(() => progress?.message("Preparing Prisma 8 project files..."));
1797
- yield* atCreateStage(runPrismaInit(context, projectDir, options.force), "initialize_prisma", "prisma_init_failed");
1858
+ yield* atCreateStage(runPrismaInit(context, projectDir, options.force, template), "initialize_prisma", "prisma_init_failed");
1798
1859
  yield* atCreateStage(Effect.gen(function* () {
1799
1860
  yield* scaffoldCreateSharedTemplatesEffect({
1800
1861
  projectDir,
@@ -1977,6 +2038,11 @@ const promptForCreateTemplate = Effect.fn("Prompts.template")(function* (output)
1977
2038
  label: "Next.js",
1978
2039
  hint: "Full-stack React app with App Router"
1979
2040
  },
2041
+ {
2042
+ value: "turborepo",
2043
+ label: "Monorepo (Turborepo)",
2044
+ hint: "Hello World server with a shared Prisma database package"
2045
+ },
1980
2046
  {
1981
2047
  value: "svelte",
1982
2048
  label: "SvelteKit",
@@ -2172,6 +2238,7 @@ const createProjectEffect = Effect.fn("Create.project")(function* (rawInput, inp
2172
2238
  yield* Effect.sync(() => intro(getCreatePrismaIntro(), { output }));
2173
2239
  const context = yield* atCreateStage(collectCreateContext(input), "collect_context", "unexpected_error");
2174
2240
  yield* Ref.set(contextRef, Option.some(context));
2241
+ yield* atCreateStage(verifyPackageManagerEffect(context.prismaSetupContext.packageManager), "install_dependencies", "dependency_install_failed");
2175
2242
  return {
2176
2243
  input,
2177
2244
  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.102.352.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,4 +1,9 @@
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
@@ -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 minimal Prisma 8 monorepo with Turborepo and a plain Node.js HTTP server.
36
+
37
+ ## Workspace layout
38
+
39
+ - `apps/server` — Hello World server; `/users` reads from the shared database package
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 builds the server with tsdown, provisions Prisma Postgres when selected, applies migrations, and deploys the server to Prisma Compute.
58
+
59
+ The home page returns `Hello World!` without querying the database. Visiting `/users` queries the shared Prisma package and inserts starter users idempotently from `packages/database/src/seed.ts`.
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}}
@@ -7,7 +7,7 @@ import { nextjsBuild } from "@prisma/composer/nextjs/control";
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 (eq template "next")}}, 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}}!,
@@ -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: node({ module: import.meta.url, entry: "./apps/server/dist/server.mjs" }),
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
 
@@ -0,0 +1,3 @@
1
+ {{#if (eq packageManager "yarn")}}
2
+ nodeLinker: node-modules
3
+ {{/if}}
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@repo/server",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "tsx watch src/index.ts",
8
+ "build": "tsdown",
9
+ "start": "node dist/server.mjs",
10
+ "typecheck": "tsc --noEmit"
11
+ },
12
+ "engines": {
13
+ "node": "^22.18.0 || >=24.11.0"
14
+ }
15
+ }
@@ -0,0 +1,31 @@
1
+ import { createServer } from "node:http";
2
+
3
+ import { listUsers } from "@repo/database";
4
+
5
+ const port = Number(process.env.PORT ?? 3000);
6
+
7
+ createServer(async (request, response) => {
8
+ if (request.url === "/") {
9
+ response.writeHead(200, { "content-type": "text/plain" });
10
+ response.end("Hello World!");
11
+ return;
12
+ }
13
+
14
+ if (request.url !== "/users") {
15
+ response.writeHead(404, { "content-type": "text/plain" });
16
+ response.end("Not found");
17
+ return;
18
+ }
19
+
20
+ try {
21
+ const users = await listUsers();
22
+ response.writeHead(200, { "content-type": "application/json" });
23
+ response.end(JSON.stringify({ users }));
24
+ } catch (error) {
25
+ console.error("Failed to query users:", error);
26
+ response.writeHead(500, { "content-type": "application/json" });
27
+ response.end(JSON.stringify({ error: "Could not query users yet." }));
28
+ }
29
+ }).listen(port, "0.0.0.0", () => {
30
+ console.log(`Server running at http://localhost:${port}`);
31
+ });
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "include": ["src/**/*.ts", "tsdown.config.ts"]
4
+ }
@@ -0,0 +1,20 @@
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",
16
+ "start": "turbo run start",
17
+ "typecheck": "tsc --noEmit && turbo run typecheck"
18
+ },
19
+ "devDependencies": {}
20
+ }
@@ -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,23 @@
1
+ {
2
+ "$schema": "https://turbo.build/schema.json",
3
+ "globalDependencies": ["service.ts", "packages/database/src/**"],
4
+ "globalPassThroughEnv": ["PORT", "DATABASE_URL", "MONGODB_URL"],
5
+ "tasks": {
6
+ "build": {
7
+ "dependsOn": ["^build"],
8
+ "outputs": ["dist/**"]
9
+ },
10
+ "dev": {
11
+ "cache": false,
12
+ "persistent": true
13
+ },
14
+ "start": {
15
+ "cache": false,
16
+ "dependsOn": ["build"],
17
+ "persistent": true
18
+ },
19
+ "typecheck": {
20
+ "dependsOn": ["^typecheck"]
21
+ }
22
+ }
23
+ }