@palbase/backend 0.7.0 → 0.9.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-4J3F32SH.js +96 -0
- package/dist/chunk-4J3F32SH.js.map +1 -0
- package/dist/db/index.cjs +12 -12
- package/dist/db/index.cjs.map +1 -1
- package/dist/db/index.d.cts +3 -70
- package/dist/db/index.d.ts +3 -70
- package/dist/db/index.js +11 -83
- package/dist/db/index.js.map +1 -1
- package/dist/endpoint-DysSe3SI.d.ts +1299 -0
- package/dist/endpoint-_1Qq8AFz.d.cts +1299 -0
- package/dist/index.cjs +125 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -20
- package/dist/index.d.ts +12 -20
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -1
- package/dist/schema-zk-a0Dv7.d.cts +133 -0
- package/dist/schema-zk-a0Dv7.d.ts +133 -0
- package/dist/test/index.cjs +151 -12
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +2 -1
- package/dist/test/index.d.ts +2 -1
- package/dist/test/index.js +151 -12
- package/dist/test/index.js.map +1 -1
- package/package.json +3 -1
- package/dist/endpoint-tZi55HU8.d.cts +0 -115
- package/dist/endpoint-tZi55HU8.d.ts +0 -115
|
@@ -0,0 +1,1299 @@
|
|
|
1
|
+
import { ZodSchema, z } from 'zod';
|
|
2
|
+
import { S as SchemaDef, T as TableDef, h as ColIsOptionalOnInsert, k as ColValue } from './schema-zk-a0Dv7.js';
|
|
3
|
+
|
|
4
|
+
/** Supported HTTP methods for endpoints. */
|
|
5
|
+
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
6
|
+
/** Authenticated user attached to the request context. */
|
|
7
|
+
interface User {
|
|
8
|
+
id: string;
|
|
9
|
+
email: string;
|
|
10
|
+
role: string;
|
|
11
|
+
metadata: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
/** Authentication configuration for an endpoint. */
|
|
14
|
+
interface AuthConfig {
|
|
15
|
+
/** Whether authentication is required. Defaults to true. */
|
|
16
|
+
required: boolean;
|
|
17
|
+
/** Required role for access. If undefined, any authenticated user is allowed. */
|
|
18
|
+
role?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Middleware context — subset of EndpointContext without input (not yet validated). */
|
|
22
|
+
interface MiddlewareContext extends PalbaseModuleClients {
|
|
23
|
+
params: Record<string, string>;
|
|
24
|
+
query: Record<string, string>;
|
|
25
|
+
headers: Record<string, string>;
|
|
26
|
+
user: User | null;
|
|
27
|
+
db: DBClient;
|
|
28
|
+
env: Record<string, string>;
|
|
29
|
+
log: Logger;
|
|
30
|
+
cache: CacheClient;
|
|
31
|
+
requestId: string;
|
|
32
|
+
projectId: string;
|
|
33
|
+
environmentId: string;
|
|
34
|
+
}
|
|
35
|
+
/** Middleware function signature — receives context and next function. */
|
|
36
|
+
type MiddlewareHandler = (ctx: MiddlewareContext, next: () => Promise<void>) => Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Define a middleware function for use in the middleware/ directory or
|
|
39
|
+
* as endpoint-specific middleware.
|
|
40
|
+
*
|
|
41
|
+
* Middleware runs before the handler. Call `next()` to pass control
|
|
42
|
+
* to the next middleware or handler. If `next()` is not called, the
|
|
43
|
+
* handler will not execute.
|
|
44
|
+
*
|
|
45
|
+
* Errors thrown in middleware are caught by the pipeline and returned
|
|
46
|
+
* as error responses.
|
|
47
|
+
*/
|
|
48
|
+
declare function defineMiddleware(fn: MiddlewareHandler): MiddlewareHandler;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* typed-db.ts — Task 2: TypedDB schema-derived insert/row shapes.
|
|
52
|
+
*
|
|
53
|
+
* Derives INSERT and full-row TypeScript types from a `defineSchema()` result
|
|
54
|
+
* and wraps the untyped runtime `DBClient` with a typed facade.
|
|
55
|
+
*
|
|
56
|
+
* No value-any. No `as unknown as X`. The two narrow `as` casts in
|
|
57
|
+
* `makeTypedTable` are safe because:
|
|
58
|
+
* - `data as Record<string, unknown>`: InsertShape<T> maps string keys to
|
|
59
|
+
* typed values; all value types are subsets of `unknown`, so the cast is
|
|
60
|
+
* structurally sound.
|
|
61
|
+
* - `result as RowShape<T>`: The runtime DBClient returns `Record<string,
|
|
62
|
+
* unknown>` which is the erased form of the typed row; we're narrowing back
|
|
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.
|
|
80
|
+
*
|
|
81
|
+
* When all columns are optional, `RequiredKeys<C>` resolves to `never` and
|
|
82
|
+
* the first part becomes `{}`, which is a neutral element for `&`.
|
|
83
|
+
*/
|
|
84
|
+
type InsertShape<T extends TableDef> = {
|
|
85
|
+
[K in RequiredKeys<T["columns"]>]: ColValue<T["columns"][K]>;
|
|
86
|
+
} & {
|
|
87
|
+
[K in OptionalKeys<T["columns"]>]?: ColValue<T["columns"][K]>;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* The TypeScript type for a full row returned by the DB for table `T`.
|
|
91
|
+
* Every column is present; nullable columns resolve to `T | null`.
|
|
92
|
+
*/
|
|
93
|
+
type RowShape<T extends TableDef> = {
|
|
94
|
+
[K in keyof T["columns"]]: ColValue<T["columns"][K]>;
|
|
95
|
+
};
|
|
96
|
+
/** A typed table accessor that mirrors the runtime DBClient surface. */
|
|
97
|
+
interface TypedTable<T extends TableDef> {
|
|
98
|
+
insert(data: InsertShape<T>): Promise<RowShape<T>>;
|
|
99
|
+
update(id: string, data: Partial<InsertShape<T>>): Promise<RowShape<T>>;
|
|
100
|
+
delete(id: string): Promise<void>;
|
|
101
|
+
findById(id: string): Promise<RowShape<T> | null>;
|
|
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
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Wraps a raw `DBClient` with the type-safe `TypedDB<S>` facade derived from
|
|
112
|
+
* the provided schema. No behavior change — all calls delegate to `raw` with
|
|
113
|
+
* the table name as a plain string.
|
|
114
|
+
*
|
|
115
|
+
* The `satisfies` check verifies the built object is structurally compatible
|
|
116
|
+
* before we present it as `TypedDB<S>`. The final `as TypedDB<S>` is a
|
|
117
|
+
* single structural narrowing from the dynamically-built type to the precise
|
|
118
|
+
* mapped type (TS cannot infer through `Object.keys` iteration).
|
|
119
|
+
*/
|
|
120
|
+
declare function makeTypedDB<S extends SchemaDef>(schema: S, raw: DBClient): TypedDB<S>;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Local typed interfaces for the 9 Palbase module clients injected into
|
|
124
|
+
* every endpoint context via `ctx.auth`, `ctx.storage`, etc.
|
|
125
|
+
*
|
|
126
|
+
* Design intent
|
|
127
|
+
* ─────────────
|
|
128
|
+
* • @palbase/backend owns this contract — no runtime or type dependency on
|
|
129
|
+
* @palbase/server or any module package.
|
|
130
|
+
* • These interfaces are STRUCTURALLY compatible with the runtime's
|
|
131
|
+
* ServerClient module objects so assignment is valid without a cast.
|
|
132
|
+
* • All parameter and return types are defined LOCALLY here (not imported
|
|
133
|
+
* from modules/) to keep the package self-contained.
|
|
134
|
+
*
|
|
135
|
+
* Privilege note
|
|
136
|
+
* ──────────────
|
|
137
|
+
* These clients run with the project's service-role (privileged) key —
|
|
138
|
+
* they bypass end-user RLS; intentional for server handlers. Treat every
|
|
139
|
+
* call as if it has admin access to the project's data.
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
/** A user as returned by auth verifyUserToken. */
|
|
143
|
+
interface PalbaseUser {
|
|
144
|
+
id: string;
|
|
145
|
+
email: string;
|
|
146
|
+
emailVerified?: boolean;
|
|
147
|
+
createdAt?: string;
|
|
148
|
+
updatedAt?: string;
|
|
149
|
+
metadata?: Record<string, unknown>;
|
|
150
|
+
}
|
|
151
|
+
/** A session as returned by auth.getSession(). */
|
|
152
|
+
interface PalbaseSession {
|
|
153
|
+
accessToken: string;
|
|
154
|
+
refreshToken: string;
|
|
155
|
+
expiresAt: number;
|
|
156
|
+
}
|
|
157
|
+
/** MFA enroll result. */
|
|
158
|
+
interface PalbaseMFAEnrollResult {
|
|
159
|
+
enrollment_id?: string;
|
|
160
|
+
secret?: string;
|
|
161
|
+
otp_url?: string;
|
|
162
|
+
qr_code?: string;
|
|
163
|
+
recovery_codes?: string[];
|
|
164
|
+
status?: string;
|
|
165
|
+
}
|
|
166
|
+
/** MFA token response. */
|
|
167
|
+
interface PalbaseTokenResponse {
|
|
168
|
+
access_token: string;
|
|
169
|
+
refresh_token: string;
|
|
170
|
+
token_type: string;
|
|
171
|
+
expires_in: number;
|
|
172
|
+
}
|
|
173
|
+
/** MFA factor. */
|
|
174
|
+
interface PalbaseMFAFactor {
|
|
175
|
+
id: string;
|
|
176
|
+
type: string;
|
|
177
|
+
verified: boolean;
|
|
178
|
+
created_at: string;
|
|
179
|
+
}
|
|
180
|
+
/** Device token view returned by registerDevice. */
|
|
181
|
+
interface PalbaseDeviceTokenView {
|
|
182
|
+
id: string;
|
|
183
|
+
device_id: string;
|
|
184
|
+
platform: "android" | "ios" | "web";
|
|
185
|
+
status: "active" | "inactive";
|
|
186
|
+
created_at: string;
|
|
187
|
+
updated_at: string;
|
|
188
|
+
}
|
|
189
|
+
/** Device info item returned by device.list(). */
|
|
190
|
+
interface PalbaseDeviceInfo {
|
|
191
|
+
id: string;
|
|
192
|
+
platform: string;
|
|
193
|
+
attestation_status: string;
|
|
194
|
+
bound: boolean;
|
|
195
|
+
created_at: string;
|
|
196
|
+
}
|
|
197
|
+
/** Params for device.attestAndroid(). */
|
|
198
|
+
interface PalbaseAttestAndroidParams {
|
|
199
|
+
verdict_token: string;
|
|
200
|
+
}
|
|
201
|
+
/** Result of device.attestAndroid(). */
|
|
202
|
+
interface PalbaseAttestAndroidResult {
|
|
203
|
+
device_id: string;
|
|
204
|
+
attestation_status: string;
|
|
205
|
+
device_integrity?: string;
|
|
206
|
+
}
|
|
207
|
+
/** Params for device.attestiOS(). */
|
|
208
|
+
interface PalbaseAttestiOSParams {
|
|
209
|
+
attestation_object: string;
|
|
210
|
+
key_id: string;
|
|
211
|
+
challenge: string;
|
|
212
|
+
}
|
|
213
|
+
/** Result of device.attestiOS(). */
|
|
214
|
+
interface PalbaseAttestiOSResult {
|
|
215
|
+
device_id: string;
|
|
216
|
+
attestation_status: string;
|
|
217
|
+
}
|
|
218
|
+
/** Params for device.bind(). */
|
|
219
|
+
interface PalbaseBindDeviceParams {
|
|
220
|
+
device_id: string;
|
|
221
|
+
public_key: string;
|
|
222
|
+
platform_attestation?: string;
|
|
223
|
+
}
|
|
224
|
+
/** Params for device.verifyRequestSignature() (server-only). */
|
|
225
|
+
interface PalbaseVerifyRequestSignatureParams {
|
|
226
|
+
payload: string;
|
|
227
|
+
signature: string;
|
|
228
|
+
}
|
|
229
|
+
/** Flag context (user targeting). */
|
|
230
|
+
interface PalbaseFlagContext {
|
|
231
|
+
userId?: string;
|
|
232
|
+
properties?: Record<string, unknown>;
|
|
233
|
+
}
|
|
234
|
+
/** Feature flag variant. */
|
|
235
|
+
interface PalbaseFlagVariant {
|
|
236
|
+
name: string;
|
|
237
|
+
payload?: unknown;
|
|
238
|
+
}
|
|
239
|
+
/** Feature flag (getAll result item). */
|
|
240
|
+
interface PalbaseFlag {
|
|
241
|
+
name: string;
|
|
242
|
+
enabled: boolean;
|
|
243
|
+
variant?: PalbaseFlagVariant;
|
|
244
|
+
}
|
|
245
|
+
/** File object returned by storage operations. */
|
|
246
|
+
interface PalbaseFileObject {
|
|
247
|
+
name: string;
|
|
248
|
+
id: string;
|
|
249
|
+
bucket: string;
|
|
250
|
+
createdAt: string;
|
|
251
|
+
updatedAt: string;
|
|
252
|
+
size: number;
|
|
253
|
+
contentType: string;
|
|
254
|
+
metadata: Record<string, unknown>;
|
|
255
|
+
}
|
|
256
|
+
/** Storage signed URL response. */
|
|
257
|
+
interface PalbaseSignedUrlResponse {
|
|
258
|
+
signedUrl: string;
|
|
259
|
+
}
|
|
260
|
+
/** Storage public URL response. */
|
|
261
|
+
interface PalbasePublicUrlResponse {
|
|
262
|
+
publicUrl: string;
|
|
263
|
+
}
|
|
264
|
+
/** Storage upload options. */
|
|
265
|
+
interface PalbaseUploadOptions {
|
|
266
|
+
contentType?: string;
|
|
267
|
+
upsert?: boolean;
|
|
268
|
+
}
|
|
269
|
+
/** Storage transform options for public URLs. */
|
|
270
|
+
interface PalbaseTransformOptions {
|
|
271
|
+
width?: number;
|
|
272
|
+
height?: number;
|
|
273
|
+
format?: "webp" | "avif" | "jpeg" | "png";
|
|
274
|
+
}
|
|
275
|
+
/** Storage list options. */
|
|
276
|
+
interface PalbaseListOptions {
|
|
277
|
+
limit?: number;
|
|
278
|
+
offset?: number;
|
|
279
|
+
sortBy?: {
|
|
280
|
+
column: string;
|
|
281
|
+
order: "asc" | "desc";
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
/** Realtime message shape for server-side publish. */
|
|
285
|
+
interface PalbaseRealtimeMessage {
|
|
286
|
+
type: "broadcast" | "presence" | "postgres_changes";
|
|
287
|
+
event?: string;
|
|
288
|
+
payload?: Record<string, unknown>;
|
|
289
|
+
}
|
|
290
|
+
/** Edge-function invoke options. */
|
|
291
|
+
interface PalbaseInvokeOptions {
|
|
292
|
+
body?: unknown;
|
|
293
|
+
headers?: Record<string, string>;
|
|
294
|
+
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
295
|
+
}
|
|
296
|
+
/** Push recipient — user ID, array of user IDs, or a topic. */
|
|
297
|
+
type PalbasePushRecipient = string | string[] | {
|
|
298
|
+
topic: string;
|
|
299
|
+
};
|
|
300
|
+
/** Localized text (plain or locale map). */
|
|
301
|
+
type PalbaseLocalizedText = string | Record<string, string>;
|
|
302
|
+
/** Push send params. */
|
|
303
|
+
interface PalbasePushSendParams {
|
|
304
|
+
to: PalbasePushRecipient;
|
|
305
|
+
title?: PalbaseLocalizedText;
|
|
306
|
+
body?: PalbaseLocalizedText;
|
|
307
|
+
variables?: Record<string, string>;
|
|
308
|
+
default_locale?: string;
|
|
309
|
+
data?: Record<string, string>;
|
|
310
|
+
image?: string;
|
|
311
|
+
badge?: number;
|
|
312
|
+
sound?: string;
|
|
313
|
+
deep_link?: string;
|
|
314
|
+
collapse_key?: string;
|
|
315
|
+
priority?: "high" | "normal";
|
|
316
|
+
ttl?: number;
|
|
317
|
+
silent?: boolean;
|
|
318
|
+
content_available?: boolean;
|
|
319
|
+
category?: string;
|
|
320
|
+
metadata?: unknown;
|
|
321
|
+
channels?: Array<"push" | "inbox">;
|
|
322
|
+
inbox_action_url?: string;
|
|
323
|
+
}
|
|
324
|
+
/** Push send response. */
|
|
325
|
+
interface PalbasePushSendResponse {
|
|
326
|
+
message_id?: string;
|
|
327
|
+
message_ids?: string[];
|
|
328
|
+
recipients: number;
|
|
329
|
+
}
|
|
330
|
+
/** Email send params. */
|
|
331
|
+
interface PalbaseEmailSendParams {
|
|
332
|
+
to: string | string[];
|
|
333
|
+
subject?: string;
|
|
334
|
+
template?: string;
|
|
335
|
+
variables?: Record<string, unknown>;
|
|
336
|
+
html?: string;
|
|
337
|
+
text?: string;
|
|
338
|
+
from?: {
|
|
339
|
+
email: string;
|
|
340
|
+
name?: string;
|
|
341
|
+
};
|
|
342
|
+
reply_to?: string;
|
|
343
|
+
category?: string;
|
|
344
|
+
}
|
|
345
|
+
/** Email send response. */
|
|
346
|
+
interface PalbaseEmailSendResponse {
|
|
347
|
+
message_id?: string;
|
|
348
|
+
message_ids?: string[];
|
|
349
|
+
}
|
|
350
|
+
/** SMS send params. */
|
|
351
|
+
interface PalbaseSmsSendParams {
|
|
352
|
+
to: string | string[];
|
|
353
|
+
body: string;
|
|
354
|
+
category?: string;
|
|
355
|
+
}
|
|
356
|
+
/** SMS send response. */
|
|
357
|
+
interface PalbaseSmsSendResponse {
|
|
358
|
+
message_id?: string;
|
|
359
|
+
message_ids?: string[];
|
|
360
|
+
}
|
|
361
|
+
/** Inbox send params (service-role: create inbox row for a user). */
|
|
362
|
+
interface PalbaseInboxSendParams {
|
|
363
|
+
to: string;
|
|
364
|
+
title?: string;
|
|
365
|
+
body: string;
|
|
366
|
+
data?: unknown;
|
|
367
|
+
action_url?: string;
|
|
368
|
+
category?: string;
|
|
369
|
+
channels?: Array<"push" | "inbox">;
|
|
370
|
+
push_deep_link?: string;
|
|
371
|
+
}
|
|
372
|
+
/** Inbox send response. */
|
|
373
|
+
interface PalbaseInboxSendResponse {
|
|
374
|
+
message_id?: string;
|
|
375
|
+
skipped?: boolean;
|
|
376
|
+
}
|
|
377
|
+
/** A per-channel status entry in a multi-channel response. */
|
|
378
|
+
interface PalbaseChannelOutcome {
|
|
379
|
+
status: "queued" | "sent" | "skipped" | "failed";
|
|
380
|
+
message_id?: string;
|
|
381
|
+
message_ids?: string[];
|
|
382
|
+
recipients?: number;
|
|
383
|
+
error?: string;
|
|
384
|
+
}
|
|
385
|
+
/** Multi-channel fan-out response. */
|
|
386
|
+
interface PalbaseMultiChannelResponse {
|
|
387
|
+
channels: Record<string, PalbaseChannelOutcome>;
|
|
388
|
+
}
|
|
389
|
+
/** An inbox message as returned by inbox.list. */
|
|
390
|
+
interface PalbaseInboxMessage {
|
|
391
|
+
id: string;
|
|
392
|
+
user_id?: string;
|
|
393
|
+
title?: string;
|
|
394
|
+
body: string;
|
|
395
|
+
data?: unknown;
|
|
396
|
+
action_url?: string;
|
|
397
|
+
category?: string;
|
|
398
|
+
is_read: boolean;
|
|
399
|
+
read_at?: string;
|
|
400
|
+
created_at: string;
|
|
401
|
+
}
|
|
402
|
+
/** Inbox list options. */
|
|
403
|
+
interface PalbaseInboxListOptions {
|
|
404
|
+
cursor?: string;
|
|
405
|
+
limit?: number;
|
|
406
|
+
is_read?: boolean;
|
|
407
|
+
category?: string;
|
|
408
|
+
include_archived?: boolean;
|
|
409
|
+
}
|
|
410
|
+
/** Inbox list result. */
|
|
411
|
+
interface PalbaseInboxListResult {
|
|
412
|
+
messages: PalbaseInboxMessage[];
|
|
413
|
+
next_cursor?: string;
|
|
414
|
+
}
|
|
415
|
+
/** Notification preferences (channel × category opt-in/out). */
|
|
416
|
+
type PalbasePreferences = Partial<Record<"push" | "email" | "sms" | "inbox", Record<string, boolean>>>;
|
|
417
|
+
/** Register device params. */
|
|
418
|
+
interface PalbaseRegisterDeviceParams {
|
|
419
|
+
device_id: string;
|
|
420
|
+
token: string;
|
|
421
|
+
platform: "android" | "ios" | "web";
|
|
422
|
+
app_version?: string;
|
|
423
|
+
locale?: string;
|
|
424
|
+
}
|
|
425
|
+
/** Analytics event properties. */
|
|
426
|
+
type PalbaseAnalyticsProperties = Record<string, unknown>;
|
|
427
|
+
/** Analytics identify traits. */
|
|
428
|
+
type PalbaseIdentifyTraits = Record<string, unknown>;
|
|
429
|
+
/** Analytics count query input. */
|
|
430
|
+
interface PalbaseCountQueryInput {
|
|
431
|
+
eventName?: string;
|
|
432
|
+
eventNames?: string[];
|
|
433
|
+
from: number;
|
|
434
|
+
to: number;
|
|
435
|
+
interval?: "hour" | "day";
|
|
436
|
+
filters?: Record<string, string>;
|
|
437
|
+
breakdown?: string;
|
|
438
|
+
}
|
|
439
|
+
/** A single time-bucket in a count result. */
|
|
440
|
+
interface PalbaseCountBucket {
|
|
441
|
+
t: number;
|
|
442
|
+
count: number;
|
|
443
|
+
breakdown?: string;
|
|
444
|
+
}
|
|
445
|
+
/** Count query result. */
|
|
446
|
+
interface PalbaseCountResult {
|
|
447
|
+
series: PalbaseCountBucket[];
|
|
448
|
+
from_mv: boolean;
|
|
449
|
+
}
|
|
450
|
+
/** Events query input. */
|
|
451
|
+
interface PalbaseEventsQueryInput {
|
|
452
|
+
from: number;
|
|
453
|
+
to: number;
|
|
454
|
+
eventName?: string;
|
|
455
|
+
distinctId?: string;
|
|
456
|
+
limit?: number;
|
|
457
|
+
cursor?: string;
|
|
458
|
+
}
|
|
459
|
+
/** A single event row. */
|
|
460
|
+
interface PalbaseEventRow {
|
|
461
|
+
event_id: string;
|
|
462
|
+
timestamp: number;
|
|
463
|
+
event_name: string;
|
|
464
|
+
distinct_id: string;
|
|
465
|
+
properties: Record<string, unknown>;
|
|
466
|
+
}
|
|
467
|
+
/** Events query result. */
|
|
468
|
+
interface PalbaseEventsResult {
|
|
469
|
+
events: PalbaseEventRow[];
|
|
470
|
+
next_cursor?: string;
|
|
471
|
+
}
|
|
472
|
+
/** Properties query input. */
|
|
473
|
+
interface PalbasePropertiesQueryInput {
|
|
474
|
+
eventName?: string;
|
|
475
|
+
from?: number;
|
|
476
|
+
to?: number;
|
|
477
|
+
}
|
|
478
|
+
/** Property descriptor (from /query/properties). */
|
|
479
|
+
interface PalbasePropertyDescriptor {
|
|
480
|
+
name: string;
|
|
481
|
+
value_count: number;
|
|
482
|
+
}
|
|
483
|
+
/** Users query input. */
|
|
484
|
+
interface PalbaseUsersQueryInput {
|
|
485
|
+
from: number;
|
|
486
|
+
to: number;
|
|
487
|
+
filters?: Record<string, string>;
|
|
488
|
+
limit?: number;
|
|
489
|
+
cursor?: string;
|
|
490
|
+
}
|
|
491
|
+
/** A single user row. */
|
|
492
|
+
interface PalbaseUserRow {
|
|
493
|
+
distinct_id: string;
|
|
494
|
+
first_seen: number;
|
|
495
|
+
last_seen: number;
|
|
496
|
+
event_count: number;
|
|
497
|
+
properties?: Record<string, unknown>;
|
|
498
|
+
}
|
|
499
|
+
/** Users query result. */
|
|
500
|
+
interface PalbaseUsersResult {
|
|
501
|
+
users: PalbaseUserRow[];
|
|
502
|
+
next_cursor?: string;
|
|
503
|
+
}
|
|
504
|
+
/** Funnel query input. */
|
|
505
|
+
interface PalbaseFunnelQueryInput {
|
|
506
|
+
steps: Array<{
|
|
507
|
+
event_name: string;
|
|
508
|
+
filters?: Record<string, string>;
|
|
509
|
+
}>;
|
|
510
|
+
from: number;
|
|
511
|
+
to: number;
|
|
512
|
+
conversionWindowSeconds?: number;
|
|
513
|
+
breakdown?: string;
|
|
514
|
+
}
|
|
515
|
+
/** Funnel step result. */
|
|
516
|
+
interface PalbaseFunnelStepResult {
|
|
517
|
+
event_name: string;
|
|
518
|
+
count: number;
|
|
519
|
+
conversion_rate: number;
|
|
520
|
+
}
|
|
521
|
+
/** Funnel query result. */
|
|
522
|
+
interface PalbaseFunnelResult {
|
|
523
|
+
steps: PalbaseFunnelStepResult[];
|
|
524
|
+
overall_conversion_rate: number;
|
|
525
|
+
}
|
|
526
|
+
/** Retention query input. */
|
|
527
|
+
interface PalbaseRetentionQueryInput {
|
|
528
|
+
firstEvent: string;
|
|
529
|
+
returnEvent: string;
|
|
530
|
+
from: number;
|
|
531
|
+
to: number;
|
|
532
|
+
periodDays?: number;
|
|
533
|
+
periods?: number;
|
|
534
|
+
}
|
|
535
|
+
/** Retention cohort result item. */
|
|
536
|
+
interface PalbaseRetentionCohort {
|
|
537
|
+
cohort_start: number;
|
|
538
|
+
size: number;
|
|
539
|
+
periods: number[];
|
|
540
|
+
}
|
|
541
|
+
/** Retention query result. */
|
|
542
|
+
interface PalbaseRetentionResult {
|
|
543
|
+
cohorts: PalbaseRetentionCohort[];
|
|
544
|
+
}
|
|
545
|
+
/** Cohort query input. */
|
|
546
|
+
interface PalbaseCohortQueryInput {
|
|
547
|
+
name: string;
|
|
548
|
+
rules: Array<{
|
|
549
|
+
event_name: string;
|
|
550
|
+
filters?: Record<string, string>;
|
|
551
|
+
}>;
|
|
552
|
+
from: number;
|
|
553
|
+
to: number;
|
|
554
|
+
}
|
|
555
|
+
/** Cohort query result. */
|
|
556
|
+
interface PalbaseCohortResult {
|
|
557
|
+
size: number;
|
|
558
|
+
distinct_ids_sample: string[];
|
|
559
|
+
}
|
|
560
|
+
/** Analytics overview result. */
|
|
561
|
+
interface PalbaseOverviewResult {
|
|
562
|
+
dau: number;
|
|
563
|
+
wau: number;
|
|
564
|
+
mau: number;
|
|
565
|
+
total_events: number;
|
|
566
|
+
top_events: Array<{
|
|
567
|
+
event_name: string;
|
|
568
|
+
count: number;
|
|
569
|
+
}>;
|
|
570
|
+
}
|
|
571
|
+
/** Event names result. */
|
|
572
|
+
interface PalbaseEventNamesResult {
|
|
573
|
+
names: string[];
|
|
574
|
+
}
|
|
575
|
+
/** User detail result. */
|
|
576
|
+
interface PalbaseUserDetailResult {
|
|
577
|
+
distinct_id: string;
|
|
578
|
+
first_seen: number;
|
|
579
|
+
last_seen: number;
|
|
580
|
+
event_count: number;
|
|
581
|
+
properties: Record<string, unknown>;
|
|
582
|
+
recent_events: PalbaseEventRow[];
|
|
583
|
+
}
|
|
584
|
+
/** Create link params. */
|
|
585
|
+
interface PalbaseCreateLinkParams {
|
|
586
|
+
url: string;
|
|
587
|
+
title?: string;
|
|
588
|
+
description?: string;
|
|
589
|
+
imageUrl?: string;
|
|
590
|
+
ios?: {
|
|
591
|
+
bundleId: string;
|
|
592
|
+
appStoreId?: string;
|
|
593
|
+
fallbackUrl?: string;
|
|
594
|
+
minimumVersion?: string;
|
|
595
|
+
};
|
|
596
|
+
android?: {
|
|
597
|
+
packageName: string;
|
|
598
|
+
fallbackUrl?: string;
|
|
599
|
+
minimumVersion?: number;
|
|
600
|
+
};
|
|
601
|
+
web?: {
|
|
602
|
+
fallbackUrl?: string;
|
|
603
|
+
};
|
|
604
|
+
social?: {
|
|
605
|
+
title?: string;
|
|
606
|
+
description?: string;
|
|
607
|
+
imageUrl?: string;
|
|
608
|
+
};
|
|
609
|
+
expiresAt?: string;
|
|
610
|
+
customShortCode?: string;
|
|
611
|
+
}
|
|
612
|
+
/** Update link params. */
|
|
613
|
+
interface PalbaseUpdateLinkParams {
|
|
614
|
+
url?: string;
|
|
615
|
+
title?: string;
|
|
616
|
+
description?: string;
|
|
617
|
+
imageUrl?: string;
|
|
618
|
+
ios?: {
|
|
619
|
+
bundleId?: string;
|
|
620
|
+
appStoreId?: string;
|
|
621
|
+
fallbackUrl?: string;
|
|
622
|
+
minimumVersion?: string;
|
|
623
|
+
};
|
|
624
|
+
android?: {
|
|
625
|
+
packageName?: string;
|
|
626
|
+
fallbackUrl?: string;
|
|
627
|
+
minimumVersion?: number;
|
|
628
|
+
};
|
|
629
|
+
web?: {
|
|
630
|
+
fallbackUrl?: string;
|
|
631
|
+
};
|
|
632
|
+
social?: {
|
|
633
|
+
title?: string;
|
|
634
|
+
description?: string;
|
|
635
|
+
imageUrl?: string;
|
|
636
|
+
};
|
|
637
|
+
expiresAt?: string;
|
|
638
|
+
}
|
|
639
|
+
/** A link object. */
|
|
640
|
+
interface PalbaseLink {
|
|
641
|
+
id: string;
|
|
642
|
+
shortCode: string;
|
|
643
|
+
shortUrl: string;
|
|
644
|
+
url: string;
|
|
645
|
+
title?: string;
|
|
646
|
+
clickCount: number;
|
|
647
|
+
createdAt: string;
|
|
648
|
+
}
|
|
649
|
+
/** Link details (extended link). */
|
|
650
|
+
interface PalbaseLinkDetails extends PalbaseLink {
|
|
651
|
+
description?: string;
|
|
652
|
+
imageUrl?: string;
|
|
653
|
+
ios?: Record<string, unknown>;
|
|
654
|
+
android?: Record<string, unknown>;
|
|
655
|
+
web?: Record<string, unknown>;
|
|
656
|
+
social?: Record<string, unknown>;
|
|
657
|
+
expiresAt?: string;
|
|
658
|
+
}
|
|
659
|
+
/** Link analytics. */
|
|
660
|
+
interface PalbaseLinkAnalytics {
|
|
661
|
+
totalClicks: number;
|
|
662
|
+
clicksByPlatform: Record<string, number>;
|
|
663
|
+
clicksByCountry: Record<string, number>;
|
|
664
|
+
clicksByDay: Array<{
|
|
665
|
+
date: string;
|
|
666
|
+
clicks: number;
|
|
667
|
+
}>;
|
|
668
|
+
}
|
|
669
|
+
/** QR code options. */
|
|
670
|
+
interface PalbaseQrCodeOptions {
|
|
671
|
+
size?: number;
|
|
672
|
+
format?: "png" | "svg";
|
|
673
|
+
}
|
|
674
|
+
/** Match params for deferred deep link resolution. */
|
|
675
|
+
interface PalbaseMatchParams {
|
|
676
|
+
fingerprintHash: string;
|
|
677
|
+
}
|
|
678
|
+
/** Initial deep link. */
|
|
679
|
+
interface PalbaseInitialLink {
|
|
680
|
+
url: string;
|
|
681
|
+
params?: Record<string, string>;
|
|
682
|
+
}
|
|
683
|
+
/** List links options. */
|
|
684
|
+
interface PalbaseListLinksOptions {
|
|
685
|
+
limit?: number;
|
|
686
|
+
offset?: number;
|
|
687
|
+
}
|
|
688
|
+
/** List links result. */
|
|
689
|
+
interface PalbaseListLinksResult {
|
|
690
|
+
links: PalbaseLink[];
|
|
691
|
+
total: number;
|
|
692
|
+
}
|
|
693
|
+
/** CMS find options. */
|
|
694
|
+
interface PalbaseCmsFindOptions {
|
|
695
|
+
locale?: string;
|
|
696
|
+
limit?: number;
|
|
697
|
+
offset?: number;
|
|
698
|
+
filter?: Record<string, unknown>;
|
|
699
|
+
}
|
|
700
|
+
/** CMS find-one options. */
|
|
701
|
+
interface PalbaseCmsFindOneOptions {
|
|
702
|
+
locale?: string;
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* Auth client surface available on `ctx.auth`.
|
|
706
|
+
* Exposes server-relevant methods only. Browser-only patterns are omitted:
|
|
707
|
+
* — signUp / signIn / signOut / refresh / requestPasswordReset / confirmPasswordReset
|
|
708
|
+
* / changePassword / resendVerification / verifyEmail (client flow helpers)
|
|
709
|
+
* — onAuthStateChange / onTokenChange (subscription callbacks)
|
|
710
|
+
* — getOAuthURL / signInWithCredential (OAuth browser redirects)
|
|
711
|
+
* — requestMagicLink / verifyMagicLink (client flow helpers)
|
|
712
|
+
* — setTokens / getAccessToken (internal token management)
|
|
713
|
+
* — listSessions / revokeSession / revokeAllSessions (user-self management)
|
|
714
|
+
* — listIdentities / linkIdentity / unlinkIdentity (user-self management)
|
|
715
|
+
* — listTrustedDevices / registerTrustedDevice / revokeTrustedDevice (user-self management)
|
|
716
|
+
*/
|
|
717
|
+
interface PalbaseAuthClient {
|
|
718
|
+
/**
|
|
719
|
+
* Verify a user's JWT by calling GET /auth/user. Returns the user if the
|
|
720
|
+
* token is valid; error otherwise. Service-role privileged.
|
|
721
|
+
*/
|
|
722
|
+
verifyUserToken(jwt: string): Promise<PalbaseResult<PalbaseUser>>;
|
|
723
|
+
/**
|
|
724
|
+
* Get the current session held by the client (synchronous — no network
|
|
725
|
+
* call). On the server the service-role client does not hold a user
|
|
726
|
+
* session; this always returns `{ data: null, error: null }`.
|
|
727
|
+
*/
|
|
728
|
+
getSession(): {
|
|
729
|
+
data: PalbaseSession | null;
|
|
730
|
+
error: null;
|
|
731
|
+
};
|
|
732
|
+
/** MFA admin surface — enroll/verify/manage factors on behalf of users. */
|
|
733
|
+
mfa: {
|
|
734
|
+
/** Enroll a new MFA factor (TOTP or email). */
|
|
735
|
+
enroll(params: {
|
|
736
|
+
type: "totp" | "email";
|
|
737
|
+
}): Promise<PalbaseResult<PalbaseMFAEnrollResult>>;
|
|
738
|
+
/** Verify an enrollment code. */
|
|
739
|
+
verifyEnrollment(code: string): Promise<PalbaseResult<{
|
|
740
|
+
status: string;
|
|
741
|
+
}>>;
|
|
742
|
+
/** Challenge an MFA factor (verify code, obtain token). */
|
|
743
|
+
challenge(params: {
|
|
744
|
+
mfa_token: string;
|
|
745
|
+
type: "totp" | "email";
|
|
746
|
+
code: string;
|
|
747
|
+
}): Promise<PalbaseResult<PalbaseTokenResponse>>;
|
|
748
|
+
/** Recover via backup code. */
|
|
749
|
+
recovery(params: {
|
|
750
|
+
mfa_token: string;
|
|
751
|
+
code: string;
|
|
752
|
+
}): Promise<PalbaseResult<PalbaseTokenResponse>>;
|
|
753
|
+
/** List enrolled factors. */
|
|
754
|
+
listFactors(): Promise<PalbaseResult<{
|
|
755
|
+
factors: PalbaseMFAFactor[];
|
|
756
|
+
}>>;
|
|
757
|
+
/** Remove a factor. Requires current password. */
|
|
758
|
+
removeFactor(factorId: string, currentPassword: string): Promise<PalbaseResult<{
|
|
759
|
+
status: string;
|
|
760
|
+
}>>;
|
|
761
|
+
/** Regenerate recovery codes. */
|
|
762
|
+
regenerateRecoveryCodes(): Promise<PalbaseResult<{
|
|
763
|
+
recovery_codes: string[];
|
|
764
|
+
}>>;
|
|
765
|
+
/** Email MFA: start enrollment. */
|
|
766
|
+
emailEnroll(): Promise<PalbaseResult<{
|
|
767
|
+
status: string;
|
|
768
|
+
}>>;
|
|
769
|
+
/** Email MFA: send challenge. */
|
|
770
|
+
emailChallenge(params: {
|
|
771
|
+
mfa_token: string;
|
|
772
|
+
}): Promise<PalbaseResult<{
|
|
773
|
+
status: string;
|
|
774
|
+
}>>;
|
|
775
|
+
/** Email MFA: verify code. */
|
|
776
|
+
emailVerify(params: {
|
|
777
|
+
mfa_token: string;
|
|
778
|
+
code: string;
|
|
779
|
+
}): Promise<PalbaseResult<PalbaseTokenResponse>>;
|
|
780
|
+
};
|
|
781
|
+
/** Device attestation surface (App Attest / Play Integrity). */
|
|
782
|
+
device: {
|
|
783
|
+
/** Generate a device attestation challenge. */
|
|
784
|
+
generateChallenge(): Promise<PalbaseResult<{
|
|
785
|
+
challenge: string;
|
|
786
|
+
}>>;
|
|
787
|
+
/** Attest an Android device with a Play Integrity verdict token. */
|
|
788
|
+
attestAndroid(params: PalbaseAttestAndroidParams): Promise<PalbaseResult<PalbaseAttestAndroidResult>>;
|
|
789
|
+
/** Attest an iOS device with App Attest attestation data. */
|
|
790
|
+
attestiOS(params: PalbaseAttestiOSParams): Promise<PalbaseResult<PalbaseAttestiOSResult>>;
|
|
791
|
+
/** Bind a verified device with a public key for request signing. */
|
|
792
|
+
bind(params: PalbaseBindDeviceParams): Promise<PalbaseResult<{
|
|
793
|
+
success: boolean;
|
|
794
|
+
}>>;
|
|
795
|
+
/** List all devices for the current user. */
|
|
796
|
+
list(): Promise<PalbaseResult<{
|
|
797
|
+
devices: PalbaseDeviceInfo[];
|
|
798
|
+
}>>;
|
|
799
|
+
/** Delete a device by ID. */
|
|
800
|
+
delete(deviceId: string): Promise<PalbaseResult<{
|
|
801
|
+
success: boolean;
|
|
802
|
+
}>>;
|
|
803
|
+
/**
|
|
804
|
+
* Verify a request signature from a device (server-only).
|
|
805
|
+
* Not exposed in the client SDK.
|
|
806
|
+
*/
|
|
807
|
+
verifyRequestSignature(deviceId: string, params: PalbaseVerifyRequestSignatureParams): Promise<PalbaseResult<{
|
|
808
|
+
verified: boolean;
|
|
809
|
+
}>>;
|
|
810
|
+
/** Get the cached App Check token, or null if not available / expired. */
|
|
811
|
+
getToken(): string | null;
|
|
812
|
+
/** Whether App Check is active (token cached and not expired). */
|
|
813
|
+
readonly isActive: boolean;
|
|
814
|
+
/** Set a cached App Check token manually (e.g. after attest flow). */
|
|
815
|
+
setCachedToken(token: string, expiresInMs: number): void;
|
|
816
|
+
/** Clean up timers and cached state. */
|
|
817
|
+
dispose(): void;
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Bucket-level file operations available via `ctx.storage.bucket(name)`.
|
|
822
|
+
* `getPublicUrl` is synchronous (no network call — constructs URL locally).
|
|
823
|
+
*/
|
|
824
|
+
interface PalbaseBucketClient {
|
|
825
|
+
/** Upload a file. */
|
|
826
|
+
upload(path: string, file: Blob | ArrayBuffer | ReadableStream, options?: PalbaseUploadOptions): Promise<PalbaseResult<PalbaseFileObject>>;
|
|
827
|
+
/** Download a file as a Blob. */
|
|
828
|
+
download(path: string): Promise<PalbaseResult<Blob>>;
|
|
829
|
+
/** Construct the public URL for a file (sync — no network call). */
|
|
830
|
+
getPublicUrl(path: string, options?: PalbaseTransformOptions): {
|
|
831
|
+
data: PalbasePublicUrlResponse;
|
|
832
|
+
};
|
|
833
|
+
/** Create a time-limited signed URL. */
|
|
834
|
+
createSignedUrl(path: string, expiresIn: number): Promise<PalbaseResult<PalbaseSignedUrlResponse>>;
|
|
835
|
+
/** List objects in the bucket (optionally filtered by prefix). */
|
|
836
|
+
list(prefix?: string, options?: PalbaseListOptions): Promise<PalbaseResult<PalbaseFileObject[]>>;
|
|
837
|
+
/** Delete one or more objects. */
|
|
838
|
+
remove(paths: string[]): Promise<PalbaseResult<PalbaseFileObject[]>>;
|
|
839
|
+
/** Move / rename an object. */
|
|
840
|
+
move(from: string, to: string): Promise<PalbaseResult<void>>;
|
|
841
|
+
/** Copy an object. */
|
|
842
|
+
copy(from: string, to: string): Promise<PalbaseResult<void>>;
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Storage client available on `ctx.storage`.
|
|
846
|
+
* Only `bucket()` is exposed — service-role callers select a bucket first.
|
|
847
|
+
*/
|
|
848
|
+
interface PalbaseStorageClient {
|
|
849
|
+
/** Get a bucket-scoped client for file operations. */
|
|
850
|
+
bucket(name: string): PalbaseBucketClient;
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Channel reference for server-side realtime publish.
|
|
854
|
+
* Omits browser subscription patterns (on(), presenceState()) and
|
|
855
|
+
* internal test helpers (_injectWebSocket). All send operations are
|
|
856
|
+
* synchronous — they throw if the channel is not subscribed.
|
|
857
|
+
*/
|
|
858
|
+
interface PalbaseRealtimeChannel {
|
|
859
|
+
/** The channel name. */
|
|
860
|
+
readonly name: string;
|
|
861
|
+
/** Send a message to all channel subscribers. */
|
|
862
|
+
send(message: PalbaseRealtimeMessage): void;
|
|
863
|
+
/** Track server presence state. */
|
|
864
|
+
track(state: Record<string, unknown>): void;
|
|
865
|
+
/** Remove server presence state. */
|
|
866
|
+
untrack(): void;
|
|
867
|
+
/** Subscribe (connect WebSocket). Returns `this` for chaining. */
|
|
868
|
+
subscribe(): PalbaseRealtimeChannel;
|
|
869
|
+
/** Unsubscribe (close WebSocket). */
|
|
870
|
+
unsubscribe(): void;
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* Realtime client available on `ctx.realtime`.
|
|
874
|
+
* Server-side usage: get a channel, call send() to publish broadcasts.
|
|
875
|
+
* Omits browser subscription patterns (onSnapshot, subscribe listeners).
|
|
876
|
+
*/
|
|
877
|
+
interface PalbaseRealtimeClient {
|
|
878
|
+
/** Get (or create) a named channel. */
|
|
879
|
+
channel(name: string): PalbaseRealtimeChannel;
|
|
880
|
+
/** Remove a channel and close its WebSocket. */
|
|
881
|
+
removeChannel(name: string): void;
|
|
882
|
+
/** Remove all channels and close all WebSockets. */
|
|
883
|
+
removeAllChannels(): void;
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Functions client available on `ctx.functions`.
|
|
887
|
+
* Invoke edge functions from a backend endpoint.
|
|
888
|
+
*/
|
|
889
|
+
interface PalbaseFunctionsClient {
|
|
890
|
+
/** Invoke a named edge function. */
|
|
891
|
+
invoke<T = unknown>(fnName: string, options?: PalbaseInvokeOptions): Promise<PalbaseResult<T>>;
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Flags client available on `ctx.flags`.
|
|
895
|
+
* Evaluate feature flags server-side (service-role key — user targeting
|
|
896
|
+
* is optional via context).
|
|
897
|
+
*/
|
|
898
|
+
interface PalbaseFlagsClient {
|
|
899
|
+
/** Is a flag enabled for the given context? */
|
|
900
|
+
isEnabled(flagName: string, context?: PalbaseFlagContext): Promise<PalbaseResult<boolean>>;
|
|
901
|
+
/** Get the active variant of a multivariate flag. */
|
|
902
|
+
getVariant(flagName: string, context?: PalbaseFlagContext): Promise<PalbaseResult<PalbaseFlagVariant>>;
|
|
903
|
+
/** Get all flags for the project. */
|
|
904
|
+
getAll(context?: PalbaseFlagContext): Promise<PalbaseResult<PalbaseFlag[]>>;
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Push sub-client surface (server-only: fan-out to users / topics).
|
|
908
|
+
*/
|
|
909
|
+
interface PalbasePushClient {
|
|
910
|
+
/** Send a push notification to one or more users, or a topic. */
|
|
911
|
+
send(params: PalbasePushSendParams): Promise<PalbaseResult<PalbasePushSendResponse | PalbaseMultiChannelResponse>>;
|
|
912
|
+
}
|
|
913
|
+
/**
|
|
914
|
+
* Email sub-client surface (service-role).
|
|
915
|
+
*/
|
|
916
|
+
interface PalbaseEmailClient {
|
|
917
|
+
/** Send a transactional email. */
|
|
918
|
+
send(params: PalbaseEmailSendParams): Promise<PalbaseResult<PalbaseEmailSendResponse>>;
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* SMS sub-client surface (service-role).
|
|
922
|
+
*/
|
|
923
|
+
interface PalbaseSmsClient {
|
|
924
|
+
/** Send an SMS message. */
|
|
925
|
+
send(params: PalbaseSmsSendParams): Promise<PalbaseResult<PalbaseSmsSendResponse>>;
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* Inbox sub-client surface (service-role send + user read operations).
|
|
929
|
+
*/
|
|
930
|
+
interface PalbaseInboxClient {
|
|
931
|
+
/** Service-role: create an inbox notification row for a user. */
|
|
932
|
+
send(params: PalbaseInboxSendParams): Promise<PalbaseResult<PalbaseInboxSendResponse | PalbaseMultiChannelResponse>>;
|
|
933
|
+
/** List inbox messages (user-scoped or admin). */
|
|
934
|
+
list(options?: PalbaseInboxListOptions): Promise<PalbaseResult<PalbaseInboxListResult>>;
|
|
935
|
+
/** Count unread messages. */
|
|
936
|
+
unreadCount(): Promise<PalbaseResult<{
|
|
937
|
+
count: number;
|
|
938
|
+
}>>;
|
|
939
|
+
/** Mark a message as read. */
|
|
940
|
+
markRead(id: string): Promise<PalbaseResult<void>>;
|
|
941
|
+
/** Mark all messages read. */
|
|
942
|
+
markAllRead(): Promise<PalbaseResult<void>>;
|
|
943
|
+
/** Archive (soft-delete) a message. */
|
|
944
|
+
archive(id: string): Promise<PalbaseResult<void>>;
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* Preferences sub-client surface.
|
|
948
|
+
*/
|
|
949
|
+
interface PalbasePreferencesClient {
|
|
950
|
+
/** Get notification preferences. */
|
|
951
|
+
get(): Promise<PalbaseResult<PalbasePreferences>>;
|
|
952
|
+
/** Update notification preferences. */
|
|
953
|
+
update(params: PalbasePreferences): Promise<PalbaseResult<PalbasePreferences>>;
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Notifications client available on `ctx.notifications`.
|
|
957
|
+
* Service-role: all send operations require privileged access.
|
|
958
|
+
* Omits ClientNotificationsClient (browser-only narrowed surface).
|
|
959
|
+
*/
|
|
960
|
+
interface PalbaseNotificationsClient {
|
|
961
|
+
/** Push notification sender. */
|
|
962
|
+
push: PalbasePushClient;
|
|
963
|
+
/** Email sender. */
|
|
964
|
+
email: PalbaseEmailClient;
|
|
965
|
+
/** SMS sender. */
|
|
966
|
+
sms: PalbaseSmsClient;
|
|
967
|
+
/** Inbox (in-app) message sender and reader. */
|
|
968
|
+
inbox: PalbaseInboxClient;
|
|
969
|
+
/** Notification preferences manager. */
|
|
970
|
+
preferences: PalbasePreferencesClient;
|
|
971
|
+
/** Register a device for push notifications. */
|
|
972
|
+
registerDevice(params: PalbaseRegisterDeviceParams): Promise<PalbaseResult<PalbaseDeviceTokenView>>;
|
|
973
|
+
/** Remove a device registration. */
|
|
974
|
+
unregisterDevice(deviceId: string): Promise<PalbaseResult<void>>;
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Analytics query namespace (read-side endpoints).
|
|
978
|
+
*/
|
|
979
|
+
interface PalbaseAnalyticsQueryNamespace {
|
|
980
|
+
/** Count events over time. */
|
|
981
|
+
count(input: PalbaseCountQueryInput): Promise<PalbaseResult<PalbaseCountResult>>;
|
|
982
|
+
/** List raw events. */
|
|
983
|
+
events(input: PalbaseEventsQueryInput): Promise<PalbaseResult<PalbaseEventsResult>>;
|
|
984
|
+
/** List event property descriptors. */
|
|
985
|
+
properties(input?: PalbasePropertiesQueryInput): Promise<PalbaseResult<PalbasePropertyDescriptor[]>>;
|
|
986
|
+
/** Query users by filters. */
|
|
987
|
+
users(input: PalbaseUsersQueryInput): Promise<PalbaseResult<PalbaseUsersResult>>;
|
|
988
|
+
/** Run a funnel query. */
|
|
989
|
+
funnel(input: PalbaseFunnelQueryInput): Promise<PalbaseResult<PalbaseFunnelResult>>;
|
|
990
|
+
/** Run a retention query. */
|
|
991
|
+
retention(input: PalbaseRetentionQueryInput): Promise<PalbaseResult<PalbaseRetentionResult>>;
|
|
992
|
+
/** Run a cohort query. */
|
|
993
|
+
cohort(input: PalbaseCohortQueryInput): Promise<PalbaseResult<PalbaseCohortResult>>;
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* Analytics management namespace (meta-level endpoints).
|
|
997
|
+
*/
|
|
998
|
+
interface PalbaseAnalyticsManagementNamespace {
|
|
999
|
+
/** Get project-level overview stats. */
|
|
1000
|
+
overview(): Promise<PalbaseResult<PalbaseOverviewResult>>;
|
|
1001
|
+
/** Get all event names seen by the project. */
|
|
1002
|
+
eventNames(): Promise<PalbaseResult<PalbaseEventNamesResult>>;
|
|
1003
|
+
/** Get details for a specific user. */
|
|
1004
|
+
userDetail(distinctId: string): Promise<PalbaseResult<PalbaseUserDetailResult>>;
|
|
1005
|
+
/** Delete all data for a user (GDPR erasure). */
|
|
1006
|
+
deleteUser(distinctId: string): Promise<PalbaseResult<void>>;
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* Analytics client available on `ctx.analytics`.
|
|
1010
|
+
* Capture events server-side and run analytical queries.
|
|
1011
|
+
*/
|
|
1012
|
+
interface PalbaseAnalyticsClient {
|
|
1013
|
+
/** Capture a custom event. */
|
|
1014
|
+
capture(event: string, properties?: PalbaseAnalyticsProperties, distinctId?: string): Promise<PalbaseResult<void>>;
|
|
1015
|
+
/** Identify a user with traits. */
|
|
1016
|
+
identify(distinctId: string, traits?: PalbaseIdentifyTraits): Promise<PalbaseResult<void>>;
|
|
1017
|
+
/** Track a screen view. */
|
|
1018
|
+
screen(screenName: string, properties?: PalbaseAnalyticsProperties, distinctId?: string): Promise<PalbaseResult<void>>;
|
|
1019
|
+
/** Query namespace for analytics read operations. */
|
|
1020
|
+
query: PalbaseAnalyticsQueryNamespace;
|
|
1021
|
+
/** Management namespace for meta-level operations. */
|
|
1022
|
+
management: PalbaseAnalyticsManagementNamespace;
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Deep-links client available on `ctx.links`.
|
|
1026
|
+
* Create, manage, and resolve deep links from server endpoints.
|
|
1027
|
+
* Omits `getInitialLink()` (client SDK convenience — browser/app only).
|
|
1028
|
+
*/
|
|
1029
|
+
interface PalbaseLinksClient {
|
|
1030
|
+
/** Create a short link. */
|
|
1031
|
+
create(params: PalbaseCreateLinkParams): Promise<PalbaseResult<PalbaseLink>>;
|
|
1032
|
+
/** List links (paginated). */
|
|
1033
|
+
list(options?: PalbaseListLinksOptions): Promise<PalbaseResult<PalbaseListLinksResult>>;
|
|
1034
|
+
/** Get link details + analytics summary. */
|
|
1035
|
+
get(linkId: string): Promise<PalbaseResult<PalbaseLinkDetails>>;
|
|
1036
|
+
/** Update a link. */
|
|
1037
|
+
update(linkId: string, params: PalbaseUpdateLinkParams): Promise<PalbaseResult<PalbaseLink>>;
|
|
1038
|
+
/** Delete a link. */
|
|
1039
|
+
delete(linkId: string): Promise<PalbaseResult<{
|
|
1040
|
+
success: boolean;
|
|
1041
|
+
}>>;
|
|
1042
|
+
/** Get click analytics for a link. */
|
|
1043
|
+
analytics(linkId: string): Promise<PalbaseResult<PalbaseLinkAnalytics>>;
|
|
1044
|
+
/** Generate a QR code for a link (returns PNG or SVG Blob). */
|
|
1045
|
+
qrCode(linkId: string, options?: PalbaseQrCodeOptions): Promise<PalbaseResult<Blob>>;
|
|
1046
|
+
/** Match a deferred deep link by device fingerprint. */
|
|
1047
|
+
match(params: PalbaseMatchParams): Promise<PalbaseResult<PalbaseInitialLink | null>>;
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* CMS client available on `ctx.cms`.
|
|
1051
|
+
* Fetch content from PayloadCMS collections within a server endpoint.
|
|
1052
|
+
*/
|
|
1053
|
+
interface PalbaseCmsClient {
|
|
1054
|
+
/** Find multiple documents in a collection. */
|
|
1055
|
+
find<T = unknown>(collection: string, options?: PalbaseCmsFindOptions): Promise<PalbaseResult<T[]>>;
|
|
1056
|
+
/** Find a single document by ID. */
|
|
1057
|
+
findOne<T = unknown>(collection: string, id: string, options?: PalbaseCmsFindOneOptions): Promise<PalbaseResult<T>>;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
/** Uploaded file metadata injected into endpoint context when a file is present.
|
|
1061
|
+
* `data` is typed as `Uint8Array` for SDK portability (Buffer extends Uint8Array in Node).
|
|
1062
|
+
*/
|
|
1063
|
+
interface FileContext {
|
|
1064
|
+
filename: string;
|
|
1065
|
+
contentType: string;
|
|
1066
|
+
size: number;
|
|
1067
|
+
data: Uint8Array;
|
|
1068
|
+
}
|
|
1069
|
+
/** Queue client for dispatching background jobs from within a handler. */
|
|
1070
|
+
interface QueueClient {
|
|
1071
|
+
/** Enqueue a job for the named worker. Returns the new job ID. */
|
|
1072
|
+
push(worker: string, payload: unknown): Promise<{
|
|
1073
|
+
jobId: string;
|
|
1074
|
+
}>;
|
|
1075
|
+
}
|
|
1076
|
+
/** Rate limit configuration for an endpoint. */
|
|
1077
|
+
interface RateLimitConfig {
|
|
1078
|
+
/** Maximum number of requests in the window. */
|
|
1079
|
+
max: number;
|
|
1080
|
+
/** Window duration in seconds. */
|
|
1081
|
+
window: number;
|
|
1082
|
+
}
|
|
1083
|
+
/** Database client interface injected into endpoint context. */
|
|
1084
|
+
interface DBClient {
|
|
1085
|
+
/** Run a read-only SQL query (executes in a READ ONLY transaction). */
|
|
1086
|
+
query(sql: string, params?: unknown[]): Promise<Record<string, unknown>[]>;
|
|
1087
|
+
insert(table: string, data: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
1088
|
+
update(table: string, id: string, data: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
1089
|
+
delete(table: string, id: string): Promise<void>;
|
|
1090
|
+
findById(table: string, id: string): Promise<Record<string, unknown> | null>;
|
|
1091
|
+
findMany(table: string, query?: Record<string, unknown>): Promise<Record<string, unknown>[]>;
|
|
1092
|
+
}
|
|
1093
|
+
/** Logger interface injected into endpoint context. */
|
|
1094
|
+
interface Logger {
|
|
1095
|
+
info(message: string, ...args: unknown[]): void;
|
|
1096
|
+
warn(message: string, ...args: unknown[]): void;
|
|
1097
|
+
error(message: string, ...args: unknown[]): void;
|
|
1098
|
+
debug(message: string, ...args: unknown[]): void;
|
|
1099
|
+
}
|
|
1100
|
+
/**
|
|
1101
|
+
* Cache client interface injected into endpoint context.
|
|
1102
|
+
*
|
|
1103
|
+
* The cache is JSON-typed: values are serialized to/from JSON, so any JSON
|
|
1104
|
+
* value (objects, arrays, numbers, booleans, strings) round-trips. `get<T>`
|
|
1105
|
+
* therefore returns `T | null` rather than `string | null`.
|
|
1106
|
+
*/
|
|
1107
|
+
interface CacheClient {
|
|
1108
|
+
/** Read a value. Returns `null` on a cache miss. */
|
|
1109
|
+
get<T = unknown>(key: string): Promise<T | null>;
|
|
1110
|
+
/** Write a JSON-serializable value with an optional TTL (seconds). */
|
|
1111
|
+
set(key: string, value: unknown, ttl?: number): Promise<void>;
|
|
1112
|
+
/** Delete a key. */
|
|
1113
|
+
del(key: string): Promise<void>;
|
|
1114
|
+
/** Atomically increment an integer counter, returning the new value. */
|
|
1115
|
+
incr(key: string): Promise<number>;
|
|
1116
|
+
/**
|
|
1117
|
+
* Stampede-safe read-through cache fill. On a hit, returns the cached value.
|
|
1118
|
+
* On a miss, a single caller (across all pod replicas, coordinated by a
|
|
1119
|
+
* distributed lock) runs `fn`, caches the result for `ttl` seconds, and
|
|
1120
|
+
* returns it; concurrent callers wait for that result instead of also
|
|
1121
|
+
* running `fn`. If no value lands within the lock's TTL, the call rejects —
|
|
1122
|
+
* it does NOT run `fn` on timeout (that would reintroduce the stampede).
|
|
1123
|
+
*
|
|
1124
|
+
* @param ttl value TTL in seconds.
|
|
1125
|
+
*/
|
|
1126
|
+
getOrSet<T>(key: string, ttl: number, fn: () => Promise<T> | T): Promise<T>;
|
|
1127
|
+
}
|
|
1128
|
+
/** Result envelope used across the Palbase Server SDK clients. */
|
|
1129
|
+
interface PalbaseResult<T> {
|
|
1130
|
+
data: T | null;
|
|
1131
|
+
error: {
|
|
1132
|
+
message?: string;
|
|
1133
|
+
code?: string;
|
|
1134
|
+
} | null;
|
|
1135
|
+
status?: number;
|
|
1136
|
+
}
|
|
1137
|
+
/** Document snapshot returned by docs.get(). */
|
|
1138
|
+
interface PalbaseDocumentSnapshot<T = Record<string, unknown>> {
|
|
1139
|
+
id: string;
|
|
1140
|
+
exists: boolean;
|
|
1141
|
+
data(): T | undefined;
|
|
1142
|
+
ref: {
|
|
1143
|
+
path: string;
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
/** Collection query snapshot returned by collection.get(). */
|
|
1147
|
+
interface PalbaseQuerySnapshot<T = Record<string, unknown>> {
|
|
1148
|
+
docs: PalbaseDocumentSnapshot<T>[];
|
|
1149
|
+
empty: boolean;
|
|
1150
|
+
size: number;
|
|
1151
|
+
}
|
|
1152
|
+
/** Comparison operators supported by docs.where(). */
|
|
1153
|
+
type PalbaseWhereOperator = "==" | "!=" | "<" | "<=" | ">" | ">=" | "in" | "array-contains";
|
|
1154
|
+
/** Document reference exposed by ctx.docs.collection(...).doc(...). */
|
|
1155
|
+
interface PalbaseDocumentRef<T = Record<string, unknown>> {
|
|
1156
|
+
readonly path: string;
|
|
1157
|
+
set(data: T): Promise<PalbaseResult<void>>;
|
|
1158
|
+
get(): Promise<PalbaseResult<PalbaseDocumentSnapshot<T>>>;
|
|
1159
|
+
update(data: Partial<T>): Promise<PalbaseResult<void>>;
|
|
1160
|
+
delete(): Promise<PalbaseResult<void>>;
|
|
1161
|
+
}
|
|
1162
|
+
/** Collection reference exposed by ctx.docs.collection(...). */
|
|
1163
|
+
interface PalbaseCollectionRef<T = Record<string, unknown>> {
|
|
1164
|
+
readonly path: string;
|
|
1165
|
+
doc(id: string): PalbaseDocumentRef<T>;
|
|
1166
|
+
add(data: T): Promise<PalbaseResult<PalbaseDocumentRef<T>>>;
|
|
1167
|
+
where(field: string, op: PalbaseWhereOperator, value: unknown): PalbaseCollectionRef<T>;
|
|
1168
|
+
orderBy(field: string, direction?: "asc" | "desc"): PalbaseCollectionRef<T>;
|
|
1169
|
+
limit(n: number): PalbaseCollectionRef<T>;
|
|
1170
|
+
get(): Promise<PalbaseResult<PalbaseQuerySnapshot<T>>>;
|
|
1171
|
+
}
|
|
1172
|
+
/** Docs client surface available on ctx.docs. */
|
|
1173
|
+
interface PalbaseDocsClient {
|
|
1174
|
+
collection<T = Record<string, unknown>>(path: string): PalbaseCollectionRef<T>;
|
|
1175
|
+
doc<T = Record<string, unknown>>(path: string): PalbaseDocumentRef<T>;
|
|
1176
|
+
}
|
|
1177
|
+
/** Palbase module clients surfaced directly on every context.
|
|
1178
|
+
*
|
|
1179
|
+
* `ctx.docs`, `ctx.storage`, … — no `ctx.palbase.*` namespace. Structurally
|
|
1180
|
+
* typed against the runtime's `ServerClient`; the runtime injects the real
|
|
1181
|
+
* client, so mismatched names would surface as `undefined is not a function`
|
|
1182
|
+
* at call time — keep these in sync with `ServerClient`.
|
|
1183
|
+
*
|
|
1184
|
+
* Note: `db` here is NOT a module client — `ctx.db` is the project's own
|
|
1185
|
+
* Postgres (pgx, schema `env_<envId>`), declared separately on each context
|
|
1186
|
+
* as `DBClient`. The SDK's PostgREST query-builder is not exposed inside
|
|
1187
|
+
* endpoints.
|
|
1188
|
+
*/
|
|
1189
|
+
interface PalbaseModuleClients {
|
|
1190
|
+
auth: PalbaseAuthClient;
|
|
1191
|
+
storage: PalbaseStorageClient;
|
|
1192
|
+
docs: PalbaseDocsClient;
|
|
1193
|
+
realtime: PalbaseRealtimeClient;
|
|
1194
|
+
functions: PalbaseFunctionsClient;
|
|
1195
|
+
flags: PalbaseFlagsClient;
|
|
1196
|
+
notifications: PalbaseNotificationsClient;
|
|
1197
|
+
analytics: PalbaseAnalyticsClient;
|
|
1198
|
+
links: PalbaseLinksClient;
|
|
1199
|
+
cms: PalbaseCmsClient;
|
|
1200
|
+
}
|
|
1201
|
+
/** Endpoint context — injected into every handler. Module clients hang
|
|
1202
|
+
* directly off ctx (`ctx.docs`, not `ctx.palbase.docs`); `ctx.db` is the
|
|
1203
|
+
* project's own Postgres.
|
|
1204
|
+
*
|
|
1205
|
+
* When `TSchema` is a `SchemaDef`, `ctx.db` is `TypedDB<TSchema> & DBClient`:
|
|
1206
|
+
* both `ctx.db.tables.rooms.insert({...})` (typed) and
|
|
1207
|
+
* `ctx.db.insert("rooms", {...})` (legacy string API) compile.
|
|
1208
|
+
* When `TSchema` is `undefined` (no schema), `ctx.db` is plain `DBClient`.
|
|
1209
|
+
*/
|
|
1210
|
+
interface EndpointContext<TInput = unknown, TSchema extends SchemaDef | undefined = undefined, TAuthed extends boolean = false> extends PalbaseModuleClients {
|
|
1211
|
+
input: TInput;
|
|
1212
|
+
params: Record<string, string>;
|
|
1213
|
+
query: Record<string, string>;
|
|
1214
|
+
headers: Record<string, string>;
|
|
1215
|
+
/** Authenticated user. Non-null (`User`) only when the endpoint's `auth`
|
|
1216
|
+
* config forces authentication; otherwise `User | null`. The narrowing is
|
|
1217
|
+
* driven by the `TAuthed` flag, which `defineEndpoint` computes from the
|
|
1218
|
+
* `auth` literal via {@link IsAuthed}. */
|
|
1219
|
+
user: TAuthed extends true ? User : User | null;
|
|
1220
|
+
/** HTTP method of the incoming request (e.g. "GET", "POST"). */
|
|
1221
|
+
method: string;
|
|
1222
|
+
/** Matched endpoint path (e.g. "/todos/create"). */
|
|
1223
|
+
endpointPath: string;
|
|
1224
|
+
/** Uploaded file, or null when the request has no file part. */
|
|
1225
|
+
file: FileContext | null;
|
|
1226
|
+
db: TSchema extends SchemaDef ? TypedDB<TSchema> & DBClient : DBClient;
|
|
1227
|
+
env: Record<string, string>;
|
|
1228
|
+
log: Logger;
|
|
1229
|
+
cache: CacheClient;
|
|
1230
|
+
/** Queue client for dispatching background jobs. */
|
|
1231
|
+
queue: QueueClient;
|
|
1232
|
+
requestId: string;
|
|
1233
|
+
projectId: string;
|
|
1234
|
+
environmentId: string;
|
|
1235
|
+
}
|
|
1236
|
+
/** Middleware function signature — uses MiddlewareContext (no input, not yet validated). */
|
|
1237
|
+
type Middleware = (ctx: MiddlewareContext, next: () => Promise<void>) => Promise<void>;
|
|
1238
|
+
/** The shape an endpoint's `auth` config may take.
|
|
1239
|
+
*
|
|
1240
|
+
* Either a bare boolean (`true`/`false`) or an object form (`{ required?,
|
|
1241
|
+
* role? }`). The object form is `Partial<AuthConfig>` so `required` may be
|
|
1242
|
+
* omitted — which the runtime treats as `required: true` (see {@link IsAuthed}).
|
|
1243
|
+
*/
|
|
1244
|
+
type AuthSpec = boolean | Partial<AuthConfig>;
|
|
1245
|
+
/** Compute, at the type level, whether an endpoint authenticates its caller —
|
|
1246
|
+
* i.e. whether `ctx.user` should be `User` (non-null) instead of `User | null`.
|
|
1247
|
+
*
|
|
1248
|
+
* This mirrors the Go pipeline's enforcement exactly (extract_meta.js + auth.go):
|
|
1249
|
+
* a request is authenticated ⟺ `auth === true` OR (`auth` is an object whose
|
|
1250
|
+
* `required` is not explicitly `false`). So `ctx.user` stays nullable ONLY when
|
|
1251
|
+
* `auth` is absent (`undefined`), `auth === false`, or `auth: { required: false }`.
|
|
1252
|
+
*
|
|
1253
|
+
* | `TAuth` | `IsAuthed<TAuth>` |
|
|
1254
|
+
* |---------------------------------|-------------------|
|
|
1255
|
+
* | `undefined` | `false` |
|
|
1256
|
+
* | `true` | `true` |
|
|
1257
|
+
* | `false` | `false` |
|
|
1258
|
+
* | `{ required: true }` | `true` |
|
|
1259
|
+
* | `{ required: false }` | `false` |
|
|
1260
|
+
* | `{ role: 'admin' }` (no `required`) | `true` ⚠️ |
|
|
1261
|
+
*
|
|
1262
|
+
* Order matters: the `{ required: false }` branch is checked first so the
|
|
1263
|
+
* object case can't swallow it; `true` then `false` literals are handled
|
|
1264
|
+
* explicitly before the catch-all object branch (which encodes the
|
|
1265
|
+
* "required omitted ⇒ required" corner case).
|
|
1266
|
+
*/
|
|
1267
|
+
type IsAuthed<TAuth> = TAuth extends {
|
|
1268
|
+
required: false;
|
|
1269
|
+
} ? false : TAuth extends true ? true : TAuth extends false ? false : TAuth extends object ? true : false;
|
|
1270
|
+
/** Configuration for defining an endpoint.
|
|
1271
|
+
*
|
|
1272
|
+
* `TSchema` — optional `SchemaDef` that, when provided, types `ctx.db` as
|
|
1273
|
+
* `TypedDB<TSchema> & DBClient` so both the typed `.tables` API and the
|
|
1274
|
+
* legacy string API compile inside the handler.
|
|
1275
|
+
*
|
|
1276
|
+
* `TAuth` — captures the literal type of the `auth` field (via the `const`
|
|
1277
|
+
* type parameter on `defineEndpoint`) so the handler's `ctx.user` can be
|
|
1278
|
+
* narrowed to non-null `User` when auth is required. See {@link IsAuthed}.
|
|
1279
|
+
*/
|
|
1280
|
+
interface EndpointConfig<TInputSchema extends ZodSchema = ZodSchema, TOutputSchema extends ZodSchema = ZodSchema, TSchema extends SchemaDef | undefined = undefined, TAuth extends AuthSpec | undefined = undefined> {
|
|
1281
|
+
method: HttpMethod;
|
|
1282
|
+
auth?: TAuth;
|
|
1283
|
+
rateLimit?: RateLimitConfig;
|
|
1284
|
+
input?: TInputSchema;
|
|
1285
|
+
output?: TOutputSchema;
|
|
1286
|
+
schema?: TSchema;
|
|
1287
|
+
middleware?: Middleware[];
|
|
1288
|
+
handler: (ctx: EndpointContext<z.infer<TInputSchema>, TSchema, IsAuthed<TAuth>>) => Promise<z.infer<TOutputSchema>>;
|
|
1289
|
+
}
|
|
1290
|
+
/** Define a type-safe endpoint. Input schema infers the ctx.input type.
|
|
1291
|
+
* Pass a `schema` (from `defineSchema`) to get a typed `ctx.db.tables.*` API.
|
|
1292
|
+
*
|
|
1293
|
+
* The `const TAuth` type parameter captures the `auth` field as a literal
|
|
1294
|
+
* (`true` / `{ required: true }` / `{ role: 'admin' }` …) so the handler's
|
|
1295
|
+
* `ctx.user` is narrowed to `User` (non-null) whenever auth is enforced.
|
|
1296
|
+
*/
|
|
1297
|
+
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>;
|
|
1298
|
+
|
|
1299
|
+
export { type PalbaseIdentifyTraits as $, type AuthConfig as A, type PalbaseDocumentRef as B, type CacheClient as C, type DBClient as D, type EndpointContext as E, type FileContext as F, type PalbaseDocumentSnapshot as G, type HttpMethod as H, type InsertShape as I, type PalbaseEmailClient as J, type PalbaseEmailSendParams as K, type Logger as L, type Middleware as M, type PalbaseEmailSendResponse as N, type PalbaseEventNamesResult as O, type PalbaseModuleClients as P, type QueueClient as Q, type PalbaseEventsQueryInput as R, type PalbaseEventsResult as S, type PalbaseFileObject as T, type PalbaseFlag as U, type PalbaseFlagContext as V, type PalbaseFlagVariant as W, type PalbaseFlagsClient as X, type PalbaseFunctionsClient as Y, type PalbaseFunnelQueryInput as Z, type PalbaseFunnelResult as _, type EndpointConfig as a, type PalbaseInboxClient as a0, type PalbaseInboxListOptions as a1, type PalbaseInboxListResult as a2, type PalbaseInboxMessage as a3, type PalbaseInboxSendParams as a4, type PalbaseInboxSendResponse as a5, type PalbaseInitialLink as a6, type PalbaseInvokeOptions as a7, type PalbaseLink as a8, type PalbaseLinkAnalytics as a9, type PalbaseSmsClient as aA, type PalbaseSmsSendParams as aB, type PalbaseSmsSendResponse as aC, type PalbaseStorageClient as aD, type PalbaseTransformOptions as aE, type PalbaseUpdateLinkParams as aF, type PalbaseUploadOptions as aG, type PalbaseUser as aH, type PalbaseUserDetailResult as aI, type PalbaseUsersQueryInput as aJ, type PalbaseUsersResult as aK, type PalbaseVerifyRequestSignatureParams as aL, type PalbaseWhereOperator as aM, type RateLimitConfig as aN, type RowShape as aO, type TypedDB as aP, type TypedTable as aQ, type User as aR, defineEndpoint as aS, defineMiddleware as aT, makeTypedDB as aU, type PalbaseLinkDetails as aa, type PalbaseLinksClient as ab, type PalbaseListLinksOptions as ac, type PalbaseListLinksResult as ad, type PalbaseListOptions as ae, type PalbaseMatchParams as af, type PalbaseMultiChannelResponse as ag, type PalbaseNotificationsClient as ah, type PalbaseOverviewResult as ai, type PalbasePreferences as aj, type PalbasePreferencesClient as ak, type PalbasePublicUrlResponse as al, type PalbasePushClient as am, type PalbasePushSendParams as an, type PalbasePushSendResponse as ao, type PalbaseQrCodeOptions as ap, type PalbaseQuerySnapshot as aq, type PalbaseRealtimeChannel as ar, type PalbaseRealtimeClient as as, type PalbaseRealtimeMessage as at, type PalbaseRegisterDeviceParams as au, type PalbaseResult as av, type PalbaseRetentionQueryInput as aw, type PalbaseRetentionResult as ax, type PalbaseSession as ay, type PalbaseSignedUrlResponse as az, type MiddlewareContext as b, type MiddlewareHandler as c, type PalbaseAnalyticsClient as d, type PalbaseAnalyticsManagementNamespace as e, type PalbaseAnalyticsProperties as f, type PalbaseAnalyticsQueryNamespace as g, type PalbaseAttestAndroidParams as h, type PalbaseAttestAndroidResult as i, type PalbaseAttestiOSParams as j, type PalbaseAttestiOSResult as k, type PalbaseAuthClient as l, type PalbaseBindDeviceParams as m, type PalbaseBucketClient as n, type PalbaseCmsClient as o, type PalbaseCmsFindOneOptions as p, type PalbaseCmsFindOptions as q, type PalbaseCohortQueryInput as r, type PalbaseCohortResult as s, type PalbaseCollectionRef as t, type PalbaseCountQueryInput as u, type PalbaseCountResult as v, type PalbaseCreateLinkParams as w, type PalbaseDeviceInfo as x, type PalbaseDeviceTokenView as y, type PalbaseDocsClient as z };
|