@objectstack/objectql 7.1.0 → 7.2.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 +104 -1
- package/dist/index.d.ts +104 -1
- package/dist/index.js +326 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +329 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -504,7 +504,9 @@ var SchemaRegistry = class {
|
|
|
504
504
|
const direct = collection.get(name);
|
|
505
505
|
if (direct) return direct;
|
|
506
506
|
for (const [key, item] of collection) {
|
|
507
|
-
if (key.endsWith(`:${name}`))
|
|
507
|
+
if (key.endsWith(`:${name}`)) {
|
|
508
|
+
return item;
|
|
509
|
+
}
|
|
508
510
|
}
|
|
509
511
|
return void 0;
|
|
510
512
|
}
|
|
@@ -1356,6 +1358,7 @@ var import_data2 = require("@objectstack/spec/data");
|
|
|
1356
1358
|
var import_shared3 = require("@objectstack/spec/shared");
|
|
1357
1359
|
var import_system = require("@objectstack/spec/system");
|
|
1358
1360
|
var import_kernel4 = require("@objectstack/spec/kernel");
|
|
1361
|
+
var import_kernel5 = require("@objectstack/spec/kernel");
|
|
1359
1362
|
var import_zod = require("zod");
|
|
1360
1363
|
|
|
1361
1364
|
// src/metadata-diagnostics.ts
|
|
@@ -1603,6 +1606,19 @@ function resolveOverlaySchema(type, _item) {
|
|
|
1603
1606
|
const singular = import_shared3.PLURAL_TO_SINGULAR[type] ?? type;
|
|
1604
1607
|
return (0, import_kernel4.getMetadataTypeSchema)(singular) ?? null;
|
|
1605
1608
|
}
|
|
1609
|
+
function mergeArtifactProtection(item, artifactItem) {
|
|
1610
|
+
if (item === void 0 || item === null) return item;
|
|
1611
|
+
if (artifactItem === void 0 || artifactItem === null) return item;
|
|
1612
|
+
const a = artifactItem;
|
|
1613
|
+
if (typeof a !== "object") return item;
|
|
1614
|
+
const out = { ...item };
|
|
1615
|
+
if (a._lock !== void 0) out._lock = a._lock;
|
|
1616
|
+
if (a._lockReason !== void 0) out._lockReason = a._lockReason;
|
|
1617
|
+
if (a._packageId !== void 0) out._packageId = a._packageId;
|
|
1618
|
+
if (a._packageVersion !== void 0) out._packageVersion = a._packageVersion;
|
|
1619
|
+
if (a._provenance !== void 0) out._provenance = a._provenance;
|
|
1620
|
+
return out;
|
|
1621
|
+
}
|
|
1606
1622
|
function simpleHash(str) {
|
|
1607
1623
|
let hash = 0;
|
|
1608
1624
|
for (let i = 0; i < str.length; i++) {
|
|
@@ -2094,6 +2110,7 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
2094
2110
|
const includeWarnings = request.severity === "warning";
|
|
2095
2111
|
const targetTypes = request.type ? [request.type] : import_kernel4.DEFAULT_METADATA_TYPE_REGISTRY.filter((e) => (0, import_kernel4.getMetadataTypeSchema)(e.type)).map((e) => e.type);
|
|
2096
2112
|
const entries = [];
|
|
2113
|
+
const stats = {};
|
|
2097
2114
|
let scannedItems = 0;
|
|
2098
2115
|
for (const t of targetTypes) {
|
|
2099
2116
|
let listed;
|
|
@@ -2107,8 +2124,11 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
2107
2124
|
continue;
|
|
2108
2125
|
}
|
|
2109
2126
|
const items = Array.isArray(listed?.items) ? listed.items : Array.isArray(listed) ? listed : [];
|
|
2127
|
+
const pkgSet = /* @__PURE__ */ new Set();
|
|
2110
2128
|
for (const item of items) {
|
|
2111
2129
|
scannedItems += 1;
|
|
2130
|
+
const pkg = item?._packageId ?? null;
|
|
2131
|
+
if (pkg) pkgSet.add(pkg);
|
|
2112
2132
|
const diag = item?._diagnostics ?? computeMetadataDiagnostics(t, item);
|
|
2113
2133
|
if (!diag) continue;
|
|
2114
2134
|
if (diag.valid && !includeWarnings) continue;
|
|
@@ -2119,12 +2139,14 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
2119
2139
|
diagnostics: diag
|
|
2120
2140
|
});
|
|
2121
2141
|
}
|
|
2142
|
+
stats[t] = { count: items.length, packages: [...pkgSet].sort() };
|
|
2122
2143
|
}
|
|
2123
2144
|
return {
|
|
2124
2145
|
entries,
|
|
2125
2146
|
total: entries.length,
|
|
2126
2147
|
scannedTypes: targetTypes.length,
|
|
2127
|
-
scannedItems
|
|
2148
|
+
scannedItems,
|
|
2149
|
+
stats
|
|
2128
2150
|
};
|
|
2129
2151
|
}
|
|
2130
2152
|
async getMetaItems(request) {
|
|
@@ -2221,7 +2243,16 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
2221
2243
|
}
|
|
2222
2244
|
return {
|
|
2223
2245
|
type: request.type,
|
|
2224
|
-
items: decorateMetadataItems(
|
|
2246
|
+
items: decorateMetadataItems(
|
|
2247
|
+
request.type,
|
|
2248
|
+
items.map((it) => {
|
|
2249
|
+
const a = this.lookupArtifactItem(
|
|
2250
|
+
request.type,
|
|
2251
|
+
it?.name
|
|
2252
|
+
);
|
|
2253
|
+
return mergeArtifactProtection(it, a);
|
|
2254
|
+
})
|
|
2255
|
+
)
|
|
2225
2256
|
};
|
|
2226
2257
|
}
|
|
2227
2258
|
async getMetaItem(request) {
|
|
@@ -2295,10 +2326,26 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
2295
2326
|
if (alt) item = this.engine.registry.getItem(alt, request.name);
|
|
2296
2327
|
}
|
|
2297
2328
|
}
|
|
2329
|
+
const artifactItem = this.lookupArtifactItem(request.type, request.name);
|
|
2330
|
+
const decorated = decorateMetadataItem(
|
|
2331
|
+
request.type,
|
|
2332
|
+
mergeArtifactProtection(item, artifactItem)
|
|
2333
|
+
);
|
|
2334
|
+
const artifactBacked = this.isArtifactBacked(request.type, request.name);
|
|
2335
|
+
const lockState = (0, import_kernel5.resolveLockState)(decorated, artifactBacked);
|
|
2298
2336
|
return {
|
|
2299
2337
|
type: request.type,
|
|
2300
2338
|
name: request.name,
|
|
2301
|
-
item:
|
|
2339
|
+
item: decorated,
|
|
2340
|
+
lock: lockState.lock,
|
|
2341
|
+
...lockState.lockReason !== void 0 ? { lockReason: lockState.lockReason } : {},
|
|
2342
|
+
...lockState.lockSource !== void 0 ? { lockSource: lockState.lockSource } : {},
|
|
2343
|
+
...lockState.provenance !== void 0 ? { provenance: lockState.provenance } : {},
|
|
2344
|
+
...lockState.packageId !== void 0 ? { packageId: lockState.packageId } : {},
|
|
2345
|
+
...lockState.packageVersion !== void 0 ? { packageVersion: lockState.packageVersion } : {},
|
|
2346
|
+
editable: lockState.editable,
|
|
2347
|
+
deletable: lockState.deletable,
|
|
2348
|
+
resettable: lockState.resettable
|
|
2302
2349
|
};
|
|
2303
2350
|
}
|
|
2304
2351
|
/**
|
|
@@ -2378,6 +2425,9 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
2378
2425
|
}
|
|
2379
2426
|
const effective = overlay ?? code;
|
|
2380
2427
|
const _diagnostics = effective !== null && effective !== void 0 ? computeMetadataDiagnostics(request.type, effective) : void 0;
|
|
2428
|
+
const artifactBacked = this.isArtifactBacked(request.type, request.name);
|
|
2429
|
+
const lockSource = code ?? overlay ?? {};
|
|
2430
|
+
const lockState = (0, import_kernel5.resolveLockState)(lockSource, artifactBacked);
|
|
2381
2431
|
return {
|
|
2382
2432
|
type: request.type,
|
|
2383
2433
|
name: request.name,
|
|
@@ -2385,9 +2435,69 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
2385
2435
|
overlay,
|
|
2386
2436
|
overlayScope,
|
|
2387
2437
|
effective,
|
|
2388
|
-
..._diagnostics ? { _diagnostics } : {}
|
|
2438
|
+
..._diagnostics ? { _diagnostics } : {},
|
|
2439
|
+
lock: lockState.lock,
|
|
2440
|
+
...lockState.lockReason !== void 0 ? { lockReason: lockState.lockReason } : {},
|
|
2441
|
+
...lockState.lockSource !== void 0 ? { lockSource: lockState.lockSource } : {},
|
|
2442
|
+
...lockState.provenance !== void 0 ? { provenance: lockState.provenance } : {},
|
|
2443
|
+
...lockState.packageId !== void 0 ? { packageId: lockState.packageId } : {},
|
|
2444
|
+
...lockState.packageVersion !== void 0 ? { packageVersion: lockState.packageVersion } : {},
|
|
2445
|
+
editable: lockState.editable,
|
|
2446
|
+
deletable: lockState.deletable,
|
|
2447
|
+
resettable: lockState.resettable
|
|
2389
2448
|
};
|
|
2390
2449
|
}
|
|
2450
|
+
/**
|
|
2451
|
+
* ADR-0010 §3.6 / Phase 4.1 — read the metadata-protection audit log
|
|
2452
|
+
* for a single item. Returns the most-recent rows of
|
|
2453
|
+
* `sys_metadata_audit` for this (type, name) tuple, sorted newest
|
|
2454
|
+
* first. Refused (`denied`) and forced (`forced`) writes both appear
|
|
2455
|
+
* here — they never reach the `history` endpoint, which only tracks
|
|
2456
|
+
* successful body snapshots.
|
|
2457
|
+
*
|
|
2458
|
+
* The table is provisioned by `platform-objects` and is the
|
|
2459
|
+
* compliance surface for the lock-enforcement story. When the
|
|
2460
|
+
* environment has not yet provisioned the table (legacy install
|
|
2461
|
+
* prior to ADR-0010) the call returns `{ events: [] }` instead of
|
|
2462
|
+
* raising, keeping the Studio tab harmless.
|
|
2463
|
+
*/
|
|
2464
|
+
async auditMetaItem(request) {
|
|
2465
|
+
const singular = import_shared3.PLURAL_TO_SINGULAR[request.type] ?? request.type;
|
|
2466
|
+
const limit = Math.min(
|
|
2467
|
+
Math.max(1, request.limit ?? 100),
|
|
2468
|
+
500
|
|
2469
|
+
);
|
|
2470
|
+
try {
|
|
2471
|
+
const where = {
|
|
2472
|
+
type: singular,
|
|
2473
|
+
name: request.name
|
|
2474
|
+
};
|
|
2475
|
+
const rows = await this.engine.find("sys_metadata_audit", {
|
|
2476
|
+
where,
|
|
2477
|
+
orderBy: [{ field: "occurred_at", direction: "desc" }],
|
|
2478
|
+
limit
|
|
2479
|
+
});
|
|
2480
|
+
const events = (Array.isArray(rows) ? rows : []).map((r) => ({
|
|
2481
|
+
id: r.id,
|
|
2482
|
+
occurredAt: typeof r.occurred_at === "string" ? r.occurred_at : r.occurred_at instanceof Date ? r.occurred_at.toISOString() : String(r.occurred_at ?? ""),
|
|
2483
|
+
actor: String(r.actor ?? "system"),
|
|
2484
|
+
source: r.source ?? null,
|
|
2485
|
+
operation: r.operation,
|
|
2486
|
+
outcome: r.outcome,
|
|
2487
|
+
code: String(r.code ?? ""),
|
|
2488
|
+
lockState: r.lock_state ?? null,
|
|
2489
|
+
lockOverridden: Boolean(r.lock_overridden),
|
|
2490
|
+
requestId: r.request_id ?? null,
|
|
2491
|
+
note: r.note ?? null
|
|
2492
|
+
}));
|
|
2493
|
+
return { events };
|
|
2494
|
+
} catch (err) {
|
|
2495
|
+
console.warn(
|
|
2496
|
+
`[Protocol] auditMetaItem read failed for ${request.type}/${request.name}: ${err?.message ?? err}`
|
|
2497
|
+
);
|
|
2498
|
+
return { events: [] };
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2391
2501
|
async getUiView(request) {
|
|
2392
2502
|
const schema = this.engine.registry.getObject(request.object);
|
|
2393
2503
|
if (!schema) throw new Error(`Object ${request.object} not found`);
|
|
@@ -3323,6 +3433,158 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3323
3433
|
if (!item || !item._packageId) return false;
|
|
3324
3434
|
return item._packageId !== "sys_metadata";
|
|
3325
3435
|
}
|
|
3436
|
+
// ───────────────────────────────────────────────────────────────────
|
|
3437
|
+
// ADR-0010 — metadata protection (Phase 1: L3 item-level lock)
|
|
3438
|
+
// ───────────────────────────────────────────────────────────────────
|
|
3439
|
+
/**
|
|
3440
|
+
* Look up an item from the artifact registry across both the requested
|
|
3441
|
+
* type and its singular/plural twin. Returns `undefined` when the
|
|
3442
|
+
* registry is unavailable or the item is not artifact-backed.
|
|
3443
|
+
*/
|
|
3444
|
+
lookupArtifactItem(type, name) {
|
|
3445
|
+
const registry = this.engine?.registry;
|
|
3446
|
+
if (!registry || typeof registry.getItem !== "function") return void 0;
|
|
3447
|
+
const singular = import_shared3.PLURAL_TO_SINGULAR[type] ?? type;
|
|
3448
|
+
return registry.getItem(singular, name) ?? registry.getItem(type, name);
|
|
3449
|
+
}
|
|
3450
|
+
/**
|
|
3451
|
+
* Resolve the effective `_lock` for an item by consulting the
|
|
3452
|
+
* artifact registry first, then the persisted overlay row. Artifact
|
|
3453
|
+
* always wins — by design, an overlay cannot loosen a packaged
|
|
3454
|
+
* lock (ADR-0010 §3.3).
|
|
3455
|
+
*
|
|
3456
|
+
* Returns `'none'` when nothing is locked, which is the common
|
|
3457
|
+
* case. Safe to call when `environmentId` is undefined (control-
|
|
3458
|
+
* plane bootstrap) — the lock check is only meaningful in tenant
|
|
3459
|
+
* scope and the caller is expected to also gate on `environmentId`.
|
|
3460
|
+
*/
|
|
3461
|
+
async getEffectiveLock(type, name, organizationId) {
|
|
3462
|
+
const registry = this.engine?.registry;
|
|
3463
|
+
const singular = import_shared3.PLURAL_TO_SINGULAR[type] ?? type;
|
|
3464
|
+
let artifactItem;
|
|
3465
|
+
if (registry && typeof registry.getItem === "function") {
|
|
3466
|
+
artifactItem = registry.getItem(singular, name) ?? registry.getItem(type, name);
|
|
3467
|
+
}
|
|
3468
|
+
if (artifactItem && artifactItem._packageId && artifactItem._packageId !== "sys_metadata") {
|
|
3469
|
+
const p = (0, import_kernel5.extractProtection)(artifactItem);
|
|
3470
|
+
if (p.lock !== "none") {
|
|
3471
|
+
return { lock: p.lock, lockReason: p.lockReason, lockSource: "artifact" };
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
try {
|
|
3475
|
+
const where = {
|
|
3476
|
+
type,
|
|
3477
|
+
name,
|
|
3478
|
+
state: "active",
|
|
3479
|
+
organization_id: organizationId ?? null
|
|
3480
|
+
};
|
|
3481
|
+
const row = await this.engine.findOne("sys_metadata", { where });
|
|
3482
|
+
if (row) {
|
|
3483
|
+
const body = typeof row.metadata === "string" ? JSON.parse(row.metadata) : row.metadata;
|
|
3484
|
+
const p = (0, import_kernel5.extractProtection)(body);
|
|
3485
|
+
if (p.lock !== "none") {
|
|
3486
|
+
return { lock: p.lock, lockReason: p.lockReason, lockSource: "overlay" };
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3489
|
+
} catch {
|
|
3490
|
+
}
|
|
3491
|
+
return { lock: "none", lockReason: void 0, lockSource: void 0 };
|
|
3492
|
+
}
|
|
3493
|
+
/**
|
|
3494
|
+
* Best-effort audit-row writer (ADR-0010 §3.6). Failures here are
|
|
3495
|
+
* logged but never block the underlying decision: an environment
|
|
3496
|
+
* without the audit table provisioned (legacy installs before this
|
|
3497
|
+
* ADR landed) still answers normal API calls, just without the
|
|
3498
|
+
* compliance trail. Phase 2 will make the audit table a hard
|
|
3499
|
+
* dependency.
|
|
3500
|
+
*/
|
|
3501
|
+
async recordMetadataAudit(entry) {
|
|
3502
|
+
try {
|
|
3503
|
+
await this.engine.insert("sys_metadata_audit", {
|
|
3504
|
+
occurred_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3505
|
+
actor: entry.actor ?? "system",
|
|
3506
|
+
source: entry.source ?? "protocol",
|
|
3507
|
+
type: import_shared3.PLURAL_TO_SINGULAR[entry.type] ?? entry.type,
|
|
3508
|
+
name: entry.name,
|
|
3509
|
+
organization_id: entry.organizationId ?? null,
|
|
3510
|
+
operation: entry.operation,
|
|
3511
|
+
outcome: entry.outcome,
|
|
3512
|
+
code: entry.code,
|
|
3513
|
+
lock_state: entry.lockState ?? "none",
|
|
3514
|
+
lock_overridden: entry.lockOverridden ?? false,
|
|
3515
|
+
request_id: entry.requestId ?? null,
|
|
3516
|
+
note: entry.note ?? null
|
|
3517
|
+
});
|
|
3518
|
+
} catch (err) {
|
|
3519
|
+
console.warn(
|
|
3520
|
+
`[Protocol] sys_metadata_audit write failed for ${entry.type}/${entry.name}: ${err?.message ?? err}`
|
|
3521
|
+
);
|
|
3522
|
+
}
|
|
3523
|
+
}
|
|
3524
|
+
/**
|
|
3525
|
+
* Phase 1 L3 enforcement for write operations (save / publish /
|
|
3526
|
+
* rollback). Returns null on allow. Returns the structured `Error`
|
|
3527
|
+
* the caller should `throw` on deny — also records the denial in
|
|
3528
|
+
* the audit log so refused attempts are visible in compliance
|
|
3529
|
+
* reports (refused writes never reach sys_metadata_history).
|
|
3530
|
+
*/
|
|
3531
|
+
async assertLockAllowsWrite(args) {
|
|
3532
|
+
if (this.environmentId === void 0) return null;
|
|
3533
|
+
const state = await this.getEffectiveLock(args.type, args.name, args.organizationId ?? null);
|
|
3534
|
+
const refusal = (0, import_kernel5.evaluateLockForWrite)(state.lock);
|
|
3535
|
+
if (!refusal) return null;
|
|
3536
|
+
const reason = state.lockReason ?? refusal.reason;
|
|
3537
|
+
const err = new Error(
|
|
3538
|
+
`[item_locked] ${args.type}/${args.name} is locked (_lock=${state.lock}${state.lockSource ? `, source=${state.lockSource}` : ""}). ${reason} \u2014 See ADR-0010 \xA73.3.`
|
|
3539
|
+
);
|
|
3540
|
+
err.code = "item_locked";
|
|
3541
|
+
err.status = 403;
|
|
3542
|
+
err.lock = state.lock;
|
|
3543
|
+
err.lockReason = reason;
|
|
3544
|
+
await this.recordMetadataAudit({
|
|
3545
|
+
type: args.type,
|
|
3546
|
+
name: args.name,
|
|
3547
|
+
organizationId: args.organizationId ?? null,
|
|
3548
|
+
operation: args.operation,
|
|
3549
|
+
outcome: "denied",
|
|
3550
|
+
code: "item_locked",
|
|
3551
|
+
lockState: state.lock,
|
|
3552
|
+
actor: args.actor,
|
|
3553
|
+
source: args.source ?? `protocol.${args.operation}MetaItem`,
|
|
3554
|
+
requestId: args.requestId,
|
|
3555
|
+
note: reason
|
|
3556
|
+
});
|
|
3557
|
+
return err;
|
|
3558
|
+
}
|
|
3559
|
+
/** Counterpart of {@link assertLockAllowsWrite} for delete. */
|
|
3560
|
+
async assertLockAllowsDelete(args) {
|
|
3561
|
+
if (this.environmentId === void 0) return null;
|
|
3562
|
+
const state = await this.getEffectiveLock(args.type, args.name, args.organizationId ?? null);
|
|
3563
|
+
const refusal = (0, import_kernel5.evaluateLockForDelete)(state.lock);
|
|
3564
|
+
if (!refusal) return null;
|
|
3565
|
+
const reason = state.lockReason ?? refusal.reason;
|
|
3566
|
+
const err = new Error(
|
|
3567
|
+
`[item_locked] ${args.type}/${args.name} is locked (_lock=${state.lock}${state.lockSource ? `, source=${state.lockSource}` : ""}). ${reason} \u2014 See ADR-0010 \xA73.3.`
|
|
3568
|
+
);
|
|
3569
|
+
err.code = "item_locked";
|
|
3570
|
+
err.status = 403;
|
|
3571
|
+
err.lock = state.lock;
|
|
3572
|
+
err.lockReason = reason;
|
|
3573
|
+
await this.recordMetadataAudit({
|
|
3574
|
+
type: args.type,
|
|
3575
|
+
name: args.name,
|
|
3576
|
+
organizationId: args.organizationId ?? null,
|
|
3577
|
+
operation: "delete",
|
|
3578
|
+
outcome: "denied",
|
|
3579
|
+
code: "item_locked",
|
|
3580
|
+
lockState: state.lock,
|
|
3581
|
+
actor: args.actor,
|
|
3582
|
+
source: args.source ?? "protocol.deleteMetaItem",
|
|
3583
|
+
requestId: args.requestId,
|
|
3584
|
+
note: reason
|
|
3585
|
+
});
|
|
3586
|
+
return err;
|
|
3587
|
+
}
|
|
3326
3588
|
/**
|
|
3327
3589
|
* Mirror an object-type overlay write into the in-memory engine
|
|
3328
3590
|
* registry so subsequent CRUD finds the new schema. Idempotent and
|
|
@@ -3369,6 +3631,15 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3369
3631
|
err.status = 403;
|
|
3370
3632
|
throw err;
|
|
3371
3633
|
}
|
|
3634
|
+
const lockErr = await this.assertLockAllowsWrite({
|
|
3635
|
+
type: request.type,
|
|
3636
|
+
name: request.name,
|
|
3637
|
+
...request.organizationId ? { organizationId: request.organizationId } : {},
|
|
3638
|
+
operation: "save",
|
|
3639
|
+
...request.actor ? { actor: request.actor } : {},
|
|
3640
|
+
source: "protocol.saveMetaItem"
|
|
3641
|
+
});
|
|
3642
|
+
if (lockErr) throw lockErr;
|
|
3372
3643
|
}
|
|
3373
3644
|
const singularType = import_shared3.PLURAL_TO_SINGULAR[request.type] ?? request.type;
|
|
3374
3645
|
if (!request.force && (singularType === "object" || singularType === "field")) {
|
|
@@ -3450,6 +3721,17 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3450
3721
|
if (mode === "publish") {
|
|
3451
3722
|
this.applyObjectRegistryMutation(request);
|
|
3452
3723
|
}
|
|
3724
|
+
await this.recordMetadataAudit({
|
|
3725
|
+
type: request.type,
|
|
3726
|
+
name: request.name,
|
|
3727
|
+
organizationId: orgId,
|
|
3728
|
+
operation: "save",
|
|
3729
|
+
outcome: "allowed",
|
|
3730
|
+
code: "ok",
|
|
3731
|
+
...request.actor ? { actor: request.actor } : {},
|
|
3732
|
+
source: "protocol.saveMetaItem",
|
|
3733
|
+
note: mode === "draft" ? "draft" : "active"
|
|
3734
|
+
});
|
|
3453
3735
|
return {
|
|
3454
3736
|
success: true,
|
|
3455
3737
|
version: result.version,
|
|
@@ -3572,6 +3854,15 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3572
3854
|
err.status = 403;
|
|
3573
3855
|
throw err;
|
|
3574
3856
|
}
|
|
3857
|
+
const _publishLockErr = await this.assertLockAllowsWrite({
|
|
3858
|
+
type: request.type,
|
|
3859
|
+
name: request.name,
|
|
3860
|
+
...request.organizationId ? { organizationId: request.organizationId } : {},
|
|
3861
|
+
operation: "publish",
|
|
3862
|
+
...request.actor ? { actor: request.actor } : {},
|
|
3863
|
+
source: "protocol.publishMetaItem"
|
|
3864
|
+
});
|
|
3865
|
+
if (_publishLockErr) throw _publishLockErr;
|
|
3575
3866
|
await this.ensureOverlayIndex();
|
|
3576
3867
|
const orgId = request.organizationId ?? null;
|
|
3577
3868
|
const repo = this.getOverlayRepo(orgId);
|
|
@@ -3639,6 +3930,15 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3639
3930
|
err.status = 403;
|
|
3640
3931
|
throw err;
|
|
3641
3932
|
}
|
|
3933
|
+
const _rollbackLockErr = await this.assertLockAllowsWrite({
|
|
3934
|
+
type: request.type,
|
|
3935
|
+
name: request.name,
|
|
3936
|
+
...request.organizationId ? { organizationId: request.organizationId } : {},
|
|
3937
|
+
operation: "rollback",
|
|
3938
|
+
...request.actor ? { actor: request.actor } : {},
|
|
3939
|
+
source: "protocol.rollbackMetaItem"
|
|
3940
|
+
});
|
|
3941
|
+
if (_rollbackLockErr) throw _rollbackLockErr;
|
|
3642
3942
|
await this.ensureOverlayIndex();
|
|
3643
3943
|
const orgId = request.organizationId ?? null;
|
|
3644
3944
|
const repo = this.getOverlayRepo(orgId);
|
|
@@ -3785,6 +4085,14 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3785
4085
|
err.status = 403;
|
|
3786
4086
|
throw err;
|
|
3787
4087
|
}
|
|
4088
|
+
const lockErr = await this.assertLockAllowsDelete({
|
|
4089
|
+
type: request.type,
|
|
4090
|
+
name: request.name,
|
|
4091
|
+
...request.organizationId ? { organizationId: request.organizationId } : {},
|
|
4092
|
+
...request.actor ? { actor: request.actor } : {},
|
|
4093
|
+
source: "protocol.deleteMetaItem"
|
|
4094
|
+
});
|
|
4095
|
+
if (lockErr) throw lockErr;
|
|
3788
4096
|
}
|
|
3789
4097
|
const singularTypeForRepo = import_shared3.PLURAL_TO_SINGULAR[request.type] ?? request.type;
|
|
3790
4098
|
const overlayAllowedForRepoDel = _ObjectStackProtocolImplementation.isOverlayAllowed(singularTypeForRepo);
|
|
@@ -3829,6 +4137,17 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3829
4137
|
} catch {
|
|
3830
4138
|
}
|
|
3831
4139
|
}
|
|
4140
|
+
await this.recordMetadataAudit({
|
|
4141
|
+
type: request.type,
|
|
4142
|
+
name: request.name,
|
|
4143
|
+
organizationId: orgId,
|
|
4144
|
+
operation: "delete",
|
|
4145
|
+
outcome: "allowed",
|
|
4146
|
+
code: "ok",
|
|
4147
|
+
...request.actor ? { actor: request.actor } : {},
|
|
4148
|
+
source: "protocol.deleteMetaItem",
|
|
4149
|
+
note: targetState
|
|
4150
|
+
});
|
|
3832
4151
|
return {
|
|
3833
4152
|
success: true,
|
|
3834
4153
|
reset: true,
|
|
@@ -4194,7 +4513,7 @@ _ObjectStackProtocolImplementation.RUNTIME_CREATE_ALLOWED_TYPES = (() => {
|
|
|
4194
4513
|
var ObjectStackProtocolImplementation = _ObjectStackProtocolImplementation;
|
|
4195
4514
|
|
|
4196
4515
|
// src/engine.ts
|
|
4197
|
-
var
|
|
4516
|
+
var import_kernel6 = require("@objectstack/spec/kernel");
|
|
4198
4517
|
var import_core = require("@objectstack/core");
|
|
4199
4518
|
var import_system2 = require("@objectstack/spec/system");
|
|
4200
4519
|
var import_shared4 = require("@objectstack/spec/shared");
|
|
@@ -6483,7 +6802,7 @@ var _ObjectQL = class _ObjectQL {
|
|
|
6483
6802
|
*/
|
|
6484
6803
|
createContext(ctx) {
|
|
6485
6804
|
return new ScopedContext(
|
|
6486
|
-
|
|
6805
|
+
import_kernel6.ExecutionContextSchema.parse(ctx),
|
|
6487
6806
|
this
|
|
6488
6807
|
);
|
|
6489
6808
|
}
|