@palbase/backend 6.0.0 → 7.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-HAVXYTDJ.js → chunk-SWT2QR5F.js} +4 -2
- package/dist/chunk-SWT2QR5F.js.map +1 -0
- package/dist/db/index.d.cts +2 -2
- package/dist/db/index.d.ts +2 -2
- package/dist/{endpoint-CfdiQbVC.d.cts → endpoint-BFgsOTiL.d.cts} +36 -40
- package/dist/{endpoint-CfdiQbVC.d.ts → endpoint-BFgsOTiL.d.ts} +36 -40
- package/dist/{index-DvhjkX6F.d.cts → index-CE31P7Dt.d.cts} +1 -1
- package/dist/{index-BVnIdFpa.d.ts → index-E7CMoir3.d.ts} +1 -1
- package/dist/index.cjs +121 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -9
- package/dist/index.d.ts +83 -9
- package/dist/index.js +122 -3
- package/dist/index.js.map +1 -1
- package/dist/test/index.cjs +4 -4
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +1 -1
- package/dist/test/index.d.ts +1 -1
- package/dist/test/index.js +4 -5
- package/dist/test/index.js.map +1 -1
- package/docs/README.md +11 -10
- package/docs/llms-full.txt +73 -19
- package/docs/routing.md +9 -5
- package/docs/services.md +53 -4
- package/package.json +5 -2
- package/dist/chunk-HAVXYTDJ.js.map +0 -1
|
@@ -110,6 +110,7 @@ var Flags = Object.assign(
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
);
|
|
113
|
+
var Realtime = makeServiceProxy("Realtime");
|
|
113
114
|
|
|
114
115
|
export {
|
|
115
116
|
__requestALS,
|
|
@@ -123,6 +124,7 @@ export {
|
|
|
123
124
|
Queue,
|
|
124
125
|
Log,
|
|
125
126
|
Notifications,
|
|
126
|
-
Flags
|
|
127
|
+
Flags,
|
|
128
|
+
Realtime
|
|
127
129
|
};
|
|
128
|
-
//# sourceMappingURL=chunk-
|
|
130
|
+
//# sourceMappingURL=chunk-SWT2QR5F.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\n * runtime.ts — request-scoped service singletons.\n *\n * The backend SDK no longer threads a `ctx` god-object through every handler.\n * Instead, controller methods import PascalCase service singletons directly:\n *\n * import { Controller, Post, Body, Database } from \"@palbase/backend\";\n *\n * \\@Controller(\"/todos\")\n * export default class TodosController {\n * \\@Post(\"\") create(\\@Body(CreateTodoBody) body: CreateTodoBody): unknown {\n * return Database.insert(\"todos\", { title: body.title });\n * }\n * }\n *\n * The singletons are thin Proxies. Every property access forwards to the live\n * client for the CURRENT request scope, resolved through {@link __getRuntime}.\n *\n * # Request-scope resolution (persistent app-server)\n *\n * The runtime is a long-running Node process that serves many concurrent\n * requests on one event loop (NOT a fresh subprocess per request). A single\n * module-global slot would let one in-flight request's services bleed into\n * another's. So the services are carried in an {@link AsyncLocalStorage} store\n * ({@link __requestALS}) that the runtime sets per request with\n * {@link __runWithRuntime}; every async continuation of that request reads its\n * own store. `__getRuntime` reads the ALS store first; the module-global slot\n * (set by {@link __setRuntime}) is only a fallback for callers that run OUTSIDE\n * an ALS scope (dev-server, unit tests, the legacy single-shot path). Because\n * each `br-<ref>` pod is single-tenant, there is no cross-tenant leakage; the\n * ALS store is what prevents cross-REQUEST leakage within the shared process.\n *\n * The seam that makes `import { Database } from \"@palbase/backend\"` resolve to\n * the runtime-injected client: `@palbase/backend` is marked esbuild-EXTERNAL\n * when the tenant bundle is built, and the package is installed globally in the\n * pod (NODE_PATH=/usr/local/lib/node_modules). So worker.js's\n * `require('@palbase/backend')` and the bundle's `import` resolve to ONE shared\n * module instance — the ALS store and `__setRuntime` slot on that instance are\n * visible to the singletons the bundle imported.\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type {\n DBClient,\n DBOps,\n TxClient,\n CacheClient,\n QueueClient,\n Logger,\n PalbaseDocsClient,\n} from \"./endpoint.js\";\nimport type {\n PalbaseStorageClient,\n PalbaseNotificationsClient,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n PalbaseFlagContext,\n PalbaseFlagVariant,\n PalbaseFlag,\n PalbaseFlagValue,\n PalbaseSetOverrideResult,\n PalbaseRealtimeClient,\n} from \"./clients.js\";\nimport type { PalbaseResult } from \"./endpoint.js\";\nimport type {\n EnvTypedDatabase,\n EnvServiceDatabase,\n EnvTypedTx,\n EnvTables,\n} from \"./db/typed-db.js\";\n\n/** The set of live clients the runtime injects per request scope.\n *\n * Realtime is BROADCAST-ONLY here (a stateless handler can push an event but\n * cannot hold a subscription socket — `subscribe()` lives on the client SDK).\n *\n * EXCLUDED on purpose: Functions, CMS, Links, Analytics, Auth. They are not\n * exposed as backend handler singletons (auth lives on the client SDK; the rest\n * are out of scope for backend endpoints). */\nexport interface RuntimeServices {\n Database: DBClient;\n Documents: PalbaseDocsClient;\n Storage: PalbaseStorageClient;\n Cache: CacheClient;\n Queue: QueueClient;\n Log: Logger;\n Notifications: PalbaseNotificationsClient;\n Flags: PalbaseFlagsClient;\n Realtime: PalbaseRealtimeClient;\n}\n\n/**\n * Per-request store. The persistent runtime runs each request inside\n * {@link __runWithRuntime}, so every async continuation of that request reads\n * its OWN `runtime` (and any other request-scoped fields the runtime adds).\n *\n * Exported with a `__` prefix so the runtime (worker.js) shares the SAME ALS\n * instance across the one module instance — two ALS instances would silently\n * not see each other's stores. NOT part of the public author-facing API.\n */\nexport const __requestALS = new AsyncLocalStorage<{ runtime: RuntimeServices }>();\n\n/** Process-global fallback slot. Used only OUTSIDE an ALS scope (dev-server,\n * unit tests, legacy single-shot worker). Inside the persistent server every\n * request runs in {@link __requestALS}, which takes precedence. */\nlet runtime: RuntimeServices | null = null;\n\n/** Install the live clients in the process-global fallback slot.\n *\n * Persistent-server requests should use {@link __runWithRuntime} instead; this\n * remains for dev-server / tests / the legacy single-shot path that run without\n * an ALS scope. NOT part of the public author-facing API. */\nexport function __setRuntime(services: RuntimeServices): void {\n runtime = services;\n}\n\n/** Run `fn` with `services` bound as the request-scoped runtime.\n *\n * The persistent worker calls this once per request so concurrent requests\n * never share a services slot. NOT part of the public author-facing API. */\nexport function __runWithRuntime<T>(services: RuntimeServices, fn: () => T): T {\n return __requestALS.run({ runtime: services }, fn);\n}\n\n/** Read the live clients, throwing if accessed outside a request scope.\n *\n * Resolves the ALS store first (persistent server, per-request), then the\n * process-global fallback (dev-server / tests). NOT part of the public\n * author-facing API — used by the runtime and the singleton Proxies. */\nexport function __getRuntime(): RuntimeServices {\n const scoped = __requestALS.getStore();\n if (scoped) return scoped.runtime;\n if (runtime === null) {\n throw new Error(\n \"Palbase services accessed outside a request scope. The Database/Documents/… \" +\n \"singletons are only available inside an endpoint handler (or after the \" +\n \"runtime has called __runWithRuntime / __setRuntime).\",\n );\n }\n return runtime;\n}\n\n/**\n * Build a Proxy singleton that forwards every property access to the live\n * client named `key` on the current runtime.\n *\n * The single `as RuntimeServices[K]` is the only contained cast in the surface:\n * `Reflect.get` on a typed object returns `unknown` for a `string | symbol`\n * key, but `prop` is constrained to keys of the client interface at the call\n * sites (the exported singletons are typed below), so the forward is sound.\n */\nfunction makeServiceProxy<K extends keyof RuntimeServices>(key: K): RuntimeServices[K] {\n const handler: ProxyHandler<RuntimeServices[K]> = {\n get(_target, prop, receiver) {\n const client = __getRuntime()[key];\n const value = Reflect.get(client as object, prop, receiver) as unknown;\n // Bind methods to their owning client so `this` stays correct when the\n // author destructures or calls `Database.query(...)`.\n return typeof value === \"function\" ? value.bind(client) : value;\n },\n };\n // The Proxy target is irrelevant (all access goes through `get`); the cast\n // names the surface type the singleton presents to authors.\n return new Proxy({} as RuntimeServices[K], handler);\n}\n\n/**\n * Build the `.tables` accessor for an op-bearing client (the top-level\n * `Database` or a transaction-scoped `tx`). Each `tables.<name>` access\n * returns a small object that forwards the five CRUD ops to the underlying\n * client using `name` as the string table identifier. The shapes are typed\n * against the generated `palbase-env.d.ts` (`EnvTables`); at runtime they are\n * plain string-keyed calls, so no schema value is needed here.\n *\n * Returns `EnvTables` — TS cannot infer the mapped type through the Proxy, so\n * a single structural narrowing names the surface (the proxy returns a\n * correctly-shaped accessor for whatever string member is read).\n */\nfunction makeTablesAccessor(ops: () => TxClient): EnvTables {\n const tablesProxy = new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n const name = prop;\n return {\n insert: (data: Record<string, unknown>) => ops().insert(name, data),\n update: (id: string, data: Record<string, unknown>) => ops().update(name, id, data),\n delete: (id: string) => ops().delete(name, id),\n findById: (id: string) => ops().findById(name, id),\n findMany: (query?: Record<string, unknown>) => ops().findMany(name, query),\n };\n },\n },\n );\n return tablesProxy as EnvTables;\n}\n\n/** The raw string-keyed `DBClient` for the current request scope. */\nconst rawDatabase: DBClient = makeServiceProxy(\"Database\");\n\n/**\n * Wrap a raw `DBClient` into the typed `{ ...ops, tables, transaction }`\n * surface. The five string ops forward straight through; `tables` is the\n * env-typed accessor; `transaction` yields typed tables. Reused for both the\n * default (RLS-enforced) `Database` and the `asService()` sibling — each is\n * fed its own raw client (the default proxy vs `rawDatabase.asService()`).\n *\n * The `satisfies` pins the op surface so a missing/renamed op is a compile\n * error; the assembled object carries `tables`/`transaction` alongside.\n */\nfunction makeTypedSurface(raw: Omit<DBClient, \"asService\">): EnvServiceDatabase {\n const ops = {\n query: (sql: string, params?: unknown[]) => raw.query(sql, params),\n insert: (table: string, data: Record<string, unknown>) => raw.insert(table, data),\n update: (table: string, id: string, data: Record<string, unknown>) =>\n raw.update(table, id, data),\n delete: (table: string, id: string) => raw.delete(table, id),\n findById: (table: string, id: string) => raw.findById(table, id),\n findMany: (table: string, query?: Record<string, unknown>) => raw.findMany(table, query),\n } satisfies DBOps;\n return Object.assign(ops, {\n tables: makeTablesAccessor(() => raw),\n transaction<T>(fn: (tx: EnvTypedTx) => Promise<T>): Promise<T> {\n return raw.transaction((rawTx) => fn({ tables: makeTablesAccessor(() => rawTx) }));\n },\n });\n}\n\n/**\n * The project's own Postgres (pgx, schema `env_<envId>`).\n *\n * Typed by default: `Database.tables.<name>.insert({...})` is typed against\n * the project's generated `palbase-env.d.ts` with NO import and NO generic.\n * The raw string ops (`query`/`insert`/`update`/`delete`/`findById`/`findMany`)\n * are also available for dynamic table names and read-only SQL.\n *\n * RLS is enforced by default (the runtime runs each op as `authenticated` with\n * the verified user's claims). To bypass RLS, call `Database.asService()` —\n * explicit and greppable — which runs as the `service_role` (BYPASSRLS).\n *\n * @example\n * import { Database } from \"@palbase/backend\";\n *\n * const todo = await Database.tables.todos.insert({ title: req.input.title });\n * todo.id; // string ✓\n * const rows = await Database.query(\"SELECT id FROM todos WHERE done = $1\", [false]);\n * const all = await Database.asService().tables.todos.findMany({}); // RLS bypass\n */\nexport const Database: EnvTypedDatabase = Object.assign(makeTypedSurface(rawDatabase), {\n /**\n * Lazily resolve the runtime's service-role sibling on each call. We do NOT\n * cache it: `rawDatabase.asService()` reads the CURRENT request scope through\n * the runtime proxy, and the per-request runtime injects a service client\n * bound to that request's identity headers — caching would leak one request's\n * sibling into another concurrent request.\n */\n asService(): EnvServiceDatabase {\n return makeTypedSurface(rawDatabase.asService());\n },\n});\n\n/** Firestore-like document client (PalDocs). */\nexport const Documents: PalbaseDocsClient = makeServiceProxy(\"Documents\");\n\n/** Object storage client (buckets, signed URLs). */\nexport const Storage: PalbaseStorageClient = makeServiceProxy(\"Storage\");\n\n/** JSON-typed cache (get/set/incr/getOrSet). */\nexport const Cache: CacheClient = makeServiceProxy(\"Cache\");\n\n/** Background job queue. */\nexport const Queue: QueueClient = makeServiceProxy(\"Queue\");\n\n/** Structured logger. */\nexport const Log: Logger = makeServiceProxy(\"Log\");\n\n/** Push / email / SMS / in-app notifications. */\nexport const Notifications: PalbaseNotificationsClient = makeServiceProxy(\"Notifications\");\n\n/**\n * The raw runtime Flags client for the current request scope. Carries the\n * default-surface reads + `setOverride` AND the runtime's `asService()` sibling\n * (the br-pod's `buildFlagsClient` returns both). The default `Flags` singleton\n * below forwards reads + `setOverride` through here; `Flags.asService()`\n * forwards to this client's own `asService()`.\n */\nconst rawFlags: PalbaseFlagsClient = makeServiceProxy(\"Flags\");\n\n/**\n * Feature flags.\n *\n * Mirrors the `Database` / `Database.asService()` model. The default surface is\n * RLS-equivalent for flags: reads resolve against the CURRENT request user and\n * `Flags.setOverride(key, value)` writes an override for that same signed-in\n * user (no userId argument, no admin power). Cross-user admin writes\n * (`setOverrideForUser`, …) live behind `Flags.asService()` — explicit and\n * greppable, just like `Database.asService()`.\n *\n * @example\n * import { Flags } from \"@palbase/backend\";\n *\n * if (await Flags.isEnabled(\"new_checkout\")) { ... } // current user\n * await Flags.setOverride(\"new_checkout\", true); // current user\n * await Flags.asService().setOverrideForUser(\"u_9\", \"x\", true); // cross-user\n */\nexport const Flags: PalbaseFlagsClient = Object.assign(\n {\n isEnabled(\n flagName: string,\n context?: PalbaseFlagContext,\n ): Promise<PalbaseResult<boolean>> {\n return rawFlags.isEnabled(flagName, context);\n },\n getVariant(\n flagName: string,\n context?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagVariant>> {\n return rawFlags.getVariant(flagName, context);\n },\n getAll(context?: PalbaseFlagContext): Promise<PalbaseResult<PalbaseFlag[]>> {\n return rawFlags.getAll(context);\n },\n setOverride(\n key: string,\n value: PalbaseFlagValue,\n ): Promise<PalbaseResult<PalbaseSetOverrideResult>> {\n return rawFlags.setOverride(key, value);\n },\n },\n {\n /**\n * Lazily resolve the runtime's cross-user sibling on each call. We do NOT\n * cache it: `rawFlags.asService()` reads the CURRENT request scope through\n * the runtime proxy, so caching would leak one request's sibling into\n * another concurrent request. Mirrors `Database.asService()`.\n */\n asService(): PalbaseFlagsServiceClient {\n return rawFlags.asService();\n },\n },\n);\n\n/**\n * The Realtime broadcast singleton for the current request scope. Backend-side\n * Realtime is BROADCAST-ONLY (a stateless handler can push but not subscribe —\n * `subscribe()` lives on the client SDK's `pb.realtime`). Fire-and-forget:\n * `broadcast` resolves once accepted (or with an `error`), never blocking the\n * handler on subscribers.\n *\n * @example\n * import { Realtime } from \"@palbase/backend\";\n *\n * await Realtime.broadcast(\"room:42\", \"message\", { text, from: user.id });\n */\nexport const Realtime: PalbaseRealtimeClient = makeServiceProxy(\"Realtime\");\n"],"mappings":"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","names":[]}
|
package/dist/db/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, E as EnvTypedDatabase, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, i as PalbaseExtension, j as PolicyBuilder, k as PolicyCommand, l as PolicyDef, m as PolicyMode, R as RowShape, S as SchemaDef, n as SchemaInput, T as TableDef, o as TableInput, p as TypedDB, q as TypedTable, r as TypedTx, s as boolean, t as defineSchema, u as enumType, v as integer, w as isPalbaseExtension, x as jsonb, y as makeTypedDB, z as policy, A as text, B as timestamp, D as uuid } from '../index-
|
|
1
|
+
export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, E as EnvTypedDatabase, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, i as PalbaseExtension, j as PolicyBuilder, k as PolicyCommand, l as PolicyDef, m as PolicyMode, R as RowShape, S as SchemaDef, n as SchemaInput, T as TableDef, o as TableInput, p as TypedDB, q as TypedTable, r as TypedTx, s as boolean, t as defineSchema, u as enumType, v as integer, w as isPalbaseExtension, x as jsonb, y as makeTypedDB, z as policy, A as text, B as timestamp, D as uuid } from '../index-CE31P7Dt.cjs';
|
|
2
2
|
import './env.cjs';
|
|
3
|
-
import '../endpoint-
|
|
3
|
+
import '../endpoint-BFgsOTiL.cjs';
|
|
4
4
|
import 'zod';
|
package/dist/db/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, E as EnvTypedDatabase, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, i as PalbaseExtension, j as PolicyBuilder, k as PolicyCommand, l as PolicyDef, m as PolicyMode, R as RowShape, S as SchemaDef, n as SchemaInput, T as TableDef, o as TableInput, p as TypedDB, q as TypedTable, r as TypedTx, s as boolean, t as defineSchema, u as enumType, v as integer, w as isPalbaseExtension, x as jsonb, y as makeTypedDB, z as policy, A as text, B as timestamp, D as uuid } from '../index-
|
|
1
|
+
export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, E as EnvTypedDatabase, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, i as PalbaseExtension, j as PolicyBuilder, k as PolicyCommand, l as PolicyDef, m as PolicyMode, R as RowShape, S as SchemaDef, n as SchemaInput, T as TableDef, o as TableInput, p as TypedDB, q as TypedTable, r as TypedTx, s as boolean, t as defineSchema, u as enumType, v as integer, w as isPalbaseExtension, x as jsonb, y as makeTypedDB, z as policy, A as text, B as timestamp, D as uuid } from '../index-E7CMoir3.js';
|
|
2
2
|
import './env.js';
|
|
3
|
-
import '../endpoint-
|
|
3
|
+
import '../endpoint-BFgsOTiL.js';
|
|
4
4
|
import 'zod';
|
|
@@ -324,12 +324,6 @@ interface PalbaseListOptions {
|
|
|
324
324
|
order: "asc" | "desc";
|
|
325
325
|
};
|
|
326
326
|
}
|
|
327
|
-
/** Realtime message shape for server-side publish. */
|
|
328
|
-
interface PalbaseRealtimeMessage {
|
|
329
|
-
type: "broadcast" | "presence" | "postgres_changes";
|
|
330
|
-
event?: string;
|
|
331
|
-
payload?: Record<string, unknown>;
|
|
332
|
-
}
|
|
333
327
|
/** Edge-function invoke options. */
|
|
334
328
|
interface PalbaseInvokeOptions {
|
|
335
329
|
body?: unknown;
|
|
@@ -964,39 +958,6 @@ interface PalbaseStorageClient {
|
|
|
964
958
|
/** Get a bucket-scoped client for file operations. */
|
|
965
959
|
bucket(name: string): PalbaseBucketClient;
|
|
966
960
|
}
|
|
967
|
-
/**
|
|
968
|
-
* Channel reference for server-side realtime publish.
|
|
969
|
-
* Omits browser subscription patterns (on(), presenceState()) and
|
|
970
|
-
* internal test helpers (_injectWebSocket). All send operations are
|
|
971
|
-
* synchronous — they throw if the channel is not subscribed.
|
|
972
|
-
*/
|
|
973
|
-
interface PalbaseRealtimeChannel {
|
|
974
|
-
/** The channel name. */
|
|
975
|
-
readonly name: string;
|
|
976
|
-
/** Send a message to all channel subscribers. */
|
|
977
|
-
send(message: PalbaseRealtimeMessage): void;
|
|
978
|
-
/** Track server presence state. */
|
|
979
|
-
track(state: Record<string, unknown>): void;
|
|
980
|
-
/** Remove server presence state. */
|
|
981
|
-
untrack(): void;
|
|
982
|
-
/** Subscribe (connect WebSocket). Returns `this` for chaining. */
|
|
983
|
-
subscribe(): PalbaseRealtimeChannel;
|
|
984
|
-
/** Unsubscribe (close WebSocket). */
|
|
985
|
-
unsubscribe(): void;
|
|
986
|
-
}
|
|
987
|
-
/**
|
|
988
|
-
* Realtime client available on `ctx.realtime`.
|
|
989
|
-
* Server-side usage: get a channel, call send() to publish broadcasts.
|
|
990
|
-
* Omits browser subscription patterns (onSnapshot, subscribe listeners).
|
|
991
|
-
*/
|
|
992
|
-
interface PalbaseRealtimeClient {
|
|
993
|
-
/** Get (or create) a named channel. */
|
|
994
|
-
channel(name: string): PalbaseRealtimeChannel;
|
|
995
|
-
/** Remove a channel and close its WebSocket. */
|
|
996
|
-
removeChannel(name: string): void;
|
|
997
|
-
/** Remove all channels and close all WebSockets. */
|
|
998
|
-
removeAllChannels(): void;
|
|
999
|
-
}
|
|
1000
961
|
/**
|
|
1001
962
|
* Functions client available on `ctx.functions`.
|
|
1002
963
|
* Invoke edge functions from a backend endpoint.
|
|
@@ -1080,6 +1041,41 @@ interface PalbaseFlagsClient {
|
|
|
1080
1041
|
*/
|
|
1081
1042
|
asService(): PalbaseFlagsServiceClient;
|
|
1082
1043
|
}
|
|
1044
|
+
/**
|
|
1045
|
+
* Realtime broadcast surface (backend handler → subscribed clients).
|
|
1046
|
+
*
|
|
1047
|
+
* Backend-side this is BROADCAST-ONLY: a handler pushes an event to a channel
|
|
1048
|
+
* and every client subscribed to that channel (via the client SDK's
|
|
1049
|
+
* `pb.realtime.channel(...).on(...)`) receives it. There is no `subscribe()` on
|
|
1050
|
+
* the backend — a stateless request handler can't hold a socket; it fires an
|
|
1051
|
+
* HTTP broadcast and returns. Delivery is fire-and-forget: `broadcast` resolves
|
|
1052
|
+
* once the broadcast is accepted (or with an `error` if it could not be sent),
|
|
1053
|
+
* but it never blocks the handler waiting on subscribers.
|
|
1054
|
+
*
|
|
1055
|
+
* Channel naming is app-defined and arbitrary (e.g. `"room:42"`, `"orders"`).
|
|
1056
|
+
* The Palbase-managed `flags:<ref>` channels are internal — author channels for
|
|
1057
|
+
* your own features.
|
|
1058
|
+
*
|
|
1059
|
+
* @example
|
|
1060
|
+
* // Notify everyone in a chat room that a message landed:
|
|
1061
|
+
* await Realtime.broadcast("room:42", "message", { text, from: user.id });
|
|
1062
|
+
*/
|
|
1063
|
+
interface PalbaseRealtimeClient {
|
|
1064
|
+
/**
|
|
1065
|
+
* Broadcast `event` with `payload` to everyone subscribed to `channel`.
|
|
1066
|
+
*
|
|
1067
|
+
* Fire-and-forget: resolves `{ data: undefined, error: null }` when the
|
|
1068
|
+
* broadcast was accepted, or `{ data: null, error }` when it could not be
|
|
1069
|
+
* sent (e.g. realtime not provisioned). A failed broadcast never throws and
|
|
1070
|
+
* never fails the handler.
|
|
1071
|
+
*
|
|
1072
|
+
* @param channel App-defined channel name (e.g. `"room:42"`). Do NOT prefix
|
|
1073
|
+
* with `"realtime:"` — that prefix is internal to the transport.
|
|
1074
|
+
* @param event Event name subscribers filter on (e.g. `"message"`).
|
|
1075
|
+
* @param payload JSON-serializable event body.
|
|
1076
|
+
*/
|
|
1077
|
+
broadcast(channel: string, event: string, payload?: Record<string, unknown>): Promise<PalbaseResult<void>>;
|
|
1078
|
+
}
|
|
1083
1079
|
/**
|
|
1084
1080
|
* Push sub-client surface (server-only: fan-out to users / topics).
|
|
1085
1081
|
*/
|
|
@@ -1573,4 +1569,4 @@ type Middleware = (ctx: MiddlewareContext, next: () => Promise<void>) => Promise
|
|
|
1573
1569
|
*/
|
|
1574
1570
|
type AuthSpec = boolean | Partial<AuthConfig>;
|
|
1575
1571
|
|
|
1576
|
-
export { type
|
|
1572
|
+
export { type PalbaseCountResult as $, type AuthSpec as A, BadRequest as B, type CacheClient as C, type DBClient as D, type ErrorDef as E, type FileContext as F, type PalbaseBatchOverrideOperation as G, HttpError as H, type PalbaseBatchSetOverridesResult as I, type PalbaseBindDeviceParams as J, type PalbaseBucketClient as K, type Logger as L, type Middleware as M, NotFound as N, type PalbaseClearAllOverridesResult as O, type PBRequest as P, type QueueClient as Q, type RateLimitConfig as R, type PalbaseClearOverrideResult as S, type PalbaseCmsClient as T, type User as U, type PalbaseCmsFindOneOptions as V, type PalbaseCmsFindOptions as W, type PalbaseCohortQueryInput as X, type PalbaseCohortResult as Y, type PalbaseCollectionRef as Z, type PalbaseCountQueryInput as _, type PalbaseModuleClients as a, type PalbaseUserDetailResult as a$, type PalbaseCreateLinkParams as a0, type PalbaseDeviceInfo as a1, type PalbaseDeviceTokenView as a2, type PalbaseDocumentRef as a3, type PalbaseDocumentSnapshot as a4, type PalbaseEmailClient as a5, type PalbaseEmailSendParams as a6, type PalbaseEmailSendResponse as a7, type PalbaseEventNamesResult as a8, type PalbaseEventsQueryInput as a9, type PalbaseListOptions as aA, type PalbaseMatchParams as aB, type PalbaseMultiChannelResponse as aC, type PalbaseOverviewResult as aD, type PalbasePreferences as aE, type PalbasePreferencesClient as aF, type PalbasePublicUrlResponse as aG, type PalbasePushClient as aH, type PalbasePushSendParams as aI, type PalbasePushSendResponse as aJ, type PalbaseQrCodeOptions as aK, type PalbaseQuerySnapshot as aL, type PalbaseRegisterDeviceParams as aM, type PalbaseResult as aN, type PalbaseRetentionQueryInput as aO, type PalbaseRetentionResult as aP, type PalbaseSession as aQ, type PalbaseSetOverrideResult as aR, type PalbaseSetOverridesResult as aS, type PalbaseSignedUrlResponse as aT, type PalbaseSmsClient as aU, type PalbaseSmsSendParams as aV, type PalbaseSmsSendResponse as aW, type PalbaseTransformOptions as aX, type PalbaseUpdateLinkParams as aY, type PalbaseUploadOptions as aZ, type PalbaseUser as a_, type PalbaseEventsResult as aa, type PalbaseFileObject as ab, type PalbaseFlag as ac, type PalbaseFlagContext as ad, type PalbaseFlagSource as ae, type PalbaseFlagValue as af, type PalbaseFlagVariant as ag, type PalbaseFlagsServiceClient as ah, type PalbaseFunctionsClient as ai, type PalbaseFunnelQueryInput as aj, type PalbaseFunnelResult as ak, type PalbaseIdentifyTraits as al, type PalbaseInboxClient as am, type PalbaseInboxListOptions as an, type PalbaseInboxListResult as ao, type PalbaseInboxMessage as ap, type PalbaseInboxSendParams as aq, type PalbaseInboxSendResponse as ar, type PalbaseInitialLink as as, type PalbaseInvokeOptions as at, type PalbaseLink as au, type PalbaseLinkAnalytics as av, type PalbaseLinkDetails as aw, type PalbaseLinksClient as ax, type PalbaseListLinksOptions as ay, type PalbaseListLinksResult as az, type PalbaseDocsClient as b, type PalbaseUsersQueryInput as b0, type PalbaseUsersResult as b1, type PalbaseVerifyRequestSignatureParams as b2, type PalbaseWhereOperator as b3, TooManyRequests as b4, type TxClient as b5, Unauthorized as b6, defineMiddleware as b7, type PalbaseFlagsClient as c, type PalbaseNotificationsClient as d, type PalbaseRealtimeClient as e, type PalbaseStorageClient as f, type AuthConfig as g, type ClientInfo as h, Conflict as i, type DBOps as j, type ErrorMap as k, type ErrorThrowers as l, Forbidden as m, type HttpMethod as n, type MiddlewareContext as o, type MiddlewareHandler as p, PalError as q, type PalbaseAnalyticsClient as r, type PalbaseAnalyticsManagementNamespace as s, type PalbaseAnalyticsProperties as t, type PalbaseAnalyticsQueryNamespace as u, type PalbaseAttestAndroidParams as v, type PalbaseAttestAndroidResult as w, type PalbaseAttestiOSParams as x, type PalbaseAttestiOSResult as y, type PalbaseAuthClient as z };
|
|
@@ -324,12 +324,6 @@ interface PalbaseListOptions {
|
|
|
324
324
|
order: "asc" | "desc";
|
|
325
325
|
};
|
|
326
326
|
}
|
|
327
|
-
/** Realtime message shape for server-side publish. */
|
|
328
|
-
interface PalbaseRealtimeMessage {
|
|
329
|
-
type: "broadcast" | "presence" | "postgres_changes";
|
|
330
|
-
event?: string;
|
|
331
|
-
payload?: Record<string, unknown>;
|
|
332
|
-
}
|
|
333
327
|
/** Edge-function invoke options. */
|
|
334
328
|
interface PalbaseInvokeOptions {
|
|
335
329
|
body?: unknown;
|
|
@@ -964,39 +958,6 @@ interface PalbaseStorageClient {
|
|
|
964
958
|
/** Get a bucket-scoped client for file operations. */
|
|
965
959
|
bucket(name: string): PalbaseBucketClient;
|
|
966
960
|
}
|
|
967
|
-
/**
|
|
968
|
-
* Channel reference for server-side realtime publish.
|
|
969
|
-
* Omits browser subscription patterns (on(), presenceState()) and
|
|
970
|
-
* internal test helpers (_injectWebSocket). All send operations are
|
|
971
|
-
* synchronous — they throw if the channel is not subscribed.
|
|
972
|
-
*/
|
|
973
|
-
interface PalbaseRealtimeChannel {
|
|
974
|
-
/** The channel name. */
|
|
975
|
-
readonly name: string;
|
|
976
|
-
/** Send a message to all channel subscribers. */
|
|
977
|
-
send(message: PalbaseRealtimeMessage): void;
|
|
978
|
-
/** Track server presence state. */
|
|
979
|
-
track(state: Record<string, unknown>): void;
|
|
980
|
-
/** Remove server presence state. */
|
|
981
|
-
untrack(): void;
|
|
982
|
-
/** Subscribe (connect WebSocket). Returns `this` for chaining. */
|
|
983
|
-
subscribe(): PalbaseRealtimeChannel;
|
|
984
|
-
/** Unsubscribe (close WebSocket). */
|
|
985
|
-
unsubscribe(): void;
|
|
986
|
-
}
|
|
987
|
-
/**
|
|
988
|
-
* Realtime client available on `ctx.realtime`.
|
|
989
|
-
* Server-side usage: get a channel, call send() to publish broadcasts.
|
|
990
|
-
* Omits browser subscription patterns (onSnapshot, subscribe listeners).
|
|
991
|
-
*/
|
|
992
|
-
interface PalbaseRealtimeClient {
|
|
993
|
-
/** Get (or create) a named channel. */
|
|
994
|
-
channel(name: string): PalbaseRealtimeChannel;
|
|
995
|
-
/** Remove a channel and close its WebSocket. */
|
|
996
|
-
removeChannel(name: string): void;
|
|
997
|
-
/** Remove all channels and close all WebSockets. */
|
|
998
|
-
removeAllChannels(): void;
|
|
999
|
-
}
|
|
1000
961
|
/**
|
|
1001
962
|
* Functions client available on `ctx.functions`.
|
|
1002
963
|
* Invoke edge functions from a backend endpoint.
|
|
@@ -1080,6 +1041,41 @@ interface PalbaseFlagsClient {
|
|
|
1080
1041
|
*/
|
|
1081
1042
|
asService(): PalbaseFlagsServiceClient;
|
|
1082
1043
|
}
|
|
1044
|
+
/**
|
|
1045
|
+
* Realtime broadcast surface (backend handler → subscribed clients).
|
|
1046
|
+
*
|
|
1047
|
+
* Backend-side this is BROADCAST-ONLY: a handler pushes an event to a channel
|
|
1048
|
+
* and every client subscribed to that channel (via the client SDK's
|
|
1049
|
+
* `pb.realtime.channel(...).on(...)`) receives it. There is no `subscribe()` on
|
|
1050
|
+
* the backend — a stateless request handler can't hold a socket; it fires an
|
|
1051
|
+
* HTTP broadcast and returns. Delivery is fire-and-forget: `broadcast` resolves
|
|
1052
|
+
* once the broadcast is accepted (or with an `error` if it could not be sent),
|
|
1053
|
+
* but it never blocks the handler waiting on subscribers.
|
|
1054
|
+
*
|
|
1055
|
+
* Channel naming is app-defined and arbitrary (e.g. `"room:42"`, `"orders"`).
|
|
1056
|
+
* The Palbase-managed `flags:<ref>` channels are internal — author channels for
|
|
1057
|
+
* your own features.
|
|
1058
|
+
*
|
|
1059
|
+
* @example
|
|
1060
|
+
* // Notify everyone in a chat room that a message landed:
|
|
1061
|
+
* await Realtime.broadcast("room:42", "message", { text, from: user.id });
|
|
1062
|
+
*/
|
|
1063
|
+
interface PalbaseRealtimeClient {
|
|
1064
|
+
/**
|
|
1065
|
+
* Broadcast `event` with `payload` to everyone subscribed to `channel`.
|
|
1066
|
+
*
|
|
1067
|
+
* Fire-and-forget: resolves `{ data: undefined, error: null }` when the
|
|
1068
|
+
* broadcast was accepted, or `{ data: null, error }` when it could not be
|
|
1069
|
+
* sent (e.g. realtime not provisioned). A failed broadcast never throws and
|
|
1070
|
+
* never fails the handler.
|
|
1071
|
+
*
|
|
1072
|
+
* @param channel App-defined channel name (e.g. `"room:42"`). Do NOT prefix
|
|
1073
|
+
* with `"realtime:"` — that prefix is internal to the transport.
|
|
1074
|
+
* @param event Event name subscribers filter on (e.g. `"message"`).
|
|
1075
|
+
* @param payload JSON-serializable event body.
|
|
1076
|
+
*/
|
|
1077
|
+
broadcast(channel: string, event: string, payload?: Record<string, unknown>): Promise<PalbaseResult<void>>;
|
|
1078
|
+
}
|
|
1083
1079
|
/**
|
|
1084
1080
|
* Push sub-client surface (server-only: fan-out to users / topics).
|
|
1085
1081
|
*/
|
|
@@ -1573,4 +1569,4 @@ type Middleware = (ctx: MiddlewareContext, next: () => Promise<void>) => Promise
|
|
|
1573
1569
|
*/
|
|
1574
1570
|
type AuthSpec = boolean | Partial<AuthConfig>;
|
|
1575
1571
|
|
|
1576
|
-
export { type
|
|
1572
|
+
export { type PalbaseCountResult as $, type AuthSpec as A, BadRequest as B, type CacheClient as C, type DBClient as D, type ErrorDef as E, type FileContext as F, type PalbaseBatchOverrideOperation as G, HttpError as H, type PalbaseBatchSetOverridesResult as I, type PalbaseBindDeviceParams as J, type PalbaseBucketClient as K, type Logger as L, type Middleware as M, NotFound as N, type PalbaseClearAllOverridesResult as O, type PBRequest as P, type QueueClient as Q, type RateLimitConfig as R, type PalbaseClearOverrideResult as S, type PalbaseCmsClient as T, type User as U, type PalbaseCmsFindOneOptions as V, type PalbaseCmsFindOptions as W, type PalbaseCohortQueryInput as X, type PalbaseCohortResult as Y, type PalbaseCollectionRef as Z, type PalbaseCountQueryInput as _, type PalbaseModuleClients as a, type PalbaseUserDetailResult as a$, type PalbaseCreateLinkParams as a0, type PalbaseDeviceInfo as a1, type PalbaseDeviceTokenView as a2, type PalbaseDocumentRef as a3, type PalbaseDocumentSnapshot as a4, type PalbaseEmailClient as a5, type PalbaseEmailSendParams as a6, type PalbaseEmailSendResponse as a7, type PalbaseEventNamesResult as a8, type PalbaseEventsQueryInput as a9, type PalbaseListOptions as aA, type PalbaseMatchParams as aB, type PalbaseMultiChannelResponse as aC, type PalbaseOverviewResult as aD, type PalbasePreferences as aE, type PalbasePreferencesClient as aF, type PalbasePublicUrlResponse as aG, type PalbasePushClient as aH, type PalbasePushSendParams as aI, type PalbasePushSendResponse as aJ, type PalbaseQrCodeOptions as aK, type PalbaseQuerySnapshot as aL, type PalbaseRegisterDeviceParams as aM, type PalbaseResult as aN, type PalbaseRetentionQueryInput as aO, type PalbaseRetentionResult as aP, type PalbaseSession as aQ, type PalbaseSetOverrideResult as aR, type PalbaseSetOverridesResult as aS, type PalbaseSignedUrlResponse as aT, type PalbaseSmsClient as aU, type PalbaseSmsSendParams as aV, type PalbaseSmsSendResponse as aW, type PalbaseTransformOptions as aX, type PalbaseUpdateLinkParams as aY, type PalbaseUploadOptions as aZ, type PalbaseUser as a_, type PalbaseEventsResult as aa, type PalbaseFileObject as ab, type PalbaseFlag as ac, type PalbaseFlagContext as ad, type PalbaseFlagSource as ae, type PalbaseFlagValue as af, type PalbaseFlagVariant as ag, type PalbaseFlagsServiceClient as ah, type PalbaseFunctionsClient as ai, type PalbaseFunnelQueryInput as aj, type PalbaseFunnelResult as ak, type PalbaseIdentifyTraits as al, type PalbaseInboxClient as am, type PalbaseInboxListOptions as an, type PalbaseInboxListResult as ao, type PalbaseInboxMessage as ap, type PalbaseInboxSendParams as aq, type PalbaseInboxSendResponse as ar, type PalbaseInitialLink as as, type PalbaseInvokeOptions as at, type PalbaseLink as au, type PalbaseLinkAnalytics as av, type PalbaseLinkDetails as aw, type PalbaseLinksClient as ax, type PalbaseListLinksOptions as ay, type PalbaseListLinksResult as az, type PalbaseDocsClient as b, type PalbaseUsersQueryInput as b0, type PalbaseUsersResult as b1, type PalbaseVerifyRequestSignatureParams as b2, type PalbaseWhereOperator as b3, TooManyRequests as b4, type TxClient as b5, Unauthorized as b6, defineMiddleware as b7, type PalbaseFlagsClient as c, type PalbaseNotificationsClient as d, type PalbaseRealtimeClient as e, type PalbaseStorageClient as f, type AuthConfig as g, type ClientInfo as h, Conflict as i, type DBOps as j, type ErrorMap as k, type ErrorThrowers as l, Forbidden as m, type HttpMethod as n, type MiddlewareContext as o, type MiddlewareHandler as p, PalError as q, type PalbaseAnalyticsClient as r, type PalbaseAnalyticsManagementNamespace as s, type PalbaseAnalyticsProperties as t, type PalbaseAnalyticsQueryNamespace as u, type PalbaseAttestAndroidParams as v, type PalbaseAttestAndroidResult as w, type PalbaseAttestiOSParams as x, type PalbaseAttestiOSResult as y, type PalbaseAuthClient as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Tables, TableTypes } from './db/env.cjs';
|
|
2
|
-
import { D as DBClient } from './endpoint-
|
|
2
|
+
import { D as DBClient } from './endpoint-BFgsOTiL.cjs';
|
|
3
3
|
|
|
4
4
|
/** On delete action for foreign key references. */
|
|
5
5
|
type OnDeleteAction = 'cascade' | 'set null' | 'restrict' | 'no action';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Tables, TableTypes } from './db/env.js';
|
|
2
|
-
import { D as DBClient } from './endpoint-
|
|
2
|
+
import { D as DBClient } from './endpoint-BFgsOTiL.js';
|
|
3
3
|
|
|
4
4
|
/** On delete action for foreign key references. */
|
|
5
5
|
type OnDeleteAction = 'cascade' | 'set null' | 'restrict' | 'no action';
|
package/dist/index.cjs
CHANGED
|
@@ -52,6 +52,7 @@ __export(src_exports, {
|
|
|
52
52
|
Query: () => Query,
|
|
53
53
|
Queue: () => Queue,
|
|
54
54
|
RESERVED_SECRET_PREFIX: () => RESERVED_SECRET_PREFIX,
|
|
55
|
+
Realtime: () => Realtime,
|
|
55
56
|
Req: () => Req,
|
|
56
57
|
RequestId: () => RequestId,
|
|
57
58
|
Resource: () => Resource,
|
|
@@ -72,6 +73,7 @@ __export(src_exports, {
|
|
|
72
73
|
boolean: () => boolean,
|
|
73
74
|
bucket: () => bucket,
|
|
74
75
|
buildProvider: () => buildProvider,
|
|
76
|
+
defineError: () => defineError,
|
|
75
77
|
defineFlags: () => defineFlags,
|
|
76
78
|
defineJob: () => defineJob,
|
|
77
79
|
defineMiddleware: () => defineMiddleware,
|
|
@@ -83,6 +85,7 @@ __export(src_exports, {
|
|
|
83
85
|
documents: () => documents,
|
|
84
86
|
enumType: () => enumType,
|
|
85
87
|
flag: () => flag,
|
|
88
|
+
getErrorRegistry: () => getErrorRegistry,
|
|
86
89
|
integer: () => integer,
|
|
87
90
|
isPalbaseExtension: () => isPalbaseExtension,
|
|
88
91
|
jsonb: () => jsonb,
|
|
@@ -90,12 +93,13 @@ __export(src_exports, {
|
|
|
90
93
|
makeTypedDB: () => makeTypedDB,
|
|
91
94
|
parseFileSizeLimit: () => parseFileSizeLimit,
|
|
92
95
|
policy: () => policy,
|
|
96
|
+
recordThrows: () => recordThrows,
|
|
93
97
|
reservedSecretKey: () => reservedSecretKey,
|
|
94
98
|
storage: () => storage,
|
|
95
99
|
text: () => text,
|
|
96
100
|
timestamp: () => timestamp,
|
|
97
101
|
uuid: () => uuid,
|
|
98
|
-
z: () =>
|
|
102
|
+
z: () => import_zod2.z
|
|
99
103
|
});
|
|
100
104
|
module.exports = __toCommonJS(src_exports);
|
|
101
105
|
|
|
@@ -211,6 +215,7 @@ var Flags = Object.assign(
|
|
|
211
215
|
}
|
|
212
216
|
}
|
|
213
217
|
);
|
|
218
|
+
var Realtime = makeServiceProxy("Realtime");
|
|
214
219
|
|
|
215
220
|
// src/db/policy.ts
|
|
216
221
|
var PolicyBuilder = class {
|
|
@@ -800,6 +805,7 @@ function Controller(basePath, options = {}) {
|
|
|
800
805
|
var ROUTES = /* @__PURE__ */ Symbol.for("palbase.backend.routes");
|
|
801
806
|
var PARAM_BUFFER = /* @__PURE__ */ Symbol.for("palbase.backend.paramBuffer");
|
|
802
807
|
var RETURN_BUFFER = /* @__PURE__ */ Symbol.for("palbase.backend.returnBuffer");
|
|
808
|
+
var THROWS_BUFFER = /* @__PURE__ */ Symbol.for("palbase.backend.throwsBuffer");
|
|
803
809
|
function carrierOf(target) {
|
|
804
810
|
const ctor = typeof target === "function" ? target : target.constructor ?? target;
|
|
805
811
|
return ctor;
|
|
@@ -826,6 +832,10 @@ function recordRoute(target, fnName, method, subpath, options) {
|
|
|
826
832
|
if (returnBuffer && returnBuffer[fnName] !== void 0) {
|
|
827
833
|
route.returnSchema = returnBuffer[fnName];
|
|
828
834
|
}
|
|
835
|
+
const throwsBuffer = carrier[THROWS_BUFFER];
|
|
836
|
+
if (throwsBuffer && throwsBuffer[fnName] !== void 0) {
|
|
837
|
+
route.throws = throwsBuffer[fnName];
|
|
838
|
+
}
|
|
829
839
|
routes.push(route);
|
|
830
840
|
}
|
|
831
841
|
function recordParam(target, fnName, meta) {
|
|
@@ -841,6 +851,20 @@ function recordParam(target, fnName, meta) {
|
|
|
841
851
|
}
|
|
842
852
|
}
|
|
843
853
|
}
|
|
854
|
+
function recordThrows(target, fnName, throws) {
|
|
855
|
+
const carrier = carrierOf(target);
|
|
856
|
+
const routes = carrier[ROUTES];
|
|
857
|
+
const route = routes?.find((r) => r.fnName === fnName);
|
|
858
|
+
if (route) {
|
|
859
|
+
route.throws = throws;
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
if (!Object.prototype.hasOwnProperty.call(carrier, THROWS_BUFFER)) {
|
|
863
|
+
carrier[THROWS_BUFFER] = {};
|
|
864
|
+
}
|
|
865
|
+
const throwsBuffer = carrier[THROWS_BUFFER];
|
|
866
|
+
if (throwsBuffer) throwsBuffer[fnName] = throws;
|
|
867
|
+
}
|
|
844
868
|
|
|
845
869
|
// src/decorators/methods.ts
|
|
846
870
|
function makeMethodDecorator(method) {
|
|
@@ -987,6 +1011,97 @@ var TooManyRequests = class extends NamedHttpError {
|
|
|
987
1011
|
}
|
|
988
1012
|
};
|
|
989
1013
|
|
|
1014
|
+
// src/error-registry.ts
|
|
1015
|
+
var import_zod_to_openapi = require("@asteasolutions/zod-to-openapi");
|
|
1016
|
+
var import_zod = require("zod");
|
|
1017
|
+
(0, import_zod_to_openapi.extendZodWithOpenApi)(import_zod.z);
|
|
1018
|
+
var ERROR_REGISTRY = /* @__PURE__ */ Symbol.for("palbase.backend.errorRegistry");
|
|
1019
|
+
function getErrorRegistry() {
|
|
1020
|
+
const g = globalThis;
|
|
1021
|
+
if (!g[ERROR_REGISTRY]) {
|
|
1022
|
+
const m = /* @__PURE__ */ new Map();
|
|
1023
|
+
for (const [code, status, className] of [
|
|
1024
|
+
["bad_request", 400, "BadRequest"],
|
|
1025
|
+
["unauthorized", 401, "Unauthorized"],
|
|
1026
|
+
["forbidden", 403, "Forbidden"],
|
|
1027
|
+
["not_found", 404, "NotFound"],
|
|
1028
|
+
["conflict", 409, "Conflict"],
|
|
1029
|
+
["too_many_requests", 429, "TooManyRequests"]
|
|
1030
|
+
]) {
|
|
1031
|
+
m.set(code, { code, status, className, builtin: true });
|
|
1032
|
+
}
|
|
1033
|
+
g[ERROR_REGISTRY] = m;
|
|
1034
|
+
}
|
|
1035
|
+
return g[ERROR_REGISTRY];
|
|
1036
|
+
}
|
|
1037
|
+
function defineError(code, status, dataSchema) {
|
|
1038
|
+
if (!Number.isInteger(status) || status < 400 || status > 599) {
|
|
1039
|
+
throw new Error(
|
|
1040
|
+
`defineError: status for "${code}" must be a 4xx/5xx integer, got ${status} \u2014 error responses must not clobber success responses in the project spec.`
|
|
1041
|
+
);
|
|
1042
|
+
}
|
|
1043
|
+
const registry2 = getErrorRegistry();
|
|
1044
|
+
const existing = registry2.get(code);
|
|
1045
|
+
const className = defaultClassName(code);
|
|
1046
|
+
const dataDigest = dataSchema ? digestOf(code, dataSchema) : void 0;
|
|
1047
|
+
if (existing) {
|
|
1048
|
+
const sameShape = existing.status === status && !existing.builtin && existing.dataDigest === dataDigest;
|
|
1049
|
+
if (!sameShape) {
|
|
1050
|
+
throw new Error(
|
|
1051
|
+
`defineError: duplicate error code "${code}" with a different shape (existing: status ${existing.status}${existing.builtin ? ", built-in" : ""}${existing.status === status && !existing.builtin ? ", different data schema" : ""}). Error codes are project-unique.`
|
|
1052
|
+
);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
const makeWithData = (schema) => class extends HttpError {
|
|
1056
|
+
static code = code;
|
|
1057
|
+
static status = status;
|
|
1058
|
+
constructor(data, message) {
|
|
1059
|
+
super(status, code, message ?? humanize(code), schema.parse(data));
|
|
1060
|
+
this.name = className;
|
|
1061
|
+
}
|
|
1062
|
+
};
|
|
1063
|
+
const makeWithoutData = () => class extends HttpError {
|
|
1064
|
+
static code = code;
|
|
1065
|
+
static status = status;
|
|
1066
|
+
constructor(message) {
|
|
1067
|
+
super(status, code, message ?? humanize(code));
|
|
1068
|
+
this.name = className;
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
const cls = dataSchema ? makeWithData(dataSchema) : makeWithoutData();
|
|
1072
|
+
Object.defineProperty(cls, "name", { value: className });
|
|
1073
|
+
registry2.set(code, {
|
|
1074
|
+
code,
|
|
1075
|
+
status,
|
|
1076
|
+
className,
|
|
1077
|
+
builtin: false,
|
|
1078
|
+
...dataSchema ? { dataSchema } : {},
|
|
1079
|
+
...dataDigest !== void 0 ? { dataDigest } : {}
|
|
1080
|
+
});
|
|
1081
|
+
return cls;
|
|
1082
|
+
}
|
|
1083
|
+
function digestOf(code, dataSchema) {
|
|
1084
|
+
const TMP_REF = "__PalbaseErrorDataDigest";
|
|
1085
|
+
const tmpRegistry = new import_zod_to_openapi.OpenAPIRegistry();
|
|
1086
|
+
tmpRegistry.register(TMP_REF, import_zod.z.object({ data: dataSchema }).openapi(TMP_REF));
|
|
1087
|
+
const generated = new import_zod_to_openapi.OpenApiGeneratorV31(tmpRegistry.definitions).generateComponents();
|
|
1088
|
+
const out = generated.components?.schemas?.[TMP_REF];
|
|
1089
|
+
const digest = JSON.stringify(out ?? null);
|
|
1090
|
+
if (digest.includes('"$ref"')) {
|
|
1091
|
+
throw new Error(
|
|
1092
|
+
`defineError: dataSchema for "${code}" carries .openapi(refId) metadata \u2014 it would emit dangling $ref pointers in the project spec. Use a plain zod schema (z.object({...})) without .openapi(...).`
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1095
|
+
return digest;
|
|
1096
|
+
}
|
|
1097
|
+
function defaultClassName(code) {
|
|
1098
|
+
return code.split("_").map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("");
|
|
1099
|
+
}
|
|
1100
|
+
function humanize(code) {
|
|
1101
|
+
const s = code.replace(/_/g, " ");
|
|
1102
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
1103
|
+
}
|
|
1104
|
+
|
|
990
1105
|
// src/worker.ts
|
|
991
1106
|
var VALID_WORKER_NAME = /^[a-zA-Z0-9_-]+$/;
|
|
992
1107
|
var WORKER_DEFAULTS = {
|
|
@@ -1285,7 +1400,7 @@ var documents = {
|
|
|
1285
1400
|
};
|
|
1286
1401
|
|
|
1287
1402
|
// src/index.ts
|
|
1288
|
-
var
|
|
1403
|
+
var import_zod2 = require("zod");
|
|
1289
1404
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1290
1405
|
0 && (module.exports = {
|
|
1291
1406
|
BadRequest,
|
|
@@ -1320,6 +1435,7 @@ var import_zod = require("zod");
|
|
|
1320
1435
|
Query,
|
|
1321
1436
|
Queue,
|
|
1322
1437
|
RESERVED_SECRET_PREFIX,
|
|
1438
|
+
Realtime,
|
|
1323
1439
|
Req,
|
|
1324
1440
|
RequestId,
|
|
1325
1441
|
Resource,
|
|
@@ -1340,6 +1456,7 @@ var import_zod = require("zod");
|
|
|
1340
1456
|
boolean,
|
|
1341
1457
|
bucket,
|
|
1342
1458
|
buildProvider,
|
|
1459
|
+
defineError,
|
|
1343
1460
|
defineFlags,
|
|
1344
1461
|
defineJob,
|
|
1345
1462
|
defineMiddleware,
|
|
@@ -1351,6 +1468,7 @@ var import_zod = require("zod");
|
|
|
1351
1468
|
documents,
|
|
1352
1469
|
enumType,
|
|
1353
1470
|
flag,
|
|
1471
|
+
getErrorRegistry,
|
|
1354
1472
|
integer,
|
|
1355
1473
|
isPalbaseExtension,
|
|
1356
1474
|
jsonb,
|
|
@@ -1358,6 +1476,7 @@ var import_zod = require("zod");
|
|
|
1358
1476
|
makeTypedDB,
|
|
1359
1477
|
parseFileSizeLimit,
|
|
1360
1478
|
policy,
|
|
1479
|
+
recordThrows,
|
|
1361
1480
|
reservedSecretKey,
|
|
1362
1481
|
storage,
|
|
1363
1482
|
text,
|