@asaidimu/anansi 1.2.1 → 1.2.3
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/index.cjs +46 -1415
- package/index.d.cts +282 -2
- package/index.d.ts +282 -2
- package/index.js +46 -1364
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -1,1415 +1,46 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
schemaToTypes: () => schemaToTypes,
|
|
48
|
-
sortSemanticVars: () => sortSemanticVars,
|
|
49
|
-
validate: () => validate,
|
|
50
|
-
validateMigration: () => validateMigration,
|
|
51
|
-
validateSchemaChange: () => validateSchemaChange,
|
|
52
|
-
validateSchemaDefinition: () => validateSchemaDefinition
|
|
53
|
-
});
|
|
54
|
-
module.exports = __toCommonJS(index_exports);
|
|
55
|
-
|
|
56
|
-
// src/lib/persistence/index.ts
|
|
57
|
-
var import_events2 = require("@asaidimu/events");
|
|
58
|
-
|
|
59
|
-
// src/lib/persistence/collection.ts
|
|
60
|
-
var import_events = require("@asaidimu/events");
|
|
61
|
-
var import_query = require("@asaidimu/query");
|
|
62
|
-
|
|
63
|
-
// src/tools/patch.ts
|
|
64
|
-
var JsonPatchError = class extends Error {
|
|
65
|
-
constructor(message, operation) {
|
|
66
|
-
super(message);
|
|
67
|
-
this.operation = operation;
|
|
68
|
-
this.name = "JsonPatchError";
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
function parseJsonPointer(path) {
|
|
72
|
-
const normalized = normalizePath(path);
|
|
73
|
-
if (normalized === "") return [];
|
|
74
|
-
return normalized.substring(1).split("/").map(unescapeJsonPointer);
|
|
75
|
-
}
|
|
76
|
-
function normalizePath(path) {
|
|
77
|
-
if (path === "" || path === "/") return "";
|
|
78
|
-
if (path.startsWith("/")) {
|
|
79
|
-
return "/" + path.substring(1).split("/").map(escapeJsonPointer).join("/");
|
|
80
|
-
}
|
|
81
|
-
return "/" + path.split(".").map(escapeJsonPointer).join("/");
|
|
82
|
-
}
|
|
83
|
-
function escapeJsonPointer(part) {
|
|
84
|
-
return part.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
85
|
-
}
|
|
86
|
-
function unescapeJsonPointer(part) {
|
|
87
|
-
return part.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
88
|
-
}
|
|
89
|
-
var pathCache = /* @__PURE__ */ new Map();
|
|
90
|
-
function navigateTo(obj, parts) {
|
|
91
|
-
let current = obj;
|
|
92
|
-
for (const part of parts) {
|
|
93
|
-
if (current === null || typeof current !== "object") {
|
|
94
|
-
throw new JsonPatchError(`Invalid path - parent not found at ${part}`);
|
|
95
|
-
}
|
|
96
|
-
if (Array.isArray(current)) {
|
|
97
|
-
const index = part === "-" ? current.length : parseInt(part);
|
|
98
|
-
if (isNaN(index) || index < 0 || index > current.length) {
|
|
99
|
-
throw new JsonPatchError(`Invalid array index: ${part}`);
|
|
100
|
-
}
|
|
101
|
-
current = current[index];
|
|
102
|
-
} else {
|
|
103
|
-
if (!current.hasOwnProperty(part)) {
|
|
104
|
-
throw new JsonPatchError(`Property ${part} not found`);
|
|
105
|
-
}
|
|
106
|
-
current = current[part];
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return current;
|
|
110
|
-
}
|
|
111
|
-
function getValueAtPath(obj, path) {
|
|
112
|
-
const parts = pathCache.get(path) || parseJsonPointer(path);
|
|
113
|
-
pathCache.set(path, parts);
|
|
114
|
-
if (parts.length === 0) return obj;
|
|
115
|
-
const parent = navigateTo(obj, parts.slice(0, -1));
|
|
116
|
-
const key = parts[parts.length - 1];
|
|
117
|
-
if (Array.isArray(parent)) {
|
|
118
|
-
const index = parseInt(key);
|
|
119
|
-
if (isNaN(index) || index < 0 || index >= parent.length) {
|
|
120
|
-
throw new JsonPatchError(`Invalid array index: ${key}`);
|
|
121
|
-
}
|
|
122
|
-
return parent[index];
|
|
123
|
-
}
|
|
124
|
-
return parent[key];
|
|
125
|
-
}
|
|
126
|
-
function applyRemoveValue(obj, path, value) {
|
|
127
|
-
const parts = pathCache.get(path) || parseJsonPointer(path);
|
|
128
|
-
pathCache.set(path, parts);
|
|
129
|
-
const parent = navigateTo(obj, parts.slice(0, -1));
|
|
130
|
-
const key = parts[parts.length - 1];
|
|
131
|
-
if (Array.isArray(parent)) {
|
|
132
|
-
parent.splice(0, parent.length, ...parent.filter((item) => item !== value));
|
|
133
|
-
} else {
|
|
134
|
-
if (parent[key] === value) {
|
|
135
|
-
delete parent[key];
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return obj;
|
|
139
|
-
}
|
|
140
|
-
function applyAdd(obj, path, value) {
|
|
141
|
-
const parts = pathCache.get(path) || parseJsonPointer(path);
|
|
142
|
-
pathCache.set(path, parts);
|
|
143
|
-
if (parts.length === 0) return value;
|
|
144
|
-
const parentPath = parts.slice(0, -1);
|
|
145
|
-
const key = parts[parts.length - 1];
|
|
146
|
-
const parent = navigateTo(obj, parentPath);
|
|
147
|
-
if (Array.isArray(parent)) {
|
|
148
|
-
if (key === "-") {
|
|
149
|
-
parent.push(value);
|
|
150
|
-
} else {
|
|
151
|
-
const index = parseInt(key);
|
|
152
|
-
if (index < 0 || index > parent.length) {
|
|
153
|
-
throw new JsonPatchError(`Invalid array index: ${key}`);
|
|
154
|
-
}
|
|
155
|
-
parent.splice(index, 0, value);
|
|
156
|
-
}
|
|
157
|
-
} else {
|
|
158
|
-
parent[key] = value;
|
|
159
|
-
}
|
|
160
|
-
return obj;
|
|
161
|
-
}
|
|
162
|
-
function applyRemove(obj, path) {
|
|
163
|
-
const parts = pathCache.get(path) || parseJsonPointer(path);
|
|
164
|
-
pathCache.set(path, parts);
|
|
165
|
-
if (parts.length === 0) return void 0;
|
|
166
|
-
const parent = navigateTo(obj, parts.slice(0, -1));
|
|
167
|
-
const key = parts[parts.length - 1];
|
|
168
|
-
if (Array.isArray(parent)) {
|
|
169
|
-
const index = parseInt(key);
|
|
170
|
-
parent.splice(index, 1);
|
|
171
|
-
} else {
|
|
172
|
-
delete parent[key];
|
|
173
|
-
}
|
|
174
|
-
return obj;
|
|
175
|
-
}
|
|
176
|
-
function applyPatch(target, patches) {
|
|
177
|
-
let result = JSON.parse(JSON.stringify(target));
|
|
178
|
-
for (const patch of patches) {
|
|
179
|
-
try {
|
|
180
|
-
switch (patch.op) {
|
|
181
|
-
case "add":
|
|
182
|
-
result = applyAdd(result, patch.path, patch.value);
|
|
183
|
-
break;
|
|
184
|
-
case "remove":
|
|
185
|
-
result = applyRemove(result, patch.path);
|
|
186
|
-
break;
|
|
187
|
-
case "removeValue":
|
|
188
|
-
result = applyRemoveValue(result, patch.path, patch.value);
|
|
189
|
-
break;
|
|
190
|
-
case "replace":
|
|
191
|
-
result = applyAdd(
|
|
192
|
-
applyRemove(result, patch.path),
|
|
193
|
-
patch.path,
|
|
194
|
-
patch.value
|
|
195
|
-
);
|
|
196
|
-
break;
|
|
197
|
-
case "copy": {
|
|
198
|
-
const value = getValueAtPath(result, patch.from);
|
|
199
|
-
result = applyAdd(
|
|
200
|
-
result,
|
|
201
|
-
patch.path,
|
|
202
|
-
JSON.parse(JSON.stringify(value))
|
|
203
|
-
);
|
|
204
|
-
break;
|
|
205
|
-
}
|
|
206
|
-
case "move": {
|
|
207
|
-
const value = getValueAtPath(result, patch.from);
|
|
208
|
-
result = applyAdd(result, patch.path, value);
|
|
209
|
-
result = applyRemove(result, patch.from);
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
case "test": {
|
|
213
|
-
const actual = getValueAtPath(result, patch.path);
|
|
214
|
-
if (JSON.stringify(actual) !== JSON.stringify(patch.value)) {
|
|
215
|
-
throw new JsonPatchError("Test operation failed");
|
|
216
|
-
}
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
default:
|
|
220
|
-
throw new JsonPatchError(
|
|
221
|
-
`Unsupported operation: ${patch.op}`
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
} catch (error) {
|
|
225
|
-
if (error instanceof JsonPatchError) {
|
|
226
|
-
error.operation = patch;
|
|
227
|
-
}
|
|
228
|
-
throw error;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
return result;
|
|
232
|
-
}
|
|
233
|
-
function createPatch(oldObj, newObj) {
|
|
234
|
-
const patches = [];
|
|
235
|
-
generatePatches(oldObj, newObj, "", patches);
|
|
236
|
-
return patches;
|
|
237
|
-
}
|
|
238
|
-
function generatePatches(oldObj, newObj, path, patches) {
|
|
239
|
-
if (oldObj === newObj) return;
|
|
240
|
-
if (typeof oldObj !== typeof newObj || Array.isArray(oldObj) !== Array.isArray(newObj)) {
|
|
241
|
-
patches.push({ op: "replace", path, value: newObj });
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
if (typeof oldObj === "object" && oldObj !== null) {
|
|
245
|
-
if (Array.isArray(oldObj)) {
|
|
246
|
-
handleArrays(oldObj, newObj, path, patches);
|
|
247
|
-
} else {
|
|
248
|
-
handleObjects(oldObj, newObj, path, patches);
|
|
249
|
-
}
|
|
250
|
-
} else if (oldObj !== newObj) {
|
|
251
|
-
patches.push({ op: "replace", path, value: newObj });
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
function handleArrays(oldArr, newArr, path, patches) {
|
|
255
|
-
const maxLen = Math.max(oldArr.length, newArr.length);
|
|
256
|
-
for (let i = 0; i < maxLen; i++) {
|
|
257
|
-
const currentPath = `${path}/${i}`;
|
|
258
|
-
if (i >= oldArr.length) {
|
|
259
|
-
patches.push({ op: "add", path: `${path}/-`, value: newArr[i] });
|
|
260
|
-
} else if (i >= newArr.length) {
|
|
261
|
-
patches.push({ op: "remove", path: currentPath });
|
|
262
|
-
} else {
|
|
263
|
-
generatePatches(oldArr[i], newArr[i], currentPath, patches);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
function handleObjects(oldObj, newObj, path, patches) {
|
|
268
|
-
const seen = /* @__PURE__ */ new Set();
|
|
269
|
-
const oldKeys = Object.keys(oldObj);
|
|
270
|
-
const newKeys = Object.keys(newObj);
|
|
271
|
-
for (const key of oldKeys) {
|
|
272
|
-
const escapedKey = escapeJsonPointer(key);
|
|
273
|
-
const currentPath = path ? `${path}/${escapedKey}` : `/${escapedKey}`;
|
|
274
|
-
if (!newObj.hasOwnProperty(key)) {
|
|
275
|
-
patches.push({ op: "remove", path: currentPath });
|
|
276
|
-
} else {
|
|
277
|
-
generatePatches(
|
|
278
|
-
oldObj[key],
|
|
279
|
-
newObj[key],
|
|
280
|
-
currentPath,
|
|
281
|
-
patches
|
|
282
|
-
);
|
|
283
|
-
seen.add(key);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
for (const key of newKeys) {
|
|
287
|
-
if (!seen.has(key)) {
|
|
288
|
-
const escapedKey = escapeJsonPointer(key);
|
|
289
|
-
const currentPath = path ? `${path}/${escapedKey}` : `/${escapedKey}`;
|
|
290
|
-
patches.push({
|
|
291
|
-
op: "add",
|
|
292
|
-
path: currentPath,
|
|
293
|
-
value: newObj[key]
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
function schemaChangeToPatch(change, schema) {
|
|
299
|
-
const patches = [];
|
|
300
|
-
switch (change.type) {
|
|
301
|
-
case "addField":
|
|
302
|
-
patches.push({
|
|
303
|
-
op: "add",
|
|
304
|
-
path: `/fields/${change.name}`,
|
|
305
|
-
value: change.definition
|
|
306
|
-
});
|
|
307
|
-
break;
|
|
308
|
-
case "removeField":
|
|
309
|
-
patches.push({
|
|
310
|
-
op: "remove",
|
|
311
|
-
path: `/fields/${change.name}`
|
|
312
|
-
});
|
|
313
|
-
break;
|
|
314
|
-
case "modifyField": {
|
|
315
|
-
const fieldPath = `/fields/${change.name}`;
|
|
316
|
-
Object.entries(change.changes).forEach(([key, value]) => {
|
|
317
|
-
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
318
|
-
patches.push({
|
|
319
|
-
op: "replace",
|
|
320
|
-
path: `${fieldPath}/${key}`,
|
|
321
|
-
value
|
|
322
|
-
});
|
|
323
|
-
} else {
|
|
324
|
-
patches.push({
|
|
325
|
-
op: "replace",
|
|
326
|
-
path: `${fieldPath}/${key}`,
|
|
327
|
-
value
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
});
|
|
331
|
-
break;
|
|
332
|
-
}
|
|
333
|
-
case "deprecateField":
|
|
334
|
-
patches.push({
|
|
335
|
-
op: "add",
|
|
336
|
-
path: `/fields/${change.name}/deprecated`,
|
|
337
|
-
value: true
|
|
338
|
-
});
|
|
339
|
-
break;
|
|
340
|
-
case "addIndex":
|
|
341
|
-
if (!schema.indexes) {
|
|
342
|
-
patches.push({
|
|
343
|
-
op: "add",
|
|
344
|
-
path: "/indexes",
|
|
345
|
-
value: []
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
patches.push({
|
|
349
|
-
op: "add",
|
|
350
|
-
path: "/indexes/-",
|
|
351
|
-
value: change.definition
|
|
352
|
-
});
|
|
353
|
-
break;
|
|
354
|
-
case "removeIndex": {
|
|
355
|
-
const indexIndex = schema.indexes?.findIndex(
|
|
356
|
-
(idx) => idx.name === change.name
|
|
357
|
-
);
|
|
358
|
-
if (indexIndex !== void 0 && indexIndex >= 0) {
|
|
359
|
-
patches.push({
|
|
360
|
-
op: "remove",
|
|
361
|
-
path: `/indexes/${indexIndex}`
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
break;
|
|
365
|
-
}
|
|
366
|
-
case "modifyIndex": {
|
|
367
|
-
const indexIndex = schema.indexes?.findIndex(
|
|
368
|
-
(idx) => idx.name === change.name
|
|
369
|
-
);
|
|
370
|
-
if (indexIndex !== void 0 && indexIndex >= 0) {
|
|
371
|
-
Object.entries(change.changes).forEach(([key, value]) => {
|
|
372
|
-
patches.push({
|
|
373
|
-
op: "replace",
|
|
374
|
-
path: `/indexes/${indexIndex}/${key}`,
|
|
375
|
-
value
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
break;
|
|
380
|
-
}
|
|
381
|
-
case "addConstraint":
|
|
382
|
-
if (!schema.constraints) {
|
|
383
|
-
patches.push({
|
|
384
|
-
op: "add",
|
|
385
|
-
path: "/constraints",
|
|
386
|
-
value: []
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
if (Array.isArray(change.constraint)) {
|
|
390
|
-
change.constraint.forEach((constraint) => {
|
|
391
|
-
patches.push({
|
|
392
|
-
op: "add",
|
|
393
|
-
path: "/constraints/-",
|
|
394
|
-
value: constraint
|
|
395
|
-
});
|
|
396
|
-
});
|
|
397
|
-
} else {
|
|
398
|
-
patches.push({
|
|
399
|
-
op: "add",
|
|
400
|
-
path: "/constraints/-",
|
|
401
|
-
value: change.constraint
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
break;
|
|
405
|
-
case "removeConstraint": {
|
|
406
|
-
const constraintIndex = schema.constraints?.findIndex(
|
|
407
|
-
(c) => Array.isArray(c) ? c.some((rule) => rule.name === change.name) : c.name === change.name
|
|
408
|
-
);
|
|
409
|
-
if (constraintIndex !== void 0 && constraintIndex >= 0) {
|
|
410
|
-
patches.push({
|
|
411
|
-
op: "remove",
|
|
412
|
-
path: `/constraints/${constraintIndex}`
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
break;
|
|
416
|
-
}
|
|
417
|
-
case "modifyConstraint": {
|
|
418
|
-
const constraintPath = findConstraintPath(schema, change.name);
|
|
419
|
-
if (constraintPath) {
|
|
420
|
-
Object.entries(change.changes).forEach(([key, value]) => {
|
|
421
|
-
patches.push({
|
|
422
|
-
op: "replace",
|
|
423
|
-
path: `${constraintPath}/${key}`,
|
|
424
|
-
value
|
|
425
|
-
});
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
break;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
return patches;
|
|
432
|
-
}
|
|
433
|
-
function findConstraintPath(schema, name) {
|
|
434
|
-
if (!schema.constraints) return null;
|
|
435
|
-
for (let i = 0; i < schema.constraints.length; i++) {
|
|
436
|
-
const constraint = schema.constraints[i];
|
|
437
|
-
if (constraint.name === name) {
|
|
438
|
-
return `/constraints/${i}`;
|
|
439
|
-
}
|
|
440
|
-
if (isConstraintGroup(constraint)) {
|
|
441
|
-
const path = searchRules(constraint.rules, name);
|
|
442
|
-
if (path) {
|
|
443
|
-
return `/constraints/${i}${path}`;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
return null;
|
|
448
|
-
}
|
|
449
|
-
function isConstraintGroup(obj) {
|
|
450
|
-
return obj && "operator" in obj && "rules" in obj;
|
|
451
|
-
}
|
|
452
|
-
function searchRules(rules, name) {
|
|
453
|
-
for (let i = 0; i < rules.length; i++) {
|
|
454
|
-
const rule = rules[i];
|
|
455
|
-
if ("name" in rule && rule.name === name) {
|
|
456
|
-
return `/rules/${i}`;
|
|
457
|
-
}
|
|
458
|
-
if (isConstraintGroup(rule)) {
|
|
459
|
-
const path = searchRules(rule.rules, name);
|
|
460
|
-
if (path) {
|
|
461
|
-
return `/rules/${i}${path}`;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
return null;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
// src/tools/merge.ts
|
|
469
|
-
function deepMerge(target, update) {
|
|
470
|
-
const output = { ...target };
|
|
471
|
-
if (isObject(target) && isObject(update)) {
|
|
472
|
-
Object.keys(update).forEach((key) => {
|
|
473
|
-
if (isObject(update[key])) {
|
|
474
|
-
if (!(key in target)) {
|
|
475
|
-
Object.assign(output, { [key]: update[key] });
|
|
476
|
-
} else {
|
|
477
|
-
output[key] = deepMerge(
|
|
478
|
-
target[key],
|
|
479
|
-
update[key]
|
|
480
|
-
);
|
|
481
|
-
}
|
|
482
|
-
} else {
|
|
483
|
-
Object.assign(output, { [key]: update[key] });
|
|
484
|
-
}
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
return output;
|
|
488
|
-
}
|
|
489
|
-
function isObject(item) {
|
|
490
|
-
return item && typeof item === "object" && !Array.isArray(item);
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// src/tools/validator.ts
|
|
494
|
-
function createStandardSchemaValidator(schema, constraintsMap) {
|
|
495
|
-
const validateTypeWithErrors = (value, fieldName, fieldDef, path) => {
|
|
496
|
-
const issues = [];
|
|
497
|
-
switch (fieldDef.type) {
|
|
498
|
-
case "string":
|
|
499
|
-
if (typeof value !== "string") {
|
|
500
|
-
issues.push({
|
|
501
|
-
message: `Expected type string but received ${typeof value}.`,
|
|
502
|
-
path
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
break;
|
|
506
|
-
case "number":
|
|
507
|
-
if (typeof value !== "number") {
|
|
508
|
-
issues.push({
|
|
509
|
-
message: `Expected type number but received ${typeof value}.`,
|
|
510
|
-
path
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
break;
|
|
514
|
-
case "boolean":
|
|
515
|
-
if (typeof value !== "boolean") {
|
|
516
|
-
issues.push({
|
|
517
|
-
message: `Expected type boolean but received ${typeof value}.`,
|
|
518
|
-
path
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
break;
|
|
522
|
-
case "array":
|
|
523
|
-
if (!Array.isArray(value)) {
|
|
524
|
-
issues.push({
|
|
525
|
-
message: `Expected an array but received ${typeof value}.`,
|
|
526
|
-
path
|
|
527
|
-
});
|
|
528
|
-
} else if (!fieldDef.itemsType) {
|
|
529
|
-
issues.push({
|
|
530
|
-
message: `Expected itemsType for array ${fieldName}`,
|
|
531
|
-
path
|
|
532
|
-
});
|
|
533
|
-
} else {
|
|
534
|
-
value.forEach((item, index) => {
|
|
535
|
-
issues.push(
|
|
536
|
-
...validateTypeWithErrors(
|
|
537
|
-
item,
|
|
538
|
-
`Array: ${fieldName}`,
|
|
539
|
-
{
|
|
540
|
-
type: fieldDef.itemsType,
|
|
541
|
-
nestedSchema: fieldDef.nestedSchema
|
|
542
|
-
},
|
|
543
|
-
[...path, index]
|
|
544
|
-
)
|
|
545
|
-
);
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
break;
|
|
549
|
-
case "object":
|
|
550
|
-
if (typeof value !== "object" || value === null) {
|
|
551
|
-
issues.push({
|
|
552
|
-
message: `Expected an object but received ${value === null ? "null" : typeof value}.`,
|
|
553
|
-
path
|
|
554
|
-
});
|
|
555
|
-
} else if (fieldDef.nestedSchema) {
|
|
556
|
-
const nestedSchema = {
|
|
557
|
-
name: fieldDef.description ? `${fieldDef.description}-schema` : "nested-schema",
|
|
558
|
-
version: "1.0",
|
|
559
|
-
fields: fieldDef.nestedSchema
|
|
560
|
-
};
|
|
561
|
-
issues.push(
|
|
562
|
-
...validateData(
|
|
563
|
-
nestedSchema,
|
|
564
|
-
value,
|
|
565
|
-
path
|
|
566
|
-
)
|
|
567
|
-
);
|
|
568
|
-
}
|
|
569
|
-
break;
|
|
570
|
-
case "dynamic":
|
|
571
|
-
break;
|
|
572
|
-
default:
|
|
573
|
-
issues.push({ message: `Unknown field type: ${fieldDef.type}`, path });
|
|
574
|
-
break;
|
|
575
|
-
}
|
|
576
|
-
return issues;
|
|
577
|
-
};
|
|
578
|
-
const validateFieldConstraints = (fieldName, fieldDef, data, path) => {
|
|
579
|
-
const issues = [];
|
|
580
|
-
if (!fieldDef.constraints) return issues;
|
|
581
|
-
fieldDef.constraints.forEach((constraint) => {
|
|
582
|
-
const predicate = constraintsMap[constraint.predicate];
|
|
583
|
-
if (!predicate) {
|
|
584
|
-
issues.push({
|
|
585
|
-
message: `Missing predicate for constraint: ${constraint.name}`,
|
|
586
|
-
path
|
|
587
|
-
});
|
|
588
|
-
} else {
|
|
589
|
-
const valid = constraint.type === "schema" ? predicate({ data, arguments: constraint.parameters }) : predicate({
|
|
590
|
-
data,
|
|
591
|
-
field: fieldName,
|
|
592
|
-
arguments: constraint.parameters
|
|
593
|
-
});
|
|
594
|
-
if (!valid) {
|
|
595
|
-
issues.push({
|
|
596
|
-
message: `Constraint '${constraint.name}' failed for field '${fieldName}'.`,
|
|
597
|
-
path
|
|
598
|
-
});
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
});
|
|
602
|
-
return issues;
|
|
603
|
-
};
|
|
604
|
-
const validateField = (fieldName, fieldDef, value, data, path) => {
|
|
605
|
-
return [
|
|
606
|
-
...validateTypeWithErrors(value, fieldName, fieldDef, path),
|
|
607
|
-
...validateFieldConstraints(fieldName, fieldDef, data, path)
|
|
608
|
-
];
|
|
609
|
-
};
|
|
610
|
-
const evaluateRuleWithErrors = (rule, data, fieldName) => {
|
|
611
|
-
if ("operator" in rule) {
|
|
612
|
-
return applyLogicalOperator(
|
|
613
|
-
rule.operator,
|
|
614
|
-
rule.rules.map((r) => evaluateRuleWithErrors(r, data, fieldName))
|
|
615
|
-
);
|
|
616
|
-
}
|
|
617
|
-
const predicate = constraintsMap[rule.predicate];
|
|
618
|
-
if (!predicate) {
|
|
619
|
-
return false;
|
|
620
|
-
}
|
|
621
|
-
return rule.type === "schema" ? predicate({ data, field: rule.field, arguments: rule.parameters }) : predicate({ data, field: fieldName, arguments: rule.parameters });
|
|
622
|
-
};
|
|
623
|
-
const applyLogicalOperator = (operator, results) => {
|
|
624
|
-
switch (operator) {
|
|
625
|
-
case "and":
|
|
626
|
-
return results.every(Boolean);
|
|
627
|
-
case "or":
|
|
628
|
-
return results.some(Boolean);
|
|
629
|
-
case "not":
|
|
630
|
-
return results.length === 1 ? !results[0] : false;
|
|
631
|
-
case "nor":
|
|
632
|
-
return !results.some(Boolean);
|
|
633
|
-
case "xor":
|
|
634
|
-
return results.filter(Boolean).length === 1;
|
|
635
|
-
default:
|
|
636
|
-
console.error(`Unknown logical operator: ${operator}`);
|
|
637
|
-
return false;
|
|
638
|
-
}
|
|
639
|
-
};
|
|
640
|
-
const ruleToString = (rule) => {
|
|
641
|
-
if ("operator" in rule) {
|
|
642
|
-
return `(${rule.rules.map(ruleToString).join(` ${rule.operator} `)})`;
|
|
643
|
-
}
|
|
644
|
-
return rule.name;
|
|
645
|
-
};
|
|
646
|
-
const validateData = (schemaToValidate, data, path = []) => {
|
|
647
|
-
const issues = [];
|
|
648
|
-
for (const [fieldName, fieldDef] of Object.entries(schemaToValidate.fields)) {
|
|
649
|
-
if (fieldDef.required && data[fieldName] === void 0) {
|
|
650
|
-
issues.push({
|
|
651
|
-
message: `Field '${fieldName}' is required.`,
|
|
652
|
-
path: [...path, fieldName]
|
|
653
|
-
});
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
for (const [fieldName, fieldDef] of Object.entries(schemaToValidate.fields)) {
|
|
657
|
-
const value = data[fieldName];
|
|
658
|
-
if (value === void 0) continue;
|
|
659
|
-
issues.push(
|
|
660
|
-
...validateField(fieldName, fieldDef, value, data, [...path, fieldName])
|
|
661
|
-
);
|
|
662
|
-
}
|
|
663
|
-
if (schemaToValidate.constraints) {
|
|
664
|
-
schemaToValidate.constraints.forEach((rule) => {
|
|
665
|
-
if (!evaluateRuleWithErrors(rule, data)) {
|
|
666
|
-
issues.push({
|
|
667
|
-
message: `Schema constraint failed: ${ruleToString(rule)}`,
|
|
668
|
-
path
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
|
-
});
|
|
672
|
-
}
|
|
673
|
-
return issues;
|
|
674
|
-
};
|
|
675
|
-
return {
|
|
676
|
-
"~standard": {
|
|
677
|
-
version: 1,
|
|
678
|
-
vendor: "@asaidimu/anansi",
|
|
679
|
-
validate: (value) => {
|
|
680
|
-
if (typeof value !== "object" || value === null) {
|
|
681
|
-
return {
|
|
682
|
-
issues: [{ message: "Value must be a non-null object", path: [] }]
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
const issues = validateData(schema, value);
|
|
686
|
-
if (issues.length === 0) {
|
|
687
|
-
return { value };
|
|
688
|
-
}
|
|
689
|
-
return { issues };
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
// src/lib/schema/validator.ts
|
|
696
|
-
var import_zod = require("zod");
|
|
697
|
-
|
|
698
|
-
// src/lib/schema/error.ts
|
|
699
|
-
var SchemaValidationError = class extends Error {
|
|
700
|
-
constructor(message, errors) {
|
|
701
|
-
super(message);
|
|
702
|
-
this.errors = errors;
|
|
703
|
-
this.name = "SchemaValidationError";
|
|
704
|
-
}
|
|
705
|
-
};
|
|
706
|
-
|
|
707
|
-
// src/lib/schema/validator.ts
|
|
708
|
-
var LogicalOperatorSchema = import_zod.z.enum(["and", "or", "not", "nor", "xor"]);
|
|
709
|
-
var FieldTypeSchema = import_zod.z.enum(["string", "number", "boolean", "array", "object", "dynamic"]);
|
|
710
|
-
var IndexTypeSchema = import_zod.z.enum(["normal", "unique", "btree", "hash", "spatial", "fulltext", "gi", "expression", "composite"]);
|
|
711
|
-
var ConstraintParametersSchema = import_zod.z.custom(() => {
|
|
712
|
-
return true;
|
|
713
|
-
});
|
|
714
|
-
var ConstraintSchema = import_zod.z.object({
|
|
715
|
-
type: import_zod.z.string().optional(),
|
|
716
|
-
name: import_zod.z.string(),
|
|
717
|
-
predicate: import_zod.z.string().optional(),
|
|
718
|
-
parameters: ConstraintParametersSchema.optional(),
|
|
719
|
-
description: import_zod.z.string().optional(),
|
|
720
|
-
field: import_zod.z.string().optional(),
|
|
721
|
-
errorMessage: import_zod.z.string().optional()
|
|
722
|
-
});
|
|
723
|
-
var ConstraintGroupSchema = import_zod.z.object({
|
|
724
|
-
operator: LogicalOperatorSchema,
|
|
725
|
-
rules: import_zod.z.array(import_zod.z.union([ConstraintSchema, import_zod.z.lazy(() => ConstraintGroupSchema)]))
|
|
726
|
-
});
|
|
727
|
-
var FieldDefinitionSchema = import_zod.z.object({
|
|
728
|
-
type: FieldTypeSchema,
|
|
729
|
-
required: import_zod.z.boolean().optional(),
|
|
730
|
-
constraints: import_zod.z.array(ConstraintSchema).optional(),
|
|
731
|
-
default: import_zod.z.any().optional(),
|
|
732
|
-
itemsType: FieldTypeSchema.optional(),
|
|
733
|
-
nestedSchema: import_zod.z.record(import_zod.z.lazy(() => FieldDefinitionSchema)).optional(),
|
|
734
|
-
deprecated: import_zod.z.boolean().optional(),
|
|
735
|
-
reference: import_zod.z.object({ schema: import_zod.z.string(), field: import_zod.z.string() }).optional(),
|
|
736
|
-
description: import_zod.z.string().optional(),
|
|
737
|
-
unique: import_zod.z.boolean().optional()
|
|
738
|
-
});
|
|
739
|
-
var PartialIndexConditionSchema = import_zod.z.object({
|
|
740
|
-
operator: LogicalOperatorSchema,
|
|
741
|
-
field: import_zod.z.string(),
|
|
742
|
-
value: import_zod.z.any().optional(),
|
|
743
|
-
conditions: import_zod.z.array(import_zod.z.lazy(() => PartialIndexConditionSchema)).optional()
|
|
744
|
-
});
|
|
745
|
-
var IndexDefinitionSchema = import_zod.z.object({
|
|
746
|
-
fields: import_zod.z.array(import_zod.z.string()),
|
|
747
|
-
type: IndexTypeSchema,
|
|
748
|
-
unique: import_zod.z.boolean().optional(),
|
|
749
|
-
partial: PartialIndexConditionSchema.optional(),
|
|
750
|
-
description: import_zod.z.string().optional(),
|
|
751
|
-
order: import_zod.z.enum(["asc", "desc"]).optional(),
|
|
752
|
-
name: import_zod.z.string().optional()
|
|
753
|
-
});
|
|
754
|
-
var SchemaConstraintSchema = import_zod.z.array(import_zod.z.union([ConstraintSchema, ConstraintGroupSchema]));
|
|
755
|
-
var SchemaDefinitionSchema = import_zod.z.object({
|
|
756
|
-
name: import_zod.z.string(),
|
|
757
|
-
version: import_zod.z.string(),
|
|
758
|
-
description: import_zod.z.string().optional(),
|
|
759
|
-
fields: import_zod.z.record(FieldDefinitionSchema),
|
|
760
|
-
indexes: import_zod.z.array(IndexDefinitionSchema).optional(),
|
|
761
|
-
constraints: SchemaConstraintSchema.optional(),
|
|
762
|
-
metadata: import_zod.z.record(import_zod.z.any()).optional(),
|
|
763
|
-
dependencies: import_zod.z.array(import_zod.z.string()).optional(),
|
|
764
|
-
migrations: import_zod.z.array(import_zod.z.any()).optional()
|
|
765
|
-
});
|
|
766
|
-
var SchemaChangeSchema = import_zod.z.union([
|
|
767
|
-
import_zod.z.object({ type: import_zod.z.literal("addField"), name: import_zod.z.string(), definition: FieldDefinitionSchema }),
|
|
768
|
-
import_zod.z.object({ type: import_zod.z.literal("removeField"), name: import_zod.z.string() }),
|
|
769
|
-
import_zod.z.object({ type: import_zod.z.literal("modifyField"), name: import_zod.z.string(), changes: FieldDefinitionSchema.partial() }),
|
|
770
|
-
import_zod.z.object({ type: import_zod.z.literal("addIndex"), definition: IndexDefinitionSchema }),
|
|
771
|
-
import_zod.z.object({ type: import_zod.z.literal("removeIndex"), name: import_zod.z.string() }),
|
|
772
|
-
import_zod.z.object({ type: import_zod.z.literal("modifyIndex"), name: import_zod.z.string(), changes: IndexDefinitionSchema.partial() }),
|
|
773
|
-
import_zod.z.object({ type: import_zod.z.literal("addConstraint"), constraint: import_zod.z.union([ConstraintSchema, ConstraintGroupSchema]) }),
|
|
774
|
-
import_zod.z.object({ type: import_zod.z.literal("removeConstraint"), name: import_zod.z.string() }),
|
|
775
|
-
import_zod.z.object({ type: import_zod.z.literal("modifyConstraint"), name: import_zod.z.string(), changes: ConstraintSchema.partial() }),
|
|
776
|
-
import_zod.z.object({ type: import_zod.z.literal("deprecateField"), name: import_zod.z.string() })
|
|
777
|
-
]);
|
|
778
|
-
var MigrationSchema = import_zod.z.object({
|
|
779
|
-
id: import_zod.z.string(),
|
|
780
|
-
schemaVersion: import_zod.z.string(),
|
|
781
|
-
changes: import_zod.z.array(SchemaChangeSchema),
|
|
782
|
-
description: import_zod.z.string(),
|
|
783
|
-
status: import_zod.z.enum(["pending", "applied", "failed"]),
|
|
784
|
-
rollback: import_zod.z.array(SchemaChangeSchema).optional(),
|
|
785
|
-
transform: import_zod.z.unknown(),
|
|
786
|
-
createdAt: import_zod.z.string(),
|
|
787
|
-
checksum: import_zod.z.string().optional()
|
|
788
|
-
});
|
|
789
|
-
function validateMigration(change) {
|
|
790
|
-
try {
|
|
791
|
-
MigrationSchema.parse(change);
|
|
792
|
-
return true;
|
|
793
|
-
} catch (error) {
|
|
794
|
-
throw new SchemaValidationError("Invalid migration definition", error);
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
function validateSchemaChange(change) {
|
|
798
|
-
try {
|
|
799
|
-
SchemaChangeSchema.parse(change);
|
|
800
|
-
return true;
|
|
801
|
-
} catch (error) {
|
|
802
|
-
throw new SchemaValidationError("Invalid schema definition", error);
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
function validateSchemaDefinition(schema) {
|
|
806
|
-
try {
|
|
807
|
-
SchemaDefinitionSchema.parse(schema);
|
|
808
|
-
return true;
|
|
809
|
-
} catch (error) {
|
|
810
|
-
throw new SchemaValidationError("Invalid schema definition", error);
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
var validate = validateSchemaDefinition;
|
|
814
|
-
|
|
815
|
-
// src/tools/crypto.ts
|
|
816
|
-
var generateSHA256Hash = async (input) => {
|
|
817
|
-
if (typeof window !== "undefined" && crypto.subtle) {
|
|
818
|
-
const encoder = new TextEncoder();
|
|
819
|
-
const data = encoder.encode(input);
|
|
820
|
-
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
821
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
822
|
-
return hashArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
823
|
-
} else {
|
|
824
|
-
const { createHash } = await import("crypto");
|
|
825
|
-
return createHash("sha256").update(input).digest("hex");
|
|
826
|
-
}
|
|
827
|
-
};
|
|
828
|
-
|
|
829
|
-
// src/tools/version.ts
|
|
830
|
-
function parseVersion(version) {
|
|
831
|
-
const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
|
|
832
|
-
if (!match) {
|
|
833
|
-
throw new Error(
|
|
834
|
-
`Invalid version format: ${version}. Expected format: major.minor.patch`
|
|
835
|
-
);
|
|
836
|
-
}
|
|
837
|
-
return {
|
|
838
|
-
major: parseInt(match[1], 10),
|
|
839
|
-
minor: parseInt(match[2], 10),
|
|
840
|
-
patch: parseInt(match[3], 10)
|
|
841
|
-
};
|
|
842
|
-
}
|
|
843
|
-
function determineFieldType(constraint, schema) {
|
|
844
|
-
if (schema && "field" in constraint && constraint.field) {
|
|
845
|
-
const fieldDef = schema.fields[constraint.field];
|
|
846
|
-
if (fieldDef) {
|
|
847
|
-
return fieldDef.type;
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
if ("parameters" in constraint) {
|
|
851
|
-
const params = constraint.parameters;
|
|
852
|
-
if (params instanceof RegExp || Array.isArray(params) && typeof params[0] === "string") {
|
|
853
|
-
return "string";
|
|
854
|
-
}
|
|
855
|
-
if (typeof params === "number" || Array.isArray(params) && typeof params[0] === "number") {
|
|
856
|
-
return "number";
|
|
857
|
-
}
|
|
858
|
-
if (typeof params === "boolean") {
|
|
859
|
-
return "boolean";
|
|
860
|
-
}
|
|
861
|
-
if (typeof params === "object" && params !== null) {
|
|
862
|
-
if ("minItems" in params || "maxItems" in params) {
|
|
863
|
-
return "array";
|
|
864
|
-
}
|
|
865
|
-
if ("schema" in params) {
|
|
866
|
-
return "object";
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
return void 0;
|
|
871
|
-
}
|
|
872
|
-
function isBreakingFieldChange(changes) {
|
|
873
|
-
if (changes.required === true) return true;
|
|
874
|
-
if (changes.type !== void 0) return true;
|
|
875
|
-
if (changes.itemsType !== void 0) return true;
|
|
876
|
-
if (changes.nestedSchema !== void 0) return true;
|
|
877
|
-
if (changes.reference !== void 0) return true;
|
|
878
|
-
if (changes.unique === true) return true;
|
|
879
|
-
return false;
|
|
880
|
-
}
|
|
881
|
-
function isBreakingConstraintParameters(oldParams, newParams, fieldType) {
|
|
882
|
-
switch (fieldType) {
|
|
883
|
-
case "string":
|
|
884
|
-
if (oldParams instanceof RegExp && newParams instanceof RegExp) {
|
|
885
|
-
return oldParams.source !== newParams.source;
|
|
886
|
-
}
|
|
887
|
-
if (Array.isArray(oldParams) && Array.isArray(newParams)) {
|
|
888
|
-
return newParams.length < oldParams.length || !oldParams.every(
|
|
889
|
-
(val) => newParams.includes(val)
|
|
890
|
-
);
|
|
891
|
-
}
|
|
892
|
-
break;
|
|
893
|
-
case "number":
|
|
894
|
-
if (typeof oldParams === "object" && typeof newParams === "object") {
|
|
895
|
-
if ("precision" in oldParams && "precision" in newParams) {
|
|
896
|
-
return newParams.precision < oldParams.precision || (newParams.scale ?? 0) < (oldParams.scale ?? 0);
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
if (Array.isArray(oldParams) && Array.isArray(newParams)) {
|
|
900
|
-
return newParams.length < oldParams.length || !oldParams.every(
|
|
901
|
-
(val) => newParams.includes(val)
|
|
902
|
-
);
|
|
903
|
-
}
|
|
904
|
-
break;
|
|
905
|
-
case "array":
|
|
906
|
-
if (typeof oldParams === "object" && typeof newParams === "object" && "minItems" in oldParams && "maxItems" in oldParams && "minItems" in newParams && "maxItems" in newParams) {
|
|
907
|
-
return newParams.minItems > oldParams.minItems || newParams.maxItems < oldParams.maxItems;
|
|
908
|
-
}
|
|
909
|
-
break;
|
|
910
|
-
case "object":
|
|
911
|
-
if (typeof oldParams === "object" && typeof newParams === "object" && "schema" in oldParams && "schema" in newParams) {
|
|
912
|
-
return Object.keys(newParams.schema).length > Object.keys(oldParams.schema).length;
|
|
913
|
-
}
|
|
914
|
-
break;
|
|
915
|
-
}
|
|
916
|
-
return false;
|
|
917
|
-
}
|
|
918
|
-
function analyzeConstraintGroupChanges(oldGroup, newGroup) {
|
|
919
|
-
const operatorPriority = {
|
|
920
|
-
or: 1,
|
|
921
|
-
xor: 2,
|
|
922
|
-
and: 3,
|
|
923
|
-
not: 4,
|
|
924
|
-
nor: 4
|
|
925
|
-
};
|
|
926
|
-
if (newGroup.operator && operatorPriority[newGroup.operator] > operatorPriority[oldGroup.operator]) {
|
|
927
|
-
return true;
|
|
928
|
-
}
|
|
929
|
-
if (newGroup.rules && newGroup.rules.length > oldGroup.rules.length) {
|
|
930
|
-
return true;
|
|
931
|
-
}
|
|
932
|
-
return false;
|
|
933
|
-
}
|
|
934
|
-
function isBreakingConstraintChange(changes, oldConstraint, schema) {
|
|
935
|
-
if (!oldConstraint) {
|
|
936
|
-
return true;
|
|
937
|
-
}
|
|
938
|
-
if ("rules" in oldConstraint && "rules" in changes) {
|
|
939
|
-
return analyzeConstraintGroupChanges(
|
|
940
|
-
oldConstraint,
|
|
941
|
-
changes
|
|
942
|
-
);
|
|
943
|
-
}
|
|
944
|
-
if ("predicate" in changes && changes.predicate !== void 0) {
|
|
945
|
-
return true;
|
|
946
|
-
}
|
|
947
|
-
if ("parameters" in changes && changes.parameters !== void 0) {
|
|
948
|
-
const fieldType = determineFieldType(
|
|
949
|
-
oldConstraint,
|
|
950
|
-
schema
|
|
951
|
-
);
|
|
952
|
-
if (fieldType) {
|
|
953
|
-
return isBreakingConstraintParameters(
|
|
954
|
-
oldConstraint.parameters,
|
|
955
|
-
changes.parameters,
|
|
956
|
-
fieldType
|
|
957
|
-
);
|
|
958
|
-
}
|
|
959
|
-
return true;
|
|
960
|
-
}
|
|
961
|
-
return false;
|
|
962
|
-
}
|
|
963
|
-
function getChangeImpact(change, currentSchema) {
|
|
964
|
-
switch (change.type) {
|
|
965
|
-
case "removeField":
|
|
966
|
-
case "removeIndex":
|
|
967
|
-
return "major";
|
|
968
|
-
case "modifyField":
|
|
969
|
-
if (isBreakingFieldChange(change.changes)) {
|
|
970
|
-
return "major";
|
|
971
|
-
}
|
|
972
|
-
if (change.changes.deprecated) {
|
|
973
|
-
return "minor";
|
|
974
|
-
}
|
|
975
|
-
return "patch";
|
|
976
|
-
case "modifyIndex":
|
|
977
|
-
if (change.changes.unique !== void 0 || change.changes.fields !== void 0) {
|
|
978
|
-
return "major";
|
|
979
|
-
}
|
|
980
|
-
return "minor";
|
|
981
|
-
case "addConstraint":
|
|
982
|
-
return "major";
|
|
983
|
-
case "removeConstraint":
|
|
984
|
-
return "minor";
|
|
985
|
-
case "modifyConstraint":
|
|
986
|
-
const oldConstraint = currentSchema?.constraints?.find(
|
|
987
|
-
(c) => "name" in c && c.name === change.name
|
|
988
|
-
);
|
|
989
|
-
if (isBreakingConstraintChange(change.changes, oldConstraint, currentSchema)) {
|
|
990
|
-
return "major";
|
|
991
|
-
}
|
|
992
|
-
return "minor";
|
|
993
|
-
case "addField":
|
|
994
|
-
case "addIndex":
|
|
995
|
-
case "deprecateField":
|
|
996
|
-
return "minor";
|
|
997
|
-
default:
|
|
998
|
-
throw new Error(`Unhandled change type: ${JSON.stringify(change)}`);
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
function validateFieldChanges(changes) {
|
|
1002
|
-
const modifiedFields = /* @__PURE__ */ new Set();
|
|
1003
|
-
const removedFields = /* @__PURE__ */ new Set();
|
|
1004
|
-
const addedFields = /* @__PURE__ */ new Set();
|
|
1005
|
-
const deprecatedFields = /* @__PURE__ */ new Set();
|
|
1006
|
-
for (const change of changes) {
|
|
1007
|
-
switch (change.type) {
|
|
1008
|
-
case "addField":
|
|
1009
|
-
if (removedFields.has(change.name)) {
|
|
1010
|
-
throw new Error(
|
|
1011
|
-
`Cannot add previously removed field: ${change.name}`
|
|
1012
|
-
);
|
|
1013
|
-
}
|
|
1014
|
-
if (modifiedFields.has(change.name)) {
|
|
1015
|
-
throw new Error(`Cannot add already modified field: ${change.name}`);
|
|
1016
|
-
}
|
|
1017
|
-
if (deprecatedFields.has(change.name)) {
|
|
1018
|
-
throw new Error(`Cannot add deprecated field: ${change.name}`);
|
|
1019
|
-
}
|
|
1020
|
-
addedFields.add(change.name);
|
|
1021
|
-
break;
|
|
1022
|
-
case "removeField":
|
|
1023
|
-
if (addedFields.has(change.name)) {
|
|
1024
|
-
throw new Error(`Cannot remove newly added field: ${change.name}`);
|
|
1025
|
-
}
|
|
1026
|
-
if (modifiedFields.has(change.name)) {
|
|
1027
|
-
throw new Error(`Cannot remove modified field: ${change.name}`);
|
|
1028
|
-
}
|
|
1029
|
-
if (deprecatedFields.has(change.name)) {
|
|
1030
|
-
throw new Error(
|
|
1031
|
-
`Cannot remove field that is being deprecated: ${change.name}`
|
|
1032
|
-
);
|
|
1033
|
-
}
|
|
1034
|
-
removedFields.add(change.name);
|
|
1035
|
-
break;
|
|
1036
|
-
case "modifyField":
|
|
1037
|
-
if (removedFields.has(change.name)) {
|
|
1038
|
-
throw new Error(`Cannot modify removed field: ${change.name}`);
|
|
1039
|
-
}
|
|
1040
|
-
if (addedFields.has(change.name)) {
|
|
1041
|
-
throw new Error(`Cannot modify newly added field: ${change.name}`);
|
|
1042
|
-
}
|
|
1043
|
-
if (deprecatedFields.has(change.name)) {
|
|
1044
|
-
throw new Error(
|
|
1045
|
-
`Cannot modify field that is being deprecated: ${change.name}`
|
|
1046
|
-
);
|
|
1047
|
-
}
|
|
1048
|
-
modifiedFields.add(change.name);
|
|
1049
|
-
break;
|
|
1050
|
-
case "deprecateField":
|
|
1051
|
-
if (removedFields.has(change.name)) {
|
|
1052
|
-
throw new Error(`Cannot deprecate removed field: ${change.name}`);
|
|
1053
|
-
}
|
|
1054
|
-
if (addedFields.has(change.name)) {
|
|
1055
|
-
throw new Error(`Cannot deprecate newly added field: ${change.name}`);
|
|
1056
|
-
}
|
|
1057
|
-
if (modifiedFields.has(change.name)) {
|
|
1058
|
-
throw new Error(`Cannot deprecate modified field: ${change.name}`);
|
|
1059
|
-
}
|
|
1060
|
-
deprecatedFields.add(change.name);
|
|
1061
|
-
break;
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
function validateConstraintChanges(changes) {
|
|
1066
|
-
const modifiedConstraints = /* @__PURE__ */ new Set();
|
|
1067
|
-
const removedConstraints = /* @__PURE__ */ new Set();
|
|
1068
|
-
const addedConstraints = /* @__PURE__ */ new Set();
|
|
1069
|
-
for (const change of changes) {
|
|
1070
|
-
switch (change.type) {
|
|
1071
|
-
case "addConstraint":
|
|
1072
|
-
const c = change.constraint;
|
|
1073
|
-
const name = "name" in c ? c.name : c.name;
|
|
1074
|
-
if (removedConstraints.has(name)) {
|
|
1075
|
-
throw new Error(
|
|
1076
|
-
`Cannot add previously removed constraint: ${name}`
|
|
1077
|
-
);
|
|
1078
|
-
}
|
|
1079
|
-
if (modifiedConstraints.has(name)) {
|
|
1080
|
-
throw new Error(`Cannot add already modified constraint: ${name}`);
|
|
1081
|
-
}
|
|
1082
|
-
addedConstraints.add(name);
|
|
1083
|
-
break;
|
|
1084
|
-
case "removeConstraint":
|
|
1085
|
-
if (addedConstraints.has(change.name)) {
|
|
1086
|
-
throw new Error(
|
|
1087
|
-
`Cannot remove newly added constraint: ${change.name}`
|
|
1088
|
-
);
|
|
1089
|
-
}
|
|
1090
|
-
if (modifiedConstraints.has(change.name)) {
|
|
1091
|
-
throw new Error(`Cannot remove modified constraint: ${change.name}`);
|
|
1092
|
-
}
|
|
1093
|
-
removedConstraints.add(change.name);
|
|
1094
|
-
break;
|
|
1095
|
-
case "modifyConstraint":
|
|
1096
|
-
if (removedConstraints.has(change.name)) {
|
|
1097
|
-
throw new Error(`Cannot modify removed constraint: ${change.name}`);
|
|
1098
|
-
}
|
|
1099
|
-
if (addedConstraints.has(change.name)) {
|
|
1100
|
-
throw new Error(
|
|
1101
|
-
`Cannot modify newly added constraint: ${change.name}`
|
|
1102
|
-
);
|
|
1103
|
-
}
|
|
1104
|
-
modifiedConstraints.add(change.name);
|
|
1105
|
-
break;
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
function calculateNextVersion(currentVersion, changes, currentSchema) {
|
|
1110
|
-
if (changes.length === 0) {
|
|
1111
|
-
throw new Error("No changes provided");
|
|
1112
|
-
}
|
|
1113
|
-
validateFieldChanges(changes);
|
|
1114
|
-
validateConstraintChanges(changes);
|
|
1115
|
-
const version = parseVersion(currentVersion);
|
|
1116
|
-
let highestImpact = "patch";
|
|
1117
|
-
for (const change of changes) {
|
|
1118
|
-
const impact = getChangeImpact(change, currentSchema);
|
|
1119
|
-
if (impact === "major") {
|
|
1120
|
-
highestImpact = "major";
|
|
1121
|
-
break;
|
|
1122
|
-
} else if (impact === "minor" && highestImpact === "patch") {
|
|
1123
|
-
highestImpact = "minor";
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
switch (highestImpact) {
|
|
1127
|
-
case "major":
|
|
1128
|
-
return `${version.major + 1}.0.0`;
|
|
1129
|
-
case "minor":
|
|
1130
|
-
return `${version.major}.${version.minor + 1}.0`;
|
|
1131
|
-
case "patch":
|
|
1132
|
-
return `${version.major}.${version.minor}.${version.patch + 1}`;
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
function compareSemanticVersions(a, b) {
|
|
1136
|
-
const parseVersion2 = (version) => version.split(".").map((part) => parseInt(part, 10) || 0);
|
|
1137
|
-
const [aMajor, aMinor, aPatch] = parseVersion2(a);
|
|
1138
|
-
const [bMajor, bMinor, bPatch] = parseVersion2(b);
|
|
1139
|
-
return aMajor - bMajor || aMinor - bMinor || aPatch - bPatch;
|
|
1140
|
-
}
|
|
1141
|
-
function sortSemanticVars(vars) {
|
|
1142
|
-
return vars.sort(compareSemanticVersions);
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
// src/lib/migration/index.ts
|
|
1146
|
-
var MigrationError = class extends Error {
|
|
1147
|
-
constructor(message, code, migrationId, cause) {
|
|
1148
|
-
super(message);
|
|
1149
|
-
this.code = code;
|
|
1150
|
-
this.migrationId = migrationId;
|
|
1151
|
-
this.cause = cause;
|
|
1152
|
-
this.name = "MigrationError";
|
|
1153
|
-
}
|
|
1154
|
-
};
|
|
1155
|
-
var MigrationErrorCode = /* @__PURE__ */ ((MigrationErrorCode2) => {
|
|
1156
|
-
MigrationErrorCode2["INVALID_SCHEMA"] = "INVALID_SCHEMA";
|
|
1157
|
-
MigrationErrorCode2["INVALID_MIGRATION"] = "INVALID_MIGRATION";
|
|
1158
|
-
MigrationErrorCode2["CHECKSUM_MISMATCH"] = "CHECKSUM_MISMATCH";
|
|
1159
|
-
MigrationErrorCode2["TIMEOUT"] = "TIMEOUT";
|
|
1160
|
-
MigrationErrorCode2["MEMORY_LIMIT"] = "MEMORY_LIMIT";
|
|
1161
|
-
MigrationErrorCode2["CONCURRENT_OPERATION"] = "CONCURRENT_OPERATION";
|
|
1162
|
-
MigrationErrorCode2["TRANSFORM_ERROR"] = "TRANSFORM_ERROR";
|
|
1163
|
-
MigrationErrorCode2["VERSION_NOT_FOUND"] = "VERSION_NOT_FOUND";
|
|
1164
|
-
MigrationErrorCode2["CIRCULAR_DEPENDENCY"] = "CIRCULAR_DEPENDENCY";
|
|
1165
|
-
MigrationErrorCode2["STREAM_ERROR"] = "STREAM_ERROR";
|
|
1166
|
-
MigrationErrorCode2["ROLLBACK_ERROR"] = "ROLLBACK_ERROR";
|
|
1167
|
-
MigrationErrorCode2["MISSING_TRANSFORM"] = "MISSING_TRANSFORM";
|
|
1168
|
-
return MigrationErrorCode2;
|
|
1169
|
-
})(MigrationErrorCode || {});
|
|
1170
|
-
|
|
1171
|
-
// src/lib/schema/helpers.ts
|
|
1172
|
-
var createSchemaMigrationHelper = (schema) => {
|
|
1173
|
-
const migrate = [];
|
|
1174
|
-
const rollback = [];
|
|
1175
|
-
return {
|
|
1176
|
-
/**
|
|
1177
|
-
* Adds a new field to the schema.
|
|
1178
|
-
* @param {string} fieldName - The name of the field to add.
|
|
1179
|
-
* @param {FieldDefinition<any>} fieldDefinition - The definition of the field to add.
|
|
1180
|
-
*/
|
|
1181
|
-
addField: (fieldName, fieldDefinition) => {
|
|
1182
|
-
migrate.push({ type: "addField", name: fieldName, definition: fieldDefinition });
|
|
1183
|
-
rollback.push({ type: "removeField", name: fieldName });
|
|
1184
|
-
},
|
|
1185
|
-
/**
|
|
1186
|
-
* Removes a field from the schema.
|
|
1187
|
-
* @param {string} fieldName - The name of the field to remove.
|
|
1188
|
-
*/
|
|
1189
|
-
removeField: (fieldName) => {
|
|
1190
|
-
migrate.push({ type: "removeField", name: fieldName });
|
|
1191
|
-
const originalField = schema.fields[fieldName];
|
|
1192
|
-
if (originalField) {
|
|
1193
|
-
rollback.push({ type: "addField", name: fieldName, definition: originalField });
|
|
1194
|
-
}
|
|
1195
|
-
},
|
|
1196
|
-
/**
|
|
1197
|
-
* Modifies an existing field in the schema.
|
|
1198
|
-
* @param {string} fieldName - The name of the field to modify.
|
|
1199
|
-
* @param {Partial<FieldDefinition<any>>} changes - The changes to apply to the field.
|
|
1200
|
-
*/
|
|
1201
|
-
modifyField: (fieldName, changes) => {
|
|
1202
|
-
migrate.push({ type: "modifyField", name: fieldName, changes });
|
|
1203
|
-
const originalField = schema.fields[fieldName];
|
|
1204
|
-
rollback.push({ type: "modifyField", name: fieldName, changes: originalField });
|
|
1205
|
-
},
|
|
1206
|
-
/**
|
|
1207
|
-
* Deprecates a field.
|
|
1208
|
-
* @param {string} fieldName - The name of the field to deprecate.
|
|
1209
|
-
*/
|
|
1210
|
-
deprecateField: (fieldName) => {
|
|
1211
|
-
migrate.push({ type: "deprecateField", name: fieldName });
|
|
1212
|
-
rollback.push({
|
|
1213
|
-
type: "modifyField",
|
|
1214
|
-
name: fieldName,
|
|
1215
|
-
changes: { deprecated: false }
|
|
1216
|
-
});
|
|
1217
|
-
},
|
|
1218
|
-
/**
|
|
1219
|
-
* Adds a new index to the schema.
|
|
1220
|
-
* @param {IndexDefinition} indexDefinition - The definition of the index to add.
|
|
1221
|
-
*/
|
|
1222
|
-
addIndex: (indexDefinition) => {
|
|
1223
|
-
migrate.push({ type: "addIndex", definition: indexDefinition });
|
|
1224
|
-
rollback.push({ type: "removeIndex", name: indexDefinition.name });
|
|
1225
|
-
},
|
|
1226
|
-
/**
|
|
1227
|
-
* Removes an index from the schema.
|
|
1228
|
-
* @param {string} indexName - The name of the index to remove.
|
|
1229
|
-
*/
|
|
1230
|
-
removeIndex: (indexName) => {
|
|
1231
|
-
migrate.push({ type: "removeIndex", name: indexName });
|
|
1232
|
-
const originalIndex = schema.indexes?.find((index) => index.name === indexName);
|
|
1233
|
-
if (originalIndex) {
|
|
1234
|
-
rollback.push({ type: "addIndex", definition: originalIndex });
|
|
1235
|
-
}
|
|
1236
|
-
},
|
|
1237
|
-
/**
|
|
1238
|
-
* Modifies an existing index in the schema.
|
|
1239
|
-
* @param {string} indexName - The name of the index to modify.
|
|
1240
|
-
* @param {Partial<IndexDefinition>} changes - The changes to apply to the index.
|
|
1241
|
-
*/
|
|
1242
|
-
modifyIndex: (indexName, changes) => {
|
|
1243
|
-
migrate.push({ type: "modifyIndex", name: indexName, changes });
|
|
1244
|
-
const originalIndex = schema.indexes?.find((index) => index.name === indexName);
|
|
1245
|
-
if (originalIndex) {
|
|
1246
|
-
rollback.push({ type: "modifyIndex", name: indexName, changes: originalIndex });
|
|
1247
|
-
}
|
|
1248
|
-
},
|
|
1249
|
-
/**
|
|
1250
|
-
* Adds a new constraint to the schema.
|
|
1251
|
-
* @param {SchemaConstraint<any>} constraint - The constraint to add.
|
|
1252
|
-
*/
|
|
1253
|
-
addConstraint: (constraint) => {
|
|
1254
|
-
migrate.push({ type: "addConstraint", constraint });
|
|
1255
|
-
rollback.push({ type: "removeConstraint", name: constraint.name });
|
|
1256
|
-
},
|
|
1257
|
-
/**
|
|
1258
|
-
* Removes a constraint from the schema.
|
|
1259
|
-
* @param {string} constraintName - The name of the constraint to remove.
|
|
1260
|
-
*/
|
|
1261
|
-
removeConstraint: (constraintName) => {
|
|
1262
|
-
migrate.push({ type: "removeConstraint", name: constraintName });
|
|
1263
|
-
const originalConstraint = schema.constraints?.find((c) => "name" in c && c.name === constraintName);
|
|
1264
|
-
if (originalConstraint) {
|
|
1265
|
-
rollback.push({ type: "addConstraint", constraint: originalConstraint });
|
|
1266
|
-
}
|
|
1267
|
-
},
|
|
1268
|
-
/**
|
|
1269
|
-
* Modifies an existing constraint in the schema.
|
|
1270
|
-
* @param {string} constraintName - The name of the constraint to modify.
|
|
1271
|
-
* @param {Partial<SchemaConstraint<any>>} changes - The changes to apply to the constraint.
|
|
1272
|
-
*/
|
|
1273
|
-
modifyConstraint: (constraintName, changes) => {
|
|
1274
|
-
migrate.push({ type: "modifyConstraint", name: constraintName, changes });
|
|
1275
|
-
const originalConstraint = schema.constraints?.find((c) => "name" in c && c.name === constraintName);
|
|
1276
|
-
if (originalConstraint) {
|
|
1277
|
-
rollback.push({ type: "modifyConstraint", name: constraintName, changes: originalConstraint });
|
|
1278
|
-
}
|
|
1279
|
-
},
|
|
1280
|
-
/**
|
|
1281
|
-
* Returns the migration changes and their corresponding rollback changes.
|
|
1282
|
-
* @returns {Object} An object containing the migrate and rollback changes.
|
|
1283
|
-
*/
|
|
1284
|
-
changes: () => ({
|
|
1285
|
-
migrate,
|
|
1286
|
-
rollback
|
|
1287
|
-
})
|
|
1288
|
-
};
|
|
1289
|
-
};
|
|
1290
|
-
|
|
1291
|
-
// src/lib/registry/index.ts
|
|
1292
|
-
var import_lightning_fs = __toESM(require("@isomorphic-git/lightning-fs"), 1);
|
|
1293
|
-
var import_buffer = require("buffer");
|
|
1294
|
-
var import_isomorphic_git = __toESM(require("isomorphic-git"), 1);
|
|
1295
|
-
var import_web = __toESM(require("isomorphic-git/http/web"), 1);
|
|
1296
|
-
window.Buffer = import_buffer.Buffer;
|
|
1297
|
-
|
|
1298
|
-
// src/tools/typegen.ts
|
|
1299
|
-
function convertFieldTypeToTS(field, parentType, fieldName) {
|
|
1300
|
-
switch (field.type) {
|
|
1301
|
-
case "string":
|
|
1302
|
-
return "string";
|
|
1303
|
-
case "number":
|
|
1304
|
-
return "number";
|
|
1305
|
-
case "boolean":
|
|
1306
|
-
return "boolean";
|
|
1307
|
-
case "array":
|
|
1308
|
-
if (field.itemsType) {
|
|
1309
|
-
if (field.itemsType === "object" && field.nestedSchema) {
|
|
1310
|
-
const nestedTypeName = `${parentType}ItemsItem`;
|
|
1311
|
-
return `${nestedTypeName}[]`;
|
|
1312
|
-
}
|
|
1313
|
-
return `${field.itemsType}[]`;
|
|
1314
|
-
}
|
|
1315
|
-
return "any[]";
|
|
1316
|
-
case "object":
|
|
1317
|
-
if (field.nestedSchema) {
|
|
1318
|
-
return `${parentType}${capitalize(fieldName)}`;
|
|
1319
|
-
}
|
|
1320
|
-
return "Record<string, any>";
|
|
1321
|
-
case "dynamic":
|
|
1322
|
-
return "any";
|
|
1323
|
-
default:
|
|
1324
|
-
return "any";
|
|
1325
|
-
}
|
|
1326
|
-
}
|
|
1327
|
-
function generateNestedTypes(fields, parentName) {
|
|
1328
|
-
let types = "";
|
|
1329
|
-
for (const [fieldName, field] of Object.entries(fields)) {
|
|
1330
|
-
if (field.type === "object" && field.nestedSchema) {
|
|
1331
|
-
const typeName = `${parentName}${capitalize(fieldName)}`;
|
|
1332
|
-
types += `
|
|
1333
|
-
export interface ${typeName} {
|
|
1334
|
-
${generateTypeProperties(field.nestedSchema, typeName)}
|
|
1335
|
-
}`;
|
|
1336
|
-
const nestedTypes = generateNestedTypes(field.nestedSchema, typeName);
|
|
1337
|
-
if (nestedTypes) {
|
|
1338
|
-
types += `
|
|
1339
|
-
${nestedTypes}`;
|
|
1340
|
-
}
|
|
1341
|
-
} else if (field.type === "array" && field.itemsType === "object" && field.nestedSchema) {
|
|
1342
|
-
const typeName = `${parentName}ItemsItem`;
|
|
1343
|
-
types += `
|
|
1344
|
-
export interface ${typeName} {
|
|
1345
|
-
${generateTypeProperties(field.nestedSchema, typeName)}
|
|
1346
|
-
}`;
|
|
1347
|
-
const nestedTypes = generateNestedTypes(field.nestedSchema, typeName);
|
|
1348
|
-
if (nestedTypes) {
|
|
1349
|
-
types += `
|
|
1350
|
-
${nestedTypes}`;
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
return types;
|
|
1355
|
-
}
|
|
1356
|
-
function generateTypeProperties(fields, parentType) {
|
|
1357
|
-
return Object.entries(fields).map(([fieldName, field]) => {
|
|
1358
|
-
const lines = [];
|
|
1359
|
-
if (field.description) {
|
|
1360
|
-
lines.push(` /** ${field.description} */`);
|
|
1361
|
-
}
|
|
1362
|
-
if (field.deprecated) {
|
|
1363
|
-
lines.push(" /** @deprecated */");
|
|
1364
|
-
}
|
|
1365
|
-
const optional = !field.required ? "?" : "";
|
|
1366
|
-
const tsType = convertFieldTypeToTS(field, parentType, fieldName);
|
|
1367
|
-
lines.push(` ${fieldName}${optional}: ${tsType};`);
|
|
1368
|
-
return lines.join("\n");
|
|
1369
|
-
}).join("\n");
|
|
1370
|
-
}
|
|
1371
|
-
function capitalize(str) {
|
|
1372
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
1373
|
-
}
|
|
1374
|
-
function schemaToTypes(schema) {
|
|
1375
|
-
const mainTypeName = capitalize(schema.name);
|
|
1376
|
-
let output = `// Generated from schema version ${schema.version}
|
|
1377
|
-
`;
|
|
1378
|
-
if (schema.description) {
|
|
1379
|
-
output += `/** ${schema.description} */
|
|
1380
|
-
`;
|
|
1381
|
-
}
|
|
1382
|
-
output += `export interface ${mainTypeName} {
|
|
1383
|
-
${generateTypeProperties(schema.fields, mainTypeName)}
|
|
1384
|
-
}`;
|
|
1385
|
-
const nestedTypes = generateNestedTypes(schema.fields, mainTypeName);
|
|
1386
|
-
if (nestedTypes) {
|
|
1387
|
-
output += `
|
|
1388
|
-
${nestedTypes}`;
|
|
1389
|
-
}
|
|
1390
|
-
output += "\n";
|
|
1391
|
-
return output;
|
|
1392
|
-
}
|
|
1393
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
1394
|
-
0 && (module.exports = {
|
|
1395
|
-
JsonPatchError,
|
|
1396
|
-
MigrationError,
|
|
1397
|
-
MigrationErrorCode,
|
|
1398
|
-
MigrationSchema,
|
|
1399
|
-
applyPatch,
|
|
1400
|
-
calculateNextVersion,
|
|
1401
|
-
compareSemanticVersions,
|
|
1402
|
-
createPatch,
|
|
1403
|
-
createSchemaMigrationHelper,
|
|
1404
|
-
createStandardSchemaValidator,
|
|
1405
|
-
deepMerge,
|
|
1406
|
-
generateSHA256Hash,
|
|
1407
|
-
normalizePath,
|
|
1408
|
-
schemaChangeToPatch,
|
|
1409
|
-
schemaToTypes,
|
|
1410
|
-
sortSemanticVars,
|
|
1411
|
-
validate,
|
|
1412
|
-
validateMigration,
|
|
1413
|
-
validateSchemaChange,
|
|
1414
|
-
validateSchemaDefinition
|
|
1415
|
-
});
|
|
1
|
+
"use strict";var ce=Object.create;var T=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var me=Object.getOwnPropertyNames;var de=Object.getPrototypeOf,le=Object.prototype.hasOwnProperty;var fe=(r,t)=>{for(var e in t)T(r,e,{get:t[e],enumerable:!0})},Q=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of me(t))!le.call(r,a)&&a!==e&&T(r,a,{get:()=>t[a],enumerable:!(n=pe(t,a))||n.enumerable});return r};var C=(r,t,e)=>(e=r!=null?ce(de(r)):{},Q(t||!r||!r.__esModule?T(e,"default",{value:r,enumerable:!0}):e,r)),ue=r=>Q(T({},"__esModule",{value:!0}),r);var Ue={};fe(Ue,{JsonPatchError:()=>g,MigrationEngine:()=>z,MigrationError:()=>h,MigrationErrorCode:()=>ie,MigrationSchema:()=>ae,applyPatch:()=>k,calculateNextVersion:()=>B,compareSemanticVersions:()=>b,createPatch:()=>ge,createSchemaMigrationHelper:()=>oe,createStandardSchemaValidator:()=>ee,deepMerge:()=>J,docgen:()=>Ge,generateSHA256Hash:()=>M,normalizePath:()=>W,schemaChangeToPatch:()=>j,schemaToTypes:()=>He,sortSemanticVars:()=>Ae,validate:()=>xe,validateMigration:()=>G,validateSchemaChange:()=>U,validateSchemaDefinition:()=>O});module.exports=ue(Ue);var je=require("@asaidimu/events");var Ne=require("@asaidimu/events"),P=require("@asaidimu/query");var g=class extends Error{constructor(e,n){super(e);this.operation=n;this.name="JsonPatchError"}};function I(r){let t=W(r);return t===""?[]:t.substring(1).split("/").map(he)}function W(r){return r===""||r==="/"?"":r.startsWith("/")?"/"+r.substring(1).split("/").map(E).join("/"):"/"+r.split(".").map(E).join("/")}function E(r){return r.replace(/~/g,"~0").replace(/\//g,"~1")}function he(r){return r.replace(/~1/g,"/").replace(/~0/g,"~")}var S=new Map;function R(r,t){let e=r;for(let n of t){if(e===null||typeof e!="object")throw new g(`Invalid path - parent not found at ${n}`);if(Array.isArray(e)){let a=n==="-"?e.length:parseInt(n);if(isNaN(a)||a<0||a>e.length)throw new g(`Invalid array index: ${n}`);e=e[a]}else{if(!e.hasOwnProperty(n))throw new g(`Property ${n} not found`);e=e[n]}}return e}function F(r,t){let e=S.get(t)||I(t);if(S.set(t,e),e.length===0)return r;let n=R(r,e.slice(0,-1)),a=e[e.length-1];if(Array.isArray(n)){let i=parseInt(a);if(isNaN(i)||i<0||i>=n.length)throw new g(`Invalid array index: ${a}`);return n[i]}return n[a]}function ye(r,t,e){let n=S.get(t)||I(t);S.set(t,n);let a=R(r,n.slice(0,-1)),i=n[n.length-1];return Array.isArray(a)?a.splice(0,a.length,...a.filter(p=>p!==e)):a[i]===e&&delete a[i],r}function x(r,t,e){let n=S.get(t)||I(t);if(S.set(t,n),n.length===0)return e;let a=n.slice(0,-1),i=n[n.length-1],p=R(r,a);if(Array.isArray(p))if(i==="-")p.push(e);else{let s=parseInt(i);if(s<0||s>p.length)throw new g(`Invalid array index: ${i}`);p.splice(s,0,e)}else p[i]=e;return r}function A(r,t){let e=S.get(t)||I(t);if(S.set(t,e),e.length===0)return;let n=R(r,e.slice(0,-1)),a=e[e.length-1];if(Array.isArray(n)){let i=parseInt(a);n.splice(i,1)}else delete n[a];return r}function k(r,t){let e=JSON.parse(JSON.stringify(r));for(let n of t)try{switch(n.op){case"add":e=x(e,n.path,n.value);break;case"remove":e=A(e,n.path);break;case"removeValue":e=ye(e,n.path,n.value);break;case"replace":e=x(A(e,n.path),n.path,n.value);break;case"copy":{let a=F(e,n.from);e=x(e,n.path,JSON.parse(JSON.stringify(a)));break}case"move":{let a=F(e,n.from);e=x(e,n.path,a),e=A(e,n.from);break}case"test":{let a=F(e,n.path);if(JSON.stringify(a)!==JSON.stringify(n.value))throw new g("Test operation failed");break}default:throw new g(`Unsupported operation: ${n.op}`)}}catch(a){throw a instanceof g&&(a.operation=n),a}return e}function ge(r,t){let e=[];return N(r,t,"",e),e}function N(r,t,e,n){if(r!==t){if(typeof r!=typeof t||Array.isArray(r)!==Array.isArray(t)){n.push({op:"replace",path:e,value:t});return}typeof r=="object"&&r!==null?Array.isArray(r)?we(r,t,e,n):Se(r,t,e,n):r!==t&&n.push({op:"replace",path:e,value:t})}}function we(r,t,e,n){let a=Math.max(r.length,t.length);for(let i=0;i<a;i++){let p=`${e}/${i}`;i>=r.length?n.push({op:"add",path:`${e}/-`,value:t[i]}):i>=t.length?n.push({op:"remove",path:p}):N(r[i],t[i],p,n)}}function Se(r,t,e,n){let a=new Set,i=Object.keys(r),p=Object.keys(t);for(let s of i){let d=E(s),c=e?`${e}/${d}`:`/${d}`;t.hasOwnProperty(s)?(N(r[s],t[s],c,n),a.add(s)):n.push({op:"remove",path:c})}for(let s of p)if(!a.has(s)){let d=E(s),c=e?`${e}/${d}`:`/${d}`;n.push({op:"add",path:c,value:t[s]})}}function j(r,t){let e=[];switch(r.type){case"addField":e.push({op:"add",path:`/fields/${r.name}`,value:r.definition});break;case"removeField":e.push({op:"remove",path:`/fields/${r.name}`});break;case"modifyField":{let n=`/fields/${r.name}`;Object.entries(r.changes).forEach(([a,i])=>{typeof i=="object"&&i!==null&&!Array.isArray(i)?e.push({op:"replace",path:`${n}/${a}`,value:i}):e.push({op:"replace",path:`${n}/${a}`,value:i})});break}case"deprecateField":e.push({op:"add",path:`/fields/${r.name}/deprecated`,value:!0});break;case"addIndex":t.indexes||e.push({op:"add",path:"/indexes",value:[]}),e.push({op:"add",path:"/indexes/-",value:r.definition});break;case"removeIndex":{let n=t.indexes?.findIndex(a=>a.name===r.name);n!==void 0&&n>=0&&e.push({op:"remove",path:`/indexes/${n}`});break}case"modifyIndex":{let n=t.indexes?.findIndex(a=>a.name===r.name);n!==void 0&&n>=0&&Object.entries(r.changes).forEach(([a,i])=>{e.push({op:"replace",path:`/indexes/${n}/${a}`,value:i})});break}case"addConstraint":t.constraints||e.push({op:"add",path:"/constraints",value:[]}),Array.isArray(r.constraint)?r.constraint.forEach(n=>{e.push({op:"add",path:"/constraints/-",value:n})}):e.push({op:"add",path:"/constraints/-",value:r.constraint});break;case"removeConstraint":{let n=t.constraints?.findIndex(a=>Array.isArray(a)?a.some(i=>i.name===r.name):a.name===r.name);n!==void 0&&n>=0&&e.push({op:"remove",path:`/constraints/${n}`});break}case"modifyConstraint":{let n=be(t,r.name);n&&Object.entries(r.changes).forEach(([a,i])=>{e.push({op:"replace",path:`${n}/${a}`,value:i})});break}}return e}function be(r,t){if(!r.constraints)return null;for(let e=0;e<r.constraints.length;e++){let n=r.constraints[e];if(n.name===t)return`/constraints/${e}`;if(Z(n)){let a=X(n.rules,t);if(a)return`/constraints/${e}${a}`}}return null}function Z(r){return r&&"operator"in r&&"rules"in r}function X(r,t){for(let e=0;e<r.length;e++){let n=r[e];if("name"in n&&n.name===t)return`/rules/${e}`;if(Z(n)){let a=X(n.rules,t);if(a)return`/rules/${e}${a}`}}return null}function J(r,t){let e={...r};return V(r)&&V(t)&&Object.keys(t).forEach(n=>{V(t[n])?n in r?e[n]=J(r[n],t[n]):Object.assign(e,{[n]:t[n]}):Object.assign(e,{[n]:t[n]})}),e}function V(r){return r&&typeof r=="object"&&!Array.isArray(r)}function ee(r,t){let e=(c,l,f,m)=>{let u=[];switch(f.type){case"string":typeof c!="string"&&u.push({message:`Expected type string but received ${typeof c}.`,path:m});break;case"number":typeof c!="number"&&u.push({message:`Expected type number but received ${typeof c}.`,path:m});break;case"boolean":typeof c!="boolean"&&u.push({message:`Expected type boolean but received ${typeof c}.`,path:m});break;case"array":Array.isArray(c)?f.itemsType?c.forEach((y,w)=>{u.push(...e(y,`Array: ${l}`,{type:f.itemsType,nestedSchema:f.nestedSchema},[...m,w]))}):u.push({message:`Expected itemsType for array ${l}`,path:m}):u.push({message:`Expected an array but received ${typeof c}.`,path:m});break;case"object":if(typeof c!="object"||c===null)u.push({message:`Expected an object but received ${c===null?"null":typeof c}.`,path:m});else if(f.nestedSchema){let y={name:f.description?`${f.description}-schema`:"nested-schema",version:"1.0",fields:f.nestedSchema};u.push(...d(y,c,m))}break;case"dynamic":break;default:u.push({message:`Unknown field type: ${f.type}`,path:m});break}return u},n=(c,l,f,m)=>{let u=[];return l.constraints&&l.constraints.forEach(y=>{let w=t[y.predicate];w?(y.type==="schema"?w({data:f,arguments:y.parameters}):w({data:f,field:c,arguments:y.parameters}))||u.push({message:`Constraint '${y.name}' failed for field '${c}'.`,path:m}):u.push({message:`Missing predicate for constraint: ${y.name}`,path:m})}),u},a=(c,l,f,m,u)=>[...e(f,c,l,u),...n(c,l,m,u)],i=(c,l,f)=>{if("operator"in c)return p(c.operator,c.rules.map(u=>i(u,l,f)));let m=t[c.predicate];return m?c.type==="schema"?m({data:l,field:c.field,arguments:c.parameters}):m({data:l,field:f,arguments:c.parameters}):!1},p=(c,l)=>{switch(c){case"and":return l.every(Boolean);case"or":return l.some(Boolean);case"not":return l.length===1?!l[0]:!1;case"nor":return!l.some(Boolean);case"xor":return l.filter(Boolean).length===1;default:return console.error(`Unknown logical operator: ${c}`),!1}},s=c=>"operator"in c?`(${c.rules.map(s).join(` ${c.operator} `)})`:c.name,d=(c,l,f=[])=>{let m=[];for(let[u,y]of Object.entries(c.fields))y.required&&l[u]===void 0&&m.push({message:`Field '${u}' is required.`,path:[...f,u]});for(let[u,y]of Object.entries(c.fields)){let w=l[u];w!==void 0&&m.push(...a(u,y,w,l,[...f,u]))}return c.constraints&&c.constraints.forEach(u=>{i(u,l)||m.push({message:`Schema constraint failed: ${s(u)}`,path:f})}),m};return{"~standard":{version:1,vendor:"@asaidimu/anansi",validate:c=>{if(typeof c!="object"||c===null)return{issues:[{message:"Value must be a non-null object",path:[]}]};let l=d(r,c);return l.length===0?{value:c}:{issues:l}}}}}var o=require("zod");var v=class extends Error{constructor(e,n){super(e);this.errors=n;this.name="SchemaValidationError"}};var ne=o.z.enum(["and","or","not","nor","xor"]),te=o.z.enum(["string","number","boolean","array","object","dynamic"]),ve=o.z.enum(["normal","unique","btree","hash","spatial","fulltext","gi","expression","composite"]),Ce=o.z.custom(()=>!0),$=o.z.object({type:o.z.string().optional(),name:o.z.string(),predicate:o.z.string().optional(),parameters:Ce.optional(),description:o.z.string().optional(),field:o.z.string().optional(),errorMessage:o.z.string().optional()}),H=o.z.object({operator:ne,rules:o.z.array(o.z.union([$,o.z.lazy(()=>H)]))}),D=o.z.object({type:te,required:o.z.boolean().optional(),constraints:o.z.array($).optional(),default:o.z.any().optional(),itemsType:te.optional(),nestedSchema:o.z.record(o.z.lazy(()=>D)).optional(),deprecated:o.z.boolean().optional(),reference:o.z.object({schema:o.z.string(),field:o.z.string()}).optional(),description:o.z.string().optional(),unique:o.z.boolean().optional()}),re=o.z.object({operator:ne,field:o.z.string(),value:o.z.any().optional(),conditions:o.z.array(o.z.lazy(()=>re)).optional()}),_=o.z.object({fields:o.z.array(o.z.string()),type:ve,unique:o.z.boolean().optional(),partial:re.optional(),description:o.z.string().optional(),order:o.z.enum(["asc","desc"]).optional(),name:o.z.string().optional()}),$e=o.z.array(o.z.union([$,H])),Te=o.z.object({name:o.z.string(),version:o.z.string(),description:o.z.string().optional(),fields:o.z.record(D),indexes:o.z.array(_).optional(),constraints:$e.optional(),metadata:o.z.record(o.z.any()).optional(),dependencies:o.z.array(o.z.string()).optional(),migrations:o.z.array(o.z.any()).optional()}),L=o.z.union([o.z.object({type:o.z.literal("addField"),name:o.z.string(),definition:D}),o.z.object({type:o.z.literal("removeField"),name:o.z.string()}),o.z.object({type:o.z.literal("modifyField"),name:o.z.string(),changes:D.partial()}),o.z.object({type:o.z.literal("addIndex"),definition:_}),o.z.object({type:o.z.literal("removeIndex"),name:o.z.string()}),o.z.object({type:o.z.literal("modifyIndex"),name:o.z.string(),changes:_.partial()}),o.z.object({type:o.z.literal("addConstraint"),constraint:o.z.union([$,H])}),o.z.object({type:o.z.literal("removeConstraint"),name:o.z.string()}),o.z.object({type:o.z.literal("modifyConstraint"),name:o.z.string(),changes:$.partial()}),o.z.object({type:o.z.literal("deprecateField"),name:o.z.string()})]),ae=o.z.object({id:o.z.string(),schemaVersion:o.z.string(),changes:o.z.array(L),description:o.z.string(),status:o.z.enum(["pending","applied","failed"]),rollback:o.z.array(L).optional(),transform:o.z.unknown(),createdAt:o.z.string(),checksum:o.z.string().optional()});function G(r){try{return ae.parse(r),!0}catch(t){throw new v("Invalid migration definition",t)}}function U(r){try{return L.parse(r),!0}catch(t){throw new v("Invalid schema definition",t)}}function O(r){try{return Te.parse(r),!0}catch(t){throw new v("Invalid schema definition",t)}}var xe=O;var M=async r=>{if(typeof window<"u"&&crypto.subtle){let e=new TextEncoder().encode(r),n=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(n)).map(i=>i.toString(16).padStart(2,"0")).join("")}else{let{createHash:t}=await import("crypto");return t("sha256").update(r).digest("hex")}};function Ee(r){let t=r.match(/^(\d+)\.(\d+)\.(\d+)$/);if(!t)throw new Error(`Invalid version format: ${r}. Expected format: major.minor.patch`);return{major:parseInt(t[1],10),minor:parseInt(t[2],10),patch:parseInt(t[3],10)}}function Ie(r,t){if(t&&"field"in r&&r.field){let e=t.fields[r.field];if(e)return e.type}if("parameters"in r){let e=r.parameters;if(e instanceof RegExp||Array.isArray(e)&&typeof e[0]=="string")return"string";if(typeof e=="number"||Array.isArray(e)&&typeof e[0]=="number")return"number";if(typeof e=="boolean")return"boolean";if(typeof e=="object"&&e!==null){if("minItems"in e||"maxItems"in e)return"array";if("schema"in e)return"object"}}}function Re(r){return r.required===!0||r.type!==void 0||r.itemsType!==void 0||r.nestedSchema!==void 0||r.reference!==void 0||r.unique===!0}function ke(r,t,e){switch(e){case"string":if(r instanceof RegExp&&t instanceof RegExp)return r.source!==t.source;if(Array.isArray(r)&&Array.isArray(t))return t.length<r.length||!r.every(n=>t.includes(n));break;case"number":if(typeof r=="object"&&typeof t=="object"&&"precision"in r&&"precision"in t)return t.precision<r.precision||(t.scale??0)<(r.scale??0);if(Array.isArray(r)&&Array.isArray(t))return t.length<r.length||!r.every(n=>t.includes(n));break;case"array":if(typeof r=="object"&&typeof t=="object"&&"minItems"in r&&"maxItems"in r&&"minItems"in t&&"maxItems"in t)return t.minItems>r.minItems||t.maxItems<r.maxItems;break;case"object":if(typeof r=="object"&&typeof t=="object"&&"schema"in r&&"schema"in t)return Object.keys(t.schema).length>Object.keys(r.schema).length;break}return!1}function De(r,t){let e={or:1,xor:2,and:3,not:4,nor:4};return!!(t.operator&&e[t.operator]>e[r.operator]||t.rules&&t.rules.length>r.rules.length)}function Oe(r,t,e){if(!t)return!0;if("rules"in t&&"rules"in r)return De(t,r);if("predicate"in r&&r.predicate!==void 0)return!0;if("parameters"in r&&r.parameters!==void 0){let n=Ie(t,e);return n?ke(t.parameters,r.parameters,n):!0}return!1}function Me(r,t){switch(r.type){case"removeField":case"removeIndex":return"major";case"modifyField":return Re(r.changes)?"major":r.changes.deprecated?"minor":"patch";case"modifyIndex":return r.changes.unique!==void 0||r.changes.fields!==void 0?"major":"minor";case"addConstraint":return"major";case"removeConstraint":return"minor";case"modifyConstraint":let e=t?.constraints?.find(n=>"name"in n&&n.name===r.name);return Oe(r.changes,e,t)?"major":"minor";case"addField":case"addIndex":case"deprecateField":return"minor";default:throw new Error(`Unhandled change type: ${JSON.stringify(r)}`)}}function Pe(r){let t=new Set,e=new Set,n=new Set,a=new Set;for(let i of r)switch(i.type){case"addField":if(e.has(i.name))throw new Error(`Cannot add previously removed field: ${i.name}`);if(t.has(i.name))throw new Error(`Cannot add already modified field: ${i.name}`);if(a.has(i.name))throw new Error(`Cannot add deprecated field: ${i.name}`);n.add(i.name);break;case"removeField":if(n.has(i.name))throw new Error(`Cannot remove newly added field: ${i.name}`);if(t.has(i.name))throw new Error(`Cannot remove modified field: ${i.name}`);if(a.has(i.name))throw new Error(`Cannot remove field that is being deprecated: ${i.name}`);e.add(i.name);break;case"modifyField":if(e.has(i.name))throw new Error(`Cannot modify removed field: ${i.name}`);if(n.has(i.name))throw new Error(`Cannot modify newly added field: ${i.name}`);if(a.has(i.name))throw new Error(`Cannot modify field that is being deprecated: ${i.name}`);t.add(i.name);break;case"deprecateField":if(e.has(i.name))throw new Error(`Cannot deprecate removed field: ${i.name}`);if(n.has(i.name))throw new Error(`Cannot deprecate newly added field: ${i.name}`);if(t.has(i.name))throw new Error(`Cannot deprecate modified field: ${i.name}`);a.add(i.name);break}}function Fe(r){let t=new Set,e=new Set,n=new Set;for(let a of r)switch(a.type){case"addConstraint":let i=a.constraint,p=("name"in i,i.name);if(e.has(p))throw new Error(`Cannot add previously removed constraint: ${p}`);if(t.has(p))throw new Error(`Cannot add already modified constraint: ${p}`);n.add(p);break;case"removeConstraint":if(n.has(a.name))throw new Error(`Cannot remove newly added constraint: ${a.name}`);if(t.has(a.name))throw new Error(`Cannot remove modified constraint: ${a.name}`);e.add(a.name);break;case"modifyConstraint":if(e.has(a.name))throw new Error(`Cannot modify removed constraint: ${a.name}`);if(n.has(a.name))throw new Error(`Cannot modify newly added constraint: ${a.name}`);t.add(a.name);break}}function B(r,t,e){if(t.length===0)throw new Error("No changes provided");Pe(t),Fe(t);let n=Ee(r),a="patch";for(let i of t){let p=Me(i,e);if(p==="major"){a="major";break}else p==="minor"&&a==="patch"&&(a="minor")}switch(a){case"major":return`${n.major+1}.0.0`;case"minor":return`${n.major}.${n.minor+1}.0`;case"patch":return`${n.major}.${n.minor}.${n.patch+1}`}}function b(r,t){let e=c=>c.split(".").map(l=>parseInt(l,10)||0),[n,a,i]=e(r),[p,s,d]=e(t);return n-p||a-s||i-d}function Ae(r){return r.sort(b)}var h=class extends Error{constructor(e,n,a,i){super(e);this.code=n;this.migrationId=a;this.cause=i;this.name="MigrationError"}},ie=(m=>(m.INVALID_SCHEMA="INVALID_SCHEMA",m.INVALID_MIGRATION="INVALID_MIGRATION",m.CHECKSUM_MISMATCH="CHECKSUM_MISMATCH",m.TIMEOUT="TIMEOUT",m.MEMORY_LIMIT="MEMORY_LIMIT",m.CONCURRENT_OPERATION="CONCURRENT_OPERATION",m.TRANSFORM_ERROR="TRANSFORM_ERROR",m.VERSION_NOT_FOUND="VERSION_NOT_FOUND",m.CIRCULAR_DEPENDENCY="CIRCULAR_DEPENDENCY",m.STREAM_ERROR="STREAM_ERROR",m.ROLLBACK_ERROR="ROLLBACK_ERROR",m.MISSING_TRANSFORM="MISSING_TRANSFORM",m))(ie||{}),z=class r{currentSchema;history=[];migrations=[];isProcessing=!1;constructor(t,e,n){try{if(!O(t))throw new h("Invalid initial schema","INVALID_SCHEMA");if(this.currentSchema=t,e){if(!e.every(a=>G(a)))throw new h("Invalid migration configuration","INVALID_MIGRATION");this.migrations=e.sort((a,i)=>b(a.schemaVersion,i.schemaVersion))}n&&(this.history=n.sort((a,i)=>b(a.version,i.version)))}catch(a){throw a instanceof h?a:new h("Failed to initialize MigrationEngine","INVALID_SCHEMA",void 0,a)}}data(){return{schema:this.currentSchema,history:this.history,migrations:this.migrations}}async generateChecksum(t){try{let e=JSON.stringify({id:t.id,schemaVersion:t.schemaVersion,changes:t.changes,description:t.description,rollback:t.rollback,createdAt:t.createdAt});return await M(e)}catch(e){throw new h("Checksum generation failed","CHECKSUM_MISMATCH",t.id,e)}}async add(t){if(this.isProcessing)throw new h("Concurrent operation","CONCURRENT_OPERATION");if(!t.changes?.length)throw new h("Migration must include changes","INVALID_MIGRATION");try{t.changes.forEach(n=>U(n))}catch(n){throw new h("Invalid schema changes","INVALID_MIGRATION",void 0,n)}let e={id:Date.now().toString(),schemaVersion:this.currentSchema.version,changes:t.changes,description:t.description,status:"pending",rollback:t.rollback,transform:t.transform,createdAt:new Date().toISOString(),checksum:""};e.checksum=await this.generateChecksum(e),this.migrations.push(e)}async dryRun(t,e,n){if(this.isProcessing)throw new h("Concurrent operation","CONCURRENT_OPERATION");try{this.isProcessing=!0;let a={...this.currentSchema},i=this.getRelevantMigrations(e,n),p=i.reduce((d,c)=>{let l=e==="forward"?c.changes:c.rollback||[];return this.applySchemaChanges(d,l,c.id)},a),s=await r.processMigrationList(t,e,i);return{newSchema:p,dataPreview:s}}catch(a){throw a instanceof h?a:new h("Dry run failed","INVALID_SCHEMA",void 0,a)}finally{this.isProcessing=!1}}getRelevantMigrations(t,e){return[...this.migrations].filter(n=>{let a=t==="forward"?"pending":"applied",i=e?b(n.schemaVersion,e)>=0:!0;return n.status===a&&i}).sort((n,a)=>t==="forward"?n.id.localeCompare(a.id):a.id.localeCompare(n.id))}applySchemaChanges(t,e,n){try{let a=B(t.version,e);return e.map(p=>{try{return j(p,t)}catch(s){throw new h("Invalid schema change","INVALID_SCHEMA",n,s)}}).reduce((p,s)=>{try{return k(p,s)}catch(d){throw new h("Failed to apply patch","INVALID_SCHEMA",n,d)}},{...t,version:a})}catch(a){throw a instanceof h?a:new h("Schema update failed","INVALID_SCHEMA",n,a)}}async prepareMigration(){let t=this.migrations.filter(e=>e.status==="pending");return await this.validateMigrations(t),t}async migrate(t){if(this.isProcessing)throw new h("Concurrent operation","CONCURRENT_OPERATION");let e=await this.prepareMigration();try{this.isProcessing=!0,this.transformSchema("forward");let n=await r.processMigrationList(t,"forward",e);return this.markMigrationsApplied(e),n}finally{this.isProcessing=!1}}async validateMigrations(t){await Promise.all(t.map(async e=>{let n=await this.generateChecksum(e);if(e.checksum!==n)throw new h("Checksum mismatch","CHECKSUM_MISMATCH",e.id)}))}markMigrationsApplied(t){this.migrations=this.migrations.map(e=>t.some(n=>n.id===e.id)?{...e,status:"applied"}:e)}async rollback(t){if(this.isProcessing)throw new h("Concurrent operation","CONCURRENT_OPERATION");return this.migrations.filter(n=>n.status==="applied").slice(-1)[0]?this.rollbackToVersion(this.history[this.history.length-1]?.version||this.currentSchema.version,t):t}async rollbackToVersion(t,e){if(this.isProcessing)throw new h("Concurrent operation","CONCURRENT_OPERATION");try{let n=this.history.findIndex(s=>s.version===t);if(n===-1)throw new Error(`Version ${t} not found in history`);let a=this.migrations.filter(s=>s.schemaVersion===t&&s.status==="applied").sort((s,d)=>d.id.localeCompare(s.id)),i=this.history.length-n;if(i<0)return e;for(let s=0;s<i;s++)this.transformSchema("backward");let p=await r.processMigrationList(e,"backward",a);return this.migrations=this.migrations.map(s=>s.schemaVersion===t&&s.status==="applied"?{...s,status:"pending"}:s),p}finally{this.isProcessing=!1}}static async processMigrationList(t,e,n){return(await Promise.all(n.map(async p=>{try{let s=await this.resolveTransform(p,e);return{migration:p,transform:s}}catch(s){throw new h(`Failed to resolve transform for migration ${p.id}`,"TRANSFORM_ERROR",p.id,s)}}))).filter(p=>!!p.transform).reduce((p,{migration:s,transform:d})=>p.pipeThrough(new TransformStream({async transform(c,l){try{let f=await d(c);l.enqueue(f)}catch(f){l.error(new h(`Data transformation failed for migration ${s.id}`,"TRANSFORM_ERROR",s.id,f))}}})),t)}static async resolveTransform(t,e){return t.transform?typeof t.transform=="string"?t.transform.startsWith("http://")||t.transform.startsWith("https://")?this.resolveRemoteTransform(t.transform,e):this.resolveLocalTransform(t.transform,e):t.transform[e]:null}static async resolveRemoteTransform(t,e){try{let n=await fetch(t);if(!n.ok)throw new h(`Failed to fetch transform module: ${t}`,"TRANSFORM_ERROR",void 0);let a=await n.text();if(typeof window<"u"){let i=new Blob([a],{type:"application/javascript"});return(await import(URL.createObjectURL(i))).default[e]}else{let{runInNewContext:i}=await import("vm"),p={module:{exports:{}},console};return i(a,p,t),p.module.exports[e]}}catch(n){throw new h(`Failed to load remote transform module: ${t}`,"TRANSFORM_ERROR",void 0,n)}}static async resolveLocalTransform(t,e){try{return(await import(t)).default[e]}catch(n){throw new h(`Failed to import local transform module: ${t}`,"TRANSFORM_ERROR",void 0,n)}}transformSchema(t){try{if(t==="backward"){let n=this.history.pop();if(!n)throw new Error("No previous version");this.currentSchema=n;return}let e=this.migrations.filter(n=>n.status==="pending").flatMap(n=>n.changes);if(!e.length)return;this.history.push(structuredClone(this.currentSchema)),this.currentSchema=e.reduce((n,a)=>this.applySchemaChanges(n,[a]),this.currentSchema)}catch(e){throw e instanceof h?e:new h("Schema transformation failed","INVALID_SCHEMA",void 0,e)}}};var oe=r=>{let t=[],e=[];return{addField:(n,a)=>{t.push({type:"addField",name:n,definition:a}),e.push({type:"removeField",name:n})},removeField:n=>{t.push({type:"removeField",name:n});let a=r.fields[n];a&&e.push({type:"addField",name:n,definition:a})},modifyField:(n,a)=>{t.push({type:"modifyField",name:n,changes:a});let i=r.fields[n];e.push({type:"modifyField",name:n,changes:i})},deprecateField:n=>{t.push({type:"deprecateField",name:n}),e.push({type:"modifyField",name:n,changes:{deprecated:!1}})},addIndex:n=>{t.push({type:"addIndex",definition:n}),e.push({type:"removeIndex",name:n.name})},removeIndex:n=>{t.push({type:"removeIndex",name:n});let a=r.indexes?.find(i=>i.name===n);a&&e.push({type:"addIndex",definition:a})},modifyIndex:(n,a)=>{t.push({type:"modifyIndex",name:n,changes:a});let i=r.indexes?.find(p=>p.name===n);i&&e.push({type:"modifyIndex",name:n,changes:i})},addConstraint:n=>{t.push({type:"addConstraint",constraint:n}),e.push({type:"removeConstraint",name:n.name})},removeConstraint:n=>{t.push({type:"removeConstraint",name:n});let a=r.constraints?.find(i=>"name"in i&&i.name===n);a&&e.push({type:"addConstraint",constraint:a})},modifyConstraint:(n,a)=>{t.push({type:"modifyConstraint",name:n,changes:a});let i=r.constraints?.find(p=>"name"in p&&p.name===n);i&&e.push({type:"modifyConstraint",name:n,changes:i})},changes:()=>({migrate:t,rollback:e})}};var Ve=C(require("@isomorphic-git/lightning-fs"),1),se=require("buffer"),Je=C(require("isomorphic-git"),1),_e=C(require("isomorphic-git/http/web"),1);window.Buffer=se.Buffer;function Le(r,t,e){switch(r.type){case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"array":return r.itemsType?r.itemsType==="object"&&r.nestedSchema?`${`${t}ItemsItem`}[]`:`${r.itemsType}[]`:"any[]";case"object":return r.nestedSchema?`${t}${Y(e)}`:"Record<string, any>";case"dynamic":return"any";default:return"any"}}function q(r,t){let e="";for(let[n,a]of Object.entries(r))if(a.type==="object"&&a.nestedSchema){let i=`${t}${Y(n)}`;e+=`
|
|
2
|
+
export interface ${i} {
|
|
3
|
+
${K(a.nestedSchema,i)}
|
|
4
|
+
}`;let p=q(a.nestedSchema,i);p&&(e+=`
|
|
5
|
+
${p}`)}else if(a.type==="array"&&a.itemsType==="object"&&a.nestedSchema){let i=`${t}ItemsItem`;e+=`
|
|
6
|
+
export interface ${i} {
|
|
7
|
+
${K(a.nestedSchema,i)}
|
|
8
|
+
}`;let p=q(a.nestedSchema,i);p&&(e+=`
|
|
9
|
+
${p}`)}return e}function K(r,t){return Object.entries(r).map(([e,n])=>{let a=[];n.description&&a.push(` /** ${n.description} */`),n.deprecated&&a.push(" /** @deprecated */");let i=n.required?"":"?",p=Le(n,t,e);return a.push(` ${e}${i}: ${p};`),a.join(`
|
|
10
|
+
`)}).join(`
|
|
11
|
+
`)}function Y(r){return r.charAt(0).toUpperCase()+r.slice(1)}function He(r){let t=Y(r.name),e=`// Generated from schema version ${r.version}
|
|
12
|
+
`;r.description&&(e+=`/** ${r.description} */
|
|
13
|
+
`),e+=`export interface ${t} {
|
|
14
|
+
${K(r.fields,t)}
|
|
15
|
+
}`;let n=q(r.fields,t);return n&&(e+=`
|
|
16
|
+
${n}`),e+=`
|
|
17
|
+
`,e}function Ge(r,t){let e=[],n=s=>s===void 0?"`None`":`\`${JSON.stringify(s,null,2)}\``,a=(s=[])=>s.map(d=>`- **${d.name}**: ${d.description||""}
|
|
18
|
+
- Parameters: ${JSON.stringify(d.parameters)}
|
|
19
|
+
- Error: ${d.errorMessage||"None"}`).join(`
|
|
20
|
+
`),i=s=>{let d=`**${s.field}** ${s.operator}`;return s.value!==void 0&&(d+=` ${JSON.stringify(s.value)}`),s.conditions&&(d+=` [
|
|
21
|
+
${s.conditions.map(c=>` ${i(c)}`).join(`
|
|
22
|
+
`)}
|
|
23
|
+
]`),d},p=(s,d=1)=>{let c="#".repeat(d+2);return Object.entries(s).map(([l,f])=>{let m=`${c} ${l} (${f.type})
|
|
24
|
+
|
|
25
|
+
`;return m+=`**Required:** ${f.required?"Yes":"No"}
|
|
26
|
+
|
|
27
|
+
`,f.description&&(m+=`**Description:** ${f.description}
|
|
28
|
+
|
|
29
|
+
`),f.itemsType&&(m+=`**Item Type:** ${f.itemsType}
|
|
30
|
+
|
|
31
|
+
`),f.nestedSchema&&(m+=p(f.nestedSchema,d+1)),m}).join(`
|
|
32
|
+
`)};e.push(`# ${r.name} Schema (Version ${r.version})`),r.description&&e.push(`
|
|
33
|
+
${r.description}
|
|
34
|
+
`),e.push("## Metadata"),e.push(`- **Dependencies:** ${r.dependencies?.join(", ")||"None"}`),e.push(`- **Created:** ${new Date().toISOString()}
|
|
35
|
+
`),e.push(`## Fields
|
|
36
|
+
`),e.push("| Name | Type | Required | Default | Description | Deprecated | Unique | Constraints |"),e.push("|------|------|----------|---------|-------------|------------|--------|-------------|");for(let[s,d]of Object.entries(r.fields))e.push([s,d.type,d.required?"Yes":"No",n(d.default),d.description?.replace(/\n/g," ")||"",d.deprecated?"Yes":"No",d.unique?"Yes":"No",d.constraints?.length||0].join("|"));Object.entries(r.fields).forEach(([s,d])=>{d.nestedSchema&&(e.push(`
|
|
37
|
+
### Nested Schema: ${s}
|
|
38
|
+
`),e.push(p(d.nestedSchema)))}),e.push(`
|
|
39
|
+
## Indexes
|
|
40
|
+
`),e.push("| Name | Type | Fields | Unique | Order | Partial Condition | Description |"),e.push("|------|------|--------|--------|-------|-------------------|-------------|");for(let s of r.indexes||[])e.push([s.name,s.type,s.fields.join(", "),s.unique?"Yes":"No",s.order||"asc",s.partial?i(s.partial):"None",s.description||""].join("|"));e.push(`
|
|
41
|
+
## Constraints
|
|
42
|
+
`),r.constraints&&e.push("### Schema-level Constraints"),e.push(`
|
|
43
|
+
## Migrations
|
|
44
|
+
`),e.push("| ID | Description | Status | Changes |"),e.push("|----|-------------|--------|---------|");for(let s of r.migrations||[])e.push([s.id,s.description,s.status,s.changes.length].join("|"));if(r.mock&&t?.faker)try{let s=r.mock(t.faker).next().value;e.push("\n## Example Data\n```json\n"+JSON.stringify(s,null,2)+"\n```")}catch{e.push(`
|
|
45
|
+
<!-- Error generating mock data -->`)}return e.join(`
|
|
46
|
+
`)}0&&(module.exports={JsonPatchError,MigrationEngine,MigrationError,MigrationErrorCode,MigrationSchema,applyPatch,calculateNextVersion,compareSemanticVersions,createPatch,createSchemaMigrationHelper,createStandardSchemaValidator,deepMerge,docgen,generateSHA256Hash,normalizePath,schemaChangeToPatch,schemaToTypes,sortSemanticVars,validate,validateMigration,validateSchemaChange,validateSchemaDefinition});
|