resora 0.2.18 → 1.0.1

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.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  import { copyFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
2
2
  import path, { dirname, join } from "path";
3
+ import { AsyncLocalStorage } from "node:async_hooks";
3
4
  import { createRequire } from "module";
4
5
  import { pathToFileURL } from "url";
5
6
  import { Command } from "@h3ravel/musket";
@@ -253,6 +254,8 @@ const getGlobalCursorMeta = () => {
253
254
  return globalCursorMeta;
254
255
  };
255
256
  let globalRequestUrl;
257
+ let globalCtx;
258
+ const requestContextStore = new AsyncLocalStorage();
256
259
  /**
257
260
  * Sets the current request URL, used as a fallback for pagination link generation
258
261
  * when no explicit path is provided in the pagination data.
@@ -268,7 +271,16 @@ const setRequestUrl = (url) => {
268
271
  * @returns The current request URL, or undefined if not set.
269
272
  */
270
273
  const getRequestUrl = () => {
271
- return globalRequestUrl;
274
+ return requestContextStore.getStore()?.url ?? globalRequestUrl;
275
+ };
276
+ const runWithCtx = (ctx, callback) => {
277
+ return requestContextStore.run({
278
+ ctx,
279
+ url: extractRequestUrl(ctx)
280
+ }, callback);
281
+ };
282
+ const getCtx = () => {
283
+ return requestContextStore.getStore()?.ctx ?? globalCtx;
272
284
  };
273
285
  /**
274
286
  * Extracts the request URL pathname (with query string) from an HTTP context.
@@ -330,6 +342,7 @@ const extractResponseFromCtx = (ctx) => {
330
342
  * @param ctx An HTTP context `{ req, res }`, Express Request, H3 HTTPEvent, or bare request.
331
343
  */
332
344
  const setCtx = (ctx) => {
345
+ globalCtx = ctx;
333
346
  setRequestUrl(extractRequestUrl(ctx));
334
347
  };
335
348
 
@@ -932,12 +945,12 @@ const resolveAndApply = (imported) => {
932
945
  * @returns
933
946
  */
934
947
  const loadRuntimeConfigSync = () => {
935
- const require = createRequire(import.meta.url);
948
+ const req = createRequire(import.meta.url);
936
949
  const syncConfigPaths = [path.join(process.cwd(), "resora.config.cjs")];
937
950
  for (const configPath of syncConfigPaths) {
938
951
  if (!existsSync(configPath)) continue;
939
952
  try {
940
- resolveAndApply(require(configPath));
953
+ resolveAndApply(req(configPath));
941
954
  return true;
942
955
  } catch {
943
956
  continue;
@@ -1159,6 +1172,51 @@ var logo_default = String.raw`
1159
1172
  |_| \_\___||___/\___/|_| \__,_|
1160
1173
  `;
1161
1174
 
1175
+ //#endregion
1176
+ //#region src/plugins.ts
1177
+ const registeredPlugins = /* @__PURE__ */ new Map();
1178
+ const registeredUtilities = /* @__PURE__ */ new Map();
1179
+ const getRegisteredPlugins = () => {
1180
+ return Array.from(registeredPlugins.values());
1181
+ };
1182
+ const registerUtility = (name, utility) => {
1183
+ registeredUtilities.set(name, utility);
1184
+ return utility;
1185
+ };
1186
+ const getUtility = (name) => {
1187
+ return registeredUtilities.get(name);
1188
+ };
1189
+ const pluginApi = {
1190
+ runWithCtx,
1191
+ setCtx,
1192
+ getCtx,
1193
+ registerUtility,
1194
+ getUtility,
1195
+ getRegisteredPlugins
1196
+ };
1197
+ const definePlugin = (plugin) => {
1198
+ return plugin;
1199
+ };
1200
+ const registerPlugin = (plugins) => {
1201
+ for (const plugin of Array.isArray(plugins) ? plugins : [plugins]) {
1202
+ if (registeredPlugins.has(plugin.name)) continue;
1203
+ registeredPlugins.set(plugin.name, plugin);
1204
+ plugin.setup?.(pluginApi);
1205
+ }
1206
+ return getRegisteredPlugins();
1207
+ };
1208
+ const runPluginHook = (hook, event) => {
1209
+ for (const plugin of registeredPlugins.values()) {
1210
+ const handler = plugin[hook];
1211
+ if (typeof handler === "function") handler(event, pluginApi);
1212
+ }
1213
+ return event;
1214
+ };
1215
+ const resetPluginsForTests = () => {
1216
+ registeredPlugins.clear();
1217
+ registeredUtilities.clear();
1218
+ };
1219
+
1162
1220
  //#endregion
1163
1221
  //#region src/ServerResponse.ts
1164
1222
  /**
@@ -1264,14 +1322,38 @@ var ServerResponse = class {
1264
1322
  */
1265
1323
  send(body) {
1266
1324
  if (typeof body !== "undefined") this.body = body;
1325
+ const beforeSend = runPluginHook("beforeSend", {
1326
+ response: this,
1327
+ rawResponse: this.response,
1328
+ body: this.body,
1329
+ status: this._status,
1330
+ headers: { ...this.headers }
1331
+ });
1332
+ this.body = beforeSend.body;
1333
+ this._status = beforeSend.status;
1334
+ this.headers = { ...beforeSend.headers };
1267
1335
  if ("send" in this.response && typeof this.response.send === "function") {
1268
1336
  if ("statusCode" in this.response) this.response.statusCode = this._status;
1269
1337
  const sentResponse = this.response.send(this.body);
1270
1338
  if (sentResponse && "status" in sentResponse && typeof sentResponse.status === "function") sentResponse.status(this._status);
1271
1339
  else if ("status" in this.response && typeof this.response.status === "function") this.response.status(this._status);
1340
+ runPluginHook("afterSend", {
1341
+ response: this,
1342
+ rawResponse: this.response,
1343
+ body: this.body,
1344
+ status: this._status,
1345
+ headers: { ...this.headers }
1346
+ });
1272
1347
  return this.body;
1273
1348
  }
1274
1349
  if ("status" in this.response && typeof this.response.status !== "function") this.response.status = this._status;
1350
+ runPluginHook("afterSend", {
1351
+ response: this,
1352
+ rawResponse: this.response,
1353
+ body: this.body,
1354
+ status: this._status,
1355
+ headers: { ...this.headers }
1356
+ });
1275
1357
  return this.body;
1276
1358
  }
1277
1359
  /**
@@ -1370,6 +1452,63 @@ var BaseSerializer = class {
1370
1452
  return resolveMergeWhen(condition, value);
1371
1453
  }
1372
1454
  /**
1455
+ * Apply registered plugins for the serialization process, allowing plugins to
1456
+ * modify the response body and metadata before the response is sent.
1457
+ *
1458
+ * @param body
1459
+ * @returns
1460
+ */
1461
+ applySerializePlugins(body) {
1462
+ return runPluginHook("afterSerialize", runPluginHook("beforeSerialize", {
1463
+ serializer: this,
1464
+ serializerType: this.getSerializerType(),
1465
+ resource: this.getResourceForMeta(),
1466
+ body
1467
+ })).body;
1468
+ }
1469
+ /**
1470
+ * Apply registered plugins for the response process, allowing plugins to modify the
1471
+ * response body, headers, and status before the response is sent.
1472
+ *
1473
+ * @param input
1474
+ * @returns
1475
+ */
1476
+ applyResponsePlugins(input) {
1477
+ const beforeResponse = runPluginHook("beforeResponse", {
1478
+ serializer: this,
1479
+ serializerType: this.getSerializerType(),
1480
+ rawResponse: input.rawResponse,
1481
+ response: input.response,
1482
+ body: input.body
1483
+ });
1484
+ this.setBody(beforeResponse.body);
1485
+ if (typeof input.response?.setBody === "function") input.response.setBody(beforeResponse.body);
1486
+ const afterResponse = runPluginHook("afterResponse", beforeResponse);
1487
+ this.setBody(afterResponse.body);
1488
+ if (typeof input.response?.setBody === "function") input.response.setBody(afterResponse.body);
1489
+ return afterResponse.body;
1490
+ }
1491
+ /**
1492
+ * Resolve the raw response object from the provided response or the current
1493
+ * context, allowing plugins to access and modify the raw response before it is sent.
1494
+ *
1495
+ * @param response
1496
+ * @returns
1497
+ */
1498
+ resolveRawResponse(response) {
1499
+ if (typeof response !== "undefined") return response;
1500
+ return extractResponseFromCtx(getCtx() ?? this.constructor.ctx);
1501
+ }
1502
+ /**
1503
+ * Dispatch a body to a raw response object when it exposes a send() transport method.
1504
+ *
1505
+ * @param raw
1506
+ * @param body
1507
+ */
1508
+ sendRawResponseBody(raw, body) {
1509
+ if (raw && typeof raw.send === "function") raw.send(body);
1510
+ }
1511
+ /**
1373
1512
  * Add additional metadata to the response. If called without arguments.
1374
1513
  *
1375
1514
  * @param meta
@@ -1417,6 +1556,11 @@ var BaseSerializer = class {
1417
1556
  this.called.withResponse = true;
1418
1557
  input.callWithResponse(response, input.rawResponse);
1419
1558
  if (typeof response?.setBody === "function") response.setBody(input.body());
1559
+ this.applyResponsePlugins({
1560
+ body: input.body(),
1561
+ rawResponse: input.rawResponse,
1562
+ response
1563
+ });
1420
1564
  return response;
1421
1565
  }
1422
1566
  /**
@@ -1441,9 +1585,14 @@ var BaseSerializer = class {
1441
1585
  }
1442
1586
  const resolvedBody = input.body();
1443
1587
  if (typeof response?.setBody === "function") response.setBody(resolvedBody);
1444
- const resolved = Promise.resolve(resolvedBody).then(input.onfulfilled, input.onrejected);
1445
- if (typeof response?.send === "function") response.send(resolvedBody);
1446
- else if (typeof input.rawResponse !== "undefined" && input.sendRawResponse) input.sendRawResponse(input.rawResponse, resolvedBody);
1588
+ const dispatchedBody = this.applyResponsePlugins({
1589
+ body: resolvedBody,
1590
+ rawResponse: input.rawResponse,
1591
+ response
1592
+ });
1593
+ const resolved = Promise.resolve(dispatchedBody).then(input.onfulfilled, input.onrejected);
1594
+ if (typeof response?.send === "function") response.send(dispatchedBody);
1595
+ else if (typeof input.rawResponse !== "undefined" && input.sendRawResponse) input.sendRawResponse(input.rawResponse, dispatchedBody);
1447
1596
  return resolved;
1448
1597
  }
1449
1598
  /**
@@ -1627,6 +1776,9 @@ var GenericResource = class GenericResource extends BaseSerializer {
1627
1776
  getResourceForMeta() {
1628
1777
  return this.resource;
1629
1778
  }
1779
+ getSerializerType() {
1780
+ return "generic";
1781
+ }
1630
1782
  getPayloadKey() {
1631
1783
  const { wrap, rootKey, factory } = this.resolveResponseStructure();
1632
1784
  return factory || !wrap ? void 0 : rootKey;
@@ -1670,6 +1822,7 @@ var GenericResource = class GenericResource extends BaseSerializer {
1670
1822
  ...paginationExtras,
1671
1823
  ...customMeta || {}
1672
1824
  }, rootKey);
1825
+ this.body = this.applySerializePlugins(this.body);
1673
1826
  }
1674
1827
  return this;
1675
1828
  }
@@ -1726,7 +1879,7 @@ var GenericResource = class GenericResource extends BaseSerializer {
1726
1879
  * @returns
1727
1880
  */
1728
1881
  response(res) {
1729
- const rawResponse = res ?? this.res ?? GenericResource.ctx?.res ?? GenericResource.ctx;
1882
+ const rawResponse = this.resolveRawResponse(res ?? this.res);
1730
1883
  return this.runResponse({
1731
1884
  ensureJson: () => this.json(),
1732
1885
  rawResponse,
@@ -1763,7 +1916,7 @@ var GenericResource = class GenericResource extends BaseSerializer {
1763
1916
  return this.runThen({
1764
1917
  ensureJson: () => this.json(),
1765
1918
  body: () => this.body,
1766
- rawResponse: this.res ?? GenericResource.ctx?.res ?? GenericResource.ctx,
1919
+ rawResponse: this.resolveRawResponse(this.res),
1767
1920
  createServerResponse: (raw, body) => {
1768
1921
  const response = new ServerResponse(raw, body);
1769
1922
  this.withResponseContext = {
@@ -1776,7 +1929,7 @@ var GenericResource = class GenericResource extends BaseSerializer {
1776
1929
  this.withResponse(response, raw);
1777
1930
  },
1778
1931
  sendRawResponse: (raw, body) => {
1779
- raw.send(body);
1932
+ this.sendRawResponseBody(raw, body);
1780
1933
  },
1781
1934
  onfulfilled,
1782
1935
  onrejected
@@ -1792,7 +1945,7 @@ var GenericResource = class GenericResource extends BaseSerializer {
1792
1945
  return this.runThen({
1793
1946
  ensureJson: () => this.json(),
1794
1947
  body: () => this.body,
1795
- rawResponse: this.res ?? GenericResource.ctx?.res ?? GenericResource.ctx,
1948
+ rawResponse: this.resolveRawResponse(this.res),
1796
1949
  createServerResponse: (raw, body) => {
1797
1950
  const response = new ServerResponse(raw, body);
1798
1951
  this.withResponseContext = {
@@ -1805,7 +1958,7 @@ var GenericResource = class GenericResource extends BaseSerializer {
1805
1958
  this.withResponse(response, raw);
1806
1959
  },
1807
1960
  sendRawResponse: (raw, body) => {
1808
- raw.send(body);
1961
+ this.sendRawResponseBody(raw, body);
1809
1962
  },
1810
1963
  onrejected
1811
1964
  });
@@ -1820,7 +1973,7 @@ var GenericResource = class GenericResource extends BaseSerializer {
1820
1973
  return this.runThen({
1821
1974
  ensureJson: () => this.json(),
1822
1975
  body: () => this.body,
1823
- rawResponse: this.res ?? GenericResource.ctx?.res ?? GenericResource.ctx,
1976
+ rawResponse: this.resolveRawResponse(this.res),
1824
1977
  createServerResponse: (raw, body) => {
1825
1978
  const response = new ServerResponse(raw, body);
1826
1979
  this.withResponseContext = {
@@ -1833,7 +1986,7 @@ var GenericResource = class GenericResource extends BaseSerializer {
1833
1986
  this.withResponse(response, raw);
1834
1987
  },
1835
1988
  sendRawResponse: (raw, body) => {
1836
- raw.send(body);
1989
+ this.sendRawResponseBody(raw, body);
1837
1990
  },
1838
1991
  onfulfilled: onfinally,
1839
1992
  onrejected: onfinally
@@ -1942,6 +2095,9 @@ var ResourceCollection = class ResourceCollection extends BaseSerializer {
1942
2095
  getResourceForMeta() {
1943
2096
  return this.resource;
1944
2097
  }
2098
+ getSerializerType() {
2099
+ return "collection";
2100
+ }
1945
2101
  /**
1946
2102
  * Get the appropriate key for the response payload based on the current response
1947
2103
  * structure configuration.
@@ -1991,6 +2147,7 @@ var ResourceCollection = class ResourceCollection extends BaseSerializer {
1991
2147
  ...paginationExtras,
1992
2148
  ...customMeta || {}
1993
2149
  }, rootKey);
2150
+ this.body = this.applySerializePlugins(this.body);
1994
2151
  }
1995
2152
  return this;
1996
2153
  }
@@ -2041,7 +2198,7 @@ var ResourceCollection = class ResourceCollection extends BaseSerializer {
2041
2198
  * @returns
2042
2199
  */
2043
2200
  response(res) {
2044
- const rawResponse = res ?? this.res ?? ResourceCollection.ctx?.res ?? ResourceCollection.ctx;
2201
+ const rawResponse = this.resolveRawResponse(res ?? this.res);
2045
2202
  return this.runResponse({
2046
2203
  ensureJson: () => this.json(),
2047
2204
  rawResponse,
@@ -2074,15 +2231,15 @@ var ResourceCollection = class ResourceCollection extends BaseSerializer {
2074
2231
  /**
2075
2232
  * Promise-like then method to allow chaining with async/await or .then() syntax
2076
2233
  *
2077
- * @param onfulfilled Callback to handle the fulfilled state of the promise, receiving the response body
2078
- * @param onrejected Callback to handle the rejected state of the promise, receiving the error reason
2234
+ * @param onfulfilled Callback to handle the fulfilled state of the promise
2235
+ * @param onrejected Callback to handle the rejected state of the promise
2079
2236
  * @returns A promise that resolves to the result of the onfulfilled or onrejected callback
2080
2237
  */
2081
2238
  then(onfulfilled, onrejected) {
2082
2239
  return this.runThen({
2083
2240
  ensureJson: () => this.json(),
2084
2241
  body: () => this.body,
2085
- rawResponse: this.res ?? ResourceCollection.ctx?.res ?? ResourceCollection.ctx,
2242
+ rawResponse: this.resolveRawResponse(this.res),
2086
2243
  createServerResponse: (raw, body) => {
2087
2244
  const response = new ServerResponse(raw, body);
2088
2245
  this.withResponseContext = {
@@ -2095,7 +2252,7 @@ var ResourceCollection = class ResourceCollection extends BaseSerializer {
2095
2252
  this.withResponse(response, raw);
2096
2253
  },
2097
2254
  sendRawResponse: (raw, body) => {
2098
- raw.send(body);
2255
+ this.sendRawResponseBody(raw, body);
2099
2256
  },
2100
2257
  onfulfilled,
2101
2258
  onrejected
@@ -2111,7 +2268,7 @@ var ResourceCollection = class ResourceCollection extends BaseSerializer {
2111
2268
  return this.runThen({
2112
2269
  ensureJson: () => this.json(),
2113
2270
  body: () => this.body,
2114
- rawResponse: this.res ?? ResourceCollection.ctx?.res ?? ResourceCollection.ctx,
2271
+ rawResponse: this.resolveRawResponse(this.res),
2115
2272
  createServerResponse: (raw, body) => {
2116
2273
  const response = new ServerResponse(raw, body);
2117
2274
  this.withResponseContext = {
@@ -2124,7 +2281,7 @@ var ResourceCollection = class ResourceCollection extends BaseSerializer {
2124
2281
  this.withResponse(response, raw);
2125
2282
  },
2126
2283
  sendRawResponse: (raw, body) => {
2127
- raw.send(body);
2284
+ this.sendRawResponseBody(raw, body);
2128
2285
  },
2129
2286
  onrejected
2130
2287
  });
@@ -2139,7 +2296,7 @@ var ResourceCollection = class ResourceCollection extends BaseSerializer {
2139
2296
  return this.runThen({
2140
2297
  ensureJson: () => this.json(),
2141
2298
  body: () => this.body,
2142
- rawResponse: this.res ?? ResourceCollection.ctx?.res ?? ResourceCollection.ctx,
2299
+ rawResponse: this.resolveRawResponse(this.res),
2143
2300
  createServerResponse: (raw, body) => {
2144
2301
  const response = new ServerResponse(raw, body);
2145
2302
  this.withResponseContext = {
@@ -2152,7 +2309,7 @@ var ResourceCollection = class ResourceCollection extends BaseSerializer {
2152
2309
  this.withResponse(response, raw);
2153
2310
  },
2154
2311
  sendRawResponse: (raw, body) => {
2155
- raw.send(body);
2312
+ this.sendRawResponseBody(raw, body);
2156
2313
  },
2157
2314
  onfulfilled: onfinally,
2158
2315
  onrejected: onfinally
@@ -2255,6 +2412,9 @@ var Resource = class Resource extends BaseSerializer {
2255
2412
  getResourceForMeta() {
2256
2413
  return this.resource;
2257
2414
  }
2415
+ getSerializerType() {
2416
+ return "resource";
2417
+ }
2258
2418
  getPayloadKey() {
2259
2419
  const { wrap, rootKey, factory } = this.resolveResponseStructure();
2260
2420
  return factory || !wrap ? void 0 : rootKey;
@@ -2288,6 +2448,7 @@ var Resource = class Resource extends BaseSerializer {
2288
2448
  }
2289
2449
  });
2290
2450
  this.body = appendRootProperties(this.body, customMeta, rootKey);
2451
+ this.body = this.applySerializePlugins(this.body);
2291
2452
  }
2292
2453
  return this;
2293
2454
  }
@@ -2341,7 +2502,7 @@ var Resource = class Resource extends BaseSerializer {
2341
2502
  * @returns
2342
2503
  */
2343
2504
  response(res) {
2344
- const rawResponse = res ?? this.res ?? Resource.ctx?.res ?? Resource.ctx;
2505
+ const rawResponse = this.resolveRawResponse(res ?? this.res);
2345
2506
  return this.runResponse({
2346
2507
  ensureJson: () => this.json(),
2347
2508
  rawResponse,
@@ -2378,7 +2539,7 @@ var Resource = class Resource extends BaseSerializer {
2378
2539
  return this.runThen({
2379
2540
  ensureJson: () => this.json(),
2380
2541
  body: () => this.body,
2381
- rawResponse: this.res ?? Resource.ctx?.res ?? Resource.ctx,
2542
+ rawResponse: this.resolveRawResponse(this.res),
2382
2543
  createServerResponse: (raw, body) => {
2383
2544
  const response = new ServerResponse(raw, body);
2384
2545
  this.withResponseContext = {
@@ -2391,7 +2552,7 @@ var Resource = class Resource extends BaseSerializer {
2391
2552
  this.withResponse(response, raw);
2392
2553
  },
2393
2554
  sendRawResponse: (raw, body) => {
2394
- raw.send(body);
2555
+ this.sendRawResponseBody(raw, body);
2395
2556
  },
2396
2557
  onfulfilled,
2397
2558
  onrejected
@@ -2407,7 +2568,7 @@ var Resource = class Resource extends BaseSerializer {
2407
2568
  return this.runThen({
2408
2569
  ensureJson: () => this.json(),
2409
2570
  body: () => this.body,
2410
- rawResponse: this.res ?? Resource.ctx?.res ?? Resource.ctx,
2571
+ rawResponse: this.resolveRawResponse(this.res),
2411
2572
  createServerResponse: (raw, body) => {
2412
2573
  const response = new ServerResponse(raw, body);
2413
2574
  this.withResponseContext = {
@@ -2420,7 +2581,7 @@ var Resource = class Resource extends BaseSerializer {
2420
2581
  this.withResponse(response, raw);
2421
2582
  },
2422
2583
  sendRawResponse: (raw, body) => {
2423
- raw.send(body);
2584
+ this.sendRawResponseBody(raw, body);
2424
2585
  },
2425
2586
  onrejected
2426
2587
  });
@@ -2435,7 +2596,7 @@ var Resource = class Resource extends BaseSerializer {
2435
2596
  return this.runThen({
2436
2597
  ensureJson: () => this.json(),
2437
2598
  body: () => this.body,
2438
- rawResponse: this.res ?? Resource.ctx?.res ?? Resource.ctx,
2599
+ rawResponse: this.resolveRawResponse(this.res),
2439
2600
  createServerResponse: (raw, body) => {
2440
2601
  const response = new ServerResponse(raw, body);
2441
2602
  this.withResponseContext = {
@@ -2448,7 +2609,7 @@ var Resource = class Resource extends BaseSerializer {
2448
2609
  this.withResponse(response, raw);
2449
2610
  },
2450
2611
  sendRawResponse: (raw, body) => {
2451
- raw.send(body);
2612
+ this.sendRawResponseBody(raw, body);
2452
2613
  },
2453
2614
  onfulfilled: onfinally,
2454
2615
  onrejected: onfinally
@@ -2457,4 +2618,4 @@ var Resource = class Resource extends BaseSerializer {
2457
2618
  };
2458
2619
 
2459
2620
  //#endregion
2460
- export { ApiResource, CONDITIONAL_ATTRIBUTE_MISSING, CliApp, GenericResource, InitCommand, MakeResource, Resource, ResourceCollection, ServerResponse, appendRootProperties, applyRuntimeConfig, buildPaginationExtras, buildResponseEnvelope, createArkormCurrentPageResolver, defineConfig, extractRequestUrl, extractResponseFromCtx, getCaseTransformer, getDefaultConfig, getGlobalBaseUrl, getGlobalCase, getGlobalCursorMeta, getGlobalPageName, getGlobalPaginatedExtras, getGlobalPaginatedLinks, getGlobalPaginatedMeta, getGlobalResponseFactory, getGlobalResponseRootKey, getGlobalResponseStructure, getGlobalResponseWrap, getPaginationExtraKeys, getRequestUrl, hasPaginationLink, isArkormLikeCollection, isArkormLikeModel, isPlainObject, loadRuntimeConfig, mergeMetadata, normalizeSerializableData, resetRuntimeConfigForTests, resolveCurrentPage, resolveMergeWhen, resolveWhen, resolveWhenNotNull, resolveWithHookMetadata, sanitizeConditionalAttributes, setCtx, setGlobalBaseUrl, setGlobalCase, setGlobalCursorMeta, setGlobalPageName, setGlobalPaginatedExtras, setGlobalPaginatedLinks, setGlobalPaginatedMeta, setGlobalResponseFactory, setGlobalResponseRootKey, setGlobalResponseStructure, setGlobalResponseWrap, setRequestUrl, splitWords, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, transformKeys };
2621
+ export { ApiResource, CONDITIONAL_ATTRIBUTE_MISSING, CliApp, GenericResource, InitCommand, MakeResource, Resource, ResourceCollection, ServerResponse, appendRootProperties, applyRuntimeConfig, buildPaginationExtras, buildResponseEnvelope, createArkormCurrentPageResolver, defineConfig, definePlugin, extractRequestUrl, extractResponseFromCtx, getCaseTransformer, getCtx, getDefaultConfig, getGlobalBaseUrl, getGlobalCase, getGlobalCursorMeta, getGlobalPageName, getGlobalPaginatedExtras, getGlobalPaginatedLinks, getGlobalPaginatedMeta, getGlobalResponseFactory, getGlobalResponseRootKey, getGlobalResponseStructure, getGlobalResponseWrap, getPaginationExtraKeys, getRegisteredPlugins, getRequestUrl, getUtility, hasPaginationLink, isArkormLikeCollection, isArkormLikeModel, isPlainObject, loadRuntimeConfig, mergeMetadata, normalizeSerializableData, registerPlugin, registerUtility, resetPluginsForTests, resetRuntimeConfigForTests, resolveCurrentPage, resolveMergeWhen, resolveWhen, resolveWhenNotNull, resolveWithHookMetadata, runPluginHook, runWithCtx, sanitizeConditionalAttributes, setCtx, setGlobalBaseUrl, setGlobalCase, setGlobalCursorMeta, setGlobalPageName, setGlobalPaginatedExtras, setGlobalPaginatedLinks, setGlobalPaginatedMeta, setGlobalResponseFactory, setGlobalResponseRootKey, setGlobalResponseStructure, setGlobalResponseWrap, setRequestUrl, splitWords, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, transformKeys };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "resora",
3
- "version": "0.2.18",
3
+ "version": "1.0.1",
4
4
  "description": "A structured API response layer for Node.js and TypeScript with automatic JSON responses, collection support, and pagination handling.",
5
5
  "keywords": [
6
6
  "api",
@@ -76,12 +76,15 @@
76
76
  "scripts": {
77
77
  "cmd": "tsx src/cli/index.ts",
78
78
  "lint": "eslint",
79
- "test": "pnpm vitest",
79
+ "test": "pnpm vitest --run",
80
+ "test:watch": "pnpm vitest --watch",
80
81
  "test:coverage": "pnpm vitest --coverage --watch=false",
81
82
  "build": "pnpm tsdown",
82
83
  "barrel": "barrelize",
83
84
  "docs:dev": "vitepress dev docs",
84
85
  "docs:build": "vitepress build docs",
85
- "docs:preview": "vitepress preview docs"
86
+ "docs:preview": "vitepress preview docs",
87
+ "version:packages": "pnpm -r --filter \"@resora/*\" version:patch && git add . && git commit -m \"chore: bump package versions\"",
88
+ "publish:packages": "pnpm version:packages && pnpm -r --filter \"@arkstack/*\" publish --access public"
86
89
  }
87
90
  }