@objectstack/runtime 9.5.1 → 9.6.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
@@ -1,7 +1,12 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __esm = (fn, res) => function __init() {
4
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
3
+ var __esm = (fn, res, err) => function __init() {
4
+ if (err) throw err[0];
5
+ try {
6
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
7
+ } catch (e) {
8
+ throw err = [e], e;
9
+ }
5
10
  };
6
11
  var __export = (target, all) => {
7
12
  for (var name in all)
@@ -1207,7 +1212,8 @@ var init_app_plugin = __esm({
1207
1212
  "ragPipelines",
1208
1213
  "data",
1209
1214
  "emailTemplates",
1210
- "docs"
1215
+ "docs",
1216
+ "books"
1211
1217
  ];
1212
1218
  const hasAppPayload = APP_CATEGORY_KEYS.some((k) => {
1213
1219
  const v = (bundle && bundle[k]) ?? (sys && sys[k]);
@@ -1860,6 +1866,35 @@ import { getEnv, resolveLocale } from "@objectstack/core";
1860
1866
  import { CoreServiceName } from "@objectstack/spec/system";
1861
1867
  import { pluralToSingular, PLURAL_TO_SINGULAR } from "@objectstack/spec/shared";
1862
1868
 
1869
+ // src/api-exposure.ts
1870
+ var ACTION_TO_API_METHOD = {
1871
+ create: "create",
1872
+ get: "get",
1873
+ update: "update",
1874
+ delete: "delete",
1875
+ query: "list",
1876
+ find: "list",
1877
+ batch: "bulk"
1878
+ };
1879
+ function checkApiExposure(def, action) {
1880
+ if (!def) return { allowed: true };
1881
+ if (def.apiEnabled === false) {
1882
+ return { allowed: false, status: 404, reason: "object is not exposed via the API" };
1883
+ }
1884
+ const whitelist = def.apiMethods;
1885
+ if (Array.isArray(whitelist) && whitelist.length > 0) {
1886
+ const method = ACTION_TO_API_METHOD[action];
1887
+ if (method && !whitelist.includes(method)) {
1888
+ return {
1889
+ allowed: false,
1890
+ status: 405,
1891
+ reason: `API operation '${method}' is not allowed for this object`
1892
+ };
1893
+ }
1894
+ }
1895
+ return { allowed: true };
1896
+ }
1897
+
1863
1898
  // src/security/api-key.ts
1864
1899
  import {
1865
1900
  API_KEY_PREFIX,
@@ -2148,6 +2183,19 @@ var _HttpDispatcher = class _HttpDispatcher {
2148
2183
  * @param scopeId - Optional project ID for scoped service resolution (SharedProjectPlugin mode)
2149
2184
  */
2150
2185
  async callData(action, params, dataDriver, scopeId, executionContext) {
2186
+ if (!executionContext?.isSystem && params?.object) {
2187
+ let def;
2188
+ try {
2189
+ const meta = await this.resolveService("metadata", scopeId);
2190
+ def = await meta?.getObject?.(params.object);
2191
+ } catch {
2192
+ def = void 0;
2193
+ }
2194
+ const gate = checkApiExposure(def, action);
2195
+ if (!gate.allowed) {
2196
+ throw { statusCode: gate.status ?? 403, message: gate.reason ?? "API access denied" };
2197
+ }
2198
+ }
2151
2199
  const protocol = await this.resolveService("protocol", scopeId);
2152
2200
  const qlService = dataDriver ?? await this.getObjectQLService(scopeId);
2153
2201
  const ql = qlService ?? await this.resolveService("objectql", scopeId);