@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
@@ -1,4 +1,4 @@
1
- export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, I as InsertShape, O as OnDeleteAction, R as RowShape, S as SchemaDef, 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';
1
+ export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, E as EnvTypedDatabase, 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, S as SchemaDef, 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';
2
2
  import './env.cjs';
3
- import '../endpoint-DJ98tQd6.cjs';
3
+ import '../endpoint-BEHjfvFH.cjs';
4
4
  import 'zod';
@@ -1,4 +1,4 @@
1
- export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, I as InsertShape, O as OnDeleteAction, R as RowShape, S as SchemaDef, 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-CXUs9iTQ.js';
1
+ export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, E as EnvTypedDatabase, 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, S as SchemaDef, 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-BTVdhfsb.js';
2
2
  import './env.js';
3
- import '../endpoint-DJ98tQd6.js';
3
+ import '../endpoint-BEHjfvFH.js';
4
4
  import 'zod';
package/dist/db/index.js CHANGED
@@ -1,21 +1,31 @@
1
1
  import {
2
+ EXTENSION_DEPENDENCIES,
3
+ PALBASE_EXTENSIONS,
4
+ PolicyBuilder,
2
5
  boolean,
3
6
  defineSchema,
4
7
  enumType,
5
8
  integer,
9
+ isPalbaseExtension,
6
10
  jsonb,
7
11
  makeTypedDB,
12
+ policy,
8
13
  text,
9
14
  timestamp,
10
15
  uuid
11
- } from "../chunk-B7EUJP5W.js";
16
+ } from "../chunk-2N4YNN6F.js";
12
17
  export {
18
+ EXTENSION_DEPENDENCIES,
19
+ PALBASE_EXTENSIONS,
20
+ PolicyBuilder,
13
21
  boolean,
14
22
  defineSchema,
15
23
  enumType,
16
24
  integer,
25
+ isPalbaseExtension,
17
26
  jsonb,
18
27
  makeTypedDB,
28
+ policy,
19
29
  text,
20
30
  timestamp,
21
31
  uuid
@@ -49,20 +49,17 @@ declare function defineMiddleware(fn: MiddlewareHandler): MiddlewareHandler;
49
49
 
50
50
  /** HTTP error with structured error response format.
51
51
  *
52
- * Two ways to construct one:
53
- *
54
- * 1. Directly: `throw new HttpError(404, "todo_not_found", "No such todo")`.
55
- * Surfaces on the wire (and to iOS) as `BackendError.server(code, status,
56
- * message, requestId)`.
57
- * 2. Via `req.errors.<name>(data?)` for declared errors — see a handler's
58
- * `errors` map (`defineHandler`). The endpoint's OpenAPI spec describes
59
- * each one, and the CLI codegen emits a typed `<Endpoint>.Error` enum so
60
- * iOS callers can `catch <Endpoint>.Error.<case>` directly.
52
+ * The base class for the throwable error classes (`PalError`, `Conflict`,
53
+ * `NotFound`, …). Construct one directly with `throw new HttpError(404,
54
+ * "todo_not_found", "No such todo")`, or throw a named subclass
55
+ * (`throw new NotFound("todo not found")`). The runtime catches any `HttpError`
56
+ * and emits the standard envelope; on the wire (and to iOS) it surfaces as
57
+ * `BackendError.server(code, status, message, requestId)`.
61
58
  *
62
59
  * The optional `data` field carries a structured payload alongside the
63
- * standard envelope — used by declared errors that need to ship extra context
64
- * (e.g. `todoLocked({ retryAfter: 30 })`). It rides through to the iOS typed
65
- * enum's associated value.
60
+ * standard envelope — for errors that need to ship extra context
61
+ * (e.g. `new Conflict("locked", "title_locked", { retryAfter: 30 })`). It rides
62
+ * through to the iOS typed enum's associated value.
66
63
  */
67
64
  declare class HttpError extends Error {
68
65
  readonly status: number;
@@ -84,6 +81,46 @@ declare class HttpError extends Error {
84
81
  data?: unknown;
85
82
  };
86
83
  }
84
+ /**
85
+ * Throw with a custom HTTP status + wire code. The general-purpose escape hatch
86
+ * when none of the named classes (`Conflict`/`NotFound`/…) fits.
87
+ *
88
+ * @example
89
+ * throw new PalError(418, "teapot", "I'm a teapot");
90
+ */
91
+ declare class PalError extends HttpError {
92
+ constructor(status: number, code: string, description: string, data?: unknown);
93
+ }
94
+ /** Base for the named status classes. Each subclass fixes its HTTP status; the
95
+ * `code` defaults to the class's canonical wire code (overridable), and the
96
+ * `message` defaults to a human-readable label (overridable). */
97
+ declare abstract class NamedHttpError extends HttpError {
98
+ protected constructor(status: number, defaultCode: string, name: string, message?: string, code?: string, data?: unknown);
99
+ }
100
+ /** 400 — the request was malformed or failed validation. */
101
+ declare class BadRequest extends NamedHttpError {
102
+ constructor(message?: string, code?: string, data?: unknown);
103
+ }
104
+ /** 401 — the caller is not authenticated. */
105
+ declare class Unauthorized extends NamedHttpError {
106
+ constructor(message?: string, code?: string, data?: unknown);
107
+ }
108
+ /** 403 — the caller is authenticated but not allowed. */
109
+ declare class Forbidden extends NamedHttpError {
110
+ constructor(message?: string, code?: string, data?: unknown);
111
+ }
112
+ /** 404 — the requested resource does not exist. */
113
+ declare class NotFound extends NamedHttpError {
114
+ constructor(message?: string, code?: string, data?: unknown);
115
+ }
116
+ /** 409 — the request conflicts with the current state. */
117
+ declare class Conflict extends NamedHttpError {
118
+ constructor(message?: string, code?: string, data?: unknown);
119
+ }
120
+ /** 429 — the caller has exceeded the rate limit. */
121
+ declare class TooManyRequests extends NamedHttpError {
122
+ constructor(message?: string, code?: string, data?: unknown);
123
+ }
87
124
 
88
125
  /**
89
126
  * Local typed interfaces for the 9 Palbase module clients injected into
@@ -1161,23 +1198,43 @@ interface RateLimitConfig {
1161
1198
  /** Window duration in seconds. */
1162
1199
  window: number;
1163
1200
  }
1164
- /** The transaction-scoped client passed to `db.transaction(fn)` same DB ops, no nested transaction. */
1165
- type TxClient = Omit<DBClient, "transaction">;
1166
- /** Database client interface injected into endpoint context. */
1167
- interface DBClient {
1201
+ /** The six raw string-keyed DB operations shared by `DBClient` and the
1202
+ * transaction-scoped client. */
1203
+ interface DBOps {
1168
1204
  /** Run a read-only SQL query (executes in a READ ONLY transaction). */
1169
1205
  query(sql: string, params?: unknown[]): Promise<Record<string, unknown>[]>;
1170
1206
  insert(table: string, data: Record<string, unknown>): Promise<Record<string, unknown>>;
1171
- update(table: string, id: string, data: Record<string, unknown>): Promise<Record<string, unknown>>;
1207
+ /**
1208
+ * Update the row with the given id and resolve to the updated row, or `null`
1209
+ * if no row matched (the id is absent, or the row is hidden by RLS). This is
1210
+ * an idempotent outcome, not an error — it mirrors `findById`. Map `null` to
1211
+ * a 404 in your service if a missing row should be a client error.
1212
+ */
1213
+ update(table: string, id: string, data: Record<string, unknown>): Promise<Record<string, unknown> | null>;
1172
1214
  delete(table: string, id: string): Promise<void>;
1173
1215
  findById(table: string, id: string): Promise<Record<string, unknown> | null>;
1174
1216
  findMany(table: string, query?: Record<string, unknown>): Promise<Record<string, unknown>[]>;
1217
+ }
1218
+ /** The transaction-scoped client passed to `db.transaction(fn)` — the raw DB
1219
+ * ops only. No nested transaction and no `asService` (the DB role is fixed once
1220
+ * when the transaction begins; see `Database.asService().transaction(...)`). */
1221
+ type TxClient = DBOps;
1222
+ /** Database client interface injected into endpoint context. */
1223
+ interface DBClient extends DBOps {
1175
1224
  /**
1176
1225
  * Run an interactive transaction. The callback receives a `tx` with the same
1177
1226
  * DB ops as this client; returning normally commits, throwing rolls back.
1178
1227
  * Nested transactions are not supported.
1179
1228
  */
1180
1229
  transaction<T>(fn: (tx: TxClient) => Promise<T>): Promise<T>;
1230
+ /**
1231
+ * Return a sibling DB client that bypasses Row-Level Security by running as
1232
+ * the `service_role` (BYPASSRLS). Use sparingly and explicitly — the default
1233
+ * `Database.*` path is RLS-enforced. The returned client exposes the same op
1234
+ * surface (`query`/`insert`/.../`transaction`) but never re-exposes
1235
+ * `asService` (no double-bypass).
1236
+ */
1237
+ asService(): Omit<DBClient, "asService">;
1181
1238
  }
1182
1239
  /** Logger interface injected into endpoint context. */
1183
1240
  interface Logger {
@@ -1349,21 +1406,29 @@ type ErrorThrowers<TErrors extends ErrorMap | undefined> = TErrors extends Error
1349
1406
  * error throwers. Services (`Database`, `Documents`, `Cache`, …) are NOT on
1350
1407
  * the request: import them directly from `@palbase/backend` as singletons.
1351
1408
  *
1352
- * import { defineHandler, Database } from "@palbase/backend";
1409
+ * import { Controller, Get, Req, Database } from "@palbase/backend";
1410
+ *
1411
+ * \@Controller("/todos")
1412
+ * export class TodosController {
1413
+ * \@Get("") list(\@Req() req: PBRequest): unknown {
1414
+ * return Database.findMany("todos");
1415
+ * }
1416
+ * }
1353
1417
  *
1354
- * export default defineHandler({
1355
- * handler: async (req) => Database.insert("todos", { title: req.input.title }),
1356
- * });
1418
+ * Most controller methods reach individual request slices via their own
1419
+ * parameter decorator (`@Body`/`@Query`/`@Param`/`@User`/…); `@Req()` is the
1420
+ * escape hatch that injects this whole object.
1357
1421
  *
1358
1422
  * Generic parameters:
1359
- * - `TInput` — the validated `input` type (inferred from the `input` Zod
1360
- * schema by `defineHandler`). The user-facing form is single-generic:
1361
- * `PBRequest<TodoInput>`.
1423
+ * - `TInput` — the validated `input` type (the `@Body` schema's `z.infer`). The
1424
+ * user-facing form is single-generic: `PBRequest<TodoInput>`.
1362
1425
  * - `TAuthed` — whether `user` is non-null. DEFAULTS to `true` (the common
1363
1426
  * case; the auth pipeline returns 401 before the handler when auth is
1364
- * required, so a non-null `user` is runtime-honest). `defineHandler` passes
1365
- * `IsAuthed<TAuth>` here, so `auth: false` `User | null`.
1366
- * - `TErrors` — the declared `errors` map, typing `req.errors.<name>(...)`.
1427
+ * required, so a non-null `user` is runtime-honest). A route whose effective
1428
+ * auth is `false` yields `User | null`.
1429
+ * - `TErrors` — RETAINED for back-compat of the `errors` thrower shape; the
1430
+ * class-controller model throws global error classes
1431
+ * (`Conflict`/`NotFound`/…) instead, so `req.errors` is empty in practice.
1367
1432
  */
1368
1433
  interface PBRequest<TInput = unknown, TAuthed extends boolean = true, TErrors extends ErrorMap | undefined = undefined> {
1369
1434
  /** Validated request input (body for POST/PUT/PATCH; `{}` otherwise). */
@@ -1375,8 +1440,9 @@ interface PBRequest<TInput = unknown, TAuthed extends boolean = true, TErrors ex
1375
1440
  /** Request headers (lowercase keys). */
1376
1441
  headers: Record<string, string>;
1377
1442
  /** Authenticated user. Non-null (`User`) by default; `User | null` only when
1378
- * the endpoint's `auth` config disables enforcement (driven by `TAuthed`,
1379
- * which `defineHandler` computes from the `auth` literal via {@link IsAuthed}). */
1443
+ * the route's effective auth disables enforcement (driven by `TAuthed`, which
1444
+ * the runtime resolves from the route/controller `auth` cascade via
1445
+ * {@link IsAuthed}). */
1380
1446
  user: TAuthed extends true ? User : User | null;
1381
1447
  /** Calling-client metadata derived from request headers (all nullable). */
1382
1448
  client: ClientInfo;
@@ -1390,8 +1456,9 @@ interface PBRequest<TInput = unknown, TAuthed extends boolean = true, TErrors ex
1390
1456
  traceId: string;
1391
1457
  /** W3C span id for this handler invocation. */
1392
1458
  spanId: string;
1393
- /** Typed throwers for the endpoint's declared errors. Empty when the
1394
- * `errors` block is absent on `defineHandler`. */
1459
+ /** Typed throwers for the endpoint's declared errors. RETAINED for the
1460
+ * `@Req()` escape-hatch shape; the class-controller model throws global error
1461
+ * classes (`Conflict`/`NotFound`/…) instead, so this is empty in practice. */
1395
1462
  errors: ErrorThrowers<TErrors>;
1396
1463
  }
1397
1464
  /** Middleware function signature — uses MiddlewareContext (no input, not yet validated). */
@@ -1403,30 +1470,5 @@ type Middleware = (ctx: MiddlewareContext, next: () => Promise<void>) => Promise
1403
1470
  * omitted — which the runtime treats as `required: true` (see {@link IsAuthed}).
1404
1471
  */
1405
1472
  type AuthSpec = boolean | Partial<AuthConfig>;
1406
- /** Compute, at the type level, whether an endpoint authenticates its caller —
1407
- * i.e. whether `req.user` should be `User` (non-null) instead of `User | null`.
1408
- *
1409
- * SECURE BY DEFAULT — mirrors the runtime (loader.go DefaultAuthConfig +
1410
- * pipeline/auth.go): an endpoint requires auth UNLESS it explicitly opts out.
1411
- * `req.user` is nullable ONLY for `auth: false` or `auth: { required: false }`.
1412
- * Omitting `auth` means AUTH REQUIRED (non-null `req.user`), so a handler that
1413
- * forgets `auth` fails safe (401) instead of silently exposing data.
1414
- *
1415
- * | `TAuth` | `IsAuthed<TAuth>` |
1416
- * |----------------------------------|-------------------|
1417
- * | omitted (`undefined`) | `true` (secure) |
1418
- * | `true` | `true` |
1419
- * | `false` | `false` (public) |
1420
- * | `{ required: true }` | `true` |
1421
- * | `{ required: false }` | `false` (public) |
1422
- * | `{ role: 'admin' }` (no `required`) | `true` |
1423
- *
1424
- * Order matters: the `{ required: false }` branch is checked first so the object
1425
- * case can't swallow it; `true`/`false` literals next; the catch-all (omitted)
1426
- * resolves to `true` (secure-by-default).
1427
- */
1428
- type IsAuthed<TAuth> = TAuth extends {
1429
- required: false;
1430
- } ? false : TAuth extends true ? true : TAuth extends false ? false : TAuth extends object ? true : true;
1431
1473
 
1432
- export { type PalbaseEventsQueryInput as $, type AuthSpec as A, type PalbaseCohortQueryInput as B, type CacheClient as C, type DBClient as D, type ErrorMap as E, type FileContext as F, type PalbaseCohortResult as G, HttpError as H, type IsAuthed as I, type PalbaseCollectionRef as J, type PalbaseCountQueryInput as K, type Logger as L, type Middleware as M, type PalbaseCountResult as N, type PalbaseCreateLinkParams as O, type PBRequest as P, type QueueClient as Q, type RateLimitConfig as R, type PalbaseDeviceInfo as S, type PalbaseDeviceTokenView as T, type User as U, type PalbaseDocumentRef as V, type PalbaseDocumentSnapshot as W, type PalbaseEmailClient as X, type PalbaseEmailSendParams as Y, type PalbaseEmailSendResponse as Z, type PalbaseEventNamesResult as _, type PalbaseModuleClients as a, type PalbaseEventsResult as a0, type PalbaseFileObject as a1, type PalbaseFlag as a2, type PalbaseFlagContext as a3, type PalbaseFlagVariant as a4, type PalbaseFunctionsClient as a5, type PalbaseFunnelQueryInput as a6, type PalbaseFunnelResult as a7, type PalbaseIdentifyTraits as a8, type PalbaseInboxClient as a9, type PalbaseRealtimeClient as aA, type PalbaseRealtimeMessage as aB, type PalbaseRegisterDeviceParams as aC, type PalbaseResult as aD, type PalbaseRetentionQueryInput as aE, type PalbaseRetentionResult as aF, type PalbaseSession as aG, type PalbaseSignedUrlResponse as aH, type PalbaseSmsClient as aI, type PalbaseSmsSendParams as aJ, type PalbaseSmsSendResponse as aK, type PalbaseTransformOptions as aL, type PalbaseUpdateLinkParams as aM, type PalbaseUploadOptions as aN, type PalbaseUser as aO, type PalbaseUserDetailResult as aP, type PalbaseUsersQueryInput as aQ, type PalbaseUsersResult as aR, type PalbaseVerifyRequestSignatureParams as aS, type PalbaseWhereOperator as aT, type TxClient as aU, defineMiddleware as aV, type PalbaseInboxListOptions as aa, type PalbaseInboxListResult as ab, type PalbaseInboxMessage as ac, type PalbaseInboxSendParams as ad, type PalbaseInboxSendResponse as ae, type PalbaseInitialLink as af, type PalbaseInvokeOptions as ag, type PalbaseLink as ah, type PalbaseLinkAnalytics as ai, type PalbaseLinkDetails as aj, type PalbaseLinksClient as ak, type PalbaseListLinksOptions as al, type PalbaseListLinksResult as am, type PalbaseListOptions as an, type PalbaseMatchParams as ao, type PalbaseMultiChannelResponse as ap, type PalbaseOverviewResult as aq, type PalbasePreferences as ar, type PalbasePreferencesClient as as, type PalbasePublicUrlResponse as at, type PalbasePushClient as au, type PalbasePushSendParams as av, type PalbasePushSendResponse as aw, type PalbaseQrCodeOptions as ax, type PalbaseQuerySnapshot as ay, type PalbaseRealtimeChannel as az, type PalbaseDocsClient as b, type PalbaseFlagsClient as c, type PalbaseNotificationsClient as d, type PalbaseStorageClient as e, type AuthConfig as f, type ClientInfo as g, type ErrorDef as h, type ErrorThrowers as i, type HttpMethod as j, type MiddlewareContext as k, type MiddlewareHandler as l, type PalbaseAnalyticsClient as m, type PalbaseAnalyticsManagementNamespace as n, type PalbaseAnalyticsProperties as o, type PalbaseAnalyticsQueryNamespace as p, type PalbaseAttestAndroidParams as q, type PalbaseAttestAndroidResult as r, type PalbaseAttestiOSParams as s, type PalbaseAttestiOSResult as t, type PalbaseAuthClient as u, type PalbaseBindDeviceParams as v, type PalbaseBucketClient as w, type PalbaseCmsClient as x, type PalbaseCmsFindOneOptions as y, type PalbaseCmsFindOptions as z };
1474
+ export { type PalbaseDocumentSnapshot as $, type AuthSpec as A, BadRequest as B, type CacheClient as C, type DBClient as D, type ErrorDef as E, type FileContext as F, type PalbaseBucketClient as G, HttpError as H, type PalbaseCmsClient as I, type PalbaseCmsFindOneOptions as J, type PalbaseCmsFindOptions as K, type Logger as L, type Middleware as M, NotFound as N, type PalbaseCohortQueryInput as O, type PBRequest as P, type QueueClient as Q, type RateLimitConfig as R, type PalbaseCohortResult as S, type PalbaseCollectionRef as T, type User as U, type PalbaseCountQueryInput as V, type PalbaseCountResult as W, type PalbaseCreateLinkParams as X, type PalbaseDeviceInfo as Y, type PalbaseDeviceTokenView as Z, type PalbaseDocumentRef as _, type PalbaseModuleClients as a, Unauthorized as a$, type PalbaseEmailClient as a0, type PalbaseEmailSendParams as a1, type PalbaseEmailSendResponse as a2, type PalbaseEventNamesResult as a3, type PalbaseEventsQueryInput as a4, type PalbaseEventsResult as a5, type PalbaseFileObject as a6, type PalbaseFlag as a7, type PalbaseFlagContext as a8, type PalbaseFlagVariant as a9, type PalbasePushSendParams as aA, type PalbasePushSendResponse as aB, type PalbaseQrCodeOptions as aC, type PalbaseQuerySnapshot as aD, type PalbaseRealtimeChannel as aE, type PalbaseRealtimeClient as aF, type PalbaseRealtimeMessage as aG, type PalbaseRegisterDeviceParams as aH, type PalbaseResult as aI, type PalbaseRetentionQueryInput as aJ, type PalbaseRetentionResult as aK, type PalbaseSession as aL, type PalbaseSignedUrlResponse as aM, type PalbaseSmsClient as aN, type PalbaseSmsSendParams as aO, type PalbaseSmsSendResponse as aP, type PalbaseTransformOptions as aQ, type PalbaseUpdateLinkParams as aR, type PalbaseUploadOptions as aS, type PalbaseUser as aT, type PalbaseUserDetailResult as aU, type PalbaseUsersQueryInput as aV, type PalbaseUsersResult as aW, type PalbaseVerifyRequestSignatureParams as aX, type PalbaseWhereOperator as aY, TooManyRequests as aZ, type TxClient as a_, type PalbaseFunctionsClient as aa, type PalbaseFunnelQueryInput as ab, type PalbaseFunnelResult as ac, type PalbaseIdentifyTraits as ad, type PalbaseInboxClient as ae, type PalbaseInboxListOptions as af, type PalbaseInboxListResult as ag, type PalbaseInboxMessage as ah, type PalbaseInboxSendParams as ai, type PalbaseInboxSendResponse as aj, type PalbaseInitialLink as ak, type PalbaseInvokeOptions as al, type PalbaseLink as am, type PalbaseLinkAnalytics as an, type PalbaseLinkDetails as ao, type PalbaseLinksClient as ap, type PalbaseListLinksOptions as aq, type PalbaseListLinksResult as ar, type PalbaseListOptions as as, type PalbaseMatchParams as at, type PalbaseMultiChannelResponse as au, type PalbaseOverviewResult as av, type PalbasePreferences as aw, type PalbasePreferencesClient as ax, type PalbasePublicUrlResponse as ay, type PalbasePushClient as az, type PalbaseDocsClient as b, defineMiddleware as b0, type PalbaseFlagsClient as c, type PalbaseNotificationsClient as d, type PalbaseStorageClient as e, type AuthConfig as f, type ClientInfo as g, Conflict as h, type DBOps as i, type ErrorMap as j, type ErrorThrowers as k, Forbidden as l, type HttpMethod as m, type MiddlewareContext as n, type MiddlewareHandler as o, PalError as p, type PalbaseAnalyticsClient as q, type PalbaseAnalyticsManagementNamespace as r, type PalbaseAnalyticsProperties as s, type PalbaseAnalyticsQueryNamespace as t, type PalbaseAttestAndroidParams as u, type PalbaseAttestAndroidResult as v, type PalbaseAttestiOSParams as w, type PalbaseAttestiOSResult as x, type PalbaseAuthClient as y, type PalbaseBindDeviceParams as z };
@@ -49,20 +49,17 @@ declare function defineMiddleware(fn: MiddlewareHandler): MiddlewareHandler;
49
49
 
50
50
  /** HTTP error with structured error response format.
51
51
  *
52
- * Two ways to construct one:
53
- *
54
- * 1. Directly: `throw new HttpError(404, "todo_not_found", "No such todo")`.
55
- * Surfaces on the wire (and to iOS) as `BackendError.server(code, status,
56
- * message, requestId)`.
57
- * 2. Via `req.errors.<name>(data?)` for declared errors — see a handler's
58
- * `errors` map (`defineHandler`). The endpoint's OpenAPI spec describes
59
- * each one, and the CLI codegen emits a typed `<Endpoint>.Error` enum so
60
- * iOS callers can `catch <Endpoint>.Error.<case>` directly.
52
+ * The base class for the throwable error classes (`PalError`, `Conflict`,
53
+ * `NotFound`, …). Construct one directly with `throw new HttpError(404,
54
+ * "todo_not_found", "No such todo")`, or throw a named subclass
55
+ * (`throw new NotFound("todo not found")`). The runtime catches any `HttpError`
56
+ * and emits the standard envelope; on the wire (and to iOS) it surfaces as
57
+ * `BackendError.server(code, status, message, requestId)`.
61
58
  *
62
59
  * The optional `data` field carries a structured payload alongside the
63
- * standard envelope — used by declared errors that need to ship extra context
64
- * (e.g. `todoLocked({ retryAfter: 30 })`). It rides through to the iOS typed
65
- * enum's associated value.
60
+ * standard envelope — for errors that need to ship extra context
61
+ * (e.g. `new Conflict("locked", "title_locked", { retryAfter: 30 })`). It rides
62
+ * through to the iOS typed enum's associated value.
66
63
  */
67
64
  declare class HttpError extends Error {
68
65
  readonly status: number;
@@ -84,6 +81,46 @@ declare class HttpError extends Error {
84
81
  data?: unknown;
85
82
  };
86
83
  }
84
+ /**
85
+ * Throw with a custom HTTP status + wire code. The general-purpose escape hatch
86
+ * when none of the named classes (`Conflict`/`NotFound`/…) fits.
87
+ *
88
+ * @example
89
+ * throw new PalError(418, "teapot", "I'm a teapot");
90
+ */
91
+ declare class PalError extends HttpError {
92
+ constructor(status: number, code: string, description: string, data?: unknown);
93
+ }
94
+ /** Base for the named status classes. Each subclass fixes its HTTP status; the
95
+ * `code` defaults to the class's canonical wire code (overridable), and the
96
+ * `message` defaults to a human-readable label (overridable). */
97
+ declare abstract class NamedHttpError extends HttpError {
98
+ protected constructor(status: number, defaultCode: string, name: string, message?: string, code?: string, data?: unknown);
99
+ }
100
+ /** 400 — the request was malformed or failed validation. */
101
+ declare class BadRequest extends NamedHttpError {
102
+ constructor(message?: string, code?: string, data?: unknown);
103
+ }
104
+ /** 401 — the caller is not authenticated. */
105
+ declare class Unauthorized extends NamedHttpError {
106
+ constructor(message?: string, code?: string, data?: unknown);
107
+ }
108
+ /** 403 — the caller is authenticated but not allowed. */
109
+ declare class Forbidden extends NamedHttpError {
110
+ constructor(message?: string, code?: string, data?: unknown);
111
+ }
112
+ /** 404 — the requested resource does not exist. */
113
+ declare class NotFound extends NamedHttpError {
114
+ constructor(message?: string, code?: string, data?: unknown);
115
+ }
116
+ /** 409 — the request conflicts with the current state. */
117
+ declare class Conflict extends NamedHttpError {
118
+ constructor(message?: string, code?: string, data?: unknown);
119
+ }
120
+ /** 429 — the caller has exceeded the rate limit. */
121
+ declare class TooManyRequests extends NamedHttpError {
122
+ constructor(message?: string, code?: string, data?: unknown);
123
+ }
87
124
 
88
125
  /**
89
126
  * Local typed interfaces for the 9 Palbase module clients injected into
@@ -1161,23 +1198,43 @@ interface RateLimitConfig {
1161
1198
  /** Window duration in seconds. */
1162
1199
  window: number;
1163
1200
  }
1164
- /** The transaction-scoped client passed to `db.transaction(fn)` same DB ops, no nested transaction. */
1165
- type TxClient = Omit<DBClient, "transaction">;
1166
- /** Database client interface injected into endpoint context. */
1167
- interface DBClient {
1201
+ /** The six raw string-keyed DB operations shared by `DBClient` and the
1202
+ * transaction-scoped client. */
1203
+ interface DBOps {
1168
1204
  /** Run a read-only SQL query (executes in a READ ONLY transaction). */
1169
1205
  query(sql: string, params?: unknown[]): Promise<Record<string, unknown>[]>;
1170
1206
  insert(table: string, data: Record<string, unknown>): Promise<Record<string, unknown>>;
1171
- update(table: string, id: string, data: Record<string, unknown>): Promise<Record<string, unknown>>;
1207
+ /**
1208
+ * Update the row with the given id and resolve to the updated row, or `null`
1209
+ * if no row matched (the id is absent, or the row is hidden by RLS). This is
1210
+ * an idempotent outcome, not an error — it mirrors `findById`. Map `null` to
1211
+ * a 404 in your service if a missing row should be a client error.
1212
+ */
1213
+ update(table: string, id: string, data: Record<string, unknown>): Promise<Record<string, unknown> | null>;
1172
1214
  delete(table: string, id: string): Promise<void>;
1173
1215
  findById(table: string, id: string): Promise<Record<string, unknown> | null>;
1174
1216
  findMany(table: string, query?: Record<string, unknown>): Promise<Record<string, unknown>[]>;
1217
+ }
1218
+ /** The transaction-scoped client passed to `db.transaction(fn)` — the raw DB
1219
+ * ops only. No nested transaction and no `asService` (the DB role is fixed once
1220
+ * when the transaction begins; see `Database.asService().transaction(...)`). */
1221
+ type TxClient = DBOps;
1222
+ /** Database client interface injected into endpoint context. */
1223
+ interface DBClient extends DBOps {
1175
1224
  /**
1176
1225
  * Run an interactive transaction. The callback receives a `tx` with the same
1177
1226
  * DB ops as this client; returning normally commits, throwing rolls back.
1178
1227
  * Nested transactions are not supported.
1179
1228
  */
1180
1229
  transaction<T>(fn: (tx: TxClient) => Promise<T>): Promise<T>;
1230
+ /**
1231
+ * Return a sibling DB client that bypasses Row-Level Security by running as
1232
+ * the `service_role` (BYPASSRLS). Use sparingly and explicitly — the default
1233
+ * `Database.*` path is RLS-enforced. The returned client exposes the same op
1234
+ * surface (`query`/`insert`/.../`transaction`) but never re-exposes
1235
+ * `asService` (no double-bypass).
1236
+ */
1237
+ asService(): Omit<DBClient, "asService">;
1181
1238
  }
1182
1239
  /** Logger interface injected into endpoint context. */
1183
1240
  interface Logger {
@@ -1349,21 +1406,29 @@ type ErrorThrowers<TErrors extends ErrorMap | undefined> = TErrors extends Error
1349
1406
  * error throwers. Services (`Database`, `Documents`, `Cache`, …) are NOT on
1350
1407
  * the request: import them directly from `@palbase/backend` as singletons.
1351
1408
  *
1352
- * import { defineHandler, Database } from "@palbase/backend";
1409
+ * import { Controller, Get, Req, Database } from "@palbase/backend";
1410
+ *
1411
+ * \@Controller("/todos")
1412
+ * export class TodosController {
1413
+ * \@Get("") list(\@Req() req: PBRequest): unknown {
1414
+ * return Database.findMany("todos");
1415
+ * }
1416
+ * }
1353
1417
  *
1354
- * export default defineHandler({
1355
- * handler: async (req) => Database.insert("todos", { title: req.input.title }),
1356
- * });
1418
+ * Most controller methods reach individual request slices via their own
1419
+ * parameter decorator (`@Body`/`@Query`/`@Param`/`@User`/…); `@Req()` is the
1420
+ * escape hatch that injects this whole object.
1357
1421
  *
1358
1422
  * Generic parameters:
1359
- * - `TInput` — the validated `input` type (inferred from the `input` Zod
1360
- * schema by `defineHandler`). The user-facing form is single-generic:
1361
- * `PBRequest<TodoInput>`.
1423
+ * - `TInput` — the validated `input` type (the `@Body` schema's `z.infer`). The
1424
+ * user-facing form is single-generic: `PBRequest<TodoInput>`.
1362
1425
  * - `TAuthed` — whether `user` is non-null. DEFAULTS to `true` (the common
1363
1426
  * case; the auth pipeline returns 401 before the handler when auth is
1364
- * required, so a non-null `user` is runtime-honest). `defineHandler` passes
1365
- * `IsAuthed<TAuth>` here, so `auth: false` `User | null`.
1366
- * - `TErrors` — the declared `errors` map, typing `req.errors.<name>(...)`.
1427
+ * required, so a non-null `user` is runtime-honest). A route whose effective
1428
+ * auth is `false` yields `User | null`.
1429
+ * - `TErrors` — RETAINED for back-compat of the `errors` thrower shape; the
1430
+ * class-controller model throws global error classes
1431
+ * (`Conflict`/`NotFound`/…) instead, so `req.errors` is empty in practice.
1367
1432
  */
1368
1433
  interface PBRequest<TInput = unknown, TAuthed extends boolean = true, TErrors extends ErrorMap | undefined = undefined> {
1369
1434
  /** Validated request input (body for POST/PUT/PATCH; `{}` otherwise). */
@@ -1375,8 +1440,9 @@ interface PBRequest<TInput = unknown, TAuthed extends boolean = true, TErrors ex
1375
1440
  /** Request headers (lowercase keys). */
1376
1441
  headers: Record<string, string>;
1377
1442
  /** Authenticated user. Non-null (`User`) by default; `User | null` only when
1378
- * the endpoint's `auth` config disables enforcement (driven by `TAuthed`,
1379
- * which `defineHandler` computes from the `auth` literal via {@link IsAuthed}). */
1443
+ * the route's effective auth disables enforcement (driven by `TAuthed`, which
1444
+ * the runtime resolves from the route/controller `auth` cascade via
1445
+ * {@link IsAuthed}). */
1380
1446
  user: TAuthed extends true ? User : User | null;
1381
1447
  /** Calling-client metadata derived from request headers (all nullable). */
1382
1448
  client: ClientInfo;
@@ -1390,8 +1456,9 @@ interface PBRequest<TInput = unknown, TAuthed extends boolean = true, TErrors ex
1390
1456
  traceId: string;
1391
1457
  /** W3C span id for this handler invocation. */
1392
1458
  spanId: string;
1393
- /** Typed throwers for the endpoint's declared errors. Empty when the
1394
- * `errors` block is absent on `defineHandler`. */
1459
+ /** Typed throwers for the endpoint's declared errors. RETAINED for the
1460
+ * `@Req()` escape-hatch shape; the class-controller model throws global error
1461
+ * classes (`Conflict`/`NotFound`/…) instead, so this is empty in practice. */
1395
1462
  errors: ErrorThrowers<TErrors>;
1396
1463
  }
1397
1464
  /** Middleware function signature — uses MiddlewareContext (no input, not yet validated). */
@@ -1403,30 +1470,5 @@ type Middleware = (ctx: MiddlewareContext, next: () => Promise<void>) => Promise
1403
1470
  * omitted — which the runtime treats as `required: true` (see {@link IsAuthed}).
1404
1471
  */
1405
1472
  type AuthSpec = boolean | Partial<AuthConfig>;
1406
- /** Compute, at the type level, whether an endpoint authenticates its caller —
1407
- * i.e. whether `req.user` should be `User` (non-null) instead of `User | null`.
1408
- *
1409
- * SECURE BY DEFAULT — mirrors the runtime (loader.go DefaultAuthConfig +
1410
- * pipeline/auth.go): an endpoint requires auth UNLESS it explicitly opts out.
1411
- * `req.user` is nullable ONLY for `auth: false` or `auth: { required: false }`.
1412
- * Omitting `auth` means AUTH REQUIRED (non-null `req.user`), so a handler that
1413
- * forgets `auth` fails safe (401) instead of silently exposing data.
1414
- *
1415
- * | `TAuth` | `IsAuthed<TAuth>` |
1416
- * |----------------------------------|-------------------|
1417
- * | omitted (`undefined`) | `true` (secure) |
1418
- * | `true` | `true` |
1419
- * | `false` | `false` (public) |
1420
- * | `{ required: true }` | `true` |
1421
- * | `{ required: false }` | `false` (public) |
1422
- * | `{ role: 'admin' }` (no `required`) | `true` |
1423
- *
1424
- * Order matters: the `{ required: false }` branch is checked first so the object
1425
- * case can't swallow it; `true`/`false` literals next; the catch-all (omitted)
1426
- * resolves to `true` (secure-by-default).
1427
- */
1428
- type IsAuthed<TAuth> = TAuth extends {
1429
- required: false;
1430
- } ? false : TAuth extends true ? true : TAuth extends false ? false : TAuth extends object ? true : true;
1431
1473
 
1432
- export { type PalbaseEventsQueryInput as $, type AuthSpec as A, type PalbaseCohortQueryInput as B, type CacheClient as C, type DBClient as D, type ErrorMap as E, type FileContext as F, type PalbaseCohortResult as G, HttpError as H, type IsAuthed as I, type PalbaseCollectionRef as J, type PalbaseCountQueryInput as K, type Logger as L, type Middleware as M, type PalbaseCountResult as N, type PalbaseCreateLinkParams as O, type PBRequest as P, type QueueClient as Q, type RateLimitConfig as R, type PalbaseDeviceInfo as S, type PalbaseDeviceTokenView as T, type User as U, type PalbaseDocumentRef as V, type PalbaseDocumentSnapshot as W, type PalbaseEmailClient as X, type PalbaseEmailSendParams as Y, type PalbaseEmailSendResponse as Z, type PalbaseEventNamesResult as _, type PalbaseModuleClients as a, type PalbaseEventsResult as a0, type PalbaseFileObject as a1, type PalbaseFlag as a2, type PalbaseFlagContext as a3, type PalbaseFlagVariant as a4, type PalbaseFunctionsClient as a5, type PalbaseFunnelQueryInput as a6, type PalbaseFunnelResult as a7, type PalbaseIdentifyTraits as a8, type PalbaseInboxClient as a9, type PalbaseRealtimeClient as aA, type PalbaseRealtimeMessage as aB, type PalbaseRegisterDeviceParams as aC, type PalbaseResult as aD, type PalbaseRetentionQueryInput as aE, type PalbaseRetentionResult as aF, type PalbaseSession as aG, type PalbaseSignedUrlResponse as aH, type PalbaseSmsClient as aI, type PalbaseSmsSendParams as aJ, type PalbaseSmsSendResponse as aK, type PalbaseTransformOptions as aL, type PalbaseUpdateLinkParams as aM, type PalbaseUploadOptions as aN, type PalbaseUser as aO, type PalbaseUserDetailResult as aP, type PalbaseUsersQueryInput as aQ, type PalbaseUsersResult as aR, type PalbaseVerifyRequestSignatureParams as aS, type PalbaseWhereOperator as aT, type TxClient as aU, defineMiddleware as aV, type PalbaseInboxListOptions as aa, type PalbaseInboxListResult as ab, type PalbaseInboxMessage as ac, type PalbaseInboxSendParams as ad, type PalbaseInboxSendResponse as ae, type PalbaseInitialLink as af, type PalbaseInvokeOptions as ag, type PalbaseLink as ah, type PalbaseLinkAnalytics as ai, type PalbaseLinkDetails as aj, type PalbaseLinksClient as ak, type PalbaseListLinksOptions as al, type PalbaseListLinksResult as am, type PalbaseListOptions as an, type PalbaseMatchParams as ao, type PalbaseMultiChannelResponse as ap, type PalbaseOverviewResult as aq, type PalbasePreferences as ar, type PalbasePreferencesClient as as, type PalbasePublicUrlResponse as at, type PalbasePushClient as au, type PalbasePushSendParams as av, type PalbasePushSendResponse as aw, type PalbaseQrCodeOptions as ax, type PalbaseQuerySnapshot as ay, type PalbaseRealtimeChannel as az, type PalbaseDocsClient as b, type PalbaseFlagsClient as c, type PalbaseNotificationsClient as d, type PalbaseStorageClient as e, type AuthConfig as f, type ClientInfo as g, type ErrorDef as h, type ErrorThrowers as i, type HttpMethod as j, type MiddlewareContext as k, type MiddlewareHandler as l, type PalbaseAnalyticsClient as m, type PalbaseAnalyticsManagementNamespace as n, type PalbaseAnalyticsProperties as o, type PalbaseAnalyticsQueryNamespace as p, type PalbaseAttestAndroidParams as q, type PalbaseAttestAndroidResult as r, type PalbaseAttestiOSParams as s, type PalbaseAttestiOSResult as t, type PalbaseAuthClient as u, type PalbaseBindDeviceParams as v, type PalbaseBucketClient as w, type PalbaseCmsClient as x, type PalbaseCmsFindOneOptions as y, type PalbaseCmsFindOptions as z };
1474
+ export { type PalbaseDocumentSnapshot as $, type AuthSpec as A, BadRequest as B, type CacheClient as C, type DBClient as D, type ErrorDef as E, type FileContext as F, type PalbaseBucketClient as G, HttpError as H, type PalbaseCmsClient as I, type PalbaseCmsFindOneOptions as J, type PalbaseCmsFindOptions as K, type Logger as L, type Middleware as M, NotFound as N, type PalbaseCohortQueryInput as O, type PBRequest as P, type QueueClient as Q, type RateLimitConfig as R, type PalbaseCohortResult as S, type PalbaseCollectionRef as T, type User as U, type PalbaseCountQueryInput as V, type PalbaseCountResult as W, type PalbaseCreateLinkParams as X, type PalbaseDeviceInfo as Y, type PalbaseDeviceTokenView as Z, type PalbaseDocumentRef as _, type PalbaseModuleClients as a, Unauthorized as a$, type PalbaseEmailClient as a0, type PalbaseEmailSendParams as a1, type PalbaseEmailSendResponse as a2, type PalbaseEventNamesResult as a3, type PalbaseEventsQueryInput as a4, type PalbaseEventsResult as a5, type PalbaseFileObject as a6, type PalbaseFlag as a7, type PalbaseFlagContext as a8, type PalbaseFlagVariant as a9, type PalbasePushSendParams as aA, type PalbasePushSendResponse as aB, type PalbaseQrCodeOptions as aC, type PalbaseQuerySnapshot as aD, type PalbaseRealtimeChannel as aE, type PalbaseRealtimeClient as aF, type PalbaseRealtimeMessage as aG, type PalbaseRegisterDeviceParams as aH, type PalbaseResult as aI, type PalbaseRetentionQueryInput as aJ, type PalbaseRetentionResult as aK, type PalbaseSession as aL, type PalbaseSignedUrlResponse as aM, type PalbaseSmsClient as aN, type PalbaseSmsSendParams as aO, type PalbaseSmsSendResponse as aP, type PalbaseTransformOptions as aQ, type PalbaseUpdateLinkParams as aR, type PalbaseUploadOptions as aS, type PalbaseUser as aT, type PalbaseUserDetailResult as aU, type PalbaseUsersQueryInput as aV, type PalbaseUsersResult as aW, type PalbaseVerifyRequestSignatureParams as aX, type PalbaseWhereOperator as aY, TooManyRequests as aZ, type TxClient as a_, type PalbaseFunctionsClient as aa, type PalbaseFunnelQueryInput as ab, type PalbaseFunnelResult as ac, type PalbaseIdentifyTraits as ad, type PalbaseInboxClient as ae, type PalbaseInboxListOptions as af, type PalbaseInboxListResult as ag, type PalbaseInboxMessage as ah, type PalbaseInboxSendParams as ai, type PalbaseInboxSendResponse as aj, type PalbaseInitialLink as ak, type PalbaseInvokeOptions as al, type PalbaseLink as am, type PalbaseLinkAnalytics as an, type PalbaseLinkDetails as ao, type PalbaseLinksClient as ap, type PalbaseListLinksOptions as aq, type PalbaseListLinksResult as ar, type PalbaseListOptions as as, type PalbaseMatchParams as at, type PalbaseMultiChannelResponse as au, type PalbaseOverviewResult as av, type PalbasePreferences as aw, type PalbasePreferencesClient as ax, type PalbasePublicUrlResponse as ay, type PalbasePushClient as az, type PalbaseDocsClient as b, defineMiddleware as b0, type PalbaseFlagsClient as c, type PalbaseNotificationsClient as d, type PalbaseStorageClient as e, type AuthConfig as f, type ClientInfo as g, Conflict as h, type DBOps as i, type ErrorMap as j, type ErrorThrowers as k, Forbidden as l, type HttpMethod as m, type MiddlewareContext as n, type MiddlewareHandler as o, PalError as p, type PalbaseAnalyticsClient as q, type PalbaseAnalyticsManagementNamespace as r, type PalbaseAnalyticsProperties as s, type PalbaseAnalyticsQueryNamespace as t, type PalbaseAttestAndroidParams as u, type PalbaseAttestAndroidResult as v, type PalbaseAttestiOSParams as w, type PalbaseAttestiOSResult as x, type PalbaseAuthClient as y, type PalbaseBindDeviceParams as z };