@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.cjs
CHANGED
|
@@ -871,6 +871,9 @@ var RestServer = class {
|
|
|
871
871
|
*/
|
|
872
872
|
filterAppForUser(item, sysPerms) {
|
|
873
873
|
if (!item || typeof item !== "object") return item;
|
|
874
|
+
if (item.hidden === true && !sysPerms.has("studio.access") && !sysPerms.has("setup.access")) {
|
|
875
|
+
return null;
|
|
876
|
+
}
|
|
874
877
|
const reqApp = Array.isArray(item.requiredPermissions) ? item.requiredPermissions : [];
|
|
875
878
|
if (reqApp.length > 0 && !reqApp.every((p) => sysPerms.has(p))) {
|
|
876
879
|
return null;
|
|
@@ -1488,9 +1491,11 @@ var RestServer = class {
|
|
|
1488
1491
|
const packageId = req.query?.package || void 0;
|
|
1489
1492
|
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
1490
1493
|
const p = await this.resolveProtocol(environmentId, req);
|
|
1494
|
+
const previewDrafts = typeof req.query?.preview === "string" && req.query.preview.toLowerCase() === "draft";
|
|
1491
1495
|
const items = await p.getMetaItems({
|
|
1492
1496
|
type: req.params.type,
|
|
1493
1497
|
packageId,
|
|
1498
|
+
...previewDrafts ? { previewDrafts: true } : {},
|
|
1494
1499
|
...environmentId ? { environmentId } : {}
|
|
1495
1500
|
});
|
|
1496
1501
|
let visible = items;
|
|
@@ -1517,6 +1522,18 @@ var RestServer = class {
|
|
|
1517
1522
|
visible = Array.isArray(raw) ? filtered : { ...raw, items: filtered };
|
|
1518
1523
|
}
|
|
1519
1524
|
}
|
|
1525
|
+
if (req.params.type === "doc" && req.query?.include !== "content") {
|
|
1526
|
+
const raw = visible;
|
|
1527
|
+
const list = Array.isArray(raw) ? raw : raw && typeof raw === "object" && Array.isArray(raw.items) ? raw.items : null;
|
|
1528
|
+
if (list) {
|
|
1529
|
+
const slim = list.map((it) => {
|
|
1530
|
+
if (!it || typeof it !== "object") return it;
|
|
1531
|
+
const { content: _content, ...rest } = it;
|
|
1532
|
+
return rest;
|
|
1533
|
+
});
|
|
1534
|
+
visible = Array.isArray(raw) ? slim : { ...raw, items: slim };
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1520
1537
|
const translated = await this.translateMetaItems(req, req.params.type, environmentId, visible);
|
|
1521
1538
|
res.header("Vary", "Accept-Language");
|
|
1522
1539
|
res.json(translated);
|
|
@@ -1578,7 +1595,8 @@ var RestServer = class {
|
|
|
1578
1595
|
}
|
|
1579
1596
|
const isAppType = req.params.type === "app";
|
|
1580
1597
|
const isDraftRead = typeof req.query?.state === "string" && req.query.state.toLowerCase() === "draft";
|
|
1581
|
-
|
|
1598
|
+
const previewDrafts = typeof req.query?.preview === "string" && req.query.preview.toLowerCase() === "draft";
|
|
1599
|
+
if (metadata.enableCache && p.getMetaItemCached && !isAppType && !isDraftRead && !previewDrafts) {
|
|
1582
1600
|
const cacheRequest = {
|
|
1583
1601
|
ifNoneMatch: req.headers["if-none-match"],
|
|
1584
1602
|
ifModifiedSince: req.headers["if-modified-since"]
|
|
@@ -1617,7 +1635,8 @@ var RestServer = class {
|
|
|
1617
1635
|
type: req.params.type,
|
|
1618
1636
|
name: req.params.name,
|
|
1619
1637
|
packageId,
|
|
1620
|
-
...stateParam === "draft" ? { state: "draft" } : {}
|
|
1638
|
+
...stateParam === "draft" ? { state: "draft" } : {},
|
|
1639
|
+
...previewDrafts ? { previewDrafts: true } : {}
|
|
1621
1640
|
});
|
|
1622
1641
|
let visible = item;
|
|
1623
1642
|
if (isAppType && item) {
|
|
@@ -3582,6 +3601,7 @@ var RestServer = class {
|
|
|
3582
3601
|
[/^VALIDATION_FAILED/, 400, "VALIDATION_FAILED"],
|
|
3583
3602
|
[/^DUPLICATE_REQUEST/, 409, "DUPLICATE_REQUEST"],
|
|
3584
3603
|
[/^INVALID_STATE/, 409, "INVALID_STATE"],
|
|
3604
|
+
[/^THROTTLED/, 429, "THROTTLED"],
|
|
3585
3605
|
[/^FORBIDDEN/, 403, "FORBIDDEN"],
|
|
3586
3606
|
[/^REQUEST_NOT_FOUND/, 404, "REQUEST_NOT_FOUND"]
|
|
3587
3607
|
];
|
|
@@ -3609,13 +3629,24 @@ var RestServer = class {
|
|
|
3609
3629
|
const q = req.query ?? {};
|
|
3610
3630
|
const rawApprover = q.approverId ?? q.approver_id;
|
|
3611
3631
|
const approverIds = (Array.isArray(rawApprover) ? rawApprover : rawApprover != null ? [rawApprover] : []).flatMap((s) => String(s).split(",")).map((s) => s.trim()).filter(Boolean);
|
|
3612
|
-
const
|
|
3632
|
+
const limit = q.limit != null ? Number(q.limit) : void 0;
|
|
3633
|
+
const offset = q.offset != null ? Number(q.offset) : void 0;
|
|
3634
|
+
const listFilter = {
|
|
3613
3635
|
object: q.object,
|
|
3614
3636
|
recordId: q.recordId ?? q.record_id,
|
|
3615
3637
|
status: q.status,
|
|
3616
3638
|
approverId: approverIds.length ? approverIds : void 0,
|
|
3617
|
-
submitterId: q.submitterId ?? q.submitter_id
|
|
3618
|
-
|
|
3639
|
+
submitterId: q.submitterId ?? q.submitter_id,
|
|
3640
|
+
q: typeof q.q === "string" ? q.q : void 0,
|
|
3641
|
+
limit: Number.isFinite(limit) ? limit : void 0,
|
|
3642
|
+
offset: Number.isFinite(offset) ? offset : void 0
|
|
3643
|
+
};
|
|
3644
|
+
const rows = await svc.listRequests(listFilter, context ?? {});
|
|
3645
|
+
if (listFilter.limit != null && typeof svc.countRequests === "function") {
|
|
3646
|
+
const total = await svc.countRequests(listFilter, context ?? {});
|
|
3647
|
+
res.json({ data: rows, total });
|
|
3648
|
+
return;
|
|
3649
|
+
}
|
|
3619
3650
|
res.json({ data: rows });
|
|
3620
3651
|
} catch (error) {
|
|
3621
3652
|
logError("[REST] List approval requests error:", error);
|
|
@@ -3708,6 +3739,63 @@ var RestServer = class {
|
|
|
3708
3739
|
},
|
|
3709
3740
|
metadata: { summary: "Recall (withdraw) an approval request", tags: ["approvals"] }
|
|
3710
3741
|
});
|
|
3742
|
+
const threadRoute = (action, invoke) => {
|
|
3743
|
+
this.routeManager.register({
|
|
3744
|
+
method: "POST",
|
|
3745
|
+
path: `${dataPath}/approvals/requests/:id/${action}`,
|
|
3746
|
+
handler: async (req, res) => {
|
|
3747
|
+
try {
|
|
3748
|
+
const environmentId = isScoped ? req.params?.environmentId : void 0;
|
|
3749
|
+
const context = await this.resolveExecCtx(environmentId, req);
|
|
3750
|
+
if (this.enforceAuth(req, res, context)) return;
|
|
3751
|
+
const svc = await resolveService(environmentId);
|
|
3752
|
+
if (!svc) return respond501(res);
|
|
3753
|
+
const body = req.body ?? {};
|
|
3754
|
+
try {
|
|
3755
|
+
const out = await invoke(svc, req.params.id, body, context ?? {});
|
|
3756
|
+
res.json(out);
|
|
3757
|
+
} catch (err) {
|
|
3758
|
+
if (handleApprovalError(res, err)) return;
|
|
3759
|
+
throw err;
|
|
3760
|
+
}
|
|
3761
|
+
} catch (error) {
|
|
3762
|
+
logError(`[REST] ${action} approval error:`, error);
|
|
3763
|
+
res.status(500).json({ code: `APPROVAL_${action.toUpperCase().replace("-", "_")}_FAILED`, error: String(error?.message ?? error).slice(0, 500) });
|
|
3764
|
+
}
|
|
3765
|
+
},
|
|
3766
|
+
metadata: { summary: `${action} on an approval request`, tags: ["approvals"] }
|
|
3767
|
+
});
|
|
3768
|
+
};
|
|
3769
|
+
threadRoute("reassign", (svc, id, body, context) => {
|
|
3770
|
+
if (typeof svc.reassign !== "function") throw new Error("VALIDATION_FAILED: reassign is not supported");
|
|
3771
|
+
return svc.reassign(id, {
|
|
3772
|
+
actorId: body.actorId ?? body.actor_id ?? context?.userId,
|
|
3773
|
+
to: body.to,
|
|
3774
|
+
from: body.from,
|
|
3775
|
+
comment: body.comment
|
|
3776
|
+
}, context);
|
|
3777
|
+
});
|
|
3778
|
+
threadRoute("remind", (svc, id, body, context) => {
|
|
3779
|
+
if (typeof svc.remind !== "function") throw new Error("VALIDATION_FAILED: remind is not supported");
|
|
3780
|
+
return svc.remind(id, {
|
|
3781
|
+
actorId: body.actorId ?? body.actor_id ?? context?.userId,
|
|
3782
|
+
comment: body.comment
|
|
3783
|
+
}, context);
|
|
3784
|
+
});
|
|
3785
|
+
threadRoute("request-info", (svc, id, body, context) => {
|
|
3786
|
+
if (typeof svc.requestInfo !== "function") throw new Error("VALIDATION_FAILED: request-info is not supported");
|
|
3787
|
+
return svc.requestInfo(id, {
|
|
3788
|
+
actorId: body.actorId ?? body.actor_id ?? context?.userId,
|
|
3789
|
+
comment: body.comment
|
|
3790
|
+
}, context);
|
|
3791
|
+
});
|
|
3792
|
+
threadRoute("comment", (svc, id, body, context) => {
|
|
3793
|
+
if (typeof svc.comment !== "function") throw new Error("VALIDATION_FAILED: comment is not supported");
|
|
3794
|
+
return svc.comment(id, {
|
|
3795
|
+
actorId: body.actorId ?? body.actor_id ?? context?.userId,
|
|
3796
|
+
comment: body.comment
|
|
3797
|
+
}, context);
|
|
3798
|
+
});
|
|
3711
3799
|
this.routeManager.register({
|
|
3712
3800
|
method: "GET",
|
|
3713
3801
|
path: `${dataPath}/approvals/requests/:id/actions`,
|