@prisma-next/cli 0.3.0-pr.99.6 → 0.3.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/LICENSE +201 -0
- package/README.md +381 -128
- package/dist/agent-skill-mongo.md +106 -0
- package/dist/agent-skill-postgres.md +106 -0
- package/dist/cli-errors-BDCYR5ap.mjs +4 -0
- package/dist/cli-errors-DStABy9d.d.mts +3 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.js +1 -2910
- package/dist/cli.mjs +261 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/client-DiUkJAeN.mjs +987 -0
- package/dist/client-DiUkJAeN.mjs.map +1 -0
- package/dist/commands/contract-emit.d.mts +7 -0
- package/dist/commands/contract-emit.d.mts.map +1 -0
- package/dist/commands/contract-emit.mjs +9 -0
- package/dist/commands/contract-infer.d.mts +7 -0
- package/dist/commands/contract-infer.d.mts.map +1 -0
- package/dist/commands/contract-infer.mjs +10 -0
- package/dist/commands/db-init.d.mts +7 -0
- package/dist/commands/db-init.d.mts.map +1 -0
- package/dist/commands/db-init.mjs +126 -0
- package/dist/commands/db-init.mjs.map +1 -0
- package/dist/commands/db-schema.d.mts +7 -0
- package/dist/commands/db-schema.d.mts.map +1 -0
- package/dist/commands/db-schema.mjs +56 -0
- package/dist/commands/db-schema.mjs.map +1 -0
- package/dist/commands/db-sign.d.mts +7 -0
- package/dist/commands/db-sign.d.mts.map +1 -0
- package/dist/commands/db-sign.mjs +137 -0
- package/dist/commands/db-sign.mjs.map +1 -0
- package/dist/commands/db-update.d.mts +7 -0
- package/dist/commands/db-update.d.mts.map +1 -0
- package/dist/commands/db-update.mjs +123 -0
- package/dist/commands/db-update.mjs.map +1 -0
- package/dist/commands/db-verify.d.mts +7 -0
- package/dist/commands/db-verify.d.mts.map +1 -0
- package/dist/commands/db-verify.mjs +323 -0
- package/dist/commands/db-verify.mjs.map +1 -0
- package/dist/commands/migration-apply.d.mts +36 -0
- package/dist/commands/migration-apply.d.mts.map +1 -0
- package/dist/commands/migration-apply.mjs +245 -0
- package/dist/commands/migration-apply.mjs.map +1 -0
- package/dist/commands/migration-new.d.mts +8 -0
- package/dist/commands/migration-new.d.mts.map +1 -0
- package/dist/commands/migration-new.mjs +152 -0
- package/dist/commands/migration-new.mjs.map +1 -0
- package/dist/commands/migration-plan.d.mts +47 -0
- package/dist/commands/migration-plan.d.mts.map +1 -0
- package/dist/commands/migration-plan.mjs +313 -0
- package/dist/commands/migration-plan.mjs.map +1 -0
- package/dist/commands/migration-ref.d.mts +43 -0
- package/dist/commands/migration-ref.d.mts.map +1 -0
- package/dist/commands/migration-ref.mjs +195 -0
- package/dist/commands/migration-ref.mjs.map +1 -0
- package/dist/commands/migration-show.d.mts +28 -0
- package/dist/commands/migration-show.d.mts.map +1 -0
- package/dist/commands/migration-show.mjs +140 -0
- package/dist/commands/migration-show.mjs.map +1 -0
- package/dist/commands/migration-status.d.mts +86 -0
- package/dist/commands/migration-status.d.mts.map +1 -0
- package/dist/commands/migration-status.mjs +9 -0
- package/dist/commands/migration-verify.d.mts +16 -0
- package/dist/commands/migration-verify.d.mts.map +1 -0
- package/dist/commands/migration-verify.mjs +110 -0
- package/dist/commands/migration-verify.mjs.map +1 -0
- package/dist/config-loader-C4VXKl8f.mjs +43 -0
- package/dist/config-loader-C4VXKl8f.mjs.map +1 -0
- package/dist/{config-loader.d.ts → config-loader.d.mts} +8 -3
- package/dist/config-loader.d.mts.map +1 -0
- package/dist/config-loader.mjs +3 -0
- package/dist/contract-emit-D2wDXfyo.mjs +191 -0
- package/dist/contract-emit-D2wDXfyo.mjs.map +1 -0
- package/dist/contract-emit-Zm_sd1wQ.mjs +112 -0
- package/dist/contract-emit-Zm_sd1wQ.mjs.map +1 -0
- package/dist/contract-emit-kN-IkKTE.mjs +6 -0
- package/dist/contract-enrichment-CGW6mm-E.mjs +79 -0
- package/dist/contract-enrichment-CGW6mm-E.mjs.map +1 -0
- package/dist/contract-infer-DozZT511.mjs +90 -0
- package/dist/contract-infer-DozZT511.mjs.map +1 -0
- package/dist/exports/config-types.d.mts +2 -0
- package/dist/exports/config-types.mjs +3 -0
- package/dist/exports/control-api.d.mts +624 -0
- package/dist/exports/control-api.d.mts.map +1 -0
- package/dist/exports/control-api.mjs +8 -0
- package/dist/{load-ts-contract.d.ts → exports/index.d.mts} +12 -7
- package/dist/exports/index.d.mts.map +1 -0
- package/dist/exports/index.mjs +142 -0
- package/dist/exports/index.mjs.map +1 -0
- package/dist/extract-operation-statements-DZUJNmL3.mjs +13 -0
- package/dist/extract-operation-statements-DZUJNmL3.mjs.map +1 -0
- package/dist/extract-sql-ddl-DDMX-9mz.mjs +26 -0
- package/dist/extract-sql-ddl-DDMX-9mz.mjs.map +1 -0
- package/dist/framework-components-BAsliT4V.mjs +59 -0
- package/dist/framework-components-BAsliT4V.mjs.map +1 -0
- package/dist/init-6Pvm_esG.mjs +430 -0
- package/dist/init-6Pvm_esG.mjs.map +1 -0
- package/dist/inspect-live-schema-BYnhztxZ.mjs +91 -0
- package/dist/inspect-live-schema-BYnhztxZ.mjs.map +1 -0
- package/dist/migration-command-scaffold-CntCcntR.mjs +105 -0
- package/dist/migration-command-scaffold-CntCcntR.mjs.map +1 -0
- package/dist/migration-status-CJANY4yr.mjs +1583 -0
- package/dist/migration-status-CJANY4yr.mjs.map +1 -0
- package/dist/migrations-DTZBYXm1.mjs +173 -0
- package/dist/migrations-DTZBYXm1.mjs.map +1 -0
- package/dist/progress-adapter-B-YvmcDu.mjs +43 -0
- package/dist/progress-adapter-B-YvmcDu.mjs.map +1 -0
- package/dist/quick-reference-mongo.md +93 -0
- package/dist/quick-reference-postgres.md +91 -0
- package/dist/result-handler-oK_vA-Fn.mjs +697 -0
- package/dist/result-handler-oK_vA-Fn.mjs.map +1 -0
- package/dist/terminal-ui-C5k88MmW.mjs +274 -0
- package/dist/terminal-ui-C5k88MmW.mjs.map +1 -0
- package/dist/validate-contract-deps-esa-VQ0h.mjs +37 -0
- package/dist/validate-contract-deps-esa-VQ0h.mjs.map +1 -0
- package/dist/verify-DlFQ2FOw.mjs +385 -0
- package/dist/verify-DlFQ2FOw.mjs.map +1 -0
- package/package.json +87 -40
- package/src/cli.ts +118 -58
- package/src/commands/contract-emit.ts +101 -78
- package/src/commands/contract-infer-paths.ts +32 -0
- package/src/commands/contract-infer.ts +143 -0
- package/src/commands/db-init.ts +97 -219
- package/src/commands/db-schema.ts +77 -0
- package/src/commands/db-sign.ts +46 -73
- package/src/commands/db-update.ts +236 -0
- package/src/commands/db-verify.ts +409 -119
- package/src/commands/init/detect-package-manager.ts +47 -0
- package/src/commands/init/index.ts +21 -0
- package/src/commands/init/init.ts +203 -0
- package/src/commands/init/templates/agent-skill-mongo.md +106 -0
- package/src/commands/init/templates/agent-skill-postgres.md +106 -0
- package/src/commands/init/templates/agent-skill.ts +19 -0
- package/src/commands/init/templates/code-templates.ts +168 -0
- package/src/commands/init/templates/quick-reference-mongo.md +93 -0
- package/src/commands/init/templates/quick-reference-postgres.md +91 -0
- package/src/commands/init/templates/quick-reference.ts +19 -0
- package/src/commands/init/templates/render.ts +20 -0
- package/src/commands/init/templates/tsconfig.ts +35 -0
- package/src/commands/inspect-live-schema.ts +170 -0
- package/src/commands/migration-apply.ts +427 -0
- package/src/commands/migration-new.ts +260 -0
- package/src/commands/migration-plan.ts +519 -0
- package/src/commands/migration-ref.ts +305 -0
- package/src/commands/migration-show.ts +246 -0
- package/src/commands/migration-status.ts +864 -0
- package/src/commands/migration-verify.ts +180 -0
- package/src/config-loader.ts +13 -3
- package/src/control-api/client.ts +205 -183
- package/src/control-api/contract-enrichment.ts +119 -0
- package/src/control-api/errors.ts +9 -0
- package/src/control-api/operations/contract-emit.ts +181 -0
- package/src/control-api/operations/db-init.ts +53 -49
- package/src/control-api/operations/db-update.ts +220 -0
- package/src/control-api/operations/extract-operation-statements.ts +14 -0
- package/src/control-api/operations/extract-sql-ddl.ts +47 -0
- package/src/control-api/operations/migration-apply.ts +191 -0
- package/src/control-api/operations/migration-helpers.ts +49 -0
- package/src/control-api/types.ts +274 -52
- package/src/exports/config-types.ts +4 -3
- package/src/exports/control-api.ts +15 -5
- package/src/load-ts-contract.ts +30 -19
- package/src/utils/cli-errors.ts +14 -8
- package/src/utils/command-helpers.ts +302 -3
- package/src/utils/formatters/emit.ts +67 -0
- package/src/utils/formatters/errors.ts +82 -0
- package/src/utils/formatters/graph-migration-mapper.ts +240 -0
- package/src/utils/formatters/graph-render.ts +1323 -0
- package/src/utils/formatters/graph-types.ts +120 -0
- package/src/utils/formatters/help.ts +380 -0
- package/src/utils/formatters/helpers.ts +28 -0
- package/src/utils/formatters/migrations.ts +346 -0
- package/src/utils/formatters/styled.ts +212 -0
- package/src/utils/formatters/verify.ts +621 -0
- package/src/utils/framework-components.ts +13 -10
- package/src/utils/global-flags.ts +41 -23
- package/src/utils/migration-command-scaffold.ts +184 -0
- package/src/utils/migration-types.ts +12 -0
- package/src/utils/progress-adapter.ts +18 -29
- package/src/utils/result-handler.ts +12 -13
- package/src/utils/shutdown.ts +92 -0
- package/src/utils/suggest-command.ts +31 -0
- package/src/utils/terminal-ui.ts +276 -0
- package/src/utils/validate-contract-deps.ts +49 -0
- package/dist/chunk-AGOTG4L3.js +0 -965
- package/dist/chunk-AGOTG4L3.js.map +0 -1
- package/dist/chunk-HLLI4YL7.js +0 -180
- package/dist/chunk-HLLI4YL7.js.map +0 -1
- package/dist/chunk-HWYQOCAJ.js +0 -47
- package/dist/chunk-HWYQOCAJ.js.map +0 -1
- package/dist/chunk-VG2R7DGF.js +0 -735
- package/dist/chunk-VG2R7DGF.js.map +0 -1
- package/dist/cli.d.ts +0 -2
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/contract-emit.d.ts +0 -3
- package/dist/commands/contract-emit.d.ts.map +0 -1
- package/dist/commands/contract-emit.js +0 -10
- package/dist/commands/contract-emit.js.map +0 -1
- package/dist/commands/db-init.d.ts +0 -3
- package/dist/commands/db-init.d.ts.map +0 -1
- package/dist/commands/db-init.js +0 -257
- package/dist/commands/db-init.js.map +0 -1
- package/dist/commands/db-introspect.d.ts +0 -3
- package/dist/commands/db-introspect.d.ts.map +0 -1
- package/dist/commands/db-introspect.js +0 -155
- package/dist/commands/db-introspect.js.map +0 -1
- package/dist/commands/db-schema-verify.d.ts +0 -3
- package/dist/commands/db-schema-verify.d.ts.map +0 -1
- package/dist/commands/db-schema-verify.js +0 -171
- package/dist/commands/db-schema-verify.js.map +0 -1
- package/dist/commands/db-sign.d.ts +0 -3
- package/dist/commands/db-sign.d.ts.map +0 -1
- package/dist/commands/db-sign.js +0 -195
- package/dist/commands/db-sign.js.map +0 -1
- package/dist/commands/db-verify.d.ts +0 -3
- package/dist/commands/db-verify.d.ts.map +0 -1
- package/dist/commands/db-verify.js +0 -193
- package/dist/commands/db-verify.js.map +0 -1
- package/dist/config-loader.d.ts.map +0 -1
- package/dist/config-loader.js +0 -7
- package/dist/config-loader.js.map +0 -1
- package/dist/control-api/client.d.ts +0 -13
- package/dist/control-api/client.d.ts.map +0 -1
- package/dist/control-api/operations/db-init.d.ts +0 -29
- package/dist/control-api/operations/db-init.d.ts.map +0 -1
- package/dist/control-api/types.d.ts +0 -387
- package/dist/control-api/types.d.ts.map +0 -1
- package/dist/exports/config-types.d.ts +0 -3
- package/dist/exports/config-types.d.ts.map +0 -1
- package/dist/exports/config-types.js +0 -6
- package/dist/exports/config-types.js.map +0 -1
- package/dist/exports/control-api.d.ts +0 -13
- package/dist/exports/control-api.d.ts.map +0 -1
- package/dist/exports/control-api.js +0 -7
- package/dist/exports/control-api.js.map +0 -1
- package/dist/exports/index.d.ts +0 -4
- package/dist/exports/index.d.ts.map +0 -1
- package/dist/exports/index.js +0 -176
- package/dist/exports/index.js.map +0 -1
- package/dist/load-ts-contract.d.ts.map +0 -1
- package/dist/utils/cli-errors.d.ts +0 -7
- package/dist/utils/cli-errors.d.ts.map +0 -1
- package/dist/utils/command-helpers.d.ts +0 -12
- package/dist/utils/command-helpers.d.ts.map +0 -1
- package/dist/utils/framework-components.d.ts +0 -70
- package/dist/utils/framework-components.d.ts.map +0 -1
- package/dist/utils/global-flags.d.ts +0 -25
- package/dist/utils/global-flags.d.ts.map +0 -1
- package/dist/utils/output.d.ts +0 -142
- package/dist/utils/output.d.ts.map +0 -1
- package/dist/utils/progress-adapter.d.ts +0 -26
- package/dist/utils/progress-adapter.d.ts.map +0 -1
- package/dist/utils/result-handler.d.ts +0 -15
- package/dist/utils/result-handler.d.ts.map +0 -1
- package/src/commands/db-introspect.ts +0 -227
- package/src/commands/db-schema-verify.ts +0 -238
- package/src/utils/output.ts +0 -1471
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { setCommandDescriptions, setCommandExamples } from '../../utils/command-helpers';
|
|
3
|
+
|
|
4
|
+
export function createInitCommand(): Command {
|
|
5
|
+
const command = new Command('init');
|
|
6
|
+
setCommandDescriptions(
|
|
7
|
+
command,
|
|
8
|
+
'Initialize a new Prisma Next project',
|
|
9
|
+
'Scaffolds config, schema, and runtime files, installs dependencies,\n' +
|
|
10
|
+
'and emits the contract. Gets you from zero to typed queries in one step.',
|
|
11
|
+
);
|
|
12
|
+
setCommandExamples(command, ['prisma-next init', 'prisma-next init --no-install']);
|
|
13
|
+
command
|
|
14
|
+
.option('--no-install', 'Skip dependency installation and contract emission')
|
|
15
|
+
.action(async (options: { readonly install?: boolean }) => {
|
|
16
|
+
const { runInit } = await import('./init');
|
|
17
|
+
await runInit(process.cwd(), { noInstall: !options.install });
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return command;
|
|
21
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import * as clack from '@clack/prompts';
|
|
5
|
+
import { dirname, extname, isAbsolute, join, normalize } from 'pathe';
|
|
6
|
+
import { TerminalUI } from '../../utils/terminal-ui';
|
|
7
|
+
import {
|
|
8
|
+
detectPackageManager,
|
|
9
|
+
formatAddArgs,
|
|
10
|
+
formatAddDevArgs,
|
|
11
|
+
formatRunCommand,
|
|
12
|
+
hasProjectManifest,
|
|
13
|
+
} from './detect-package-manager';
|
|
14
|
+
import { agentSkillMd } from './templates/agent-skill';
|
|
15
|
+
import {
|
|
16
|
+
type AuthoringId,
|
|
17
|
+
configFile,
|
|
18
|
+
dbFile,
|
|
19
|
+
defaultSchemaPath,
|
|
20
|
+
starterSchema,
|
|
21
|
+
type TargetId,
|
|
22
|
+
targetPackageName,
|
|
23
|
+
} from './templates/code-templates';
|
|
24
|
+
import { quickReferenceMd } from './templates/quick-reference';
|
|
25
|
+
import { defaultTsConfig, mergeTsConfig } from './templates/tsconfig';
|
|
26
|
+
|
|
27
|
+
export interface InitOptions {
|
|
28
|
+
readonly noInstall?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface FileEntry {
|
|
32
|
+
readonly path: string;
|
|
33
|
+
readonly content: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function runInit(baseDir: string, options: InitOptions): Promise<void> {
|
|
37
|
+
const ui = new TerminalUI();
|
|
38
|
+
|
|
39
|
+
clack.intro('prisma-next init', { output: process.stderr });
|
|
40
|
+
|
|
41
|
+
if (!hasProjectManifest(baseDir)) {
|
|
42
|
+
ui.error(
|
|
43
|
+
'No package.json or deno.json found. Initialize your project first (e.g. npm init or deno init), then re-run prisma-next init.',
|
|
44
|
+
);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const pm = await detectPackageManager(baseDir);
|
|
49
|
+
const pkgRun = formatRunCommand(pm, 'prisma-next', '').trimEnd();
|
|
50
|
+
|
|
51
|
+
if (existsSync(join(baseDir, 'prisma-next.config.ts'))) {
|
|
52
|
+
const reinit = await clack.confirm({
|
|
53
|
+
message:
|
|
54
|
+
'This project is already initialized. Re-initialize? This will overwrite all generated files.',
|
|
55
|
+
initialValue: false,
|
|
56
|
+
output: process.stderr,
|
|
57
|
+
});
|
|
58
|
+
if (clack.isCancel(reinit) || !reinit) {
|
|
59
|
+
clack.cancel('Init cancelled.', { output: process.stderr });
|
|
60
|
+
process.exit(0);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const targetResult = await clack.select({
|
|
65
|
+
message: 'What database are you using?',
|
|
66
|
+
options: [
|
|
67
|
+
{ value: 'postgres' as TargetId, label: 'PostgreSQL' },
|
|
68
|
+
{ value: 'mongo' as TargetId, label: 'MongoDB' },
|
|
69
|
+
],
|
|
70
|
+
output: process.stderr,
|
|
71
|
+
});
|
|
72
|
+
if (clack.isCancel(targetResult)) {
|
|
73
|
+
clack.cancel('Init cancelled.', { output: process.stderr });
|
|
74
|
+
process.exit(0);
|
|
75
|
+
}
|
|
76
|
+
const target = targetResult as TargetId;
|
|
77
|
+
|
|
78
|
+
const authoringResult = await clack.select({
|
|
79
|
+
message: 'How do you want to write your schema?',
|
|
80
|
+
options: [
|
|
81
|
+
{ value: 'psl' as AuthoringId, label: 'Prisma Schema Language (.prisma)' },
|
|
82
|
+
{ value: 'typescript' as AuthoringId, label: 'TypeScript (.ts)' },
|
|
83
|
+
],
|
|
84
|
+
output: process.stderr,
|
|
85
|
+
});
|
|
86
|
+
if (clack.isCancel(authoringResult)) {
|
|
87
|
+
clack.cancel('Init cancelled.', { output: process.stderr });
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}
|
|
90
|
+
const authoring = authoringResult as AuthoringId;
|
|
91
|
+
|
|
92
|
+
const schemaPathResult = await clack.text({
|
|
93
|
+
message: 'Where should the schema file go?',
|
|
94
|
+
initialValue: defaultSchemaPath(authoring),
|
|
95
|
+
validate(value = '') {
|
|
96
|
+
const trimmed = value.trim();
|
|
97
|
+
if (trimmed.length === 0) return 'Path cannot be empty';
|
|
98
|
+
if (trimmed.endsWith('/') || trimmed.endsWith('\\'))
|
|
99
|
+
return 'Path must be a file, not a directory';
|
|
100
|
+
if (!extname(trimmed)) return 'Path must include a file extension (e.g. .prisma or .ts)';
|
|
101
|
+
return undefined;
|
|
102
|
+
},
|
|
103
|
+
output: process.stderr,
|
|
104
|
+
});
|
|
105
|
+
if (clack.isCancel(schemaPathResult)) {
|
|
106
|
+
clack.cancel('Init cancelled.', { output: process.stderr });
|
|
107
|
+
process.exit(0);
|
|
108
|
+
}
|
|
109
|
+
const schemaPath = normalize((schemaPathResult as string).trim());
|
|
110
|
+
|
|
111
|
+
const schemaDir = dirname(schemaPath);
|
|
112
|
+
const configPath = isAbsolute(schemaPath) ? schemaPath : `./${schemaPath}`;
|
|
113
|
+
|
|
114
|
+
const files: FileEntry[] = [
|
|
115
|
+
{ path: schemaPath, content: starterSchema(target, authoring) },
|
|
116
|
+
{ path: 'prisma-next.config.ts', content: configFile(target, configPath) },
|
|
117
|
+
{ path: join(schemaDir, 'db.ts'), content: dbFile(target) },
|
|
118
|
+
{ path: 'prisma-next.md', content: quickReferenceMd(target, schemaPath, pkgRun) },
|
|
119
|
+
{
|
|
120
|
+
path: '.agents/skills/prisma-next/SKILL.md',
|
|
121
|
+
content: agentSkillMd(target, schemaPath, pkgRun),
|
|
122
|
+
},
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
for (const file of files) {
|
|
126
|
+
const fullPath = join(baseDir, file.path);
|
|
127
|
+
mkdirSync(dirname(fullPath), { recursive: true });
|
|
128
|
+
writeFileSync(fullPath, file.content, 'utf-8');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const tsconfigPath = join(baseDir, 'tsconfig.json');
|
|
132
|
+
if (existsSync(tsconfigPath)) {
|
|
133
|
+
const existing = readFileSync(tsconfigPath, 'utf-8');
|
|
134
|
+
writeFileSync(tsconfigPath, mergeTsConfig(existing), 'utf-8');
|
|
135
|
+
ui.log('Updated tsconfig.json with required compiler options.');
|
|
136
|
+
} else {
|
|
137
|
+
writeFileSync(tsconfigPath, defaultTsConfig(), 'utf-8');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const emitCommand = formatRunCommand(pm, 'prisma-next', 'contract emit');
|
|
141
|
+
|
|
142
|
+
if (options.noInstall) {
|
|
143
|
+
const pkg = targetPackageName(target);
|
|
144
|
+
ui.note(
|
|
145
|
+
[
|
|
146
|
+
'Run the following commands to complete setup:',
|
|
147
|
+
'',
|
|
148
|
+
' 1. Install dependencies:',
|
|
149
|
+
` ${pm} ${formatAddArgs(pm, [pkg, 'dotenv']).join(' ')}`,
|
|
150
|
+
` ${pm} ${formatAddDevArgs(pm, ['@prisma-next/cli']).join(' ')}`,
|
|
151
|
+
'',
|
|
152
|
+
' 2. Emit the contract:',
|
|
153
|
+
` ${emitCommand}`,
|
|
154
|
+
].join('\n'),
|
|
155
|
+
'Manual steps',
|
|
156
|
+
);
|
|
157
|
+
} else {
|
|
158
|
+
const pkg = targetPackageName(target);
|
|
159
|
+
const spinner = ui.spinner();
|
|
160
|
+
let installSucceeded = false;
|
|
161
|
+
|
|
162
|
+
const exec = promisify(execFile);
|
|
163
|
+
|
|
164
|
+
spinner.start(`Installing ${pkg}, dotenv, and @prisma-next/cli...`);
|
|
165
|
+
try {
|
|
166
|
+
await exec(pm, formatAddArgs(pm, [pkg, 'dotenv']), { cwd: baseDir });
|
|
167
|
+
await exec(pm, formatAddDevArgs(pm, ['@prisma-next/cli']), { cwd: baseDir });
|
|
168
|
+
spinner.stop(`Installed ${pkg}, dotenv, and @prisma-next/cli`);
|
|
169
|
+
installSucceeded = true;
|
|
170
|
+
} catch (err) {
|
|
171
|
+
spinner.stop('Installation failed');
|
|
172
|
+
const stderr =
|
|
173
|
+
err instanceof Error && 'stderr' in err ? (err as { stderr: string }).stderr : '';
|
|
174
|
+
ui.warn(
|
|
175
|
+
[
|
|
176
|
+
'Could not install dependencies automatically.',
|
|
177
|
+
...(stderr ? [` ${stderr.trim()}`] : []),
|
|
178
|
+
'',
|
|
179
|
+
'Run manually:',
|
|
180
|
+
` ${pm} ${formatAddArgs(pm, [pkg, 'dotenv']).join(' ')}`,
|
|
181
|
+
` ${pm} ${formatAddDevArgs(pm, ['@prisma-next/cli']).join(' ')}`,
|
|
182
|
+
].join('\n'),
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (installSucceeded) {
|
|
187
|
+
spinner.start('Emitting contract...');
|
|
188
|
+
try {
|
|
189
|
+
const { executeContractEmit } = await import('../../control-api/operations/contract-emit');
|
|
190
|
+
const configFilePath = join(baseDir, 'prisma-next.config.ts');
|
|
191
|
+
await executeContractEmit({ configPath: configFilePath });
|
|
192
|
+
spinner.stop('Contract emitted');
|
|
193
|
+
} catch {
|
|
194
|
+
spinner.stop('Contract emission failed');
|
|
195
|
+
ui.warn(
|
|
196
|
+
['Could not emit contract automatically. Run manually:', ` ${emitCommand}`].join('\n'),
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
clack.outro('Done! Open prisma-next.md to get started.', { output: process.stderr });
|
|
203
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Prisma Next — project skill
|
|
2
|
+
|
|
3
|
+
This project uses **Prisma Next** with **MongoDB** via `@prisma-next/mongo`. Prisma Next lets the user define data models in a contract file and query them with a fully typed ORM.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
- **Contract**: `{{schemaPath}}` — the user's data models. Edit this to add or change models.
|
|
8
|
+
- **Config**: `prisma-next.config.ts` — tells the CLI where the contract is and how to connect to the database. Loads `.env` via `dotenv/config`.
|
|
9
|
+
- **Database client**: `{{schemaDir}}/db.ts` — `import { db } from '{{dbImportPath}}'`. This is the entry point for all queries.
|
|
10
|
+
- **Generated files** (do not edit by hand):
|
|
11
|
+
- `{{schemaDir}}/contract.json` — compiled contract, used at runtime
|
|
12
|
+
- `{{schemaDir}}/contract.d.ts` — TypeScript types for the contract, used for autocomplete and type checking
|
|
13
|
+
|
|
14
|
+
## Commands
|
|
15
|
+
|
|
16
|
+
- `{{pkgRun}} contract emit` — regenerate `contract.json` and `contract.d.ts` after changing the contract
|
|
17
|
+
- `{{pkgRun}} db init` — bootstrap a database to match the contract (creates collections, indexes, constraints). Additive only — won't drop existing structures.
|
|
18
|
+
- `{{pkgRun}} db update` — update the database to match the current contract. Prompts for confirmation on destructive changes. Use `--dry-run` to preview.
|
|
19
|
+
- `{{pkgRun}} migration plan` — create a new migration from contract changes (offline, no database needed). Use `--name <slug>` to name it.
|
|
20
|
+
- `{{pkgRun}} migration apply` — apply pending migrations to the database
|
|
21
|
+
- `{{pkgRun}} migration status` — show which migrations are applied and which are pending
|
|
22
|
+
- `{{pkgRun}} migration show <name>` — show details of a specific migration
|
|
23
|
+
|
|
24
|
+
## How to write queries
|
|
25
|
+
|
|
26
|
+
Always use the ORM (`db.orm`). Only fall back to `db.sql` if the user explicitly asks for raw queries or the ORM doesn't support the operation.
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { db } from '{{dbImportPath}}';
|
|
30
|
+
|
|
31
|
+
// Find one record
|
|
32
|
+
const user = await db.orm.User
|
|
33
|
+
.where(user => user.email.eq('alice@example.com'))
|
|
34
|
+
.first();
|
|
35
|
+
// Returns { id: ObjectId; email: string; ... } | null
|
|
36
|
+
|
|
37
|
+
// Find multiple records
|
|
38
|
+
const users = await db.orm.User
|
|
39
|
+
.select('id', 'email')
|
|
40
|
+
.take(10)
|
|
41
|
+
.all();
|
|
42
|
+
// Returns Array<{ id: ObjectId; email: string }>
|
|
43
|
+
|
|
44
|
+
// Filter, order, limit
|
|
45
|
+
const recentPosts = await db.orm.Post
|
|
46
|
+
.where(post => post.authorId.eq(userId))
|
|
47
|
+
.orderBy(post => post.createdAt.desc())
|
|
48
|
+
.select('id', 'title', 'createdAt')
|
|
49
|
+
.take(50)
|
|
50
|
+
.all();
|
|
51
|
+
|
|
52
|
+
// Include relations
|
|
53
|
+
const usersWithPosts = await db.orm.User
|
|
54
|
+
.select('id', 'email')
|
|
55
|
+
.include('posts', post =>
|
|
56
|
+
post.select('id', 'title').orderBy(p => p.createdAt.desc()).take(5)
|
|
57
|
+
)
|
|
58
|
+
.take(10)
|
|
59
|
+
.all();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Key ORM methods
|
|
63
|
+
|
|
64
|
+
- `.where(predicate)` — filter records. Predicate receives a model accessor with `.eq()`, `.neq()`, `.ilike()`, `.lt()`, `.gt()`, etc.
|
|
65
|
+
- `.select('field1', 'field2', ...)` — pick which fields to return
|
|
66
|
+
- `.orderBy(accessor => accessor.field.asc()` or `.desc())` — sort results
|
|
67
|
+
- `.take(n)` — limit number of results
|
|
68
|
+
- `.all()` — execute and return all matching records as an array
|
|
69
|
+
- `.first()` — execute and return the first matching record, or `null`
|
|
70
|
+
- `.first({ id: value })` — find a single record by primary key, or `null`
|
|
71
|
+
- `.include('relation', builder => ...)` — eager-load a relation
|
|
72
|
+
|
|
73
|
+
## Rules
|
|
74
|
+
|
|
75
|
+
- **Never hand-edit** `contract.json` or `contract.d.ts`. Always regenerate them with `contract emit`.
|
|
76
|
+
- **Always emit after contract changes.** When you modify `{{schemaPath}}`, run `{{pkgRun}} contract emit` before writing any code that depends on the new or changed models.
|
|
77
|
+
- **Don't restructure `db.ts`.** It's scaffolded by init and works as-is.
|
|
78
|
+
- **Use `db.orm` for queries**, not `db.sql`. The ORM is the primary query surface.
|
|
79
|
+
- **Connection string** is `DATABASE_URL` in `.env`. If the user reports connection errors, check this value and the `.env` file.
|
|
80
|
+
|
|
81
|
+
## Workflow for common tasks
|
|
82
|
+
|
|
83
|
+
**User wants to add a new model or field:**
|
|
84
|
+
1. Edit `{{schemaPath}}`
|
|
85
|
+
2. Run `{{pkgRun}} contract emit`
|
|
86
|
+
3. Write query code using `db.orm.ModelName`
|
|
87
|
+
|
|
88
|
+
**User wants to query data:**
|
|
89
|
+
1. Import `db` from `{{dbImportPath}}`
|
|
90
|
+
2. Use `db.orm.ModelName` with `.where()`, `.select()`, `.all()`, `.first()`, etc.
|
|
91
|
+
|
|
92
|
+
**User wants to set up or change the database connection:**
|
|
93
|
+
1. Edit `DATABASE_URL` in `.env`
|
|
94
|
+
2. The config file (`prisma-next.config.ts`) reads it automatically via `dotenv/config`
|
|
95
|
+
|
|
96
|
+
**User wants to set up the database for the first time:**
|
|
97
|
+
1. Run `{{pkgRun}} db init`
|
|
98
|
+
|
|
99
|
+
**User wants to update the database after changing the contract:**
|
|
100
|
+
1. Quick path: `{{pkgRun}} db update` — compares the database to the contract and applies changes directly
|
|
101
|
+
2. Migration path (for production workflows):
|
|
102
|
+
- `{{pkgRun}} migration plan --name describe-the-change` — creates a migration
|
|
103
|
+
- `{{pkgRun}} migration apply` — applies pending migrations
|
|
104
|
+
|
|
105
|
+
**User wants to check what migrations need to be applied:**
|
|
106
|
+
1. Run `{{pkgRun}} migration status`
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Prisma Next — project skill
|
|
2
|
+
|
|
3
|
+
This project uses **Prisma Next** with **PostgreSQL** via `@prisma-next/postgres`. Prisma Next lets the user define data models in a contract file and query them with a fully typed ORM.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
- **Contract**: `{{schemaPath}}` — the user's data models. Edit this to add or change models.
|
|
8
|
+
- **Config**: `prisma-next.config.ts` — tells the CLI where the contract is and how to connect to the database. Loads `.env` via `dotenv/config`.
|
|
9
|
+
- **Database client**: `{{schemaDir}}/db.ts` — `import { db } from '{{dbImportPath}}'`. This is the entry point for all queries.
|
|
10
|
+
- **Generated files** (do not edit by hand):
|
|
11
|
+
- `{{schemaDir}}/contract.json` — compiled contract, used at runtime
|
|
12
|
+
- `{{schemaDir}}/contract.d.ts` — TypeScript types for the contract, used for autocomplete and type checking
|
|
13
|
+
|
|
14
|
+
## Commands
|
|
15
|
+
|
|
16
|
+
- `{{pkgRun}} contract emit` — regenerate `contract.json` and `contract.d.ts` after changing the contract
|
|
17
|
+
- `{{pkgRun}} db init` — bootstrap a database to match the contract (creates tables, indexes, constraints). Additive only — won't drop existing structures.
|
|
18
|
+
- `{{pkgRun}} db update` — update the database to match the current contract. Prompts for confirmation on destructive changes. Use `--dry-run` to preview.
|
|
19
|
+
- `{{pkgRun}} migration plan` — create a new migration from contract changes (offline, no database needed). Use `--name <slug>` to name it.
|
|
20
|
+
- `{{pkgRun}} migration apply` — apply pending migrations to the database
|
|
21
|
+
- `{{pkgRun}} migration status` — show which migrations are applied and which are pending
|
|
22
|
+
- `{{pkgRun}} migration show <name>` — show details of a specific migration
|
|
23
|
+
|
|
24
|
+
## How to write queries
|
|
25
|
+
|
|
26
|
+
Always use the ORM (`db.orm`). Only fall back to `db.sql` if the user explicitly asks for raw SQL or the ORM doesn't support the operation.
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { db } from '{{dbImportPath}}';
|
|
30
|
+
|
|
31
|
+
// Find one record
|
|
32
|
+
const user = await db.orm.User
|
|
33
|
+
.where(user => user.email.eq('alice@example.com'))
|
|
34
|
+
.first();
|
|
35
|
+
// Returns { id: number; email: string; ... } | null
|
|
36
|
+
|
|
37
|
+
// Find multiple records
|
|
38
|
+
const users = await db.orm.User
|
|
39
|
+
.select('id', 'email')
|
|
40
|
+
.take(10)
|
|
41
|
+
.all();
|
|
42
|
+
// Returns Array<{ id: number; email: string }>
|
|
43
|
+
|
|
44
|
+
// Filter, order, limit
|
|
45
|
+
const recentPosts = await db.orm.Post
|
|
46
|
+
.where(post => post.authorId.eq(userId))
|
|
47
|
+
.orderBy(post => post.createdAt.desc())
|
|
48
|
+
.select('id', 'title', 'createdAt')
|
|
49
|
+
.take(50)
|
|
50
|
+
.all();
|
|
51
|
+
|
|
52
|
+
// Include relations
|
|
53
|
+
const usersWithPosts = await db.orm.User
|
|
54
|
+
.select('id', 'email')
|
|
55
|
+
.include('posts', post =>
|
|
56
|
+
post.select('id', 'title').orderBy(p => p.createdAt.desc()).take(5)
|
|
57
|
+
)
|
|
58
|
+
.take(10)
|
|
59
|
+
.all();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Key ORM methods
|
|
63
|
+
|
|
64
|
+
- `.where(predicate)` — filter records. Predicate receives a model accessor with `.eq()`, `.neq()`, `.ilike()`, `.lt()`, `.gt()`, etc.
|
|
65
|
+
- `.select('field1', 'field2', ...)` — pick which fields to return
|
|
66
|
+
- `.orderBy(accessor => accessor.field.asc()` or `.desc())` — sort results
|
|
67
|
+
- `.take(n)` — limit number of results
|
|
68
|
+
- `.all()` — execute and return all matching records as an array
|
|
69
|
+
- `.first()` — execute and return the first matching record, or `null`
|
|
70
|
+
- `.first({ id: value })` — find a single record by primary key, or `null`
|
|
71
|
+
- `.include('relation', builder => ...)` — eager-load a relation
|
|
72
|
+
|
|
73
|
+
## Rules
|
|
74
|
+
|
|
75
|
+
- **Never hand-edit** `contract.json` or `contract.d.ts`. Always regenerate them with `contract emit`.
|
|
76
|
+
- **Always emit after contract changes.** When you modify `{{schemaPath}}`, run `{{pkgRun}} contract emit` before writing any code that depends on the new or changed models.
|
|
77
|
+
- **Don't restructure `db.ts`.** It's scaffolded by init and works as-is.
|
|
78
|
+
- **Use `db.orm` for queries**, not `db.sql`. The ORM is the primary query surface.
|
|
79
|
+
- **Connection string** is `DATABASE_URL` in `.env`. If the user reports connection errors, check this value and the `.env` file.
|
|
80
|
+
|
|
81
|
+
## Workflow for common tasks
|
|
82
|
+
|
|
83
|
+
**User wants to add a new model or field:**
|
|
84
|
+
1. Edit `{{schemaPath}}`
|
|
85
|
+
2. Run `{{pkgRun}} contract emit`
|
|
86
|
+
3. Write query code using `db.orm.ModelName`
|
|
87
|
+
|
|
88
|
+
**User wants to query data:**
|
|
89
|
+
1. Import `db` from `{{dbImportPath}}`
|
|
90
|
+
2. Use `db.orm.ModelName` with `.where()`, `.select()`, `.all()`, `.first()`, etc.
|
|
91
|
+
|
|
92
|
+
**User wants to set up or change the database connection:**
|
|
93
|
+
1. Edit `DATABASE_URL` in `.env`
|
|
94
|
+
2. The config file (`prisma-next.config.ts`) reads it automatically via `dotenv/config`
|
|
95
|
+
|
|
96
|
+
**User wants to set up the database for the first time:**
|
|
97
|
+
1. Run `{{pkgRun}} db init`
|
|
98
|
+
|
|
99
|
+
**User wants to update the database after changing the contract:**
|
|
100
|
+
1. Quick path: `{{pkgRun}} db update` — compares the database to the contract and applies changes directly
|
|
101
|
+
2. Migration path (for production workflows):
|
|
102
|
+
- `{{pkgRun}} migration plan --name describe-the-change` — creates a migration
|
|
103
|
+
- `{{pkgRun}} migration apply` — applies pending migrations
|
|
104
|
+
|
|
105
|
+
**User wants to check what migrations need to be applied:**
|
|
106
|
+
1. Run `{{pkgRun}} migration status`
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { dirname } from 'pathe';
|
|
2
|
+
import type { TargetId } from './code-templates';
|
|
3
|
+
import { renderTemplate } from './render';
|
|
4
|
+
|
|
5
|
+
export const variables = ['schemaPath', 'schemaDir', 'dbImportPath', 'pkgRun'] as const;
|
|
6
|
+
|
|
7
|
+
type TemplateVars = Record<(typeof variables)[number], string>;
|
|
8
|
+
|
|
9
|
+
export function agentSkillMd(target: TargetId, schemaPath: string, pkgRun: string): string {
|
|
10
|
+
const schemaDir = dirname(schemaPath);
|
|
11
|
+
const vars: TemplateVars = {
|
|
12
|
+
schemaPath,
|
|
13
|
+
schemaDir,
|
|
14
|
+
dbImportPath: `./${schemaDir}/db`,
|
|
15
|
+
pkgRun,
|
|
16
|
+
};
|
|
17
|
+
const templateFile = `agent-skill-${target}.md`;
|
|
18
|
+
return renderTemplate(templateFile, variables, vars);
|
|
19
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
export type TargetId = 'postgres' | 'mongo';
|
|
2
|
+
export type AuthoringId = 'psl' | 'typescript';
|
|
3
|
+
|
|
4
|
+
export function targetPackageName(target: TargetId): string {
|
|
5
|
+
return target === 'postgres' ? '@prisma-next/postgres' : '@prisma-next/mongo';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function targetLabel(target: TargetId): string {
|
|
9
|
+
return target === 'postgres' ? 'PostgreSQL' : 'MongoDB';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function defaultSchemaPath(authoring: AuthoringId): string {
|
|
13
|
+
if (authoring === 'typescript') {
|
|
14
|
+
return 'prisma/contract.ts';
|
|
15
|
+
}
|
|
16
|
+
return 'prisma/contract.prisma';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function starterSchema(target: TargetId, authoring: AuthoringId): string {
|
|
20
|
+
if (authoring === 'typescript') {
|
|
21
|
+
return target === 'mongo' ? starterSchemaTsMongo() : starterSchemaTsPostgres();
|
|
22
|
+
}
|
|
23
|
+
return target === 'mongo' ? starterSchemaPslMongo() : starterSchemaPslPostgres();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function starterSchemaPslPostgres(): string {
|
|
27
|
+
return `model User {
|
|
28
|
+
id Int @id @default(autoincrement())
|
|
29
|
+
email String @unique
|
|
30
|
+
name String?
|
|
31
|
+
posts Post[]
|
|
32
|
+
createdAt DateTime @default(now())
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
model Post {
|
|
36
|
+
id Int @id @default(autoincrement())
|
|
37
|
+
title String
|
|
38
|
+
content String?
|
|
39
|
+
author User @relation(fields: [authorId], references: [id])
|
|
40
|
+
authorId Int
|
|
41
|
+
createdAt DateTime @default(now())
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function starterSchemaPslMongo(): string {
|
|
47
|
+
return `model User {
|
|
48
|
+
id ObjectId @id @map("_id")
|
|
49
|
+
email String @unique
|
|
50
|
+
name String?
|
|
51
|
+
posts Post[]
|
|
52
|
+
@@map("users")
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
model Post {
|
|
56
|
+
id ObjectId @id @map("_id")
|
|
57
|
+
title String
|
|
58
|
+
content String?
|
|
59
|
+
author User @relation(fields: [authorId], references: [id])
|
|
60
|
+
authorId ObjectId
|
|
61
|
+
@@map("posts")
|
|
62
|
+
}
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function starterSchemaTsPostgres(): string {
|
|
67
|
+
return `import sqlFamily from '@prisma-next/family-sql/pack';
|
|
68
|
+
import { defineContract } from '@prisma-next/sql-contract-ts/contract-builder';
|
|
69
|
+
import postgresPack from '@prisma-next/target-postgres/pack';
|
|
70
|
+
|
|
71
|
+
export const contract = defineContract(
|
|
72
|
+
{ family: sqlFamily, target: postgresPack },
|
|
73
|
+
({ field, model, rel }) => ({
|
|
74
|
+
models: {
|
|
75
|
+
User: model('User', {
|
|
76
|
+
fields: {
|
|
77
|
+
id: field.id.uuidv7(),
|
|
78
|
+
email: field.text().unique(),
|
|
79
|
+
name: field.text().optional(),
|
|
80
|
+
createdAt: field.createdAt(),
|
|
81
|
+
},
|
|
82
|
+
}).relations({
|
|
83
|
+
posts: rel.hasMany('Post', { by: 'authorId' }),
|
|
84
|
+
}),
|
|
85
|
+
|
|
86
|
+
Post: model('Post', {
|
|
87
|
+
fields: {
|
|
88
|
+
id: field.id.uuidv7(),
|
|
89
|
+
title: field.text(),
|
|
90
|
+
content: field.text().optional(),
|
|
91
|
+
authorId: field.uuid(),
|
|
92
|
+
createdAt: field.createdAt(),
|
|
93
|
+
},
|
|
94
|
+
}).relations({
|
|
95
|
+
author: rel.belongsTo('User', { from: 'authorId', to: 'id' }),
|
|
96
|
+
}),
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function starterSchemaTsMongo(): string {
|
|
104
|
+
return `import mongoFamily from '@prisma-next/family-mongo/pack';
|
|
105
|
+
import { defineContract, field, model, rel } from '@prisma-next/mongo-contract-ts/contract-builder';
|
|
106
|
+
import mongoTarget from '@prisma-next/target-mongo/pack';
|
|
107
|
+
|
|
108
|
+
const User = model('User', {
|
|
109
|
+
collection: 'users',
|
|
110
|
+
fields: {
|
|
111
|
+
_id: field.objectId(),
|
|
112
|
+
email: field.string(),
|
|
113
|
+
name: field.string().optional(),
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const Post = model('Post', {
|
|
118
|
+
collection: 'posts',
|
|
119
|
+
fields: {
|
|
120
|
+
_id: field.objectId(),
|
|
121
|
+
title: field.string(),
|
|
122
|
+
content: field.string().optional(),
|
|
123
|
+
authorId: field.objectId(),
|
|
124
|
+
},
|
|
125
|
+
relations: {
|
|
126
|
+
author: rel.belongsTo(User, { from: 'authorId', to: User.ref('_id') }),
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
export const contract = defineContract({
|
|
131
|
+
family: mongoFamily,
|
|
132
|
+
target: mongoTarget,
|
|
133
|
+
models: { User, Post },
|
|
134
|
+
});
|
|
135
|
+
`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function configFile(target: TargetId, contractPath: string): string {
|
|
139
|
+
const pkg = targetPackageName(target);
|
|
140
|
+
return `import 'dotenv/config';
|
|
141
|
+
import { defineConfig } from '${pkg}/config';
|
|
142
|
+
|
|
143
|
+
export default defineConfig({
|
|
144
|
+
contract: ${JSON.stringify(contractPath)},
|
|
145
|
+
db: {
|
|
146
|
+
connection: process.env['DATABASE_URL']!,
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function dbFile(target: TargetId): string {
|
|
153
|
+
if (target === 'postgres') {
|
|
154
|
+
return `import postgres from '@prisma-next/postgres/runtime';
|
|
155
|
+
import type { Contract } from './contract.d';
|
|
156
|
+
import contractJson from './contract.json' with { type: 'json' };
|
|
157
|
+
|
|
158
|
+
export const db = postgres<Contract>({ contractJson });
|
|
159
|
+
`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return `import mongo from '@prisma-next/mongo/runtime';
|
|
163
|
+
import type { Contract } from './contract.d';
|
|
164
|
+
import contractJson from './contract.json' with { type: 'json' };
|
|
165
|
+
|
|
166
|
+
export const db = mongo<Contract>({ contractJson });
|
|
167
|
+
`;
|
|
168
|
+
}
|