@objectstack/metadata 5.2.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +82 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +82 -24
- package/dist/index.js.map +1 -1
- package/dist/migrations/index.cjs +58 -3
- package/dist/migrations/index.cjs.map +1 -1
- package/dist/migrations/index.d.cts +45 -3
- package/dist/migrations/index.d.ts +45 -3
- package/dist/migrations/index.js +56 -2
- package/dist/migrations/index.js.map +1 -1
- package/dist/node.cjs +82 -24
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +82 -24
- package/dist/node.js.map +1 -1
- package/package.json +7 -7
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,
|
|
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.
|
|
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. `
|
|
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
|
-
|
|
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
|
|
1378
|
+
* @param environmentId - Project ID (undefined = platform-global)
|
|
1321
1379
|
*/
|
|
1322
|
-
setDatabaseDriver(driver, organizationId,
|
|
1323
|
-
if (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1407
|
+
* @param environmentId - Project ID (undefined = platform-global)
|
|
1350
1408
|
*/
|
|
1351
|
-
setDataEngine(engine, organizationId,
|
|
1352
|
-
if (
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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 =
|
|
3426
|
+
const artifact = EnvironmentArtifactSchema.parse(obj);
|
|
3369
3427
|
metadata = artifact.metadata;
|
|
3370
3428
|
} else if (obj?.success && obj?.data?.metadata) {
|
|
3371
|
-
const artifact =
|
|
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
|
|
3378
|
-
|
|
3435
|
+
const environmentId = this.options.environmentId ?? "proj_local";
|
|
3436
|
+
EnvironmentArtifactSchema.parse({
|
|
3379
3437
|
schemaVersion: "0.1",
|
|
3380
|
-
|
|
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
|
|
3437
|
-
if (!
|
|
3438
|
-
throw new Error("[MetadataPlugin] artifact-api source requires options.
|
|
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/
|
|
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)}`;
|