@palbase/backend 2.0.0 → 3.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.
Files changed (51) hide show
  1. package/README.md +24 -0
  2. package/dist/{chunk-4J3F32SH.js → chunk-B7EUJP5W.js} +38 -9
  3. package/dist/chunk-B7EUJP5W.js.map +1 -0
  4. package/dist/{chunk-L36JLUPO.js → chunk-PHAFZGHN.js} +43 -46
  5. package/dist/chunk-PHAFZGHN.js.map +1 -0
  6. package/dist/db/env.cjs +19 -0
  7. package/dist/db/env.cjs.map +1 -0
  8. package/dist/db/env.d.cts +45 -0
  9. package/dist/db/env.d.ts +45 -0
  10. package/dist/db/env.js +1 -0
  11. package/dist/db/env.js.map +1 -0
  12. package/dist/db/index.cjs +28 -231
  13. package/dist/db/index.cjs.map +1 -1
  14. package/dist/db/index.d.cts +4 -20
  15. package/dist/db/index.d.ts +4 -20
  16. package/dist/db/index.js +3 -233
  17. package/dist/db/index.js.map +1 -1
  18. package/dist/{endpoint-Djk5L6G2.d.ts → endpoint-DJ98tQd6.d.cts} +30 -68
  19. package/dist/{endpoint-BlcY2xNA.d.cts → endpoint-DJ98tQd6.d.ts} +30 -68
  20. package/dist/index-CXUs9iTQ.d.ts +294 -0
  21. package/dist/index-CZAwpQE1.d.cts +294 -0
  22. package/dist/index.cjs +229 -61
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +398 -154
  25. package/dist/index.d.ts +398 -154
  26. package/dist/index.js +147 -12
  27. package/dist/index.js.map +1 -1
  28. package/dist/test/index.cjs +41 -1
  29. package/dist/test/index.cjs.map +1 -1
  30. package/dist/test/index.d.cts +1 -2
  31. package/dist/test/index.d.ts +1 -2
  32. package/dist/test/index.js +1 -1
  33. package/docs/README.md +72 -0
  34. package/docs/background.md +62 -0
  35. package/docs/database.md +73 -0
  36. package/docs/endpoints.md +134 -0
  37. package/docs/errors.md +47 -0
  38. package/docs/events.md +67 -0
  39. package/docs/getting-started.md +65 -0
  40. package/docs/llms-full.txt +1038 -0
  41. package/docs/llms.txt +18 -0
  42. package/docs/migrations.md +98 -0
  43. package/docs/resources.md +94 -0
  44. package/docs/routing.md +67 -0
  45. package/docs/schema.md +92 -0
  46. package/docs/services.md +104 -0
  47. package/package.json +15 -3
  48. package/dist/chunk-4J3F32SH.js.map +0 -1
  49. package/dist/chunk-L36JLUPO.js.map +0 -1
  50. package/dist/schema-BqfEhIC0.d.cts +0 -133
  51. package/dist/schema-BqfEhIC0.d.ts +0 -133
package/dist/index.d.cts CHANGED
@@ -1,95 +1,12 @@
1
- import { D as DBClient, C as CacheClient, P as PalbaseDocsClient, a as PalbaseFlagsClient, L as Logger, b as PalbaseNotificationsClient, Q as QueueClient, c as PalbaseStorageClient, d as PalbaseModuleClients, U as User, E as ErrorThrowers } from './endpoint-BlcY2xNA.cjs';
2
- export { A as AuthConfig, e as ClientInfo, f as EndpointConfig, g as ErrorDef, h as ErrorMap, F as FileContext, H as HttpError, i as HttpMethod, M as Middleware, j as MiddlewareContext, k as MiddlewareHandler, l as PBRequest, m as PalbaseAnalyticsClient, n as PalbaseAnalyticsManagementNamespace, o as PalbaseAnalyticsProperties, p as PalbaseAnalyticsQueryNamespace, q as PalbaseAttestAndroidParams, r as PalbaseAttestAndroidResult, s as PalbaseAttestiOSParams, t as PalbaseAttestiOSResult, u as PalbaseAuthClient, v as PalbaseBindDeviceParams, w as PalbaseBucketClient, x as PalbaseCmsClient, y as PalbaseCmsFindOneOptions, z as PalbaseCmsFindOptions, B as PalbaseCohortQueryInput, G as PalbaseCohortResult, I as PalbaseCollectionRef, J as PalbaseCountQueryInput, K as PalbaseCountResult, N as PalbaseCreateLinkParams, O as PalbaseDeviceInfo, R as PalbaseDeviceTokenView, S as PalbaseDocumentRef, T as PalbaseDocumentSnapshot, V as PalbaseEmailClient, W as PalbaseEmailSendParams, X as PalbaseEmailSendResponse, Y as PalbaseEventNamesResult, Z as PalbaseEventsQueryInput, _ as PalbaseEventsResult, $ as PalbaseFileObject, a0 as PalbaseFlag, a1 as PalbaseFlagContext, a2 as PalbaseFlagVariant, a3 as PalbaseFunctionsClient, a4 as PalbaseFunnelQueryInput, a5 as PalbaseFunnelResult, a6 as PalbaseIdentifyTraits, a7 as PalbaseInboxClient, a8 as PalbaseInboxListOptions, a9 as PalbaseInboxListResult, aa as PalbaseInboxMessage, ab as PalbaseInboxSendParams, ac as PalbaseInboxSendResponse, ad as PalbaseInitialLink, ae as PalbaseInvokeOptions, af as PalbaseLink, ag as PalbaseLinkAnalytics, ah as PalbaseLinkDetails, ai as PalbaseLinksClient, aj as PalbaseListLinksOptions, ak as PalbaseListLinksResult, al as PalbaseListOptions, am as PalbaseMatchParams, an as PalbaseMultiChannelResponse, ao as PalbaseOverviewResult, ap as PalbasePreferences, aq as PalbasePreferencesClient, ar as PalbasePublicUrlResponse, as as PalbasePushClient, at as PalbasePushSendParams, au as PalbasePushSendResponse, av as PalbaseQrCodeOptions, aw as PalbaseQuerySnapshot, ax as PalbaseRealtimeChannel, ay as PalbaseRealtimeClient, az as PalbaseRealtimeMessage, aA as PalbaseRegisterDeviceParams, aB as PalbaseResult, aC as PalbaseRetentionQueryInput, aD as PalbaseRetentionResult, aE as PalbaseSession, aF as PalbaseSignedUrlResponse, aG as PalbaseSmsClient, aH as PalbaseSmsSendParams, aI as PalbaseSmsSendResponse, aJ as PalbaseTransformOptions, aK as PalbaseUpdateLinkParams, aL as PalbaseUploadOptions, aM as PalbaseUser, aN as PalbaseUserDetailResult, aO as PalbaseUsersQueryInput, aP as PalbaseUsersResult, aQ as PalbaseVerifyRequestSignatureParams, aR as PalbaseWhereOperator, aS as RateLimitConfig, aT as TxClient, aU as defineEndpoint, aV as defineMiddleware } from './endpoint-BlcY2xNA.cjs';
1
+ import { C as CacheClient, b as PalbaseDocsClient, c as PalbaseFlagsClient, L as Logger, d as PalbaseNotificationsClient, Q as QueueClient, D as DBClient, e as PalbaseStorageClient, A as AuthSpec, R as RateLimitConfig, E as ErrorMap, M as Middleware, P as PBRequest, I as IsAuthed, U as User } from './endpoint-DJ98tQd6.cjs';
2
+ export { f as AuthConfig, g as ClientInfo, h as ErrorDef, i as ErrorThrowers, F as FileContext, H as HttpError, j as HttpMethod, k as MiddlewareContext, l as MiddlewareHandler, m as PalbaseAnalyticsClient, n as PalbaseAnalyticsManagementNamespace, o as PalbaseAnalyticsProperties, p as PalbaseAnalyticsQueryNamespace, q as PalbaseAttestAndroidParams, r as PalbaseAttestAndroidResult, s as PalbaseAttestiOSParams, t as PalbaseAttestiOSResult, u as PalbaseAuthClient, v as PalbaseBindDeviceParams, w as PalbaseBucketClient, x as PalbaseCmsClient, y as PalbaseCmsFindOneOptions, z as PalbaseCmsFindOptions, B as PalbaseCohortQueryInput, G as PalbaseCohortResult, J as PalbaseCollectionRef, K as PalbaseCountQueryInput, N as PalbaseCountResult, O as PalbaseCreateLinkParams, S as PalbaseDeviceInfo, T as PalbaseDeviceTokenView, V as PalbaseDocumentRef, W as PalbaseDocumentSnapshot, X as PalbaseEmailClient, Y as PalbaseEmailSendParams, Z as PalbaseEmailSendResponse, _ as PalbaseEventNamesResult, $ as PalbaseEventsQueryInput, a0 as PalbaseEventsResult, a1 as PalbaseFileObject, a2 as PalbaseFlag, a3 as PalbaseFlagContext, a4 as PalbaseFlagVariant, a5 as PalbaseFunctionsClient, a6 as PalbaseFunnelQueryInput, a7 as PalbaseFunnelResult, a8 as PalbaseIdentifyTraits, a9 as PalbaseInboxClient, aa as PalbaseInboxListOptions, ab as PalbaseInboxListResult, ac as PalbaseInboxMessage, ad as PalbaseInboxSendParams, ae as PalbaseInboxSendResponse, af as PalbaseInitialLink, ag as PalbaseInvokeOptions, ah as PalbaseLink, ai as PalbaseLinkAnalytics, aj as PalbaseLinkDetails, ak as PalbaseLinksClient, al as PalbaseListLinksOptions, am as PalbaseListLinksResult, an as PalbaseListOptions, ao as PalbaseMatchParams, ap as PalbaseMultiChannelResponse, aq as PalbaseOverviewResult, ar as PalbasePreferences, as as PalbasePreferencesClient, at as PalbasePublicUrlResponse, au as PalbasePushClient, av as PalbasePushSendParams, aw as PalbasePushSendResponse, ax as PalbaseQrCodeOptions, ay as PalbaseQuerySnapshot, az as PalbaseRealtimeChannel, aA as PalbaseRealtimeClient, aB as PalbaseRealtimeMessage, aC as PalbaseRegisterDeviceParams, aD as PalbaseResult, aE as PalbaseRetentionQueryInput, aF as PalbaseRetentionResult, aG as PalbaseSession, aH as PalbaseSignedUrlResponse, aI as PalbaseSmsClient, aJ as PalbaseSmsSendParams, aK as PalbaseSmsSendResponse, aL as PalbaseTransformOptions, aM as PalbaseUpdateLinkParams, aN as PalbaseUploadOptions, aO as PalbaseUser, aP as PalbaseUserDetailResult, aQ as PalbaseUsersQueryInput, aR as PalbaseUsersResult, aS as PalbaseVerifyRequestSignatureParams, aT as PalbaseWhereOperator, aU as TxClient, aV as defineMiddleware } from './endpoint-DJ98tQd6.cjs';
3
3
  import { AsyncLocalStorage } from 'node:async_hooks';
4
- import { T as TableDef, C as ColIsOptionalOnInsert, a as ColValue, S as SchemaDef } from './schema-BqfEhIC0.cjs';
5
- export { b as ColumnBuilder, c as ColumnDef, d as ColumnType, O as OnDeleteAction, e as boolean, f as defineSchema, g as enumType, i as integer, j as jsonb, t as table, h as text, k as timestamp, u as uuid } from './schema-BqfEhIC0.cjs';
4
+ import { E as EnvTypedDatabase, S as SchemaDef } from './index-CZAwpQE1.cjs';
5
+ export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EnvTables, e as EnvTypedTable, f as EnvTypedTx, I as InsertShape, O as OnDeleteAction, R as RowShape, g as SchemaInput, T as TableDef, h as TypedDB, i as TypedTable, j as TypedTx, k as boolean, l as defineSchema, m as enumType, n as integer, o as jsonb, p as makeTypedDB, t as text, q as timestamp, u as uuid } from './index-CZAwpQE1.cjs';
6
+ export { TableTypes, Tables } from './db/env.cjs';
7
+ import { ZodSchema, z } from 'zod';
6
8
  export { z } from 'zod';
7
9
 
8
- /**
9
- * typed-db.ts — Task 2: TypedDB schema-derived insert/row shapes.
10
- *
11
- * Derives INSERT and full-row TypeScript types from a `defineSchema()` result
12
- * and wraps the untyped runtime `DBClient` with a typed facade.
13
- *
14
- * No value-any. No `as unknown as X`. The two narrow `as` casts in
15
- * `makeTypedTable` are safe because:
16
- * - `data as Record<string, unknown>`: InsertShape<T> maps string keys to
17
- * typed values; all value types are subsets of `unknown`, so the cast is
18
- * structurally sound.
19
- * - `result as RowShape<T>`: The runtime DBClient returns `Record<string,
20
- * unknown>` which is the erased form of the typed row; we're narrowing back
21
- * to the precise shape that the schema declared.
22
- * Both casts are narrowing only (not widening) and correctness is guaranteed
23
- * by the schema the caller provides.
24
- */
25
-
26
- /** Keys of C whose columns are required on INSERT (not nullable, no default). */
27
- type RequiredKeys<C> = {
28
- [K in keyof C]: ColIsOptionalOnInsert<C[K]> extends true ? never : K;
29
- }[keyof C];
30
- /** Keys of C whose columns are optional on INSERT (nullable or has a default). */
31
- type OptionalKeys<C> = {
32
- [K in keyof C]: ColIsOptionalOnInsert<C[K]> extends true ? K : never;
33
- }[keyof C];
34
- /**
35
- * The TypeScript type for an INSERT payload for table `T`.
36
- * - Required: columns that are NOT NULL and have no DB-level default.
37
- * - Optional: columns that are nullable or carry a default.
38
- *
39
- * When all columns are optional, `RequiredKeys<C>` resolves to `never` and
40
- * the first part becomes `{}`, which is a neutral element for `&`.
41
- */
42
- type InsertShape<T extends TableDef> = {
43
- [K in RequiredKeys<T["columns"]>]: ColValue<T["columns"][K]>;
44
- } & {
45
- [K in OptionalKeys<T["columns"]>]?: ColValue<T["columns"][K]>;
46
- };
47
- /**
48
- * The TypeScript type for a full row returned by the DB for table `T`.
49
- * Every column is present; nullable columns resolve to `T | null`.
50
- */
51
- type RowShape<T extends TableDef> = {
52
- [K in keyof T["columns"]]: ColValue<T["columns"][K]>;
53
- };
54
- /** A typed table accessor that mirrors the runtime DBClient surface. */
55
- interface TypedTable<T extends TableDef> {
56
- insert(data: InsertShape<T>): Promise<RowShape<T>>;
57
- update(id: string, data: Partial<InsertShape<T>>): Promise<RowShape<T>>;
58
- delete(id: string): Promise<void>;
59
- findById(id: string): Promise<RowShape<T> | null>;
60
- findMany(query?: Partial<RowShape<T>>): Promise<RowShape<T>[]>;
61
- }
62
- /** A typed DB facade covering all tables declared in schema `S`. */
63
- interface TypedDB<S extends SchemaDef> {
64
- tables: {
65
- [K in keyof S["tables"]]: TypedTable<S["tables"][K]>;
66
- };
67
- transaction<T>(fn: (tx: TypedTx<S>) => Promise<T>): Promise<T>;
68
- }
69
- /** Transaction-scoped typed facade: same typed tables, no nested transaction. */
70
- interface TypedTx<S extends SchemaDef> {
71
- tables: {
72
- [K in keyof S["tables"]]: TypedTable<S["tables"][K]>;
73
- };
74
- }
75
- /**
76
- * Wraps a raw `DBClient` with the type-safe `TypedDB<S>` facade derived from
77
- * the provided schema. No behavior change — all calls delegate to `raw` with
78
- * the table name as a plain string.
79
- *
80
- * `buildTables` is the reusable factory that wraps any op-bearing client
81
- * (`TxClient` — the surface shared by `DBClient` and the transaction-scoped
82
- * client) into the typed tables map. It is used both for the top-level db
83
- * (wrapping `raw`) and inside `transaction`, where it wraps the raw `TxClient`
84
- * the runtime yields so the callback sees the same typed `.tables` API.
85
- *
86
- * `transaction` delegates straight to `raw.transaction`; the two narrow
87
- * `as TypedTx<S>` / `as TypedDB<S>` casts are single structural narrowings
88
- * from the dynamically-built tables object to the precise mapped type (TS
89
- * cannot infer through `Object.keys` iteration) — see module-level doc comment.
90
- */
91
- declare function makeTypedDB<S extends SchemaDef>(schema: S, raw: DBClient): TypedDB<S>;
92
-
93
10
  /**
94
11
  * runtime.ts — request-scoped service singletons.
95
12
  *
@@ -98,8 +15,7 @@ declare function makeTypedDB<S extends SchemaDef>(schema: S, raw: DBClient): Typ
98
15
  *
99
16
  * import { Database, Documents, Cache } from "@palbase/backend";
100
17
  *
101
- * export default defineEndpoint({
102
- * method: "POST",
18
+ * export default defineHandler({
103
19
  * handler: async (req) => {
104
20
  * const row = await Database.insert("todos", { title: req.input.title });
105
21
  * return row;
@@ -176,10 +92,22 @@ declare function __runWithRuntime<T>(services: RuntimeServices, fn: () => T): T;
176
92
  * process-global fallback (dev-server / tests). NOT part of the public
177
93
  * author-facing API — used by the runtime and the singleton Proxies. */
178
94
  declare function __getRuntime(): RuntimeServices;
179
- /** The project's own Postgres (pgx, schema `env_<envId>`). Typed CRUD +
180
- * `query`/`transaction`. For a typed `.tables.<name>` API, wrap with
181
- * {@link typedDatabase}. */
182
- declare const Database: DBClient;
95
+ /**
96
+ * The project's own Postgres (pgx, schema `env_<envId>`).
97
+ *
98
+ * Typed by default: `Database.tables.<name>.insert({...})` is typed against
99
+ * the project's generated `palbase-env.d.ts` with NO import and NO generic.
100
+ * The raw string ops (`query`/`insert`/`update`/`delete`/`findById`/`findMany`)
101
+ * are also available for dynamic table names and read-only SQL.
102
+ *
103
+ * @example
104
+ * import { Database } from "@palbase/backend";
105
+ *
106
+ * const todo = await Database.tables.todos.insert({ title: req.input.title });
107
+ * todo.id; // string ✓
108
+ * const rows = await Database.query("SELECT id FROM todos WHERE done = $1", [false]);
109
+ */
110
+ declare const Database: EnvTypedDatabase;
183
111
  /** Firestore-like document client (PalDocs). */
184
112
  declare const Documents: PalbaseDocsClient;
185
113
  /** Object storage client (buckets, signed URLs). */
@@ -194,31 +122,255 @@ declare const Log: Logger;
194
122
  declare const Notifications: PalbaseNotificationsClient;
195
123
  /** Feature flags. */
196
124
  declare const Flags: PalbaseFlagsClient;
125
+
197
126
  /**
198
- * Type the `Database` singleton against a `defineSchema()` result, returning a
199
- * facade with a typed `.tables.<name>.insert(...)` API alongside the raw
200
- * `query`/`transaction` ops.
127
+ * env-gen.ts — generate the `palbase-env.d.ts` text from a `defineSchema()`
128
+ * result.
201
129
  *
202
- * const Db = typedDatabase(schema);
203
- * const todo = await Db.tables.todos.insert({ title: "x" });
130
+ * The CLI (`palbase serve` / codegen) and the deploy pipeline call
131
+ * {@link makeEnvDts} with the project's schema and write the returned string to
132
+ * `palbase-env.d.ts` at the project root. That file AUGMENTS the
133
+ * `@palbase/backend/env` `Tables` interface (controlled global augmentation,
134
+ * C5) so `Database.tables.<name>` is typed with no import and no generic.
204
135
  *
205
- * This is per-endpoint (not global module augmentation), so one endpoint's
206
- * tables never leak into another's `Database` type.
136
+ * The output is FLAT: each table gets a `{ row: {...}; insert: {...} }` entry
137
+ * with plain TypeScript object types. The phantom `ColumnBuilder<...>` type
138
+ * NEVER appears in the generated `.d.ts` — that type only lives at authoring
139
+ * time inside `db/schema.ts`.
207
140
  */
208
- declare function typedDatabase<TSchema extends SchemaDef>(schema: TSchema): TypedDB<TSchema> & DBClient;
209
141
 
210
- /** Context injected into worker handlers — the non-request-scoped service
211
- * surface (db/log/cache/queue + module clients), plus correlation ids. Workers
212
- * are not part of the Phase 1 `ctx → PBRequest` redesign, so they keep their
213
- * own `ctx`; the job payload arrives as the handler's second argument. */
214
- interface WorkerContext extends PalbaseModuleClients {
215
- user: User | null;
216
- db: DBClient;
142
+ /**
143
+ * Generate the full `palbase-env.d.ts` text for a schema.
144
+ *
145
+ * @example
146
+ * import { makeEnvDts } from "@palbase/backend";
147
+ * import schema from "./db/schema.js";
148
+ * writeFileSync("palbase-env.d.ts", makeEnvDts(schema));
149
+ */
150
+ declare function makeEnvDts(schema: SchemaDef): string;
151
+
152
+ /**
153
+ * handler.ts — `defineHandler`: an endpoint UNIT (schema + thin logic), one per
154
+ * file, with NO routing.
155
+ *
156
+ * Everything that types `req` lives here (colocated): `auth` → `req.user`
157
+ * nullability, `input` → `req.input`, `errors` → `req.errors`, `output` → the
158
+ * return type. There is NO `method`/`path` on a handler — the HTTP verb + path
159
+ * are declared in a controller's route map, NOT on the handler. A handler file
160
+ * does:
161
+ *
162
+ * // handlers/places/import-nearby.ts
163
+ * export default defineHandler({ auth, input, output, errors, handler });
164
+ *
165
+ * # Runtime-readable shape (read by the Go runtime's extract_meta.js)
166
+ *
167
+ * `defineHandler` returns a {@link HandlerDef}: a plain object marked with
168
+ * `__palbase: "handler"` carrying the optional `auth`/`input`/`output`/`errors`
169
+ * and the `handler` function. There is deliberately NO `method`/`path` on it —
170
+ * a handler is route-agnostic.
171
+ */
172
+ /** Configuration accepted by {@link defineHandler}. Carries the schema +
173
+ * auth/errors/middleware that type `req`, but NO `method` (routing lives in
174
+ * controllers). */
175
+ interface HandlerConfig<TInputSchema extends ZodSchema = ZodSchema, TOutputSchema extends ZodSchema = ZodSchema, TAuth extends AuthSpec | undefined = undefined, TErrors extends ErrorMap | undefined = undefined> {
176
+ auth?: TAuth;
177
+ rateLimit?: RateLimitConfig;
178
+ input?: TInputSchema;
179
+ output?: TOutputSchema;
180
+ errors?: TErrors;
181
+ middleware?: Middleware[];
182
+ handler: (req: PBRequest<z.infer<TInputSchema>, IsAuthed<TAuth>, TErrors>) => Promise<z.infer<TOutputSchema>> | z.infer<TOutputSchema>;
183
+ }
184
+ /**
185
+ * The runtime-readable handler descriptor returned by {@link defineHandler}.
186
+ *
187
+ * Shape (the Go runtime's `extract_meta.js` reads this off the default export):
188
+ *
189
+ * {
190
+ * __palbase: "handler",
191
+ * auth?: AuthSpec,
192
+ * rateLimit?: RateLimitConfig,
193
+ * input?: ZodSchema,
194
+ * output?: ZodSchema,
195
+ * errors?: ErrorMap,
196
+ * middleware?: Middleware[],
197
+ * handler: (req) => result, // the invoked function
198
+ * }
199
+ *
200
+ * NOTE: there is NO `method`/`path` — those come from the controller route map.
201
+ */
202
+ interface HandlerDef<TInputSchema extends ZodSchema = ZodSchema, TOutputSchema extends ZodSchema = ZodSchema, TAuth extends AuthSpec | undefined = undefined, TErrors extends ErrorMap | undefined = undefined> {
203
+ /** Discriminant the runtime + a controller route check read. */
204
+ readonly __palbase: "handler";
205
+ auth?: TAuth;
206
+ rateLimit?: RateLimitConfig;
207
+ input?: TInputSchema;
208
+ output?: TOutputSchema;
209
+ errors?: TErrors;
210
+ middleware?: Middleware[];
211
+ handler: (req: PBRequest<z.infer<TInputSchema>, IsAuthed<TAuth>, TErrors>) => Promise<z.infer<TOutputSchema>> | z.infer<TOutputSchema>;
212
+ }
213
+ /**
214
+ * A {@link HandlerDef} with its schema/auth/errors type params ERASED — the
215
+ * shape a controller's `route.*` stores. EVERY `defineHandler()` result (any
216
+ * `auth`/`input`/`output`/`errors`) is assignable to this, because `handler` is
217
+ * typed `(req: never) => unknown` (params are contravariant, so a handler taking
218
+ * any concrete `PBRequest` satisfies a `never` param). A controller only needs
219
+ * to route + carry the handler; the handler's own `req` typing is validated
220
+ * where it is defined, so erasing the params here is sound and lets a route
221
+ * accept a handler regardless of its `auth`/`errors` — without `any`.
222
+ */
223
+ interface AnyHandlerDef {
224
+ readonly __palbase: "handler";
225
+ auth?: AuthSpec;
226
+ rateLimit?: RateLimitConfig;
227
+ input?: ZodSchema;
228
+ output?: ZodSchema;
229
+ errors?: ErrorMap;
230
+ middleware?: Middleware[];
231
+ handler: (req: never) => unknown;
232
+ }
233
+ /**
234
+ * Define an endpoint handler (schema + thin logic), with full `req` inference
235
+ * and NO routing. Mounted by a controller's `route.*` map.
236
+ *
237
+ * @example
238
+ * import { defineHandler, z, Database } from "@palbase/backend";
239
+ *
240
+ * export default defineHandler({
241
+ * auth: { required: true },
242
+ * input: z.object({ title: z.string() }),
243
+ * output: z.object({ id: z.string() }),
244
+ * errors: { titleTaken: { status: 409, code: "title_taken" } },
245
+ * handler: (req) => Database.tables.todos.insert({ title: req.input.title }),
246
+ * });
247
+ */
248
+ declare function defineHandler<TInputSchema extends ZodSchema, TOutputSchema extends ZodSchema, const TAuth extends AuthSpec | undefined = undefined, const TErrors extends ErrorMap | undefined = undefined>(config: HandlerConfig<TInputSchema, TOutputSchema, TAuth, TErrors>): HandlerDef<TInputSchema, TOutputSchema, TAuth, TErrors>;
249
+
250
+ /**
251
+ * controller.ts — `defineController` + `route.*`: the ROUTE MAP (method+path →
252
+ * handler). Logic cannot be written here — a controller only wires existing
253
+ * handlers, so the small-blast-radius / no-cross-file-type-sync property holds.
254
+ *
255
+ * ```ts
256
+ * // controllers/places.controller.ts
257
+ * import { defineController, route } from "@palbase/backend";
258
+ * import importNearby from "../handlers/places/import-nearby.js";
259
+ * import listFavorites from "../handlers/places/list-favorites.js";
260
+ *
261
+ * export default defineController("/places", {
262
+ * importNearby: route.post("/import", importNearby), // map key = sugar
263
+ * listFavorites: route.get ("/favorites", listFavorites),
264
+ * });
265
+ * ```
266
+ *
267
+ * # Runtime-readable object shapes (read by the Go runtime's extract_meta.js)
268
+ *
269
+ * The default export of a controller file is a `ControllerDef`:
270
+ *
271
+ * ControllerDef = {
272
+ * __palbase: "controller",
273
+ * basePath: string, // e.g. "/places"
274
+ * routes: { [mapKey: string]: RouteDef } // mapKey is AUTHORING SUGAR only
275
+ * }
276
+ *
277
+ * RouteDef = {
278
+ * __palbase: "route",
279
+ * method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE", // upper-case
280
+ * path: string, // the SUBPATH passed to route.*(…), e.g. "/import"
281
+ * handler: HandlerDef, // the imported defineHandler() result
282
+ * }
283
+ *
284
+ * HandlerDef = {
285
+ * __palbase: "handler",
286
+ * auth?, rateLimit?, input?, output?, errors?, middleware?,
287
+ * handler: (req) => result,
288
+ * }
289
+ *
290
+ * The FULL path for a route is `basePath + path` (e.g. "/places" + "/import" =
291
+ * "/places/import"). The operationId is NOT computed here — the runtime
292
+ * `generator.go` derives it FLAT from `(method, full-path)` (e.g.
293
+ * `postPlacesImport`). The map key (`importNearby`) is authoring sugar and is
294
+ * NOT the operationId.
295
+ */
296
+ /** The five HTTP verbs a route may declare, upper-cased (matches the runtime
297
+ * router + OpenAPI which lower-cases on its own). */
298
+ type HttpMethodUpper = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
299
+ /**
300
+ * A single route entry: the HTTP verb, the SUBPATH (relative to the
301
+ * controller's `basePath`), and the handler to invoke. Produced by `route.*`.
302
+ */
303
+ interface RouteDef<H extends AnyHandlerDef = AnyHandlerDef, M extends HttpMethodUpper = HttpMethodUpper> {
304
+ /** Discriminant the runtime + `defineController` read. */
305
+ readonly __palbase: "route";
306
+ /** Upper-case HTTP verb. */
307
+ method: M;
308
+ /** The subpath passed to `route.*(subpath, handler)` (relative to basePath). */
309
+ path: string;
310
+ /** The handler (a `defineHandler()` result) this route invokes. */
311
+ handler: H;
312
+ }
313
+ /** The route map a controller declares: keys are authoring sugar, values must
314
+ * each be a `route.*()` result. The mapped-over `Record<string, RouteDef>`
315
+ * constraint is what makes a bare handler (or plain object) a TS error. */
316
+ type RouteMap = Record<string, RouteDef>;
317
+ /**
318
+ * The controller descriptor returned by {@link defineController}. The default
319
+ * export of a `controllers/*.ts` file.
320
+ */
321
+ interface ControllerDef<R extends RouteMap = RouteMap> {
322
+ /** Discriminant the runtime reads. */
323
+ readonly __palbase: "controller";
324
+ /** The path every route in this controller is mounted under (e.g. "/places"). */
325
+ basePath: string;
326
+ /** The route map — keys are authoring sugar, values are RouteDefs. */
327
+ routes: R;
328
+ }
329
+ /**
330
+ * Route builders — one per HTTP verb. Each takes the SUBPATH (relative to the
331
+ * controller `basePath`) and the handler to mount there.
332
+ *
333
+ * @example
334
+ * import { defineController, route } from "@palbase/backend";
335
+ * import create from "../handlers/todos/create.js";
336
+ *
337
+ * export default defineController("/todos", {
338
+ * create: route.post("/", create),
339
+ * });
340
+ */
341
+ declare const route: {
342
+ readonly get: <H extends AnyHandlerDef>(path: string, handler: H) => RouteDef<H, "GET">;
343
+ readonly post: <H extends AnyHandlerDef>(path: string, handler: H) => RouteDef<H, "POST">;
344
+ readonly put: <H extends AnyHandlerDef>(path: string, handler: H) => RouteDef<H, "PUT">;
345
+ readonly patch: <H extends AnyHandlerDef>(path: string, handler: H) => RouteDef<H, "PATCH">;
346
+ readonly delete: <H extends AnyHandlerDef>(path: string, handler: H) => RouteDef<H, "DELETE">;
347
+ };
348
+ /**
349
+ * Define a controller: a base path + a route map (method+path → handler). The
350
+ * route-map KEY is authoring sugar only (NOT the operationId). Each route value
351
+ * MUST be a `route.*()` result — a bare handler or plain object is a TS error,
352
+ * which is what keeps logic out of controllers structurally.
353
+ *
354
+ * @example
355
+ * import { defineController, route } from "@palbase/backend";
356
+ * import create from "../handlers/todos/create.js";
357
+ * import list from "../handlers/todos/list.js";
358
+ *
359
+ * export default defineController("/todos", {
360
+ * create: route.post("/", create),
361
+ * list: route.get("/", list),
362
+ * });
363
+ */
364
+ declare function defineController<const R extends RouteMap>(basePath: string, routes: R): ControllerDef<R>;
365
+
366
+ /** Non-service, per-invocation data for background worker handlers.
367
+ * Services (Database, Log, …) are imported as singletons, not passed here. */
368
+ interface WorkerMeta {
369
+ /** Branch-scoped env vars. */
217
370
  env: Record<string, string>;
218
- log: Logger;
219
- cache: CacheClient;
220
- queue: QueueClient;
221
- errors: ErrorThrowers<undefined>;
371
+ /** The user that enqueued the job, if any (background jobs are usually system-initiated). */
372
+ user: User | null;
373
+ /** Per-invocation id for correlation. */
222
374
  requestId: string;
223
375
  projectId: string;
224
376
  environmentId: string;
@@ -236,7 +388,7 @@ interface WorkerConfig<TPayload = unknown> {
236
388
  /** Backoff strategy between retries. Defaults to "exponential". */
237
389
  backoff?: BackoffStrategy;
238
390
  /** Handler function that processes the job payload. */
239
- handler: (ctx: WorkerContext, payload: TPayload) => Promise<void>;
391
+ handler: (payload: TPayload, meta: WorkerMeta) => Promise<void>;
240
392
  }
241
393
  /** Resolved worker configuration with defaults applied. */
242
394
  interface ResolvedWorkerConfig<TPayload = unknown> {
@@ -244,7 +396,7 @@ interface ResolvedWorkerConfig<TPayload = unknown> {
244
396
  retry: number;
245
397
  timeout: number;
246
398
  backoff: BackoffStrategy;
247
- handler: (ctx: WorkerContext, payload: TPayload) => Promise<void>;
399
+ handler: (payload: TPayload, meta: WorkerMeta) => Promise<void>;
248
400
  }
249
401
  /**
250
402
  * Define a background worker that processes jobs from the queue.
@@ -258,7 +410,7 @@ interface ResolvedWorkerConfig<TPayload = unknown> {
258
410
  * retry: 5,
259
411
  * timeout: 60,
260
412
  * backoff: "exponential",
261
- * handler: async (ctx, payload: { to: string; subject: string }) => {
413
+ * handler: async (payload: { to: string; subject: string }, meta) => {
262
414
  * await sendEmail(payload.to, payload.subject);
263
415
  * },
264
416
  * });
@@ -266,13 +418,11 @@ interface ResolvedWorkerConfig<TPayload = unknown> {
266
418
  */
267
419
  declare function defineWorker<TPayload = unknown>(config: WorkerConfig<TPayload>): ResolvedWorkerConfig<TPayload>;
268
420
 
269
- /** Context injected into job handlers — subset of EndpointContext without request-specific fields. */
270
- interface JobContext extends PalbaseModuleClients {
271
- db: DBClient;
421
+ /** Non-service, per-invocation data for job handlers.
422
+ * Services (Database, Log, …) are imported as singletons, not passed here. */
423
+ interface JobMeta {
424
+ /** Branch-scoped env vars. */
272
425
  env: Record<string, string>;
273
- log: Logger;
274
- cache: CacheClient;
275
- queue: QueueClient;
276
426
  projectId: string;
277
427
  environmentId: string;
278
428
  }
@@ -285,14 +435,14 @@ interface JobConfig {
285
435
  /** Execution timeout in seconds. Defaults to 30. */
286
436
  timeout?: number;
287
437
  /** Job handler function. */
288
- handler: (ctx: JobContext) => Promise<void>;
438
+ handler: (meta: JobMeta) => Promise<void>;
289
439
  }
290
440
  /** Resolved job configuration with defaults applied. */
291
441
  interface ResolvedJobConfig {
292
442
  name: string;
293
443
  schedule: string;
294
444
  timeout: number;
295
- handler: (ctx: JobContext) => Promise<void>;
445
+ handler: (meta: JobMeta) => Promise<void>;
296
446
  }
297
447
  /**
298
448
  * Define a scheduled cron job.
@@ -305,9 +455,9 @@ interface ResolvedJobConfig {
305
455
  * name: "cleanup-expired",
306
456
  * schedule: "0 3 * * *", // every day at 3 AM
307
457
  * timeout: 60,
308
- * handler: async (ctx) => {
309
- * await ctx.db.delete("sessions", "expired < NOW()");
310
- * ctx.log.info("Cleaned up expired sessions");
458
+ * handler: async (meta) => {
459
+ * await Database.delete("sessions", "expired < NOW()");
460
+ * Log.info("Cleaned up expired sessions");
311
461
  * },
312
462
  * });
313
463
  * ```
@@ -316,16 +466,15 @@ declare function defineJob(config: JobConfig): ResolvedJobConfig;
316
466
 
317
467
  /** Supported webhook provider types. */
318
468
  type WebhookProvider = "stripe" | "github" | "twilio" | "sendgrid" | "slack" | "discord" | "livekit";
319
- /** Context injected into webhook handlers — no user (webhooks are machine-to-machine). */
320
- interface WebhookContext extends PalbaseModuleClients {
321
- db: DBClient;
469
+ /** Non-service, per-invocation data for webhook handlers.
470
+ * Services (Database, Log, …) are imported as singletons, not passed here. */
471
+ interface WebhookMeta {
472
+ /** Branch-scoped env vars. */
322
473
  env: Record<string, string>;
323
- log: Logger;
324
- cache: CacheClient;
325
- queue: QueueClient;
474
+ /** Per-invocation id for correlation. */
475
+ requestId: string;
326
476
  projectId: string;
327
477
  environmentId: string;
328
- requestId: string;
329
478
  }
330
479
  /** Secret reference — resolves from environment variables at runtime. */
331
480
  interface EnvSecretRef {
@@ -386,7 +535,7 @@ interface ProviderEventMap {
386
535
  };
387
536
  }
388
537
  /** Event handler function type. */
389
- type WebhookEventHandler<TEvent = Record<string, unknown>> = (ctx: WebhookContext, event: TEvent) => Promise<void>;
538
+ type WebhookEventHandler<TEvent = Record<string, unknown>> = (event: TEvent, meta: WebhookMeta) => Promise<void>;
390
539
  /** Provider-based webhook configuration. */
391
540
  interface ProviderWebhookConfig<P extends WebhookProvider = WebhookProvider> {
392
541
  provider: P;
@@ -406,7 +555,7 @@ interface WebhookRequest {
406
555
  interface CustomWebhookConfig {
407
556
  path: string;
408
557
  verify?: (req: WebhookRequest) => Promise<boolean> | boolean;
409
- handler: (ctx: WebhookContext, payload: Record<string, unknown>) => Promise<void>;
558
+ handler: (payload: Record<string, unknown>, meta: WebhookMeta) => Promise<void>;
410
559
  }
411
560
  /** Resolved provider webhook (internal). */
412
561
  interface ResolvedProviderWebhook<P extends WebhookProvider = WebhookProvider> {
@@ -420,7 +569,7 @@ interface ResolvedCustomWebhook {
420
569
  type: "custom";
421
570
  path: string;
422
571
  verify?: (req: WebhookRequest) => Promise<boolean> | boolean;
423
- handler: (ctx: WebhookContext, payload: Record<string, unknown>) => Promise<void>;
572
+ handler: (payload: Record<string, unknown>, meta: WebhookMeta) => Promise<void>;
424
573
  }
425
574
  /** Union of resolved webhook types. */
426
575
  type ResolvedWebhookConfig = ResolvedProviderWebhook | ResolvedCustomWebhook;
@@ -433,8 +582,8 @@ type ResolvedWebhookConfig = ResolvedProviderWebhook | ResolvedCustomWebhook;
433
582
  * provider: "stripe",
434
583
  * secret: { env: "STRIPE_WEBHOOK_SECRET" },
435
584
  * events: {
436
- * "checkout.session.completed": async (ctx, event) => {
437
- * await ctx.db.insert("orders", { status: "paid" });
585
+ * "checkout.session.completed": async (event, meta) => {
586
+ * await Database.insert("orders", { status: "paid" });
438
587
  * },
439
588
  * },
440
589
  * });
@@ -449,21 +598,111 @@ declare function defineWebhook<P extends WebhookProvider>(config: ProviderWebhoo
449
598
  * export default defineWebhook({
450
599
  * path: "/webhooks/livekit",
451
600
  * verify: async (req) => req.headers["x-api-key"] === "secret",
452
- * handler: async (ctx, payload) => {
453
- * ctx.log.info("Received webhook", payload);
601
+ * handler: async (payload, meta) => {
602
+ * Log.info("Received webhook", payload);
454
603
  * },
455
604
  * });
456
605
  * ```
457
606
  */
458
607
  declare function defineWebhook(config: CustomWebhookConfig): ResolvedCustomWebhook;
459
608
 
460
- /** Context injected into hook handlers. */
461
- interface HookContext extends PalbaseModuleClients {
462
- db: DBClient;
609
+ /**
610
+ * resource.ts external connections as lifecycle-managed classes.
611
+ *
612
+ * A `Resource` subclass models one external connection (a pooled datastore, a
613
+ * stateless API client, or a per-user factory). The framework discovers each
614
+ * instance, calls `init(env)` ONCE at boot with the declared secret subset, and
615
+ * `shutdown()` (reverse order) on SIGTERM. On top of that lifecycle the author
616
+ * exposes their own clean facade methods.
617
+ *
618
+ * // resources/neo4j.ts
619
+ * import { Resource } from "@palbase/backend";
620
+ * import neo4j, { type Driver, type Session } from "neo4j-driver";
621
+ *
622
+ * export class Neo4jResource extends Resource {
623
+ * static secrets = ["NEO4J_URL", "NEO4J_USER", "NEO4J_PASSWORD"] as const;
624
+ * private driver!: Driver;
625
+ * async init(env: { NEO4J_URL: string; NEO4J_USER: string; NEO4J_PASSWORD: string }) {
626
+ * this.driver = neo4j.driver(env.NEO4J_URL, neo4j.auth.basic(env.NEO4J_USER, env.NEO4J_PASSWORD));
627
+ * }
628
+ * async shutdown() { await this.driver.close(); }
629
+ * session(): Session { return this.driver.session(); }
630
+ * }
631
+ * export const neo4j = new Neo4jResource(); // framework finds + manages it
632
+ *
633
+ * # Boot scope (NOT request-ALS)
634
+ *
635
+ * Resources are instantiated once at process boot. This is deliberately NOT the
636
+ * per-request {@link AsyncLocalStorage} scope used for `Database`/`Cache`/… — a
637
+ * connection pool must outlive a single request. The runtime discovers
638
+ * resources from the project's `resources/` directory, registers each via
639
+ * {@link __registerResource}, then calls {@link __runResourceBoot} before
640
+ * serving and {@link __shutdownResources} on SIGTERM. Discovery is a runtime
641
+ * concern; the SDK provides the base class + registry + boot/shutdown hooks.
642
+ */
643
+ /** Map a declared `secrets` tuple to the `init(env)` argument type — a record
644
+ * over the secret names, each `string`. An empty tuple maps to an empty
645
+ * record. */
646
+ type ResourceEnv<Secrets extends readonly string[]> = {
647
+ [K in Secrets[number]]: string;
648
+ };
649
+ /**
650
+ * Base class for external connections.
651
+ *
652
+ * - `static secrets` — OPTIONAL readonly tuple of env-var names this resource
653
+ * needs. Drives (a) the `env` type passed to `init` and (b) the
654
+ * missing-secret check at boot (deploy fails naming the absent secret).
655
+ * - `init(env)` — called ONCE at boot with the declared secret subset. May be
656
+ * sync (`void`) or async (`Promise<void>`).
657
+ * - `shutdown()` — OPTIONAL drain hook, called on SIGTERM in reverse boot
658
+ * order.
659
+ *
660
+ * @example
661
+ * import { Resource } from "@palbase/backend";
662
+ * import { Client } from "@googlemaps/google-maps-services-js";
663
+ *
664
+ * export class GoogleResource extends Resource {
665
+ * static secrets = ["GOOGLE_MAPS_KEY"] as const;
666
+ * private client = new Client();
667
+ * private key = "";
668
+ * init(env: { GOOGLE_MAPS_KEY: string }) { this.key = env.GOOGLE_MAPS_KEY; }
669
+ * }
670
+ * export const google = new GoogleResource();
671
+ */
672
+ declare abstract class Resource {
673
+ /** The env-var names this resource needs. Optional; omit for none. */
674
+ static secrets?: readonly string[];
675
+ /** Set up the connection from the declared secrets. Called once at boot. */
676
+ abstract init(env: Record<string, string>): void | Promise<void>;
677
+ /** Drain/close the connection on SIGTERM. Optional. */
678
+ shutdown?(): void | Promise<void>;
679
+ }
680
+ /**
681
+ * Register a resource instance with the boot registry. The runtime calls this
682
+ * for each instance discovered under the project's `resources/` directory.
683
+ * NOT part of the public author-facing API (prefixed `__`).
684
+ */
685
+ declare function __registerResource(resource: Resource): void;
686
+ /**
687
+ * Boot every registered resource that has not yet been booted: resolve its
688
+ * declared secret subset from `envMap`, then await its `init(env)`. Idempotent
689
+ * — an already-booted resource is skipped. Throws (failing deploy/boot) when a
690
+ * declared secret is absent, naming the missing secret. NOT part of the public
691
+ * author-facing API.
692
+ */
693
+ declare function __runResourceBoot(envMap: Record<string, string>): Promise<void>;
694
+ /**
695
+ * Shut down every booted resource in REVERSE registration order, awaiting each
696
+ * `shutdown()` (a no-op when undefined). Clears the registry afterwards so a
697
+ * second call is a no-op. NOT part of the public author-facing API.
698
+ */
699
+ declare function __shutdownResources(): Promise<void>;
700
+
701
+ /** Non-service, per-invocation data for hook handlers.
702
+ * Services (Database, Log, …) are imported as singletons, not passed here. */
703
+ interface HookMeta {
704
+ /** Branch-scoped env vars. */
463
705
  env: Record<string, string>;
464
- log: Logger;
465
- cache: CacheClient;
466
- queue: QueueClient;
467
706
  projectId: string;
468
707
  environmentId: string;
469
708
  }
@@ -471,7 +710,8 @@ interface HookContext extends PalbaseModuleClients {
471
710
  interface UserCreatedEvent {
472
711
  user: {
473
712
  id: string;
474
- email: string;
713
+ /** User's email, if they signed up with one (absent for phone-only users). */
714
+ email?: string;
475
715
  role: string;
476
716
  metadata: Record<string, unknown>;
477
717
  createdAt: string;
@@ -481,7 +721,8 @@ interface UserCreatedEvent {
481
721
  interface SignInEvent {
482
722
  user: {
483
723
  id: string;
484
- email: string;
724
+ /** User's email, if they have one (absent for phone-only users). */
725
+ email?: string;
485
726
  role: string;
486
727
  };
487
728
  provider: string;
@@ -491,11 +732,14 @@ interface SignInEvent {
491
732
  interface SignOutEvent {
492
733
  user: {
493
734
  id: string;
494
- email: string;
735
+ /** User's email, if they have one (absent for phone-only users). */
736
+ email?: string;
495
737
  };
496
738
  timestamp: string;
497
739
  }
498
- /** Payload for auth.onPasswordReset hook. */
740
+ /** Payload for auth.onPasswordReset hook.
741
+ * Password reset is inherently email-based, so `email` is always present here
742
+ * (a phone-only passwordless user cannot trigger this event). */
499
743
  interface PasswordResetEvent {
500
744
  user: {
501
745
  id: string;
@@ -548,7 +792,7 @@ interface DocumentDeletedEvent {
548
792
  data: Record<string, unknown>;
549
793
  };
550
794
  }
551
- type HookHandler<TEvent> = (ctx: HookContext, event: TEvent) => Promise<void>;
795
+ type HookHandler<TEvent> = (event: TEvent, meta: HookMeta) => Promise<void>;
552
796
  /** Resolved hook configuration (internal). */
553
797
  interface ResolvedHook<TEvent = unknown> {
554
798
  module: string;
@@ -571,4 +815,4 @@ declare const documents: {
571
815
  onDocumentDeleted(handler: HookHandler<DocumentDeletedEvent>): ResolvedHook<DocumentDeletedEvent>;
572
816
  };
573
817
 
574
- export { type BackoffStrategy, Cache, CacheClient, type CustomWebhookConfig, DBClient, Database, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, type EnvSecretRef, ErrorThrowers, type FileDeletedEvent, type FileUploadedEvent, Flags, type HookContext, type HookHandler, type InsertShape, type JobConfig, type JobContext, Log, Logger, Notifications, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseStorageClient, type PasswordResetEvent, type ProviderEventMap, type ProviderWebhookConfig, Queue, QueueClient, type ResolvedCustomWebhook, type ResolvedHook, type ResolvedJobConfig, type ResolvedProviderWebhook, type ResolvedWebhookConfig, type ResolvedWorkerConfig, type RowShape, type RuntimeServices, SchemaDef, type SignInEvent, type SignOutEvent, Storage, TableDef, type TypedDB, type TypedTable, type TypedTx, User, type UserCreatedEvent, type WebhookContext, type WebhookEventHandler, type WebhookProvider, type WebhookRequest, type WorkerConfig, type WorkerContext, __getRuntime, __requestALS, __runWithRuntime, __setRuntime, auth, defineJob, defineWebhook, defineWorker, documents, makeTypedDB, storage, typedDatabase };
818
+ export { type BackoffStrategy, Cache, CacheClient, type ControllerDef, type CustomWebhookConfig, DBClient, Database, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, type EnvSecretRef, EnvTypedDatabase, ErrorMap, type FileDeletedEvent, type FileUploadedEvent, Flags, type HandlerConfig, type HandlerDef, type HookHandler, type HookMeta, type HttpMethodUpper, type JobConfig, type JobMeta, Log, Logger, Middleware, Notifications, PBRequest, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseStorageClient, type PasswordResetEvent, type ProviderEventMap, type ProviderWebhookConfig, Queue, QueueClient, RateLimitConfig, type ResolvedCustomWebhook, type ResolvedHook, type ResolvedJobConfig, type ResolvedProviderWebhook, type ResolvedWebhookConfig, type ResolvedWorkerConfig, Resource, type ResourceEnv, type RouteDef, type RouteMap, type RuntimeServices, SchemaDef, type SignInEvent, type SignOutEvent, Storage, User, type UserCreatedEvent, type WebhookEventHandler, type WebhookMeta, type WebhookProvider, type WebhookRequest, type WorkerConfig, type WorkerMeta, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, defineController, defineHandler, defineJob, defineWebhook, defineWorker, documents, makeEnvDts, route, storage };