@palbase/backend 9.0.0 → 10.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-SO6YV35D.js → chunk-4WOQWFUP.js} +38 -6
- package/dist/chunk-4WOQWFUP.js.map +1 -0
- package/dist/db/env.cjs.map +1 -1
- package/dist/db/env.d.cts +18 -4
- package/dist/db/env.d.ts +18 -4
- package/dist/db/index.cjs +37 -5
- 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 +1 -1
- package/dist/{endpoint-CGI5cZMg.d.cts → endpoint-Cn3ICGTf.d.cts} +26 -4
- package/dist/{endpoint-CGI5cZMg.d.ts → endpoint-Cn3ICGTf.d.ts} +26 -4
- package/dist/{index-osv2jMmZ.d.cts → index-Bt7UHkAM.d.cts} +40 -5
- package/dist/{index--dH5i4Nu.d.ts → index-V0ealeY-.d.ts} +40 -5
- package/dist/index.cjs +241 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +262 -14
- package/dist/index.d.ts +262 -14
- package/dist/index.js +199 -3
- package/dist/index.js.map +1 -1
- package/dist/test/index.d.cts +1 -1
- package/dist/test/index.d.ts +1 -1
- package/docs/README.md +12 -10
- package/docs/background.md +4 -4
- package/docs/events.md +4 -4
- package/docs/getting-started.md +6 -5
- package/docs/llms-full.txt +39 -36
- package/docs/migrations.md +10 -10
- package/docs/resources.md +3 -3
- package/package.json +1 -1
- package/dist/chunk-SO6YV35D.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -29,6 +29,7 @@ __export(src_exports, {
|
|
|
29
29
|
Database: () => Database,
|
|
30
30
|
Delete: () => Delete,
|
|
31
31
|
Documents: () => Documents,
|
|
32
|
+
EGRESS_CONFIG_KIND: () => EGRESS_CONFIG_KIND,
|
|
32
33
|
EXTENSION_DEPENDENCIES: () => EXTENSION_DEPENDENCIES,
|
|
33
34
|
FLAGS_CONFIG_KIND: () => FLAGS_CONFIG_KIND,
|
|
34
35
|
Flags: () => Flags,
|
|
@@ -59,6 +60,7 @@ __export(src_exports, {
|
|
|
59
60
|
Resource: () => Resource,
|
|
60
61
|
STORAGE_CONFIG_KIND: () => STORAGE_CONFIG_KIND,
|
|
61
62
|
Storage: () => Storage,
|
|
63
|
+
TEST_USERS_CONFIG_KIND: () => TEST_USERS_CONFIG_KIND,
|
|
62
64
|
TooManyRequests: () => TooManyRequests,
|
|
63
65
|
TraceId: () => TraceId,
|
|
64
66
|
Unauthorized: () => Unauthorized,
|
|
@@ -77,6 +79,7 @@ __export(src_exports, {
|
|
|
77
79
|
boolean: () => boolean,
|
|
78
80
|
bucket: () => bucket,
|
|
79
81
|
buildProvider: () => buildProvider,
|
|
82
|
+
defineEgress: () => defineEgress,
|
|
80
83
|
defineError: () => defineError,
|
|
81
84
|
defineFlags: () => defineFlags,
|
|
82
85
|
defineJob: () => defineJob,
|
|
@@ -84,12 +87,14 @@ __export(src_exports, {
|
|
|
84
87
|
defineNotifications: () => defineNotifications,
|
|
85
88
|
defineSchema: () => defineSchema,
|
|
86
89
|
defineStorage: () => defineStorage,
|
|
90
|
+
defineTestUsers: () => defineTestUsers,
|
|
87
91
|
defineWebhook: () => defineWebhook,
|
|
88
92
|
defineWorker: () => defineWorker,
|
|
89
93
|
documents: () => documents,
|
|
90
94
|
enumType: () => enumType,
|
|
91
95
|
flag: () => flag,
|
|
92
96
|
getErrorRegistry: () => getErrorRegistry,
|
|
97
|
+
getRoutes: () => getRoutes,
|
|
93
98
|
integer: () => integer,
|
|
94
99
|
isPalbaseExtension: () => isPalbaseExtension,
|
|
95
100
|
jsonb: () => jsonb,
|
|
@@ -102,6 +107,7 @@ __export(src_exports, {
|
|
|
102
107
|
recordThrows: () => recordThrows,
|
|
103
108
|
reservedSecretKey: () => reservedSecretKey,
|
|
104
109
|
storage: () => storage,
|
|
110
|
+
testUser: () => testUser,
|
|
105
111
|
text: () => text,
|
|
106
112
|
timestamp: () => timestamp,
|
|
107
113
|
uuid: () => uuid,
|
|
@@ -402,12 +408,44 @@ var ColumnBuilder = class _ColumnBuilder {
|
|
|
402
408
|
* `auth.users` lives in the SAME tenant database (palauth-owned), so this is
|
|
403
409
|
* a genuine cross-schema integrity constraint scoped to THIS tenant's users.
|
|
404
410
|
* The referenced `auth.users.id` is `text` (palauth ids are `usr_<uuid>`), so
|
|
405
|
-
* the referencing column must be `text()` too.
|
|
406
|
-
*
|
|
407
|
-
* `
|
|
411
|
+
* the referencing column must be `text()` too.
|
|
412
|
+
*
|
|
413
|
+
* ON DELETE is REQUIRED here and may only be `cascade` or `set null`: an
|
|
414
|
+
* account-erasure request must never be blocked by a lingering FK, so
|
|
415
|
+
* `restrict` / `no action` are not accepted (they don't type-check). Example:
|
|
416
|
+
* `text().notNull().referencesAuthUser("cascade")`, or
|
|
417
|
+
* `text().nullable().referencesAuthUser("set null")`. The server
|
|
418
|
+
* (validateAuthUserFK) enforces this — and the remaining rules the type can't
|
|
419
|
+
* express (referencing column is text, `set null` needs a nullable column) —
|
|
420
|
+
* as the real boundary; this signature is the compile-time DX mirror.
|
|
408
421
|
*/
|
|
409
|
-
referencesAuthUser() {
|
|
410
|
-
|
|
422
|
+
referencesAuthUser(onDelete) {
|
|
423
|
+
this._def.references = { table: "auth.users", column: "id" };
|
|
424
|
+
this._def.onDeleteAction = onDelete;
|
|
425
|
+
return new _ColumnBuilder(this._def.type, this._def);
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Add a real DB-level foreign key to the canonical, server-minted installation
|
|
429
|
+
* anchor (`REFERENCES auth.installations(id)`) — the app-scoped verified-device
|
|
430
|
+
* root (`ins_...`). Sugar for `.references("auth.installations", "id")`.
|
|
431
|
+
*
|
|
432
|
+
* An installation is an APP INSTALL, not a user: this FK is NOT user ownership.
|
|
433
|
+
* A user-owned row STILL needs its own `.referencesAuthUser(...)` FK so account
|
|
434
|
+
* erasure removes it — an installation reference alone does not tie a row to a
|
|
435
|
+
* user's deletion. Use this only for install-scoped state (device prefs, push
|
|
436
|
+
* routing, …), alongside a separate auth-user FK where the row is user-owned.
|
|
437
|
+
*
|
|
438
|
+
* `auth.installations` lives in the SAME tenant DB (palauth-owned); its `id` is
|
|
439
|
+
* `text` (`ins_<uuid>`), so the referencing column must be `text()` too. ON
|
|
440
|
+
* DELETE is REQUIRED and may only be `cascade` or `set null` (same allowed set
|
|
441
|
+
* as an auth-user FK): an installation revoke / orphan cleanup must never be
|
|
442
|
+
* blocked by a lingering FK. The server (validateAuthAnchorFK) is the real
|
|
443
|
+
* boundary; this signature is the compile-time DX mirror.
|
|
444
|
+
*/
|
|
445
|
+
referencesInstallation(onDelete) {
|
|
446
|
+
this._def.references = { table: "auth.installations", column: "id" };
|
|
447
|
+
this._def.onDeleteAction = onDelete;
|
|
448
|
+
return new _ColumnBuilder(this._def.type, this._def);
|
|
411
449
|
}
|
|
412
450
|
/** Set the ON DELETE action for a foreign key reference. */
|
|
413
451
|
onDelete(action) {
|
|
@@ -515,7 +553,50 @@ function rowType(def) {
|
|
|
515
553
|
function optionalOnInsert(def) {
|
|
516
554
|
return def.nullable === true || def.defaultRandom === true || def.defaultNow === true || def.defaultValue !== void 0;
|
|
517
555
|
}
|
|
518
|
-
|
|
556
|
+
var AUTH_USERS_TABLE = "auth.users";
|
|
557
|
+
function ownerColumnOf(table) {
|
|
558
|
+
for (const [col, builder] of Object.entries(table.columns)) {
|
|
559
|
+
if (builder._def.references?.table === AUTH_USERS_TABLE) return col;
|
|
560
|
+
}
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
function buildChildEdges(schema) {
|
|
564
|
+
const edges = /* @__PURE__ */ new Map();
|
|
565
|
+
for (const name of Object.keys(schema.tables)) edges.set(name, []);
|
|
566
|
+
for (const childName of Object.keys(schema.tables)) {
|
|
567
|
+
const table = schema.tables[childName];
|
|
568
|
+
if (table === void 0) continue;
|
|
569
|
+
for (const [col, builder] of Object.entries(table.columns)) {
|
|
570
|
+
const ref = builder._def.references;
|
|
571
|
+
if (ref === void 0) continue;
|
|
572
|
+
if (ref.table === childName) continue;
|
|
573
|
+
const bucket2 = edges.get(ref.table);
|
|
574
|
+
if (bucket2 === void 0) continue;
|
|
575
|
+
if (bucket2.some((e) => e.child === childName)) continue;
|
|
576
|
+
bucket2.push({ child: childName, column: col });
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
return edges;
|
|
580
|
+
}
|
|
581
|
+
function pruneCycles(raw2) {
|
|
582
|
+
const pruned = /* @__PURE__ */ new Map();
|
|
583
|
+
for (const table of raw2.keys()) pruned.set(table, []);
|
|
584
|
+
const state = /* @__PURE__ */ new Map();
|
|
585
|
+
function visit(table) {
|
|
586
|
+
state.set(table, "visiting");
|
|
587
|
+
for (const edge of raw2.get(table) ?? []) {
|
|
588
|
+
if (state.get(edge.child) === "visiting") continue;
|
|
589
|
+
pruned.get(table)?.push(edge);
|
|
590
|
+
if (state.get(edge.child) === void 0) visit(edge.child);
|
|
591
|
+
}
|
|
592
|
+
state.set(table, "done");
|
|
593
|
+
}
|
|
594
|
+
for (const table of raw2.keys()) {
|
|
595
|
+
if (state.get(table) === void 0) visit(table);
|
|
596
|
+
}
|
|
597
|
+
return pruned;
|
|
598
|
+
}
|
|
599
|
+
function tableBlock(table, children, indent) {
|
|
519
600
|
const cols = Object.entries(table.columns);
|
|
520
601
|
const rowLines = cols.map(([col, builder]) => {
|
|
521
602
|
return `${indent} ${col}: ${rowType(builder._def)};`;
|
|
@@ -525,6 +606,8 @@ function tableBlock(table, indent) {
|
|
|
525
606
|
const opt = optionalOnInsert(def) ? "?" : "";
|
|
526
607
|
return `${indent} ${col}${opt}: ${rowType(def)};`;
|
|
527
608
|
});
|
|
609
|
+
const owner = ownerColumnOf(table);
|
|
610
|
+
const childEntries = children.map((e) => `${JSON.stringify(e.child)}: ${JSON.stringify(e.column)}`).join("; ");
|
|
528
611
|
return [
|
|
529
612
|
`${indent}${table.name}: {`,
|
|
530
613
|
`${indent} row: {`,
|
|
@@ -533,12 +616,17 @@ function tableBlock(table, indent) {
|
|
|
533
616
|
`${indent} insert: {`,
|
|
534
617
|
...insertLines,
|
|
535
618
|
`${indent} };`,
|
|
619
|
+
`${indent} owner: ${owner === null ? "null" : JSON.stringify(owner)};`,
|
|
620
|
+
`${indent} children: {${childEntries === "" ? "" : ` ${childEntries} `}};`,
|
|
536
621
|
`${indent}};`
|
|
537
622
|
].join("\n");
|
|
538
623
|
}
|
|
539
624
|
function makeEnvDts(schema) {
|
|
540
625
|
const tableNames = Object.keys(schema.tables);
|
|
541
|
-
const
|
|
626
|
+
const children = pruneCycles(buildChildEdges(schema));
|
|
627
|
+
const blocks = tableNames.map(
|
|
628
|
+
(name) => tableBlock(schema.tables[name], children.get(name) ?? [], " ")
|
|
629
|
+
);
|
|
542
630
|
const body = blocks.length > 0 ? `
|
|
543
631
|
${blocks.join("\n")}
|
|
544
632
|
` : "";
|
|
@@ -633,6 +721,22 @@ function defineStorage(input) {
|
|
|
633
721
|
return { __config: STORAGE_CONFIG_KIND, buckets };
|
|
634
722
|
}
|
|
635
723
|
|
|
724
|
+
// src/config/egress.ts
|
|
725
|
+
var EGRESS_CONFIG_KIND = "egress";
|
|
726
|
+
function defineEgress(input) {
|
|
727
|
+
if (input === null || typeof input !== "object" || !Array.isArray(input.hosts)) {
|
|
728
|
+
throw new Error("defineEgress expects { hosts: string[] }");
|
|
729
|
+
}
|
|
730
|
+
const hosts = [];
|
|
731
|
+
for (const h of input.hosts) {
|
|
732
|
+
if (typeof h !== "string" || h.trim().length === 0) {
|
|
733
|
+
throw new Error("defineEgress: every host must be a non-empty string");
|
|
734
|
+
}
|
|
735
|
+
hosts.push(h.trim().toLowerCase());
|
|
736
|
+
}
|
|
737
|
+
return { __config: EGRESS_CONFIG_KIND, hosts };
|
|
738
|
+
}
|
|
739
|
+
|
|
636
740
|
// src/config/notifications.ts
|
|
637
741
|
var NOTIFICATIONS_CONFIG_KIND = "notifications";
|
|
638
742
|
var RESERVED_SECRET_PREFIX = "PB_NOTIFICATIONS";
|
|
@@ -744,6 +848,98 @@ function camelToUpperSnake(s) {
|
|
|
744
848
|
return s.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toUpperCase();
|
|
745
849
|
}
|
|
746
850
|
|
|
851
|
+
// src/config/test-users.ts
|
|
852
|
+
var TEST_USERS_CONFIG_KIND = "test-users";
|
|
853
|
+
var TEST_USER_NAME_RE = /^[a-zA-Z][a-zA-Z0-9_]*$/;
|
|
854
|
+
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
855
|
+
var MIN_PASSWORD_LENGTH = 8;
|
|
856
|
+
function isPlainObject(value) {
|
|
857
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
858
|
+
}
|
|
859
|
+
function normalizeSeed(seed, userName) {
|
|
860
|
+
if (seed === void 0) return {};
|
|
861
|
+
if (!isPlainObject(seed)) {
|
|
862
|
+
throw new Error(`testUser ${JSON.stringify(userName)}: seed must be { <table>: [ {...} ] }`);
|
|
863
|
+
}
|
|
864
|
+
const out = {};
|
|
865
|
+
for (const [table, rows] of Object.entries(seed)) {
|
|
866
|
+
if (!Array.isArray(rows)) {
|
|
867
|
+
throw new Error(
|
|
868
|
+
`testUser ${JSON.stringify(userName)}: seed.${table} must be an array of rows`
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
if (rows.length === 0) {
|
|
872
|
+
throw new Error(
|
|
873
|
+
`testUser ${JSON.stringify(userName)}: seed.${table} is empty \u2014 remove it or add a row`
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
for (const row of rows) {
|
|
877
|
+
if (!isPlainObject(row)) {
|
|
878
|
+
throw new Error(
|
|
879
|
+
`testUser ${JSON.stringify(userName)}: every row in seed.${table} must be an object`
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
out[table] = rows;
|
|
884
|
+
}
|
|
885
|
+
return out;
|
|
886
|
+
}
|
|
887
|
+
function testUser(opts = {}) {
|
|
888
|
+
if (!isPlainObject(opts)) {
|
|
889
|
+
throw new Error("testUser() expects { email?, password?, seed? }");
|
|
890
|
+
}
|
|
891
|
+
const hasEmail = opts.email !== void 0;
|
|
892
|
+
const hasPassword = opts.password !== void 0;
|
|
893
|
+
if (hasEmail !== hasPassword) {
|
|
894
|
+
throw new Error(
|
|
895
|
+
"testUser() needs email AND password together (a fixture with stable credentials) or neither (a template the server generates credentials for)"
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
let email = null;
|
|
899
|
+
let password = null;
|
|
900
|
+
if (hasEmail) {
|
|
901
|
+
if (typeof opts.email !== "string" || !EMAIL_RE.test(opts.email)) {
|
|
902
|
+
throw new Error(`testUser email ${JSON.stringify(opts.email)} is not a valid address`);
|
|
903
|
+
}
|
|
904
|
+
if (typeof opts.password !== "string" || opts.password.length < MIN_PASSWORD_LENGTH) {
|
|
905
|
+
throw new Error(
|
|
906
|
+
`testUser password must be at least ${MIN_PASSWORD_LENGTH} characters (got ${typeof opts.password === "string" ? opts.password.length : 0})`
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
email = opts.email;
|
|
910
|
+
password = opts.password;
|
|
911
|
+
}
|
|
912
|
+
return { email, password, seed: normalizeSeed(opts.seed, email ?? "<template>") };
|
|
913
|
+
}
|
|
914
|
+
function defineTestUsers(input) {
|
|
915
|
+
if (!isPlainObject(input) || !isPlainObject(input.users)) {
|
|
916
|
+
throw new Error("defineTestUsers expects { users: { <name>: testUser({...}) } }");
|
|
917
|
+
}
|
|
918
|
+
const users = {};
|
|
919
|
+
const emails = /* @__PURE__ */ new Map();
|
|
920
|
+
for (const name of Object.keys(input.users)) {
|
|
921
|
+
if (!TEST_USER_NAME_RE.test(name)) {
|
|
922
|
+
throw new Error(
|
|
923
|
+
`test user name ${JSON.stringify(name)} is invalid \u2014 must start with a letter and contain only letters, digits, and underscores`
|
|
924
|
+
);
|
|
925
|
+
}
|
|
926
|
+
const def = input.users[name];
|
|
927
|
+
if (def === void 0) continue;
|
|
928
|
+
if (def.email !== null) {
|
|
929
|
+
const lower = def.email.toLowerCase();
|
|
930
|
+
const already = emails.get(lower);
|
|
931
|
+
if (already !== void 0) {
|
|
932
|
+
throw new Error(
|
|
933
|
+
`test users ${JSON.stringify(already)} and ${JSON.stringify(name)} declare the same e-mail ${JSON.stringify(def.email)}`
|
|
934
|
+
);
|
|
935
|
+
}
|
|
936
|
+
emails.set(lower, name);
|
|
937
|
+
}
|
|
938
|
+
users[name] = def;
|
|
939
|
+
}
|
|
940
|
+
return { __config: TEST_USERS_CONFIG_KIND, users };
|
|
941
|
+
}
|
|
942
|
+
|
|
747
943
|
// src/config/flags.ts
|
|
748
944
|
var FLAGS_CONFIG_KIND = "flags";
|
|
749
945
|
var FLAG_KEY_RE = /^[a-zA-Z][a-zA-Z0-9_]*$/;
|
|
@@ -916,10 +1112,42 @@ function recordThrows(target, fnName, throws) {
|
|
|
916
1112
|
const throwsBuffer = carrier[THROWS_BUFFER];
|
|
917
1113
|
if (throwsBuffer) throwsBuffer[fnName] = throws;
|
|
918
1114
|
}
|
|
1115
|
+
function getRoutes(ctor) {
|
|
1116
|
+
const carrier = carrierOf(ctor);
|
|
1117
|
+
const routes = carrier[ROUTES] ?? [];
|
|
1118
|
+
const returnBuffer = carrier[RETURN_BUFFER];
|
|
1119
|
+
if (returnBuffer) {
|
|
1120
|
+
for (const route of routes) {
|
|
1121
|
+
const buffered = returnBuffer[route.fnName];
|
|
1122
|
+
if (buffered && route.returnSchema === void 0) {
|
|
1123
|
+
route.returnSchema = buffered;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
const throwsBuffer = carrier[THROWS_BUFFER];
|
|
1128
|
+
if (throwsBuffer) {
|
|
1129
|
+
for (const route of routes) {
|
|
1130
|
+
const buffered = throwsBuffer[route.fnName];
|
|
1131
|
+
if (buffered && route.throws === void 0) {
|
|
1132
|
+
route.throws = buffered;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
return routes.map((r) => ({
|
|
1137
|
+
...r,
|
|
1138
|
+
params: r.params.slice(),
|
|
1139
|
+
...r.throws !== void 0 ? { throws: r.throws.slice() } : {}
|
|
1140
|
+
}));
|
|
1141
|
+
}
|
|
919
1142
|
|
|
920
1143
|
// src/decorators/methods.ts
|
|
921
1144
|
function makeMethodDecorator(method) {
|
|
922
1145
|
return function(subpath, options = {}) {
|
|
1146
|
+
if (typeof subpath !== "string") {
|
|
1147
|
+
throw new Error(
|
|
1148
|
+
`@${method[0]}${method.slice(1).toLowerCase()}(subpath) expects a string subpath, got ${typeof subpath}.` + (method === "QUERY" ? " If this is a zod schema on a method parameter: the query-string param decorator was renamed @QueryParams(schema) in @palbase/backend 9.0.0." : "")
|
|
1149
|
+
);
|
|
1150
|
+
}
|
|
923
1151
|
return function(target, propertyKey) {
|
|
924
1152
|
recordRoute(target, String(propertyKey), method, subpath, options);
|
|
925
1153
|
};
|
|
@@ -1519,6 +1747,7 @@ var import_zod2 = require("zod");
|
|
|
1519
1747
|
Database,
|
|
1520
1748
|
Delete,
|
|
1521
1749
|
Documents,
|
|
1750
|
+
EGRESS_CONFIG_KIND,
|
|
1522
1751
|
EXTENSION_DEPENDENCIES,
|
|
1523
1752
|
FLAGS_CONFIG_KIND,
|
|
1524
1753
|
Flags,
|
|
@@ -1549,6 +1778,7 @@ var import_zod2 = require("zod");
|
|
|
1549
1778
|
Resource,
|
|
1550
1779
|
STORAGE_CONFIG_KIND,
|
|
1551
1780
|
Storage,
|
|
1781
|
+
TEST_USERS_CONFIG_KIND,
|
|
1552
1782
|
TooManyRequests,
|
|
1553
1783
|
TraceId,
|
|
1554
1784
|
Unauthorized,
|
|
@@ -1567,6 +1797,7 @@ var import_zod2 = require("zod");
|
|
|
1567
1797
|
boolean,
|
|
1568
1798
|
bucket,
|
|
1569
1799
|
buildProvider,
|
|
1800
|
+
defineEgress,
|
|
1570
1801
|
defineError,
|
|
1571
1802
|
defineFlags,
|
|
1572
1803
|
defineJob,
|
|
@@ -1574,12 +1805,14 @@ var import_zod2 = require("zod");
|
|
|
1574
1805
|
defineNotifications,
|
|
1575
1806
|
defineSchema,
|
|
1576
1807
|
defineStorage,
|
|
1808
|
+
defineTestUsers,
|
|
1577
1809
|
defineWebhook,
|
|
1578
1810
|
defineWorker,
|
|
1579
1811
|
documents,
|
|
1580
1812
|
enumType,
|
|
1581
1813
|
flag,
|
|
1582
1814
|
getErrorRegistry,
|
|
1815
|
+
getRoutes,
|
|
1583
1816
|
integer,
|
|
1584
1817
|
isPalbaseExtension,
|
|
1585
1818
|
jsonb,
|
|
@@ -1592,6 +1825,7 @@ var import_zod2 = require("zod");
|
|
|
1592
1825
|
recordThrows,
|
|
1593
1826
|
reservedSecretKey,
|
|
1594
1827
|
storage,
|
|
1828
|
+
testUser,
|
|
1595
1829
|
text,
|
|
1596
1830
|
timestamp,
|
|
1597
1831
|
uuid,
|