@palbase/backend 6.0.0 → 8.0.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 CHANGED
@@ -52,6 +52,7 @@ __export(src_exports, {
52
52
  Query: () => Query,
53
53
  Queue: () => Queue,
54
54
  RESERVED_SECRET_PREFIX: () => RESERVED_SECRET_PREFIX,
55
+ Realtime: () => Realtime,
55
56
  Req: () => Req,
56
57
  RequestId: () => RequestId,
57
58
  Resource: () => Resource,
@@ -72,6 +73,7 @@ __export(src_exports, {
72
73
  boolean: () => boolean,
73
74
  bucket: () => bucket,
74
75
  buildProvider: () => buildProvider,
76
+ defineError: () => defineError,
75
77
  defineFlags: () => defineFlags,
76
78
  defineJob: () => defineJob,
77
79
  defineMiddleware: () => defineMiddleware,
@@ -83,6 +85,7 @@ __export(src_exports, {
83
85
  documents: () => documents,
84
86
  enumType: () => enumType,
85
87
  flag: () => flag,
88
+ getErrorRegistry: () => getErrorRegistry,
86
89
  integer: () => integer,
87
90
  isPalbaseExtension: () => isPalbaseExtension,
88
91
  jsonb: () => jsonb,
@@ -90,12 +93,13 @@ __export(src_exports, {
90
93
  makeTypedDB: () => makeTypedDB,
91
94
  parseFileSizeLimit: () => parseFileSizeLimit,
92
95
  policy: () => policy,
96
+ recordThrows: () => recordThrows,
93
97
  reservedSecretKey: () => reservedSecretKey,
94
98
  storage: () => storage,
95
99
  text: () => text,
96
100
  timestamp: () => timestamp,
97
101
  uuid: () => uuid,
98
- z: () => import_zod.z
102
+ z: () => import_zod2.z
99
103
  });
100
104
  module.exports = __toCommonJS(src_exports);
101
105
 
@@ -211,6 +215,7 @@ var Flags = Object.assign(
211
215
  }
212
216
  }
213
217
  );
218
+ var Realtime = makeServiceProxy("Realtime");
214
219
 
215
220
  // src/db/policy.ts
216
221
  var PolicyBuilder = class {
@@ -800,6 +805,7 @@ function Controller(basePath, options = {}) {
800
805
  var ROUTES = /* @__PURE__ */ Symbol.for("palbase.backend.routes");
801
806
  var PARAM_BUFFER = /* @__PURE__ */ Symbol.for("palbase.backend.paramBuffer");
802
807
  var RETURN_BUFFER = /* @__PURE__ */ Symbol.for("palbase.backend.returnBuffer");
808
+ var THROWS_BUFFER = /* @__PURE__ */ Symbol.for("palbase.backend.throwsBuffer");
803
809
  function carrierOf(target) {
804
810
  const ctor = typeof target === "function" ? target : target.constructor ?? target;
805
811
  return ctor;
@@ -826,6 +832,10 @@ function recordRoute(target, fnName, method, subpath, options) {
826
832
  if (returnBuffer && returnBuffer[fnName] !== void 0) {
827
833
  route.returnSchema = returnBuffer[fnName];
828
834
  }
835
+ const throwsBuffer = carrier[THROWS_BUFFER];
836
+ if (throwsBuffer && throwsBuffer[fnName] !== void 0) {
837
+ route.throws = throwsBuffer[fnName];
838
+ }
829
839
  routes.push(route);
830
840
  }
831
841
  function recordParam(target, fnName, meta) {
@@ -841,6 +851,20 @@ function recordParam(target, fnName, meta) {
841
851
  }
842
852
  }
843
853
  }
854
+ function recordThrows(target, fnName, throws) {
855
+ const carrier = carrierOf(target);
856
+ const routes = carrier[ROUTES];
857
+ const route = routes?.find((r) => r.fnName === fnName);
858
+ if (route) {
859
+ route.throws = throws;
860
+ return;
861
+ }
862
+ if (!Object.prototype.hasOwnProperty.call(carrier, THROWS_BUFFER)) {
863
+ carrier[THROWS_BUFFER] = {};
864
+ }
865
+ const throwsBuffer = carrier[THROWS_BUFFER];
866
+ if (throwsBuffer) throwsBuffer[fnName] = throws;
867
+ }
844
868
 
845
869
  // src/decorators/methods.ts
846
870
  function makeMethodDecorator(method) {
@@ -957,8 +981,8 @@ function defaultMessage(name) {
957
981
  return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
958
982
  }
959
983
  var BadRequest = class extends NamedHttpError {
960
- constructor(message, code, data) {
961
- super(400, "bad_request", "BadRequest", message, code, data);
984
+ constructor(data, message) {
985
+ super(400, "bad_request", "BadRequest", message, void 0, data);
962
986
  }
963
987
  };
964
988
  var Unauthorized = class extends NamedHttpError {
@@ -982,11 +1006,115 @@ var Conflict = class extends NamedHttpError {
982
1006
  }
983
1007
  };
984
1008
  var TooManyRequests = class extends NamedHttpError {
985
- constructor(message, code, data) {
986
- super(429, "too_many_requests", "TooManyRequests", message, code, data);
1009
+ constructor(data, message) {
1010
+ super(429, "too_many_requests", "TooManyRequests", message, void 0, data);
987
1011
  }
988
1012
  };
989
1013
 
1014
+ // src/error-registry.ts
1015
+ var import_zod_to_openapi = require("@asteasolutions/zod-to-openapi");
1016
+ var import_zod = require("zod");
1017
+ (0, import_zod_to_openapi.extendZodWithOpenApi)(import_zod.z);
1018
+ var ERROR_REGISTRY = /* @__PURE__ */ Symbol.for("palbase.backend.errorRegistry");
1019
+ var BUILTIN_DATA_SCHEMAS = {
1020
+ bad_request: import_zod.z.object({
1021
+ fields: import_zod.z.array(import_zod.z.object({ field: import_zod.z.string(), message: import_zod.z.string() }))
1022
+ }),
1023
+ too_many_requests: import_zod.z.object({ retryAfter: import_zod.z.number().int() })
1024
+ };
1025
+ function getErrorRegistry() {
1026
+ const g = globalThis;
1027
+ if (!g[ERROR_REGISTRY]) {
1028
+ const m = /* @__PURE__ */ new Map();
1029
+ for (const [code, status, className] of [
1030
+ ["bad_request", 400, "BadRequest"],
1031
+ ["unauthorized", 401, "Unauthorized"],
1032
+ ["forbidden", 403, "Forbidden"],
1033
+ ["not_found", 404, "NotFound"],
1034
+ ["conflict", 409, "Conflict"],
1035
+ ["too_many_requests", 429, "TooManyRequests"]
1036
+ ]) {
1037
+ const dataSchema = BUILTIN_DATA_SCHEMAS[code];
1038
+ m.set(code, {
1039
+ code,
1040
+ status,
1041
+ className,
1042
+ builtin: true,
1043
+ ...dataSchema ? { dataSchema, dataDigest: digestOf(code, dataSchema) } : {}
1044
+ });
1045
+ }
1046
+ g[ERROR_REGISTRY] = m;
1047
+ }
1048
+ return g[ERROR_REGISTRY];
1049
+ }
1050
+ function defineError(code, status, dataSchema) {
1051
+ if (!Number.isInteger(status) || status < 400 || status > 599) {
1052
+ throw new Error(
1053
+ `defineError: status for "${code}" must be a 4xx/5xx integer, got ${status} \u2014 error responses must not clobber success responses in the project spec.`
1054
+ );
1055
+ }
1056
+ const registry2 = getErrorRegistry();
1057
+ const existing = registry2.get(code);
1058
+ const className = defaultClassName(code);
1059
+ const dataDigest = dataSchema ? digestOf(code, dataSchema) : void 0;
1060
+ if (existing) {
1061
+ const sameShape = existing.status === status && !existing.builtin && existing.dataDigest === dataDigest;
1062
+ if (!sameShape) {
1063
+ throw new Error(
1064
+ `defineError: duplicate error code "${code}" with a different shape (existing: status ${existing.status}${existing.builtin ? ", built-in" : ""}${existing.status === status && !existing.builtin ? ", different data schema" : ""}). Error codes are project-unique.`
1065
+ );
1066
+ }
1067
+ }
1068
+ const makeWithData = (schema) => class extends HttpError {
1069
+ static code = code;
1070
+ static status = status;
1071
+ constructor(data, message) {
1072
+ super(status, code, message ?? humanize(code), schema.parse(data));
1073
+ this.name = className;
1074
+ }
1075
+ };
1076
+ const makeWithoutData = () => class extends HttpError {
1077
+ static code = code;
1078
+ static status = status;
1079
+ constructor(message) {
1080
+ super(status, code, message ?? humanize(code));
1081
+ this.name = className;
1082
+ }
1083
+ };
1084
+ const cls = dataSchema ? makeWithData(dataSchema) : makeWithoutData();
1085
+ Object.defineProperty(cls, "name", { value: className });
1086
+ registry2.set(code, {
1087
+ code,
1088
+ status,
1089
+ className,
1090
+ builtin: false,
1091
+ ...dataSchema ? { dataSchema } : {},
1092
+ ...dataDigest !== void 0 ? { dataDigest } : {}
1093
+ });
1094
+ return cls;
1095
+ }
1096
+ function digestOf(code, dataSchema) {
1097
+ const TMP_REF = "__PalbaseErrorDataDigest";
1098
+ const tmpRegistry = new import_zod_to_openapi.OpenAPIRegistry();
1099
+ tmpRegistry.register(TMP_REF, import_zod.z.object({ data: dataSchema }).openapi(TMP_REF));
1100
+ const generated = new import_zod_to_openapi.OpenApiGeneratorV31(tmpRegistry.definitions).generateComponents();
1101
+ const out = generated.components?.schemas?.[TMP_REF];
1102
+ const digest = JSON.stringify(out ?? null);
1103
+ if (digest.includes('"$ref"')) {
1104
+ throw new Error(
1105
+ `defineError: dataSchema for "${code}" carries .openapi(refId) metadata \u2014 it would emit dangling $ref pointers in the project spec. Use a plain zod schema (z.object({...})) without .openapi(...).`
1106
+ );
1107
+ }
1108
+ return digest;
1109
+ }
1110
+ function defaultClassName(code) {
1111
+ return code.split("_").map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("");
1112
+ }
1113
+ function humanize(code) {
1114
+ const s = code.replace(/_/g, " ");
1115
+ return s.charAt(0).toUpperCase() + s.slice(1);
1116
+ }
1117
+
990
1118
  // src/worker.ts
991
1119
  var VALID_WORKER_NAME = /^[a-zA-Z0-9_-]+$/;
992
1120
  var WORKER_DEFAULTS = {
@@ -1285,7 +1413,7 @@ var documents = {
1285
1413
  };
1286
1414
 
1287
1415
  // src/index.ts
1288
- var import_zod = require("zod");
1416
+ var import_zod2 = require("zod");
1289
1417
  // Annotate the CommonJS export names for ESM import in node:
1290
1418
  0 && (module.exports = {
1291
1419
  BadRequest,
@@ -1320,6 +1448,7 @@ var import_zod = require("zod");
1320
1448
  Query,
1321
1449
  Queue,
1322
1450
  RESERVED_SECRET_PREFIX,
1451
+ Realtime,
1323
1452
  Req,
1324
1453
  RequestId,
1325
1454
  Resource,
@@ -1340,6 +1469,7 @@ var import_zod = require("zod");
1340
1469
  boolean,
1341
1470
  bucket,
1342
1471
  buildProvider,
1472
+ defineError,
1343
1473
  defineFlags,
1344
1474
  defineJob,
1345
1475
  defineMiddleware,
@@ -1351,6 +1481,7 @@ var import_zod = require("zod");
1351
1481
  documents,
1352
1482
  enumType,
1353
1483
  flag,
1484
+ getErrorRegistry,
1354
1485
  integer,
1355
1486
  isPalbaseExtension,
1356
1487
  jsonb,
@@ -1358,6 +1489,7 @@ var import_zod = require("zod");
1358
1489
  makeTypedDB,
1359
1490
  parseFileSizeLimit,
1360
1491
  policy,
1492
+ recordThrows,
1361
1493
  reservedSecretKey,
1362
1494
  storage,
1363
1495
  text,