@palbase/backend 10.3.0 → 12.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/chunk-7LAXRLPG.js +418 -0
- package/dist/chunk-7LAXRLPG.js.map +1 -0
- package/dist/{chunk-4WOQWFUP.js → chunk-LUV36KQU.js} +26 -11
- package/dist/{chunk-4WOQWFUP.js.map → chunk-LUV36KQU.js.map} +1 -1
- package/dist/{chunk-2PCNZBNZ.js → chunk-XATG7BRC.js} +20 -2
- package/dist/chunk-XATG7BRC.js.map +1 -0
- package/dist/db/index.cjs +438 -10
- package/dist/db/index.cjs.map +1 -1
- package/dist/db/index.d.cts +2 -2
- package/dist/db/index.d.ts +2 -2
- package/dist/db/index.js +13 -1
- package/dist/{endpoint-92kVepng.d.cts → endpoint-Ck4hER_7.d.cts} +343 -11
- package/dist/{endpoint-92kVepng.d.ts → endpoint-Ck4hER_7.d.ts} +343 -11
- package/dist/{index-BaHs33jr.d.cts → index-BJAf1uPC.d.cts} +64 -34
- package/dist/{index-DfryIw9U.d.ts → index-l7DhBDtn.d.ts} +64 -34
- package/dist/index.cjs +589 -124
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +60 -162
- package/dist/index.d.ts +60 -162
- package/dist/index.js +139 -108
- package/dist/index.js.map +1 -1
- package/dist/test/index.cjs +545 -12
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +1 -1
- package/dist/test/index.d.ts +1 -1
- package/dist/test/index.js +153 -12
- package/dist/test/index.js.map +1 -1
- package/docs/background.md +8 -9
- package/docs/database.md +106 -16
- package/docs/events.md +20 -17
- package/docs/llms-full.txt +141 -47
- package/docs/schema.md +6 -4
- package/package.json +1 -1
- package/dist/chunk-2PCNZBNZ.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -37,10 +37,12 @@ __export(src_exports, {
|
|
|
37
37
|
Get: () => Get,
|
|
38
38
|
Headers: () => Headers,
|
|
39
39
|
HttpError: () => HttpError,
|
|
40
|
+
Job: () => Job,
|
|
40
41
|
Log: () => Log,
|
|
41
42
|
NOTIFICATIONS_CONFIG_KIND: () => NOTIFICATIONS_CONFIG_KIND,
|
|
42
43
|
NotFound: () => NotFound,
|
|
43
44
|
Notifications: () => Notifications,
|
|
45
|
+
On: () => On,
|
|
44
46
|
OptionalUser: () => OptionalUser,
|
|
45
47
|
PALBASE_EXTENSIONS: () => PALBASE_EXTENSIONS,
|
|
46
48
|
PROVIDER_CATALOG: () => PROVIDER_CATALOG,
|
|
@@ -66,10 +68,13 @@ __export(src_exports, {
|
|
|
66
68
|
TEST_USERS_CONFIG_KIND: () => TEST_USERS_CONFIG_KIND,
|
|
67
69
|
TooManyRequests: () => TooManyRequests,
|
|
68
70
|
TraceId: () => TraceId,
|
|
71
|
+
TxPlanError: () => TxPlanError,
|
|
72
|
+
TxRefError: () => TxRefError,
|
|
69
73
|
Unauthorized: () => Unauthorized,
|
|
70
74
|
Upload: () => Upload,
|
|
71
75
|
UploadedObject: () => UploadedObject,
|
|
72
76
|
User: () => User,
|
|
77
|
+
Webhook: () => Webhook,
|
|
73
78
|
__getRuntime: () => __getRuntime,
|
|
74
79
|
__registerResource: () => __registerResource,
|
|
75
80
|
__requestALS: () => __requestALS,
|
|
@@ -82,29 +87,32 @@ __export(src_exports, {
|
|
|
82
87
|
boolean: () => boolean,
|
|
83
88
|
bucket: () => bucket,
|
|
84
89
|
buildProvider: () => buildProvider,
|
|
90
|
+
dec: () => dec,
|
|
85
91
|
defineEgress: () => defineEgress,
|
|
86
92
|
defineError: () => defineError,
|
|
87
93
|
defineFlags: () => defineFlags,
|
|
88
|
-
defineJob: () => defineJob,
|
|
89
94
|
defineMiddleware: () => defineMiddleware,
|
|
90
95
|
defineNotifications: () => defineNotifications,
|
|
91
96
|
defineSchema: () => defineSchema,
|
|
92
97
|
defineStorage: () => defineStorage,
|
|
93
98
|
defineTestUsers: () => defineTestUsers,
|
|
94
|
-
defineWebhook: () => defineWebhook,
|
|
95
99
|
defineWorker: () => defineWorker,
|
|
96
100
|
documents: () => documents,
|
|
97
101
|
entitlementFor: () => entitlementFor,
|
|
98
102
|
enumType: () => enumType,
|
|
99
103
|
flag: () => flag,
|
|
100
104
|
getErrorRegistry: () => getErrorRegistry,
|
|
105
|
+
getJobConfig: () => getJobConfig,
|
|
101
106
|
getRoutes: () => getRoutes,
|
|
107
|
+
getWebhookConfig: () => getWebhookConfig,
|
|
108
|
+
inc: () => inc,
|
|
102
109
|
integer: () => integer,
|
|
103
110
|
isPalbaseExtension: () => isPalbaseExtension,
|
|
104
111
|
jsonb: () => jsonb,
|
|
105
112
|
makeEnvDts: () => makeEnvDts,
|
|
106
113
|
makePurchasesDts: () => makePurchasesDts,
|
|
107
114
|
makeTypedDB: () => makeTypedDB,
|
|
115
|
+
now: () => now,
|
|
108
116
|
numeric: () => numeric,
|
|
109
117
|
parseFileSizeLimit: () => parseFileSizeLimit,
|
|
110
118
|
policy: () => policy,
|
|
@@ -124,6 +132,416 @@ module.exports = __toCommonJS(src_exports);
|
|
|
124
132
|
|
|
125
133
|
// src/runtime.ts
|
|
126
134
|
var import_node_async_hooks = require("async_hooks");
|
|
135
|
+
|
|
136
|
+
// src/db/tx-plan.ts
|
|
137
|
+
var TxRefError = class extends Error {
|
|
138
|
+
constructor(message) {
|
|
139
|
+
super(message);
|
|
140
|
+
this.name = "TxRefError";
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
var TxPlanError = class extends Error {
|
|
144
|
+
constructor(message) {
|
|
145
|
+
super(message);
|
|
146
|
+
this.name = "TxPlanError";
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
var EXPR = /* @__PURE__ */ Symbol.for("palbase.tx.expr");
|
|
150
|
+
var REF = /* @__PURE__ */ Symbol.for("palbase.tx.ref");
|
|
151
|
+
var ROW = /* @__PURE__ */ Symbol.for("palbase.tx.row");
|
|
152
|
+
var ROWS = /* @__PURE__ */ Symbol.for("palbase.tx.rows");
|
|
153
|
+
var TRAPPED_PROPS = [
|
|
154
|
+
"then",
|
|
155
|
+
"valueOf",
|
|
156
|
+
"toString",
|
|
157
|
+
"toJSON",
|
|
158
|
+
Symbol.toPrimitive
|
|
159
|
+
];
|
|
160
|
+
function trap(prop, what, hint) {
|
|
161
|
+
const name = typeof prop === "symbol" ? prop.description ?? String(prop) : prop;
|
|
162
|
+
throw new TxRefError(
|
|
163
|
+
`${what} was used as a value (via \`${name}\`). Nothing in a transaction callback has run yet, so there is no value to read. ${hint}`
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
function now() {
|
|
167
|
+
return makeExpr({ fn: "now" });
|
|
168
|
+
}
|
|
169
|
+
function inc(by) {
|
|
170
|
+
assertFiniteNumber(by, "inc");
|
|
171
|
+
return makeExpr({ fn: "inc", by });
|
|
172
|
+
}
|
|
173
|
+
function dec(by) {
|
|
174
|
+
assertFiniteNumber(by, "dec");
|
|
175
|
+
return makeExpr({ fn: "dec", by });
|
|
176
|
+
}
|
|
177
|
+
function assertFiniteNumber(by, fn) {
|
|
178
|
+
if (typeof by !== "number" || !Number.isFinite(by)) {
|
|
179
|
+
throw new TxPlanError(`${fn}() needs a finite number, got ${String(by)}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function makeExpr(expr) {
|
|
183
|
+
return new Proxy(
|
|
184
|
+
{ [EXPR]: expr },
|
|
185
|
+
{
|
|
186
|
+
get(target, prop) {
|
|
187
|
+
if (prop === EXPR) return target[EXPR];
|
|
188
|
+
if (TRAPPED_PROPS.includes(prop)) {
|
|
189
|
+
trap(prop, "A plan expression", "Write it into an operation instead.");
|
|
190
|
+
}
|
|
191
|
+
return void 0;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
function makeRef(op, field) {
|
|
197
|
+
const target = { [REF]: { op, field } };
|
|
198
|
+
return new Proxy(target, {
|
|
199
|
+
get(t, prop) {
|
|
200
|
+
if (prop === REF) return t[REF];
|
|
201
|
+
if (TRAPPED_PROPS.includes(prop)) {
|
|
202
|
+
trap(
|
|
203
|
+
prop,
|
|
204
|
+
`\`${field}\` of a row this transaction has not written yet`,
|
|
205
|
+
"Pass it to another operation in the same plan, or return it from the callback and read it after `transaction()` resolves."
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
return void 0;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
function makeRowHandle(op) {
|
|
213
|
+
const target = { [ROW]: op };
|
|
214
|
+
return new Proxy(target, {
|
|
215
|
+
get(t, prop) {
|
|
216
|
+
if (prop === ROW) return t[ROW];
|
|
217
|
+
if (TRAPPED_PROPS.includes(prop)) {
|
|
218
|
+
trap(
|
|
219
|
+
prop,
|
|
220
|
+
"A row this transaction has not written yet",
|
|
221
|
+
"Read one of its columns to reference it, or return the row from the callback and read it after `transaction()` resolves."
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
if (typeof prop === "symbol") return void 0;
|
|
225
|
+
return makeRef(op, prop);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function refDescriptor(v) {
|
|
230
|
+
if (typeof v !== "object" || v === null) return null;
|
|
231
|
+
const d = v[REF];
|
|
232
|
+
return isRefDescriptor(d) ? d : null;
|
|
233
|
+
}
|
|
234
|
+
function isRefDescriptor(d) {
|
|
235
|
+
return typeof d === "object" && d !== null && typeof d.op === "number" && typeof d.field === "string";
|
|
236
|
+
}
|
|
237
|
+
function rowOpIndex(v) {
|
|
238
|
+
if (typeof v !== "object" || v === null) return null;
|
|
239
|
+
const op = v[ROW];
|
|
240
|
+
return typeof op === "number" ? op : null;
|
|
241
|
+
}
|
|
242
|
+
function exprOf(v) {
|
|
243
|
+
if (typeof v !== "object" || v === null) return null;
|
|
244
|
+
const e = v[EXPR];
|
|
245
|
+
return typeof e === "object" && e !== null ? e : null;
|
|
246
|
+
}
|
|
247
|
+
function isRowsHandle(v) {
|
|
248
|
+
return typeof v === "object" && v !== null && v[ROWS] !== void 0;
|
|
249
|
+
}
|
|
250
|
+
function encodeValue(value, column, allowColumnExpr) {
|
|
251
|
+
const ref = refDescriptor(value);
|
|
252
|
+
if (ref) return { $ref: { op: ref.op, field: ref.field } };
|
|
253
|
+
const expr = exprOf(value);
|
|
254
|
+
if (expr) {
|
|
255
|
+
if (expr.fn !== "now" && !allowColumnExpr) {
|
|
256
|
+
throw new TxPlanError(
|
|
257
|
+
`\`${column}\`: ${expr.fn}() reads the column's current value, so it is only valid in updateWhere(where, set).`
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
return { $expr: expr };
|
|
261
|
+
}
|
|
262
|
+
if (rowOpIndex(value) !== null) {
|
|
263
|
+
throw new TxPlanError(
|
|
264
|
+
`\`${column}\`: a row handle is not a value. Read the column you meant (e.g. \`row.id\`).`
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
if (isRowsHandle(value)) {
|
|
268
|
+
throw new TxPlanError(
|
|
269
|
+
`\`${column}\`: an operation result is not a value. Declare an expectation first (\`.expectOne(err)\`) and read a column from the row.`
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
assertNoNestedHandles(value, column);
|
|
273
|
+
return value;
|
|
274
|
+
}
|
|
275
|
+
function assertNoNestedHandles(value, column) {
|
|
276
|
+
if (typeof value !== "object" || value === null) return;
|
|
277
|
+
if (value instanceof Date) return;
|
|
278
|
+
if (refDescriptor(value) || exprOf(value) || rowOpIndex(value) !== null || isRowsHandle(value)) {
|
|
279
|
+
throw new TxPlanError(
|
|
280
|
+
`\`${column}\`: a plan handle is nested inside a value. The server would store it as literal JSON, not resolve it. Put the reference directly in the column.`
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
if (Array.isArray(value)) {
|
|
284
|
+
for (const item of value) assertNoNestedHandles(item, column);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
for (const item of Object.values(value)) {
|
|
288
|
+
assertNoNestedHandles(item, column);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function encodeMap(map, allowColumnExpr) {
|
|
292
|
+
const out = {};
|
|
293
|
+
for (const key of Object.keys(map).sort()) {
|
|
294
|
+
const value = map[key];
|
|
295
|
+
if (value === void 0) continue;
|
|
296
|
+
out[key] = encodeValue(value, key, allowColumnExpr);
|
|
297
|
+
}
|
|
298
|
+
return out;
|
|
299
|
+
}
|
|
300
|
+
var SKIPPED_OP = -1;
|
|
301
|
+
var TxRowsImpl = class {
|
|
302
|
+
constructor(builder, opIndex, what) {
|
|
303
|
+
this.builder = builder;
|
|
304
|
+
this.opIndex = opIndex;
|
|
305
|
+
this.what = what;
|
|
306
|
+
}
|
|
307
|
+
builder;
|
|
308
|
+
opIndex;
|
|
309
|
+
what;
|
|
310
|
+
// Present so `isRowsHandle` recognises the object; never read for its value.
|
|
311
|
+
[ROWS] = true;
|
|
312
|
+
guarded = false;
|
|
313
|
+
// The type-level `await` guard made real: TS rejects `await rows` at compile
|
|
314
|
+
// time, and reaching this means someone called `.then(...)` by hand.
|
|
315
|
+
then() {
|
|
316
|
+
throw new TxRefError(
|
|
317
|
+
`${this.what} cannot be awaited: a transaction callback builds a plan, it does not run statements. Remove the \`await\`.`
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
expectOne(error) {
|
|
321
|
+
this.declareGuard("one", 1, error);
|
|
322
|
+
if (this.opIndex === SKIPPED_OP) throw error;
|
|
323
|
+
return makeRowHandle(this.opIndex);
|
|
324
|
+
}
|
|
325
|
+
expectNone(error) {
|
|
326
|
+
this.declareGuard("none", 0, error);
|
|
327
|
+
}
|
|
328
|
+
expectAtLeast(n, error) {
|
|
329
|
+
assertGuardCount(n, "expectAtLeast");
|
|
330
|
+
this.declareGuard("atLeast", n, error);
|
|
331
|
+
if (this.opIndex === SKIPPED_OP && n > 0) throw error;
|
|
332
|
+
}
|
|
333
|
+
expectAtMost(n, error) {
|
|
334
|
+
assertGuardCount(n, "expectAtMost");
|
|
335
|
+
this.declareGuard("atMost", n, error);
|
|
336
|
+
}
|
|
337
|
+
declareGuard(kind, n, error) {
|
|
338
|
+
if (!(error instanceof Error)) {
|
|
339
|
+
throw new TxPlanError(
|
|
340
|
+
`${this.what}: an expectation needs the Error to throw when it does not hold (e.g. \`.expect\u2026(new Conflict("already accepted"))\`).`
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
if (this.guarded) {
|
|
344
|
+
throw new TxPlanError(
|
|
345
|
+
`${this.what} already has an expectation. One operation carries one expectation; declare the second one on its own operation.`
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
this.guarded = true;
|
|
349
|
+
if (this.opIndex === SKIPPED_OP) return;
|
|
350
|
+
this.builder.attachGuard(this.opIndex, kind, n, error);
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
function assertGuardCount(n, fn) {
|
|
354
|
+
if (!Number.isInteger(n) || n < 0) {
|
|
355
|
+
throw new TxPlanError(`${fn}(n) needs a non-negative integer, got ${String(n)}`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
var MAX_OPS = 1e3;
|
|
359
|
+
var MAX_ROWS = 5e3;
|
|
360
|
+
var TxPlanBuilder = class {
|
|
361
|
+
ops = [];
|
|
362
|
+
/** Errors handed to expectations, indexed by the `slot` the server echoes. */
|
|
363
|
+
slots = [];
|
|
364
|
+
/** The table surface handed to the callback. Untyped here; the public
|
|
365
|
+
* `transaction()` signatures put the schema types on top. */
|
|
366
|
+
table(name) {
|
|
367
|
+
return {
|
|
368
|
+
insert: (values) => {
|
|
369
|
+
const encoded = encodeMap(values, false);
|
|
370
|
+
if (Object.keys(encoded).length === 0) {
|
|
371
|
+
throw new TxPlanError(`${name}.insert() needs at least one column`);
|
|
372
|
+
}
|
|
373
|
+
return this.push({ op: "insert", table: name, values: encoded }, `${name}.insert()`);
|
|
374
|
+
},
|
|
375
|
+
insertMany: (rows) => {
|
|
376
|
+
if (rows.length === 0) {
|
|
377
|
+
return new TxRowsImpl(this, SKIPPED_OP, `${name}.insertMany()`);
|
|
378
|
+
}
|
|
379
|
+
if (rows.length > MAX_ROWS) {
|
|
380
|
+
throw new TxPlanError(
|
|
381
|
+
`${name}.insertMany() has ${rows.length} rows; the limit is ${MAX_ROWS}. Split the write across requests.`
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
const encoded = rows.map((row) => encodeMap(row, false));
|
|
385
|
+
assertUniformRows(encoded, name);
|
|
386
|
+
return this.push({ op: "insertMany", table: name, rows: encoded }, `${name}.insertMany()`);
|
|
387
|
+
},
|
|
388
|
+
updateWhere: (where, set) => {
|
|
389
|
+
const encodedWhere = encodeMap(where, false);
|
|
390
|
+
const encodedSet = encodeMap(set, true);
|
|
391
|
+
if (Object.keys(encodedWhere).length === 0) {
|
|
392
|
+
throw new TxPlanError(
|
|
393
|
+
`${name}.updateWhere() needs a filter. An update with no filter rewrites the whole table.`
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
if (Object.keys(encodedSet).length === 0) {
|
|
397
|
+
throw new TxPlanError(`${name}.updateWhere() needs at least one column to set`);
|
|
398
|
+
}
|
|
399
|
+
return this.push(
|
|
400
|
+
{ op: "update", table: name, set: encodedSet, where: encodedWhere },
|
|
401
|
+
`${name}.updateWhere()`
|
|
402
|
+
);
|
|
403
|
+
},
|
|
404
|
+
deleteWhere: (where) => {
|
|
405
|
+
const encodedWhere = encodeMap(where, false);
|
|
406
|
+
if (Object.keys(encodedWhere).length === 0) {
|
|
407
|
+
throw new TxPlanError(
|
|
408
|
+
`${name}.deleteWhere() needs a filter. A delete with no filter empties the table.`
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
return this.push(
|
|
412
|
+
{ op: "delete", table: name, where: encodedWhere },
|
|
413
|
+
`${name}.deleteWhere()`
|
|
414
|
+
);
|
|
415
|
+
},
|
|
416
|
+
select: (where, options) => {
|
|
417
|
+
const op = { op: "select", table: name };
|
|
418
|
+
const encodedWhere = encodeMap(where ?? {}, false);
|
|
419
|
+
if (Object.keys(encodedWhere).length > 0) op.where = encodedWhere;
|
|
420
|
+
if (options?.limit !== void 0) {
|
|
421
|
+
if (!Number.isInteger(options.limit) || options.limit < 0) {
|
|
422
|
+
throw new TxPlanError(
|
|
423
|
+
`${name}.select(): limit needs a non-negative integer, got ${String(options.limit)}`
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
op.limit = options.limit;
|
|
427
|
+
}
|
|
428
|
+
if (options?.lock !== void 0) op.lock = options.lock;
|
|
429
|
+
return this.push(op, `${name}.select()`);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
push(op, what) {
|
|
434
|
+
if (this.ops.length >= MAX_OPS) {
|
|
435
|
+
throw new TxPlanError(
|
|
436
|
+
`this transaction has ${MAX_OPS} operations, which is the limit. Use insertMany() for bulk writes, or split the work across requests.`
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
const index = this.ops.length;
|
|
440
|
+
this.ops.push(op);
|
|
441
|
+
return new TxRowsImpl(this, index, what);
|
|
442
|
+
}
|
|
443
|
+
/** Attach an expectation to an op and record its error in the slot table. */
|
|
444
|
+
attachGuard(opIndex, kind, n, error) {
|
|
445
|
+
const op = this.ops[opIndex];
|
|
446
|
+
if (!op) throw new TxPlanError(`internal: expectation on unknown operation ${opIndex}`);
|
|
447
|
+
const slot = this.slots.length;
|
|
448
|
+
this.slots.push(error);
|
|
449
|
+
op.guard = { kind, n, slot };
|
|
450
|
+
}
|
|
451
|
+
/** The serialisable plan. Empty when the callback described no writes. */
|
|
452
|
+
body() {
|
|
453
|
+
return { ops: this.ops };
|
|
454
|
+
}
|
|
455
|
+
/** The error the server's `slot` selects, or `null` when it names one this
|
|
456
|
+
* plan never declared (a server/client disagreement, not a tenant error). */
|
|
457
|
+
errorForSlot(slot) {
|
|
458
|
+
return this.slots[slot] ?? null;
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
function assertUniformRows(rows, table) {
|
|
462
|
+
const first = rows[0];
|
|
463
|
+
if (!first) return;
|
|
464
|
+
const want = Object.keys(first);
|
|
465
|
+
const wantKey = want.join(",");
|
|
466
|
+
for (let i = 1; i < rows.length; i++) {
|
|
467
|
+
const got = Object.keys(rows[i]);
|
|
468
|
+
if (got.join(",") !== wantKey) {
|
|
469
|
+
throw new TxPlanError(
|
|
470
|
+
`${table}.insertMany(): every row must set the same columns. Row 0 sets [${want.join(", ")}] but row ${i} sets [${got.join(", ")}]. (A property set to \`undefined\` counts as absent \u2014 use \`null\`.)`
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
function materializeResult(value, results) {
|
|
476
|
+
const ref = refDescriptor(value);
|
|
477
|
+
if (ref) {
|
|
478
|
+
const row = rowOf(results, ref.op, `\`${ref.field}\``);
|
|
479
|
+
if (!(ref.field in row)) {
|
|
480
|
+
throw new TxPlanError(
|
|
481
|
+
`the transaction's operation ${ref.op} returned no column \`${ref.field}\`.`
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
return row[ref.field];
|
|
485
|
+
}
|
|
486
|
+
const rowOp = rowOpIndex(value);
|
|
487
|
+
if (rowOp !== null) return rowOf(results, rowOp, "a row");
|
|
488
|
+
if (isRowsHandle(value)) {
|
|
489
|
+
throw new TxPlanError(
|
|
490
|
+
"an operation result cannot be returned from a transaction callback: its row count is not known until the plan runs. Declare an expectation (`.expectOne(err)`) and return the row, or a column of it."
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
if (Array.isArray(value)) return value.map((item) => materializeResult(item, results));
|
|
494
|
+
if (isPlainObject(value)) {
|
|
495
|
+
const out = {};
|
|
496
|
+
for (const [key, item] of Object.entries(value)) out[key] = materializeResult(item, results);
|
|
497
|
+
return out;
|
|
498
|
+
}
|
|
499
|
+
return value;
|
|
500
|
+
}
|
|
501
|
+
function rowOf(results, opIndex, what) {
|
|
502
|
+
const result = results[opIndex];
|
|
503
|
+
if (!result) {
|
|
504
|
+
throw new TxPlanError(
|
|
505
|
+
`the transaction returned no result for operation ${opIndex}, so ${what} cannot be read.`
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
const row = result.rows[0];
|
|
509
|
+
if (!row) {
|
|
510
|
+
throw new TxPlanError(
|
|
511
|
+
`the transaction's operation ${opIndex} returned no row, so ${what} cannot be read.`
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
return row;
|
|
515
|
+
}
|
|
516
|
+
function isPlainObject(value) {
|
|
517
|
+
if (typeof value !== "object" || value === null) return false;
|
|
518
|
+
const proto = Object.getPrototypeOf(value);
|
|
519
|
+
return proto === Object.prototype || proto === null;
|
|
520
|
+
}
|
|
521
|
+
async function runTxPlan(transport, tables, builder, fn) {
|
|
522
|
+
const returned = fn({ tables });
|
|
523
|
+
const body = builder.body();
|
|
524
|
+
if (body.ops.length === 0) {
|
|
525
|
+
return materializeResult(returned, []);
|
|
526
|
+
}
|
|
527
|
+
let response;
|
|
528
|
+
try {
|
|
529
|
+
response = await transport.txPlan(body);
|
|
530
|
+
} catch (err) {
|
|
531
|
+
throw translateRejection(err, builder);
|
|
532
|
+
}
|
|
533
|
+
return materializeResult(returned, response.results);
|
|
534
|
+
}
|
|
535
|
+
function translateRejection(err, builder) {
|
|
536
|
+
if (typeof err !== "object" || err === null) return err;
|
|
537
|
+
const rejection = err;
|
|
538
|
+
if (rejection.error_code !== "tx_guard_failed" || typeof rejection.slot !== "number") {
|
|
539
|
+
return err;
|
|
540
|
+
}
|
|
541
|
+
return builder.errorForSlot(rejection.slot) ?? err;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// src/runtime.ts
|
|
127
545
|
var __requestALS = new import_node_async_hooks.AsyncLocalStorage();
|
|
128
546
|
var runtime = null;
|
|
129
547
|
function __setRuntime(services) {
|
|
@@ -184,10 +602,23 @@ function makeTypedSurface(raw2) {
|
|
|
184
602
|
return Object.assign(ops, {
|
|
185
603
|
tables: makeTablesAccessor(() => raw2),
|
|
186
604
|
transaction(fn) {
|
|
187
|
-
|
|
605
|
+
const builder = new TxPlanBuilder();
|
|
606
|
+
return runTxPlan(raw2, makeTxTablesAccessor(builder), builder, fn);
|
|
188
607
|
}
|
|
189
608
|
});
|
|
190
609
|
}
|
|
610
|
+
function makeTxTablesAccessor(builder) {
|
|
611
|
+
const tablesProxy = new Proxy(
|
|
612
|
+
{},
|
|
613
|
+
{
|
|
614
|
+
get(_t, prop) {
|
|
615
|
+
if (typeof prop !== "string") return void 0;
|
|
616
|
+
return builder.table(prop);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
);
|
|
620
|
+
return tablesProxy;
|
|
621
|
+
}
|
|
191
622
|
var Database = Object.assign(makeTypedSurface(rawDatabase), {
|
|
192
623
|
/**
|
|
193
624
|
* Lazily resolve the runtime's service-role sibling on each call. We do NOT
|
|
@@ -782,19 +1213,29 @@ function makeTypedTable(name, raw2) {
|
|
|
782
1213
|
};
|
|
783
1214
|
}
|
|
784
1215
|
function makeTypedDB(schema, raw2) {
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
tables[key] = makeTypedTable(tableDef.name, client);
|
|
791
|
-
}
|
|
1216
|
+
const tables = {};
|
|
1217
|
+
for (const key of Object.keys(schema.tables)) {
|
|
1218
|
+
const tableDef = schema.tables[key];
|
|
1219
|
+
if (tableDef !== void 0) {
|
|
1220
|
+
tables[key] = makeTypedTable(tableDef.name, raw2);
|
|
792
1221
|
}
|
|
793
|
-
return tables;
|
|
794
1222
|
}
|
|
795
1223
|
const result = {
|
|
796
|
-
tables
|
|
797
|
-
transaction
|
|
1224
|
+
tables,
|
|
1225
|
+
transaction(fn) {
|
|
1226
|
+
const builder = new TxPlanBuilder();
|
|
1227
|
+
const planTables = {};
|
|
1228
|
+
for (const key of Object.keys(schema.tables)) {
|
|
1229
|
+
const tableDef = schema.tables[key];
|
|
1230
|
+
if (tableDef !== void 0) planTables[key] = builder.table(tableDef.name);
|
|
1231
|
+
}
|
|
1232
|
+
return runTxPlan(
|
|
1233
|
+
raw2,
|
|
1234
|
+
planTables,
|
|
1235
|
+
builder,
|
|
1236
|
+
fn
|
|
1237
|
+
);
|
|
1238
|
+
}
|
|
798
1239
|
};
|
|
799
1240
|
return result;
|
|
800
1241
|
}
|
|
@@ -1133,12 +1574,12 @@ var E164_RE = /^\+[1-9]\d{1,14}$/;
|
|
|
1133
1574
|
var OTP_LENGTH = 6;
|
|
1134
1575
|
var OTP_RE = /^\d{6}$/;
|
|
1135
1576
|
var MIN_PASSWORD_LENGTH = 8;
|
|
1136
|
-
function
|
|
1577
|
+
function isPlainObject2(value) {
|
|
1137
1578
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1138
1579
|
}
|
|
1139
1580
|
function normalizeSeed(seed, userName) {
|
|
1140
1581
|
if (seed === void 0) return {};
|
|
1141
|
-
if (!
|
|
1582
|
+
if (!isPlainObject2(seed)) {
|
|
1142
1583
|
throw new Error(`testUser ${JSON.stringify(userName)}: seed must be { <table>: [ {...} ] }`);
|
|
1143
1584
|
}
|
|
1144
1585
|
const out = {};
|
|
@@ -1154,7 +1595,7 @@ function normalizeSeed(seed, userName) {
|
|
|
1154
1595
|
);
|
|
1155
1596
|
}
|
|
1156
1597
|
for (const row of rows) {
|
|
1157
|
-
if (!
|
|
1598
|
+
if (!isPlainObject2(row)) {
|
|
1158
1599
|
throw new Error(
|
|
1159
1600
|
`testUser ${JSON.stringify(userName)}: every row in seed.${table} must be an object`
|
|
1160
1601
|
);
|
|
@@ -1165,7 +1606,7 @@ function normalizeSeed(seed, userName) {
|
|
|
1165
1606
|
return out;
|
|
1166
1607
|
}
|
|
1167
1608
|
function testUser(opts = {}) {
|
|
1168
|
-
if (!
|
|
1609
|
+
if (!isPlainObject2(opts)) {
|
|
1169
1610
|
throw new Error("testUser() expects { email?, password?, phone?, otp?, seed? }");
|
|
1170
1611
|
}
|
|
1171
1612
|
const hasEmail = opts.email !== void 0;
|
|
@@ -1215,7 +1656,7 @@ function testUser(opts = {}) {
|
|
|
1215
1656
|
return { email, password, phone, otp, seed: normalizeSeed(opts.seed, email ?? "<template>") };
|
|
1216
1657
|
}
|
|
1217
1658
|
function defineTestUsers(input) {
|
|
1218
|
-
if (!
|
|
1659
|
+
if (!isPlainObject2(input) || !isPlainObject2(input.users)) {
|
|
1219
1660
|
throw new Error("defineTestUsers expects { users: { <name>: testUser({...}) } }");
|
|
1220
1661
|
}
|
|
1221
1662
|
const users = {};
|
|
@@ -1331,6 +1772,12 @@ function defineFlags(input) {
|
|
|
1331
1772
|
var CONTROLLER_META = /* @__PURE__ */ Symbol.for("palbase.backend.controllerMeta");
|
|
1332
1773
|
function Controller(basePath, options = {}) {
|
|
1333
1774
|
return function(ctor) {
|
|
1775
|
+
const normalized = basePath.replace(/\/+$/, "");
|
|
1776
|
+
if (normalized === "/webhooks" || normalized.startsWith("/webhooks/")) {
|
|
1777
|
+
throw new Error(
|
|
1778
|
+
`@Controller("${basePath}") uses the reserved /webhooks path \u2014 inbound webhooks are served there`
|
|
1779
|
+
);
|
|
1780
|
+
}
|
|
1334
1781
|
const carrier = ctor;
|
|
1335
1782
|
const meta = {
|
|
1336
1783
|
__palbase: "controller",
|
|
@@ -1718,12 +2165,81 @@ function defineWorker(config) {
|
|
|
1718
2165
|
};
|
|
1719
2166
|
}
|
|
1720
2167
|
|
|
2168
|
+
// src/decorators/webhook.ts
|
|
2169
|
+
var WEBHOOK_META = /* @__PURE__ */ Symbol.for("palbase.backend.webhookMeta");
|
|
2170
|
+
var WEBHOOK_EVENTS = /* @__PURE__ */ Symbol.for("palbase.backend.webhookEvents");
|
|
2171
|
+
function carrierOf3(ctor) {
|
|
2172
|
+
return ctor;
|
|
2173
|
+
}
|
|
2174
|
+
function Webhook(options) {
|
|
2175
|
+
return function(ctor) {
|
|
2176
|
+
const carrier = carrierOf3(ctor);
|
|
2177
|
+
Object.defineProperty(carrier, WEBHOOK_META, {
|
|
2178
|
+
value: options,
|
|
2179
|
+
enumerable: false,
|
|
2180
|
+
configurable: true,
|
|
2181
|
+
writable: false
|
|
2182
|
+
});
|
|
2183
|
+
Object.defineProperty(carrier, "__palbase", {
|
|
2184
|
+
value: "webhook",
|
|
2185
|
+
enumerable: false,
|
|
2186
|
+
configurable: true,
|
|
2187
|
+
writable: false
|
|
2188
|
+
});
|
|
2189
|
+
return ctor;
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2192
|
+
function On(event) {
|
|
2193
|
+
return function(target, fnName) {
|
|
2194
|
+
const carrier = carrierOf3(target.constructor);
|
|
2195
|
+
const existing = carrier[WEBHOOK_EVENTS];
|
|
2196
|
+
const entries = existing ? [...existing] : [];
|
|
2197
|
+
entries.push({ event, fnName: String(fnName) });
|
|
2198
|
+
Object.defineProperty(carrier, WEBHOOK_EVENTS, {
|
|
2199
|
+
value: entries,
|
|
2200
|
+
enumerable: false,
|
|
2201
|
+
configurable: true,
|
|
2202
|
+
writable: false
|
|
2203
|
+
});
|
|
2204
|
+
};
|
|
2205
|
+
}
|
|
2206
|
+
function getWebhookConfig(ctor) {
|
|
2207
|
+
const carrier = carrierOf3(ctor);
|
|
2208
|
+
const meta = carrier[WEBHOOK_META];
|
|
2209
|
+
const entries = carrier[WEBHOOK_EVENTS] ?? [];
|
|
2210
|
+
if (!meta) {
|
|
2211
|
+
throw new Error(
|
|
2212
|
+
`@On used on a class that is not decorated with @Webhook (${ctor.name ?? "anonymous"})`
|
|
2213
|
+
);
|
|
2214
|
+
}
|
|
2215
|
+
if (!meta.provider && !meta.signature) {
|
|
2216
|
+
throw new Error(
|
|
2217
|
+
"@Webhook requires either a `provider` preset or an explicit `signature` \u2014 an endpoint with no verification would accept forged deliveries"
|
|
2218
|
+
);
|
|
2219
|
+
}
|
|
2220
|
+
if (!meta.secret?.env) {
|
|
2221
|
+
throw new Error('@Webhook requires `secret: { env: "VAR_NAME" }`');
|
|
2222
|
+
}
|
|
2223
|
+
if (entries.length === 0) {
|
|
2224
|
+
throw new Error("@Webhook requires at least one @On handler");
|
|
2225
|
+
}
|
|
2226
|
+
const instance = new ctor();
|
|
2227
|
+
const events = /* @__PURE__ */ Object.create(null);
|
|
2228
|
+
for (const entry of entries) {
|
|
2229
|
+
if (Object.prototype.hasOwnProperty.call(events, entry.event)) {
|
|
2230
|
+
throw new Error(`@On("${entry.event}") declared twice on the same webhook`);
|
|
2231
|
+
}
|
|
2232
|
+
events[entry.event] = (event, metaArg) => instance[entry.fnName].call(instance, event, metaArg);
|
|
2233
|
+
}
|
|
2234
|
+
return {
|
|
2235
|
+
...meta.provider ? { provider: meta.provider } : {},
|
|
2236
|
+
...meta.signature ? { signature: meta.signature } : {},
|
|
2237
|
+
secret: meta.secret,
|
|
2238
|
+
events
|
|
2239
|
+
};
|
|
2240
|
+
}
|
|
2241
|
+
|
|
1721
2242
|
// src/job.ts
|
|
1722
|
-
var VALID_JOB_NAME = /^[a-zA-Z0-9_-]+$/;
|
|
1723
|
-
var MAX_TIMEOUT_SECONDS = 300;
|
|
1724
|
-
var JOB_DEFAULTS = {
|
|
1725
|
-
timeout: 30
|
|
1726
|
-
};
|
|
1727
2243
|
function validateCronExpression(expression) {
|
|
1728
2244
|
const trimmed = expression.trim();
|
|
1729
2245
|
if (trimmed === "") {
|
|
@@ -1789,115 +2305,56 @@ function validateCronField(field, name, min, max) {
|
|
|
1789
2305
|
}
|
|
1790
2306
|
return null;
|
|
1791
2307
|
}
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
}
|
|
1814
|
-
if (config.timeout !== void 0 && !Number.isInteger(config.timeout)) {
|
|
1815
|
-
throw new Error("Job timeout must be an integer");
|
|
1816
|
-
}
|
|
1817
|
-
if (config.timeout !== void 0 && config.timeout > MAX_TIMEOUT_SECONDS) {
|
|
1818
|
-
throw new Error(
|
|
1819
|
-
`Job timeout ${config.timeout}s exceeds maximum ${MAX_TIMEOUT_SECONDS}s`
|
|
1820
|
-
);
|
|
1821
|
-
}
|
|
1822
|
-
return {
|
|
1823
|
-
name: config.name,
|
|
1824
|
-
schedule: config.schedule.trim(),
|
|
1825
|
-
timeout: config.timeout ?? JOB_DEFAULTS.timeout,
|
|
1826
|
-
handler: config.handler
|
|
2308
|
+
|
|
2309
|
+
// src/decorators/job.ts
|
|
2310
|
+
var DEFAULT_TIMEOUT_SECONDS = 30;
|
|
2311
|
+
var MAX_TIMEOUT_SECONDS = 300;
|
|
2312
|
+
var JOB_META = /* @__PURE__ */ Symbol.for("palbase.backend.jobMeta");
|
|
2313
|
+
function Job(options) {
|
|
2314
|
+
return function(ctor) {
|
|
2315
|
+
const carrier = ctor;
|
|
2316
|
+
Object.defineProperty(carrier, JOB_META, {
|
|
2317
|
+
value: options,
|
|
2318
|
+
enumerable: false,
|
|
2319
|
+
configurable: true,
|
|
2320
|
+
writable: false
|
|
2321
|
+
});
|
|
2322
|
+
Object.defineProperty(carrier, "__palbase", {
|
|
2323
|
+
value: "job",
|
|
2324
|
+
enumerable: false,
|
|
2325
|
+
configurable: true,
|
|
2326
|
+
writable: false
|
|
2327
|
+
});
|
|
2328
|
+
return ctor;
|
|
1827
2329
|
};
|
|
1828
2330
|
}
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
function defineWebhook(config) {
|
|
1833
|
-
if ("provider" in config) {
|
|
1834
|
-
return validateProviderWebhook(config);
|
|
1835
|
-
}
|
|
1836
|
-
return validateCustomWebhook(config);
|
|
1837
|
-
}
|
|
1838
|
-
function validateProviderWebhook(config) {
|
|
1839
|
-
if (!config.provider) {
|
|
1840
|
-
throw new Error("Webhook provider is required");
|
|
1841
|
-
}
|
|
1842
|
-
const validProviders = [
|
|
1843
|
-
"stripe",
|
|
1844
|
-
"github",
|
|
1845
|
-
"twilio",
|
|
1846
|
-
"sendgrid",
|
|
1847
|
-
"slack",
|
|
1848
|
-
"discord",
|
|
1849
|
-
"livekit"
|
|
1850
|
-
];
|
|
1851
|
-
if (!validProviders.includes(config.provider)) {
|
|
2331
|
+
function getJobConfig(ctor) {
|
|
2332
|
+
const meta = ctor[JOB_META];
|
|
2333
|
+
if (!meta) {
|
|
1852
2334
|
throw new Error(
|
|
1853
|
-
`
|
|
2335
|
+
`getJobConfig on a class with no @Job decorator (${ctor.name ?? "anonymous"})`
|
|
1854
2336
|
);
|
|
1855
2337
|
}
|
|
1856
|
-
if (!
|
|
1857
|
-
throw new Error(
|
|
2338
|
+
if (!meta.schedule || meta.schedule.trim() === "") {
|
|
2339
|
+
throw new Error("@Job requires a `schedule` cron expression");
|
|
1858
2340
|
}
|
|
1859
|
-
|
|
1860
|
-
|
|
2341
|
+
const cronError = validateCronExpression(meta.schedule);
|
|
2342
|
+
if (cronError) {
|
|
2343
|
+
throw new Error(`@Job has an invalid cron schedule: ${cronError}`);
|
|
1861
2344
|
}
|
|
1862
|
-
|
|
1863
|
-
|
|
2345
|
+
const timeout = meta.timeout ?? DEFAULT_TIMEOUT_SECONDS;
|
|
2346
|
+
if (!Number.isInteger(timeout) || timeout <= 0) {
|
|
2347
|
+
throw new Error("@Job `timeout` must be a positive whole number of seconds");
|
|
1864
2348
|
}
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
throw new Error(`Event handler for "${eventName}" must be a function`);
|
|
1868
|
-
}
|
|
2349
|
+
if (timeout > MAX_TIMEOUT_SECONDS) {
|
|
2350
|
+
throw new Error(`@Job \`timeout\` exceeds the ${MAX_TIMEOUT_SECONDS}s sandbox ceiling`);
|
|
1869
2351
|
}
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
secret: config.secret,
|
|
1874
|
-
events: config.events
|
|
1875
|
-
};
|
|
1876
|
-
}
|
|
1877
|
-
function validateCustomWebhook(config) {
|
|
1878
|
-
if (!config.path || config.path.trim() === "") {
|
|
1879
|
-
throw new Error("Webhook path is required");
|
|
1880
|
-
}
|
|
1881
|
-
if (!VALID_WEBHOOK_PATH.test(config.path)) {
|
|
1882
|
-
throw new Error(
|
|
1883
|
-
`Invalid webhook path "${config.path}": must start with / and contain only alphanumeric, hyphen, underscore, slash`
|
|
1884
|
-
);
|
|
2352
|
+
const instance = new ctor();
|
|
2353
|
+
if (typeof instance.run !== "function") {
|
|
2354
|
+
throw new Error("@Job class must declare an async run() method");
|
|
1885
2355
|
}
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
}
|
|
1889
|
-
if (typeof config.handler !== "function") {
|
|
1890
|
-
throw new Error("Webhook handler must be a function");
|
|
1891
|
-
}
|
|
1892
|
-
if (config.verify !== void 0 && typeof config.verify !== "function") {
|
|
1893
|
-
throw new Error("Webhook verify must be a function");
|
|
1894
|
-
}
|
|
1895
|
-
return {
|
|
1896
|
-
type: "custom",
|
|
1897
|
-
path: config.path,
|
|
1898
|
-
verify: config.verify,
|
|
1899
|
-
handler: config.handler
|
|
1900
|
-
};
|
|
2356
|
+
const run = instance.run.bind(instance);
|
|
2357
|
+
return { schedule: meta.schedule, timeout, handler: run };
|
|
1901
2358
|
}
|
|
1902
2359
|
|
|
1903
2360
|
// src/resource.ts
|
|
@@ -2002,10 +2459,12 @@ var import_zod2 = require("zod");
|
|
|
2002
2459
|
Get,
|
|
2003
2460
|
Headers,
|
|
2004
2461
|
HttpError,
|
|
2462
|
+
Job,
|
|
2005
2463
|
Log,
|
|
2006
2464
|
NOTIFICATIONS_CONFIG_KIND,
|
|
2007
2465
|
NotFound,
|
|
2008
2466
|
Notifications,
|
|
2467
|
+
On,
|
|
2009
2468
|
OptionalUser,
|
|
2010
2469
|
PALBASE_EXTENSIONS,
|
|
2011
2470
|
PROVIDER_CATALOG,
|
|
@@ -2031,10 +2490,13 @@ var import_zod2 = require("zod");
|
|
|
2031
2490
|
TEST_USERS_CONFIG_KIND,
|
|
2032
2491
|
TooManyRequests,
|
|
2033
2492
|
TraceId,
|
|
2493
|
+
TxPlanError,
|
|
2494
|
+
TxRefError,
|
|
2034
2495
|
Unauthorized,
|
|
2035
2496
|
Upload,
|
|
2036
2497
|
UploadedObject,
|
|
2037
2498
|
User,
|
|
2499
|
+
Webhook,
|
|
2038
2500
|
__getRuntime,
|
|
2039
2501
|
__registerResource,
|
|
2040
2502
|
__requestALS,
|
|
@@ -2047,29 +2509,32 @@ var import_zod2 = require("zod");
|
|
|
2047
2509
|
boolean,
|
|
2048
2510
|
bucket,
|
|
2049
2511
|
buildProvider,
|
|
2512
|
+
dec,
|
|
2050
2513
|
defineEgress,
|
|
2051
2514
|
defineError,
|
|
2052
2515
|
defineFlags,
|
|
2053
|
-
defineJob,
|
|
2054
2516
|
defineMiddleware,
|
|
2055
2517
|
defineNotifications,
|
|
2056
2518
|
defineSchema,
|
|
2057
2519
|
defineStorage,
|
|
2058
2520
|
defineTestUsers,
|
|
2059
|
-
defineWebhook,
|
|
2060
2521
|
defineWorker,
|
|
2061
2522
|
documents,
|
|
2062
2523
|
entitlementFor,
|
|
2063
2524
|
enumType,
|
|
2064
2525
|
flag,
|
|
2065
2526
|
getErrorRegistry,
|
|
2527
|
+
getJobConfig,
|
|
2066
2528
|
getRoutes,
|
|
2529
|
+
getWebhookConfig,
|
|
2530
|
+
inc,
|
|
2067
2531
|
integer,
|
|
2068
2532
|
isPalbaseExtension,
|
|
2069
2533
|
jsonb,
|
|
2070
2534
|
makeEnvDts,
|
|
2071
2535
|
makePurchasesDts,
|
|
2072
2536
|
makeTypedDB,
|
|
2537
|
+
now,
|
|
2073
2538
|
numeric,
|
|
2074
2539
|
parseFileSizeLimit,
|
|
2075
2540
|
policy,
|