@objectstack/objectql 7.8.0 → 7.9.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 +100 -1
- package/dist/index.d.ts +100 -1
- package/dist/index.js +216 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +216 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -719,6 +719,7 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
719
719
|
type: string;
|
|
720
720
|
packageId?: string;
|
|
721
721
|
organizationId?: string;
|
|
722
|
+
previewDrafts?: boolean;
|
|
722
723
|
}): Promise<{
|
|
723
724
|
type: string;
|
|
724
725
|
items: any[];
|
|
@@ -729,10 +730,11 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
729
730
|
packageId?: string;
|
|
730
731
|
organizationId?: string;
|
|
731
732
|
state?: 'active' | 'draft';
|
|
733
|
+
previewDrafts?: boolean;
|
|
732
734
|
}): Promise<{
|
|
733
735
|
type: string;
|
|
734
736
|
name: string;
|
|
735
|
-
item:
|
|
737
|
+
item: any;
|
|
736
738
|
} | {
|
|
737
739
|
editable: boolean;
|
|
738
740
|
deletable: boolean;
|
|
@@ -1155,6 +1157,23 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1155
1157
|
* simply no-op, and a sync failure must not abort the publish.
|
|
1156
1158
|
*/
|
|
1157
1159
|
private ensureObjectStorage;
|
|
1160
|
+
/**
|
|
1161
|
+
* Inverse of {@link ensureObjectStorage}: drop an object's physical table.
|
|
1162
|
+
* DESTRUCTIVE — deletes the table and all its rows. Only invoked when a
|
|
1163
|
+
* delete explicitly opts into storage teardown (see {@link deleteMetaItem}'s
|
|
1164
|
+
* `dropStorage`), so publishing an object solely to preview it can be undone
|
|
1165
|
+
* without leaving an orphan table. Best-effort: a failure is logged, not
|
|
1166
|
+
* thrown — the metadata delete already succeeded, and a stray table is
|
|
1167
|
+
* reclaimed by the next sync/drop rather than blocking the delete.
|
|
1168
|
+
*/
|
|
1169
|
+
private dropObjectStorage;
|
|
1170
|
+
/**
|
|
1171
|
+
* Guard for storage teardown on delete. Drops a physical table only when
|
|
1172
|
+
* the caller opted in AND it is safe: object types only (others have no
|
|
1173
|
+
* table), active state only (drafts were never materialised), and never a
|
|
1174
|
+
* `sys_`-prefixed platform table.
|
|
1175
|
+
*/
|
|
1176
|
+
private shouldDropStorage;
|
|
1158
1177
|
saveMetaItem(request: {
|
|
1159
1178
|
type: string;
|
|
1160
1179
|
name: string;
|
|
@@ -1263,6 +1282,69 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1263
1282
|
code?: string;
|
|
1264
1283
|
}>;
|
|
1265
1284
|
}>;
|
|
1285
|
+
/**
|
|
1286
|
+
* Discard every pending DRAFT bound to a package — the NON-destructive
|
|
1287
|
+
* inverse of {@link publishPackageDrafts}. Drops only `state='draft'` rows
|
|
1288
|
+
* (via the per-item delete primitive), reverting the package to its last
|
|
1289
|
+
* published baseline; active/published metadata and physical tables are
|
|
1290
|
+
* left untouched.
|
|
1291
|
+
*
|
|
1292
|
+
* Use case: "I edited this app for a while and it turned out worse than
|
|
1293
|
+
* before — abandon all my changes." Routes through the sys_metadata path
|
|
1294
|
+
* (no metadata-service dependency, unlike `POST /packages/:id/revert`).
|
|
1295
|
+
*/
|
|
1296
|
+
discardPackageDrafts(request: {
|
|
1297
|
+
packageId: string;
|
|
1298
|
+
organizationId?: string;
|
|
1299
|
+
actor?: string;
|
|
1300
|
+
}): Promise<{
|
|
1301
|
+
success: boolean;
|
|
1302
|
+
discardedCount: number;
|
|
1303
|
+
failedCount: number;
|
|
1304
|
+
discarded: Array<{
|
|
1305
|
+
type: string;
|
|
1306
|
+
name: string;
|
|
1307
|
+
}>;
|
|
1308
|
+
failed: Array<{
|
|
1309
|
+
type: string;
|
|
1310
|
+
name: string;
|
|
1311
|
+
error: string;
|
|
1312
|
+
code?: string;
|
|
1313
|
+
}>;
|
|
1314
|
+
}>;
|
|
1315
|
+
/**
|
|
1316
|
+
* Delete an ENTIRE package: every `sys_metadata` row bound to it (active
|
|
1317
|
+
* AND draft) and — by default — the physical table of each object it
|
|
1318
|
+
* defined. DESTRUCTIVE: removes the app and its data. Use case: "I don't
|
|
1319
|
+
* want this package anymore."
|
|
1320
|
+
*
|
|
1321
|
+
* Set `keepData: true` to remove the metadata but preserve object tables.
|
|
1322
|
+
* The `sys_`-table guard in {@link deleteMetaItem} still applies, so
|
|
1323
|
+
* platform storage is never dropped. Drafts are removed before active rows
|
|
1324
|
+
* so each object's table is torn down once. Per-item failures are collected
|
|
1325
|
+
* without aborting the rest.
|
|
1326
|
+
*/
|
|
1327
|
+
deletePackage(request: {
|
|
1328
|
+
packageId: string;
|
|
1329
|
+
organizationId?: string;
|
|
1330
|
+
actor?: string;
|
|
1331
|
+
keepData?: boolean;
|
|
1332
|
+
}): Promise<{
|
|
1333
|
+
success: boolean;
|
|
1334
|
+
deletedCount: number;
|
|
1335
|
+
failedCount: number;
|
|
1336
|
+
deleted: Array<{
|
|
1337
|
+
type: string;
|
|
1338
|
+
name: string;
|
|
1339
|
+
state: string;
|
|
1340
|
+
}>;
|
|
1341
|
+
failed: Array<{
|
|
1342
|
+
type: string;
|
|
1343
|
+
name: string;
|
|
1344
|
+
error: string;
|
|
1345
|
+
code?: string;
|
|
1346
|
+
}>;
|
|
1347
|
+
}>;
|
|
1266
1348
|
/**
|
|
1267
1349
|
* Restore the body recorded at history `toVersion` as the new
|
|
1268
1350
|
* live row. Writes a history event with `op='revert'`. 404
|
|
@@ -1331,6 +1413,13 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1331
1413
|
parentVersion?: string | null;
|
|
1332
1414
|
actor?: string;
|
|
1333
1415
|
state?: 'active' | 'draft';
|
|
1416
|
+
/**
|
|
1417
|
+
* When true, also drop the object's physical table after the metadata
|
|
1418
|
+
* is removed (object + active only; never `sys_`). Default false keeps
|
|
1419
|
+
* delete non-destructive to data. Used by the "discard a previewed
|
|
1420
|
+
* object" flow so a publish-to-preview leaves no orphan table.
|
|
1421
|
+
*/
|
|
1422
|
+
dropStorage?: boolean;
|
|
1334
1423
|
}): Promise<{
|
|
1335
1424
|
success: boolean;
|
|
1336
1425
|
message?: string;
|
|
@@ -2163,6 +2252,16 @@ declare class ObjectQL implements IDataEngine {
|
|
|
2163
2252
|
* table when absent (and alters to add new columns).
|
|
2164
2253
|
*/
|
|
2165
2254
|
syncObjectSchema(objectName: string): Promise<void>;
|
|
2255
|
+
/**
|
|
2256
|
+
* Drop the physical storage (table/collection) backing an object — the
|
|
2257
|
+
* inverse of {@link syncObjectSchema}. DESTRUCTIVE: deletes all rows in the
|
|
2258
|
+
* table. Used by the protocol delete path when the caller explicitly opts
|
|
2259
|
+
* into storage teardown (e.g. discarding an object that was published only
|
|
2260
|
+
* to preview it). No-op when the object's driver does not expose `dropTable`.
|
|
2261
|
+
* Resolves the physical table name from the registered definition, falling
|
|
2262
|
+
* back to the bare name if the def was already removed.
|
|
2263
|
+
*/
|
|
2264
|
+
dropObjectSchema(objectName: string): Promise<void>;
|
|
2166
2265
|
/**
|
|
2167
2266
|
* Get a registered driver by datasource name.
|
|
2168
2267
|
* Alias matching @objectql/core datasource() API.
|
package/dist/index.d.ts
CHANGED
|
@@ -719,6 +719,7 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
719
719
|
type: string;
|
|
720
720
|
packageId?: string;
|
|
721
721
|
organizationId?: string;
|
|
722
|
+
previewDrafts?: boolean;
|
|
722
723
|
}): Promise<{
|
|
723
724
|
type: string;
|
|
724
725
|
items: any[];
|
|
@@ -729,10 +730,11 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
729
730
|
packageId?: string;
|
|
730
731
|
organizationId?: string;
|
|
731
732
|
state?: 'active' | 'draft';
|
|
733
|
+
previewDrafts?: boolean;
|
|
732
734
|
}): Promise<{
|
|
733
735
|
type: string;
|
|
734
736
|
name: string;
|
|
735
|
-
item:
|
|
737
|
+
item: any;
|
|
736
738
|
} | {
|
|
737
739
|
editable: boolean;
|
|
738
740
|
deletable: boolean;
|
|
@@ -1155,6 +1157,23 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1155
1157
|
* simply no-op, and a sync failure must not abort the publish.
|
|
1156
1158
|
*/
|
|
1157
1159
|
private ensureObjectStorage;
|
|
1160
|
+
/**
|
|
1161
|
+
* Inverse of {@link ensureObjectStorage}: drop an object's physical table.
|
|
1162
|
+
* DESTRUCTIVE — deletes the table and all its rows. Only invoked when a
|
|
1163
|
+
* delete explicitly opts into storage teardown (see {@link deleteMetaItem}'s
|
|
1164
|
+
* `dropStorage`), so publishing an object solely to preview it can be undone
|
|
1165
|
+
* without leaving an orphan table. Best-effort: a failure is logged, not
|
|
1166
|
+
* thrown — the metadata delete already succeeded, and a stray table is
|
|
1167
|
+
* reclaimed by the next sync/drop rather than blocking the delete.
|
|
1168
|
+
*/
|
|
1169
|
+
private dropObjectStorage;
|
|
1170
|
+
/**
|
|
1171
|
+
* Guard for storage teardown on delete. Drops a physical table only when
|
|
1172
|
+
* the caller opted in AND it is safe: object types only (others have no
|
|
1173
|
+
* table), active state only (drafts were never materialised), and never a
|
|
1174
|
+
* `sys_`-prefixed platform table.
|
|
1175
|
+
*/
|
|
1176
|
+
private shouldDropStorage;
|
|
1158
1177
|
saveMetaItem(request: {
|
|
1159
1178
|
type: string;
|
|
1160
1179
|
name: string;
|
|
@@ -1263,6 +1282,69 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1263
1282
|
code?: string;
|
|
1264
1283
|
}>;
|
|
1265
1284
|
}>;
|
|
1285
|
+
/**
|
|
1286
|
+
* Discard every pending DRAFT bound to a package — the NON-destructive
|
|
1287
|
+
* inverse of {@link publishPackageDrafts}. Drops only `state='draft'` rows
|
|
1288
|
+
* (via the per-item delete primitive), reverting the package to its last
|
|
1289
|
+
* published baseline; active/published metadata and physical tables are
|
|
1290
|
+
* left untouched.
|
|
1291
|
+
*
|
|
1292
|
+
* Use case: "I edited this app for a while and it turned out worse than
|
|
1293
|
+
* before — abandon all my changes." Routes through the sys_metadata path
|
|
1294
|
+
* (no metadata-service dependency, unlike `POST /packages/:id/revert`).
|
|
1295
|
+
*/
|
|
1296
|
+
discardPackageDrafts(request: {
|
|
1297
|
+
packageId: string;
|
|
1298
|
+
organizationId?: string;
|
|
1299
|
+
actor?: string;
|
|
1300
|
+
}): Promise<{
|
|
1301
|
+
success: boolean;
|
|
1302
|
+
discardedCount: number;
|
|
1303
|
+
failedCount: number;
|
|
1304
|
+
discarded: Array<{
|
|
1305
|
+
type: string;
|
|
1306
|
+
name: string;
|
|
1307
|
+
}>;
|
|
1308
|
+
failed: Array<{
|
|
1309
|
+
type: string;
|
|
1310
|
+
name: string;
|
|
1311
|
+
error: string;
|
|
1312
|
+
code?: string;
|
|
1313
|
+
}>;
|
|
1314
|
+
}>;
|
|
1315
|
+
/**
|
|
1316
|
+
* Delete an ENTIRE package: every `sys_metadata` row bound to it (active
|
|
1317
|
+
* AND draft) and — by default — the physical table of each object it
|
|
1318
|
+
* defined. DESTRUCTIVE: removes the app and its data. Use case: "I don't
|
|
1319
|
+
* want this package anymore."
|
|
1320
|
+
*
|
|
1321
|
+
* Set `keepData: true` to remove the metadata but preserve object tables.
|
|
1322
|
+
* The `sys_`-table guard in {@link deleteMetaItem} still applies, so
|
|
1323
|
+
* platform storage is never dropped. Drafts are removed before active rows
|
|
1324
|
+
* so each object's table is torn down once. Per-item failures are collected
|
|
1325
|
+
* without aborting the rest.
|
|
1326
|
+
*/
|
|
1327
|
+
deletePackage(request: {
|
|
1328
|
+
packageId: string;
|
|
1329
|
+
organizationId?: string;
|
|
1330
|
+
actor?: string;
|
|
1331
|
+
keepData?: boolean;
|
|
1332
|
+
}): Promise<{
|
|
1333
|
+
success: boolean;
|
|
1334
|
+
deletedCount: number;
|
|
1335
|
+
failedCount: number;
|
|
1336
|
+
deleted: Array<{
|
|
1337
|
+
type: string;
|
|
1338
|
+
name: string;
|
|
1339
|
+
state: string;
|
|
1340
|
+
}>;
|
|
1341
|
+
failed: Array<{
|
|
1342
|
+
type: string;
|
|
1343
|
+
name: string;
|
|
1344
|
+
error: string;
|
|
1345
|
+
code?: string;
|
|
1346
|
+
}>;
|
|
1347
|
+
}>;
|
|
1266
1348
|
/**
|
|
1267
1349
|
* Restore the body recorded at history `toVersion` as the new
|
|
1268
1350
|
* live row. Writes a history event with `op='revert'`. 404
|
|
@@ -1331,6 +1413,13 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
|
|
|
1331
1413
|
parentVersion?: string | null;
|
|
1332
1414
|
actor?: string;
|
|
1333
1415
|
state?: 'active' | 'draft';
|
|
1416
|
+
/**
|
|
1417
|
+
* When true, also drop the object's physical table after the metadata
|
|
1418
|
+
* is removed (object + active only; never `sys_`). Default false keeps
|
|
1419
|
+
* delete non-destructive to data. Used by the "discard a previewed
|
|
1420
|
+
* object" flow so a publish-to-preview leaves no orphan table.
|
|
1421
|
+
*/
|
|
1422
|
+
dropStorage?: boolean;
|
|
1334
1423
|
}): Promise<{
|
|
1335
1424
|
success: boolean;
|
|
1336
1425
|
message?: string;
|
|
@@ -2163,6 +2252,16 @@ declare class ObjectQL implements IDataEngine {
|
|
|
2163
2252
|
* table when absent (and alters to add new columns).
|
|
2164
2253
|
*/
|
|
2165
2254
|
syncObjectSchema(objectName: string): Promise<void>;
|
|
2255
|
+
/**
|
|
2256
|
+
* Drop the physical storage (table/collection) backing an object — the
|
|
2257
|
+
* inverse of {@link syncObjectSchema}. DESTRUCTIVE: deletes all rows in the
|
|
2258
|
+
* table. Used by the protocol delete path when the caller explicitly opts
|
|
2259
|
+
* into storage teardown (e.g. discarding an object that was published only
|
|
2260
|
+
* to preview it). No-op when the object's driver does not expose `dropTable`.
|
|
2261
|
+
* Resolves the physical table name from the registered definition, falling
|
|
2262
|
+
* back to the bare name if the def was already removed.
|
|
2263
|
+
*/
|
|
2264
|
+
dropObjectSchema(objectName: string): Promise<void>;
|
|
2166
2265
|
/**
|
|
2167
2266
|
* Get a registered driver by datasource name.
|
|
2168
2267
|
* Alias matching @objectql/core datasource() API.
|
package/dist/index.js
CHANGED
|
@@ -2450,6 +2450,44 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
2450
2450
|
}
|
|
2451
2451
|
} catch {
|
|
2452
2452
|
}
|
|
2453
|
+
if (request.previewDrafts) {
|
|
2454
|
+
try {
|
|
2455
|
+
const orgId = request.organizationId;
|
|
2456
|
+
const queryDrafts = async (oid) => {
|
|
2457
|
+
const whereClause = { type: request.type, state: "draft", organization_id: oid };
|
|
2458
|
+
if (packageId) whereClause.package_id = packageId;
|
|
2459
|
+
let rs = await this.engine.find("sys_metadata", { where: whereClause });
|
|
2460
|
+
if (!rs || rs.length === 0) {
|
|
2461
|
+
const alt = import_shared4.PLURAL_TO_SINGULAR[request.type] ?? import_shared4.SINGULAR_TO_PLURAL[request.type];
|
|
2462
|
+
if (alt) {
|
|
2463
|
+
const altWhere = { type: alt, state: "draft", organization_id: oid };
|
|
2464
|
+
if (packageId) altWhere.package_id = packageId;
|
|
2465
|
+
rs = await this.engine.find("sys_metadata", { where: altWhere });
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
return rs ?? [];
|
|
2469
|
+
};
|
|
2470
|
+
const draftRecords = [...await queryDrafts(null), ...orgId ? await queryDrafts(orgId) : []];
|
|
2471
|
+
if (draftRecords.length > 0) {
|
|
2472
|
+
const byName = /* @__PURE__ */ new Map();
|
|
2473
|
+
for (const existing of items) {
|
|
2474
|
+
const entry = existing;
|
|
2475
|
+
if (entry && typeof entry === "object" && "name" in entry) byName.set(entry.name, entry);
|
|
2476
|
+
}
|
|
2477
|
+
for (const record of draftRecords) {
|
|
2478
|
+
const data = typeof record.metadata === "string" ? JSON.parse(record.metadata) : record.metadata;
|
|
2479
|
+
if (data && typeof data === "object" && "name" in data) {
|
|
2480
|
+
const recPkg = record.package_id ?? void 0;
|
|
2481
|
+
if (recPkg && data._packageId === void 0) data._packageId = recPkg;
|
|
2482
|
+
data._draft = true;
|
|
2483
|
+
byName.set(data.name, data);
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
items = Array.from(byName.values());
|
|
2487
|
+
}
|
|
2488
|
+
} catch {
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2453
2491
|
try {
|
|
2454
2492
|
const services = this.getServicesRegistry?.();
|
|
2455
2493
|
const metadataService = services?.get("metadata");
|
|
@@ -2508,6 +2546,34 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
2508
2546
|
let item;
|
|
2509
2547
|
const orgId = request.organizationId;
|
|
2510
2548
|
const readState = request.state === "draft" ? "draft" : "active";
|
|
2549
|
+
if (request.previewDrafts && readState !== "draft") {
|
|
2550
|
+
try {
|
|
2551
|
+
const findDraft = async (oid) => {
|
|
2552
|
+
const rec = await this.engine.findOne("sys_metadata", {
|
|
2553
|
+
where: { type: request.type, name: request.name, state: "draft", organization_id: oid }
|
|
2554
|
+
});
|
|
2555
|
+
if (rec) return rec;
|
|
2556
|
+
const alt = import_shared4.PLURAL_TO_SINGULAR[request.type] ?? import_shared4.SINGULAR_TO_PLURAL[request.type];
|
|
2557
|
+
if (alt) {
|
|
2558
|
+
return await this.engine.findOne("sys_metadata", {
|
|
2559
|
+
where: { type: alt, name: request.name, state: "draft", organization_id: oid }
|
|
2560
|
+
});
|
|
2561
|
+
}
|
|
2562
|
+
return void 0;
|
|
2563
|
+
};
|
|
2564
|
+
const draftRec = (orgId ? await findDraft(orgId) : void 0) ?? await findDraft(null);
|
|
2565
|
+
if (draftRec) {
|
|
2566
|
+
const draftItem = typeof draftRec.metadata === "string" ? JSON.parse(draftRec.metadata) : draftRec.metadata;
|
|
2567
|
+
if (draftItem && typeof draftItem === "object") {
|
|
2568
|
+
const recPkg = draftRec.package_id ?? void 0;
|
|
2569
|
+
if (recPkg && draftItem._packageId === void 0) draftItem._packageId = recPkg;
|
|
2570
|
+
draftItem._draft = true;
|
|
2571
|
+
}
|
|
2572
|
+
return { type: request.type, name: request.name, item: decorateMetadataItem(request.type, draftItem) };
|
|
2573
|
+
}
|
|
2574
|
+
} catch {
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2511
2577
|
try {
|
|
2512
2578
|
const findOverlay = async (oid) => {
|
|
2513
2579
|
const where = {
|
|
@@ -3882,6 +3948,37 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
3882
3948
|
console.warn(`[Protocol] table sync failed for object '${name}': ${err?.message ?? err}`);
|
|
3883
3949
|
}
|
|
3884
3950
|
}
|
|
3951
|
+
/**
|
|
3952
|
+
* Inverse of {@link ensureObjectStorage}: drop an object's physical table.
|
|
3953
|
+
* DESTRUCTIVE — deletes the table and all its rows. Only invoked when a
|
|
3954
|
+
* delete explicitly opts into storage teardown (see {@link deleteMetaItem}'s
|
|
3955
|
+
* `dropStorage`), so publishing an object solely to preview it can be undone
|
|
3956
|
+
* without leaving an orphan table. Best-effort: a failure is logged, not
|
|
3957
|
+
* thrown — the metadata delete already succeeded, and a stray table is
|
|
3958
|
+
* reclaimed by the next sync/drop rather than blocking the delete.
|
|
3959
|
+
*/
|
|
3960
|
+
async dropObjectStorage(type, name) {
|
|
3961
|
+
if (type !== "object" && type !== "objects") return;
|
|
3962
|
+
try {
|
|
3963
|
+
await this.engine.dropObjectSchema(name);
|
|
3964
|
+
} catch (err) {
|
|
3965
|
+
console.warn(`[Protocol] table drop failed for object '${name}': ${err?.message ?? err}`);
|
|
3966
|
+
}
|
|
3967
|
+
}
|
|
3968
|
+
/**
|
|
3969
|
+
* Guard for storage teardown on delete. Drops a physical table only when
|
|
3970
|
+
* the caller opted in AND it is safe: object types only (others have no
|
|
3971
|
+
* table), active state only (drafts were never materialised), and never a
|
|
3972
|
+
* `sys_`-prefixed platform table.
|
|
3973
|
+
*/
|
|
3974
|
+
shouldDropStorage(type, name, dropStorage, state) {
|
|
3975
|
+
if (!dropStorage) return false;
|
|
3976
|
+
const singular = import_shared4.PLURAL_TO_SINGULAR[type] ?? type;
|
|
3977
|
+
if (singular !== "object") return false;
|
|
3978
|
+
if (state !== "active") return false;
|
|
3979
|
+
if (name.startsWith("sys_")) return false;
|
|
3980
|
+
return true;
|
|
3981
|
+
}
|
|
3885
3982
|
async saveMetaItem(request) {
|
|
3886
3983
|
if (!request.item) {
|
|
3887
3984
|
throw new Error("Item data is required");
|
|
@@ -4262,6 +4359,100 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
4262
4359
|
failed
|
|
4263
4360
|
};
|
|
4264
4361
|
}
|
|
4362
|
+
/**
|
|
4363
|
+
* Discard every pending DRAFT bound to a package — the NON-destructive
|
|
4364
|
+
* inverse of {@link publishPackageDrafts}. Drops only `state='draft'` rows
|
|
4365
|
+
* (via the per-item delete primitive), reverting the package to its last
|
|
4366
|
+
* published baseline; active/published metadata and physical tables are
|
|
4367
|
+
* left untouched.
|
|
4368
|
+
*
|
|
4369
|
+
* Use case: "I edited this app for a while and it turned out worse than
|
|
4370
|
+
* before — abandon all my changes." Routes through the sys_metadata path
|
|
4371
|
+
* (no metadata-service dependency, unlike `POST /packages/:id/revert`).
|
|
4372
|
+
*/
|
|
4373
|
+
async discardPackageDrafts(request) {
|
|
4374
|
+
await this.ensureOverlayIndex();
|
|
4375
|
+
const orgId = request.organizationId ?? null;
|
|
4376
|
+
const repo = this.getOverlayRepo(orgId);
|
|
4377
|
+
const drafts = await repo.listDrafts({ packageId: request.packageId });
|
|
4378
|
+
const discarded = [];
|
|
4379
|
+
const failed = [];
|
|
4380
|
+
for (const d of drafts) {
|
|
4381
|
+
try {
|
|
4382
|
+
await this.deleteMetaItem({
|
|
4383
|
+
type: d.type,
|
|
4384
|
+
name: d.name,
|
|
4385
|
+
state: "draft",
|
|
4386
|
+
...request.organizationId ? { organizationId: request.organizationId } : {},
|
|
4387
|
+
...request.actor ? { actor: request.actor } : {}
|
|
4388
|
+
});
|
|
4389
|
+
discarded.push({ type: d.type, name: d.name });
|
|
4390
|
+
} catch (e) {
|
|
4391
|
+
failed.push({
|
|
4392
|
+
type: d.type,
|
|
4393
|
+
name: d.name,
|
|
4394
|
+
error: e?.message ?? "discard failed",
|
|
4395
|
+
...e?.code ? { code: e.code } : {}
|
|
4396
|
+
});
|
|
4397
|
+
}
|
|
4398
|
+
}
|
|
4399
|
+
return {
|
|
4400
|
+
success: failed.length === 0 && discarded.length > 0,
|
|
4401
|
+
discardedCount: discarded.length,
|
|
4402
|
+
failedCount: failed.length,
|
|
4403
|
+
discarded,
|
|
4404
|
+
failed
|
|
4405
|
+
};
|
|
4406
|
+
}
|
|
4407
|
+
/**
|
|
4408
|
+
* Delete an ENTIRE package: every `sys_metadata` row bound to it (active
|
|
4409
|
+
* AND draft) and — by default — the physical table of each object it
|
|
4410
|
+
* defined. DESTRUCTIVE: removes the app and its data. Use case: "I don't
|
|
4411
|
+
* want this package anymore."
|
|
4412
|
+
*
|
|
4413
|
+
* Set `keepData: true` to remove the metadata but preserve object tables.
|
|
4414
|
+
* The `sys_`-table guard in {@link deleteMetaItem} still applies, so
|
|
4415
|
+
* platform storage is never dropped. Drafts are removed before active rows
|
|
4416
|
+
* so each object's table is torn down once. Per-item failures are collected
|
|
4417
|
+
* without aborting the rest.
|
|
4418
|
+
*/
|
|
4419
|
+
async deletePackage(request) {
|
|
4420
|
+
const where = { package_id: request.packageId };
|
|
4421
|
+
if (request.organizationId) where.organization_id = request.organizationId;
|
|
4422
|
+
const rows = await this.engine.find("sys_metadata", { where });
|
|
4423
|
+
const dropStorage = request.keepData !== true;
|
|
4424
|
+
const ordered = [...rows].sort((a, b) => (a.state === "draft" ? 0 : 1) - (b.state === "draft" ? 0 : 1));
|
|
4425
|
+
const deleted = [];
|
|
4426
|
+
const failed = [];
|
|
4427
|
+
for (const row of ordered) {
|
|
4428
|
+
const state = row.state === "draft" ? "draft" : "active";
|
|
4429
|
+
try {
|
|
4430
|
+
await this.deleteMetaItem({
|
|
4431
|
+
type: row.type,
|
|
4432
|
+
name: row.name,
|
|
4433
|
+
state,
|
|
4434
|
+
...row.organization_id ? { organizationId: row.organization_id } : {},
|
|
4435
|
+
...request.actor ? { actor: request.actor } : {},
|
|
4436
|
+
...dropStorage ? { dropStorage: true } : {}
|
|
4437
|
+
});
|
|
4438
|
+
deleted.push({ type: row.type, name: row.name, state });
|
|
4439
|
+
} catch (e) {
|
|
4440
|
+
failed.push({
|
|
4441
|
+
type: row.type,
|
|
4442
|
+
name: row.name,
|
|
4443
|
+
error: e?.message ?? "delete failed",
|
|
4444
|
+
...e?.code ? { code: e.code } : {}
|
|
4445
|
+
});
|
|
4446
|
+
}
|
|
4447
|
+
}
|
|
4448
|
+
return {
|
|
4449
|
+
success: failed.length === 0 && deleted.length > 0,
|
|
4450
|
+
deletedCount: deleted.length,
|
|
4451
|
+
failedCount: failed.length,
|
|
4452
|
+
deleted,
|
|
4453
|
+
failed
|
|
4454
|
+
};
|
|
4455
|
+
}
|
|
4265
4456
|
/**
|
|
4266
4457
|
* Restore the body recorded at history `toVersion` as the new
|
|
4267
4458
|
* live row. Writes a history event with `op='revert'`. 404
|
|
@@ -4494,6 +4685,9 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
4494
4685
|
} catch {
|
|
4495
4686
|
}
|
|
4496
4687
|
}
|
|
4688
|
+
if (this.shouldDropStorage(request.type, request.name, request.dropStorage, targetState)) {
|
|
4689
|
+
await this.dropObjectStorage(singularTypeForRepo, request.name);
|
|
4690
|
+
}
|
|
4497
4691
|
await this.recordMetadataAudit({
|
|
4498
4692
|
type: request.type,
|
|
4499
4693
|
name: request.name,
|
|
@@ -4542,6 +4736,12 @@ var _ObjectStackProtocolImplementation = class _ObjectStackProtocolImplementatio
|
|
|
4542
4736
|
};
|
|
4543
4737
|
}
|
|
4544
4738
|
await this.engine.delete("sys_metadata", { where: { id: existing.id } });
|
|
4739
|
+
{
|
|
4740
|
+
const targetState = request.state === "draft" ? "draft" : "active";
|
|
4741
|
+
if (this.shouldDropStorage(request.type, request.name, request.dropStorage, targetState)) {
|
|
4742
|
+
await this.dropObjectStorage(import_shared4.PLURAL_TO_SINGULAR[request.type] ?? request.type, request.name);
|
|
4743
|
+
}
|
|
4744
|
+
}
|
|
4545
4745
|
if (this.environmentId === void 0) {
|
|
4546
4746
|
try {
|
|
4547
4747
|
const services = this.getServicesRegistry?.();
|
|
@@ -7643,6 +7843,22 @@ var _ObjectQL = class _ObjectQL {
|
|
|
7643
7843
|
const tableName = import_system2.StorageNameMapping.resolveTableName(obj);
|
|
7644
7844
|
await driver.syncSchema(tableName, obj);
|
|
7645
7845
|
}
|
|
7846
|
+
/**
|
|
7847
|
+
* Drop the physical storage (table/collection) backing an object — the
|
|
7848
|
+
* inverse of {@link syncObjectSchema}. DESTRUCTIVE: deletes all rows in the
|
|
7849
|
+
* table. Used by the protocol delete path when the caller explicitly opts
|
|
7850
|
+
* into storage teardown (e.g. discarding an object that was published only
|
|
7851
|
+
* to preview it). No-op when the object's driver does not expose `dropTable`.
|
|
7852
|
+
* Resolves the physical table name from the registered definition, falling
|
|
7853
|
+
* back to the bare name if the def was already removed.
|
|
7854
|
+
*/
|
|
7855
|
+
async dropObjectSchema(objectName) {
|
|
7856
|
+
const obj = this._registry.getObject(objectName);
|
|
7857
|
+
const driver = this.getDriverForObject(objectName);
|
|
7858
|
+
if (!driver || typeof driver.dropTable !== "function") return;
|
|
7859
|
+
const tableName = import_system2.StorageNameMapping.resolveTableName(obj ?? { name: objectName });
|
|
7860
|
+
await driver.dropTable(tableName);
|
|
7861
|
+
}
|
|
7646
7862
|
/**
|
|
7647
7863
|
* Get a registered driver by datasource name.
|
|
7648
7864
|
* Alias matching @objectql/core datasource() API.
|