@asaidimu/anansi 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. package/index.cjs +40 -1834
  2. package/index.d.cts +2 -319
  3. package/index.d.ts +2 -319
  4. package/index.js +22 -1828
  5. package/package.json +1 -1
package/index.cjs CHANGED
@@ -30,40 +30,30 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- MigrationTypes: () => migrations_exports,
34
- PersistenceTypes: () => persistence_exports,
35
- RegistryType: () => registry_exports,
36
- SchemaTypes: () => schema_definition_exports,
37
- crypto: () => crypto_exports,
38
- merge: () => merge_exports,
39
- migration: () => migration_exports,
40
- patch: () => patch_exports,
41
- persistence: () => persistence_exports2,
42
- registry: () => registry_exports2,
43
- schema: () => schema_exports,
44
- typegen: () => typegen_exports,
45
- validator: () => validator_exports,
46
- version: () => version_exports
33
+ JsonPatchError: () => JsonPatchError,
34
+ MigrationError: () => MigrationError,
35
+ MigrationErrorCode: () => MigrationErrorCode,
36
+ MigrationSchema: () => MigrationSchema,
37
+ applyPatch: () => applyPatch,
38
+ calculateNextVersion: () => calculateNextVersion,
39
+ compareSemanticVersions: () => compareSemanticVersions,
40
+ createPatch: () => createPatch,
41
+ createSchemaMigrationHelper: () => createSchemaMigrationHelper,
42
+ createStandardSchemaValidator: () => createStandardSchemaValidator,
43
+ deepMerge: () => deepMerge,
44
+ generateSHA256Hash: () => generateSHA256Hash,
45
+ normalizePath: () => normalizePath,
46
+ schemaChangeToPatch: () => schemaChangeToPatch,
47
+ schemaToTypes: () => schemaToTypes,
48
+ sortSemanticVars: () => sortSemanticVars,
49
+ validate: () => validate,
50
+ validateMigration: () => validateMigration,
51
+ validateSchemaChange: () => validateSchemaChange,
52
+ validateSchemaDefinition: () => validateSchemaDefinition
47
53
  });
48
54
  module.exports = __toCommonJS(index_exports);
49
55
 
50
- // src/types/migrations.ts
51
- var migrations_exports = {};
52
-
53
- // src/types/persistence.ts
54
- var persistence_exports = {};
55
-
56
- // src/types/registry.ts
57
- var registry_exports = {};
58
-
59
- // src/types/schema-definition.ts
60
- var schema_definition_exports = {};
61
-
62
56
  // src/lib/persistence/index.ts
63
- var persistence_exports2 = {};
64
- __export(persistence_exports2, {
65
- default: () => createEphemeralPersistence
66
- });
67
57
  var import_events2 = require("@asaidimu/events");
68
58
 
69
59
  // src/lib/persistence/collection.ts
@@ -71,14 +61,6 @@ var import_events = require("@asaidimu/events");
71
61
  var import_query = require("@asaidimu/query");
72
62
 
73
63
  // src/tools/patch.ts
74
- var patch_exports = {};
75
- __export(patch_exports, {
76
- JsonPatchError: () => JsonPatchError,
77
- applyPatch: () => applyPatch,
78
- createPatch: () => createPatch,
79
- normalizePath: () => normalizePath,
80
- schemaChangeToPatch: () => schemaChangeToPatch
81
- });
82
64
  var JsonPatchError = class extends Error {
83
65
  constructor(message, operation) {
84
66
  super(message);
@@ -484,10 +466,6 @@ function searchRules(rules, name) {
484
466
  }
485
467
 
486
468
  // src/tools/merge.ts
487
- var merge_exports = {};
488
- __export(merge_exports, {
489
- deepMerge: () => deepMerge
490
- });
491
469
  function deepMerge(target, update) {
492
470
  const output = { ...target };
493
471
  if (isObject(target) && isObject(update)) {
@@ -513,10 +491,6 @@ function isObject(item) {
513
491
  }
514
492
 
515
493
  // src/tools/validator.ts
516
- var validator_exports = {};
517
- __export(validator_exports, {
518
- createStandardSchemaValidator: () => createStandardSchemaValidator
519
- });
520
494
  function createStandardSchemaValidator(schema, constraintsMap) {
521
495
  const validateTypeWithErrors = (value, fieldName, fieldDef, path) => {
522
496
  const issues = [];
@@ -718,14 +692,6 @@ function createStandardSchemaValidator(schema, constraintsMap) {
718
692
  };
719
693
  }
720
694
 
721
- // src/lib/migration/index.ts
722
- var migration_exports = {};
723
- __export(migration_exports, {
724
- MigrationError: () => MigrationError,
725
- MigrationErrorCode: () => MigrationErrorCode,
726
- default: () => MigrationEngine
727
- });
728
-
729
695
  // src/lib/schema/validator.ts
730
696
  var import_zod = require("zod");
731
697
 
@@ -847,10 +813,6 @@ function validateSchemaDefinition(schema) {
847
813
  var validate = validateSchemaDefinition;
848
814
 
849
815
  // src/tools/crypto.ts
850
- var crypto_exports = {};
851
- __export(crypto_exports, {
852
- generateSHA256Hash: () => generateSHA256Hash
853
- });
854
816
  var generateSHA256Hash = async (input) => {
855
817
  if (typeof window !== "undefined" && crypto.subtle) {
856
818
  const encoder = new TextEncoder();
@@ -865,12 +827,6 @@ var generateSHA256Hash = async (input) => {
865
827
  };
866
828
 
867
829
  // src/tools/version.ts
868
- var version_exports = {};
869
- __export(version_exports, {
870
- calculateNextVersion: () => calculateNextVersion,
871
- compareSemanticVersions: () => compareSemanticVersions,
872
- sortSemanticVars: () => sortSemanticVars
873
- });
874
830
  function parseVersion(version) {
875
831
  const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
876
832
  if (!match) {
@@ -1211,561 +1167,6 @@ var MigrationErrorCode = /* @__PURE__ */ ((MigrationErrorCode2) => {
1211
1167
  MigrationErrorCode2["MISSING_TRANSFORM"] = "MISSING_TRANSFORM";
1212
1168
  return MigrationErrorCode2;
1213
1169
  })(MigrationErrorCode || {});
1214
- var MigrationEngine = class _MigrationEngine {
1215
- currentSchema;
1216
- history = [];
1217
- migrations = [];
1218
- isProcessing = false;
1219
- /**
1220
- * @constructor
1221
- * @param {SchemaDefinition} currentSchema - The current schema definition
1222
- * @param {Array<Migration<any>>} [migrations] - Optional array of migrations
1223
- */
1224
- constructor(currentSchema, migrations, history) {
1225
- try {
1226
- if (!validateSchemaDefinition(currentSchema)) {
1227
- throw new MigrationError(
1228
- "Invalid initial schema",
1229
- "INVALID_SCHEMA" /* INVALID_SCHEMA */
1230
- );
1231
- }
1232
- this.currentSchema = currentSchema;
1233
- if (migrations) {
1234
- if (!migrations.every((migration) => validateMigration(migration))) {
1235
- throw new MigrationError(
1236
- "Invalid migration configuration",
1237
- "INVALID_MIGRATION" /* INVALID_MIGRATION */
1238
- );
1239
- }
1240
- this.migrations = migrations.sort(
1241
- (a, b) => compareSemanticVersions(a.schemaVersion, b.schemaVersion)
1242
- );
1243
- }
1244
- if (history) {
1245
- this.history = history.sort(
1246
- (a, b) => compareSemanticVersions(a.version, b.version)
1247
- );
1248
- }
1249
- } catch (error) {
1250
- if (error instanceof MigrationError) throw error;
1251
- throw new MigrationError(
1252
- "Failed to initialize MigrationEngine",
1253
- "INVALID_SCHEMA" /* INVALID_SCHEMA */,
1254
- void 0,
1255
- error
1256
- );
1257
- }
1258
- }
1259
- /**
1260
- * Gets the current state of the migration helper
1261
- * @returns {Object} Current state containing schema, history, and migrations
1262
- * @example
1263
- * ```javascript
1264
- * const state = migrationEngine.data();
1265
- * // state contains currentSchema, history, and migrations
1266
- * ```
1267
- */
1268
- data() {
1269
- const result = {
1270
- schema: this.currentSchema,
1271
- history: this.history,
1272
- migrations: this.migrations
1273
- };
1274
- return result;
1275
- }
1276
- /**
1277
- * Generates a SHA-256 checksum for a migration
1278
- * @private
1279
- * @param {Omit<Migration<any>, "checksum">} migration - The migration object
1280
- * @returns {Promise<string>} The generated checksum
1281
- * @throws {MigrationError} If checksum generation fails
1282
- */
1283
- async generateChecksum(migration) {
1284
- try {
1285
- const payload = JSON.stringify({
1286
- id: migration.id,
1287
- schemaVersion: migration.schemaVersion,
1288
- changes: migration.changes,
1289
- description: migration.description,
1290
- rollback: migration.rollback,
1291
- createdAt: migration.createdAt
1292
- });
1293
- return await generateSHA256Hash(payload);
1294
- } catch (error) {
1295
- throw new MigrationError(
1296
- "Checksum generation failed",
1297
- "CHECKSUM_MISMATCH" /* CHECKSUM_MISMATCH */,
1298
- migration.id,
1299
- error
1300
- );
1301
- }
1302
- }
1303
- /**
1304
- * Adds a new migration to the engine
1305
- * @async
1306
- * @param {Object} opts - Options for the new migration
1307
- * @param {SchemaChange<any>[]} opts.changes - Array of schema changes
1308
- * @param {string} opts.description - Description of the migration
1309
- * @param {SchemaChange<any>[]} [opts.rollback] - Optional rollback changes
1310
- * @param {DataTransform<any, any>} [opts.transform] - Optional data transform
1311
- * @throws {MigrationError} If adding the migration fails
1312
- */
1313
- async add(opts) {
1314
- if (this.isProcessing) {
1315
- throw new MigrationError(
1316
- "Concurrent operation",
1317
- "CONCURRENT_OPERATION" /* CONCURRENT_OPERATION */
1318
- );
1319
- }
1320
- if (!opts.changes?.length) {
1321
- throw new MigrationError(
1322
- "Migration must include changes",
1323
- "INVALID_MIGRATION" /* INVALID_MIGRATION */
1324
- );
1325
- }
1326
- try {
1327
- opts.changes.forEach((change) => validateSchemaChange(change));
1328
- } catch (error) {
1329
- throw new MigrationError(
1330
- "Invalid schema changes",
1331
- "INVALID_MIGRATION" /* INVALID_MIGRATION */,
1332
- void 0,
1333
- error
1334
- );
1335
- }
1336
- const newMigration = {
1337
- id: Date.now().toString(),
1338
- schemaVersion: this.currentSchema.version,
1339
- changes: opts.changes,
1340
- description: opts.description,
1341
- status: "pending",
1342
- rollback: opts.rollback,
1343
- transform: opts.transform,
1344
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1345
- checksum: ""
1346
- };
1347
- newMigration.checksum = await this.generateChecksum(newMigration);
1348
- this.migrations.push(newMigration);
1349
- }
1350
- /**
1351
- * Performs a dry run of the migration
1352
- * @async
1353
- * @param {ReadableStream<any>} input - Input data stream
1354
- * @param {"forward" | "backward"} direction - Direction of migration
1355
- * @param {version} version - Version to rollback to
1356
- * @returns {Promise<Object>} Object containing newSchema and dataPreview
1357
- * @throws {MigrationError} If dry run fails
1358
- */
1359
- async dryRun(input, direction, version) {
1360
- if (this.isProcessing) {
1361
- throw new MigrationError(
1362
- "Concurrent operation",
1363
- "CONCURRENT_OPERATION" /* CONCURRENT_OPERATION */
1364
- );
1365
- }
1366
- try {
1367
- this.isProcessing = true;
1368
- const simulatedSchema = { ...this.currentSchema };
1369
- const relevantMigrations = this.getRelevantMigrations(direction, version);
1370
- const tempSchema = relevantMigrations.reduce((acc, migration) => {
1371
- const changes = direction === "forward" ? migration.changes : migration.rollback || [];
1372
- return this.applySchemaChanges(acc, changes, migration.id);
1373
- }, simulatedSchema);
1374
- const previewStream = await _MigrationEngine.processMigrationList(
1375
- input,
1376
- direction,
1377
- relevantMigrations
1378
- );
1379
- return { newSchema: tempSchema, dataPreview: previewStream };
1380
- } catch (error) {
1381
- if (error instanceof MigrationError) throw error;
1382
- throw new MigrationError(
1383
- "Dry run failed",
1384
- "INVALID_SCHEMA" /* INVALID_SCHEMA */,
1385
- void 0,
1386
- error
1387
- );
1388
- } finally {
1389
- this.isProcessing = false;
1390
- }
1391
- }
1392
- /**
1393
- * Gets relevant migrations based on direction
1394
- * @private
1395
- * @param {"forward" | "backward"} direction - Direction of migration
1396
- * @returns {Array<Migration<any>>} Relevant migrations
1397
- */
1398
- getRelevantMigrations(direction, version) {
1399
- return [...this.migrations].filter((m) => {
1400
- const dir = direction === "forward" ? "pending" : "applied";
1401
- const vs = version ? compareSemanticVersions(m.schemaVersion, version) >= 0 : true;
1402
- return m.status === dir && vs;
1403
- }).sort(
1404
- (a, b) => direction === "forward" ? a.id.localeCompare(b.id) : b.id.localeCompare(a.id)
1405
- );
1406
- }
1407
- /**
1408
- * Applies schema changes to a given schema
1409
- * @private
1410
- * @param {SchemaDefinition} schema - The schema to modify
1411
- * @param {SchemaChange<any>[]} changes - Array of schema changes
1412
- * @param {string} [migrationId] - ID of the migration
1413
- * @returns {SchemaDefinition} Modified schema
1414
- * @throws {MigrationError} If applying changes fails
1415
- */
1416
- applySchemaChanges(schema, changes, migrationId) {
1417
- try {
1418
- const version = calculateNextVersion(schema.version, changes);
1419
- const patches = changes.map((change) => {
1420
- try {
1421
- return schemaChangeToPatch(change, schema);
1422
- } catch (error) {
1423
- throw new MigrationError(
1424
- "Invalid schema change",
1425
- "INVALID_SCHEMA" /* INVALID_SCHEMA */,
1426
- migrationId,
1427
- error
1428
- );
1429
- }
1430
- });
1431
- return patches.reduce(
1432
- (acc, patch) => {
1433
- try {
1434
- return applyPatch(acc, patch);
1435
- } catch (error) {
1436
- throw new MigrationError(
1437
- "Failed to apply patch",
1438
- "INVALID_SCHEMA" /* INVALID_SCHEMA */,
1439
- migrationId,
1440
- error
1441
- );
1442
- }
1443
- },
1444
- { ...schema, version }
1445
- );
1446
- } catch (error) {
1447
- if (error instanceof MigrationError) throw error;
1448
- throw new MigrationError(
1449
- "Schema update failed",
1450
- "INVALID_SCHEMA" /* INVALID_SCHEMA */,
1451
- migrationId,
1452
- error
1453
- );
1454
- }
1455
- }
1456
- /**
1457
- * Prepares the list of pending migrations for application
1458
- * @async
1459
- * @returns {Promise<Array<Migration<any>>} List of pending migrations
1460
- * @throws {MigrationError} If preparation fails
1461
- */
1462
- async prepareMigration() {
1463
- const pendingMigrations = this.migrations.filter(
1464
- (m) => m.status === "pending"
1465
- );
1466
- await this.validateMigrations(pendingMigrations);
1467
- return pendingMigrations;
1468
- }
1469
- /**
1470
- * Applies pending migrations
1471
- * @async
1472
- * @param {ReadableStream<any>} input - Input data stream
1473
- * @returns {Promise<ReadableStream<any>>} Transformed data stream
1474
- * @throws {MigrationError} If migration fails
1475
- */
1476
- async migrate(input) {
1477
- if (this.isProcessing) {
1478
- throw new MigrationError(
1479
- "Concurrent operation",
1480
- "CONCURRENT_OPERATION" /* CONCURRENT_OPERATION */
1481
- );
1482
- }
1483
- const pendingMigrations = await this.prepareMigration();
1484
- try {
1485
- this.isProcessing = true;
1486
- this.transformSchema("forward");
1487
- const result = await _MigrationEngine.processMigrationList(
1488
- input,
1489
- "forward",
1490
- pendingMigrations
1491
- );
1492
- this.markMigrationsApplied(pendingMigrations);
1493
- return result;
1494
- } finally {
1495
- this.isProcessing = false;
1496
- }
1497
- }
1498
- /**
1499
- * Validates migrations by checking their checksums
1500
- * @private
1501
- * @async
1502
- * @param {Array<Migration<any>>} migrations - Migrations to validate
1503
- * @throws {MigrationError} If validation fails
1504
- */
1505
- async validateMigrations(migrations) {
1506
- await Promise.all(
1507
- migrations.map(async (migration) => {
1508
- const currentChecksum = await this.generateChecksum(migration);
1509
- if (migration.checksum !== currentChecksum) {
1510
- throw new MigrationError(
1511
- "Checksum mismatch",
1512
- "CHECKSUM_MISMATCH" /* CHECKSUM_MISMATCH */,
1513
- migration.id
1514
- );
1515
- }
1516
- })
1517
- );
1518
- }
1519
- /**
1520
- * Marks migrations as applied
1521
- * @private
1522
- * @param {Array<Migration<any>>} migrations - Migrations to mark as applied
1523
- */
1524
- markMigrationsApplied(migrations) {
1525
- this.migrations = this.migrations.map(
1526
- (m) => migrations.some((mm) => mm.id === m.id) ? { ...m, status: "applied" } : m
1527
- );
1528
- }
1529
- /**
1530
- * Rolls back the last applied migration
1531
- * @async
1532
- * @param {ReadableStream<any>} input - Input data stream
1533
- * @returns {Promise<ReadableStream<any>>} Transformed data stream
1534
- */
1535
- async rollback(input) {
1536
- if (this.isProcessing) {
1537
- throw new MigrationError(
1538
- "Concurrent operation",
1539
- "CONCURRENT_OPERATION" /* CONCURRENT_OPERATION */
1540
- );
1541
- }
1542
- const lastApplied = this.migrations.filter((m) => m.status === "applied").slice(-1)[0];
1543
- if (!lastApplied) return input;
1544
- return this.rollbackToVersion(
1545
- this.history[this.history.length - 1]?.version || this.currentSchema.version,
1546
- input
1547
- );
1548
- }
1549
- /**
1550
- * Rolls back to a specific schema version
1551
- * @async
1552
- * @param {string} targetVersion - Target schema version
1553
- * @param {ReadableStream<any>} input - Input data stream
1554
- * @returns {Promise<ReadableStream<any>>} Transformed data stream
1555
- * @throws {Error} If target version is not found
1556
- */
1557
- async rollbackToVersion(targetVersion, input) {
1558
- if (this.isProcessing) {
1559
- throw new MigrationError(
1560
- "Concurrent operation",
1561
- "CONCURRENT_OPERATION" /* CONCURRENT_OPERATION */
1562
- );
1563
- }
1564
- try {
1565
- const versionIndex = this.history.findIndex(
1566
- (s) => s.version === targetVersion
1567
- );
1568
- if (versionIndex === -1) {
1569
- throw new Error(`Version ${targetVersion} not found in history`);
1570
- }
1571
- const migrations = this.migrations.filter(
1572
- (m) => m.schemaVersion === targetVersion && m.status === "applied"
1573
- ).sort((a, b) => b.id.localeCompare(a.id));
1574
- const stepsBack = this.history.length - versionIndex;
1575
- if (stepsBack < 0) return input;
1576
- for (let i = 0; i < stepsBack; i++) {
1577
- this.transformSchema("backward");
1578
- }
1579
- const transformedStream = await _MigrationEngine.processMigrationList(
1580
- input,
1581
- "backward",
1582
- migrations
1583
- );
1584
- this.migrations = this.migrations.map((m) => {
1585
- if (m.schemaVersion === targetVersion && m.status === "applied") {
1586
- return { ...m, status: "pending" };
1587
- }
1588
- return m;
1589
- });
1590
- return transformedStream;
1591
- } finally {
1592
- this.isProcessing = false;
1593
- }
1594
- }
1595
- /**
1596
- * Processes a list of migrations on a data stream, applying transformations
1597
- * in the specified direction (forward or backward).
1598
- *
1599
- * @static
1600
- * @async
1601
- * @param {ReadableStream<any>} input - The input data stream to process
1602
- * @param {"forward" | "backward"} direction - Direction of migration (either "forward" or "backward")
1603
- * @param {Array<Migration<any>>} migrations - Array of Migration objects to process
1604
- * @returns {Promise<ReadableStream<any>>} Transformed data stream
1605
- * @throws {MigrationError} If any migration processing fails
1606
- */
1607
- static async processMigrationList(input, direction, migrations) {
1608
- const transformEntries = await Promise.all(
1609
- migrations.map(async (migration) => {
1610
- try {
1611
- const transform = await this.resolveTransform(migration, direction);
1612
- return { migration, transform };
1613
- } catch (error) {
1614
- throw new MigrationError(
1615
- `Failed to resolve transform for migration ${migration.id}`,
1616
- "TRANSFORM_ERROR" /* TRANSFORM_ERROR */,
1617
- migration.id,
1618
- error
1619
- );
1620
- }
1621
- })
1622
- );
1623
- const validTransformEntries = transformEntries.filter(
1624
- (entry) => Boolean(entry.transform)
1625
- );
1626
- return validTransformEntries.reduce((stream, { migration, transform }) => {
1627
- return stream.pipeThrough(
1628
- new TransformStream({
1629
- async transform(chunk, controller) {
1630
- try {
1631
- const result = await transform(chunk);
1632
- controller.enqueue(result);
1633
- } catch (error) {
1634
- controller.error(
1635
- new MigrationError(
1636
- `Data transformation failed for migration ${migration.id}`,
1637
- "TRANSFORM_ERROR" /* TRANSFORM_ERROR */,
1638
- migration.id,
1639
- error
1640
- )
1641
- );
1642
- }
1643
- }
1644
- })
1645
- );
1646
- }, input);
1647
- }
1648
- /**
1649
- * Resolves the transform function for a given migration in the specified direction.
1650
- *
1651
- * @private
1652
- * @async
1653
- * @param {Migration<any>} migration - The migration to resolve the transform for
1654
- * @param {"forward" | "backward"} direction - Direction of migration
1655
- * @returns {Promise<TransformFunction<any, any>>} Resolved transform function
1656
- * @throws {MigrationError} If transform resolution fails
1657
- */
1658
- static async resolveTransform(migration, direction) {
1659
- if (!migration.transform) {
1660
- return null;
1661
- }
1662
- if (typeof migration.transform === "string") {
1663
- if (migration.transform.startsWith("http://") || migration.transform.startsWith("https://")) {
1664
- return this.resolveRemoteTransform(migration.transform, direction);
1665
- }
1666
- return this.resolveLocalTransform(migration.transform, direction);
1667
- }
1668
- return migration.transform[direction];
1669
- }
1670
- /**
1671
- * Resolves a transform function from a remote URL.
1672
- *
1673
- * @private
1674
- * @async
1675
- * @param {string} url - URL of the transform module
1676
- * @param {"forward" | "backward"} direction - Direction of migration
1677
- * @returns {Promise<TransformFunction<any, any>>} Resolved transform function
1678
- * @throws {MigrationError} If resolution fails
1679
- */
1680
- static async resolveRemoteTransform(url, direction) {
1681
- try {
1682
- const response = await fetch(url);
1683
- if (!response.ok) {
1684
- throw new MigrationError(
1685
- `Failed to fetch transform module: ${url}`,
1686
- "TRANSFORM_ERROR" /* TRANSFORM_ERROR */,
1687
- void 0
1688
- );
1689
- }
1690
- const moduleText = await response.text();
1691
- if (typeof window !== "undefined") {
1692
- const blob = new Blob([moduleText], {
1693
- type: "application/javascript"
1694
- });
1695
- const url2 = URL.createObjectURL(blob);
1696
- const module2 = (await import(url2)).default;
1697
- return module2[direction];
1698
- } else {
1699
- const { runInNewContext } = await import("vm");
1700
- const sandbox = { module: { exports: {} }, console };
1701
- runInNewContext(moduleText, sandbox, url);
1702
- return sandbox.module.exports[direction];
1703
- }
1704
- } catch (error) {
1705
- throw new MigrationError(
1706
- `Failed to load remote transform module: ${url}`,
1707
- "TRANSFORM_ERROR" /* TRANSFORM_ERROR */,
1708
- void 0,
1709
- error
1710
- );
1711
- }
1712
- }
1713
- /**
1714
- * Resolves a transform function from a local module path.
1715
- *
1716
- * @private
1717
- * @async
1718
- * @param {string} path - Local module path
1719
- * @param {"forward" | "backward"} direction - Direction of migration
1720
- * @returns {Promise<TransformFunction<any, any>>} Resolved transform function
1721
- * @throws {MigrationError} If resolution fails
1722
- */
1723
- static async resolveLocalTransform(path, direction) {
1724
- try {
1725
- const module2 = await import(path);
1726
- const dataTransform = module2.default;
1727
- return dataTransform[direction];
1728
- } catch (error) {
1729
- throw new MigrationError(
1730
- `Failed to import local transform module: ${path}`,
1731
- "TRANSFORM_ERROR" /* TRANSFORM_ERROR */,
1732
- void 0,
1733
- error
1734
- );
1735
- }
1736
- }
1737
- /**
1738
- * Transforms the schema either forward or backward
1739
- * @private
1740
- * @param {"forward" | "backward"} direction - Direction of transformation
1741
- * @throws {Error} If transformation fails
1742
- */
1743
- transformSchema(direction) {
1744
- try {
1745
- if (direction === "backward") {
1746
- const schema = this.history.pop();
1747
- if (!schema) throw new Error("No previous version");
1748
- this.currentSchema = schema;
1749
- return;
1750
- }
1751
- const changes = this.migrations.filter((m) => m.status === "pending").flatMap((m) => m.changes);
1752
- if (!changes.length) return;
1753
- this.history.push(structuredClone(this.currentSchema));
1754
- this.currentSchema = changes.reduce(
1755
- (acc, change) => this.applySchemaChanges(acc, [change]),
1756
- this.currentSchema
1757
- );
1758
- } catch (error) {
1759
- if (error instanceof MigrationError) throw error;
1760
- throw new MigrationError(
1761
- "Schema transformation failed",
1762
- "INVALID_SCHEMA" /* INVALID_SCHEMA */,
1763
- void 0,
1764
- error
1765
- );
1766
- }
1767
- }
1768
- };
1769
1170
 
1770
1171
  // src/lib/schema/helpers.ts
1771
1172
  var createSchemaMigrationHelper = (schema) => {
@@ -1887,1214 +1288,14 @@ var createSchemaMigrationHelper = (schema) => {
1887
1288
  };
1888
1289
  };
1889
1290
 
1890
- // src/lib/persistence/collection.ts
1891
- var EmphemeralCollection = class {
1892
- definition;
1893
- // Stores the schema definition for the collection.
1894
- collectionEventBus;
1895
- // Event bus for collection-related events.
1896
- validator;
1897
- collectionData = [];
1898
- // Array to store the collection data.
1899
- predicateMap;
1900
- // Map of predicate names to their implementations.
1901
- match;
1902
- project;
1903
- sort;
1904
- paginate;
1905
- migrator;
1906
- /**
1907
- * @constructor
1908
- * @param {Record<string, Function>} functionMap Map of function names to their implementations.
1909
- * @param {Record<string, (params: any) => boolean>} predicateMap Map of predicate names to their implementations.
1910
- */
1911
- constructor(schema, functionMap, predicateMap) {
1912
- this.definition = schema;
1913
- this.collectionEventBus = (0, import_events.createEventBus)();
1914
- this.predicateMap = predicateMap;
1915
- this.validator = createStandardSchemaValidator(schema, predicateMap)["~standard"];
1916
- this.match = (0, import_query.createMatcher)(functionMap);
1917
- this.project = (0, import_query.createProjector)(functionMap);
1918
- this.sort = (0, import_query.createSorter)();
1919
- this.paginate = (0, import_query.createPaginator)();
1920
- this.migrator = new MigrationEngine(schema);
1921
- }
1922
- /**
1923
- * @method schema
1924
- * @description Returns the schema definition for the collection.
1925
- * @returns {SchemaDefinition | null} The schema definition, or null if not set.
1926
- */
1927
- schema() {
1928
- return this.definition;
1929
- }
1930
- /**
1931
- * @method create
1932
- * @description Creates new data in the collection.
1933
- * @param {{ data: DataType | DataType[] }} The data to create.
1934
- * @returns {Promise<DataType | DataType[]>} The created data.
1935
- */
1936
- async create({ data }) {
1937
- const dataArray = Array.isArray(data) ? data : [data];
1938
- const allIssues = dataArray.reduce(
1939
- (acc, item) => {
1940
- const validationResult = this.validate(item);
1941
- if (validationResult.issues) {
1942
- acc.push(...validationResult.issues);
1943
- }
1944
- return acc;
1945
- },
1946
- []
1947
- );
1948
- if (allIssues.length > 0) {
1949
- this.emitCollectionEvent("create:failed", {
1950
- operation: "create",
1951
- collection: this.definition?.name || "",
1952
- input: dataArray,
1953
- type: "create:failed",
1954
- timestamp: Date.now(),
1955
- issues: allIssues
1956
- });
1957
- throw new Error(`Invalid data: ${JSON.stringify(allIssues)}`);
1958
- }
1959
- this.collectionData.push(...dataArray);
1960
- this.emitCollectionEvent("create:success", {
1961
- operation: "create",
1962
- collection: this.definition?.name || "",
1963
- input: dataArray,
1964
- output: dataArray,
1965
- type: "create:success",
1966
- timestamp: Date.now()
1967
- });
1968
- return data;
1969
- }
1970
- /**
1971
- * @method read
1972
- * @description Reads data from the collection based on the provided query.
1973
- * @param {QueryDSL<T>} [query] Optional query to filter the data.
1974
- * @returns {Promise<T[]>} An array of data matching the query.
1975
- */
1976
- async read({
1977
- query
1978
- }) {
1979
- this.emitCollectionEvent("read:start", {
1980
- operation: "read",
1981
- collection: this.definition?.name,
1982
- query,
1983
- type: "read:start",
1984
- timestamp: Date.now()
1985
- });
1986
- let result = this.collectionData;
1987
- if (query.filters) {
1988
- result = result.filter(
1989
- (item) => this.match.match(item, query.filters)
1990
- );
1991
- }
1992
- if (query.projection) {
1993
- result = result.map(
1994
- (item) => this.project.project(item, query.projection)
1995
- );
1996
- }
1997
- if (query.sort) {
1998
- result = this.sort.sort(result, query.sort);
1999
- }
2000
- if (query.pagination) {
2001
- const paginator = this.paginate.paginate(result, query.pagination);
2002
- result = (await paginator.next()).value;
2003
- }
2004
- this.emitCollectionEvent("read:success", {
2005
- operation: "read",
2006
- collection: this.definition?.name,
2007
- query,
2008
- output: result,
2009
- type: "read:success",
2010
- timestamp: Date.now()
2011
- });
2012
- return result;
2013
- }
2014
- /**
2015
- * @method update
2016
- * @description Updates data in the collection based on the provided query and update data.
2017
- * @param {{ data?: Partial<T>; patch?: PatchOperation | Array<PatchOperation>; query: QueryFilter }} The update parameters.
2018
- * @returns {Array<T>} The updated data.
2019
- */
2020
- async update({
2021
- data,
2022
- patch,
2023
- query
2024
- }) {
2025
- this.emitCollectionEvent("update:start", {
2026
- operation: "update",
2027
- collection: this.definition?.name,
2028
- input: data,
2029
- query,
2030
- type: "update:start",
2031
- timestamp: Date.now()
2032
- });
2033
- const results = [];
2034
- this.collectionData.forEach((i, index) => {
2035
- if (!this.match.match(i, query)) return;
2036
- let result = i;
2037
- if (data) {
2038
- result = deepMerge(result, data);
2039
- }
2040
- if (patch) {
2041
- const changes = Array.isArray(patch) ? patch : [patch];
2042
- result = applyPatch(result, changes);
2043
- }
2044
- this.collectionData[index] = result;
2045
- results.push(result);
2046
- });
2047
- this.emitCollectionEvent("update:success", {
2048
- operation: "update",
2049
- collection: this.definition?.name,
2050
- input: data,
2051
- query,
2052
- output: results,
2053
- type: "update:success",
2054
- timestamp: Date.now()
2055
- });
2056
- return results;
2057
- }
2058
- /**
2059
- * @method delete
2060
- * @description Deletes data from the collection based on the provided query.
2061
- * @param {{ query: QueryFilter<T> }} The query to use for deleting data.
2062
- * @returns {number} The number of deleted items.
2063
- */
2064
- async delete({ query }) {
2065
- this.emitCollectionEvent("delete:start", {
2066
- operation: "delete",
2067
- collection: this.definition?.name,
2068
- query,
2069
- type: "delete:start",
2070
- timestamp: Date.now()
2071
- });
2072
- const beforeCount = this.collectionData.length;
2073
- const remainingItems = this.collectionData.filter(
2074
- (item) => !this.match.match(item, query)
2075
- );
2076
- const deletedCount = beforeCount - remainingItems.length;
2077
- this.collectionData = remainingItems;
2078
- this.emitCollectionEvent("delete:success", {
2079
- operation: "delete",
2080
- collection: this.definition?.name,
2081
- query,
2082
- context: { deletedCount },
2083
- type: "delete:success",
2084
- timestamp: Date.now()
2085
- });
2086
- return deletedCount;
2087
- }
2088
- /**
2089
- * @method validate
2090
- * @description Validates data against the collection's schema.
2091
- * @param {T} data The data to validate.
2092
- * @returns {{ valid: boolean; issues: StandardSchemaV1.Issue[] | null }} An object containing the validation result.
2093
- */
2094
- validate(data) {
2095
- if (!this.definition) {
2096
- throw new Error("No schema exists. Call setSchema first.");
2097
- }
2098
- if (!this.validator) {
2099
- this.validator = createStandardSchemaValidator(
2100
- this.definition,
2101
- this.predicateMap
2102
- )["~standard"];
2103
- }
2104
- const results = this.validator.validate(
2105
- data
2106
- );
2107
- return { valid: !results.issues, issues: results.issues || null };
2108
- }
2109
- /**
2110
- * @method emitCollectionEvent
2111
- * @description Emits a collection-related event.
2112
- * @param {PersistenceEventType} type The type of the event.
2113
- * @param {PersistenceEvent<SchemaDefinition>} payload The event payload.
2114
- */
2115
- emitCollectionEvent(type, payload) {
2116
- this.collectionEventBus.emit({ name: type, payload });
2117
- }
2118
- /**
2119
- * @method subscribeToCollectionEvents
2120
- * @description Subscribes to collection-related events.
2121
- * @param {PersistenceEventType} event The type of the event to subscribe to.
2122
- * @param {(payload: PersistenceEvent<SchemaDefinition>) => void} callback The callback function.
2123
- * @returns {() => void} A function to unsubscribe.
2124
- */
2125
- subscribe(event, callback) {
2126
- return this.collectionEventBus.subscribe(event, callback);
2127
- }
2128
- async rollback(version, dryRun = true) {
2129
- this.emitCollectionEvent("rollback:start", {
2130
- operation: "rollback",
2131
- collection: this.definition?.name,
2132
- input: { version },
2133
- type: "rollback:start",
2134
- timestamp: Date.now(),
2135
- context: {
2136
- dryRun
2137
- }
2138
- });
2139
- if (dryRun) {
2140
- const input = new ReadableStream({
2141
- start(controller) {
2142
- controller.close();
2143
- }
2144
- });
2145
- const result = await this.migrator.dryRun(input, "backward", version);
2146
- this.emitCollectionEvent("migrate:success", {
2147
- operation: "rollback",
2148
- collection: this.definition?.name,
2149
- input: { version },
2150
- type: "migrate:success",
2151
- timestamp: Date.now(),
2152
- context: {
2153
- dryRun
2154
- }
2155
- });
2156
- return result;
2157
- }
2158
- try {
2159
- const data = this.collectionData;
2160
- const input = new ReadableStream({
2161
- start(controller) {
2162
- data.forEach((i) => controller.enqueue(i));
2163
- controller.close();
2164
- }
2165
- });
2166
- const output = Boolean(version) ? await this.migrator.rollbackToVersion(version, input) : await this.migrator.rollback(input);
2167
- const reader = output.getReader();
2168
- let value = await reader.read();
2169
- const result = [];
2170
- do {
2171
- if (value.value) {
2172
- result.push(value.value);
2173
- }
2174
- value = await reader.read();
2175
- } while (!value.done);
2176
- this.collectionData = result;
2177
- this.definition = this.migrator.data().schema;
2178
- this.validator = createStandardSchemaValidator(this.definition, this.predicateMap)["~standard"];
2179
- this.emitCollectionEvent("rollback:failed", {
2180
- operation: "rollback",
2181
- collection: this.definition?.name,
2182
- input: { version },
2183
- type: "rollback:failed",
2184
- timestamp: Date.now(),
2185
- context: {
2186
- dryRun
2187
- }
2188
- });
2189
- } catch (error) {
2190
- this.emitCollectionEvent("migrate:failed", {
2191
- operation: "rollback",
2192
- collection: this.definition?.name,
2193
- input: { version },
2194
- type: "migrate:failed",
2195
- timestamp: Date.now(),
2196
- error,
2197
- context: {
2198
- dryRun,
2199
- error
2200
- }
2201
- });
2202
- }
2203
- }
2204
- async migrate(description, cb, dryRun = true) {
2205
- const helper = createSchemaMigrationHelper(this.definition);
2206
- const transform = cb(helper);
2207
- const { migrate, rollback } = helper.changes();
2208
- this.emitCollectionEvent("migrate:start", {
2209
- operation: "migrate",
2210
- collection: this.definition?.name,
2211
- input: { migrate, rollback },
2212
- type: "migrate:start",
2213
- timestamp: Date.now(),
2214
- context: {
2215
- dryRun
2216
- }
2217
- });
2218
- await this.migrator.add({
2219
- description,
2220
- changes: migrate,
2221
- rollback,
2222
- transform
2223
- });
2224
- try {
2225
- if (dryRun) {
2226
- const input2 = new ReadableStream({
2227
- start(controller) {
2228
- controller.close();
2229
- }
2230
- });
2231
- const result2 = await this.migrator.dryRun(input2, "forward");
2232
- this.emitCollectionEvent("migrate:success", {
2233
- operation: "migrate",
2234
- collection: this.definition?.name,
2235
- input: { migrate, rollback },
2236
- type: "migrate:success",
2237
- timestamp: Date.now(),
2238
- context: {
2239
- dryRun
2240
- }
2241
- });
2242
- return result2;
2243
- }
2244
- const data = this.collectionData;
2245
- const input = new ReadableStream({
2246
- start(controller) {
2247
- data.forEach((i) => controller.enqueue(i));
2248
- controller.close();
2249
- }
2250
- });
2251
- const output = await this.migrator.migrate(input);
2252
- const reader = output.getReader();
2253
- let value = await reader.read();
2254
- const result = [];
2255
- do {
2256
- if (value.value) {
2257
- result.push(value.value);
2258
- }
2259
- value = await reader.read();
2260
- } while (!value.done);
2261
- this.collectionData = result;
2262
- this.definition = this.migrator.data().schema;
2263
- this.validator = createStandardSchemaValidator(this.definition, this.predicateMap)["~standard"];
2264
- this.emitCollectionEvent("migrate:success", {
2265
- operation: "migrate",
2266
- collection: this.definition?.name,
2267
- input: { migrate, rollback },
2268
- type: "migrate:success",
2269
- timestamp: Date.now(),
2270
- context: {
2271
- dryRun
2272
- }
2273
- });
2274
- } catch (error) {
2275
- this.emitCollectionEvent("migrate:failed", {
2276
- operation: "migrate",
2277
- collection: this.definition?.name,
2278
- input: { migrate, rollback },
2279
- type: "migrate:failed",
2280
- timestamp: Date.now(),
2281
- error,
2282
- context: {
2283
- dryRun,
2284
- error
2285
- }
2286
- });
2287
- }
2288
- }
2289
- };
2290
-
2291
- // src/lib/persistence/index.ts
2292
- function createEphemeralPersistence(functionMap, predicateMap) {
2293
- const bus = (0, import_events2.createEventBus)();
2294
- const data = /* @__PURE__ */ new Map();
2295
- function subscribe(event, callback) {
2296
- return bus.subscribe(event, callback);
2297
- }
2298
- function transact(callback) {
2299
- return callback({
2300
- createCollection,
2301
- deleteCollection,
2302
- collections,
2303
- schema,
2304
- collection
2305
- });
2306
- }
2307
- async function createCollection(schema2) {
2308
- if (data.has(schema2.name)) {
2309
- bus.emit({
2310
- name: "collection:create:failed",
2311
- payload: {
2312
- operation: "create",
2313
- collection: schema2.name,
2314
- input: schema2,
2315
- type: "collection:create:failed",
2316
- timestamp: Date.now()
2317
- }
2318
- });
2319
- throw new Error("Collection exists!");
2320
- }
2321
- const collection2 = new EmphemeralCollection(
2322
- schema2,
2323
- functionMap,
2324
- predicateMap
2325
- );
2326
- data.set(schema2.name, collection2);
2327
- bus.emit({
2328
- name: "collection:create:success",
2329
- payload: {
2330
- operation: "create",
2331
- collection: schema2.name,
2332
- input: schema2,
2333
- type: "collection:create:success",
2334
- timestamp: Date.now()
2335
- }
2336
- });
2337
- return collection2;
2338
- }
2339
- async function deleteCollection(id) {
2340
- if (data.has(id)) {
2341
- data.delete(id);
2342
- bus.emit({
2343
- name: "collection:delete:success",
2344
- payload: {
2345
- operation: "delete",
2346
- collection: id,
2347
- input: id,
2348
- type: "collection:delete:success",
2349
- timestamp: Date.now()
2350
- }
2351
- });
2352
- } else {
2353
- bus.emit({
2354
- name: "collection:delete:failed",
2355
- payload: {
2356
- operation: "delete",
2357
- collection: id,
2358
- input: id,
2359
- type: "collection:delete:failed",
2360
- timestamp: Date.now()
2361
- }
2362
- });
2363
- throw new Error("Collection not found!");
2364
- }
2365
- }
2366
- async function collections() {
2367
- return Array.from(data.keys());
2368
- }
2369
- async function schema(id) {
2370
- const collection2 = data.get(id);
2371
- if (!collection2) throw new Error("Collection not found!");
2372
- return collection2.schema();
2373
- }
2374
- function collection(id) {
2375
- const coll = data.get(id);
2376
- if (!coll) throw new Error("Collection not found!");
2377
- return coll;
2378
- }
2379
- return {
2380
- transact,
2381
- createCollection,
2382
- deleteCollection,
2383
- collections,
2384
- schema,
2385
- collection,
2386
- subscribe
2387
- };
2388
- }
2389
-
2390
1291
  // src/lib/registry/index.ts
2391
- var registry_exports2 = {};
2392
- __export(registry_exports2, {
2393
- default: () => createRegistry
2394
- });
2395
1292
  var import_lightning_fs = __toESM(require("@isomorphic-git/lightning-fs"), 1);
2396
1293
  var import_buffer = require("buffer");
2397
1294
  var import_isomorphic_git = __toESM(require("isomorphic-git"), 1);
2398
1295
  var import_web = __toESM(require("isomorphic-git/http/web"), 1);
2399
-
2400
- // src/lib/registry/repository.ts
2401
- async function createGithubRepository({
2402
- token,
2403
- repoConfig
2404
- }) {
2405
- try {
2406
- const response = await fetch("https://api.github.com/user/repos", {
2407
- method: "POST",
2408
- headers: {
2409
- "X-GitHub-Api-Version": "2022-11-28",
2410
- Accept: "application/vnd.github+json",
2411
- Authorization: `Bearer ${token}`,
2412
- "Content-Type": "application/json"
2413
- },
2414
- body: JSON.stringify(repoConfig),
2415
- redirect: "follow"
2416
- });
2417
- if (!response.ok) {
2418
- throw new Error(`HTTP error! status: ${response.status}`);
2419
- }
2420
- const data = await response.json();
2421
- return data;
2422
- } catch (error) {
2423
- console.error("Error creating repository:", error);
2424
- throw error;
2425
- }
2426
- }
2427
-
2428
- // src/lib/registry/utils.ts
2429
- function serializeGenerator(fn) {
2430
- const fnStr = fn.toString();
2431
- const params = fnStr.substring(fnStr.indexOf("(") + 1, fnStr.indexOf(")"));
2432
- const body = fnStr.substring(fnStr.indexOf("{") + 1, fnStr.lastIndexOf("}")).trim();
2433
- return JSON.stringify({ params, body });
2434
- }
2435
- function deserializeGenerator(serialized) {
2436
- const { params, body } = JSON.parse(serialized);
2437
- const GeneratorFunction = Object.getPrototypeOf(function* () {
2438
- }).constructor;
2439
- return new GeneratorFunction(params, body);
2440
- }
2441
- function serializeFunction(fn) {
2442
- const fnStr = fn.toString();
2443
- const params = fnStr.substring(fnStr.indexOf("(") + 1, fnStr.indexOf(")"));
2444
- const body = fnStr.substring(fnStr.indexOf("{") + 1, fnStr.lastIndexOf("}")).trim();
2445
- return JSON.stringify({ params, body });
2446
- }
2447
- function deserializeFunction(serialized) {
2448
- const { params, body } = JSON.parse(serialized);
2449
- return new Function(params, body);
2450
- }
2451
- function authUrl(repoUrl, username, password) {
2452
- const u = new URL(repoUrl);
2453
- u.username = username;
2454
- u.password = password;
2455
- return u.toString();
2456
- }
2457
-
2458
- // src/lib/registry/index.ts
2459
1296
  window.Buffer = import_buffer.Buffer;
2460
- async function createRegistry(credentials, dir = "/registry", proxy = "https://cors.isomorphic-git.org") {
2461
- const fs = new import_lightning_fs.default(dir);
2462
- const pfs = fs.promises;
2463
- const main = "main";
2464
- async function init() {
2465
- await pfs.mkdir(dir);
2466
- await import_isomorphic_git.default.init({ fs, dir, defaultBranch: main });
2467
- await pfs.writeFile(
2468
- `${dir}/registry.json`,
2469
- JSON.stringify({
2470
- schemas: {},
2471
- created: (/* @__PURE__ */ new Date()).toISOString(),
2472
- updated: (/* @__PURE__ */ new Date()).toISOString()
2473
- })
2474
- );
2475
- await import_isomorphic_git.default.add({
2476
- fs,
2477
- dir,
2478
- filepath: `registry.json`
2479
- });
2480
- await pfs.writeFile(
2481
- `${dir}/registry.lock`,
2482
- JSON.stringify({
2483
- hashes: [],
2484
- updated: (/* @__PURE__ */ new Date()).toISOString()
2485
- })
2486
- );
2487
- await import_isomorphic_git.default.add({
2488
- fs,
2489
- dir,
2490
- filepath: `registry.lock`
2491
- });
2492
- await import_isomorphic_git.default.commit({
2493
- fs,
2494
- dir,
2495
- author: { name: "bot", email: "bot@registry.domain" },
2496
- message: "initial commit"
2497
- });
2498
- await createGithubRepository({
2499
- token: credentials.password,
2500
- repoConfig: {
2501
- name: credentials.repository,
2502
- private: true
2503
- }
2504
- });
2505
- await import_isomorphic_git.default.addRemote({
2506
- fs,
2507
- dir,
2508
- remote: "origin",
2509
- url: `https://github.com/${credentials.username}/${credentials.repository}.git`
2510
- });
2511
- await import_isomorphic_git.default.push({
2512
- fs,
2513
- dir,
2514
- http: import_web.default,
2515
- remote: "origin",
2516
- url: authUrl(
2517
- `https://github.com/${credentials.username}/${credentials.repository}.git`,
2518
- credentials.username,
2519
- credentials.password
2520
- ),
2521
- corsProxy: proxy,
2522
- ref: main,
2523
- onAuth: () => ({
2524
- username: credentials.username,
2525
- password: credentials.password
2526
- })
2527
- });
2528
- }
2529
- async function clone() {
2530
- await import_isomorphic_git.default.clone({
2531
- fs,
2532
- dir,
2533
- http: import_web.default,
2534
- corsProxy: proxy,
2535
- url: authUrl(
2536
- `https://github.com/${credentials.username}/${credentials.repository}.git`,
2537
- credentials.username,
2538
- credentials.password
2539
- ),
2540
- onAuth: () => ({
2541
- username: credentials.username,
2542
- password: credentials.password
2543
- }),
2544
- singleBranch: true,
2545
- depth: 1
2546
- });
2547
- }
2548
- async function create(schema2) {
2549
- await import_isomorphic_git.default.branch({
2550
- fs,
2551
- dir,
2552
- ref: schema2.name,
2553
- checkout: true
2554
- });
2555
- const dirs = [schema2.name, `${schema2.name}/migrations`];
2556
- for (const filepath of dirs) {
2557
- await pfs.mkdir(`${dir}/${filepath}`);
2558
- }
2559
- const migrations2 = await Promise.all(
2560
- (schema2.migrations || []).map(async (migration) => {
2561
- let content = { ...migration };
2562
- if (migration.transform && typeof migration.transform !== "string") {
2563
- content.transform = {
2564
- forward: serializeFunction(migration.transform.forward),
2565
- backward: serializeFunction(migration.transform.backward)
2566
- };
2567
- }
2568
- content = JSON.stringify(content);
2569
- const hash = await generateSHA256Hash(content);
2570
- return {
2571
- hash,
2572
- checksum: migration.checksum,
2573
- content,
2574
- id: migration.id
2575
- };
2576
- })
2577
- );
2578
- await pfs.writeFile(`${dir}/${schema2.name}/migrations/.nomedia`, "");
2579
- for (const { hash, content } of migrations2) {
2580
- await pfs.writeFile(
2581
- `${dir}/${schema2.name}/migrations/${hash}.json`,
2582
- content
2583
- );
2584
- }
2585
- const schemaContent = JSON.stringify({
2586
- ...schema2,
2587
- migrations: [],
2588
- mock: schema2.mock ? serializeGenerator(schema2.mock) : null
2589
- });
2590
- const schemaHash = await generateSHA256Hash(schemaContent);
2591
- await pfs.writeFile(`${dir}/${schema2.name}/schema.json`, schemaContent);
2592
- const index = {
2593
- schema: schema2.name,
2594
- version: schema2.version,
2595
- history: [
2596
- {
2597
- version: schema2.version,
2598
- hash: schemaHash,
2599
- date: (/* @__PURE__ */ new Date()).toISOString(),
2600
- description: schema2.description || "",
2601
- migrations: migrations2.map(({ id }) => id),
2602
- changelog: [],
2603
- predicates: []
2604
- }
2605
- ],
2606
- migrations: migrations2.reduce(
2607
- (acc, { hash, checksum, id }) => {
2608
- acc[id] = { hash, checksum };
2609
- return acc;
2610
- },
2611
- {}
2612
- )
2613
- };
2614
- await pfs.writeFile(
2615
- `${dir}/${schema2.name}/index.json`,
2616
- JSON.stringify(index)
2617
- );
2618
- await import_isomorphic_git.default.add({ fs, dir, filepath: schema2.name });
2619
- await import_isomorphic_git.default.commit({
2620
- fs,
2621
- dir,
2622
- author: { name: "bot", email: "bot@registry.domain" },
2623
- message: `chore: created schema: ${schema2.name}`
2624
- });
2625
- await import_isomorphic_git.default.tag({
2626
- fs,
2627
- dir,
2628
- ref: `${schema2.name}-${schema2.version}`
2629
- });
2630
- await import_isomorphic_git.default.checkout({
2631
- fs,
2632
- dir,
2633
- ref: main
2634
- });
2635
- await import_isomorphic_git.default.merge({
2636
- fs,
2637
- dir,
2638
- author: { name: "bot", email: "bot@registry.domain" },
2639
- theirs: `${schema2.name}`,
2640
- message: `add schema: ${schema2.name}`
2641
- });
2642
- await import_isomorphic_git.default.checkout({ fs, dir, ref: main });
2643
- const registry = JSON.parse(
2644
- (await pfs.readFile(`${dir}/registry.json`)).toString()
2645
- );
2646
- registry.updated = (/* @__PURE__ */ new Date()).toISOString();
2647
- registry.schemas[schema2.name] = {
2648
- name: schema2.name,
2649
- version: schema2.version,
2650
- description: schema2.description || "",
2651
- created: (/* @__PURE__ */ new Date()).toISOString(),
2652
- updated: (/* @__PURE__ */ new Date()).toISOString()
2653
- };
2654
- await pfs.writeFile(`${dir}/registry.json`, JSON.stringify(registry));
2655
- const files = (await import_isomorphic_git.default.listFiles({
2656
- fs,
2657
- dir
2658
- })).filter((i) => i !== "registry.lock");
2659
- const hashes = await Promise.all(
2660
- files.map(async (file) => {
2661
- return [file, await generateSHA256Hash(file)];
2662
- })
2663
- );
2664
- await pfs.writeFile(
2665
- `${dir}/registry.lock`,
2666
- JSON.stringify({
2667
- updated: (/* @__PURE__ */ new Date()).toISOString(),
2668
- hashes
2669
- })
2670
- );
2671
- await import_isomorphic_git.default.add({
2672
- fs,
2673
- dir,
2674
- filepath: `registry.lock`
2675
- });
2676
- await import_isomorphic_git.default.add({
2677
- fs,
2678
- dir,
2679
- filepath: `registry.json`
2680
- });
2681
- await import_isomorphic_git.default.commit({
2682
- fs,
2683
- dir,
2684
- author: { name: "bot", email: "bot@registry.domain" },
2685
- message: `fix: created schema: ${schema2.name}`
2686
- });
2687
- }
2688
- async function update(schema2) {
2689
- await import_isomorphic_git.default.checkout({
2690
- fs,
2691
- dir,
2692
- ref: schema2.name
2693
- });
2694
- const migrations2 = await Promise.all(
2695
- (schema2.migrations || []).map(async (migration) => {
2696
- let content = { ...migration };
2697
- if (migration.transform && typeof migration.transform !== "string") {
2698
- content.transform = {
2699
- forward: serializeFunction(migration.transform.forward),
2700
- backward: serializeFunction(migration.transform.backward)
2701
- };
2702
- }
2703
- content = JSON.stringify(content);
2704
- const hash = await generateSHA256Hash(content);
2705
- return {
2706
- hash,
2707
- checksum: migration.checksum,
2708
- content,
2709
- id: migration.id
2710
- };
2711
- })
2712
- );
2713
- for (const { hash, content } of migrations2) {
2714
- await pfs.writeFile(
2715
- `${dir}/${schema2.name}/migrations/${hash}.json`,
2716
- content
2717
- );
2718
- }
2719
- const schemaContent = JSON.stringify({
2720
- ...schema2,
2721
- migrations: [],
2722
- mock: schema2.mock ? serializeGenerator(schema2.mock) : null
2723
- });
2724
- const schemaHash = await generateSHA256Hash(schemaContent);
2725
- await pfs.writeFile(`${dir}/${schema2.name}/schema.json`, schemaContent);
2726
- const indexPath = `${dir}/${schema2.name}/index.json`;
2727
- const existingIndex = JSON.parse(
2728
- (await pfs.readFile(indexPath)).toString()
2729
- );
2730
- const newHistoryEntry = {
2731
- version: schema2.version,
2732
- hash: schemaHash,
2733
- date: (/* @__PURE__ */ new Date()).toISOString(),
2734
- description: schema2.description || "",
2735
- migrations: migrations2.map(({ id }) => id),
2736
- changelog: [],
2737
- predicates: []
2738
- };
2739
- existingIndex.history.push(newHistoryEntry);
2740
- existingIndex.migrations = {
2741
- ...existingIndex.migrations,
2742
- ...migrations2.reduce(
2743
- (acc, { hash, checksum, id }) => {
2744
- acc[id] = { hash, checksum };
2745
- return acc;
2746
- },
2747
- {}
2748
- )
2749
- };
2750
- await pfs.writeFile(indexPath, JSON.stringify(existingIndex));
2751
- await import_isomorphic_git.default.add({ fs, dir, filepath: schema2.name });
2752
- await import_isomorphic_git.default.commit({
2753
- fs,
2754
- dir,
2755
- author: { name: "bot", email: "bot@registry.domain" },
2756
- message: `chore: updated schema: ${schema2.name} to version ${schema2.version}`
2757
- });
2758
- await import_isomorphic_git.default.tag({
2759
- fs,
2760
- dir,
2761
- ref: `${schema2.name}-${schema2.version}`
2762
- });
2763
- await import_isomorphic_git.default.checkout({
2764
- fs,
2765
- dir,
2766
- ref: main
2767
- });
2768
- await import_isomorphic_git.default.merge({
2769
- fs,
2770
- dir,
2771
- author: { name: "bot", email: "bot@registry.domain" },
2772
- theirs: `${schema2.name}`,
2773
- message: `update schema: ${schema2.name} to version ${schema2.version}`
2774
- });
2775
- const registry = JSON.parse(
2776
- (await pfs.readFile(`${dir}/registry.json`)).toString()
2777
- );
2778
- registry.updated = (/* @__PURE__ */ new Date()).toISOString();
2779
- registry.schemas[schema2.name] = {
2780
- name: schema2.name,
2781
- version: schema2.version,
2782
- description: schema2.description || "",
2783
- created: registry.schemas[schema2.name]?.created || (/* @__PURE__ */ new Date()).toISOString(),
2784
- updated: (/* @__PURE__ */ new Date()).toISOString()
2785
- };
2786
- await pfs.writeFile(`${dir}/registry.json`, JSON.stringify(registry));
2787
- const files = (await import_isomorphic_git.default.listFiles({
2788
- fs,
2789
- dir
2790
- })).filter((i) => i !== "registry.lock");
2791
- const hashes = await Promise.all(
2792
- files.map(async (file) => {
2793
- return [file, await generateSHA256Hash(file)];
2794
- })
2795
- );
2796
- await pfs.writeFile(
2797
- `${dir}/registry.lock`,
2798
- JSON.stringify({
2799
- updated: (/* @__PURE__ */ new Date()).toISOString(),
2800
- hashes
2801
- })
2802
- );
2803
- await import_isomorphic_git.default.add({
2804
- fs,
2805
- dir,
2806
- filepath: `registry.lock`
2807
- });
2808
- await import_isomorphic_git.default.add({
2809
- fs,
2810
- dir,
2811
- filepath: `registry.json`
2812
- });
2813
- await import_isomorphic_git.default.commit({
2814
- fs,
2815
- dir,
2816
- author: { name: "bot", email: "bot@registry.domain" },
2817
- message: `fix: updated schema: ${schema2.name} to version ${schema2.version}`
2818
- });
2819
- await import_isomorphic_git.default.checkout({ fs, dir, ref: main });
2820
- }
2821
- async function delete_(name) {
2822
- await import_isomorphic_git.default.checkout({
2823
- fs,
2824
- dir,
2825
- ref: main,
2826
- force: true
2827
- });
2828
- await import_isomorphic_git.default.deleteBranch({
2829
- fs,
2830
- dir,
2831
- ref: name
2832
- });
2833
- const registry = JSON.parse(
2834
- (await pfs.readFile(`${dir}/registry.json`)).toString()
2835
- );
2836
- delete registry.schemas[name];
2837
- registry.updated = (/* @__PURE__ */ new Date()).toISOString();
2838
- await pfs.writeFile(`${dir}/registry.json`, JSON.stringify(registry));
2839
- const files = (await import_isomorphic_git.default.listFiles({
2840
- fs,
2841
- dir
2842
- })).filter((i) => i !== "registry.lock");
2843
- const hashes = await Promise.all(
2844
- files.map(async (file) => {
2845
- return [file, await generateSHA256Hash(file)];
2846
- })
2847
- );
2848
- await pfs.writeFile(
2849
- `${dir}/registry.lock`,
2850
- JSON.stringify({
2851
- updated: (/* @__PURE__ */ new Date()).toISOString(),
2852
- hashes
2853
- })
2854
- );
2855
- await import_isomorphic_git.default.add({
2856
- fs,
2857
- dir,
2858
- filepath: `registry.json`
2859
- });
2860
- await import_isomorphic_git.default.add({
2861
- fs,
2862
- dir,
2863
- filepath: `registry.lock`
2864
- });
2865
- await import_isomorphic_git.default.commit({
2866
- fs,
2867
- dir,
2868
- author: { name: "bot", email: "bot@registry.domain" },
2869
- message: `chore: deleted schema: ${name}`
2870
- });
2871
- }
2872
- async function list() {
2873
- await import_isomorphic_git.default.checkout({
2874
- fs,
2875
- dir,
2876
- ref: main,
2877
- force: true
2878
- });
2879
- const registry = JSON.parse(
2880
- (await pfs.readFile(`${dir}/registry.json`)).toString()
2881
- );
2882
- const result = Object.entries(registry.schemas).map(
2883
- ([name, { version }]) => ({ name, version })
2884
- );
2885
- return result;
2886
- }
2887
- async function schema(name, version, migrations2 = false) {
2888
- await import_isomorphic_git.default.checkout({
2889
- fs,
2890
- dir,
2891
- ref: main,
2892
- force: true
2893
- });
2894
- const registry = JSON.parse(
2895
- (await pfs.readFile(`${dir}/registry.json`)).toString()
2896
- );
2897
- if (!registry.schemas[name]) {
2898
- return null;
2899
- }
2900
- let ref = name;
2901
- if (version) {
2902
- ref = await import_isomorphic_git.default.resolveRef({ fs, dir, ref: `${name}-${version}` });
2903
- }
2904
- await import_isomorphic_git.default.checkout({
2905
- fs,
2906
- dir,
2907
- ref,
2908
- force: true
2909
- });
2910
- const schema2 = JSON.parse(
2911
- (await pfs.readFile(`${dir}/${name}/schema.json`)).toString()
2912
- );
2913
- if (schema2.mock) {
2914
- schema2.mock = deserializeGenerator(schema2.mock);
2915
- }
2916
- if (migrations2) {
2917
- const migrations3 = await Promise.all(
2918
- (await pfs.readdir(`${dir}/${name}/migrations`)).filter((i) => i !== ".nomedia").map(
2919
- async (i) => (await pfs.readFile(`${dir}/${name}/migrations/${i}`)).toString()
2920
- )
2921
- );
2922
- schema2.migrations = migrations3.map((m) => {
2923
- const migration = JSON.parse(m);
2924
- migration.transform = {
2925
- forward: deserializeFunction(migration.transform.forward),
2926
- backward: deserializeFunction(migration.transform.backward)
2927
- };
2928
- return migration;
2929
- });
2930
- }
2931
- await import_isomorphic_git.default.checkout({
2932
- fs,
2933
- dir,
2934
- ref: main,
2935
- force: true
2936
- });
2937
- return schema2;
2938
- }
2939
- async function stats(schema2) {
2940
- await import_isomorphic_git.default.checkout({
2941
- fs,
2942
- dir,
2943
- ref: main,
2944
- force: true
2945
- });
2946
- if (schema2) {
2947
- const index = JSON.parse(
2948
- (await pfs.readFile(`${dir}/${schema2}/index.json`)).toString()
2949
- );
2950
- return index;
2951
- } else {
2952
- const index = JSON.parse(
2953
- (await pfs.readFile(`${dir}/registry.json`)).toString()
2954
- );
2955
- return index;
2956
- }
2957
- }
2958
- async function sync() {
2959
- await import_isomorphic_git.default.pull({
2960
- fs,
2961
- dir,
2962
- http: import_web.default,
2963
- remote: "origin",
2964
- corsProxy: proxy,
2965
- ref: main,
2966
- author: { name: "bot", email: "bot@registry.domain" },
2967
- fastForwardOnly: true,
2968
- url: authUrl(
2969
- `https://github.com/${credentials.username}/${credentials.repository}.git`,
2970
- credentials.username,
2971
- credentials.password
2972
- ),
2973
- onAuth: () => ({
2974
- username: credentials.username,
2975
- password: credentials.password
2976
- })
2977
- });
2978
- await import_isomorphic_git.default.push({
2979
- fs,
2980
- http: import_web.default,
2981
- dir,
2982
- corsProxy: proxy,
2983
- remote: "origin",
2984
- ref: main,
2985
- url: authUrl(
2986
- `https://github.com/${credentials.username}/${credentials.repository}.git`,
2987
- credentials.username,
2988
- credentials.password
2989
- ),
2990
- onAuth: () => ({
2991
- username: credentials.username,
2992
- password: credentials.password
2993
- })
2994
- });
2995
- }
2996
- async function predicates(name, version) {
2997
- throw new Error("predicates not implemented");
2998
- }
2999
- async function migrations(name, version) {
3000
- await import_isomorphic_git.default.checkout({
3001
- fs,
3002
- dir,
3003
- ref: main,
3004
- force: true
3005
- });
3006
- const registry = JSON.parse(
3007
- (await pfs.readFile(`${dir}/registry.json`)).toString()
3008
- );
3009
- if (!registry.schemas[name]) {
3010
- return [];
3011
- }
3012
- let effectiveVersion = version || registry.schemas[name].version;
3013
- const index = JSON.parse(
3014
- (await pfs.readFile(`${dir}/${name}/index.json`)).toString()
3015
- );
3016
- const compatibleMigrations = [];
3017
- for (const migrationId of Object.keys(index.migrations)) {
3018
- const { hash } = index.migrations[migrationId];
3019
- const migrationFile = `${dir}/${name}/migrations/${hash}.json`;
3020
- const migrationContent = JSON.parse(
3021
- (await pfs.readFile(migrationFile)).toString()
3022
- );
3023
- if (compareSemanticVersions(
3024
- migrationContent.schemaVersion,
3025
- effectiveVersion
3026
- ) <= 0) {
3027
- migrationContent.transform = {
3028
- forward: deserializeFunction(migrationContent.transform.forward),
3029
- backward: deserializeFunction(migrationContent.transform.backward)
3030
- };
3031
- compatibleMigrations.push(migrationContent);
3032
- }
3033
- }
3034
- return compatibleMigrations.sort(
3035
- (a, b) => compareSemanticVersions(a.schemaVersion, b.schemaVersion)
3036
- );
3037
- }
3038
- async function history(name) {
3039
- await import_isomorphic_git.default.checkout({
3040
- fs,
3041
- dir,
3042
- ref: main,
3043
- force: true
3044
- });
3045
- const registry = JSON.parse(
3046
- (await pfs.readFile(`${dir}/registry.json`)).toString()
3047
- );
3048
- if (!registry.schemas[name]) {
3049
- return [];
3050
- }
3051
- const index = JSON.parse(
3052
- (await pfs.readFile(`${dir}/${name}/index.json`)).toString()
3053
- );
3054
- const historicalSchemas = [];
3055
- for (const historyEntry of index.history) {
3056
- const schemaDefinition = await schema(name, historyEntry.version, true);
3057
- if (schemaDefinition) {
3058
- historicalSchemas.push(schemaDefinition);
3059
- }
3060
- }
3061
- return historicalSchemas.sort(
3062
- (a, b) => compareSemanticVersions(a.version, b.version)
3063
- );
3064
- }
3065
- return {
3066
- init,
3067
- clone,
3068
- create,
3069
- update,
3070
- delete: delete_,
3071
- list,
3072
- schema,
3073
- stats,
3074
- sync,
3075
- predicates,
3076
- migrations,
3077
- history
3078
- };
3079
- }
3080
-
3081
- // src/lib/schema/index.ts
3082
- var schema_exports = {};
3083
- __export(schema_exports, {
3084
- MigrationSchema: () => MigrationSchema,
3085
- createSchemaMigrationHelper: () => createSchemaMigrationHelper,
3086
- validate: () => validate,
3087
- validateMigration: () => validateMigration,
3088
- validateSchemaChange: () => validateSchemaChange,
3089
- validateSchemaDefinition: () => validateSchemaDefinition
3090
- });
3091
1297
 
3092
1298
  // src/tools/typegen.ts
3093
- var typegen_exports = {};
3094
- __export(typegen_exports, {
3095
- default: () => typegen_default,
3096
- schemaToTypes: () => schemaToTypes
3097
- });
3098
1299
  function convertFieldTypeToTS(field, parentType, fieldName) {
3099
1300
  switch (field.type) {
3100
1301
  case "string":
@@ -3189,21 +1390,26 @@ ${nestedTypes}`;
3189
1390
  output += "\n";
3190
1391
  return output;
3191
1392
  }
3192
- var typegen_default = schemaToTypes;
3193
1393
  // Annotate the CommonJS export names for ESM import in node:
3194
1394
  0 && (module.exports = {
3195
- MigrationTypes,
3196
- PersistenceTypes,
3197
- RegistryType,
3198
- SchemaTypes,
3199
- crypto,
3200
- merge,
3201
- migration,
3202
- patch,
3203
- persistence,
3204
- registry,
3205
- schema,
3206
- typegen,
3207
- validator,
3208
- version
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
3209
1415
  });