create-prisma 0.12.1 → 0.13.0
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-Bpk7rG2T.mjs} +70 -16
- 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-Bpk7rG2T.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-Bpk7rG2T.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";
|
|
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",
|
|
@@ -388,7 +389,7 @@ const getAnonymousIdEffect = Effect.fn("Telemetry.getAnonymousId")(function* ()
|
|
|
388
389
|
return anonymousId;
|
|
389
390
|
});
|
|
390
391
|
const getCommonProperties = () => ({
|
|
391
|
-
"cli-version": "0.
|
|
392
|
+
"cli-version": "0.13.0",
|
|
392
393
|
"node-version": process.version,
|
|
393
394
|
platform: process.platform,
|
|
394
395
|
arch: process.arch
|
|
@@ -767,9 +768,10 @@ const renderTemplateTreeEffect = Effect.fn("Templates.renderTree")(function* (op
|
|
|
767
768
|
for (const relativePath of entries) {
|
|
768
769
|
const templateFilePath = path.join(opts.templateRoot, relativePath);
|
|
769
770
|
if ((yield* fs.stat(templateFilePath)).type !== "File") continue;
|
|
771
|
+
const renderedRelativePath = stripHbsExtension(relativePath);
|
|
770
772
|
yield* renderTemplateFileEffect({
|
|
771
773
|
templateFilePath,
|
|
772
|
-
outputPath: path.join(opts.outputDir,
|
|
774
|
+
outputPath: path.join(opts.outputDir, opts.mapRelativeOutputPath?.(renderedRelativePath) ?? renderedRelativePath),
|
|
773
775
|
context: opts.context
|
|
774
776
|
});
|
|
775
777
|
}
|
|
@@ -777,11 +779,17 @@ const renderTemplateTreeEffect = Effect.fn("Templates.renderTree")(function* (op
|
|
|
777
779
|
|
|
778
780
|
//#endregion
|
|
779
781
|
//#region src/templates/render-create-template.ts
|
|
782
|
+
const DEFAULT_PRISMA_SOURCE_DIR = "src/prisma";
|
|
783
|
+
const TURBOREPO_PRISMA_SOURCE_DIR = "packages/database/src";
|
|
784
|
+
function getCreatePrismaSourceDir(template) {
|
|
785
|
+
return template === "turborepo" ? TURBOREPO_PRISMA_SOURCE_DIR : DEFAULT_PRISMA_SOURCE_DIR;
|
|
786
|
+
}
|
|
780
787
|
const tsdownEntries = {
|
|
781
788
|
minimal: "src/index.ts",
|
|
782
789
|
hono: "src/index.ts",
|
|
783
790
|
elysia: "src/index.ts",
|
|
784
|
-
nest: "src/main.ts"
|
|
791
|
+
nest: "src/main.ts",
|
|
792
|
+
turborepo: "src/index.ts"
|
|
785
793
|
};
|
|
786
794
|
function createTemplateContext(options) {
|
|
787
795
|
return {
|
|
@@ -798,7 +806,14 @@ const scaffoldCreateSharedTemplatesEffect = Effect.fn("Templates.scaffoldShared"
|
|
|
798
806
|
yield* renderTemplateTreeEffect({
|
|
799
807
|
templateRoot: yield* resolveTemplatesDirEffect("templates/create/_shared"),
|
|
800
808
|
outputDir: options.projectDir,
|
|
801
|
-
context: createTemplateContext(options)
|
|
809
|
+
context: createTemplateContext(options),
|
|
810
|
+
mapRelativeOutputPath(relativePath) {
|
|
811
|
+
if (options.template !== "turborepo") return relativePath;
|
|
812
|
+
if (relativePath === "tsdown.config.ts") return path.join("apps/server", relativePath);
|
|
813
|
+
const relativePrismaPath = path.relative(DEFAULT_PRISMA_SOURCE_DIR, relativePath);
|
|
814
|
+
if (relativePrismaPath === ".." || relativePrismaPath.startsWith(`..${path.sep}`) || path.isAbsolute(relativePrismaPath)) return relativePath;
|
|
815
|
+
return path.join(TURBOREPO_PRISMA_SOURCE_DIR, relativePrismaPath);
|
|
816
|
+
}
|
|
802
817
|
});
|
|
803
818
|
});
|
|
804
819
|
const scaffoldCreatePackageManagerTemplatesEffect = Effect.fn("Templates.scaffoldPackageManager")(function* (options) {
|
|
@@ -828,6 +843,7 @@ const dependencyVersionMap = {
|
|
|
828
843
|
"@elysiajs/node": "^1.4.5",
|
|
829
844
|
"@prisma/composer": "0.19.0",
|
|
830
845
|
"@prisma/composer-prisma-cloud": "0.19.0",
|
|
846
|
+
"@prisma/dev": "0.25.2",
|
|
831
847
|
"@prisma/orm-mongo": "8.0.0-rc.10",
|
|
832
848
|
"@prisma/orm-postgres": "8.0.0-rc.10",
|
|
833
849
|
"@sveltejs/adapter-node": "^5.3.2",
|
|
@@ -842,6 +858,7 @@ const dependencyVersionMap = {
|
|
|
842
858
|
prisma: "latest",
|
|
843
859
|
"temporal-polyfill": "^1.0.4",
|
|
844
860
|
tsdown: "^0.22.14",
|
|
861
|
+
turbo: "2.10.12",
|
|
845
862
|
tsx: "^4.21.0",
|
|
846
863
|
typescript: "^5.9.3"
|
|
847
864
|
};
|
|
@@ -853,7 +870,7 @@ function getDependencyVersion(packageName) {
|
|
|
853
870
|
function usesTsdown(template) {
|
|
854
871
|
return template === "minimal" || template === "hono" || template === "elysia" || template === "nest";
|
|
855
872
|
}
|
|
856
|
-
function getCreateTemplateDependencies(template,
|
|
873
|
+
function getCreateTemplateDependencies(template, packageManager) {
|
|
857
874
|
const dependencies = [
|
|
858
875
|
"@prisma/composer",
|
|
859
876
|
"@prisma/composer-prisma-cloud",
|
|
@@ -872,11 +889,31 @@ function getCreateTemplateDependencies(template, _packageManager) {
|
|
|
872
889
|
if (template === "svelte") devDependencies.push("@sveltejs/adapter-node");
|
|
873
890
|
if (template === "astro") dependencies.push("@astrojs/node");
|
|
874
891
|
if (template === "tanstack-start") devDependencies.push("nitro");
|
|
875
|
-
|
|
892
|
+
if (template === "turborepo") devDependencies.push("turbo", "typescript");
|
|
893
|
+
const targets = [{
|
|
876
894
|
packageJsonPath: "package.json",
|
|
877
895
|
dependencies,
|
|
878
896
|
devDependencies
|
|
879
897
|
}];
|
|
898
|
+
if (template === "turborepo") {
|
|
899
|
+
targets.push({
|
|
900
|
+
packageJsonPath: "apps/server/package.json",
|
|
901
|
+
dependencies: [],
|
|
902
|
+
devDependencies: [
|
|
903
|
+
"@types/node",
|
|
904
|
+
"tsdown",
|
|
905
|
+
"tsx",
|
|
906
|
+
"typescript"
|
|
907
|
+
],
|
|
908
|
+
customDependencies: { "@repo/database": packageManager === "npm" ? "*" : "workspace:*" }
|
|
909
|
+
});
|
|
910
|
+
targets.push({
|
|
911
|
+
packageJsonPath: "packages/database/package.json",
|
|
912
|
+
dependencies: [],
|
|
913
|
+
devDependencies: ["typescript"]
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
return targets;
|
|
880
917
|
}
|
|
881
918
|
|
|
882
919
|
//#endregion
|
|
@@ -995,16 +1032,25 @@ const addPackageDependencyEffect = Effect.fn("Dependencies.add")(function* (opts
|
|
|
995
1032
|
yield* writePackageJson(packageJsonPath, packageJson);
|
|
996
1033
|
});
|
|
997
1034
|
const writePrismaDependenciesEffect = Effect.fn("Dependencies.writePrisma")(function* (provider, packageManager, _authoring, projectDir = process.cwd(), options = {}) {
|
|
998
|
-
const
|
|
999
|
-
|
|
1000
|
-
if (provider === "
|
|
1035
|
+
const databaseDependencies = [getDbPackages(provider)];
|
|
1036
|
+
const devDependencies = ["@types/node", "prisma"];
|
|
1037
|
+
if (provider === "postgres" && packageManager !== "deno") {
|
|
1038
|
+
databaseDependencies.push("temporal-polyfill");
|
|
1039
|
+
devDependencies.push("@prisma/dev");
|
|
1040
|
+
}
|
|
1041
|
+
if (provider === "mongo") databaseDependencies.push("arktype", "mongodb");
|
|
1042
|
+
const dependencies = options.template === "turborepo" ? [getDbPackages(provider), ...provider === "mongo" ? ["arktype"] : []] : [...databaseDependencies];
|
|
1001
1043
|
if (packageManager === "deno") dependencies.push("dotenv");
|
|
1002
1044
|
yield* addPackageDependencyEffect({
|
|
1003
1045
|
dependencies,
|
|
1004
|
-
devDependencies
|
|
1046
|
+
devDependencies,
|
|
1005
1047
|
scripts: getPrismaScriptMap(packageManager, options.skillsSync ?? true),
|
|
1006
1048
|
projectDir
|
|
1007
1049
|
});
|
|
1050
|
+
if (options.template === "turborepo") yield* addPackageDependencyEffect({
|
|
1051
|
+
dependencies: databaseDependencies,
|
|
1052
|
+
projectDir: path.join(projectDir, "packages/database")
|
|
1053
|
+
});
|
|
1008
1054
|
});
|
|
1009
1055
|
const writeCreateTemplateDependenciesEffect = Effect.fn("Dependencies.writeTemplate")(function* (opts) {
|
|
1010
1056
|
const projectDir = opts.projectDir ?? process.cwd();
|
|
@@ -1013,7 +1059,7 @@ const writeCreateTemplateDependenciesEffect = Effect.fn("Dependencies.writeTempl
|
|
|
1013
1059
|
dependencies: target.dependencies,
|
|
1014
1060
|
devDependencies: target.devDependencies,
|
|
1015
1061
|
customDependencies: target.customDependencies,
|
|
1016
|
-
scripts: getComposerScriptMap(opts.packageManager),
|
|
1062
|
+
scripts: target.packageJsonPath === "package.json" ? getComposerScriptMap(opts.packageManager) : void 0,
|
|
1017
1063
|
projectDir: path.join(projectDir, path.dirname(target.packageJsonPath))
|
|
1018
1064
|
});
|
|
1019
1065
|
const packageJsonPath = path.join(projectDir, "package.json");
|
|
@@ -1508,7 +1554,7 @@ const initializeGitRepositoryEffect = Effect.fn("Git.initialize")(function* (pro
|
|
|
1508
1554
|
|
|
1509
1555
|
//#endregion
|
|
1510
1556
|
//#region src/tasks/prisma-setup/commands.ts
|
|
1511
|
-
const getContractPath = (authoring) =>
|
|
1557
|
+
const getContractPath = (authoring, template) => `${getCreatePrismaSourceDir(template)}/contract${authoring === "typescript" ? ".ts" : ".prisma"}`;
|
|
1512
1558
|
const getInitTarget = (provider) => provider === "mongo" ? "mongodb" : "postgres";
|
|
1513
1559
|
const runPrismaCli = Effect.fn("PrismaSetup.runCli")(function* (context, projectDir, args) {
|
|
1514
1560
|
const invocation = getLocalPackageBinaryArgs(context.packageManager, "prisma", args);
|
|
@@ -1526,7 +1572,7 @@ const runPrismaCli = Effect.fn("PrismaSetup.runCli")(function* (context, project
|
|
|
1526
1572
|
...context.verbose ? { onStderrLine: (line) => log.message(redactSecrets(line), { output: context.output }) } : {}
|
|
1527
1573
|
});
|
|
1528
1574
|
});
|
|
1529
|
-
const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectDir, force = false) {
|
|
1575
|
+
const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectDir, force = false, template = "minimal") {
|
|
1530
1576
|
yield* runPrismaCli(context, projectDir, [
|
|
1531
1577
|
"orm",
|
|
1532
1578
|
"init",
|
|
@@ -1537,7 +1583,7 @@ const runPrismaInit = Effect.fn("PrismaSetup.init")(function* (context, projectD
|
|
|
1537
1583
|
"--authoring",
|
|
1538
1584
|
context.authoring,
|
|
1539
1585
|
"--schema-path",
|
|
1540
|
-
getContractPath(context.authoring),
|
|
1586
|
+
getContractPath(context.authoring, template),
|
|
1541
1587
|
"--skip-install"
|
|
1542
1588
|
]);
|
|
1543
1589
|
if (context.packageManager === "deno") {
|
|
@@ -1805,14 +1851,17 @@ const executePrismaSetupContextEffect = Effect.fn("PrismaSetup.execute")(functio
|
|
|
1805
1851
|
packageManager: context.packageManager,
|
|
1806
1852
|
skillAgents: context.skillAgents
|
|
1807
1853
|
}), "configure_project", "project_configuration_failed");
|
|
1808
|
-
yield* atCreateStage(writePrismaDependenciesEffect(context.databaseProvider, context.packageManager, context.authoring, projectDir, {
|
|
1854
|
+
yield* atCreateStage(writePrismaDependenciesEffect(context.databaseProvider, context.packageManager, context.authoring, projectDir, {
|
|
1855
|
+
skillsSync: context.skillAgents.length > 0,
|
|
1856
|
+
template
|
|
1857
|
+
}), "configure_project", "project_configuration_failed");
|
|
1809
1858
|
yield* Effect.sync(() => progress?.message(`Installing dependencies with ${getInstallCommand(context.packageManager)}...`));
|
|
1810
1859
|
yield* atCreateStage(installProjectDependenciesEffect(context.packageManager, projectDir, {
|
|
1811
1860
|
verbose: context.verbose,
|
|
1812
1861
|
json: context.json
|
|
1813
1862
|
}), "install_dependencies", "dependency_install_failed");
|
|
1814
1863
|
yield* Effect.sync(() => progress?.message("Preparing Prisma 8 project files..."));
|
|
1815
|
-
yield* atCreateStage(runPrismaInit(context, projectDir, options.force), "initialize_prisma", "prisma_init_failed");
|
|
1864
|
+
yield* atCreateStage(runPrismaInit(context, projectDir, options.force, template), "initialize_prisma", "prisma_init_failed");
|
|
1816
1865
|
yield* atCreateStage(Effect.gen(function* () {
|
|
1817
1866
|
yield* scaffoldCreateSharedTemplatesEffect({
|
|
1818
1867
|
projectDir,
|
|
@@ -1995,6 +2044,11 @@ const promptForCreateTemplate = Effect.fn("Prompts.template")(function* (output)
|
|
|
1995
2044
|
label: "Next.js",
|
|
1996
2045
|
hint: "Full-stack React app with App Router"
|
|
1997
2046
|
},
|
|
2047
|
+
{
|
|
2048
|
+
value: "turborepo",
|
|
2049
|
+
label: "Monorepo (Turborepo)",
|
|
2050
|
+
hint: "Hello World server with a shared Prisma database package"
|
|
2051
|
+
},
|
|
1998
2052
|
{
|
|
1999
2053
|
value: "svelte",
|
|
2000
2054
|
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
|
+
}
|