@objectstack/metadata 5.2.0 → 6.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.cjs CHANGED
@@ -548,7 +548,7 @@ var LRUCache = class {
548
548
  // src/migrations/add-sys-metadata-overlay-index.ts
549
549
  var INDEX_NAME = "idx_sys_metadata_overlay_active";
550
550
  var TABLE = "sys_metadata";
551
- var COLUMNS = "(type, name, organization_id, project_id, scope)";
551
+ var COLUMNS = "(type, name, organization_id, environment_id, scope)";
552
552
  var WHERE = "state = 'active'";
553
553
  async function addSysMetadataOverlayIndex(driver) {
554
554
  const driverAny = driver;
@@ -587,6 +587,59 @@ async function addSysMetadataOverlayIndex(driver) {
587
587
  }
588
588
  }
589
589
 
590
+ // src/migrations/migrate-project-id-to-environment-id.ts
591
+ var AFFECTED_TABLES = [
592
+ "sys_metadata",
593
+ "sys_metadata_history"
594
+ ];
595
+ async function migrateProjectIdToEnvironmentId(driver) {
596
+ const driverAny = driver;
597
+ if (typeof driverAny.raw !== "function") {
598
+ throw new Error(
599
+ "migrateProjectIdToEnvironmentId: driver must expose a .raw(sql, bindings?) method. SqlDriver (better-sqlite3/knex) and TursoDriver both support this."
600
+ );
601
+ }
602
+ const results = [];
603
+ for (const table of AFFECTED_TABLES) {
604
+ try {
605
+ const hasColumn = await _columnExists(driverAny, table, "project_id");
606
+ const alreadyMigrated = await _columnExists(driverAny, table, "environment_id");
607
+ if (alreadyMigrated && !hasColumn) {
608
+ results.push({ table, status: "already_done" });
609
+ continue;
610
+ }
611
+ if (!hasColumn) {
612
+ results.push({ table, status: "table_missing" });
613
+ continue;
614
+ }
615
+ await driverAny.raw(
616
+ `ALTER TABLE "${table}" RENAME COLUMN project_id TO environment_id`
617
+ );
618
+ results.push({ table, status: "renamed" });
619
+ } catch (err) {
620
+ results.push({ table, status: "error", error: err?.message ?? String(err) });
621
+ }
622
+ }
623
+ return results;
624
+ }
625
+ async function _columnExists(driver, table, column) {
626
+ try {
627
+ const rows = await driver.raw(`PRAGMA table_info("${table}")`);
628
+ if (Array.isArray(rows) && rows.length > 0) {
629
+ const list2 = Array.isArray(rows[0]) ? rows[0] : rows;
630
+ return list2.some((r) => r?.name === column);
631
+ }
632
+ const result = await driver.raw(
633
+ `SELECT column_name FROM information_schema.columns WHERE table_name = ? AND column_name = ?`,
634
+ [table, column]
635
+ );
636
+ const list = Array.isArray(result[0]) ? result[0] : result;
637
+ return list.length > 0;
638
+ } catch {
639
+ return false;
640
+ }
641
+ }
642
+
590
643
  // src/loaders/database-loader.ts
591
644
  var DatabaseLoader = class {
592
645
  constructor(options) {
@@ -610,7 +663,7 @@ var DatabaseLoader = class {
610
663
  this.tableName = options.tableName ?? "sys_metadata";
611
664
  this.historyTableName = options.historyTableName ?? "sys_metadata_history";
612
665
  this.organizationId = options.organizationId;
613
- void options.projectId;
666
+ void options.environmentId;
614
667
  this.trackHistory = options.trackHistory !== false;
615
668
  const cacheOpts = options.cache;
616
669
  const cacheEnabled = cacheOpts?.enabled !== false;
@@ -742,6 +795,7 @@ var DatabaseLoader = class {
742
795
  }
743
796
  }
744
797
  if (driver) {
798
+ await migrateProjectIdToEnvironmentId(driver).catch(() => void 0);
745
799
  await addSysMetadataOverlayIndex(driver);
746
800
  }
747
801
  } catch {
@@ -754,6 +808,10 @@ var DatabaseLoader = class {
754
808
  name: this.tableName
755
809
  });
756
810
  this.schemaReady = true;
811
+ try {
812
+ await migrateProjectIdToEnvironmentId(this.driver);
813
+ } catch {
814
+ }
757
815
  try {
758
816
  await addSysMetadataOverlayIndex(this.driver);
759
817
  } catch {
@@ -784,7 +842,7 @@ var DatabaseLoader = class {
784
842
  }
785
843
  /**
786
844
  * Build base filter conditions for queries.
787
- * Filters by organizationId when configured. `projectId` is accepted
845
+ * Filters by organizationId when configured. `environmentId` is accepted
788
846
  * for back-compat but no longer constrains the query — see
789
847
  * ADR-0008 §0 (branch/project removal).
790
848
  */
@@ -883,7 +941,7 @@ var DatabaseLoader = class {
883
941
  owner: row.owner,
884
942
  state: row.state ?? "active",
885
943
  organizationId: row.organization_id,
886
- projectId: row.project_id,
944
+ environmentId: row.environment_id,
887
945
  version: row.version ?? 1,
888
946
  checksum: row.checksum,
889
947
  source: row.source,
@@ -1317,13 +1375,13 @@ var _MetadataManager = class _MetadataManager {
1317
1375
  *
1318
1376
  * @param driver - An IDataDriver instance for database operations
1319
1377
  * @param organizationId - Organization ID for multi-tenant isolation
1320
- * @param projectId - Project ID (undefined = platform-global)
1378
+ * @param environmentId - Project ID (undefined = platform-global)
1321
1379
  */
1322
- setDatabaseDriver(driver, organizationId, projectId) {
1323
- if (projectId !== void 0) {
1380
+ setDatabaseDriver(driver, organizationId, environmentId) {
1381
+ if (environmentId !== void 0) {
1324
1382
  this.logger.info("Project kernel \u2014 skipping DatabaseLoader for sys_metadata (control-plane only)", {
1325
1383
  organizationId,
1326
- projectId
1384
+ environmentId
1327
1385
  });
1328
1386
  return;
1329
1387
  }
@@ -1332,7 +1390,7 @@ var _MetadataManager = class _MetadataManager {
1332
1390
  driver,
1333
1391
  tableName,
1334
1392
  organizationId,
1335
- projectId,
1393
+ environmentId,
1336
1394
  cache: this.config.cache?.databaseLoader
1337
1395
  });
1338
1396
  this.registerLoader(dbLoader);
@@ -1346,13 +1404,13 @@ var _MetadataManager = class _MetadataManager {
1346
1404
  *
1347
1405
  * @param engine - An IDataEngine instance (typically the ObjectQL service)
1348
1406
  * @param organizationId - Organization ID for multi-tenant isolation
1349
- * @param projectId - Project ID (undefined = platform-global)
1407
+ * @param environmentId - Project ID (undefined = platform-global)
1350
1408
  */
1351
- setDataEngine(engine, organizationId, projectId) {
1352
- if (projectId !== void 0) {
1409
+ setDataEngine(engine, organizationId, environmentId) {
1410
+ if (environmentId !== void 0) {
1353
1411
  this.logger.info("Project kernel \u2014 skipping DatabaseLoader for sys_metadata (control-plane only)", {
1354
1412
  organizationId,
1355
- projectId
1413
+ environmentId
1356
1414
  });
1357
1415
  return;
1358
1416
  }
@@ -1361,7 +1419,7 @@ var _MetadataManager = class _MetadataManager {
1361
1419
  engine,
1362
1420
  tableName,
1363
1421
  organizationId,
1364
- projectId,
1422
+ environmentId,
1365
1423
  cache: this.config.cache?.databaseLoader
1366
1424
  });
1367
1425
  this.registerLoader(dbLoader);
@@ -3360,24 +3418,24 @@ var MetadataPlugin = class {
3360
3418
  * metadata items into the MetadataManager.
3361
3419
  */
3362
3420
  async _parseAndRegisterArtifact(ctx, raw, label) {
3363
- const { ProjectArtifactSchema } = await import("@objectstack/spec/cloud");
3421
+ const { EnvironmentArtifactSchema } = await import("@objectstack/spec/cloud");
3364
3422
  const { ObjectStackDefinitionSchema } = await import("@objectstack/spec");
3365
3423
  let metadata;
3366
3424
  const obj = raw;
3367
3425
  if (obj?.schemaVersion && obj?.commitId && obj?.metadata !== void 0) {
3368
- const artifact = ProjectArtifactSchema.parse(obj);
3426
+ const artifact = EnvironmentArtifactSchema.parse(obj);
3369
3427
  metadata = artifact.metadata;
3370
3428
  } else if (obj?.success && obj?.data?.metadata) {
3371
- const artifact = ProjectArtifactSchema.parse(obj.data);
3429
+ const artifact = EnvironmentArtifactSchema.parse(obj.data);
3372
3430
  metadata = artifact.metadata;
3373
3431
  } else {
3374
3432
  const def = ObjectStackDefinitionSchema.parse(obj);
3375
3433
  const canonical = JSON.stringify(def, Object.keys(def).sort());
3376
3434
  const checksum = (0, import_node_crypto2.createHash)("sha256").update(canonical).digest("hex");
3377
- const projectId = this.options.projectId ?? "proj_local";
3378
- ProjectArtifactSchema.parse({
3435
+ const environmentId = this.options.environmentId ?? "proj_local";
3436
+ EnvironmentArtifactSchema.parse({
3379
3437
  schemaVersion: "0.1",
3380
- projectId,
3438
+ environmentId,
3381
3439
  commitId: "local-dev",
3382
3440
  checksum,
3383
3441
  metadata: def
@@ -3433,13 +3491,13 @@ var MetadataPlugin = class {
3433
3491
  * P2: Load metadata from the cloud artifact API endpoint.
3434
3492
  */
3435
3493
  async _loadFromArtifactApi(ctx, src) {
3436
- const projectId = this.options.projectId;
3437
- if (!projectId) {
3438
- throw new Error("[MetadataPlugin] artifact-api source requires options.projectId to be set");
3494
+ const environmentId = this.options.environmentId;
3495
+ if (!environmentId) {
3496
+ throw new Error("[MetadataPlugin] artifact-api source requires options.environmentId to be set");
3439
3497
  }
3440
3498
  let artifactUrl = src.url.replace(/\/+$/, "");
3441
3499
  if (!/\/api\/v\d+\/cloud\/projects\//i.test(artifactUrl)) {
3442
- artifactUrl = `${artifactUrl}/api/v1/cloud/projects/${projectId}/artifact`;
3500
+ artifactUrl = `${artifactUrl}/api/v1/cloud/environments/${environmentId}/artifact`;
3443
3501
  }
3444
3502
  if (src.commitId) {
3445
3503
  artifactUrl += `${artifactUrl.includes("?") ? "&" : "?"}commit=${encodeURIComponent(src.commitId)}`;