@prisma-next-idb/target-idb 0.1.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 +21 -0
- package/dist/apply-ddl-op-DZAoihY0.d.mts +129 -0
- package/dist/apply-ddl-op-DZAoihY0.d.mts.map +1 -0
- package/dist/apply-ddl-op-LP-l0o4O.mjs +232 -0
- package/dist/apply-ddl-op-LP-l0o4O.mjs.map +1 -0
- package/dist/control.d.mts +33 -0
- package/dist/control.d.mts.map +1 -0
- package/dist/control.mjs +44 -0
- package/dist/control.mjs.map +1 -0
- package/dist/descriptor-meta-CKLekROR.mjs +237 -0
- package/dist/descriptor-meta-CKLekROR.mjs.map +1 -0
- package/dist/idb-contract-types-DndrdtW0.d.mts +111 -0
- package/dist/idb-contract-types-DndrdtW0.d.mts.map +1 -0
- package/dist/migration-B43yOFXO.d.mts +227 -0
- package/dist/migration-B43yOFXO.d.mts.map +1 -0
- package/dist/migration-driver-4T8Hk1vu.mjs +334 -0
- package/dist/migration-driver-4T8Hk1vu.mjs.map +1 -0
- package/dist/migration.d.mts +3 -0
- package/dist/migration.mjs +89 -0
- package/dist/migration.mjs.map +1 -0
- package/dist/pack.d.mts +104 -0
- package/dist/pack.d.mts.map +1 -0
- package/dist/pack.mjs +7 -0
- package/dist/pack.mjs.map +1 -0
- package/dist/runtime.d.mts +20 -0
- package/dist/runtime.d.mts.map +1 -0
- package/dist/runtime.mjs +16 -0
- package/dist/runtime.mjs.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { a as createIndexOp, c as dropIndexOp, l as dropObjectStoreOp, o as createMarkerStoreOp, s as createObjectStoreOp } from "./apply-ddl-op-LP-l0o4O.mjs";
|
|
2
|
+
import { APP_SPACE_ID } from "@prisma-next/framework-components/control";
|
|
3
|
+
//#region src/core/schema-diff.ts
|
|
4
|
+
/**
|
|
5
|
+
* Returns `true` if the two index definitions differ in any property that
|
|
6
|
+
* IDB cannot alter in place. IDB does not support mutating an existing
|
|
7
|
+
* index's `keyPath`, `unique`, or `multiEntry` — the only path is
|
|
8
|
+
* drop-then-create. We normalise `unique` and `multiEntry` to `false` when
|
|
9
|
+
* absent so default-stripped contracts compare cleanly.
|
|
10
|
+
*/
|
|
11
|
+
function indexDefinitionsDiffer(a, b) {
|
|
12
|
+
return a.keyPath !== b.keyPath || (a.unique ?? false) !== (b.unique ?? false) || (a.multiEntry ?? false) !== (b.multiEntry ?? false);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Compute an ordered set of DDL operations to migrate from `from` to `to`.
|
|
16
|
+
*
|
|
17
|
+
* Safe execution order (important for a single `upgradeneeded` transaction):
|
|
18
|
+
* 1. Create new stores — additive
|
|
19
|
+
* 2. Create indexes on those new stores — additive
|
|
20
|
+
* 3. Create new indexes on existing stores — additive
|
|
21
|
+
* 4. Replace mutated indexes on surviving stores — destructive + additive
|
|
22
|
+
* (IDB cannot alter an existing index in place, so this is drop+create)
|
|
23
|
+
* 5. Drop removed indexes from surviving stores — destructive
|
|
24
|
+
* 6. Drop removed stores — destructive
|
|
25
|
+
*
|
|
26
|
+
* @param from - Current schema, or `null` for a fresh (empty) database.
|
|
27
|
+
* @param to - Desired target schema.
|
|
28
|
+
*
|
|
29
|
+
* **Note on store-level mutations.** IDB cannot alter an object store's
|
|
30
|
+
* `keyPath` or `autoIncrement` after creation. When those change between
|
|
31
|
+
* `from` and `to` for the same store name, this function throws — silent
|
|
32
|
+
* no-op is worse than an explicit error. The recovery path is a manual
|
|
33
|
+
* migration that drops the store and re-creates it (with whatever data
|
|
34
|
+
* preservation strategy the caller wants).
|
|
35
|
+
*/
|
|
36
|
+
function diffIdbSchema(from, to) {
|
|
37
|
+
const fromStores = from?.stores ?? {};
|
|
38
|
+
const toStores = to.stores;
|
|
39
|
+
const ops = [];
|
|
40
|
+
for (const [storeName, toDef] of Object.entries(toStores)) {
|
|
41
|
+
const fromDef = fromStores[storeName];
|
|
42
|
+
if (fromDef === void 0) continue;
|
|
43
|
+
if (fromDef.keyPath !== toDef.keyPath) throw new Error(`IDB does not support altering an existing store's keyPath. Store "${storeName}" keyPath changed from "${fromDef.keyPath}" to "${toDef.keyPath}". Author a manual migration that drops and re-creates the store with the desired data flow.`);
|
|
44
|
+
if ((fromDef.autoIncrement ?? false) !== (toDef.autoIncrement ?? false)) throw new Error(`IDB does not support altering an existing store's autoIncrement flag. Store "${storeName}" autoIncrement changed from ${fromDef.autoIncrement ?? false} to ${toDef.autoIncrement ?? false}. Author a manual migration that drops and re-creates the store.`);
|
|
45
|
+
}
|
|
46
|
+
for (const [storeName, toDef] of Object.entries(toStores)) {
|
|
47
|
+
if (storeName in fromStores) continue;
|
|
48
|
+
ops.push(createObjectStoreOp(storeName, toDef));
|
|
49
|
+
for (const [indexName, indexDef] of Object.entries(toDef.indexes ?? {})) ops.push(createIndexOp(storeName, indexName, indexDef));
|
|
50
|
+
}
|
|
51
|
+
for (const [storeName, toDef] of Object.entries(toStores)) {
|
|
52
|
+
const fromDef = fromStores[storeName];
|
|
53
|
+
if (fromDef === void 0) continue;
|
|
54
|
+
const fromIndexes = fromDef.indexes ?? {};
|
|
55
|
+
for (const [indexName, indexDef] of Object.entries(toDef.indexes ?? {})) if (!(indexName in fromIndexes)) ops.push(createIndexOp(storeName, indexName, indexDef));
|
|
56
|
+
}
|
|
57
|
+
for (const [storeName, toDef] of Object.entries(toStores)) {
|
|
58
|
+
const fromDef = fromStores[storeName];
|
|
59
|
+
if (fromDef === void 0) continue;
|
|
60
|
+
const fromIndexes = fromDef.indexes ?? {};
|
|
61
|
+
const toIndexes = toDef.indexes ?? {};
|
|
62
|
+
for (const [indexName, toIndexDef] of Object.entries(toIndexes)) {
|
|
63
|
+
const fromIndexDef = fromIndexes[indexName];
|
|
64
|
+
if (fromIndexDef === void 0) continue;
|
|
65
|
+
if (indexDefinitionsDiffer(fromIndexDef, toIndexDef)) {
|
|
66
|
+
ops.push(dropIndexOp(storeName, indexName));
|
|
67
|
+
ops.push(createIndexOp(storeName, indexName, toIndexDef));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
for (const [storeName, fromDef] of Object.entries(fromStores)) {
|
|
72
|
+
if (!(storeName in toStores)) continue;
|
|
73
|
+
const toIndexes = toStores[storeName]?.indexes ?? {};
|
|
74
|
+
for (const indexName of Object.keys(fromDef.indexes ?? {})) if (!(indexName in toIndexes)) ops.push(dropIndexOp(storeName, indexName));
|
|
75
|
+
}
|
|
76
|
+
for (const storeName of Object.keys(fromStores)) if (!(storeName in toStores)) ops.push(dropObjectStoreOp(storeName));
|
|
77
|
+
return ops;
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/core/migration-planner.ts
|
|
81
|
+
/**
|
|
82
|
+
* Extract an `IdbSchemaDiffInput` from a raw contract object.
|
|
83
|
+
*
|
|
84
|
+
* Returns `null` for a null contract (fresh database — no prior schema).
|
|
85
|
+
* The extraction is dynamic because contracts arrive as `unknown` / `Contract`
|
|
86
|
+
* at planner call sites.
|
|
87
|
+
*/
|
|
88
|
+
function contractToIdbSchema(contract) {
|
|
89
|
+
if (contract === null || typeof contract !== "object") return null;
|
|
90
|
+
const storage = contract["storage"];
|
|
91
|
+
if (storage === null || typeof storage !== "object") return null;
|
|
92
|
+
const stores = storage["stores"];
|
|
93
|
+
if (stores === null || typeof stores !== "object") return null;
|
|
94
|
+
return { stores };
|
|
95
|
+
}
|
|
96
|
+
function extractStorageHash(contract) {
|
|
97
|
+
if (contract === null || typeof contract !== "object") return "unknown";
|
|
98
|
+
const storage = contract["storage"];
|
|
99
|
+
if (storage === null || typeof storage !== "object") return "unknown";
|
|
100
|
+
const hash = storage["storageHash"];
|
|
101
|
+
return typeof hash === "string" ? hash : "unknown";
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Render a class-based `migration.ts` scaffold from a planner-derived ops
|
|
105
|
+
* list plus the `describe()` identity bookends. The output is the
|
|
106
|
+
* canonical authoring surface — identical in shape to vendor's Postgres
|
|
107
|
+
* `renderCallsToTypeScript` (shebang → imports → class → describe →
|
|
108
|
+
* operations → MigrationCLI.run).
|
|
109
|
+
*
|
|
110
|
+
* @internal
|
|
111
|
+
*/
|
|
112
|
+
function renderMigrationTs(input) {
|
|
113
|
+
const { fromHash, toHash, ops } = input;
|
|
114
|
+
const importList = [
|
|
115
|
+
"Migration",
|
|
116
|
+
"MigrationCLI",
|
|
117
|
+
...collectFactoryImports(ops)
|
|
118
|
+
].join(", ");
|
|
119
|
+
const operationsBlock = ops.length === 0 ? [
|
|
120
|
+
" return [",
|
|
121
|
+
" // Add IDB DDL operations here (createObjectStoreOp, createIndexOp, ...).",
|
|
122
|
+
" ];"
|
|
123
|
+
].join("\n") : [
|
|
124
|
+
" return [",
|
|
125
|
+
ops.map((op) => ` ${renderOpCall(op)},`).join("\n"),
|
|
126
|
+
" ];"
|
|
127
|
+
].join("\n");
|
|
128
|
+
return [
|
|
129
|
+
"#!/usr/bin/env -S npx tsx",
|
|
130
|
+
`import { ${importList} } from "@prisma-next-idb/target-idb/migration";`,
|
|
131
|
+
"",
|
|
132
|
+
"export default class M extends Migration {",
|
|
133
|
+
" override describe() {",
|
|
134
|
+
" return {",
|
|
135
|
+
` from: ${JSON.stringify(fromHash)},`,
|
|
136
|
+
` to: ${JSON.stringify(toHash)},`,
|
|
137
|
+
" };",
|
|
138
|
+
" }",
|
|
139
|
+
"",
|
|
140
|
+
" override get operations() {",
|
|
141
|
+
operationsBlock,
|
|
142
|
+
" }",
|
|
143
|
+
"}",
|
|
144
|
+
"",
|
|
145
|
+
"MigrationCLI.run(import.meta.url, M);",
|
|
146
|
+
""
|
|
147
|
+
].join("\n");
|
|
148
|
+
}
|
|
149
|
+
function collectFactoryImports(ops) {
|
|
150
|
+
const names = /* @__PURE__ */ new Set();
|
|
151
|
+
for (const op of ops) switch (op.kind) {
|
|
152
|
+
case "createObjectStore":
|
|
153
|
+
names.add("createObjectStoreOp");
|
|
154
|
+
break;
|
|
155
|
+
case "dropObjectStore":
|
|
156
|
+
names.add("dropObjectStoreOp");
|
|
157
|
+
break;
|
|
158
|
+
case "createIndex":
|
|
159
|
+
names.add("createIndexOp");
|
|
160
|
+
break;
|
|
161
|
+
case "dropIndex":
|
|
162
|
+
names.add("dropIndexOp");
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
return [...names].sort();
|
|
166
|
+
}
|
|
167
|
+
function renderOpCall(op) {
|
|
168
|
+
switch (op.kind) {
|
|
169
|
+
case "createObjectStore": {
|
|
170
|
+
const optsParts = [`keyPath: ${JSON.stringify(op.def.keyPath)}`];
|
|
171
|
+
if (op.def.autoIncrement !== void 0) optsParts.push(`autoIncrement: ${op.def.autoIncrement}`);
|
|
172
|
+
return `createObjectStoreOp(${JSON.stringify(op.storeName)}, { ${optsParts.join(", ")} })`;
|
|
173
|
+
}
|
|
174
|
+
case "dropObjectStore": return `dropObjectStoreOp(${JSON.stringify(op.storeName)})`;
|
|
175
|
+
case "createIndex": {
|
|
176
|
+
const unique = op.def.unique ?? false;
|
|
177
|
+
const optsParts = [`keyPath: ${JSON.stringify(op.def.keyPath)}`, `unique: ${unique}`];
|
|
178
|
+
if (op.def.multiEntry !== void 0) optsParts.push(`multiEntry: ${op.def.multiEntry}`);
|
|
179
|
+
return `createIndexOp(${JSON.stringify(op.storeName)}, ${JSON.stringify(op.indexName)}, { ${optsParts.join(", ")} })`;
|
|
180
|
+
}
|
|
181
|
+
case "dropIndex": return `dropIndexOp(${JSON.stringify(op.storeName)}, ${JSON.stringify(op.indexName)})`;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* IDB migration planner.
|
|
186
|
+
*
|
|
187
|
+
* `plan()` converts `fromContract` and `contract` into `IdbSchemaDiffInput`s,
|
|
188
|
+
* diffs them using {@link diffIdbSchema}, and returns an
|
|
189
|
+
* {@link IdbMigrationPlanWithAuthoring} that can be executed by
|
|
190
|
+
* {@link IdbMigrationRunner} or rendered to a TypeScript migration file via
|
|
191
|
+
* the class-based scaffold matching vendor's Postgres/Mongo authoring surface.
|
|
192
|
+
*
|
|
193
|
+
* The planner does NOT apply the policy — it always returns the full op set.
|
|
194
|
+
* Policy enforcement happens in the runner and in the browser-side
|
|
195
|
+
* auto-migrate path.
|
|
196
|
+
*/
|
|
197
|
+
var IdbMigrationPlanner = class {
|
|
198
|
+
plan(options) {
|
|
199
|
+
const { contract, fromContract } = options;
|
|
200
|
+
const fromSchema = contractToIdbSchema(fromContract);
|
|
201
|
+
const toSchema = contractToIdbSchema(contract);
|
|
202
|
+
if (toSchema === null) return {
|
|
203
|
+
kind: "failure",
|
|
204
|
+
conflicts: [{
|
|
205
|
+
kind: "invalidContract",
|
|
206
|
+
summary: "Could not extract IDB schema from contract. Expected contract.storage.stores to be a record of IdbStoreDefinition."
|
|
207
|
+
}]
|
|
208
|
+
};
|
|
209
|
+
const ops = diffIdbSchema(fromSchema, toSchema);
|
|
210
|
+
if (fromSchema === null) ops.unshift(createMarkerStoreOp());
|
|
211
|
+
const fromHash = fromContract !== null ? extractStorageHash(fromContract) : null;
|
|
212
|
+
const toHash = extractStorageHash(contract);
|
|
213
|
+
return {
|
|
214
|
+
kind: "success",
|
|
215
|
+
plan: {
|
|
216
|
+
targetId: "idb",
|
|
217
|
+
origin: fromHash !== null ? { storageHash: fromHash } : null,
|
|
218
|
+
destination: { storageHash: toHash },
|
|
219
|
+
operations: ops,
|
|
220
|
+
renderTypeScript() {
|
|
221
|
+
return renderMigrationTs({
|
|
222
|
+
fromHash,
|
|
223
|
+
toHash,
|
|
224
|
+
ops
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
emptyMigration(context, _spaceId) {
|
|
231
|
+
const { fromHash, toHash } = context;
|
|
232
|
+
return {
|
|
233
|
+
targetId: "idb",
|
|
234
|
+
origin: fromHash !== null ? { storageHash: fromHash } : null,
|
|
235
|
+
destination: { storageHash: toHash },
|
|
236
|
+
operations: [],
|
|
237
|
+
renderTypeScript() {
|
|
238
|
+
return renderMigrationTs({
|
|
239
|
+
fromHash,
|
|
240
|
+
toHash,
|
|
241
|
+
ops: []
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region src/core/migration-runner.ts
|
|
249
|
+
function makeNotOk(failure) {
|
|
250
|
+
return {
|
|
251
|
+
ok: false,
|
|
252
|
+
failure,
|
|
253
|
+
assertOk() {
|
|
254
|
+
throw new Error("assertOk called on NotOk result");
|
|
255
|
+
},
|
|
256
|
+
assertNotOk() {
|
|
257
|
+
return failure;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* IDB migration runner.
|
|
263
|
+
*
|
|
264
|
+
* `execute()` returns a structured refusal — IndexedDB only exists in the
|
|
265
|
+
* browser, so the framework's CLI control plane (`db init`, `db update`,
|
|
266
|
+
* `migration apply`) has no live database to talk to. The refusal points users
|
|
267
|
+
* at `prisma-next-idb preflight` for chain validation. The browser apply path
|
|
268
|
+
* goes through `openAndUpgrade()` directly via `auto-migrate.ts` in client-idb.
|
|
269
|
+
*
|
|
270
|
+
* v0.12.0 merged the former single-space `execute({plan, …})` and
|
|
271
|
+
* `executeAcrossSpaces({perSpaceOptions})` into one multi-space
|
|
272
|
+
* `execute({driver, perSpaceOptions})`; the `MultiSpaceCapableRunner` interface
|
|
273
|
+
* and `MultiSpace*` types were removed.
|
|
274
|
+
*/
|
|
275
|
+
var IdbMigrationRunner = class {
|
|
276
|
+
/**
|
|
277
|
+
* Apply one or more per-space migration plans. IDB cannot be applied from
|
|
278
|
+
* the CLI — `IndexedDB` is a browser API — so this always returns a
|
|
279
|
+
* structured refusal. Authoring stays in `prisma-next migration new` /
|
|
280
|
+
* `prisma-next migration plan`; validation lives in `prisma-next-idb
|
|
281
|
+
* preflight`; apply happens in the browser the next time the user opens the
|
|
282
|
+
* app via `createAutoMigratingIdbClient`.
|
|
283
|
+
*/
|
|
284
|
+
async execute(options) {
|
|
285
|
+
return makeNotOk({
|
|
286
|
+
code: "IDB-RUNNER-CLI-UNSUPPORTED",
|
|
287
|
+
summary: "IndexedDB migrations cannot be applied from the CLI.",
|
|
288
|
+
why: "IndexedDB only exists in the browser; the CLI runs in Node.js. There is no live database to apply ops against from this process. Migrations apply automatically the next time a user opens the app with createAutoMigratingIdbClient.",
|
|
289
|
+
meta: { fix: "Run `prisma-next-idb preflight` to validate the migration chain applies cleanly against a fake-indexeddb shadow before shipping." },
|
|
290
|
+
failingSpace: options.perSpaceOptions[0]?.space ?? APP_SPACE_ID
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
//#endregion
|
|
295
|
+
//#region src/core/migration-driver.ts
|
|
296
|
+
/**
|
|
297
|
+
* Factory descriptor for `IdbMigrationControlDriver`.
|
|
298
|
+
*
|
|
299
|
+
* Usage:
|
|
300
|
+
* ```ts
|
|
301
|
+
* const driver = IdbMigrationControlDriverDescriptor.create({
|
|
302
|
+
* dbName: "my-app",
|
|
303
|
+
* factory: window.indexedDB, // or new IDBFactory() from fake-indexeddb
|
|
304
|
+
* targetVersion: (manifest.idbVersion ?? 0) + 1,
|
|
305
|
+
* });
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
const IdbMigrationControlDriverDescriptor = {
|
|
309
|
+
version: "1.0.0",
|
|
310
|
+
create({ dbName, factory, targetVersion }) {
|
|
311
|
+
return {
|
|
312
|
+
familyId: "idb",
|
|
313
|
+
targetId: "idb",
|
|
314
|
+
dbName,
|
|
315
|
+
factory,
|
|
316
|
+
targetVersion,
|
|
317
|
+
async close() {}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* Narrows a `ControlDriverInstance<"idb","idb">` to `IdbMigrationControlDriver`.
|
|
323
|
+
*
|
|
324
|
+
* Throws a descriptive error if the driver was not created by
|
|
325
|
+
* {@link IdbMigrationControlDriverDescriptor}.
|
|
326
|
+
*/
|
|
327
|
+
function extractMigrationDriver(driver) {
|
|
328
|
+
if (!("dbName" in driver) || !("factory" in driver) || !("targetVersion" in driver)) throw new Error("IDB migration runner requires an IdbMigrationControlDriver. Create one with IdbMigrationControlDriverDescriptor.create({ dbName, factory, targetVersion }).");
|
|
329
|
+
return driver;
|
|
330
|
+
}
|
|
331
|
+
//#endregion
|
|
332
|
+
export { contractToIdbSchema as a, IdbMigrationPlanner as i, extractMigrationDriver as n, diffIdbSchema as o, IdbMigrationRunner as r, IdbMigrationControlDriverDescriptor as t };
|
|
333
|
+
|
|
334
|
+
//# sourceMappingURL=migration-driver-4T8Hk1vu.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-driver-4T8Hk1vu.mjs","names":[],"sources":["../src/core/schema-diff.ts","../src/core/migration-planner.ts","../src/core/migration-runner.ts","../src/core/migration-driver.ts"],"sourcesContent":["import type { IdbIndexDefinition, IdbStoreDefinition } from \"./idb-contract-types\";\nimport {\n createIndexOp,\n createObjectStoreOp,\n dropIndexOp,\n dropObjectStoreOp,\n type IdbDdlOp,\n} from \"./migration-factories\";\n\n/**\n * Minimal schema shape used for diffing.\n *\n * Structurally identical to `IdbSchemaIR` in `family-idb` — compatible by\n * TypeScript's structural typing. The contract's `storage.stores` map\n * (which uses `IdbStoreDefinition`) has the same shape as `IdbStoreIR`, so\n * both can be passed here without conversion.\n */\nexport type IdbSchemaDiffInput = {\n readonly stores: Record<string, IdbStoreDefinition>;\n};\n\n/**\n * Returns `true` if the two index definitions differ in any property that\n * IDB cannot alter in place. IDB does not support mutating an existing\n * index's `keyPath`, `unique`, or `multiEntry` — the only path is\n * drop-then-create. We normalise `unique` and `multiEntry` to `false` when\n * absent so default-stripped contracts compare cleanly.\n */\nfunction indexDefinitionsDiffer(a: IdbIndexDefinition, b: IdbIndexDefinition): boolean {\n return (\n a.keyPath !== b.keyPath ||\n (a.unique ?? false) !== (b.unique ?? false) ||\n (a.multiEntry ?? false) !== (b.multiEntry ?? false)\n );\n}\n\n/**\n * Compute an ordered set of DDL operations to migrate from `from` to `to`.\n *\n * Safe execution order (important for a single `upgradeneeded` transaction):\n * 1. Create new stores — additive\n * 2. Create indexes on those new stores — additive\n * 3. Create new indexes on existing stores — additive\n * 4. Replace mutated indexes on surviving stores — destructive + additive\n * (IDB cannot alter an existing index in place, so this is drop+create)\n * 5. Drop removed indexes from surviving stores — destructive\n * 6. Drop removed stores — destructive\n *\n * @param from - Current schema, or `null` for a fresh (empty) database.\n * @param to - Desired target schema.\n *\n * **Note on store-level mutations.** IDB cannot alter an object store's\n * `keyPath` or `autoIncrement` after creation. When those change between\n * `from` and `to` for the same store name, this function throws — silent\n * no-op is worse than an explicit error. The recovery path is a manual\n * migration that drops the store and re-creates it (with whatever data\n * preservation strategy the caller wants).\n */\nexport function diffIdbSchema(from: IdbSchemaDiffInput | null, to: IdbSchemaDiffInput): IdbDdlOp[] {\n const fromStores = from?.stores ?? {};\n const toStores = to.stores;\n const ops: IdbDdlOp[] = [];\n\n // 0. Store-level mutation guard. IDB has no in-place alter for store\n // structure — keyPath / autoIncrement changes are unrecoverable without\n // dropping the store. Fail loudly so the caller can author a manual\n // migration rather than silently misbehaving at runtime.\n for (const [storeName, toDef] of Object.entries(toStores)) {\n const fromDef = fromStores[storeName];\n if (fromDef === undefined) continue;\n if (fromDef.keyPath !== toDef.keyPath) {\n throw new Error(\n `IDB does not support altering an existing store's keyPath. ` +\n `Store \"${storeName}\" keyPath changed from \"${fromDef.keyPath}\" to \"${toDef.keyPath}\". ` +\n `Author a manual migration that drops and re-creates the store with the desired data flow.`\n );\n }\n if ((fromDef.autoIncrement ?? false) !== (toDef.autoIncrement ?? false)) {\n throw new Error(\n `IDB does not support altering an existing store's autoIncrement flag. ` +\n `Store \"${storeName}\" autoIncrement changed from ${fromDef.autoIncrement ?? false} ` +\n `to ${toDef.autoIncrement ?? false}. Author a manual migration that drops and re-creates the store.`\n );\n }\n }\n\n // 1 + 2. New stores and their indexes (additive)\n for (const [storeName, toDef] of Object.entries(toStores)) {\n if (storeName in fromStores) continue;\n ops.push(createObjectStoreOp(storeName, toDef));\n for (const [indexName, indexDef] of Object.entries(toDef.indexes ?? {})) {\n ops.push(createIndexOp(storeName, indexName, indexDef));\n }\n }\n\n // 3. New indexes on existing stores (additive)\n for (const [storeName, toDef] of Object.entries(toStores)) {\n const fromDef = fromStores[storeName];\n if (fromDef === undefined) continue; // new store — handled above\n const fromIndexes = fromDef.indexes ?? {};\n for (const [indexName, indexDef] of Object.entries(toDef.indexes ?? {})) {\n if (!(indexName in fromIndexes)) {\n ops.push(createIndexOp(storeName, indexName, indexDef));\n }\n }\n }\n\n // 4. Replace mutated indexes on surviving stores — drop then create.\n // Emit the drop first so the createIndex in the same upgradeneeded\n // transaction sees an available slot. Operation class is \"destructive\"\n // for the drop (policy may filter it) and \"additive\" for the create.\n for (const [storeName, toDef] of Object.entries(toStores)) {\n const fromDef = fromStores[storeName];\n if (fromDef === undefined) continue;\n const fromIndexes = fromDef.indexes ?? {};\n const toIndexes = toDef.indexes ?? {};\n for (const [indexName, toIndexDef] of Object.entries(toIndexes)) {\n const fromIndexDef = fromIndexes[indexName];\n if (fromIndexDef === undefined) continue; // new index — already covered by step 3\n if (indexDefinitionsDiffer(fromIndexDef, toIndexDef)) {\n ops.push(dropIndexOp(storeName, indexName));\n ops.push(createIndexOp(storeName, indexName, toIndexDef));\n }\n }\n }\n\n // 5. Drop removed indexes from surviving stores (destructive)\n for (const [storeName, fromDef] of Object.entries(fromStores)) {\n if (!(storeName in toStores)) continue; // whole store gone — handled below\n const toStoreDef = toStores[storeName];\n const toIndexes = toStoreDef?.indexes ?? {};\n for (const indexName of Object.keys(fromDef.indexes ?? {})) {\n if (!(indexName in toIndexes)) {\n ops.push(dropIndexOp(storeName, indexName));\n }\n }\n }\n\n // 6. Drop removed stores (destructive)\n for (const storeName of Object.keys(fromStores)) {\n if (!(storeName in toStores)) {\n ops.push(dropObjectStoreOp(storeName));\n }\n }\n\n return ops;\n}\n","import type { Contract } from \"@prisma-next/contract/types\";\nimport type { TargetBoundComponentDescriptor } from \"@prisma-next/framework-components/components\";\nimport type {\n MigrationOperationPolicy,\n MigrationPlanWithAuthoringSurface,\n MigrationPlanner,\n MigrationPlannerResult,\n MigrationScaffoldContext,\n} from \"@prisma-next/framework-components/control\";\nimport type { IdbStoreDefinition } from \"./idb-contract-types\";\nimport { createMarkerStoreOp, type IdbDdlOp } from \"./migration-factories\";\nimport type { IdbSchemaDiffInput } from \"./schema-diff\";\nimport { diffIdbSchema } from \"./schema-diff\";\n\n// ── Plan type ─────────────────────────────────────────────────────────────────\n\n/**\n * IDB-specific migration plan.\n *\n * Extends `MigrationPlanWithAuthoringSurface` by narrowing `operations` to\n * `readonly IdbDdlOp[]`. This is a valid covariant narrowing because\n * `IdbDdlOp extends MigrationPlanOperation`.\n *\n * The runner re-casts `plan.operations` back to `readonly IdbDdlOp[]` via\n * `isIdbDdlOp` validation.\n */\nexport interface IdbMigrationPlanWithAuthoring extends MigrationPlanWithAuthoringSurface {\n readonly operations: readonly IdbDdlOp[];\n}\n\n// ── Contract → schema IR extraction ──────────────────────────────────────────\n\n/**\n * Extract an `IdbSchemaDiffInput` from a raw contract object.\n *\n * Returns `null` for a null contract (fresh database — no prior schema).\n * The extraction is dynamic because contracts arrive as `unknown` / `Contract`\n * at planner call sites.\n */\nexport function contractToIdbSchema(contract: Contract | null | unknown): IdbSchemaDiffInput | null {\n if (contract === null || typeof contract !== \"object\") return null;\n const storage = (contract as Record<string, unknown>)[\"storage\"];\n if (storage === null || typeof storage !== \"object\") return null;\n const stores = (storage as Record<string, unknown>)[\"stores\"];\n if (stores === null || typeof stores !== \"object\") return null;\n return { stores: stores as Record<string, IdbStoreDefinition> };\n}\n\nfunction extractStorageHash(contract: Contract | null | unknown): string {\n if (contract === null || typeof contract !== \"object\") return \"unknown\";\n const storage = (contract as Record<string, unknown>)[\"storage\"];\n if (storage === null || typeof storage !== \"object\") return \"unknown\";\n const hash = (storage as Record<string, unknown>)[\"storageHash\"];\n return typeof hash === \"string\" ? hash : \"unknown\";\n}\n\n// ── TypeScript scaffold renderer ──────────────────────────────────────────────\n\n/**\n * Render a class-based `migration.ts` scaffold from a planner-derived ops\n * list plus the `describe()` identity bookends. The output is the\n * canonical authoring surface — identical in shape to vendor's Postgres\n * `renderCallsToTypeScript` (shebang → imports → class → describe →\n * operations → MigrationCLI.run).\n *\n * @internal\n */\nfunction renderMigrationTs(input: {\n readonly fromHash: string | null;\n readonly toHash: string;\n readonly ops: readonly IdbDdlOp[];\n}): string {\n const { fromHash, toHash, ops } = input;\n\n const factoryImports = collectFactoryImports(ops);\n const importList = [\"Migration\", \"MigrationCLI\", ...factoryImports].join(\", \");\n\n const operationsBlock =\n ops.length === 0\n ? [\n \" return [\",\n \" // Add IDB DDL operations here (createObjectStoreOp, createIndexOp, ...).\",\n \" ];\",\n ].join(\"\\n\")\n : [\" return [\", ops.map((op) => ` ${renderOpCall(op)},`).join(\"\\n\"), \" ];\"].join(\"\\n\");\n\n return [\n \"#!/usr/bin/env -S npx tsx\",\n `import { ${importList} } from \"@prisma-next-idb/target-idb/migration\";`,\n \"\",\n \"export default class M extends Migration {\",\n \" override describe() {\",\n \" return {\",\n ` from: ${JSON.stringify(fromHash)},`,\n ` to: ${JSON.stringify(toHash)},`,\n \" };\",\n \" }\",\n \"\",\n \" override get operations() {\",\n operationsBlock,\n \" }\",\n \"}\",\n \"\",\n \"MigrationCLI.run(import.meta.url, M);\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction collectFactoryImports(ops: readonly IdbDdlOp[]): string[] {\n const names = new Set<string>();\n for (const op of ops) {\n switch (op.kind) {\n case \"createObjectStore\":\n names.add(\"createObjectStoreOp\");\n break;\n case \"dropObjectStore\":\n names.add(\"dropObjectStoreOp\");\n break;\n case \"createIndex\":\n names.add(\"createIndexOp\");\n break;\n case \"dropIndex\":\n names.add(\"dropIndexOp\");\n break;\n }\n }\n return [...names].sort();\n}\n\nfunction renderOpCall(op: IdbDdlOp): string {\n switch (op.kind) {\n case \"createObjectStore\": {\n const optsParts = [`keyPath: ${JSON.stringify(op.def.keyPath)}`];\n if (op.def.autoIncrement !== undefined) {\n optsParts.push(`autoIncrement: ${op.def.autoIncrement}`);\n }\n return `createObjectStoreOp(${JSON.stringify(op.storeName)}, { ${optsParts.join(\", \")} })`;\n }\n case \"dropObjectStore\":\n return `dropObjectStoreOp(${JSON.stringify(op.storeName)})`;\n case \"createIndex\": {\n // IDB defaults `unique` to false when absent; the IR sometimes omits it\n // after canonicalisation. Default to false in the rendered TS so the\n // output is always valid.\n const unique = op.def.unique ?? false;\n const optsParts = [`keyPath: ${JSON.stringify(op.def.keyPath)}`, `unique: ${unique}`];\n if (op.def.multiEntry !== undefined) {\n optsParts.push(`multiEntry: ${op.def.multiEntry}`);\n }\n return `createIndexOp(${JSON.stringify(op.storeName)}, ${JSON.stringify(op.indexName)}, { ${optsParts.join(\", \")} })`;\n }\n case \"dropIndex\":\n return `dropIndexOp(${JSON.stringify(op.storeName)}, ${JSON.stringify(op.indexName)})`;\n }\n}\n\n// ── Planner ───────────────────────────────────────────────────────────────────\n\n/**\n * IDB migration planner.\n *\n * `plan()` converts `fromContract` and `contract` into `IdbSchemaDiffInput`s,\n * diffs them using {@link diffIdbSchema}, and returns an\n * {@link IdbMigrationPlanWithAuthoring} that can be executed by\n * {@link IdbMigrationRunner} or rendered to a TypeScript migration file via\n * the class-based scaffold matching vendor's Postgres/Mongo authoring surface.\n *\n * The planner does NOT apply the policy — it always returns the full op set.\n * Policy enforcement happens in the runner and in the browser-side\n * auto-migrate path.\n */\nexport class IdbMigrationPlanner implements MigrationPlanner<\"idb\", \"idb\"> {\n plan(options: {\n readonly contract: unknown;\n readonly schema: unknown;\n readonly policy: MigrationOperationPolicy;\n readonly fromContract: Contract | null;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<\"idb\", \"idb\">>;\n /**\n * Contract space this plan applies to.\n *\n * Stamped onto the produced plan so the runner keys the marker row\n * by the right space. IDB only has a single space (`\"app\"`), but\n * the parameter is required by the framework's\n * {@link MigrationPlanner} interface (added for multi-space support\n * in contract-spaces ADR 212). Ignored by the IDB planner — all\n * IDB schemas are single-space.\n */\n readonly spaceId: string;\n }): MigrationPlannerResult {\n const { contract, fromContract } = options;\n\n const fromSchema = contractToIdbSchema(fromContract);\n const toSchema = contractToIdbSchema(contract);\n\n if (toSchema === null) {\n return {\n kind: \"failure\",\n conflicts: [\n {\n kind: \"invalidContract\",\n summary:\n \"Could not extract IDB schema from contract. \" +\n \"Expected contract.storage.stores to be a record of IdbStoreDefinition.\",\n },\n ],\n };\n }\n\n const ops = diffIdbSchema(fromSchema, toSchema);\n\n // On first migration (fresh database), create the internal\n // _prisma_next_marker store so the runtime can verify the\n // contract marker before executing queries. Subsequent migrations\n // don't need this — the marker store persists across upgrades\n // since it's an internal store not declared in the user's contract.\n if (fromSchema === null) {\n ops.unshift(createMarkerStoreOp());\n }\n\n const fromHash = fromContract !== null ? extractStorageHash(fromContract) : null;\n const toHash = extractStorageHash(contract);\n\n const plan: IdbMigrationPlanWithAuthoring = {\n targetId: \"idb\",\n // `null` means \"no origin validation\" — the runner skips the origin check.\n origin: fromHash !== null ? { storageHash: fromHash } : null,\n destination: { storageHash: toHash },\n operations: ops,\n renderTypeScript() {\n return renderMigrationTs({ fromHash, toHash, ops });\n },\n };\n\n return { kind: \"success\", plan };\n }\n\n emptyMigration(context: MigrationScaffoldContext, _spaceId: string): MigrationPlanWithAuthoringSurface {\n const { fromHash, toHash } = context;\n return {\n targetId: \"idb\",\n origin: fromHash !== null ? { storageHash: fromHash } : null,\n destination: { storageHash: toHash },\n operations: [],\n renderTypeScript() {\n return renderMigrationTs({ fromHash, toHash, ops: [] });\n },\n };\n }\n}\n","import type {\n ControlDriverInstance,\n MigrationRunner,\n MigrationRunnerFailure,\n MigrationRunnerPerSpaceOptions,\n MigrationRunnerResult,\n} from \"@prisma-next/framework-components/control\";\nimport { APP_SPACE_ID } from \"@prisma-next/framework-components/control\";\n\n// ── Inline Result helper ──────────────────────────────────────────────────────\n// `@prisma-next/utils` is not a direct dependency, so satisfy `NotOk<F>`\n// structurally via TypeScript's structural typing.\n\nfunction makeNotOk(failure: MigrationRunnerFailure): MigrationRunnerResult {\n return {\n ok: false as const,\n failure,\n assertOk(): never {\n throw new Error(\"assertOk called on NotOk result\");\n },\n assertNotOk() {\n return failure;\n },\n };\n}\n\n// ── Runner ────────────────────────────────────────────────────────────────────\n\n/**\n * IDB migration runner.\n *\n * `execute()` returns a structured refusal — IndexedDB only exists in the\n * browser, so the framework's CLI control plane (`db init`, `db update`,\n * `migration apply`) has no live database to talk to. The refusal points users\n * at `prisma-next-idb preflight` for chain validation. The browser apply path\n * goes through `openAndUpgrade()` directly via `auto-migrate.ts` in client-idb.\n *\n * v0.12.0 merged the former single-space `execute({plan, …})` and\n * `executeAcrossSpaces({perSpaceOptions})` into one multi-space\n * `execute({driver, perSpaceOptions})`; the `MultiSpaceCapableRunner` interface\n * and `MultiSpace*` types were removed.\n */\nexport class IdbMigrationRunner implements MigrationRunner<\"idb\", \"idb\"> {\n /**\n * Apply one or more per-space migration plans. IDB cannot be applied from\n * the CLI — `IndexedDB` is a browser API — so this always returns a\n * structured refusal. Authoring stays in `prisma-next migration new` /\n * `prisma-next migration plan`; validation lives in `prisma-next-idb\n * preflight`; apply happens in the browser the next time the user opens the\n * app via `createAutoMigratingIdbClient`.\n */\n async execute(options: {\n readonly driver: ControlDriverInstance<\"idb\", \"idb\">;\n readonly perSpaceOptions: ReadonlyArray<MigrationRunnerPerSpaceOptions<\"idb\", \"idb\">>;\n }): Promise<MigrationRunnerResult> {\n const failingSpace = options.perSpaceOptions[0]?.space ?? APP_SPACE_ID;\n return makeNotOk({\n code: \"IDB-RUNNER-CLI-UNSUPPORTED\",\n summary: \"IndexedDB migrations cannot be applied from the CLI.\",\n why:\n \"IndexedDB only exists in the browser; the CLI runs in Node.js. \" +\n \"There is no live database to apply ops against from this process. \" +\n \"Migrations apply automatically the next time a user opens the app \" +\n \"with createAutoMigratingIdbClient.\",\n meta: {\n fix:\n \"Run `prisma-next-idb preflight` to validate the migration chain \" +\n \"applies cleanly against a fake-indexeddb shadow before shipping.\",\n },\n failingSpace,\n });\n }\n}\n\n// Re-export helpers so target-idb/migration exposes them for downstream\n// consumers (client-idb auto-migrate, family-idb preflight).\nexport { applyOneDdlOp, openAndUpgrade, writeMarker, readMarker } from \"./apply-ddl-op\";\nexport type { IdbMarkerRecord, MarkerWriteInput } from \"./apply-ddl-op\";\n","import type { ControlDriverInstance } from \"@prisma-next/framework-components/control\";\n\n/**\n * Extended IDB control driver for migrations.\n *\n * Carries the `IDBFactory`, database name, and target version number so\n * the migration runner can open the database and perform DDL inside the\n * `upgradeneeded` callback.\n *\n * The `targetVersion` is the IDB database version to upgrade **to**. The\n * caller is responsible for computing this value — typically by reading\n * `manifest.idbVersion ?? 0` and adding 1.\n *\n * After a successful `IdbMigrationRunner.execute()` call, the caller must\n * write the new `idbVersion` (= `targetVersion`) back to the manifest.\n * The runner itself does not touch the manifest.\n */\nexport type IdbMigrationControlDriver = ControlDriverInstance<\"idb\", \"idb\"> & {\n readonly dbName: string;\n readonly factory: IDBFactory;\n readonly targetVersion: number;\n};\n\n// ── Descriptor ────────────────────────────────────────────────────────────────\n\n/**\n * Factory descriptor for `IdbMigrationControlDriver`.\n *\n * Usage:\n * ```ts\n * const driver = IdbMigrationControlDriverDescriptor.create({\n * dbName: \"my-app\",\n * factory: window.indexedDB, // or new IDBFactory() from fake-indexeddb\n * targetVersion: (manifest.idbVersion ?? 0) + 1,\n * });\n * ```\n */\nexport const IdbMigrationControlDriverDescriptor = {\n version: \"1.0.0\",\n create({\n dbName,\n factory,\n targetVersion,\n }: {\n readonly dbName: string;\n readonly factory: IDBFactory;\n readonly targetVersion: number;\n }): IdbMigrationControlDriver {\n return {\n familyId: \"idb\",\n targetId: \"idb\",\n dbName,\n factory,\n targetVersion,\n async close() {},\n };\n },\n} as const;\n\n// ── Extractor ─────────────────────────────────────────────────────────────────\n\n/**\n * Narrows a `ControlDriverInstance<\"idb\",\"idb\">` to `IdbMigrationControlDriver`.\n *\n * Throws a descriptive error if the driver was not created by\n * {@link IdbMigrationControlDriverDescriptor}.\n */\nexport function extractMigrationDriver(driver: ControlDriverInstance<\"idb\", \"idb\">): IdbMigrationControlDriver {\n if (!(\"dbName\" in driver) || !(\"factory\" in driver) || !(\"targetVersion\" in driver)) {\n throw new Error(\n \"IDB migration runner requires an IdbMigrationControlDriver. \" +\n \"Create one with IdbMigrationControlDriverDescriptor.create({ dbName, factory, targetVersion }).\"\n );\n }\n return driver as IdbMigrationControlDriver;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { a as readMarker, c as CreateObjectStoreOp, d as IdbDdlOp, f as createIndexOp, g as isIdbDdlOp, h as dropObjectStoreOp, i as openAndUpgrade, l as DropIndexOp, m as dropIndexOp, n as MarkerWriteInput, o as writeMarker, p as createObjectStoreOp, r as applyOneDdlOp, s as CreateIndexOp, t as IdbMarkerRecord, u as DropObjectStoreOp } from "./apply-ddl-op-DZAoihY0.mjs";
|
|
2
|
+
import { a as contractToIdbSchema, c as IdbMigrationControlDriverDescriptor, d as diffIdbSchema, i as IdbMigrationPlanner, l as extractMigrationDriver, n as IdbMigration, o as IdbMigrationRunner, r as IdbMigrationPlanWithAuthoring, s as IdbMigrationControlDriver, t as MigrationCLI, u as IdbSchemaDiffInput } from "./migration-B43yOFXO.mjs";
|
|
3
|
+
export { type CreateIndexOp, type CreateObjectStoreOp, type DropIndexOp, type DropObjectStoreOp, type IdbDdlOp, type IdbMarkerRecord, type IdbMigrationControlDriver, IdbMigrationControlDriverDescriptor, type IdbMigrationPlanWithAuthoring, IdbMigrationPlanner, IdbMigrationRunner, type IdbSchemaDiffInput, type MarkerWriteInput, IdbMigration as Migration, MigrationCLI, applyOneDdlOp, contractToIdbSchema, createIndexOp, createObjectStoreOp, diffIdbSchema, dropIndexOp, dropObjectStoreOp, extractMigrationDriver, isIdbDdlOp, openAndUpgrade, readMarker, writeMarker };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { a as createIndexOp, c as dropIndexOp, i as writeMarker, l as dropObjectStoreOp, n as openAndUpgrade, r as readMarker, s as createObjectStoreOp, t as applyOneDdlOp, u as isIdbDdlOp } from "./apply-ddl-op-LP-l0o4O.mjs";
|
|
2
|
+
import { a as contractToIdbSchema, i as IdbMigrationPlanner, n as extractMigrationDriver, o as diffIdbSchema, r as IdbMigrationRunner, t as IdbMigrationControlDriverDescriptor } from "./migration-driver-4T8Hk1vu.mjs";
|
|
3
|
+
import { Migration, buildMigrationArtifacts, isDirectEntrypoint } from "@prisma-next/migration-tools/migration";
|
|
4
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { parseArgs } from "node:util";
|
|
7
|
+
import { dirname, join } from "pathe";
|
|
8
|
+
//#region src/core/idb-migration.ts
|
|
9
|
+
/**
|
|
10
|
+
* Target-owned base class for IDB migrations.
|
|
11
|
+
*
|
|
12
|
+
* Fixes the framework's `Migration` generic to IDB target identity (operations
|
|
13
|
+
* narrowed to `IdbDdlOp`, family/target ids both `'idb'`) so user-authored
|
|
14
|
+
* migrations and renderer-generated scaffolds can `extends Migration` against
|
|
15
|
+
* the facade re-export from `@prisma-next-idb/target-idb/migration` without
|
|
16
|
+
* redeclaring target-local identity.
|
|
17
|
+
*
|
|
18
|
+
* Unlike SQL/Mongo, IDB has no per-instance control adapter to materialize —
|
|
19
|
+
* IDB DDL ops are pure data. The base constructor signature still accepts the
|
|
20
|
+
* `ControlStack` so the framework's `MigrationCLI` orchestration can pass one
|
|
21
|
+
* uniformly, but it is unused inside an IDB migration.
|
|
22
|
+
*/
|
|
23
|
+
var IdbMigration = class extends Migration {
|
|
24
|
+
targetId = "idb";
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/core/migration-cli.ts
|
|
28
|
+
/**
|
|
29
|
+
* Self-emit CLI invoked by an authored `migration.ts` file:
|
|
30
|
+
*
|
|
31
|
+
* `MigrationCLI.run(import.meta.url, M);`
|
|
32
|
+
*
|
|
33
|
+
* When the file is run as a node entrypoint (`node migration.ts`), regenerates
|
|
34
|
+
* `ops.json` and `migration.json` next to the file from the migration class's
|
|
35
|
+
* current `operations` getter and `describe()` output. When the file is merely
|
|
36
|
+
* imported (e.g. by `contract-space.generated.ts`), returns 0 without side
|
|
37
|
+
* effects.
|
|
38
|
+
*
|
|
39
|
+
* IDB migrations are pure data — no SQL string compilation, no adapter-driven
|
|
40
|
+
* materialization — so this shim deliberately skips config loading and
|
|
41
|
+
* `ControlStack` assembly. That keeps the shim free of the workspace-internal
|
|
42
|
+
* `@prisma-next/cli` package (which is what vendor's `MigrationCLI.run`
|
|
43
|
+
* depends on).
|
|
44
|
+
*/
|
|
45
|
+
var MigrationCLI = class {
|
|
46
|
+
static async run(importMetaUrl, MigrationClass) {
|
|
47
|
+
if (!isDirectEntrypoint(importMetaUrl)) return 0;
|
|
48
|
+
const { values } = parseArgs({
|
|
49
|
+
options: {
|
|
50
|
+
"dry-run": {
|
|
51
|
+
type: "boolean",
|
|
52
|
+
default: false
|
|
53
|
+
},
|
|
54
|
+
help: {
|
|
55
|
+
type: "boolean",
|
|
56
|
+
default: false
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
strict: false
|
|
60
|
+
});
|
|
61
|
+
if (values.help) {
|
|
62
|
+
process.stdout.write("Usage: node migration.ts [--dry-run]\n\n Self-emits ops.json and migration.json next to this file from the\n migration class's describe() and operations getter.\n\n Serializes the DDL ops defined in this file into JSON artifacts\n consumed by the migration runner at design-time (preflight) and\n runtime (browser auto-migrate). A no-op when imported.\n\nOptions:\n --dry-run Print artifacts to stdout without writing files\n --help Show this message\n");
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
const instance = new MigrationClass();
|
|
66
|
+
const migrationDir = dirname(fileURLToPath(importMetaUrl));
|
|
67
|
+
const metaPath = join(migrationDir, "migration.json");
|
|
68
|
+
const opsPath = join(migrationDir, "ops.json");
|
|
69
|
+
let existing = null;
|
|
70
|
+
try {
|
|
71
|
+
const raw = readFileSync(metaPath, "utf-8");
|
|
72
|
+
existing = JSON.parse(raw);
|
|
73
|
+
} catch {}
|
|
74
|
+
const { opsJson, metadataJson } = await buildMigrationArtifacts(instance, existing);
|
|
75
|
+
if (values["dry-run"]) {
|
|
76
|
+
process.stdout.write(`--- migration.json ---\n${metadataJson}\n`);
|
|
77
|
+
process.stdout.write(`--- ops.json ---\n${opsJson}\n`);
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
writeFileSync(opsPath, opsJson);
|
|
81
|
+
writeFileSync(metaPath, metadataJson);
|
|
82
|
+
process.stdout.write(`Wrote ops.json + migration.json to ${migrationDir}\n`);
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
//#endregion
|
|
87
|
+
export { IdbMigrationControlDriverDescriptor, IdbMigrationPlanner, IdbMigrationRunner, IdbMigration as Migration, MigrationCLI, applyOneDdlOp, contractToIdbSchema, createIndexOp, createObjectStoreOp, diffIdbSchema, dropIndexOp, dropObjectStoreOp, extractMigrationDriver, isIdbDdlOp, openAndUpgrade, readMarker, writeMarker };
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=migration.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.mjs","names":[],"sources":["../src/core/idb-migration.ts","../src/core/migration-cli.ts"],"sourcesContent":["import { Migration } from \"@prisma-next/migration-tools/migration\";\nimport type { IdbDdlOp } from \"./migration-factories\";\n\n/**\n * Target-owned base class for IDB migrations.\n *\n * Fixes the framework's `Migration` generic to IDB target identity (operations\n * narrowed to `IdbDdlOp`, family/target ids both `'idb'`) so user-authored\n * migrations and renderer-generated scaffolds can `extends Migration` against\n * the facade re-export from `@prisma-next-idb/target-idb/migration` without\n * redeclaring target-local identity.\n *\n * Unlike SQL/Mongo, IDB has no per-instance control adapter to materialize —\n * IDB DDL ops are pure data. The base constructor signature still accepts the\n * `ControlStack` so the framework's `MigrationCLI` orchestration can pass one\n * uniformly, but it is unused inside an IDB migration.\n */\nexport abstract class IdbMigration extends Migration<IdbDdlOp, \"idb\", \"idb\"> {\n readonly targetId = \"idb\" as const;\n}\n","import { readFileSync, writeFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport type { MigrationMetadata } from \"@prisma-next/migration-tools/metadata\";\nimport { buildMigrationArtifacts, isDirectEntrypoint } from \"@prisma-next/migration-tools/migration\";\nimport { dirname, join } from \"pathe\";\nimport type { IdbMigration } from \"./idb-migration\";\n\ntype IdbMigrationConstructor = new () => IdbMigration;\n\n/**\n * Self-emit CLI invoked by an authored `migration.ts` file:\n *\n * `MigrationCLI.run(import.meta.url, M);`\n *\n * When the file is run as a node entrypoint (`node migration.ts`), regenerates\n * `ops.json` and `migration.json` next to the file from the migration class's\n * current `operations` getter and `describe()` output. When the file is merely\n * imported (e.g. by `contract-space.generated.ts`), returns 0 without side\n * effects.\n *\n * IDB migrations are pure data — no SQL string compilation, no adapter-driven\n * materialization — so this shim deliberately skips config loading and\n * `ControlStack` assembly. That keeps the shim free of the workspace-internal\n * `@prisma-next/cli` package (which is what vendor's `MigrationCLI.run`\n * depends on).\n */\nexport class MigrationCLI {\n static async run(importMetaUrl: string, MigrationClass: IdbMigrationConstructor): Promise<number> {\n if (!isDirectEntrypoint(importMetaUrl)) return 0;\n\n const { values } = parseArgs({\n options: {\n \"dry-run\": { type: \"boolean\", default: false },\n help: { type: \"boolean\", default: false },\n },\n strict: false,\n });\n\n if (values.help) {\n process.stdout.write(\n \"Usage: node migration.ts [--dry-run]\\n\" +\n \"\\n\" +\n \" Self-emits ops.json and migration.json next to this file from the\\n\" +\n \" migration class's describe() and operations getter.\\n\" +\n \"\\n\" +\n \" Serializes the DDL ops defined in this file into JSON artifacts\\n\" +\n \" consumed by the migration runner at design-time (preflight) and\\n\" +\n \" runtime (browser auto-migrate). A no-op when imported.\\n\" +\n \"\\n\" +\n \"Options:\\n\" +\n \" --dry-run Print artifacts to stdout without writing files\\n\" +\n \" --help Show this message\\n\"\n );\n return 0;\n }\n\n const instance = new MigrationClass();\n const migrationDir = dirname(fileURLToPath(importMetaUrl));\n const metaPath = join(migrationDir, \"migration.json\");\n const opsPath = join(migrationDir, \"ops.json\");\n\n let existing: Partial<MigrationMetadata> | null = null;\n try {\n const raw = readFileSync(metaPath, \"utf-8\");\n existing = JSON.parse(raw) as Partial<MigrationMetadata>;\n } catch {\n // No prior metadata — fresh emit.\n }\n\n const { opsJson, metadataJson } = await buildMigrationArtifacts(instance, existing);\n\n if (values[\"dry-run\"]) {\n process.stdout.write(`--- migration.json ---\\n${metadataJson}\\n`);\n process.stdout.write(`--- ops.json ---\\n${opsJson}\\n`);\n return 0;\n }\n\n writeFileSync(opsPath, opsJson);\n writeFileSync(metaPath, metadataJson);\n process.stdout.write(`Wrote ops.json + migration.json to ${migrationDir}\\n`);\n return 0;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiBA,IAAsB,eAAtB,cAA2C,UAAkC;CAC3E,WAAoB;AACtB;;;;;;;;;;;;;;;;;;;;ACQA,IAAa,eAAb,MAA0B;CACxB,aAAa,IAAI,eAAuB,gBAA0D;EAChG,IAAI,CAAC,mBAAmB,aAAa,GAAG,OAAO;EAE/C,MAAM,EAAE,WAAW,UAAU;GAC3B,SAAS;IACP,WAAW;KAAE,MAAM;KAAW,SAAS;IAAM;IAC7C,MAAM;KAAE,MAAM;KAAW,SAAS;IAAM;GAC1C;GACA,QAAQ;EACV,CAAC;EAED,IAAI,OAAO,MAAM;GACf,QAAQ,OAAO,MACb,kdAYF;GACA,OAAO;EACT;EAEA,MAAM,WAAW,IAAI,eAAe;EACpC,MAAM,eAAe,QAAQ,cAAc,aAAa,CAAC;EACzD,MAAM,WAAW,KAAK,cAAc,gBAAgB;EACpD,MAAM,UAAU,KAAK,cAAc,UAAU;EAE7C,IAAI,WAA8C;EAClD,IAAI;GACF,MAAM,MAAM,aAAa,UAAU,OAAO;GAC1C,WAAW,KAAK,MAAM,GAAG;EAC3B,QAAQ,CAER;EAEA,MAAM,EAAE,SAAS,iBAAiB,MAAM,wBAAwB,UAAU,QAAQ;EAElF,IAAI,OAAO,YAAY;GACrB,QAAQ,OAAO,MAAM,2BAA2B,aAAa,GAAG;GAChE,QAAQ,OAAO,MAAM,qBAAqB,QAAQ,GAAG;GACrD,OAAO;EACT;EAEA,cAAc,SAAS,OAAO;EAC9B,cAAc,UAAU,YAAY;EACpC,QAAQ,OAAO,MAAM,sCAAsC,aAAa,GAAG;EAC3E,OAAO;CACT;AACF"}
|
package/dist/pack.d.mts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { a as IdbIndexDefinition, c as IdbRelationStorage, d as IdbTypeMaps, i as IdbContractWithTypeMaps, l as IdbStorage, n as ExtractIdbFieldOutputTypes, o as IdbModelStorage, r as ExtractIdbTypeMaps, s as IdbReferentialAction, t as ExtractIdbFieldInputTypes, u as IdbStoreDefinition } from "./idb-contract-types-DndrdtW0.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/core/descriptor-meta.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Descriptor metadata for the IndexedDB target.
|
|
6
|
+
*
|
|
7
|
+
* This is the identity record for the `idb` target within the `idb` family.
|
|
8
|
+
* It is consumed by:
|
|
9
|
+
* - The family descriptor (`family-idb`) to register this target in the control stack.
|
|
10
|
+
* - The emitter during contract generation to stamp `contract.target = 'idb'`.
|
|
11
|
+
*
|
|
12
|
+
* `types.codecTypes.import` tells the emitter where to import `CodecTypes`
|
|
13
|
+
* when generating `contract.d.ts`. The named export `CodecTypes` must be
|
|
14
|
+
* re-exported from the `pack` entrypoint of this package.
|
|
15
|
+
*
|
|
16
|
+
* Targets are identifiers/descriptors — they do NOT declare capabilities.
|
|
17
|
+
* Capabilities belong on the adapter descriptor.
|
|
18
|
+
*/
|
|
19
|
+
declare const idbTargetDescriptorMeta: {
|
|
20
|
+
readonly kind: "target";
|
|
21
|
+
readonly familyId: "idb";
|
|
22
|
+
readonly targetId: "idb";
|
|
23
|
+
readonly id: "idb";
|
|
24
|
+
readonly version: "0.0.1";
|
|
25
|
+
readonly types: {
|
|
26
|
+
readonly codecTypes: {
|
|
27
|
+
readonly import: {
|
|
28
|
+
readonly package: "@prisma-next-idb/target-idb/pack";
|
|
29
|
+
readonly named: "CodecTypes";
|
|
30
|
+
readonly alias: "IdbCodecTypes";
|
|
31
|
+
};
|
|
32
|
+
readonly codecDescriptors: readonly import("@prisma-next/framework-components/codec").AnyCodecDescriptor[];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/core/codec-types.d.ts
|
|
38
|
+
/**
|
|
39
|
+
* Codec type map for the IndexedDB target.
|
|
40
|
+
*
|
|
41
|
+
* Each key is a stable codec type ID in the form `namespace/type@version`.
|
|
42
|
+
* The emitter stamps these IDs into `contract.json` when it encounters a
|
|
43
|
+
* matching Prisma scalar, and the runtime uses them to look up the correct
|
|
44
|
+
* codec at execute time.
|
|
45
|
+
*
|
|
46
|
+
* - `input` — the TypeScript type the application provides when writing (encode direction).
|
|
47
|
+
* - `output` — the TypeScript type the application receives when reading (decode direction).
|
|
48
|
+
*
|
|
49
|
+
* IDB stores most primitives natively via the Structured Clone Algorithm,
|
|
50
|
+
* so most codecs here are near-identity at runtime. The type IDs still exist
|
|
51
|
+
* so the contract system has a stable, versioned handle for each scalar kind.
|
|
52
|
+
*
|
|
53
|
+
* Prisma scalar → codec ID mapping:
|
|
54
|
+
* - `String` → `idb/string@1`
|
|
55
|
+
* - `Float` → `idb/double@1` (64-bit IEEE 754 double)
|
|
56
|
+
* - `Int` → `idb/int32@1` (32-bit signed integer — NOT for BigInt values)
|
|
57
|
+
* - `Boolean` → `idb/bool@1`
|
|
58
|
+
* - `DateTime` → `idb/date@1` (IDB stores Date natively)
|
|
59
|
+
* - `BigInt` → `idb/bigint@1` (IDB stores BigInt via structured clone)
|
|
60
|
+
* - `Decimal` → `idb/decimal@1` (no native type; round-trips as string)
|
|
61
|
+
* - `Json` → `idb/json@1` (IDB stores plain objects natively)
|
|
62
|
+
* - `Bytes` → `idb/bytes@1` (IDB stores Uint8Array natively)
|
|
63
|
+
*/
|
|
64
|
+
type CodecTypes = {
|
|
65
|
+
readonly "idb/string@1": {
|
|
66
|
+
readonly input: string;
|
|
67
|
+
readonly output: string;
|
|
68
|
+
};
|
|
69
|
+
readonly "idb/double@1": {
|
|
70
|
+
readonly input: number;
|
|
71
|
+
readonly output: number;
|
|
72
|
+
};
|
|
73
|
+
readonly "idb/int32@1": {
|
|
74
|
+
readonly input: number;
|
|
75
|
+
readonly output: number;
|
|
76
|
+
};
|
|
77
|
+
readonly "idb/bool@1": {
|
|
78
|
+
readonly input: boolean;
|
|
79
|
+
readonly output: boolean;
|
|
80
|
+
};
|
|
81
|
+
readonly "idb/date@1": {
|
|
82
|
+
readonly input: Date;
|
|
83
|
+
readonly output: Date;
|
|
84
|
+
};
|
|
85
|
+
readonly "idb/bigint@1": {
|
|
86
|
+
readonly input: bigint;
|
|
87
|
+
readonly output: bigint;
|
|
88
|
+
};
|
|
89
|
+
readonly "idb/decimal@1": {
|
|
90
|
+
readonly input: string;
|
|
91
|
+
readonly output: string;
|
|
92
|
+
};
|
|
93
|
+
readonly "idb/json@1": {
|
|
94
|
+
readonly input: unknown;
|
|
95
|
+
readonly output: unknown;
|
|
96
|
+
};
|
|
97
|
+
readonly "idb/bytes@1": {
|
|
98
|
+
readonly input: Uint8Array;
|
|
99
|
+
readonly output: Uint8Array;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
//#endregion
|
|
103
|
+
export { type CodecTypes, type ExtractIdbFieldInputTypes, type ExtractIdbFieldOutputTypes, type ExtractIdbTypeMaps, type IdbContractWithTypeMaps, type IdbIndexDefinition, type IdbModelStorage, type IdbReferentialAction, type IdbRelationStorage, type IdbStorage, type IdbStoreDefinition, type IdbTypeMaps, idbTargetDescriptorMeta as default };
|
|
104
|
+
//# sourceMappingURL=pack.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.d.mts","names":[],"sources":["../src/core/descriptor-meta.ts","../src/core/codec-types.ts"],"mappings":";;;;;;AAkBA;;;;;;;;;;;;cAAa,uBAAA;EAAA;;;;;;;;;;;;;;;;;;;;;AAAb;;;;;;;;;;;;;;;;;;;;;;ACQA;KAAY,UAAA;EAAA,SACD,cAAA;IAAA,SAA2B,KAAA;IAAA,SAAwB,MAAA;EAAA;EAAA,SACnD,cAAA;IAAA,SAA2B,KAAA;IAAA,SAAwB,MAAA;EAAA;EAAA,SACnD,aAAA;IAAA,SAA0B,KAAA;IAAA,SAAwB,MAAA;EAAA;EAAA,SAClD,YAAA;IAAA,SAAyB,KAAA;IAAA,SAAyB,MAAA;EAAA;EAAA,SAClD,YAAA;IAAA,SAAyB,KAAA,EAAO,IAAA;IAAA,SAAe,MAAA,EAAQ,IAAA;EAAA;EAAA,SACvD,cAAA;IAAA,SAA2B,KAAA;IAAA,SAAwB,MAAA;EAAA;EAAA,SACnD,eAAA;IAAA,SAA4B,KAAA;IAAA,SAAwB,MAAA;EAAA;EAAA,SACpD,YAAA;IAAA,SAAyB,KAAA;IAAA,SAAyB,MAAA;EAAA;EAAA,SAClD,aAAA;IAAA,SAA0B,KAAA,EAAO,UAAA;IAAA,SAAqB,MAAA,EAAQ,UAAA;EAAA;AAAA"}
|
package/dist/pack.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.mjs","names":[],"sources":["../src/exports/pack.ts"],"sourcesContent":["import { idbTargetDescriptorMeta } from \"../core/descriptor-meta\";\n\nexport default idbTargetDescriptorMeta;\nexport type { CodecTypes } from \"../core/codec-types\";\nexport type {\n IdbContractWithTypeMaps,\n IdbIndexDefinition,\n IdbModelStorage,\n IdbReferentialAction,\n IdbRelationStorage,\n IdbStoreDefinition,\n IdbStorage,\n IdbTypeMaps,\n ExtractIdbTypeMaps,\n ExtractIdbFieldOutputTypes,\n ExtractIdbFieldInputTypes,\n} from \"../core/idb-contract-types\";\n"],"mappings":";;AAEA,IAAA,eAAe"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { a as readMarker, c as CreateObjectStoreOp, d as IdbDdlOp, g as isIdbDdlOp, i as openAndUpgrade, l as DropIndexOp, n as MarkerWriteInput, o as writeMarker, r as applyOneDdlOp, s as CreateIndexOp, t as IdbMarkerRecord, u as DropObjectStoreOp } from "./apply-ddl-op-DZAoihY0.mjs";
|
|
2
|
+
import { RuntimeTargetDescriptor, RuntimeTargetInstance } from "@prisma-next/framework-components/execution";
|
|
3
|
+
import { CodecLookup } from "@prisma-next/framework-components/codec";
|
|
4
|
+
|
|
5
|
+
//#region src/core/codecs.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Pre-built CodecLookup for all IDB codecs.
|
|
8
|
+
*
|
|
9
|
+
* All IDB codecs are currently identity transforms, but using the real lookup
|
|
10
|
+
* ensures per-field encoding works automatically when non-identity codecs are
|
|
11
|
+
* added (e.g. idb/date@1 already encodes/decodes Date objects).
|
|
12
|
+
*/
|
|
13
|
+
declare const idbCodecLookup: CodecLookup;
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/exports/runtime.d.ts
|
|
16
|
+
type IdbRuntimeTargetInstance = RuntimeTargetInstance<"idb", "idb">;
|
|
17
|
+
declare const idbRuntimeTargetDescriptor: RuntimeTargetDescriptor<"idb", "idb", IdbRuntimeTargetInstance>;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { type CreateIndexOp, type CreateObjectStoreOp, type DropIndexOp, type DropObjectStoreOp, type IdbDdlOp, type IdbMarkerRecord, IdbRuntimeTargetInstance, type MarkerWriteInput, applyOneDdlOp, idbRuntimeTargetDescriptor as default, idbCodecLookup, isIdbDdlOp, openAndUpgrade, readMarker, writeMarker };
|
|
20
|
+
//# sourceMappingURL=runtime.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/core/codecs.ts","../src/exports/runtime.ts"],"mappings":";;;;;;;;ACmBA;;;;cD4Ka,cAAA,EAAgB,WAezB;;;KC3LQ,wBAAA,GAA2B,qBAAqB;AAAA,cAEtD,0BAAA,EAA4B,uBAAuB,eAAe,wBAAA"}
|