@palbase/backend 0.10.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-7N5ICXCB.js +88 -0
- package/dist/chunk-7N5ICXCB.js.map +1 -0
- package/dist/db/index.d.cts +2 -2
- package/dist/db/index.d.ts +2 -2
- package/dist/{endpoint-BbbU1hE1.d.ts → endpoint-knNIeovM.d.ts} +166 -131
- package/dist/{endpoint-6LeBP-eb.d.cts → endpoint-yn2xcrWu.d.cts} +166 -131
- package/dist/index.cjs +104 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +195 -22
- package/dist/index.d.ts +195 -22
- package/dist/index.js +34 -29
- package/dist/index.js.map +1 -1
- package/dist/{schema-zk-a0Dv7.d.cts → schema-BqfEhIC0.d.cts} +1 -1
- package/dist/{schema-zk-a0Dv7.d.ts → schema-BqfEhIC0.d.ts} +1 -1
- package/dist/test/index.cjs +62 -7
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +28 -5
- package/dist/test/index.d.ts +28 -5
- package/dist/test/index.js +34 -7
- package/dist/test/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ZodSchema, z } from 'zod';
|
|
2
|
-
import { S as SchemaDef
|
|
2
|
+
import { S as SchemaDef } from './schema-BqfEhIC0.cjs';
|
|
3
3
|
|
|
4
4
|
/** Supported HTTP methods for endpoints. */
|
|
5
5
|
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
@@ -47,90 +47,43 @@ type MiddlewareHandler = (ctx: MiddlewareContext, next: () => Promise<void>) =>
|
|
|
47
47
|
*/
|
|
48
48
|
declare function defineMiddleware(fn: MiddlewareHandler): MiddlewareHandler;
|
|
49
49
|
|
|
50
|
-
/**
|
|
51
|
-
* typed-db.ts — Task 2: TypedDB schema-derived insert/row shapes.
|
|
50
|
+
/** HTTP error with structured error response format.
|
|
52
51
|
*
|
|
53
|
-
*
|
|
54
|
-
* and wraps the untyped runtime `DBClient` with a typed facade.
|
|
52
|
+
* Two ways to construct one:
|
|
55
53
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* to the precise shape that the schema declared.
|
|
64
|
-
* Both casts are narrowing only (not widening) and correctness is guaranteed
|
|
65
|
-
* by the schema the caller provides.
|
|
66
|
-
*/
|
|
67
|
-
|
|
68
|
-
/** Keys of C whose columns are required on INSERT (not nullable, no default). */
|
|
69
|
-
type RequiredKeys<C> = {
|
|
70
|
-
[K in keyof C]: ColIsOptionalOnInsert<C[K]> extends true ? never : K;
|
|
71
|
-
}[keyof C];
|
|
72
|
-
/** Keys of C whose columns are optional on INSERT (nullable or has a default). */
|
|
73
|
-
type OptionalKeys<C> = {
|
|
74
|
-
[K in keyof C]: ColIsOptionalOnInsert<C[K]> extends true ? K : never;
|
|
75
|
-
}[keyof C];
|
|
76
|
-
/**
|
|
77
|
-
* The TypeScript type for an INSERT payload for table `T`.
|
|
78
|
-
* - Required: columns that are NOT NULL and have no DB-level default.
|
|
79
|
-
* - Optional: columns that are nullable or carry a default.
|
|
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 `ctx.errors.<name>(data?)` for declared errors — see
|
|
58
|
+
* `EndpointConfig.errors`. The endpoint's OpenAPI spec describes each
|
|
59
|
+
* one, and the CLI codegen emits a typed `<Endpoint>.Error` enum so iOS
|
|
60
|
+
* callers can `catch <Endpoint>.Error.<case>` directly.
|
|
80
61
|
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
62
|
+
* 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.
|
|
83
66
|
*/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
findMany(query?: Partial<RowShape<T>>): Promise<RowShape<T>[]>;
|
|
103
|
-
}
|
|
104
|
-
/** A typed DB facade covering all tables declared in schema `S`. */
|
|
105
|
-
interface TypedDB<S extends SchemaDef> {
|
|
106
|
-
tables: {
|
|
107
|
-
[K in keyof S["tables"]]: TypedTable<S["tables"][K]>;
|
|
108
|
-
};
|
|
109
|
-
transaction<T>(fn: (tx: TypedTx<S>) => Promise<T>): Promise<T>;
|
|
110
|
-
}
|
|
111
|
-
/** Transaction-scoped typed facade: same typed tables, no nested transaction. */
|
|
112
|
-
interface TypedTx<S extends SchemaDef> {
|
|
113
|
-
tables: {
|
|
114
|
-
[K in keyof S["tables"]]: TypedTable<S["tables"][K]>;
|
|
67
|
+
declare class HttpError extends Error {
|
|
68
|
+
readonly status: number;
|
|
69
|
+
readonly error: string;
|
|
70
|
+
readonly errorDescription: string;
|
|
71
|
+
readonly data?: unknown;
|
|
72
|
+
constructor(status: number, error: string, errorDescription: string, data?: unknown);
|
|
73
|
+
/**
|
|
74
|
+
* Serialize to the standard Palbase error response format.
|
|
75
|
+
* The `requestId` is injected by the runtime layer from the request context.
|
|
76
|
+
* When called without arguments (e.g. JSON.stringify), request_id is omitted.
|
|
77
|
+
* When `data` is set, it is appended as a strict-superset field.
|
|
78
|
+
*/
|
|
79
|
+
toJSON(requestId?: string): {
|
|
80
|
+
error: string;
|
|
81
|
+
error_description: string;
|
|
82
|
+
status: number;
|
|
83
|
+
request_id?: string;
|
|
84
|
+
data?: unknown;
|
|
115
85
|
};
|
|
116
86
|
}
|
|
117
|
-
/**
|
|
118
|
-
* Wraps a raw `DBClient` with the type-safe `TypedDB<S>` facade derived from
|
|
119
|
-
* the provided schema. No behavior change — all calls delegate to `raw` with
|
|
120
|
-
* the table name as a plain string.
|
|
121
|
-
*
|
|
122
|
-
* `buildTables` is the reusable factory that wraps any op-bearing client
|
|
123
|
-
* (`TxClient` — the surface shared by `DBClient` and the transaction-scoped
|
|
124
|
-
* client) into the typed tables map. It is used both for the top-level db
|
|
125
|
-
* (wrapping `raw`) and inside `transaction`, where it wraps the raw `TxClient`
|
|
126
|
-
* the runtime yields so the callback sees the same typed `.tables` API.
|
|
127
|
-
*
|
|
128
|
-
* `transaction` delegates straight to `raw.transaction`; the two narrow
|
|
129
|
-
* `as TypedTx<S>` / `as TypedDB<S>` casts are single structural narrowings
|
|
130
|
-
* from the dynamically-built tables object to the precise mapped type (TS
|
|
131
|
-
* cannot infer through `Object.keys` iteration) — see module-level doc comment.
|
|
132
|
-
*/
|
|
133
|
-
declare function makeTypedDB<S extends SchemaDef>(schema: S, raw: DBClient): TypedDB<S>;
|
|
134
87
|
|
|
135
88
|
/**
|
|
136
89
|
* Local typed interfaces for the 9 Palbase module clients injected into
|
|
@@ -1287,7 +1240,7 @@ interface PalbaseQuerySnapshot<T = Record<string, unknown>> {
|
|
|
1287
1240
|
}
|
|
1288
1241
|
/** Comparison operators supported by docs.where(). */
|
|
1289
1242
|
type PalbaseWhereOperator = "==" | "!=" | "<" | "<=" | ">" | ">=" | "in" | "array-contains";
|
|
1290
|
-
/** Document reference exposed by
|
|
1243
|
+
/** Document reference exposed by Documents.collection(...).doc(...). */
|
|
1291
1244
|
interface PalbaseDocumentRef<T = Record<string, unknown>> {
|
|
1292
1245
|
readonly path: string;
|
|
1293
1246
|
set(data: T): Promise<PalbaseResult<void>>;
|
|
@@ -1295,7 +1248,7 @@ interface PalbaseDocumentRef<T = Record<string, unknown>> {
|
|
|
1295
1248
|
update(data: Partial<T>): Promise<PalbaseResult<void>>;
|
|
1296
1249
|
delete(): Promise<PalbaseResult<void>>;
|
|
1297
1250
|
}
|
|
1298
|
-
/** Collection reference exposed by
|
|
1251
|
+
/** Collection reference exposed by Documents.collection(...). */
|
|
1299
1252
|
interface PalbaseCollectionRef<T = Record<string, unknown>> {
|
|
1300
1253
|
readonly path: string;
|
|
1301
1254
|
doc(id: string): PalbaseDocumentRef<T>;
|
|
@@ -1305,23 +1258,39 @@ interface PalbaseCollectionRef<T = Record<string, unknown>> {
|
|
|
1305
1258
|
limit(n: number): PalbaseCollectionRef<T>;
|
|
1306
1259
|
get(): Promise<PalbaseResult<PalbaseQuerySnapshot<T>>>;
|
|
1307
1260
|
}
|
|
1308
|
-
/** Docs client surface available on
|
|
1261
|
+
/** Docs client surface available on the Documents singleton. */
|
|
1309
1262
|
interface PalbaseDocsClient {
|
|
1310
1263
|
collection<T = Record<string, unknown>>(path: string): PalbaseCollectionRef<T>;
|
|
1311
1264
|
doc<T = Record<string, unknown>>(path: string): PalbaseDocumentRef<T>;
|
|
1312
1265
|
}
|
|
1313
|
-
/**
|
|
1266
|
+
/** Calling-client metadata, derived from request headers.
|
|
1314
1267
|
*
|
|
1315
|
-
*
|
|
1316
|
-
*
|
|
1317
|
-
*
|
|
1318
|
-
*
|
|
1268
|
+
* Populated from the `X-Palbase-*-Version` / platform headers the client SDKs
|
|
1269
|
+
* send. All fields are nullable: a request may come from a non-SDK caller
|
|
1270
|
+
* (curl, server-to-server) that sends none of them. The semver comparison
|
|
1271
|
+
* helpers (`appVersionAtLeast`, …) arrive in Phase 2 — Phase 1 surfaces only
|
|
1272
|
+
* the raw data fields. */
|
|
1273
|
+
interface ClientInfo {
|
|
1274
|
+
/** Palbase SDK version (`X-Palbase-Sdk-Version`), or null. */
|
|
1275
|
+
sdkVersion: string | null;
|
|
1276
|
+
/** Calling app's own version (`X-Palbase-Client-Version`), or null. */
|
|
1277
|
+
appVersion: string | null;
|
|
1278
|
+
/** Platform identifier (e.g. "ios", "android", "web"), or null. */
|
|
1279
|
+
platform: string | null;
|
|
1280
|
+
/** OS version string, or null. */
|
|
1281
|
+
osVersion: string | null;
|
|
1282
|
+
}
|
|
1283
|
+
/** Palbase module clients, as a structural bundle.
|
|
1319
1284
|
*
|
|
1320
|
-
*
|
|
1321
|
-
*
|
|
1322
|
-
* as
|
|
1323
|
-
*
|
|
1324
|
-
|
|
1285
|
+
* NOT part of the endpoint surface anymore — endpoint handlers reach services
|
|
1286
|
+
* via the PascalCase singletons (`Database`, `Documents`, …). This type is
|
|
1287
|
+
* retained as an INTERNAL shape for the sibling contexts that still carry a
|
|
1288
|
+
* `ctx` (middleware, jobs, workers, hooks, webhooks — out of Phase 1 scope).
|
|
1289
|
+
* It is intentionally not re-exported from `index.ts`.
|
|
1290
|
+
*
|
|
1291
|
+
* Structurally typed against the runtime's `ServerClient`; the runtime injects
|
|
1292
|
+
* the real client, so mismatched names would surface as `undefined is not a
|
|
1293
|
+
* function` at call time — keep these in sync with `ServerClient`. */
|
|
1325
1294
|
interface PalbaseModuleClients {
|
|
1326
1295
|
auth: PalbaseAuthClient;
|
|
1327
1296
|
storage: PalbaseStorageClient;
|
|
@@ -1334,40 +1303,97 @@ interface PalbaseModuleClients {
|
|
|
1334
1303
|
links: PalbaseLinksClient;
|
|
1335
1304
|
cms: PalbaseCmsClient;
|
|
1336
1305
|
}
|
|
1337
|
-
/**
|
|
1338
|
-
*
|
|
1339
|
-
*
|
|
1306
|
+
/** Declared-error definition.
|
|
1307
|
+
*
|
|
1308
|
+
* `code` is the stable snake_case identifier that lands on the wire envelope's
|
|
1309
|
+
* `error` field. `status` is the HTTP status code returned. `data`, if set,
|
|
1310
|
+
* is a Zod schema whose value rides on the envelope's `data` field — the CLI
|
|
1311
|
+
* codegen lowers it to the typed enum's associated value on iOS.
|
|
1340
1312
|
*
|
|
1341
|
-
*
|
|
1342
|
-
*
|
|
1343
|
-
*
|
|
1344
|
-
* When `TSchema` is `undefined` (no schema), `ctx.db` is plain `DBClient`.
|
|
1313
|
+
* `description` is optional human-readable text; the OpenAPI generator uses it
|
|
1314
|
+
* for the response description and the iOS codegen surfaces it in the
|
|
1315
|
+
* generated method's doc-comment.
|
|
1345
1316
|
*/
|
|
1346
|
-
interface
|
|
1317
|
+
interface ErrorDef<TData extends ZodSchema = ZodSchema> {
|
|
1318
|
+
status: number;
|
|
1319
|
+
code: string;
|
|
1320
|
+
description?: string;
|
|
1321
|
+
data?: TData;
|
|
1322
|
+
}
|
|
1323
|
+
/** Map of declared errors keyed by their TypeScript-side names.
|
|
1324
|
+
*
|
|
1325
|
+
* Keys are the friendly names the handler uses (`req.errors.todoLocked`);
|
|
1326
|
+
* `code` on each value is the wire identifier. The TS name is what the iOS
|
|
1327
|
+
* codegen lowers to (camelCase enum cases), and the wire `code` is what the
|
|
1328
|
+
* envelope's `error` field carries.
|
|
1329
|
+
*/
|
|
1330
|
+
type ErrorMap = Record<string, ErrorDef>;
|
|
1331
|
+
/** Throwable proxy projected onto `req.errors` when `errors` is declared.
|
|
1332
|
+
*
|
|
1333
|
+
* Each entry is a constructor: declared errors with a `data` schema demand
|
|
1334
|
+
* the payload as a required argument; declared errors without `data` take
|
|
1335
|
+
* none. Throwing the result emits the standard envelope (with `data` when
|
|
1336
|
+
* present).
|
|
1337
|
+
*
|
|
1338
|
+
* throw req.errors.todoNotFound();
|
|
1339
|
+
* throw req.errors.todoLocked({ retryAfter: 30 });
|
|
1340
|
+
*/
|
|
1341
|
+
type ErrorThrowers<TErrors extends ErrorMap | undefined> = TErrors extends ErrorMap ? {
|
|
1342
|
+
[K in keyof TErrors]: TErrors[K]["data"] extends ZodSchema ? (data: z.infer<NonNullable<TErrors[K]["data"]>>) => HttpError : () => HttpError;
|
|
1343
|
+
} : Record<string, never>;
|
|
1344
|
+
/** The request-scoped object passed to every endpoint handler.
|
|
1345
|
+
*
|
|
1346
|
+
* Replaces the old `ctx` god-object. `PBRequest` carries ONLY request-scoped
|
|
1347
|
+
* data — the typed `input`, route/query params, headers, the authenticated
|
|
1348
|
+
* `user`, calling-client metadata, trace ids, and the endpoint's declared
|
|
1349
|
+
* error throwers. Services (`Database`, `Documents`, `Cache`, …) are NOT on
|
|
1350
|
+
* the request: import them directly from `@palbase/backend` as singletons.
|
|
1351
|
+
*
|
|
1352
|
+
* import { defineEndpoint, Database } from "@palbase/backend";
|
|
1353
|
+
*
|
|
1354
|
+
* export default defineEndpoint({
|
|
1355
|
+
* method: "POST",
|
|
1356
|
+
* handler: async (req) => Database.insert("todos", { title: req.input.title }),
|
|
1357
|
+
* });
|
|
1358
|
+
*
|
|
1359
|
+
* Generic parameters:
|
|
1360
|
+
* - `TInput` — the validated `input` type (inferred from the `input` Zod
|
|
1361
|
+
* schema by `defineEndpoint`). The user-facing form is single-generic:
|
|
1362
|
+
* `PBRequest<TodoInput>`.
|
|
1363
|
+
* - `TAuthed` — whether `user` is non-null. DEFAULTS to `true` (the common
|
|
1364
|
+
* case; the auth pipeline returns 401 before the handler when auth is
|
|
1365
|
+
* required, so a non-null `user` is runtime-honest). `defineEndpoint` passes
|
|
1366
|
+
* `IsAuthed<TAuth>` here, so `auth: false` → `User | null`.
|
|
1367
|
+
* - `TErrors` — the declared `errors` map, typing `req.errors.<name>(...)`.
|
|
1368
|
+
*/
|
|
1369
|
+
interface PBRequest<TInput = unknown, TAuthed extends boolean = true, TErrors extends ErrorMap | undefined = undefined> {
|
|
1370
|
+
/** Validated request input (body for POST/PUT/PATCH; `{}` otherwise). */
|
|
1347
1371
|
input: TInput;
|
|
1372
|
+
/** Matched route params (e.g. `{ id }` for `/todos/[id]`). */
|
|
1348
1373
|
params: Record<string, string>;
|
|
1374
|
+
/** Parsed query-string params. */
|
|
1349
1375
|
query: Record<string, string>;
|
|
1376
|
+
/** Request headers (lowercase keys). */
|
|
1350
1377
|
headers: Record<string, string>;
|
|
1351
|
-
/** Authenticated user. Non-null (`User`)
|
|
1352
|
-
*
|
|
1353
|
-
*
|
|
1354
|
-
* `auth` literal via {@link IsAuthed}. */
|
|
1378
|
+
/** Authenticated user. Non-null (`User`) by default; `User | null` only when
|
|
1379
|
+
* the endpoint's `auth` config disables enforcement (driven by `TAuthed`,
|
|
1380
|
+
* which `defineEndpoint` computes from the `auth` literal via {@link IsAuthed}). */
|
|
1355
1381
|
user: TAuthed extends true ? User : User | null;
|
|
1356
|
-
/**
|
|
1357
|
-
|
|
1358
|
-
/** Matched endpoint path (e.g. "/todos/create"). */
|
|
1359
|
-
endpointPath: string;
|
|
1382
|
+
/** Calling-client metadata derived from request headers (all nullable). */
|
|
1383
|
+
client: ClientInfo;
|
|
1360
1384
|
/** Uploaded file, or null when the request has no file part. */
|
|
1361
1385
|
file: FileContext | null;
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
cache: CacheClient;
|
|
1366
|
-
/** Queue client for dispatching background jobs. */
|
|
1367
|
-
queue: QueueClient;
|
|
1386
|
+
/** HTTP method of the incoming request (e.g. "GET", "POST"). */
|
|
1387
|
+
method: string;
|
|
1388
|
+
/** Per-request id (`req_<…>`), preserved for back-compat correlation. */
|
|
1368
1389
|
requestId: string;
|
|
1369
|
-
|
|
1370
|
-
|
|
1390
|
+
/** W3C trace id (primary correlation key across modules). */
|
|
1391
|
+
traceId: string;
|
|
1392
|
+
/** W3C span id for this handler invocation. */
|
|
1393
|
+
spanId: string;
|
|
1394
|
+
/** Typed throwers for the endpoint's declared errors. Empty when the
|
|
1395
|
+
* `errors` block is absent on `defineEndpoint`. */
|
|
1396
|
+
errors: ErrorThrowers<TErrors>;
|
|
1371
1397
|
}
|
|
1372
1398
|
/** Middleware function signature — uses MiddlewareContext (no input, not yet validated). */
|
|
1373
1399
|
type Middleware = (ctx: MiddlewareContext, next: () => Promise<void>) => Promise<void>;
|
|
@@ -1379,11 +1405,11 @@ type Middleware = (ctx: MiddlewareContext, next: () => Promise<void>) => Promise
|
|
|
1379
1405
|
*/
|
|
1380
1406
|
type AuthSpec = boolean | Partial<AuthConfig>;
|
|
1381
1407
|
/** Compute, at the type level, whether an endpoint authenticates its caller —
|
|
1382
|
-
* i.e. whether `
|
|
1408
|
+
* i.e. whether `req.user` should be `User` (non-null) instead of `User | null`.
|
|
1383
1409
|
*
|
|
1384
1410
|
* This mirrors the Go pipeline's enforcement exactly (extract_meta.js + auth.go):
|
|
1385
1411
|
* a request is authenticated ⟺ `auth === true` OR (`auth` is an object whose
|
|
1386
|
-
* `required` is not explicitly `false`). So `
|
|
1412
|
+
* `required` is not explicitly `false`). So `req.user` stays nullable ONLY when
|
|
1387
1413
|
* `auth` is absent (`undefined`), `auth === false`, or `auth: { required: false }`.
|
|
1388
1414
|
*
|
|
1389
1415
|
* | `TAuth` | `IsAuthed<TAuth>` |
|
|
@@ -1405,31 +1431,40 @@ type IsAuthed<TAuth> = TAuth extends {
|
|
|
1405
1431
|
} ? false : TAuth extends true ? true : TAuth extends false ? false : TAuth extends object ? true : false;
|
|
1406
1432
|
/** Configuration for defining an endpoint.
|
|
1407
1433
|
*
|
|
1408
|
-
* `TSchema` — optional `SchemaDef`
|
|
1409
|
-
*
|
|
1410
|
-
*
|
|
1434
|
+
* `TSchema` — optional `SchemaDef` carried on the `schema` field. The runtime
|
|
1435
|
+
* uses it to wire a typed `.tables.*` API; authors opt in per endpoint with
|
|
1436
|
+
* `typedDatabase(schema)` (see runtime.ts).
|
|
1411
1437
|
*
|
|
1412
1438
|
* `TAuth` — captures the literal type of the `auth` field (via the `const`
|
|
1413
|
-
* type parameter on `defineEndpoint`) so the handler's `
|
|
1439
|
+
* type parameter on `defineEndpoint`) so the handler's `req.user` can be
|
|
1414
1440
|
* narrowed to non-null `User` when auth is required. See {@link IsAuthed}.
|
|
1441
|
+
*
|
|
1442
|
+
* `TErrors` — captures the literal `errors` map (via the `const` type
|
|
1443
|
+
* parameter on `defineEndpoint`) so `req.errors.<name>(...)` is typed per
|
|
1444
|
+
* declared entry. The OpenAPI generator emits each one as a discriminated
|
|
1445
|
+
* response under `responses[<status>]`, and the CLI codegen lowers them to
|
|
1446
|
+
* a typed `<Endpoint>.Error` enum on iOS.
|
|
1415
1447
|
*/
|
|
1416
|
-
interface EndpointConfig<TInputSchema extends ZodSchema = ZodSchema, TOutputSchema extends ZodSchema = ZodSchema, TSchema extends SchemaDef | undefined = undefined, TAuth extends AuthSpec | undefined = undefined> {
|
|
1448
|
+
interface EndpointConfig<TInputSchema extends ZodSchema = ZodSchema, TOutputSchema extends ZodSchema = ZodSchema, TSchema extends SchemaDef | undefined = undefined, TAuth extends AuthSpec | undefined = undefined, TErrors extends ErrorMap | undefined = undefined> {
|
|
1417
1449
|
method: HttpMethod;
|
|
1418
1450
|
auth?: TAuth;
|
|
1419
1451
|
rateLimit?: RateLimitConfig;
|
|
1420
1452
|
input?: TInputSchema;
|
|
1421
1453
|
output?: TOutputSchema;
|
|
1422
1454
|
schema?: TSchema;
|
|
1455
|
+
errors?: TErrors;
|
|
1423
1456
|
middleware?: Middleware[];
|
|
1424
|
-
handler: (
|
|
1457
|
+
handler: (req: PBRequest<z.infer<TInputSchema>, IsAuthed<TAuth>, TErrors>) => Promise<z.infer<TOutputSchema>>;
|
|
1425
1458
|
}
|
|
1426
|
-
/** Define a type-safe endpoint.
|
|
1427
|
-
* Pass a `schema` (from `defineSchema`)
|
|
1459
|
+
/** Define a type-safe endpoint. The input schema infers the `req.input` type.
|
|
1460
|
+
* Pass a `schema` (from `defineSchema`) and wrap `Database` with
|
|
1461
|
+
* `typedDatabase(schema)` in the handler for a typed `.tables.*` API.
|
|
1428
1462
|
*
|
|
1429
|
-
* The `const TAuth` type
|
|
1430
|
-
*
|
|
1431
|
-
*
|
|
1463
|
+
* The `const TAuth` and `const TErrors` type parameters capture the `auth`
|
|
1464
|
+
* and `errors` fields as literals, so `req.user` narrows to non-null `User`
|
|
1465
|
+
* when auth is enforced and `req.errors.<name>(...)` is typed per declared
|
|
1466
|
+
* entry.
|
|
1432
1467
|
*/
|
|
1433
|
-
declare function defineEndpoint<TInputSchema extends ZodSchema, TOutputSchema extends ZodSchema, TSchema extends SchemaDef | undefined = undefined, const TAuth extends AuthSpec | undefined = undefined>(config: EndpointConfig<TInputSchema, TOutputSchema, TSchema, TAuth>): EndpointConfig<TInputSchema, TOutputSchema, TSchema, TAuth>;
|
|
1468
|
+
declare function defineEndpoint<TInputSchema extends ZodSchema, TOutputSchema extends ZodSchema, TSchema extends SchemaDef | undefined = undefined, const TAuth extends AuthSpec | undefined = undefined, const TErrors extends ErrorMap | undefined = undefined>(config: EndpointConfig<TInputSchema, TOutputSchema, TSchema, TAuth, TErrors>): EndpointConfig<TInputSchema, TOutputSchema, TSchema, TAuth, TErrors>;
|
|
1434
1469
|
|
|
1435
|
-
export { type
|
|
1470
|
+
export { type PalbaseFileObject as $, type AuthConfig as A, type PalbaseCohortQueryInput as B, type CacheClient as C, type DBClient as D, type ErrorThrowers as E, type FileContext as F, type PalbaseCohortResult as G, HttpError as H, type PalbaseCollectionRef as I, type PalbaseCountQueryInput as J, type PalbaseCountResult as K, type Logger as L, type Middleware as M, type PalbaseCreateLinkParams as N, type PalbaseDeviceInfo as O, type PalbaseDocsClient as P, type QueueClient as Q, type PalbaseDeviceTokenView as R, type PalbaseDocumentRef as S, type PalbaseDocumentSnapshot as T, type User as U, type PalbaseEmailClient as V, type PalbaseEmailSendParams as W, type PalbaseEmailSendResponse as X, type PalbaseEventNamesResult as Y, type PalbaseEventsQueryInput as Z, type PalbaseEventsResult as _, type PalbaseFlagsClient as a, type PalbaseFlag as a0, type PalbaseFlagContext as a1, type PalbaseFlagVariant as a2, type PalbaseFunctionsClient as a3, type PalbaseFunnelQueryInput as a4, type PalbaseFunnelResult as a5, type PalbaseIdentifyTraits as a6, type PalbaseInboxClient as a7, type PalbaseInboxListOptions as a8, type PalbaseInboxListResult as a9, type PalbaseRegisterDeviceParams as aA, type PalbaseResult as aB, type PalbaseRetentionQueryInput as aC, type PalbaseRetentionResult as aD, type PalbaseSession as aE, type PalbaseSignedUrlResponse as aF, type PalbaseSmsClient as aG, type PalbaseSmsSendParams as aH, type PalbaseSmsSendResponse as aI, type PalbaseTransformOptions as aJ, type PalbaseUpdateLinkParams as aK, type PalbaseUploadOptions as aL, type PalbaseUser as aM, type PalbaseUserDetailResult as aN, type PalbaseUsersQueryInput as aO, type PalbaseUsersResult as aP, type PalbaseVerifyRequestSignatureParams as aQ, type PalbaseWhereOperator as aR, type RateLimitConfig as aS, type TxClient as aT, defineEndpoint as aU, defineMiddleware as aV, type PalbaseInboxMessage as aa, type PalbaseInboxSendParams as ab, type PalbaseInboxSendResponse as ac, type PalbaseInitialLink as ad, type PalbaseInvokeOptions as ae, type PalbaseLink as af, type PalbaseLinkAnalytics as ag, type PalbaseLinkDetails as ah, type PalbaseLinksClient as ai, type PalbaseListLinksOptions as aj, type PalbaseListLinksResult as ak, type PalbaseListOptions as al, type PalbaseMatchParams as am, type PalbaseMultiChannelResponse as an, type PalbaseOverviewResult as ao, type PalbasePreferences as ap, type PalbasePreferencesClient as aq, type PalbasePublicUrlResponse as ar, type PalbasePushClient as as, type PalbasePushSendParams as at, type PalbasePushSendResponse as au, type PalbaseQrCodeOptions as av, type PalbaseQuerySnapshot as aw, type PalbaseRealtimeChannel as ax, type PalbaseRealtimeClient as ay, type PalbaseRealtimeMessage as az, type PalbaseNotificationsClient as b, type PalbaseStorageClient as c, type PalbaseModuleClients as d, type ClientInfo as e, type EndpointConfig as f, type ErrorDef as g, type ErrorMap as h, type HttpMethod as i, type MiddlewareContext as j, type MiddlewareHandler as k, type PBRequest 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 };
|
package/dist/index.cjs
CHANGED
|
@@ -20,7 +20,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
+
Cache: () => Cache,
|
|
24
|
+
Database: () => Database,
|
|
25
|
+
Documents: () => Documents,
|
|
26
|
+
Flags: () => Flags,
|
|
23
27
|
HttpError: () => HttpError,
|
|
28
|
+
Log: () => Log,
|
|
29
|
+
Notifications: () => Notifications,
|
|
30
|
+
Queue: () => Queue,
|
|
31
|
+
Storage: () => Storage,
|
|
32
|
+
__getRuntime: () => __getRuntime,
|
|
33
|
+
__setRuntime: () => __setRuntime,
|
|
24
34
|
auth: () => auth,
|
|
25
35
|
boolean: () => boolean,
|
|
26
36
|
defineEndpoint: () => defineEndpoint,
|
|
@@ -38,6 +48,7 @@ __export(src_exports, {
|
|
|
38
48
|
table: () => table,
|
|
39
49
|
text: () => text,
|
|
40
50
|
timestamp: () => timestamp,
|
|
51
|
+
typedDatabase: () => typedDatabase,
|
|
41
52
|
uuid: () => uuid,
|
|
42
53
|
z: () => import_zod.z
|
|
43
54
|
});
|
|
@@ -48,6 +59,79 @@ function defineEndpoint(config) {
|
|
|
48
59
|
return config;
|
|
49
60
|
}
|
|
50
61
|
|
|
62
|
+
// src/db/typed-db.ts
|
|
63
|
+
function makeTypedTable(name, raw) {
|
|
64
|
+
return {
|
|
65
|
+
insert: (data) => raw.insert(name, data),
|
|
66
|
+
update: (id, data) => raw.update(name, id, data),
|
|
67
|
+
delete: (id) => raw.delete(name, id),
|
|
68
|
+
findById: (id) => raw.findById(name, id),
|
|
69
|
+
findMany: (query) => raw.findMany(name, query)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function makeTypedDB(schema, raw) {
|
|
73
|
+
function buildTables(client) {
|
|
74
|
+
const tables = {};
|
|
75
|
+
for (const key of Object.keys(schema.tables)) {
|
|
76
|
+
const tableDef = schema.tables[key];
|
|
77
|
+
if (tableDef !== void 0) {
|
|
78
|
+
tables[key] = makeTypedTable(tableDef.name, client);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return tables;
|
|
82
|
+
}
|
|
83
|
+
const result = {
|
|
84
|
+
tables: buildTables(raw),
|
|
85
|
+
transaction: (fn) => raw.transaction((rawTx) => fn({ tables: buildTables(rawTx) }))
|
|
86
|
+
};
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/runtime.ts
|
|
91
|
+
var runtime = null;
|
|
92
|
+
function __setRuntime(services) {
|
|
93
|
+
runtime = services;
|
|
94
|
+
}
|
|
95
|
+
function __getRuntime() {
|
|
96
|
+
if (runtime === null) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
"Palbase services accessed outside a request scope. The Database/Documents/\u2026 singletons are only available inside an endpoint handler (or after the runtime has called __setRuntime)."
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return runtime;
|
|
102
|
+
}
|
|
103
|
+
function makeServiceProxy(key) {
|
|
104
|
+
const handler = {
|
|
105
|
+
get(_target, prop, receiver) {
|
|
106
|
+
const client = __getRuntime()[key];
|
|
107
|
+
const value = Reflect.get(client, prop, receiver);
|
|
108
|
+
return typeof value === "function" ? value.bind(client) : value;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
return new Proxy({}, handler);
|
|
112
|
+
}
|
|
113
|
+
var Database = makeServiceProxy("Database");
|
|
114
|
+
var Documents = makeServiceProxy("Documents");
|
|
115
|
+
var Storage = makeServiceProxy("Storage");
|
|
116
|
+
var Cache = makeServiceProxy("Cache");
|
|
117
|
+
var Queue = makeServiceProxy("Queue");
|
|
118
|
+
var Log = makeServiceProxy("Log");
|
|
119
|
+
var Notifications = makeServiceProxy("Notifications");
|
|
120
|
+
var Flags = makeServiceProxy("Flags");
|
|
121
|
+
function typedDatabase(schema) {
|
|
122
|
+
const typed = makeTypedDB(schema, Database);
|
|
123
|
+
const rawOps = {
|
|
124
|
+
query: (sql, params) => Database.query(sql, params),
|
|
125
|
+
insert: (table2, data) => Database.insert(table2, data),
|
|
126
|
+
update: (table2, id, data) => Database.update(table2, id, data),
|
|
127
|
+
delete: (table2, id) => Database.delete(table2, id),
|
|
128
|
+
findById: (table2, id) => Database.findById(table2, id),
|
|
129
|
+
findMany: (table2, q) => Database.findMany(table2, q),
|
|
130
|
+
transaction: (fn) => Database.transaction(fn)
|
|
131
|
+
};
|
|
132
|
+
return Object.assign(rawOps, typed);
|
|
133
|
+
}
|
|
134
|
+
|
|
51
135
|
// src/db/schema.ts
|
|
52
136
|
function table(name, columns) {
|
|
53
137
|
return { name, columns };
|
|
@@ -132,34 +216,6 @@ function enumType(name, values) {
|
|
|
132
216
|
return builder;
|
|
133
217
|
}
|
|
134
218
|
|
|
135
|
-
// src/db/typed-db.ts
|
|
136
|
-
function makeTypedTable(name, raw) {
|
|
137
|
-
return {
|
|
138
|
-
insert: (data) => raw.insert(name, data),
|
|
139
|
-
update: (id, data) => raw.update(name, id, data),
|
|
140
|
-
delete: (id) => raw.delete(name, id),
|
|
141
|
-
findById: (id) => raw.findById(name, id),
|
|
142
|
-
findMany: (query) => raw.findMany(name, query)
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
function makeTypedDB(schema, raw) {
|
|
146
|
-
function buildTables(client) {
|
|
147
|
-
const tables = {};
|
|
148
|
-
for (const key of Object.keys(schema.tables)) {
|
|
149
|
-
const tableDef = schema.tables[key];
|
|
150
|
-
if (tableDef !== void 0) {
|
|
151
|
-
tables[key] = makeTypedTable(tableDef.name, client);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return tables;
|
|
155
|
-
}
|
|
156
|
-
const result = {
|
|
157
|
-
tables: buildTables(raw),
|
|
158
|
-
transaction: (fn) => raw.transaction((rawTx) => fn({ tables: buildTables(rawTx) }))
|
|
159
|
-
};
|
|
160
|
-
return result;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
219
|
// src/middleware.ts
|
|
164
220
|
function defineMiddleware(fn) {
|
|
165
221
|
return fn;
|
|
@@ -170,17 +226,22 @@ var HttpError = class extends Error {
|
|
|
170
226
|
status;
|
|
171
227
|
error;
|
|
172
228
|
errorDescription;
|
|
173
|
-
|
|
229
|
+
data;
|
|
230
|
+
constructor(status, error, errorDescription, data) {
|
|
174
231
|
super(errorDescription);
|
|
175
232
|
this.name = "HttpError";
|
|
176
233
|
this.status = status;
|
|
177
234
|
this.error = error;
|
|
178
235
|
this.errorDescription = errorDescription;
|
|
236
|
+
if (data !== void 0) {
|
|
237
|
+
this.data = data;
|
|
238
|
+
}
|
|
179
239
|
}
|
|
180
240
|
/**
|
|
181
241
|
* Serialize to the standard Palbase error response format.
|
|
182
242
|
* The `requestId` is injected by the runtime layer from the request context.
|
|
183
243
|
* When called without arguments (e.g. JSON.stringify), request_id is omitted.
|
|
244
|
+
* When `data` is set, it is appended as a strict-superset field.
|
|
184
245
|
*/
|
|
185
246
|
toJSON(requestId) {
|
|
186
247
|
const result = {
|
|
@@ -191,6 +252,9 @@ var HttpError = class extends Error {
|
|
|
191
252
|
if (requestId) {
|
|
192
253
|
result.request_id = requestId;
|
|
193
254
|
}
|
|
255
|
+
if (this.data !== void 0) {
|
|
256
|
+
result.data = this.data;
|
|
257
|
+
}
|
|
194
258
|
return result;
|
|
195
259
|
}
|
|
196
260
|
};
|
|
@@ -450,7 +514,17 @@ var documents = {
|
|
|
450
514
|
var import_zod = require("zod");
|
|
451
515
|
// Annotate the CommonJS export names for ESM import in node:
|
|
452
516
|
0 && (module.exports = {
|
|
517
|
+
Cache,
|
|
518
|
+
Database,
|
|
519
|
+
Documents,
|
|
520
|
+
Flags,
|
|
453
521
|
HttpError,
|
|
522
|
+
Log,
|
|
523
|
+
Notifications,
|
|
524
|
+
Queue,
|
|
525
|
+
Storage,
|
|
526
|
+
__getRuntime,
|
|
527
|
+
__setRuntime,
|
|
454
528
|
auth,
|
|
455
529
|
boolean,
|
|
456
530
|
defineEndpoint,
|
|
@@ -468,6 +542,7 @@ var import_zod = require("zod");
|
|
|
468
542
|
table,
|
|
469
543
|
text,
|
|
470
544
|
timestamp,
|
|
545
|
+
typedDatabase,
|
|
471
546
|
uuid,
|
|
472
547
|
z
|
|
473
548
|
});
|