@objectstack/rest 7.0.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.js CHANGED
@@ -1275,6 +1275,40 @@ var RestServer = class {
1275
1275
  }
1276
1276
  });
1277
1277
  }
1278
+ if (metadata.endpoints.items !== false) {
1279
+ this.routeManager.register({
1280
+ method: "GET",
1281
+ path: `${metaPath}/diagnostics`,
1282
+ handler: async (req, res) => {
1283
+ try {
1284
+ const environmentId = isScoped ? req.params?.environmentId : void 0;
1285
+ const p = await this.resolveProtocol(environmentId, req);
1286
+ if (typeof p.getMetaDiagnostics !== "function") {
1287
+ res.status(501).json({
1288
+ error: "not_implemented",
1289
+ message: "protocol.getMetaDiagnostics() is not available in this kernel"
1290
+ });
1291
+ return;
1292
+ }
1293
+ const severityParam = req.query?.severity ?? "error";
1294
+ const severity = severityParam === "warning" ? "warning" : "error";
1295
+ const result = await p.getMetaDiagnostics({
1296
+ type: req.query?.type || void 0,
1297
+ severity,
1298
+ packageId: req.query?.package || void 0
1299
+ });
1300
+ res.json(result);
1301
+ } catch (error) {
1302
+ logError("[REST] Unhandled error:", error);
1303
+ sendError(res, error);
1304
+ }
1305
+ },
1306
+ metadata: {
1307
+ summary: "List metadata entries that fail spec validation",
1308
+ tags: ["metadata"]
1309
+ }
1310
+ });
1311
+ }
1278
1312
  if (metadata.endpoints.items !== false) {
1279
1313
  this.routeManager.register({
1280
1314
  method: "GET",
@@ -1364,7 +1398,8 @@ var RestServer = class {
1364
1398
  return;
1365
1399
  }
1366
1400
  const isAppType = req.params.type === "app";
1367
- if (metadata.enableCache && p.getMetaItemCached && !isAppType) {
1401
+ const isDraftRead = typeof req.query?.state === "string" && req.query.state.toLowerCase() === "draft";
1402
+ if (metadata.enableCache && p.getMetaItemCached && !isAppType && !isDraftRead) {
1368
1403
  const cacheRequest = {
1369
1404
  ifNoneMatch: req.headers["if-none-match"],
1370
1405
  ifModifiedSince: req.headers["if-modified-since"]
@@ -1395,10 +1430,12 @@ var RestServer = class {
1395
1430
  res.json(await this.translateMetaItem(req, req.params.type, environmentId, result.data));
1396
1431
  } else {
1397
1432
  const packageId = req.query?.package || void 0;
1433
+ const stateParam = typeof req.query?.state === "string" ? req.query.state.toLowerCase() : void 0;
1398
1434
  const item = await p.getMetaItem({
1399
1435
  type: req.params.type,
1400
1436
  name: req.params.name,
1401
- packageId
1437
+ packageId,
1438
+ ...stateParam === "draft" ? { state: "draft" } : {}
1402
1439
  });
1403
1440
  let visible = item;
1404
1441
  if (isAppType && item) {
@@ -1457,7 +1494,8 @@ var RestServer = class {
1457
1494
  ...environmentId ? { environmentId } : {},
1458
1495
  ...parentVersion !== void 0 ? { parentVersion } : {},
1459
1496
  ...actor ? { actor } : {},
1460
- ...force ? { force: true } : {}
1497
+ ...force ? { force: true } : {},
1498
+ ...typeof req.query?.mode === "string" && req.query.mode.toLowerCase() === "draft" ? { mode: "draft" } : {}
1461
1499
  });
1462
1500
  res.json(result);
1463
1501
  } catch (error) {
@@ -1487,12 +1525,14 @@ var RestServer = class {
1487
1525
  const parentVersion = typeof ifMatchHeader === "string" ? ifMatchHeader.replace(/^"|"$/g, "") : void 0;
1488
1526
  const actorHeader = req.headers?.["x-actor"] ?? req.headers?.["X-Actor"] ?? req.user?.id ?? req.userId;
1489
1527
  const actor = typeof actorHeader === "string" ? actorHeader : void 0;
1528
+ const stateParam = typeof req.query?.state === "string" && req.query.state.toLowerCase() === "draft" ? "draft" : void 0;
1490
1529
  const result = await p.deleteMetaItem({
1491
1530
  type: req.params.type,
1492
1531
  name: req.params.name,
1493
1532
  ...environmentId ? { environmentId } : {},
1494
1533
  ...parentVersion !== void 0 ? { parentVersion } : {},
1495
- ...actor ? { actor } : {}
1534
+ ...actor ? { actor } : {},
1535
+ ...stateParam ? { state: stateParam } : {}
1496
1536
  });
1497
1537
  res.json(result);
1498
1538
  } catch (error) {
@@ -1538,6 +1578,153 @@ var RestServer = class {
1538
1578
  tags: ["metadata"]
1539
1579
  }
1540
1580
  });
1581
+ this.routeManager.register({
1582
+ method: "GET",
1583
+ path: `${metaPath}/:type/:name/audit`,
1584
+ handler: async (req, res) => {
1585
+ try {
1586
+ const environmentId = isScoped ? req.params?.environmentId : void 0;
1587
+ const p = await this.resolveProtocol(environmentId, req);
1588
+ if (typeof p.auditMetaItem !== "function") {
1589
+ res.json({ events: [] });
1590
+ return;
1591
+ }
1592
+ const limit = req.query?.limit !== void 0 ? Number(req.query.limit) : void 0;
1593
+ const result = await p.auditMetaItem({
1594
+ type: req.params.type,
1595
+ name: req.params.name,
1596
+ ...environmentId ? { environmentId } : {},
1597
+ ...limit !== void 0 && Number.isFinite(limit) ? { limit } : {}
1598
+ });
1599
+ res.json(result);
1600
+ } catch (error) {
1601
+ logError("[REST] Unhandled error:", error);
1602
+ sendError(res, error);
1603
+ }
1604
+ },
1605
+ metadata: {
1606
+ summary: "List protection-audit events for a metadata item",
1607
+ tags: ["metadata"]
1608
+ }
1609
+ });
1610
+ this.routeManager.register({
1611
+ method: "POST",
1612
+ path: `${metaPath}/:type/:name/publish`,
1613
+ handler: async (req, res) => {
1614
+ try {
1615
+ const environmentId = isScoped ? req.params?.environmentId : void 0;
1616
+ const p = await this.resolveProtocol(environmentId, req);
1617
+ if (!p.publishMetaItem) {
1618
+ res.status(501).json({
1619
+ error: "Publish operation not supported by protocol implementation"
1620
+ });
1621
+ return;
1622
+ }
1623
+ const actorHeader = req.headers?.["x-actor"] ?? req.headers?.["X-Actor"] ?? req.user?.id ?? req.userId;
1624
+ const actor = typeof actorHeader === "string" ? actorHeader : void 0;
1625
+ const body = req.body && typeof req.body === "object" ? req.body : {};
1626
+ const message = typeof body.message === "string" ? body.message : void 0;
1627
+ const result = await p.publishMetaItem({
1628
+ type: req.params.type,
1629
+ name: req.params.name,
1630
+ ...environmentId ? { environmentId } : {},
1631
+ ...actor ? { actor } : {},
1632
+ ...message ? { message } : {}
1633
+ });
1634
+ res.json(result);
1635
+ } catch (error) {
1636
+ logError("[REST] Unhandled error:", error);
1637
+ sendError(res, error);
1638
+ }
1639
+ },
1640
+ metadata: {
1641
+ summary: "Publish the pending draft overlay (promotes draft \u2192 active)",
1642
+ tags: ["metadata"]
1643
+ }
1644
+ });
1645
+ this.routeManager.register({
1646
+ method: "POST",
1647
+ path: `${metaPath}/:type/:name/rollback`,
1648
+ handler: async (req, res) => {
1649
+ try {
1650
+ const environmentId = isScoped ? req.params?.environmentId : void 0;
1651
+ const p = await this.resolveProtocol(environmentId, req);
1652
+ if (!p.rollbackMetaItem) {
1653
+ res.status(501).json({
1654
+ error: "Rollback operation not supported by protocol implementation"
1655
+ });
1656
+ return;
1657
+ }
1658
+ const body = req.body && typeof req.body === "object" ? req.body : {};
1659
+ const toVersionRaw = body.toVersion ?? body.version ?? req.query?.toVersion;
1660
+ const toVersion = Number(toVersionRaw);
1661
+ if (!Number.isFinite(toVersion) || toVersion < 1) {
1662
+ res.status(400).json({
1663
+ error: `'toVersion' (positive integer) is required`,
1664
+ code: "invalid_request"
1665
+ });
1666
+ return;
1667
+ }
1668
+ const actorHeader = req.headers?.["x-actor"] ?? req.headers?.["X-Actor"] ?? req.user?.id ?? req.userId;
1669
+ const actor = typeof actorHeader === "string" ? actorHeader : void 0;
1670
+ const message = typeof body.message === "string" ? body.message : void 0;
1671
+ const result = await p.rollbackMetaItem({
1672
+ type: req.params.type,
1673
+ name: req.params.name,
1674
+ toVersion,
1675
+ ...environmentId ? { environmentId } : {},
1676
+ ...actor ? { actor } : {},
1677
+ ...message ? { message } : {}
1678
+ });
1679
+ res.json(result);
1680
+ } catch (error) {
1681
+ logError("[REST] Unhandled error:", error);
1682
+ sendError(res, error);
1683
+ }
1684
+ },
1685
+ metadata: {
1686
+ summary: "Restore the body at the given history version as the new live row",
1687
+ tags: ["metadata"]
1688
+ }
1689
+ });
1690
+ this.routeManager.register({
1691
+ method: "GET",
1692
+ path: `${metaPath}/:type/:name/diff`,
1693
+ handler: async (req, res) => {
1694
+ try {
1695
+ const environmentId = isScoped ? req.params?.environmentId : void 0;
1696
+ const p = await this.resolveProtocol(environmentId, req);
1697
+ if (!p.diffMetaItem) {
1698
+ res.status(501).json({
1699
+ error: "Diff operation not supported by protocol implementation"
1700
+ });
1701
+ return;
1702
+ }
1703
+ const parseV = (raw) => {
1704
+ if (raw === void 0 || raw === null || raw === "") return void 0;
1705
+ const n = Number(raw);
1706
+ return Number.isFinite(n) ? n : void 0;
1707
+ };
1708
+ const fromVersion = parseV(req.query?.from ?? req.query?.fromVersion);
1709
+ const toVersion = parseV(req.query?.to ?? req.query?.toVersion);
1710
+ const result = await p.diffMetaItem({
1711
+ type: req.params.type,
1712
+ name: req.params.name,
1713
+ ...environmentId ? { environmentId } : {},
1714
+ ...fromVersion !== void 0 ? { fromVersion } : {},
1715
+ ...toVersion !== void 0 ? { toVersion } : {}
1716
+ });
1717
+ res.json(result);
1718
+ } catch (error) {
1719
+ logError("[REST] Unhandled error:", error);
1720
+ sendError(res, error);
1721
+ }
1722
+ },
1723
+ metadata: {
1724
+ summary: "Diff two metadata versions (from/to query params; omit for previous-vs-current)",
1725
+ tags: ["metadata"]
1726
+ }
1727
+ });
1541
1728
  if (metadata.endpoints.item !== false) {
1542
1729
  this.routeManager.register({
1543
1730
  method: "GET",