@prisma/orm-mongo 8.0.0-rc.4-dev.17 → 8.0.0-rc.5-dev.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/package.json +11 -10
- package/skills/prisma-8/SKILL.md +84 -0
- package/skills/prisma-8/references/build.md +142 -0
- package/skills/prisma-8/references/contract.md +417 -0
- package/skills/prisma-8/references/debug.md +141 -0
- package/skills/prisma-8/references/feedback.md +251 -0
- package/skills/prisma-8/references/migration-review.md +224 -0
- package/skills/prisma-8/references/migrations.md +519 -0
- package/skills/prisma-8/references/queries-mongo.md +236 -0
- package/skills/prisma-8/references/queries-postgres.md +415 -0
- package/skills/prisma-8/references/queries.md +168 -0
- package/skills/prisma-8/references/quickstart.md +326 -0
- package/skills/prisma-8/references/runtime.md +344 -0
- package/skills/prisma-8/references/supabase.md +244 -0
- package/skills/prisma-8/references/upgrade-app.md +101 -0
- package/skills/prisma-8/references/upgrade-extension.md +105 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.10-to-0.11/instructions.md +56 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/instructions.md +381 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-closed-mongo-contracts.ts +202 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts +201 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts +198 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts +340 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/instructions.md +339 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/re-emit-mti-variant-link-columns.ts +229 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/instructions.md +543 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts +290 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/uuid-preset-rename.ts +43 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.14-to-0.15/instructions.md +359 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.15-to-0.16/instructions.md +173 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/instructions.md +805 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts +382 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.17-to-8.0.0-rc.1/instructions.md +72 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md +8 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/instructions.md +36 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/strip-inline-contracts.ts +226 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/instructions.md +86 -0
- package/skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts +360 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md +588 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md +5 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md +158 -0
- package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md +42 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.10-to-0.11/instructions.md +276 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/instructions.md +738 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts +97 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts +223 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts +340 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.12-to-0.13/instructions.md +266 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/instructions.md +522 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts +290 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/uuid-preset-rename.ts +43 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.14-to-0.15/instructions.md +803 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.15-to-0.16/instructions.md +219 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/instructions.md +731 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts +382 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.17-to-8.0.0-rc.1/instructions.md +194 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md +8 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/instructions.md +57 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/strip-inline-contracts.ts +226 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/instructions.md +150 -0
- package/skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts +360 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md +746 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md +5 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md +137 -0
- package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md +129 -0
package/skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/re-emit-mti-variant-link-columns.ts
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-emits every contract whose MTI variant tables (PSL `@@base(Parent, "tag")`
|
|
3
|
+
* models that carry their own `@@map`) predate the base-PK link column.
|
|
4
|
+
*
|
|
5
|
+
* Starting at this release, a `@@base` variant stored in its own table
|
|
6
|
+
* materialises a base-PK link column in storage: the variant table gains an
|
|
7
|
+
* `id` column, a single-column primary key on it, and a cascading foreign key
|
|
8
|
+
* referencing the base table's primary key. Before the change, the variant
|
|
9
|
+
* table held only the variant-specific columns with no primary key.
|
|
10
|
+
*
|
|
11
|
+
* Detection: a contract is a candidate when its domain carries a model with a
|
|
12
|
+
* `base` reference (an MTI variant) whose matching storage table has no
|
|
13
|
+
* `primaryKey` — the pre-change shape. After re-emit the table gains its
|
|
14
|
+
* `id` PK + cascading FK and the contract's `storageHash` changes.
|
|
15
|
+
*
|
|
16
|
+
* Dispatch: walks the project root for `prisma.config.ts` directories,
|
|
17
|
+
* resolves each space's committed `contract.json`, and re-emits when a variant
|
|
18
|
+
* table still lacks its link column. Uses the nearest ancestor `package.json`
|
|
19
|
+
* `scripts.emit` when present; otherwise runs
|
|
20
|
+
* `prisma-next contract emit --config <path>`.
|
|
21
|
+
*
|
|
22
|
+
* Flags:
|
|
23
|
+
* --check dry-run; lists contract-spaces that still need re-emitting and
|
|
24
|
+
* exits 1 if any remain.
|
|
25
|
+
*/
|
|
26
|
+
import { execFile } from 'node:child_process';
|
|
27
|
+
import { access, readdir, readFile } from 'node:fs/promises';
|
|
28
|
+
import { dirname, join } from 'node:path';
|
|
29
|
+
import { promisify } from 'node:util';
|
|
30
|
+
|
|
31
|
+
const execFileAsync = promisify(execFile);
|
|
32
|
+
|
|
33
|
+
const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build']);
|
|
34
|
+
|
|
35
|
+
const dryRun = process.argv.includes('--check');
|
|
36
|
+
const projectRoot = process.cwd();
|
|
37
|
+
|
|
38
|
+
async function pathExists(path: string): Promise<boolean> {
|
|
39
|
+
try {
|
|
40
|
+
await access(path);
|
|
41
|
+
return true;
|
|
42
|
+
} catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function isJsonObject(value: unknown): value is Record<string, unknown> {
|
|
48
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function findPrismaNextConfigDirs(root: string): Promise<string[]> {
|
|
52
|
+
const out: string[] = [];
|
|
53
|
+
|
|
54
|
+
async function walk(dir: string): Promise<void> {
|
|
55
|
+
let entries: Awaited<ReturnType<typeof readdir>>;
|
|
56
|
+
try {
|
|
57
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
58
|
+
} catch {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
for (const entry of entries) {
|
|
62
|
+
if (entry.isDirectory()) {
|
|
63
|
+
if (SKIP_DIRS.has(entry.name)) continue;
|
|
64
|
+
await walk(join(dir, entry.name));
|
|
65
|
+
} else if (entry.isFile() && entry.name === 'prisma.config.ts') {
|
|
66
|
+
out.push(dir);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
await walk(root);
|
|
72
|
+
return out.sort();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function contractJsonCandidates(configDir: string): string[] {
|
|
76
|
+
return [
|
|
77
|
+
join(configDir, 'src', 'contract.json'),
|
|
78
|
+
join(configDir, 'src', 'prisma', 'contract.json'),
|
|
79
|
+
join(configDir, 'prisma', 'contract.json'),
|
|
80
|
+
join(configDir, 'contract.json'),
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function resolveContractJson(configDir: string): Promise<string | null> {
|
|
85
|
+
for (const candidate of contractJsonCandidates(configDir)) {
|
|
86
|
+
if (await pathExists(candidate)) return candidate;
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* A contract needs the MTI link-column migration when any of its domain models
|
|
93
|
+
* is an MTI variant (carries a `base` reference) whose matching storage table
|
|
94
|
+
* has no `primaryKey` — the pre-change shape that lacks the link column.
|
|
95
|
+
*/
|
|
96
|
+
function contractNeedsMtiLinkColumns(raw: string): boolean {
|
|
97
|
+
let parsed: unknown;
|
|
98
|
+
try {
|
|
99
|
+
parsed = JSON.parse(raw);
|
|
100
|
+
} catch {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
if (!isJsonObject(parsed)) return false;
|
|
104
|
+
|
|
105
|
+
const domain = parsed['domain'];
|
|
106
|
+
const storage = parsed['storage'];
|
|
107
|
+
if (!isJsonObject(domain) || !isJsonObject(storage)) return false;
|
|
108
|
+
|
|
109
|
+
const domainNamespaces = domain['namespaces'];
|
|
110
|
+
const storageNamespaces = storage['namespaces'];
|
|
111
|
+
if (!isJsonObject(domainNamespaces) || !isJsonObject(storageNamespaces)) return false;
|
|
112
|
+
|
|
113
|
+
for (const [nsKey, ns] of Object.entries(domainNamespaces)) {
|
|
114
|
+
if (!isJsonObject(ns)) continue;
|
|
115
|
+
const models = ns['models'];
|
|
116
|
+
if (!isJsonObject(models)) continue;
|
|
117
|
+
for (const model of Object.values(models)) {
|
|
118
|
+
if (!isJsonObject(model)) continue;
|
|
119
|
+
if (!isJsonObject(model['base'])) continue;
|
|
120
|
+
const variantStorage = model['storage'];
|
|
121
|
+
if (!isJsonObject(variantStorage)) continue;
|
|
122
|
+
const tableName = variantStorage['table'];
|
|
123
|
+
// The variant table's namespace defaults to the model's enclosing domain
|
|
124
|
+
// namespace when `storage.namespace` is absent.
|
|
125
|
+
const namespaceId =
|
|
126
|
+
typeof variantStorage['namespace'] === 'string' ? variantStorage['namespace'] : nsKey;
|
|
127
|
+
if (typeof tableName !== 'string') continue;
|
|
128
|
+
const storageNs = storageNamespaces[namespaceId];
|
|
129
|
+
if (!isJsonObject(storageNs)) continue;
|
|
130
|
+
const tables = storageNs['tables'];
|
|
131
|
+
if (!isJsonObject(tables)) continue;
|
|
132
|
+
const table = tables[tableName];
|
|
133
|
+
if (!isJsonObject(table)) continue;
|
|
134
|
+
if (table['primaryKey'] === undefined || table['primaryKey'] === null) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function packageJsonHasScript(dir: string, name: string): Promise<boolean> {
|
|
143
|
+
const pkgPath = join(dir, 'package.json');
|
|
144
|
+
if (!(await pathExists(pkgPath))) return false;
|
|
145
|
+
const raw = await readFile(pkgPath, 'utf-8');
|
|
146
|
+
try {
|
|
147
|
+
const parsed: unknown = JSON.parse(raw);
|
|
148
|
+
if (!isJsonObject(parsed)) return false;
|
|
149
|
+
const scripts = parsed['scripts'];
|
|
150
|
+
if (!isJsonObject(scripts)) return false;
|
|
151
|
+
const value = scripts[name];
|
|
152
|
+
return typeof value === 'string' && value.length > 0;
|
|
153
|
+
} catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function resolveEmitInvocation(configDir: string): Promise<{
|
|
159
|
+
readonly cwd: string;
|
|
160
|
+
readonly args: string[];
|
|
161
|
+
readonly key: string;
|
|
162
|
+
}> {
|
|
163
|
+
let dir = configDir;
|
|
164
|
+
while (dir.startsWith(projectRoot)) {
|
|
165
|
+
if (await packageJsonHasScript(dir, 'emit')) {
|
|
166
|
+
return { cwd: dir, args: ['emit'], key: `script:${dir}` };
|
|
167
|
+
}
|
|
168
|
+
const parent = dirname(dir);
|
|
169
|
+
if (parent === dir) break;
|
|
170
|
+
dir = parent;
|
|
171
|
+
}
|
|
172
|
+
const configPath = join(configDir, 'prisma.config.ts');
|
|
173
|
+
return {
|
|
174
|
+
cwd: projectRoot,
|
|
175
|
+
args: ['exec', 'prisma-next', 'contract', 'emit', '--config', configPath],
|
|
176
|
+
key: `config:${configPath}`,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function runEmit(configDir: string): Promise<void> {
|
|
181
|
+
const { cwd, args } = await resolveEmitInvocation(configDir);
|
|
182
|
+
await execFileAsync('pnpm', args, { cwd, env: process.env });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const configDirs = await findPrismaNextConfigDirs(projectRoot);
|
|
186
|
+
const emitKeys = new Set<string>();
|
|
187
|
+
const targets: Array<{ configDir: string; contractPath: string }> = [];
|
|
188
|
+
|
|
189
|
+
for (const configDir of configDirs) {
|
|
190
|
+
if (await packageJsonHasScript(configDir, 'build:contract-space')) continue;
|
|
191
|
+
const contractPath = await resolveContractJson(configDir);
|
|
192
|
+
if (contractPath === null) continue;
|
|
193
|
+
const raw = await readFile(contractPath, 'utf-8');
|
|
194
|
+
if (!contractNeedsMtiLinkColumns(raw)) continue;
|
|
195
|
+
const { key } = await resolveEmitInvocation(configDir);
|
|
196
|
+
if (emitKeys.has(key)) continue;
|
|
197
|
+
emitKeys.add(key);
|
|
198
|
+
targets.push({ configDir, contractPath });
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (targets.length === 0) {
|
|
202
|
+
console.error(`No MTI variant link-column migration candidates under ${projectRoot}.`);
|
|
203
|
+
process.exit(dryRun ? 0 : 1);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
let needsFix = 0;
|
|
207
|
+
|
|
208
|
+
for (const { configDir, contractPath } of targets) {
|
|
209
|
+
const rel = configDir.slice(projectRoot.length + 1) || '.';
|
|
210
|
+
const raw = await readFile(contractPath, 'utf-8');
|
|
211
|
+
if (!contractNeedsMtiLinkColumns(raw)) {
|
|
212
|
+
console.log(`OK ${rel}`);
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
needsFix += 1;
|
|
216
|
+
if (dryRun) {
|
|
217
|
+
console.log(`WOULD RE-EMIT ${rel}`);
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
console.log(`EMIT ${rel}`);
|
|
221
|
+
await runEmit(configDir);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
console.log();
|
|
225
|
+
console.log(
|
|
226
|
+
`${targets.length} contract-space(s): ${needsFix} ${dryRun ? 'needing re-emit' : 're-emitted'}.`,
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
if (dryRun && needsFix > 0) process.exit(1);
|