@palbase/backend 3.0.0 → 5.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 (41) hide show
  1. package/dist/{chunk-B7EUJP5W.js → chunk-2N4YNN6F.js} +113 -3
  2. package/dist/chunk-2N4YNN6F.js.map +1 -0
  3. package/dist/{chunk-PHAFZGHN.js → chunk-WUQO76NW.js} +26 -19
  4. package/dist/chunk-WUQO76NW.js.map +1 -0
  5. package/dist/db/index.cjs +117 -2
  6. package/dist/db/index.cjs.map +1 -1
  7. package/dist/db/index.d.cts +2 -2
  8. package/dist/db/index.d.ts +2 -2
  9. package/dist/db/index.js +11 -1
  10. package/dist/{endpoint-DJ98tQd6.d.cts → endpoint-BEHjfvFH.d.cts} +99 -57
  11. package/dist/{endpoint-DJ98tQd6.d.ts → endpoint-BEHjfvFH.d.ts} +99 -57
  12. package/dist/index-BTVdhfsb.d.ts +469 -0
  13. package/dist/index-mr3Co63T.d.cts +469 -0
  14. package/dist/index.cjs +356 -42
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +80 -219
  17. package/dist/index.d.ts +80 -219
  18. package/dist/index.js +203 -21
  19. package/dist/index.js.map +1 -1
  20. package/dist/test/index.cjs +34 -19
  21. package/dist/test/index.cjs.map +1 -1
  22. package/dist/test/index.d.cts +1 -1
  23. package/dist/test/index.d.ts +1 -1
  24. package/dist/test/index.js +10 -2
  25. package/dist/test/index.js.map +1 -1
  26. package/docs/README.md +212 -14
  27. package/docs/database.md +40 -0
  28. package/docs/endpoints.md +110 -92
  29. package/docs/errors.md +37 -30
  30. package/docs/getting-started.md +64 -26
  31. package/docs/llms-full.txt +724 -312
  32. package/docs/llms.txt +1 -1
  33. package/docs/migrations.md +75 -73
  34. package/docs/routing.md +39 -45
  35. package/docs/schema.md +135 -23
  36. package/docs/services.md +13 -10
  37. package/package.json +2 -2
  38. package/dist/chunk-B7EUJP5W.js.map +0 -1
  39. package/dist/chunk-PHAFZGHN.js.map +0 -1
  40. package/dist/index-CXUs9iTQ.d.ts +0 -294
  41. package/dist/index-CZAwpQE1.d.cts +0 -294
package/dist/index.d.cts CHANGED
@@ -1,26 +1,26 @@
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';
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, U as User$1 } from './endpoint-BEHjfvFH.cjs';
2
+ export { f as AuthConfig, B as BadRequest, g as ClientInfo, h as Conflict, i as DBOps, E as ErrorDef, j as ErrorMap, k as ErrorThrowers, F as FileContext, l as Forbidden, H as HttpError, m as HttpMethod, M as Middleware, n as MiddlewareContext, o as MiddlewareHandler, N as NotFound, P as PBRequest, p as PalError, q as PalbaseAnalyticsClient, r as PalbaseAnalyticsManagementNamespace, s as PalbaseAnalyticsProperties, t as PalbaseAnalyticsQueryNamespace, u as PalbaseAttestAndroidParams, v as PalbaseAttestAndroidResult, w as PalbaseAttestiOSParams, x as PalbaseAttestiOSResult, y as PalbaseAuthClient, z as PalbaseBindDeviceParams, G as PalbaseBucketClient, I as PalbaseCmsClient, J as PalbaseCmsFindOneOptions, K as PalbaseCmsFindOptions, O as PalbaseCohortQueryInput, S as PalbaseCohortResult, T as PalbaseCollectionRef, V as PalbaseCountQueryInput, W as PalbaseCountResult, X as PalbaseCreateLinkParams, Y as PalbaseDeviceInfo, Z as PalbaseDeviceTokenView, _ as PalbaseDocumentRef, $ as PalbaseDocumentSnapshot, a0 as PalbaseEmailClient, a1 as PalbaseEmailSendParams, a2 as PalbaseEmailSendResponse, a3 as PalbaseEventNamesResult, a4 as PalbaseEventsQueryInput, a5 as PalbaseEventsResult, a6 as PalbaseFileObject, a7 as PalbaseFlag, a8 as PalbaseFlagContext, a9 as PalbaseFlagVariant, aa as PalbaseFunctionsClient, ab as PalbaseFunnelQueryInput, ac as PalbaseFunnelResult, ad as PalbaseIdentifyTraits, ae as PalbaseInboxClient, af as PalbaseInboxListOptions, ag as PalbaseInboxListResult, ah as PalbaseInboxMessage, ai as PalbaseInboxSendParams, aj as PalbaseInboxSendResponse, ak as PalbaseInitialLink, al as PalbaseInvokeOptions, am as PalbaseLink, an as PalbaseLinkAnalytics, ao as PalbaseLinkDetails, ap as PalbaseLinksClient, aq as PalbaseListLinksOptions, ar as PalbaseListLinksResult, as as PalbaseListOptions, at as PalbaseMatchParams, au as PalbaseMultiChannelResponse, av as PalbaseOverviewResult, aw as PalbasePreferences, ax as PalbasePreferencesClient, ay as PalbasePublicUrlResponse, az as PalbasePushClient, aA as PalbasePushSendParams, aB as PalbasePushSendResponse, aC as PalbaseQrCodeOptions, aD as PalbaseQuerySnapshot, aE as PalbaseRealtimeChannel, aF as PalbaseRealtimeClient, aG as PalbaseRealtimeMessage, aH as PalbaseRegisterDeviceParams, aI as PalbaseResult, aJ as PalbaseRetentionQueryInput, aK as PalbaseRetentionResult, aL as PalbaseSession, aM as PalbaseSignedUrlResponse, aN as PalbaseSmsClient, aO as PalbaseSmsSendParams, aP as PalbaseSmsSendResponse, aQ as PalbaseTransformOptions, aR as PalbaseUpdateLinkParams, aS as PalbaseUploadOptions, aT as PalbaseUser, aU as PalbaseUserDetailResult, aV as PalbaseUsersQueryInput, aW as PalbaseUsersResult, aX as PalbaseVerifyRequestSignatureParams, aY as PalbaseWhereOperator, aZ as TooManyRequests, a_ as TxClient, a$ as Unauthorized, b0 as defineMiddleware } from './endpoint-BEHjfvFH.cjs';
3
3
  import { AsyncLocalStorage } from 'node:async_hooks';
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';
4
+ import { E as EnvTypedDatabase, S as SchemaDef } from './index-mr3Co63T.cjs';
5
+ export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, f as EnvTables, g as EnvTypedTable, h as EnvTypedTx, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, i as PalbaseExtension, j as PolicyBuilder, k as PolicyCommand, l as PolicyDef, m as PolicyMode, R as RowShape, n as SchemaInput, T as TableDef, o as TableInput, p as TypedDB, q as TypedTable, r as TypedTx, s as boolean, t as defineSchema, u as enumType, v as integer, w as isPalbaseExtension, x as jsonb, y as makeTypedDB, z as policy, A as text, B as timestamp, D as uuid } from './index-mr3Co63T.cjs';
6
6
  export { TableTypes, Tables } from './db/env.cjs';
7
- import { ZodSchema, z } from 'zod';
7
+ import { ZodTypeAny } from 'zod';
8
8
  export { z } from 'zod';
9
9
 
10
10
  /**
11
11
  * runtime.ts — request-scoped service singletons.
12
12
  *
13
13
  * The backend SDK no longer threads a `ctx` god-object through every handler.
14
- * Instead, endpoint authors import PascalCase service singletons directly:
14
+ * Instead, controller methods import PascalCase service singletons directly:
15
15
  *
16
- * import { Database, Documents, Cache } from "@palbase/backend";
16
+ * import { Controller, Post, Body, Database } from "@palbase/backend";
17
17
  *
18
- * export default defineHandler({
19
- * handler: async (req) => {
20
- * const row = await Database.insert("todos", { title: req.input.title });
21
- * return row;
22
- * },
23
- * });
18
+ * \@Controller("/todos")
19
+ * export default class TodosController {
20
+ * \@Post("") create(\@Body(CreateTodoBody) body: CreateTodoBody): unknown {
21
+ * return Database.insert("todos", { title: body.title });
22
+ * }
23
+ * }
24
24
  *
25
25
  * The singletons are thin Proxies. Every property access forwards to the live
26
26
  * client for the CURRENT request scope, resolved through {@link __getRuntime}.
@@ -100,12 +100,17 @@ declare function __getRuntime(): RuntimeServices;
100
100
  * The raw string ops (`query`/`insert`/`update`/`delete`/`findById`/`findMany`)
101
101
  * are also available for dynamic table names and read-only SQL.
102
102
  *
103
+ * RLS is enforced by default (the runtime runs each op as `authenticated` with
104
+ * the verified user's claims). To bypass RLS, call `Database.asService()` —
105
+ * explicit and greppable — which runs as the `service_role` (BYPASSRLS).
106
+ *
103
107
  * @example
104
108
  * import { Database } from "@palbase/backend";
105
109
  *
106
110
  * const todo = await Database.tables.todos.insert({ title: req.input.title });
107
111
  * todo.id; // string ✓
108
112
  * const rows = await Database.query("SELECT id FROM todos WHERE done = $1", [false]);
113
+ * const all = await Database.asService().tables.todos.findMany({}); // RLS bypass
109
114
  */
110
115
  declare const Database: EnvTypedDatabase;
111
116
  /** Firestore-like document client (PalDocs). */
@@ -149,219 +154,75 @@ declare const Flags: PalbaseFlagsClient;
149
154
  */
150
155
  declare function makeEnvDts(schema: SchemaDef): string;
151
156
 
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";
157
+ /** Options accepted by `@Controller`. */
158
+ interface ControllerOptions {
159
+ /** Default auth for ALL routes in this controller (route-level overrides). */
225
160
  auth?: AuthSpec;
226
- rateLimit?: RateLimitConfig;
227
- input?: ZodSchema;
228
- output?: ZodSchema;
229
- errors?: ErrorMap;
230
- middleware?: Middleware[];
231
- handler: (req: never) => unknown;
232
161
  }
233
162
  /**
234
- * Define an endpoint handler (schema + thin logic), with full `req` inference
235
- * and NO routing. Mounted by a controller's `route.*` map.
163
+ * Mark a class as a Palbase backend controller. `basePath` is the mount path
164
+ * for every route the class declares; `options.auth` sets the controller-level
165
+ * default auth (a route's own `auth` overrides it; absent ⇒ secure-by-default).
236
166
  *
237
167
  * @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
- * });
168
+ * \@Controller("/todos", { auth: false })
169
+ * export class TodosController {
170
+ * \@Get("") list(\@Query(ListTodosQuery) q: ListTodosQuery): TodoSchema[] { … }
171
+ * }
247
172
  */
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>;
173
+ declare function Controller(basePath: string, options?: ControllerOptions): <T extends abstract new (...args: never[]) => object>(ctor: T) => T;
249
174
 
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). */
175
+ /** The HTTP verbs a route may declare, upper-cased (the runtime router +
176
+ * OpenAPI lower-case on their own). */
298
177
  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;
178
+ /** Route-level options accepted by the method decorators (`@Get`/`@Post`/…). */
179
+ interface RouteOptions {
180
+ /** OVERRIDES the controller-level default auth for this one route. */
181
+ auth?: AuthSpec;
182
+ /** Per-route rate limit. */
183
+ rateLimit?: RateLimitConfig;
328
184
  }
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>;
185
+
186
+ /** A legacy method decorator. */
187
+ type MethodDecorator = (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void;
188
+ /** `@Get(subpath, options?)` — declare a GET route. */
189
+ declare const Get: (subpath: string, options?: RouteOptions) => MethodDecorator;
190
+ /** `@Post(subpath, options?)` declare a POST route. */
191
+ declare const Post: (subpath: string, options?: RouteOptions) => MethodDecorator;
192
+ /** `@Put(subpath, options?)` — declare a PUT route. */
193
+ declare const Put: (subpath: string, options?: RouteOptions) => MethodDecorator;
194
+ /** `@Patch(subpath, options?)` — declare a PATCH route. */
195
+ declare const Patch: (subpath: string, options?: RouteOptions) => MethodDecorator;
196
+ /** `@Delete(subpath, options?)` — declare a DELETE route. */
197
+ declare const Delete: (subpath: string, options?: RouteOptions) => MethodDecorator;
198
+
199
+ /** A legacy parameter decorator. */
200
+ type ParameterDecorator = (target: object, propertyKey: string | symbol, parameterIndex: number) => void;
201
+ /** `@Body(schema)` inject the request body, validated against `schema`. The
202
+ * developer writes `: T` (= `z.infer<schema>`, same name) for autocomplete. */
203
+ declare function Body(schema: ZodTypeAny): ParameterDecorator;
204
+ /** `@Query(schema)` — inject the parsed query params, validated against
205
+ * `schema`. */
206
+ declare function Query(schema: ZodTypeAny): ParameterDecorator;
207
+ /** `@Headers(schema?)` — inject the request headers (lowercase keys). With a
208
+ * schema, headers are validated + the codegen emits header parameters. */
209
+ declare function Headers(schema?: ZodTypeAny): ParameterDecorator;
210
+ /** `@Param("id")` — inject one matched path param by name. */
211
+ declare function Param(name: string): ParameterDecorator;
212
+ /** `@User()` inject the authenticated user (`: User`, non-null for an
213
+ * effective-required route). The runtime resolves the effective auth. */
214
+ declare function User(): ParameterDecorator;
215
+ /** `@OptionalUser()` inject the user as `User | null` (for routes whose
216
+ * effective auth is `false` / `{ required: false }`). */
217
+ declare function OptionalUser(): ParameterDecorator;
218
+ /** `@Client()` — inject the parsed calling-client metadata (`: ClientInfo`). */
219
+ declare function Client(): ParameterDecorator;
220
+ /** `@RequestId()` inject the per-request id (`: string`). */
221
+ declare function RequestId(): ParameterDecorator;
222
+ /** `@TraceId()` — inject the W3C trace id (`: string`). */
223
+ declare function TraceId(): ParameterDecorator;
224
+ /** `@Req()` — inject the raw request object (escape hatch, `: PBRequest`). */
225
+ declare function Req(): ParameterDecorator;
365
226
 
366
227
  /** Non-service, per-invocation data for background worker handlers.
367
228
  * Services (Database, Log, …) are imported as singletons, not passed here. */
@@ -369,7 +230,7 @@ interface WorkerMeta {
369
230
  /** Branch-scoped env vars. */
370
231
  env: Record<string, string>;
371
232
  /** The user that enqueued the job, if any (background jobs are usually system-initiated). */
372
- user: User | null;
233
+ user: User$1 | null;
373
234
  /** Per-invocation id for correlation. */
374
235
  requestId: string;
375
236
  projectId: string;
@@ -815,4 +676,4 @@ declare const documents: {
815
676
  onDocumentDeleted(handler: HookHandler<DocumentDeletedEvent>): ResolvedHook<DocumentDeletedEvent>;
816
677
  };
817
678
 
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 };
679
+ export { type BackoffStrategy, Body, Cache, CacheClient, Client, Controller, type ControllerOptions, type CustomWebhookConfig, DBClient, Database, Delete, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, type EnvSecretRef, EnvTypedDatabase, type FileDeletedEvent, type FileUploadedEvent, Flags, Get, Headers, type HookHandler, type HookMeta, type HttpMethodUpper, type JobConfig, type JobMeta, Log, Logger, Notifications, OptionalUser, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseStorageClient, Param, type PasswordResetEvent, Patch, Post, type ProviderEventMap, type ProviderWebhookConfig, Put, Query, Queue, QueueClient, RateLimitConfig, Req, RequestId, type ResolvedCustomWebhook, type ResolvedHook, type ResolvedJobConfig, type ResolvedProviderWebhook, type ResolvedWebhookConfig, type ResolvedWorkerConfig, Resource, type ResourceEnv, type RouteOptions, type RuntimeServices, SchemaDef, type SignInEvent, type SignOutEvent, Storage, TraceId, User, type UserCreatedEvent, User$1 as UserT, type WebhookEventHandler, type WebhookMeta, type WebhookProvider, type WebhookRequest, type WorkerConfig, type WorkerMeta, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, defineJob, defineWebhook, defineWorker, documents, makeEnvDts, storage };