@palbase/backend 22.1.0 → 23.1.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.
Files changed (81) hide show
  1. package/dist/bin/palbase-backend.cjs +750 -40
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +5 -5
  4. package/dist/{chunk-YL4C5NRY.js → chunk-HQRJDARQ.js} +2 -2
  5. package/dist/{chunk-74XDEF5J.js → chunk-M5MCBWJI.js} +723 -37
  6. package/dist/chunk-M5MCBWJI.js.map +1 -0
  7. package/dist/{chunk-W5ODXPY3.js → chunk-NS5V43YQ.js} +14 -1
  8. package/dist/chunk-NS5V43YQ.js.map +1 -0
  9. package/dist/{chunk-SQC5EIWY.js → chunk-OHALWEOG.js} +19 -9
  10. package/dist/chunk-OHALWEOG.js.map +1 -0
  11. package/dist/{chunk-I3ON7MYF.js → chunk-PY7YJDCT.js} +129 -18
  12. package/dist/chunk-PY7YJDCT.js.map +1 -0
  13. package/dist/{chunk-N32VDWKH.js → chunk-R3KN6RHD.js} +4 -59
  14. package/dist/chunk-R3KN6RHD.js.map +1 -0
  15. package/dist/{chunk-QMVK4X3V.js → chunk-RCLNBJCM.js} +98 -98
  16. package/dist/chunk-RCLNBJCM.js.map +1 -0
  17. package/dist/db/env.cjs.map +1 -1
  18. package/dist/db/env.d.cts +3 -21
  19. package/dist/db/env.d.ts +3 -21
  20. package/dist/db/index.cjs +140 -16
  21. package/dist/db/index.cjs.map +1 -1
  22. package/dist/db/index.d.cts +3 -2
  23. package/dist/db/index.d.ts +3 -2
  24. package/dist/db/index.js +2 -2
  25. package/dist/{endpoint-BVT6jcVW.d.cts → endpoint-CVWXh6oG.d.ts} +147 -15
  26. package/dist/{endpoint-BVT6jcVW.d.ts → endpoint-c9h5jriX.d.cts} +147 -15
  27. package/dist/engine/index.cjs +750 -40
  28. package/dist/engine/index.cjs.map +1 -1
  29. package/dist/engine/index.d.cts +6 -5
  30. package/dist/engine/index.d.ts +6 -5
  31. package/dist/engine/index.js +4 -4
  32. package/dist/{index-BS1gW4nV.d.cts → index-BZrJXnVh.d.ts} +142 -72
  33. package/dist/{index-BqCiHao8.d.cts → index-By8Dle5U.d.cts} +196 -21
  34. package/dist/{index-vwHoS0l2.d.ts → index-CwAJ7HEe.d.ts} +196 -21
  35. package/dist/{index-CCZqzych.d.ts → index-CxeQSfJP.d.cts} +142 -72
  36. package/dist/index.cjs +388 -1101
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d.cts +89 -1134
  39. package/dist/index.d.ts +89 -1134
  40. package/dist/index.js +133 -902
  41. package/dist/index.js.map +1 -1
  42. package/dist/openapi/index.cjs +32 -61
  43. package/dist/openapi/index.cjs.map +1 -1
  44. package/dist/openapi/index.d.cts +6 -2
  45. package/dist/openapi/index.d.ts +6 -2
  46. package/dist/openapi/index.js +34 -26
  47. package/dist/openapi/index.js.map +1 -1
  48. package/dist/{registry-Bsuf-orT.d.ts → registry-B3niOVYp.d.ts} +108 -170
  49. package/dist/{registry-BWttGlaT.d.cts → registry-CqPK2Qby.d.cts} +108 -170
  50. package/dist/{purchases/keys.cjs → stack.cjs} +4 -4
  51. package/dist/stack.cjs.map +1 -0
  52. package/dist/stack.d.cts +76 -0
  53. package/dist/stack.d.ts +76 -0
  54. package/dist/stack.js +1 -0
  55. package/dist/test/index.cjs +482 -9
  56. package/dist/test/index.cjs.map +1 -1
  57. package/dist/test/index.d.cts +35 -3
  58. package/dist/test/index.d.ts +35 -3
  59. package/dist/test/index.js +480 -8
  60. package/dist/test/index.js.map +1 -1
  61. package/docs/README.md +7 -6
  62. package/docs/llms-full.txt +7 -260
  63. package/docs/llms.txt +0 -2
  64. package/package.json +9 -8
  65. package/stager/return_types.js +23 -0
  66. package/template/package.json +1 -1
  67. package/dist/chunk-74XDEF5J.js.map +0 -1
  68. package/dist/chunk-I3ON7MYF.js.map +0 -1
  69. package/dist/chunk-N32VDWKH.js.map +0 -1
  70. package/dist/chunk-QMVK4X3V.js.map +0 -1
  71. package/dist/chunk-SQC5EIWY.js.map +0 -1
  72. package/dist/chunk-W5ODXPY3.js.map +0 -1
  73. package/dist/purchases/keys.cjs.map +0 -1
  74. package/dist/purchases/keys.d.cts +0 -42
  75. package/dist/purchases/keys.d.ts +0 -42
  76. package/dist/purchases/keys.js +0 -1
  77. package/docs/config.md +0 -147
  78. package/docs/resources.md +0 -97
  79. package/template/config/secrets.ts +0 -24
  80. /package/dist/{chunk-YL4C5NRY.js.map → chunk-HQRJDARQ.js.map} +0 -0
  81. /package/dist/{purchases/keys.js.map → stack.js.map} +0 -0
@@ -5857,27 +5857,7 @@ var BUILTIN_DATA_SCHEMAS = {
5857
5857
  bad_request: import_zod.z.object({
5858
5858
  fields: import_zod.z.array(import_zod.z.object({ field: import_zod.z.string(), message: import_zod.z.string() }))
5859
5859
  }),
5860
- too_many_requests: import_zod.z.object({ retryAfter: import_zod.z.number().int() }),
5861
- // Purchases (@RequireEntitlement / @Spend). Their payloads are what make a
5862
- // paywall renderable on the client: WHICH entitlement was missing, and for a
5863
- // spend the real ceiling and reset time rather than a guessed retry delay.
5864
- entitlement_required: import_zod.z.object({ entitlement: import_zod.z.string().nullable() }),
5865
- quota_exceeded: import_zod.z.object({
5866
- key: import_zod.z.string(),
5867
- scope: import_zod.z.string(),
5868
- window: import_zod.z.string(),
5869
- used: import_zod.z.number().int(),
5870
- reserved: import_zod.z.number().int(),
5871
- max: import_zod.z.number().int(),
5872
- remaining: import_zod.z.number().int(),
5873
- resetAt: import_zod.z.string()
5874
- }),
5875
- credit_insufficient: import_zod.z.object({
5876
- key: import_zod.z.string(),
5877
- balance: import_zod.z.number().int(),
5878
- reserved: import_zod.z.number().int(),
5879
- remaining: import_zod.z.number().int()
5880
- })
5860
+ too_many_requests: import_zod.z.object({ retryAfter: import_zod.z.number().int() })
5881
5861
  };
5882
5862
  function getErrorRegistry() {
5883
5863
  const g = globalThis;
@@ -5889,13 +5869,7 @@ function getErrorRegistry() {
5889
5869
  ["forbidden", 403, "Forbidden"],
5890
5870
  ["not_found", 404, "NotFound"],
5891
5871
  ["conflict", 409, "Conflict"],
5892
- ["too_many_requests", 429, "TooManyRequests"],
5893
- // Thrown by the purchases decorators, so they are pre-seeded like the
5894
- // other built-ins: a project never declares them, but every gated or
5895
- // metered route must surface them as TYPED errors on the client.
5896
- ["entitlement_required", 403, "EntitlementRequired"],
5897
- ["quota_exceeded", 429, "QuotaExceeded"],
5898
- ["credit_insufficient", 429, "CreditInsufficient"]
5872
+ ["too_many_requests", 429, "TooManyRequests"]
5899
5873
  ]) {
5900
5874
  const dataSchema = BUILTIN_DATA_SCHEMAS[code];
5901
5875
  m.set(code, {
@@ -5994,32 +5968,6 @@ function resolveController(ctor) {
5994
5968
  return meta;
5995
5969
  }
5996
5970
 
5997
- // src/purchases/registry.ts
5998
- var ENTITLEMENTS = /* @__PURE__ */ Symbol.for("palbase.backend.purchases.entitlements");
5999
- var SPENDS = /* @__PURE__ */ Symbol.for("palbase.backend.purchases.spends");
6000
- function carrierOf2(target) {
6001
- return typeof target === "function" ? target : target.constructor ?? target;
6002
- }
6003
- function entitlementFor(ctor, fnName) {
6004
- return carrierOf2(ctor)[ENTITLEMENTS]?.[fnName];
6005
- }
6006
- function spendFor(ctor, fnName) {
6007
- return carrierOf2(ctor)[SPENDS]?.[fnName];
6008
- }
6009
-
6010
- // src/purchases/openapi.ts
6011
- function purchaseThrows(ctor, fnName) {
6012
- const out = [];
6013
- if (entitlementFor(ctor, fnName) !== void 0) {
6014
- out.push({ name: "EntitlementRequired", code: "entitlement_required" });
6015
- }
6016
- if (spendFor(ctor, fnName) !== void 0) {
6017
- out.push({ name: "QuotaExceeded", code: "quota_exceeded" });
6018
- out.push({ name: "CreditInsufficient", code: "credit_insufficient" });
6019
- }
6020
- return out;
6021
- }
6022
-
6023
5971
  // src/openapi/discover.ts
6024
5972
  function capitalizeSegment(s) {
6025
5973
  if (s.length === 0) return s;
@@ -6066,6 +6014,20 @@ function flattenController(controller) {
6066
6014
  const meta = resolveController(controller);
6067
6015
  const controllerName = deriveControllerName(controller.name);
6068
6016
  const routes = getRoutes(controller);
6017
+ const kindsByMethod = /* @__PURE__ */ new Map();
6018
+ for (const route of routes) {
6019
+ const seen = kindsByMethod.get(route.fnName) ?? { sse: false, upload: false };
6020
+ if (route.options.sseConfig !== void 0) seen.sse = true;
6021
+ if (route.options.uploadConfig !== void 0) seen.upload = true;
6022
+ kindsByMethod.set(route.fnName, seen);
6023
+ }
6024
+ for (const [fnName, seen] of kindsByMethod) {
6025
+ if (seen.sse && seen.upload) {
6026
+ throw new Error(
6027
+ `${controller.name}.${fnName} declares BOTH @Sse and @Upload. One method cannot be both a streaming response and an upload completion handler \u2014 the two describe the same handler twice and the second one read silently wins. Split them into two methods.`
6028
+ );
6029
+ }
6030
+ }
6069
6031
  const out = [];
6070
6032
  for (const route of routes) {
6071
6033
  const fullPath = joinControllerPath(meta.basePath, route.subpath);
@@ -6090,11 +6052,9 @@ function flattenController(controller) {
6090
6052
  break;
6091
6053
  }
6092
6054
  }
6093
- const purchases = purchaseThrows(controller, route.fnName);
6094
6055
  const seen = new Set((route.throws ?? []).map((t) => t.code));
6095
6056
  const allThrows = [
6096
- ...route.throws ?? [],
6097
- ...purchases.filter((t) => !seen.has(t.code))
6057
+ ...route.throws ?? []
6098
6058
  ];
6099
6059
  out.push({
6100
6060
  method: route.method,
@@ -6108,7 +6068,8 @@ function flattenController(controller) {
6108
6068
  ...route.returnSchema !== void 0 ? { returnSchema: route.returnSchema } : {},
6109
6069
  ...route.options.rateLimit !== void 0 ? { rateLimit: route.options.rateLimit } : {},
6110
6070
  ...allThrows.length > 0 ? { throws: allThrows } : {},
6111
- ...route.options.uploadConfig !== void 0 ? { uploadConfig: route.options.uploadConfig } : {}
6071
+ ...route.options.uploadConfig !== void 0 ? { uploadConfig: route.options.uploadConfig } : {},
6072
+ ...route.options.sseConfig !== void 0 ? { sseConfig: route.options.sseConfig } : {}
6112
6073
  });
6113
6074
  }
6114
6075
  return out;
@@ -6206,7 +6167,8 @@ function registerControllerRoute(registry, route) {
6206
6167
  returnSchema: route.returnSchema,
6207
6168
  effectiveAuth: route.effectiveAuth,
6208
6169
  throws: route.throws,
6209
- ...route.uploadConfig !== void 0 ? { uploadConfig: route.uploadConfig } : {}
6170
+ ...route.uploadConfig !== void 0 ? { uploadConfig: route.uploadConfig } : {},
6171
+ ...route.sseConfig !== void 0 ? { sseConfig: route.sseConfig } : {}
6210
6172
  });
6211
6173
  }
6212
6174
  function registerOperation(registry, op) {
@@ -6227,7 +6189,11 @@ function registerOperation(registry, op) {
6227
6189
  description: "Success",
6228
6190
  content: {
6229
6191
  "application/json": {
6230
- schema: op.returnSchema !== void 0 ? op.returnSchema : import_zod2.z.unknown()
6192
+ // A streaming operation's response is ONE FRAME, and its schema is the
6193
+ // declared frame — not the handler's return type, which is void. Without
6194
+ // this the document describes an untyped response and every generated
6195
+ // client is opaque (measured live: the contract gate refuses the deploy).
6196
+ schema: op.sseConfig !== void 0 ? op.sseConfig.frame : op.returnSchema !== void 0 ? op.returnSchema : import_zod2.z.unknown()
6231
6197
  }
6232
6198
  }
6233
6199
  },
@@ -6274,7 +6240,12 @@ function registerOperation(registry, op) {
6274
6240
  bucket: op.uploadConfig.bucket,
6275
6241
  pathTemplate: op.uploadConfig.pathTemplate
6276
6242
  }
6277
- } : {}
6243
+ } : {},
6244
+ // Without this extension the document describes a streaming route as a
6245
+ // plain POST, and every client generated from it reads the body ONCE
6246
+ // instead of iterating frames — a generated client that compiles, runs and
6247
+ // is simply wrong. Same failure class as the upload extension above.
6248
+ ...op.sseConfig !== void 0 ? { "x-palbase-sse": {} } : {}
6278
6249
  });
6279
6250
  }
6280
6251
  function resolveThrows(throws) {