@objectstack/objectql 9.3.0 → 9.4.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.d.mts +62 -25
- package/dist/index.d.ts +62 -25
- package/dist/index.js +163 -101
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +163 -101
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -332,6 +332,19 @@ var init_seed_loader = __esm({
|
|
|
332
332
|
if (records && records.length > 0) {
|
|
333
333
|
return String(records[0].id || records[0]._id);
|
|
334
334
|
}
|
|
335
|
+
if (targetField !== "id") {
|
|
336
|
+
const byId = { id: value };
|
|
337
|
+
if (organizationId) byId.organization_id = organizationId;
|
|
338
|
+
const idMatch = await this.engine.find(targetObject, {
|
|
339
|
+
where: byId,
|
|
340
|
+
fields: ["id"],
|
|
341
|
+
limit: 1,
|
|
342
|
+
context: { isSystem: true }
|
|
343
|
+
});
|
|
344
|
+
if (idMatch && idMatch.length > 0) {
|
|
345
|
+
return String(idMatch[0].id || idMatch[0]._id);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
335
348
|
} catch {
|
|
336
349
|
}
|
|
337
350
|
return null;
|
|
@@ -950,18 +963,16 @@ function applySystemFields(schema, opts) {
|
|
|
950
963
|
fields: { ...additions, ...schema.fields ?? {} }
|
|
951
964
|
};
|
|
952
965
|
}
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
return typeof pkg === "string" && pkg.length > 0 && pkg !== SYS_METADATA_OWNER;
|
|
966
|
+
function isShareableNamespace(ns) {
|
|
967
|
+
return RESERVED_NAMESPACES.has(ns) || ns === "sys";
|
|
956
968
|
}
|
|
957
|
-
var
|
|
958
|
-
constructor(
|
|
969
|
+
var NamespaceConflictError = class extends Error {
|
|
970
|
+
constructor(namespace, existingPackageId, incomingPackageId) {
|
|
959
971
|
super(
|
|
960
|
-
`
|
|
972
|
+
`Namespace conflict: namespace "${namespace}" is already owned by package "${existingPackageId}", so package "${incomingPackageId}" cannot be installed alongside it. A namespace is the mandatory prefix of every object name (e.g. "${namespace}_account") and the container that scopes a package's UI metadata, so it must be unique per installation. Choose a different namespace for "${incomingPackageId}", or uninstall "${existingPackageId}" first. If this is a deliberate migration, set OS_METADATA_COLLISION=warn to downgrade to a warning. See ADR-0048.`
|
|
961
973
|
);
|
|
962
|
-
this.name = "
|
|
963
|
-
this.
|
|
964
|
-
this.name_ = name;
|
|
974
|
+
this.name = "NamespaceConflictError";
|
|
975
|
+
this.namespace = namespace;
|
|
965
976
|
this.existingPackageId = existingPackageId;
|
|
966
977
|
this.incomingPackageId = incomingPackageId;
|
|
967
978
|
}
|
|
@@ -1317,17 +1328,6 @@ var SchemaRegistry = class {
|
|
|
1317
1328
|
if (collection.has(storageKey)) {
|
|
1318
1329
|
this.log(`[Registry] Overwriting ${type}: ${storageKey}`);
|
|
1319
1330
|
}
|
|
1320
|
-
if (isRealPackage(packageId)) {
|
|
1321
|
-
const conflictOwner = this.findOtherPackageOwner(collection, baseName, packageId);
|
|
1322
|
-
if (conflictOwner) {
|
|
1323
|
-
const err = new MetadataCollisionError(type, baseName, conflictOwner, packageId);
|
|
1324
|
-
if (this.collisionPolicy === "warn") {
|
|
1325
|
-
console.warn(`[Registry] ${err.message}`);
|
|
1326
|
-
} else {
|
|
1327
|
-
throw err;
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
1331
|
if (packageId && collection.has(baseName)) {
|
|
1332
1332
|
const dbOnly = collection.get(baseName);
|
|
1333
1333
|
if (dbOnly && !dbOnly._packageId) {
|
|
@@ -1339,22 +1339,6 @@ var SchemaRegistry = class {
|
|
|
1339
1339
|
collection.set(storageKey, item);
|
|
1340
1340
|
this.log(`[Registry] Registered ${type}: ${storageKey}`);
|
|
1341
1341
|
}
|
|
1342
|
-
/**
|
|
1343
|
-
* Find a code package OTHER than `incoming` that already owns `baseName` in
|
|
1344
|
-
* `collection` (ADR-0048 cross-package collision detection). Scans the live
|
|
1345
|
-
* collection — like {@link getItem} / {@link unregisterItem} — so it always
|
|
1346
|
-
* reflects current state with no parallel index to drift across
|
|
1347
|
-
* reset/unregister. Returns the conflicting owner's package id, or undefined
|
|
1348
|
-
* when the name is free or only held by the same package / a runtime overlay.
|
|
1349
|
-
*/
|
|
1350
|
-
findOtherPackageOwner(collection, baseName, incoming) {
|
|
1351
|
-
for (const [key, item] of collection) {
|
|
1352
|
-
if (key !== baseName && !key.endsWith(`:${baseName}`)) continue;
|
|
1353
|
-
const owner = item?._packageId;
|
|
1354
|
-
if (isRealPackage(owner) && owner !== incoming) return owner;
|
|
1355
|
-
}
|
|
1356
|
-
return void 0;
|
|
1357
|
-
}
|
|
1358
1342
|
/**
|
|
1359
1343
|
* Validate Metadata against Spec Zod Schemas
|
|
1360
1344
|
*/
|
|
@@ -1397,9 +1381,23 @@ var SchemaRegistry = class {
|
|
|
1397
1381
|
console.warn(`[Registry] Attempted to unregister non-existent ${type}: ${name}`);
|
|
1398
1382
|
}
|
|
1399
1383
|
/**
|
|
1400
|
-
* Universal Get Method
|
|
1384
|
+
* Universal Get Method.
|
|
1385
|
+
*
|
|
1386
|
+
* ADR-0048 §3.3 — *package-scoped* resolution. When `currentPackageId` is
|
|
1387
|
+
* given (the package the caller is resolving within — known from the route /
|
|
1388
|
+
* `activeApp._packageId`), a bare name resolves to *that package's* item
|
|
1389
|
+
* before any cross-package fallback, so two packages shipping e.g.
|
|
1390
|
+
* `page/home` no longer resolve by registration order (first-match-wins).
|
|
1391
|
+
* Because package ids are globally unique this is unambiguous. Omitting
|
|
1392
|
+
* `currentPackageId` preserves the legacy resolution exactly (backward
|
|
1393
|
+
* compatible) and is best-effort: it returns the first match.
|
|
1394
|
+
*
|
|
1395
|
+
* Precedence (highest first):
|
|
1396
|
+
* 1. bare-key runtime/DB overlay (ADR-0005 sanctioned override) — unchanged
|
|
1397
|
+
* 2. the `currentPackageId` composite entry (prefer-local)
|
|
1398
|
+
* 3. first composite match (legacy first-registered-wins fallback)
|
|
1401
1399
|
*/
|
|
1402
|
-
getItem(type, name) {
|
|
1400
|
+
getItem(type, name, currentPackageId) {
|
|
1403
1401
|
if (type === "object" || type === "objects") {
|
|
1404
1402
|
return this.getObject(name);
|
|
1405
1403
|
}
|
|
@@ -1407,6 +1405,10 @@ var SchemaRegistry = class {
|
|
|
1407
1405
|
if (!collection) return void 0;
|
|
1408
1406
|
const direct = collection.get(name);
|
|
1409
1407
|
if (direct) return direct;
|
|
1408
|
+
if (currentPackageId) {
|
|
1409
|
+
const local = collection.get(`${currentPackageId}:${name}`);
|
|
1410
|
+
if (local) return local;
|
|
1411
|
+
}
|
|
1410
1412
|
for (const [key, item] of collection) {
|
|
1411
1413
|
if (key.endsWith(`:${name}`)) {
|
|
1412
1414
|
return item;
|
|
@@ -1428,13 +1430,17 @@ var SchemaRegistry = class {
|
|
|
1428
1430
|
* it (that masking is exactly the "registry pollution" bug where a
|
|
1429
1431
|
* locked app's `_lock` read back as undefined after a PUT+GET).
|
|
1430
1432
|
*/
|
|
1431
|
-
getArtifactItem(type, name) {
|
|
1433
|
+
getArtifactItem(type, name, currentPackageId) {
|
|
1432
1434
|
if (type === "object" || type === "objects") {
|
|
1433
1435
|
const obj = this.getObject(name);
|
|
1434
1436
|
return obj && obj._packageId && obj._packageId !== "sys_metadata" ? obj : void 0;
|
|
1435
1437
|
}
|
|
1436
1438
|
const collection = this.metadata.get(type);
|
|
1437
1439
|
if (!collection) return void 0;
|
|
1440
|
+
if (currentPackageId) {
|
|
1441
|
+
const local = collection.get(`${currentPackageId}:${name}`);
|
|
1442
|
+
if (local && local._packageId && local._packageId !== "sys_metadata") return local;
|
|
1443
|
+
}
|
|
1438
1444
|
for (const [key, item] of collection) {
|
|
1439
1445
|
if (key !== name && key.endsWith(`:${name}`)) {
|
|
1440
1446
|
const it = item;
|
|
@@ -1518,6 +1524,20 @@ var SchemaRegistry = class {
|
|
|
1518
1524
|
// Package Management
|
|
1519
1525
|
// ==========================================
|
|
1520
1526
|
installPackage(manifest, settings) {
|
|
1527
|
+
if (manifest.namespace && !isShareableNamespace(manifest.namespace)) {
|
|
1528
|
+
const conflictOwner = this.getNamespaceOwners(manifest.namespace).find(
|
|
1529
|
+
(owner) => owner !== manifest.id
|
|
1530
|
+
);
|
|
1531
|
+
if (conflictOwner) {
|
|
1532
|
+
if (this.collisionPolicy === "warn") {
|
|
1533
|
+
console.warn(
|
|
1534
|
+
`[Registry] Namespace conflict (downgraded to warning via OS_METADATA_COLLISION=warn): namespace "${manifest.namespace}" is already owned by "${conflictOwner}"; installing "${manifest.id}" anyway. See ADR-0048.`
|
|
1535
|
+
);
|
|
1536
|
+
} else {
|
|
1537
|
+
throw new NamespaceConflictError(manifest.namespace, conflictOwner, manifest.id);
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1521
1541
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1522
1542
|
const disabled = this.initialDisabledPackageIds.has(manifest.id);
|
|
1523
1543
|
const pkg = {
|
|
@@ -1595,8 +1615,8 @@ var SchemaRegistry = class {
|
|
|
1595
1615
|
registerApp(app, packageId) {
|
|
1596
1616
|
this.registerItem("app", app, "name", packageId);
|
|
1597
1617
|
}
|
|
1598
|
-
getApp(name) {
|
|
1599
|
-
const app = this.getItem("app", name);
|
|
1618
|
+
getApp(name, currentPackageId) {
|
|
1619
|
+
const app = this.getItem("app", name, currentPackageId);
|
|
1600
1620
|
if (!app) return app;
|
|
1601
1621
|
return this.applyNavContributions(app);
|
|
1602
1622
|
}
|
|
@@ -1816,7 +1836,7 @@ var SysMetadataRepository = class {
|
|
|
1816
1836
|
this.assertOpen();
|
|
1817
1837
|
const state = opts?.state ?? "active";
|
|
1818
1838
|
const row = await this.engine.findOne("sys_metadata", {
|
|
1819
|
-
where: this.whereFor(ref, state)
|
|
1839
|
+
where: this.whereFor(ref, state, opts && "packageId" in opts ? opts.packageId ?? null : void 0)
|
|
1820
1840
|
});
|
|
1821
1841
|
if (!row) return null;
|
|
1822
1842
|
return this.rowToItem(ref, row);
|
|
@@ -1865,7 +1885,7 @@ var SysMetadataRepository = class {
|
|
|
1865
1885
|
const hash = (0, import_metadata_core.hashSpec)(body);
|
|
1866
1886
|
const result = await this.withTxn(async (ctx) => {
|
|
1867
1887
|
const existing = await this.engine.findOne("sys_metadata", {
|
|
1868
|
-
where: this.whereFor(ref, state),
|
|
1888
|
+
where: this.whereFor(ref, state, opts.packageId ?? null),
|
|
1869
1889
|
context: ctx
|
|
1870
1890
|
});
|
|
1871
1891
|
const existingHash = existing?.checksum ?? null;
|
|
@@ -2349,13 +2369,15 @@ var SysMetadataRepository = class {
|
|
|
2349
2369
|
err.status = 403;
|
|
2350
2370
|
throw err;
|
|
2351
2371
|
}
|
|
2352
|
-
whereFor(ref, state = "active") {
|
|
2353
|
-
|
|
2372
|
+
whereFor(ref, state = "active", packageId) {
|
|
2373
|
+
const where = {
|
|
2354
2374
|
type: ref.type,
|
|
2355
2375
|
name: ref.name,
|
|
2356
2376
|
organization_id: this.organizationId,
|
|
2357
2377
|
state
|
|
2358
2378
|
};
|
|
2379
|
+
if (packageId !== void 0) where.package_id = packageId;
|
|
2380
|
+
return where;
|
|
2359
2381
|
}
|
|
2360
2382
|
fullRef(ref) {
|
|
2361
2383
|
return {
|
|
@@ -3042,8 +3064,8 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3042
3064
|
await exec("DROP INDEX IF EXISTS idx_sys_metadata_overlay_active");
|
|
3043
3065
|
} catch {
|
|
3044
3066
|
}
|
|
3045
|
-
const partialSql = "CREATE UNIQUE INDEX IF NOT EXISTS idx_sys_metadata_overlay_active ON sys_metadata (type, name, organization_id) WHERE state = 'active'";
|
|
3046
|
-
const fallbackSql = "CREATE INDEX IF NOT EXISTS idx_sys_metadata_overlay_active ON sys_metadata (type, name, organization_id)";
|
|
3067
|
+
const partialSql = "CREATE UNIQUE INDEX IF NOT EXISTS idx_sys_metadata_overlay_active ON sys_metadata (type, name, organization_id, COALESCE(package_id, '')) WHERE state = 'active'";
|
|
3068
|
+
const fallbackSql = "CREATE INDEX IF NOT EXISTS idx_sys_metadata_overlay_active ON sys_metadata (type, name, organization_id, package_id)";
|
|
3047
3069
|
try {
|
|
3048
3070
|
await exec(partialSql);
|
|
3049
3071
|
} catch (err) {
|
|
@@ -3055,7 +3077,11 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3055
3077
|
}
|
|
3056
3078
|
}
|
|
3057
3079
|
}
|
|
3058
|
-
|
|
3080
|
+
try {
|
|
3081
|
+
await exec("DROP INDEX IF EXISTS idx_sys_metadata_overlay_draft");
|
|
3082
|
+
} catch {
|
|
3083
|
+
}
|
|
3084
|
+
const draftPartialSql = "CREATE UNIQUE INDEX IF NOT EXISTS idx_sys_metadata_overlay_draft ON sys_metadata (type, name, organization_id, COALESCE(package_id, '')) WHERE state = 'draft'";
|
|
3059
3085
|
try {
|
|
3060
3086
|
await exec(draftPartialSql);
|
|
3061
3087
|
} catch (err) {
|
|
@@ -3063,7 +3089,7 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3063
3089
|
if (/partial|where clause|syntax/i.test(msg)) {
|
|
3064
3090
|
try {
|
|
3065
3091
|
await exec(
|
|
3066
|
-
"CREATE INDEX IF NOT EXISTS idx_sys_metadata_overlay_draft ON sys_metadata (type, name, organization_id)"
|
|
3092
|
+
"CREATE INDEX IF NOT EXISTS idx_sys_metadata_overlay_draft ON sys_metadata (type, name, organization_id, package_id)"
|
|
3067
3093
|
);
|
|
3068
3094
|
} catch {
|
|
3069
3095
|
}
|
|
@@ -3464,7 +3490,8 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3464
3490
|
items.map((it) => {
|
|
3465
3491
|
const a = this.lookupArtifactItem(
|
|
3466
3492
|
request.type,
|
|
3467
|
-
it?.name
|
|
3493
|
+
it?.name,
|
|
3494
|
+
packageId ?? it?._packageId
|
|
3468
3495
|
);
|
|
3469
3496
|
return mergeArtifactProtection(it, a);
|
|
3470
3497
|
})
|
|
@@ -3478,16 +3505,28 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3478
3505
|
if (request.previewDrafts && readState !== "draft") {
|
|
3479
3506
|
try {
|
|
3480
3507
|
const findDraft = async (oid) => {
|
|
3481
|
-
const
|
|
3482
|
-
|
|
3483
|
-
|
|
3508
|
+
const lookup = async (t) => {
|
|
3509
|
+
const base = {
|
|
3510
|
+
type: t,
|
|
3511
|
+
name: request.name,
|
|
3512
|
+
state: "draft",
|
|
3513
|
+
organization_id: oid
|
|
3514
|
+
};
|
|
3515
|
+
if (request.packageId) {
|
|
3516
|
+
const scoped = await this.engine.findOne("sys_metadata", {
|
|
3517
|
+
where: { ...base, package_id: request.packageId }
|
|
3518
|
+
});
|
|
3519
|
+
if (scoped) return scoped;
|
|
3520
|
+
return await this.engine.findOne("sys_metadata", {
|
|
3521
|
+
where: { ...base, package_id: null }
|
|
3522
|
+
});
|
|
3523
|
+
}
|
|
3524
|
+
return await this.engine.findOne("sys_metadata", { where: base });
|
|
3525
|
+
};
|
|
3526
|
+
const rec = await lookup(request.type);
|
|
3484
3527
|
if (rec) return rec;
|
|
3485
3528
|
const alt = import_shared4.PLURAL_TO_SINGULAR[request.type] ?? import_shared4.SINGULAR_TO_PLURAL[request.type];
|
|
3486
|
-
if (alt)
|
|
3487
|
-
return await this.engine.findOne("sys_metadata", {
|
|
3488
|
-
where: { type: alt, name: request.name, state: "draft", organization_id: oid }
|
|
3489
|
-
});
|
|
3490
|
-
}
|
|
3529
|
+
if (alt) return await lookup(alt);
|
|
3491
3530
|
return void 0;
|
|
3492
3531
|
};
|
|
3493
3532
|
const draftRec = (orgId ? await findDraft(orgId) : void 0) ?? await findDraft(null);
|
|
@@ -3505,24 +3544,28 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3505
3544
|
}
|
|
3506
3545
|
try {
|
|
3507
3546
|
const findOverlay = async (oid) => {
|
|
3508
|
-
const
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
state: readState,
|
|
3512
|
-
organization_id: oid
|
|
3513
|
-
};
|
|
3514
|
-
const rec = await this.engine.findOne("sys_metadata", { where });
|
|
3515
|
-
if (rec) return rec;
|
|
3516
|
-
const alt = import_shared4.PLURAL_TO_SINGULAR[request.type] ?? import_shared4.SINGULAR_TO_PLURAL[request.type];
|
|
3517
|
-
if (alt) {
|
|
3518
|
-
const altWhere = {
|
|
3519
|
-
type: alt,
|
|
3547
|
+
const lookup = async (t) => {
|
|
3548
|
+
const base = {
|
|
3549
|
+
type: t,
|
|
3520
3550
|
name: request.name,
|
|
3521
3551
|
state: readState,
|
|
3522
3552
|
organization_id: oid
|
|
3523
3553
|
};
|
|
3524
|
-
|
|
3525
|
-
|
|
3554
|
+
if (request.packageId) {
|
|
3555
|
+
const scoped = await this.engine.findOne("sys_metadata", {
|
|
3556
|
+
where: { ...base, package_id: request.packageId }
|
|
3557
|
+
});
|
|
3558
|
+
if (scoped) return scoped;
|
|
3559
|
+
return await this.engine.findOne("sys_metadata", {
|
|
3560
|
+
where: { ...base, package_id: null }
|
|
3561
|
+
});
|
|
3562
|
+
}
|
|
3563
|
+
return await this.engine.findOne("sys_metadata", { where: base });
|
|
3564
|
+
};
|
|
3565
|
+
const rec = await lookup(request.type);
|
|
3566
|
+
if (rec) return rec;
|
|
3567
|
+
const alt = import_shared4.PLURAL_TO_SINGULAR[request.type] ?? import_shared4.SINGULAR_TO_PLURAL[request.type];
|
|
3568
|
+
if (alt) return await lookup(alt);
|
|
3526
3569
|
return void 0;
|
|
3527
3570
|
};
|
|
3528
3571
|
const record = (orgId ? await findOverlay(orgId) : void 0) ?? await findOverlay(null);
|
|
@@ -3551,13 +3594,13 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3551
3594
|
const services = this.getServicesRegistry?.();
|
|
3552
3595
|
const metadataService = services?.get("metadata");
|
|
3553
3596
|
if (metadataService && typeof metadataService.get === "function") {
|
|
3554
|
-
const fromService = await metadataService.get(request.type, request.name);
|
|
3597
|
+
const fromService = await metadataService.get(request.type, request.name, request.packageId);
|
|
3555
3598
|
if (fromService !== void 0 && fromService !== null) {
|
|
3556
3599
|
item = fromService;
|
|
3557
3600
|
} else {
|
|
3558
3601
|
const alt = import_shared4.PLURAL_TO_SINGULAR[request.type] ?? import_shared4.SINGULAR_TO_PLURAL[request.type];
|
|
3559
3602
|
if (alt) {
|
|
3560
|
-
const altFromService = await metadataService.get(alt, request.name);
|
|
3603
|
+
const altFromService = await metadataService.get(alt, request.name, request.packageId);
|
|
3561
3604
|
if (altFromService !== void 0 && altFromService !== null) {
|
|
3562
3605
|
item = altFromService;
|
|
3563
3606
|
}
|
|
@@ -3568,16 +3611,16 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3568
3611
|
}
|
|
3569
3612
|
}
|
|
3570
3613
|
if (item === void 0) {
|
|
3571
|
-
item = this.engine.registry.getItem(request.type, request.name);
|
|
3614
|
+
item = this.engine.registry.getItem(request.type, request.name, request.packageId);
|
|
3572
3615
|
if (item === void 0) {
|
|
3573
3616
|
const alt = import_shared4.PLURAL_TO_SINGULAR[request.type] ?? import_shared4.SINGULAR_TO_PLURAL[request.type];
|
|
3574
|
-
if (alt) item = this.engine.registry.getItem(alt, request.name);
|
|
3617
|
+
if (alt) item = this.engine.registry.getItem(alt, request.name, request.packageId);
|
|
3575
3618
|
}
|
|
3576
3619
|
}
|
|
3577
3620
|
if ((request.type === "app" || request.type === "apps") && item) {
|
|
3578
3621
|
item = this.engine.registry.applyNavContributions(item);
|
|
3579
3622
|
}
|
|
3580
|
-
const artifactItem = this.lookupArtifactItem(request.type, request.name);
|
|
3623
|
+
const artifactItem = this.lookupArtifactItem(request.type, request.name, request.packageId);
|
|
3581
3624
|
let decorated = decorateMetadataItem(
|
|
3582
3625
|
request.type,
|
|
3583
3626
|
mergeArtifactProtection(item, artifactItem)
|
|
@@ -3645,20 +3688,20 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3645
3688
|
const services = this.getServicesRegistry?.();
|
|
3646
3689
|
const metadataService = services?.get("metadata");
|
|
3647
3690
|
if (metadataService && typeof metadataService.get === "function") {
|
|
3648
|
-
let fromService = await metadataService.get(request.type, request.name);
|
|
3691
|
+
let fromService = await metadataService.get(request.type, request.name, request.packageId);
|
|
3649
3692
|
if (fromService === void 0 || fromService === null) {
|
|
3650
3693
|
const alt = import_shared4.PLURAL_TO_SINGULAR[request.type] ?? import_shared4.SINGULAR_TO_PLURAL[request.type];
|
|
3651
|
-
if (alt) fromService = await metadataService.get(alt, request.name);
|
|
3694
|
+
if (alt) fromService = await metadataService.get(alt, request.name, request.packageId);
|
|
3652
3695
|
}
|
|
3653
3696
|
if (fromService !== void 0 && fromService !== null) code = fromService;
|
|
3654
3697
|
}
|
|
3655
3698
|
} catch {
|
|
3656
3699
|
}
|
|
3657
3700
|
if (code === null) {
|
|
3658
|
-
let regItem = this.lookupArtifactItem(request.type, request.name) ?? this.engine.registry.getItem(request.type, request.name);
|
|
3701
|
+
let regItem = this.lookupArtifactItem(request.type, request.name, request.packageId) ?? this.engine.registry.getItem(request.type, request.name, request.packageId);
|
|
3659
3702
|
if (regItem === void 0) {
|
|
3660
3703
|
const alt = import_shared4.PLURAL_TO_SINGULAR[request.type] ?? import_shared4.SINGULAR_TO_PLURAL[request.type];
|
|
3661
|
-
if (alt) regItem = this.engine.registry.getItem(alt, request.name);
|
|
3704
|
+
if (alt) regItem = this.engine.registry.getItem(alt, request.name, request.packageId);
|
|
3662
3705
|
}
|
|
3663
3706
|
if (regItem !== void 0) code = regItem;
|
|
3664
3707
|
}
|
|
@@ -3666,20 +3709,28 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3666
3709
|
let overlayScope = null;
|
|
3667
3710
|
try {
|
|
3668
3711
|
const findOverlay = async (oid) => {
|
|
3669
|
-
const
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3712
|
+
const lookup = async (t) => {
|
|
3713
|
+
const base = {
|
|
3714
|
+
type: t,
|
|
3715
|
+
name: request.name,
|
|
3716
|
+
state: "active",
|
|
3717
|
+
organization_id: oid
|
|
3718
|
+
};
|
|
3719
|
+
if (request.packageId) {
|
|
3720
|
+
const scoped = await this.engine.findOne("sys_metadata", {
|
|
3721
|
+
where: { ...base, package_id: request.packageId }
|
|
3722
|
+
});
|
|
3723
|
+
if (scoped) return scoped;
|
|
3724
|
+
return await this.engine.findOne("sys_metadata", {
|
|
3725
|
+
where: { ...base, package_id: null }
|
|
3726
|
+
});
|
|
3727
|
+
}
|
|
3728
|
+
return await this.engine.findOne("sys_metadata", { where: base });
|
|
3674
3729
|
};
|
|
3675
|
-
let rec = await
|
|
3730
|
+
let rec = await lookup(request.type);
|
|
3676
3731
|
if (!rec) {
|
|
3677
3732
|
const alt = import_shared4.PLURAL_TO_SINGULAR[request.type] ?? import_shared4.SINGULAR_TO_PLURAL[request.type];
|
|
3678
|
-
if (alt)
|
|
3679
|
-
rec = await this.engine.findOne("sys_metadata", {
|
|
3680
|
-
where: { ...where, type: alt }
|
|
3681
|
-
});
|
|
3682
|
-
}
|
|
3733
|
+
if (alt) rec = await lookup(alt);
|
|
3683
3734
|
}
|
|
3684
3735
|
return rec;
|
|
3685
3736
|
};
|
|
@@ -4711,15 +4762,15 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
4711
4762
|
* type and its singular/plural twin. Returns `undefined` when the
|
|
4712
4763
|
* registry is unavailable or the item is not artifact-backed.
|
|
4713
4764
|
*/
|
|
4714
|
-
lookupArtifactItem(type, name) {
|
|
4765
|
+
lookupArtifactItem(type, name, currentPackageId) {
|
|
4715
4766
|
const registry = this.engine?.registry;
|
|
4716
4767
|
if (!registry) return void 0;
|
|
4717
4768
|
const singular = import_shared4.PLURAL_TO_SINGULAR[type] ?? type;
|
|
4718
4769
|
if (typeof registry.getArtifactItem === "function") {
|
|
4719
|
-
return registry.getArtifactItem(singular, name) ?? registry.getArtifactItem(type, name);
|
|
4770
|
+
return registry.getArtifactItem(singular, name, currentPackageId) ?? registry.getArtifactItem(type, name, currentPackageId);
|
|
4720
4771
|
}
|
|
4721
4772
|
if (typeof registry.getItem !== "function") return void 0;
|
|
4722
|
-
const item = registry.getItem(singular, name) ?? registry.getItem(type, name);
|
|
4773
|
+
const item = registry.getItem(singular, name, currentPackageId) ?? registry.getItem(type, name, currentPackageId);
|
|
4723
4774
|
if (!item || !item._packageId || item._packageId === "sys_metadata") {
|
|
4724
4775
|
return void 0;
|
|
4725
4776
|
}
|
|
@@ -5085,7 +5136,10 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
5085
5136
|
if (request.parentVersion !== void 0) {
|
|
5086
5137
|
parentVersion = request.parentVersion;
|
|
5087
5138
|
} else {
|
|
5088
|
-
const current = await repo.get(ref, {
|
|
5139
|
+
const current = await repo.get(ref, {
|
|
5140
|
+
state: mode === "draft" ? "draft" : "active",
|
|
5141
|
+
packageId: request.packageId ?? null
|
|
5142
|
+
});
|
|
5089
5143
|
parentVersion = current?.hash ?? null;
|
|
5090
5144
|
}
|
|
5091
5145
|
try {
|
|
@@ -9507,10 +9561,16 @@ var MetadataFacade = class {
|
|
|
9507
9561
|
}
|
|
9508
9562
|
}
|
|
9509
9563
|
/**
|
|
9510
|
-
* Get a metadata item by type and name
|
|
9511
|
-
|
|
9512
|
-
|
|
9513
|
-
|
|
9564
|
+
* Get a metadata item by type and name.
|
|
9565
|
+
*
|
|
9566
|
+
* `currentPackageId` (ADR-0048) opts into package-scoped resolution: when two
|
|
9567
|
+
* installed packages ship an item of the same `type`/`name`, the registry
|
|
9568
|
+
* prefers the one owned by `currentPackageId` (composite key
|
|
9569
|
+
* `${packageId}:${name}`) before falling back to first-match. Omit it for the
|
|
9570
|
+
* legacy context-free lookup.
|
|
9571
|
+
*/
|
|
9572
|
+
async get(type, name, currentPackageId) {
|
|
9573
|
+
const item = this.registry.getItem(type, name, currentPackageId);
|
|
9514
9574
|
return item?.content ?? item;
|
|
9515
9575
|
}
|
|
9516
9576
|
/**
|
|
@@ -9584,6 +9644,7 @@ var ObjectQLPlugin = class {
|
|
|
9584
9644
|
*/
|
|
9585
9645
|
this.startupTimeout = 12e4;
|
|
9586
9646
|
this.skipSchemaSync = false;
|
|
9647
|
+
this.hydrateMetadataFromDb = false;
|
|
9587
9648
|
/** Unsubscribe handles for metadata-event subscriptions (ADR-0008 PR-7). */
|
|
9588
9649
|
this.metadataUnsubscribes = [];
|
|
9589
9650
|
this.init = async (ctx) => {
|
|
@@ -9708,7 +9769,7 @@ var ObjectQLPlugin = class {
|
|
|
9708
9769
|
} else {
|
|
9709
9770
|
await this.syncRegisteredSchemas(ctx);
|
|
9710
9771
|
}
|
|
9711
|
-
if (this.environmentId === void 0) {
|
|
9772
|
+
if (this.environmentId === void 0 || this.hydrateMetadataFromDb) {
|
|
9712
9773
|
await this.restoreMetadataFromDb(ctx);
|
|
9713
9774
|
} else {
|
|
9714
9775
|
ctx.logger.info("Project kernel \u2014 skipping sys_metadata hydration (metadata sourced from artifact)");
|
|
@@ -9750,6 +9811,7 @@ var ObjectQLPlugin = class {
|
|
|
9750
9811
|
this.startupTimeout = opts.startupTimeout;
|
|
9751
9812
|
}
|
|
9752
9813
|
this.skipSchemaSync = typeof opts.skipSchemaSync === "boolean" ? opts.skipSchemaSync : process.env.OS_SKIP_SCHEMA_SYNC === "1";
|
|
9814
|
+
this.hydrateMetadataFromDb = opts.hydrateMetadataFromDb === true;
|
|
9753
9815
|
}
|
|
9754
9816
|
/**
|
|
9755
9817
|
* Subscribe to `object` metadata events from the metadata service and
|