create-prisma 0.12.1 → 0.13.0-pr.103.354.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 +5 -0
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +9 -9
- package/dist/index.mjs +2 -2
- package/dist/{json-output-BEzP-dBw.mjs → json-output-CoUxlDn8.mjs} +72 -24
- package/package.json +1 -1
- package/templates/create/_package-manager/pnpm-workspace.yaml.hbs +5 -0
- package/templates/create/_shared/.gitattributes.hbs +6 -6
- package/templates/create/_shared/README.md.hbs +44 -0
- package/templates/create/_shared/module.ts.hbs +1 -1
- package/templates/create/_shared/prisma.config.ts.hbs +4 -4
- package/templates/create/_shared/service.ts.hbs +3 -1
- package/templates/create/_shared/src/prisma/db.ts.hbs +2 -2
- package/templates/create/turborepo/.yarnrc.yml.hbs +3 -0
- package/templates/create/turborepo/apps/server/package.json +15 -0
- package/templates/create/turborepo/apps/server/src/index.ts +31 -0
- package/templates/create/turborepo/apps/server/tsconfig.json +4 -0
- package/templates/create/turborepo/package.json.hbs +20 -0
- package/templates/create/turborepo/packages/database/package.json +13 -0
- package/templates/create/turborepo/packages/database/tsconfig.json +4 -0
- package/templates/create/turborepo/tsconfig.json +22 -0
- package/templates/create/turborepo/turbo.json +23 -0
package/README.md
CHANGED
|
@@ -15,6 +15,10 @@ 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
|
+
|
|
18
22
|
For npm, use 11.6.0 or newer, which includes the [upstream resolver fix](https://github.com/npm/cli/pull/8448).
|
|
19
23
|
Older npm releases can crash resolving the dependency tree (`Cannot read properties of null (reading 'edgesOut')`). Run
|
|
20
24
|
`npm install --global npm@11` to update. create-prisma checks the selected npm
|
|
@@ -44,6 +48,7 @@ workspace. Choosing another workspace also updates the Prisma CLI's active works
|
|
|
44
48
|
- `elysia`
|
|
45
49
|
- `nest`
|
|
46
50
|
- `next`
|
|
51
|
+
- `turborepo` (Hello World Node.js server in `apps/server`, shared Prisma package in `packages/database`)
|
|
47
52
|
- `svelte` (SvelteKit)
|
|
48
53
|
- `astro`
|
|
49
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-
|
|
2
|
+
import { a as ApplicationLayer } from "./json-output-CoUxlDn8.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-
|
|
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-CoUxlDn8.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.
|
|
7
|
+
const CLI_VERSION = "0.13.0-pr.103.354.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));
|
|
@@ -130,6 +130,7 @@ const createTemplates = [
|
|
|
130
130
|
"elysia",
|
|
131
131
|
"nest",
|
|
132
132
|
"next",
|
|
133
|
+
"turborepo",
|
|
133
134
|
"svelte",
|
|
134
135
|
"astro",
|
|
135
136
|
"nuxt",
|
|
@@ -352,20 +353,14 @@ const applicationRuntime = ManagedRuntime.make(ApplicationLayer);
|
|
|
352
353
|
|
|
353
354
|
//#endregion
|
|
354
355
|
//#region src/telemetry/client.ts
|
|
355
|
-
const TELEMETRY_API_KEY = "
|
|
356
|
+
const TELEMETRY_API_KEY = "";
|
|
356
357
|
const TELEMETRY_HOST = "https://us.i.posthog.com";
|
|
357
358
|
const TELEMETRY_CONFIG_FILE = "telemetry.json";
|
|
358
359
|
const TELEMETRY_TIMEOUT_MS = 2e3;
|
|
359
360
|
const AnonymousId = Schema.String.check(Schema.isUUID(4));
|
|
360
361
|
const decodeAnonymousId = Schema.decodeUnknownExit(AnonymousId);
|
|
361
|
-
const isTruthyEnvValue = (value) => [
|
|
362
|
-
"1",
|
|
363
|
-
"true",
|
|
364
|
-
"yes",
|
|
365
|
-
"on"
|
|
366
|
-
].includes(String(value ?? "").trim().toLowerCase());
|
|
367
362
|
function shouldDisableTelemetry() {
|
|
368
|
-
return
|
|
363
|
+
return true;
|
|
369
364
|
}
|
|
370
365
|
function getTelemetryConfigDir() {
|
|
371
366
|
if (process.platform === "darwin") return path.join(os.homedir(), "Library", "Application Support", "create-prisma");
|
|
@@ -388,7 +383,7 @@ const getAnonymousIdEffect = Effect.fn("Telemetry.getAnonymousId")(function* ()
|
|
|
388
383
|
return anonymousId;
|
|
389
384
|
});
|
|
390
385
|
const getCommonProperties = () => ({
|
|
391
|
-
"cli-version": "0.
|
|
386
|
+
"cli-version": "0.13.0-pr.103.354.1",
|
|
392
387
|
"node-version": process.version,
|
|
393
388
|
platform: process.platform,
|
|
394
389
|
arch: process.arch
|
|
@@ -767,9 +762,10 @@ const renderTemplateTreeEffect = Effect.fn("Templates.renderTree")(function* (op
|
|
|
767
762
|
for (const relativePath of entries) {
|
|
768
763
|
const templateFilePath = path.join(opts.templateRoot, relativePath);
|
|
769
764
|
if ((yield* fs.stat(templateFilePath)).type !== "File") continue;
|
|
765
|
+
const renderedRelativePath = stripHbsExtension(relativePath);
|
|
770
766
|
yield* renderTemplateFileEffect({
|
|
771
767
|
templateFilePath,
|
|
772
|
-
outputPath: path.join(opts.outputDir,
|
|
768
|
+
outputPath: path.join(opts.outputDir, opts.mapRelativeOutputPath?.(renderedRelativePath) ?? renderedRelativePath),
|
|
773
769
|
context: opts.context
|
|
774
770
|
});
|
|
775
771
|
}
|
|
@@ -777,11 +773,17 @@ const renderTemplateTreeEffect = Effect.fn("Templates.renderTree")(function* (op
|
|
|
777
773
|
|
|
778
774
|
//#endregion
|
|
779
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
|
+
}
|
|
780
781
|
const tsdownEntries = {
|
|
781
782
|
minimal: "src/index.ts",
|
|
782
783
|
hono: "src/index.ts",
|
|
783
784
|
elysia: "src/index.ts",
|
|
784
|
-
nest: "src/main.ts"
|
|
785
|
+
nest: "src/main.ts",
|
|
786
|
+
turborepo: "src/index.ts"
|
|
785
787
|
};
|
|
786
788
|
function createTemplateContext(options) {
|
|
787
789
|
return {
|
|
@@ -798,7 +800,14 @@ const scaffoldCreateSharedTemplatesEffect = Effect.fn("Templates.scaffoldShared"
|
|
|
798
800
|
yield* renderTemplateTreeEffect({
|
|
799
801
|
templateRoot: yield* resolveTemplatesDirEffect("templates/create/_shared"),
|
|
800
802
|
outputDir: options.projectDir,
|
|
801
|
-
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
|
+
}
|
|
802
811
|
});
|
|
803
812
|
});
|
|
804
813
|
const scaffoldCreatePackageManagerTemplatesEffect = Effect.fn("Templates.scaffoldPackageManager")(function* (options) {
|
|
@@ -828,6 +837,7 @@ const dependencyVersionMap = {
|
|
|
828
837
|
"@elysiajs/node": "^1.4.5",
|
|
829
838
|
"@prisma/composer": "0.19.0",
|
|
830
839
|
"@prisma/composer-prisma-cloud": "0.19.0",
|
|
840
|
+
"@prisma/dev": "0.25.2",
|
|
831
841
|
"@prisma/orm-mongo": "8.0.0-rc.10",
|
|
832
842
|
"@prisma/orm-postgres": "8.0.0-rc.10",
|
|
833
843
|
"@sveltejs/adapter-node": "^5.3.2",
|
|
@@ -842,6 +852,7 @@ const dependencyVersionMap = {
|
|
|
842
852
|
prisma: "latest",
|
|
843
853
|
"temporal-polyfill": "^1.0.4",
|
|
844
854
|
tsdown: "^0.22.14",
|
|
855
|
+
turbo: "2.10.12",
|
|
845
856
|
tsx: "^4.21.0",
|
|
846
857
|
typescript: "^5.9.3"
|
|
847
858
|
};
|
|
@@ -853,7 +864,7 @@ function getDependencyVersion(packageName) {
|
|
|
853
864
|
function usesTsdown(template) {
|
|
854
865
|
return template === "minimal" || template === "hono" || template === "elysia" || template === "nest";
|
|
855
866
|
}
|
|
856
|
-
function getCreateTemplateDependencies(template,
|
|
867
|
+
function getCreateTemplateDependencies(template, packageManager) {
|
|
857
868
|
const dependencies = [
|
|
858
869
|
"@prisma/composer",
|
|
859
870
|
"@prisma/composer-prisma-cloud",
|
|
@@ -872,11 +883,31 @@ function getCreateTemplateDependencies(template, _packageManager) {
|
|
|
872
883
|
if (template === "svelte") devDependencies.push("@sveltejs/adapter-node");
|
|
873
884
|
if (template === "astro") dependencies.push("@astrojs/node");
|
|
874
885
|
if (template === "tanstack-start") devDependencies.push("nitro");
|
|
875
|
-
|
|
886
|
+
if (template === "turborepo") devDependencies.push("turbo", "typescript");
|
|
887
|
+
const targets = [{
|
|
876
888
|
packageJsonPath: "package.json",
|
|
877
889
|
dependencies,
|
|
878
890
|
devDependencies
|
|
879
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;
|
|
880
911
|
}
|
|
881
912
|
|
|
882
913
|
//#endregion
|
|
@@ -995,16 +1026,25 @@ const addPackageDependencyEffect = Effect.fn("Dependencies.add")(function* (opts
|
|
|
995
1026
|
yield* writePackageJson(packageJsonPath, packageJson);
|
|
996
1027
|
});
|
|
997
1028
|
const writePrismaDependenciesEffect = Effect.fn("Dependencies.writePrisma")(function* (provider, packageManager, _authoring, projectDir = process.cwd(), options = {}) {
|
|
998
|
-
const
|
|
999
|
-
|
|
1000
|
-
if (provider === "
|
|
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];
|
|
1001
1037
|
if (packageManager === "deno") dependencies.push("dotenv");
|
|
1002
1038
|
yield* addPackageDependencyEffect({
|
|
1003
1039
|
dependencies,
|
|
1004
|
-
devDependencies
|
|
1040
|
+
devDependencies,
|
|
1005
1041
|
scripts: getPrismaScriptMap(packageManager, options.skillsSync ?? true),
|
|
1006
1042
|
projectDir
|
|
1007
1043
|
});
|
|
1044
|
+
if (options.template === "turborepo") yield* addPackageDependencyEffect({
|
|
1045
|
+
dependencies: databaseDependencies,
|
|
1046
|
+
projectDir: path.join(projectDir, "packages/database")
|
|
1047
|
+
});
|
|
1008
1048
|
});
|
|
1009
1049
|
const writeCreateTemplateDependenciesEffect = Effect.fn("Dependencies.writeTemplate")(function* (opts) {
|
|
1010
1050
|
const projectDir = opts.projectDir ?? process.cwd();
|
|
@@ -1013,7 +1053,7 @@ const writeCreateTemplateDependenciesEffect = Effect.fn("Dependencies.writeTempl
|
|
|
1013
1053
|
dependencies: target.dependencies,
|
|
1014
1054
|
devDependencies: target.devDependencies,
|
|
1015
1055
|
customDependencies: target.customDependencies,
|
|
1016
|
-
scripts: getComposerScriptMap(opts.packageManager),
|
|
1056
|
+
scripts: target.packageJsonPath === "package.json" ? getComposerScriptMap(opts.packageManager) : void 0,
|
|
1017
1057
|
projectDir: path.join(projectDir, path.dirname(target.packageJsonPath))
|
|
1018
1058
|
});
|
|
1019
1059
|
const packageJsonPath = path.join(projectDir, "package.json");
|
|
@@ -1508,7 +1548,7 @@ const initializeGitRepositoryEffect = Effect.fn("Git.initialize")(function* (pro
|
|
|
1508
1548
|
|
|
1509
1549
|
//#endregion
|
|
1510
1550
|
//#region src/tasks/prisma-setup/commands.ts
|
|
1511
|
-
const getContractPath = (authoring) =>
|
|
1551
|
+
const getContractPath = (authoring, template) => `${getCreatePrismaSourceDir(template)}/contract${authoring === "typescript" ? ".ts" : ".prisma"}`;
|
|
1512
1552
|
const getInitTarget = (provider) => provider === "mongo" ? "mongodb" : "postgres";
|
|
1513
1553
|
const runPrismaCli = Effect.fn("PrismaSetup.runCli")(function* (context, projectDir, args) {
|
|
1514
1554
|
const invocation = getLocalPackageBinaryArgs(context.packageManager, "prisma", args);
|
|
@@ -1526,7 +1566,7 @@ const runPrismaCli = Effect.fn("PrismaSetup.runCli")(function* (context, project
|
|
|
1526
1566
|
...context.verbose ? { onStderrLine: (line) => log.message(redactSecrets(line), { output: context.output }) } : {}
|
|
1527
1567
|
});
|
|
1528
1568
|
});
|
|
1529
|
-
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") {
|
|
1530
1570
|
yield* runPrismaCli(context, projectDir, [
|
|
1531
1571
|
"orm",
|
|
1532
1572
|
"init",
|
|
@@ -1537,7 +1577,7 @@ const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectD
|
|
|
1537
1577
|
"--authoring",
|
|
1538
1578
|
context.authoring,
|
|
1539
1579
|
"--schema-path",
|
|
1540
|
-
getContractPath(context.authoring),
|
|
1580
|
+
getContractPath(context.authoring, template),
|
|
1541
1581
|
"--skip-install"
|
|
1542
1582
|
]);
|
|
1543
1583
|
if (context.packageManager === "deno") {
|
|
@@ -1805,14 +1845,17 @@ const executePrismaSetupContextEffect = Effect.fn("PrismaSetup.execute")(functio
|
|
|
1805
1845
|
packageManager: context.packageManager,
|
|
1806
1846
|
skillAgents: context.skillAgents
|
|
1807
1847
|
}), "configure_project", "project_configuration_failed");
|
|
1808
|
-
yield* atCreateStage(writePrismaDependenciesEffect(context.databaseProvider, context.packageManager, context.authoring, projectDir, {
|
|
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");
|
|
1809
1852
|
yield* Effect.sync(() => progress?.message(`Installing dependencies with ${getInstallCommand(context.packageManager)}...`));
|
|
1810
1853
|
yield* atCreateStage(installProjectDependenciesEffect(context.packageManager, projectDir, {
|
|
1811
1854
|
verbose: context.verbose,
|
|
1812
1855
|
json: context.json
|
|
1813
1856
|
}), "install_dependencies", "dependency_install_failed");
|
|
1814
1857
|
yield* Effect.sync(() => progress?.message("Preparing Prisma 8 project files..."));
|
|
1815
|
-
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");
|
|
1816
1859
|
yield* atCreateStage(Effect.gen(function* () {
|
|
1817
1860
|
yield* scaffoldCreateSharedTemplatesEffect({
|
|
1818
1861
|
projectDir,
|
|
@@ -1995,6 +2038,11 @@ const promptForCreateTemplate = Effect.fn("Prompts.template")(function* (output)
|
|
|
1995
2038
|
label: "Next.js",
|
|
1996
2039
|
hint: "Full-stack React app with App Router"
|
|
1997
2040
|
},
|
|
2041
|
+
{
|
|
2042
|
+
value: "turborepo",
|
|
2043
|
+
label: "Monorepo (Turborepo)",
|
|
2044
|
+
hint: "Hello World server with a shared Prisma database package"
|
|
2045
|
+
},
|
|
1998
2046
|
{
|
|
1999
2047
|
value: "svelte",
|
|
2000
2048
|
label: "SvelteKit",
|
package/package.json
CHANGED
|
@@ -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}}
|
|
@@ -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,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,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,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
|
+
}
|