@objectstack/rest 9.2.0 → 9.3.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 +93 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +93 -5
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -831,6 +831,9 @@ var RestServer = class {
|
|
|
831
831
|
*/
|
|
832
832
|
filterAppForUser(item, sysPerms) {
|
|
833
833
|
if (!item || typeof item !== "object") return item;
|
|
834
|
+
if (item.hidden === true && !sysPerms.has("studio.access") && !sysPerms.has("setup.access")) {
|
|
835
|
+
return null;
|
|
836
|
+
}
|
|
834
837
|
const reqApp = Array.isArray(item.requiredPermissions) ? item.requiredPermissions : [];
|
|
835
838
|
if (reqApp.length > 0 && !reqApp.every((p) => sysPerms.has(p))) {
|
|
836
839
|
return null;
|
|
@@ -1448,9 +1451,11 @@ var RestServer = class {
|
|
|
1448
1451
|
const packageId = req.query?.package || void 0;
|
|
1449
1452
|
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1450
1453
|
const p = await this.resolveProtocol(environmentId, req);
|
|
1454
|
+
const previewDrafts = typeof req.query?.preview === "string" && req.query.preview.toLowerCase() === "draft";
|
|
1451
1455
|
const items = await p.getMetaItems({
|
|
1452
1456
|
type: req.params.type,
|
|
1453
1457
|
packageId,
|
|
1458
|
+
...previewDrafts ? { previewDrafts: true } : {},
|
|
1454
1459
|
...environmentId ? { environmentId } : {}
|
|
1455
1460
|
});
|
|
1456
1461
|
let visible = items;
|
|
@@ -1477,6 +1482,18 @@ var RestServer = class {
|
|
|
1477
1482
|
visible = Array.isArray(raw) ? filtered : { ...raw, items: filtered };
|
|
1478
1483
|
}
|
|
1479
1484
|
}
|
|
1485
|
+
if (req.params.type === "doc" && req.query?.include !== "content") {
|
|
1486
|
+
const raw = visible;
|
|
1487
|
+
const list = Array.isArray(raw) ? raw : raw && typeof raw === "object" && Array.isArray(raw.items) ? raw.items : null;
|
|
1488
|
+
if (list) {
|
|
1489
|
+
const slim = list.map((it) => {
|
|
1490
|
+
if (!it || typeof it !== "object") return it;
|
|
1491
|
+
const { content: _content, ...rest } = it;
|
|
1492
|
+
return rest;
|
|
1493
|
+
});
|
|
1494
|
+
visible = Array.isArray(raw) ? slim : { ...raw, items: slim };
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1480
1497
|
const translated = await this.translateMetaItems(req, req.params.type, environmentId, visible);
|
|
1481
1498
|
res.header("Vary", "Accept-Language");
|
|
1482
1499
|
res.json(translated);
|
|
@@ -1538,7 +1555,8 @@ var RestServer = class {
|
|
|
1538
1555
|
}
|
|
1539
1556
|
const isAppType = req.params.type === "app";
|
|
1540
1557
|
const isDraftRead = typeof req.query?.state === "string" && req.query.state.toLowerCase() === "draft";
|
|
1541
|
-
|
|
1558
|
+
const previewDrafts = typeof req.query?.preview === "string" && req.query.preview.toLowerCase() === "draft";
|
|
1559
|
+
if (metadata.enableCache && p.getMetaItemCached && !isAppType && !isDraftRead && !previewDrafts) {
|
|
1542
1560
|
const cacheRequest = {
|
|
1543
1561
|
ifNoneMatch: req.headers["if-none-match"],
|
|
1544
1562
|
ifModifiedSince: req.headers["if-modified-since"]
|
|
@@ -1577,7 +1595,8 @@ var RestServer = class {
|
|
|
1577
1595
|
type: req.params.type,
|
|
1578
1596
|
name: req.params.name,
|
|
1579
1597
|
packageId,
|
|
1580
|
-
...stateParam === "draft" ? { state: "draft" } : {}
|
|
1598
|
+
...stateParam === "draft" ? { state: "draft" } : {},
|
|
1599
|
+
...previewDrafts ? { previewDrafts: true } : {}
|
|
1581
1600
|
});
|
|
1582
1601
|
let visible = item;
|
|
1583
1602
|
if (isAppType && item) {
|
|
@@ -3542,6 +3561,7 @@ var RestServer = class {
|
|
|
3542
3561
|
[/^VALIDATION_FAILED/, 400, "VALIDATION_FAILED"],
|
|
3543
3562
|
[/^DUPLICATE_REQUEST/, 409, "DUPLICATE_REQUEST"],
|
|
3544
3563
|
[/^INVALID_STATE/, 409, "INVALID_STATE"],
|
|
3564
|
+
[/^THROTTLED/, 429, "THROTTLED"],
|
|
3545
3565
|
[/^FORBIDDEN/, 403, "FORBIDDEN"],
|
|
3546
3566
|
[/^REQUEST_NOT_FOUND/, 404, "REQUEST_NOT_FOUND"]
|
|
3547
3567
|
];
|
|
@@ -3569,13 +3589,24 @@ var RestServer = class {
|
|
|
3569
3589
|
const q = req.query ?? {};
|
|
3570
3590
|
const rawApprover = q.approverId ?? q.approver_id;
|
|
3571
3591
|
const approverIds = (Array.isArray(rawApprover) ? rawApprover : rawApprover != null ? [rawApprover] : []).flatMap((s) => String(s).split(",")).map((s) => s.trim()).filter(Boolean);
|
|
3572
|
-
const
|
|
3592
|
+
const limit = q.limit != null ? Number(q.limit) : void 0;
|
|
3593
|
+
const offset = q.offset != null ? Number(q.offset) : void 0;
|
|
3594
|
+
const listFilter = {
|
|
3573
3595
|
object: q.object,
|
|
3574
3596
|
recordId: q.recordId ?? q.record_id,
|
|
3575
3597
|
status: q.status,
|
|
3576
3598
|
approverId: approverIds.length ? approverIds : void 0,
|
|
3577
|
-
submitterId: q.submitterId ?? q.submitter_id
|
|
3578
|
-
|
|
3599
|
+
submitterId: q.submitterId ?? q.submitter_id,
|
|
3600
|
+
q: typeof q.q === "string" ? q.q : void 0,
|
|
3601
|
+
limit: Number.isFinite(limit) ? limit : void 0,
|
|
3602
|
+
offset: Number.isFinite(offset) ? offset : void 0
|
|
3603
|
+
};
|
|
3604
|
+
const rows = await svc.listRequests(listFilter, context ?? {});
|
|
3605
|
+
if (listFilter.limit != null && typeof svc.countRequests === "function") {
|
|
3606
|
+
const total = await svc.countRequests(listFilter, context ?? {});
|
|
3607
|
+
res.json({ data: rows, total });
|
|
3608
|
+
return;
|
|
3609
|
+
}
|
|
3579
3610
|
res.json({ data: rows });
|
|
3580
3611
|
} catch (error) {
|
|
3581
3612
|
logError("[REST] List approval requests error:", error);
|
|
@@ -3668,6 +3699,63 @@ var RestServer = class {
|
|
|
3668
3699
|
},
|
|
3669
3700
|
metadata: { summary: "Recall (withdraw) an approval request", tags: ["approvals"] }
|
|
3670
3701
|
});
|
|
3702
|
+
const threadRoute = (action, invoke) => {
|
|
3703
|
+
this.routeManager.register({
|
|
3704
|
+
method: "POST",
|
|
3705
|
+
path: `${dataPath}/approvals/requests/:id/${action}`,
|
|
3706
|
+
handler: async (req, res) => {
|
|
3707
|
+
try {
|
|
3708
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3709
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3710
|
+
if (this.enforceAuth(req, res, context)) return;
|
|
3711
|
+
const svc = await resolveService(environmentId);
|
|
3712
|
+
if (!svc) return respond501(res);
|
|
3713
|
+
const body = req.body ?? {};
|
|
3714
|
+
try {
|
|
3715
|
+
const out = await invoke(svc, req.params.id, body, context ?? {});
|
|
3716
|
+
res.json(out);
|
|
3717
|
+
} catch (err) {
|
|
3718
|
+
if (handleApprovalError(res, err)) return;
|
|
3719
|
+
throw err;
|
|
3720
|
+
}
|
|
3721
|
+
} catch (error) {
|
|
3722
|
+
logError(`[REST] ${action} approval error:`, error);
|
|
3723
|
+
res.status(500).json({ code: `APPROVAL_${action.toUpperCase().replace("-", "_")}_FAILED`, error: String(error?.message ?? error).slice(0, 500) });
|
|
3724
|
+
}
|
|
3725
|
+
},
|
|
3726
|
+
metadata: { summary: `${action} on an approval request`, tags: ["approvals"] }
|
|
3727
|
+
});
|
|
3728
|
+
};
|
|
3729
|
+
threadRoute("reassign", (svc, id, body, context) => {
|
|
3730
|
+
if (typeof svc.reassign !== "function") throw new Error("VALIDATION_FAILED: reassign is not supported");
|
|
3731
|
+
return svc.reassign(id, {
|
|
3732
|
+
actorId: body.actorId ?? body.actor_id ?? context?.userId,
|
|
3733
|
+
to: body.to,
|
|
3734
|
+
from: body.from,
|
|
3735
|
+
comment: body.comment
|
|
3736
|
+
}, context);
|
|
3737
|
+
});
|
|
3738
|
+
threadRoute("remind", (svc, id, body, context) => {
|
|
3739
|
+
if (typeof svc.remind !== "function") throw new Error("VALIDATION_FAILED: remind is not supported");
|
|
3740
|
+
return svc.remind(id, {
|
|
3741
|
+
actorId: body.actorId ?? body.actor_id ?? context?.userId,
|
|
3742
|
+
comment: body.comment
|
|
3743
|
+
}, context);
|
|
3744
|
+
});
|
|
3745
|
+
threadRoute("request-info", (svc, id, body, context) => {
|
|
3746
|
+
if (typeof svc.requestInfo !== "function") throw new Error("VALIDATION_FAILED: request-info is not supported");
|
|
3747
|
+
return svc.requestInfo(id, {
|
|
3748
|
+
actorId: body.actorId ?? body.actor_id ?? context?.userId,
|
|
3749
|
+
comment: body.comment
|
|
3750
|
+
}, context);
|
|
3751
|
+
});
|
|
3752
|
+
threadRoute("comment", (svc, id, body, context) => {
|
|
3753
|
+
if (typeof svc.comment !== "function") throw new Error("VALIDATION_FAILED: comment is not supported");
|
|
3754
|
+
return svc.comment(id, {
|
|
3755
|
+
actorId: body.actorId ?? body.actor_id ?? context?.userId,
|
|
3756
|
+
comment: body.comment
|
|
3757
|
+
}, context);
|
|
3758
|
+
});
|
|
3671
3759
|
this.routeManager.register({
|
|
3672
3760
|
method: "GET",
|
|
3673
3761
|
path: `${dataPath}/approvals/requests/:id/actions`,
|