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