@palbase/backend 24.3.0 → 25.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/bin/palbase-backend.cjs +101 -60
  2. package/dist/bin/palbase-backend.cjs.map +1 -1
  3. package/dist/bin/palbase-backend.js +17 -13
  4. package/dist/bin/palbase-backend.js.map +1 -1
  5. package/dist/{chunk-EIXCY4SS.js → chunk-43A3KGWL.js} +80 -49
  6. package/dist/chunk-43A3KGWL.js.map +1 -0
  7. package/dist/{chunk-ERDL5VAE.js → chunk-5CMLOAEF.js} +2 -2
  8. package/dist/chunk-OEQBHE2Z.js +825 -0
  9. package/dist/chunk-OEQBHE2Z.js.map +1 -0
  10. package/dist/{chunk-7Z6MGMXQ.js → chunk-XJ2RSHEU.js} +11 -5
  11. package/dist/chunk-XJ2RSHEU.js.map +1 -0
  12. package/dist/{chunk-UWSYTUGM.js → chunk-ZQRWW37O.js} +44 -1
  13. package/dist/chunk-ZQRWW37O.js.map +1 -0
  14. package/dist/db/env.cjs.map +1 -1
  15. package/dist/db/env.d.cts +29 -13
  16. package/dist/db/env.d.ts +29 -13
  17. package/dist/db/index.cjs +212 -111
  18. package/dist/db/index.cjs.map +1 -1
  19. package/dist/db/index.d.cts +1 -1
  20. package/dist/db/index.d.ts +1 -1
  21. package/dist/db/index.js +11 -1
  22. package/dist/engine/index.cjs +87 -50
  23. package/dist/engine/index.cjs.map +1 -1
  24. package/dist/engine/index.d.cts +2 -2
  25. package/dist/engine/index.d.ts +2 -2
  26. package/dist/engine/index.js +3 -3
  27. package/dist/{index-DEneI8Mn.d.ts → index-BF1f0DfA.d.ts} +5 -2
  28. package/dist/{index-C-ALG22n.d.cts → index-CoaDN9dL.d.cts} +5 -2
  29. package/dist/{index-BTMYod_l.d.ts → index-Ct1iiB4N.d.ts} +203 -61
  30. package/dist/{index-BLAbr9ZH.d.cts → index-CwaWRhyc.d.cts} +203 -61
  31. package/dist/index.cjs +550 -297
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +122 -20
  34. package/dist/index.d.ts +122 -20
  35. package/dist/index.js +164 -217
  36. package/dist/index.js.map +1 -1
  37. package/dist/openapi/index.cjs +100 -36
  38. package/dist/openapi/index.cjs.map +1 -1
  39. package/dist/openapi/index.js +59 -2
  40. package/dist/openapi/index.js.map +1 -1
  41. package/docs/README.md +64 -31
  42. package/docs/endpoints.md +25 -28
  43. package/docs/llms-full.txt +399 -153
  44. package/docs/schema.md +272 -91
  45. package/docs/services.md +39 -4
  46. package/package.json +1 -1
  47. package/template/AGENTS.md +119 -314
  48. package/template/CLAUDE.md +13 -0
  49. package/template/controllers/notes.controller.ts +6 -13
  50. package/template/db/public.ts +38 -0
  51. package/template/models/notes/create.ts +38 -0
  52. package/template/package.json +6 -3
  53. package/template/services/note.service.test.ts +45 -0
  54. package/template/services/note.service.ts +2 -2
  55. package/dist/chunk-7Z6MGMXQ.js.map +0 -1
  56. package/dist/chunk-D5CQES25.js +0 -556
  57. package/dist/chunk-D5CQES25.js.map +0 -1
  58. package/dist/chunk-EIXCY4SS.js.map +0 -1
  59. package/dist/chunk-UWSYTUGM.js.map +0 -1
  60. package/template/db/schema.ts +0 -35
  61. /package/dist/{chunk-ERDL5VAE.js.map → chunk-5CMLOAEF.js.map} +0 -0
package/dist/index.d.cts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { h as PalbaseResult, A as AuthSpec, H as HttpError } from './endpoint-BSGw1pTu.cjs';
2
2
  export { i as AuthConfig, B as BadRequest, C as CacheClient, j as ClientInfo, k as Conflict, D as DBClient, f as DBOps, E as ErrorDef, l as ErrorMap, m as ErrorThrowers, F as FileContext, n as Forbidden, o as HttpMethod, L as Logger, M as Materialized, p as Middleware, q as MiddlewareContext, r as MiddlewareHandler, N as NotFound, s as PBRequest, t as PalError, u as PalbaseAnalyticsClient, v as PalbaseAnalyticsManagementNamespace, w as PalbaseAnalyticsProperties, x as PalbaseAnalyticsQueryNamespace, y as PalbaseAttestAndroidParams, z as PalbaseAttestAndroidResult, G as PalbaseAttestiOSParams, I as PalbaseAttestiOSResult, J as PalbaseAuthClient, K as PalbaseBatchOverrideOperation, O as PalbaseBatchSetOverridesResult, Q as PalbaseBindDeviceParams, e as PalbaseBucketClient, U as PalbaseClearAllOverridesResult, V as PalbaseClearOverrideResult, W as PalbaseCohortQueryInput, X as PalbaseCohortResult, Y as PalbaseCollectionRef, Z as PalbaseCountQueryInput, _ as PalbaseCountResult, $ as PalbaseCreateLinkParams, a0 as PalbaseDeviceInfo, a1 as PalbaseDeviceTokenView, P as PalbaseDocsClient, a2 as PalbaseDocumentRef, a3 as PalbaseDocumentSnapshot, a4 as PalbaseEmailClient, a5 as PalbaseEmailSendParams, a6 as PalbaseEmailSendResponse, a7 as PalbaseEventNamesResult, a8 as PalbaseEventsQueryInput, a9 as PalbaseEventsResult, aa as PalbaseFileObject, ab as PalbaseFlag, ac as PalbaseFlagContext, ad as PalbaseFlagSource, ae as PalbaseFlagValue, af as PalbaseFlagVariant, a as PalbaseFlagsClient, ag as PalbaseFlagsServiceClient, ah as PalbaseFunctionsClient, ai as PalbaseFunnelQueryInput, aj as PalbaseFunnelResult, ak as PalbaseIdentifyTraits, al as PalbaseInboxClient, am as PalbaseInboxListOptions, an as PalbaseInboxListResult, ao as PalbaseInboxMessage, ap as PalbaseInboxSendParams, aq as PalbaseInboxSendResponse, ar as PalbaseInitialLink, as as PalbaseInvokeOptions, at as PalbaseLink, au as PalbaseLinkAnalytics, av as PalbaseLinkDetails, aw as PalbaseLinksClient, ax as PalbaseListLinksOptions, ay as PalbaseListLinksResult, az as PalbaseListOptions, aA as PalbaseMatchParams, aB as PalbaseMultiChannelResponse, b as PalbaseNotificationsClient, aC as PalbaseOverviewResult, aD as PalbasePreferences, aE as PalbasePreferencesClient, aF as PalbasePushClient, aG as PalbasePushSendParams, aH as PalbasePushSendResponse, aI as PalbaseQrCodeOptions, aJ as PalbaseQuerySnapshot, c as PalbaseRealtimeClient, aK as PalbaseRegisterDeviceParams, aL as PalbaseRetentionQueryInput, aM as PalbaseRetentionResult, aN as PalbaseSession, aO as PalbaseSetOverrideResult, aP as PalbaseSetOverridesResult, aQ as PalbaseSignedUrlResponse, aR as PalbaseSmsClient, aS as PalbaseSmsSendParams, aT as PalbaseSmsSendResponse, d as PalbaseStorageClient, aU as PalbaseTransformOptions, aV as PalbaseUpdateLinkParams, aW as PalbaseUploadOptions, aX as PalbaseUser, aY as PalbaseUserDetailResult, aZ as PalbaseUsersQueryInput, a_ as PalbaseUsersResult, a$ as PalbaseVerifyRequestSignatureParams, b0 as PalbaseWhereOperator, R as RateLimitConfig, b1 as Ref, S as SecretsService, b2 as TooManyRequests, b3 as TxColumnExpr, b4 as TxInsertShape, b5 as TxInsertValue, b6 as TxNow, T as TxPlanBody, b7 as TxPlanError, b8 as TxPlanHandle, b9 as TxPlanOpResult, ba as TxPlanRejection, g as TxPlanResponse, bb as TxRefError, bc as TxRow, bd as TxRows, be as TxSelectOptions, bf as TxSetShape, bg as TxSetValue, bh as TxTable, bi as TxWhere, bj as TxWireExpr, bk as TxWireGuard, bl as TxWireOp, bm as TxWireRef, bn as TxWireValue, bo as Unauthorized, bp as UniqueViolation, bq as UserT, br as VerifiedDevice, bs as dec, bt as defineMiddleware, bu as inc, bv as now } from './endpoint-BSGw1pTu.cjs';
3
- import { M as ModuleClients } from './index-C-ALG22n.cjs';
4
- export { C as Cache, D as Database, a as Documents, F as Flags, L as LifecycleHook, b as Log, N as Notifications, R as Realtime, c as RequestStore, d as RuntimeServices, S as Secrets, e as ShutdownRunner, f as Storage, _ as __getRuntime, g as __requestALS, h as __resetLifecycleHooks, i as __runStartHooks, j as __runWithRuntime, k as __setRuntime, o as onShutdown, l as onStart } from './index-C-ALG22n.cjs';
5
- import { S as SchemaDef } from './index-BLAbr9ZH.cjs';
6
- export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EmbeddingModelRef, f as EnvServiceDatabase, g as EnvTables, E as EnvTypedDatabase, h as EnvTypedTable, 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 RawConstraintDef, n as RowShape, o as SchemaInput, T as TableDef, p as TableInput, q as TxPlan, r as TxTables, s as TypedDB, t as TypedTable, u as TypedTx, v as bigint, w as boolean, x as defineSchema, y as enumType, z as integer, A as isPalbaseExtension, B as jsonb, D as makeTypedDB, F as numeric, G as openai, H as policy, J as raw, K as text, L as timestamp, M as uuid, N as vector } from './index-BLAbr9ZH.cjs';
3
+ import { M as ModuleClients } from './index-CoaDN9dL.cjs';
4
+ export { C as Cache, D as Database, a as Documents, F as Flags, L as LifecycleHook, b as Log, N as Notifications, R as Realtime, c as RequestStore, d as RuntimeServices, S as Secrets, e as ShutdownRunner, f as Storage, _ as __getRuntime, g as __requestALS, h as __resetLifecycleHooks, i as __runStartHooks, j as __runWithRuntime, k as __setRuntime, o as onShutdown, l as onStart } from './index-CoaDN9dL.cjs';
5
+ import { S as SchemaDef } from './index-CwaWRhyc.cjs';
6
+ export { A as AnyColumn, C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EmbeddingModelRef, f as EnvSchemas, g as EnvServiceDatabase, h as EnvTables, E as EnvTypedDatabase, i as EnvTypedTable, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, j as PalbaseExtension, k as PolicyBuilder, l as PolicyCommand, m as PolicyDef, n as PolicyMode, R as RawConstraintDef, o as RowShape, p as SchemaInput, T as TABLE_META, q as TableDef, r as TableHandle, s as TableInput, t as TxPlan, u as TxTables, v as TypedDB, w as TypedTable, x as TypedTx, y as bigint, z as boolean, B as defineSchema, D as defineTable, F as enumType, G as installationRef, H as integer, J as isPalbaseExtension, K as jsonb, L as makeTypedDB, M as numeric, N as openai, Q as ownedByUser, U as policy, V as raw, W as text, X as timestamp, Y as userRef, Z as uuid, _ as vector } from './index-CwaWRhyc.cjs';
7
7
  export { TableTypes, Tables } from './db/env.cjs';
8
8
  export { PalbaseBucketName, PalbaseFlagKey, PalbaseSecretName } from './stack.cjs';
9
9
  import { a as RouteOptions } from './registry-CgJvDYUW.cjs';
@@ -160,6 +160,14 @@ interface PolicyJSON {
160
160
  }
161
161
  /** One table. Mirrors Go's `schema.TableJSON`. */
162
162
  interface TableJSON {
163
+ /**
164
+ * The schema this table lives in. `public` unless declared otherwise.
165
+ *
166
+ * The table carries it because the diff iterates over KEYS but passes the
167
+ * VALUE around: a bare name inside a qualified key space writes the migration
168
+ * into the wrong schema, silently.
169
+ */
170
+ schema: string;
163
171
  name: string;
164
172
  columns: Record<string, ColumnJSON>;
165
173
  rls: boolean;
@@ -200,6 +208,19 @@ interface MemoryJSON {
200
208
  interface SchemaJSON {
201
209
  tables: Record<string, TableJSON>;
202
210
  extensions: string[];
211
+ /**
212
+ * Every declared schema, with its HTTP reachability.
213
+ *
214
+ * The flag has nowhere else to live: `/v1/db` must know which schemas are
215
+ * reachable, and introspection must know which schemas the project DECLARED —
216
+ * a live database also contains internal module schemas that are none of the
217
+ * diff's business.
218
+ */
219
+ schemas: SchemaMetaJSON[];
220
+ }
221
+ interface SchemaMetaJSON {
222
+ name: string;
223
+ exposed: boolean;
203
224
  }
204
225
  /** C-4 wire şekli — Go'nun SearchJSON'ıyla ALAN ADI sözleşmesi (C-5).
205
226
  * `mode`/`chunks` yalnız yeni-biçim chunk-modunda emit edilir (D-010);
@@ -233,13 +254,12 @@ interface SearchJSON {
233
254
  validity?: boolean;
234
255
  }
235
256
  /**
236
- * Serialize a `defineSchema(...)` result into the JSON the deploy applies.
257
+ * Serialize declared schemas into the JSON the deploy applies.
237
258
  *
238
- * Keyed by the SQL table name rather than by the author's object key, because
239
- * that is the name the live database answers to and the diff on the other side
240
- * compares against what it introspected.
259
+ * Takes every schema the project declares one file per schema because a
260
+ * cross-schema foreign key can only be checked when both ends are in hand.
241
261
  */
242
- declare function toSchemaJSON(schema: SchemaDef): SchemaJSON;
262
+ declare function toSchemaJSON(schemas: readonly SchemaDef[]): SchemaJSON;
243
263
 
244
264
  /**
245
265
  * channels.ts — the realtime channel authorization DSL (spec C-5).
@@ -352,14 +372,22 @@ declare function defineChannels(map: ChannelsInput): ChannelsDef;
352
372
  */
353
373
 
354
374
  /**
355
- * Generate the full `palbase-env.d.ts` text for a schema.
375
+ * Generate the full `palbase-env.d.ts` text for the project's schemas.
376
+ *
377
+ * The emitted file ends in `export {};` — same as `makeStackDts`. Without it the
378
+ * `.d.ts` is a global script, and `declare module "…"` there DECLARES an ambient
379
+ * module (shadowing the real one, so every export of `@palbase/backend/env`
380
+ * silently becomes invalid) instead of AUGMENTING it. Measured on a minimal tsc
381
+ * repro: with the line, exit 0; without it, `TS2305: Module '"…"' has no
382
+ * exported member`. The line was dropped once in a rewrite and nothing caught
383
+ * it, so `env-gen.test.ts` now gates it directly.
356
384
  *
357
385
  * @example
358
386
  * import { makeEnvDts } from "@palbase/backend";
359
387
  * import schema from "./db/schema.js";
360
- * writeFileSync("palbase-env.d.ts", makeEnvDts(schema));
388
+ * writeFileSync("palbase-env.d.ts", makeEnvDts([schema]));
361
389
  */
362
- declare function makeEnvDts(schema: SchemaDef): string;
390
+ declare function makeEnvDts(schemas: readonly SchemaDef[]): string;
363
391
 
364
392
  /**
365
393
  * stack-gen.ts — generate the `palbase-stack.d.ts` text from the names the
@@ -497,20 +525,20 @@ declare function Controller(basePath: string, options?: ControllerOptions): <T e
497
525
  declare function assertZeroArgConstructor(Ctrl: unknown, kind: string): void;
498
526
 
499
527
  /** A legacy method decorator. */
500
- type MethodDecorator = (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void;
528
+ type MethodDecorator$1 = (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void;
501
529
  /** `@Get(subpath, options?)` — declare a GET route. */
502
- declare const Get: (subpath: string, options?: RouteOptions) => MethodDecorator;
530
+ declare const Get: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
503
531
  /** `@Post(subpath, options?)` — declare a POST route. */
504
- declare const Post: (subpath: string, options?: RouteOptions) => MethodDecorator;
532
+ declare const Post: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
505
533
  /** `@Put(subpath, options?)` — declare a PUT route. */
506
- declare const Put: (subpath: string, options?: RouteOptions) => MethodDecorator;
534
+ declare const Put: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
507
535
  /** `@Patch(subpath, options?)` — declare a PATCH route. */
508
- declare const Patch: (subpath: string, options?: RouteOptions) => MethodDecorator;
536
+ declare const Patch: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
509
537
  /** `@Delete(subpath, options?)` — declare a DELETE route. */
510
- declare const Delete: (subpath: string, options?: RouteOptions) => MethodDecorator;
538
+ declare const Delete: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
511
539
  /** `@Query(subpath, options?)` — declare an HTTP QUERY route (RFC 10008):
512
540
  * safe + idempotent like GET, body-carrying like POST. Input rides `@Body`. */
513
- declare const Query: (subpath: string, options?: RouteOptions) => MethodDecorator;
541
+ declare const Query: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
514
542
 
515
543
  /**
516
544
  * The payloads a hook handler receives, and nothing else.
@@ -649,6 +677,80 @@ declare function Hook(event: string): (target: object, fnName: string | symbol)
649
677
  * here supplies them, so the field would be `undefined` on every event. */
650
678
  declare function getHookConfig(ctor: object): ResolvedHookClass;
651
679
 
680
+ interface RoomOptions {
681
+ /**
682
+ * The events this room sends to its clients, by name.
683
+ *
684
+ * Declared rather than inferred, because a room emits from anywhere in the
685
+ * class — there is no return type to read. The map is the room's public
686
+ * surface: it becomes a Swift enum and a TypeScript union in the generated
687
+ * clients, so a device gets `case .tick(n:)` instead of an opaque bag.
688
+ *
689
+ * Per-event rather than one blob because realtime is event-ADDRESSED all the
690
+ * way down (`Realtime.broadcast(channel, EVENT, payload)`).
691
+ */
692
+ events: Record<string, ZodTypeAny>;
693
+ /**
694
+ * How long a room is held after its last sign of life, in milliseconds.
695
+ *
696
+ * Default 60_000, and the floor is not a matter of taste: the decision must
697
+ * survive the SLOWEST client's heartbeat gap twice over, and the web SDK
698
+ * beats every 25 s (palbe/src/realtime/connection.ts:133) against iOS's 2 s
699
+ * (RealtimeConnection.swift:162). A shorter default would declare healthy web
700
+ * clients dead between two beats.
701
+ *
702
+ * Raise it for an upstream that is expensive to restart; lower it (never
703
+ * below ~50 s while web beats at 25 s) for one that is cheap.
704
+ */
705
+ graceMs?: number;
706
+ }
707
+ /**
708
+ * Declare a class as a room.
709
+ *
710
+ * ```ts
711
+ * @Room("chat:{roomId}", { events: { message: Message } })
712
+ * class ChatRoom {
713
+ * @OnAuthorize() can({ user, params }) { … }
714
+ * @OnFirst() open(ctx) { … } // the room filled
715
+ * @OnEmpty() close(ctx) { … } // nobody is watching any more
716
+ * @OnMessage("say", Say) say(ctx) { … }
717
+ * }
718
+ * ```
719
+ *
720
+ * The pattern is the topic: `chat:{roomId}` addresses `chat:42`. A room is
721
+ * marked by the PRESENCE of this config — never by a name, a base class or a
722
+ * naming convention.
723
+ */
724
+ declare function Room(pattern: string, options: RoomOptions): <T extends abstract new (...args: never[]) => object>(ctor: T) => T;
725
+ /** Who may enter. Return a grant to admit, `null` to refuse. */
726
+ declare const OnAuthorize: () => MethodDecorator;
727
+ /**
728
+ * The room is occupied and nobody owns it — start whatever the room needs.
729
+ *
730
+ * Deliberately a CONDITION rather than a 0→1 transition, and the difference is
731
+ * load-bearing: a runtime restart, a deploy pointer swap (the previous release
732
+ * is never torn down) and an owner that died all leave a full room with nobody
733
+ * holding it. A transition would fire once and never again; a condition
734
+ * recovers every time.
735
+ *
736
+ * Exactly one runtime in the cluster enters this hook for a given room, so
737
+ * three devices never open three upstreams.
738
+ */
739
+ declare const OnFirst: () => MethodDecorator;
740
+ /** A device arrived. Anything emitted here reaches ONLY that device. */
741
+ declare const OnJoin: () => MethodDecorator;
742
+ /** A device left. */
743
+ declare const OnLeave: () => MethodDecorator;
744
+ /** Nobody is watching any more — stop whatever `@OnFirst` started. */
745
+ declare const OnEmpty: () => MethodDecorator;
746
+ /**
747
+ * A message from a client, validated against `schema` before the method runs.
748
+ *
749
+ * A payload that fails the schema never reaches the method: the client is told
750
+ * why, and the room's code only ever sees the shape it declared.
751
+ */
752
+ declare function OnMessage(name: string, schema: ZodTypeAny): MethodDecorator;
753
+
652
754
  /** A legacy parameter decorator. */
653
755
  type ParameterDecorator = (target: object, propertyKey: string | symbol, parameterIndex: number) => void;
654
756
  /** `@Body(schema)` — inject the request body, validated against `schema`. The
@@ -817,4 +919,4 @@ interface ResolvedJob {
817
919
  declare function Job(options: JobOptions): <T extends abstract new (...args: never[]) => object>(ctor: T) => T;
818
920
  declare function getJobConfig(ctor: object): ResolvedJob;
819
921
 
820
- export { type AuthHookEvent, Body, type ChannelAuthorizeCtx, type ChannelEntry, type ChannelGrant, type ChannelsDef, type ChannelsInput, Client, type ColumnJSON, Controller, type ControllerOptions, type DefinedError, type DefinedErrorWithData, Delete, Deny, type DocumentHookEvent, type FileDeletedEvent, type FileUploadedEvent, Get, Headers, Hook, type HookFn, type HookMeta, HttpError, Job, type JobMeta, type JobOptions, type ModuleClientsConfig, type ModuleTransport, On, OptionalUser, PalbaseModuleError, PalbaseResult, Param, Patch, type PolicyJSON, Post, Put, Query, QueryParams, type RegisteredError, Req, RequestId, type RequestOptions, type ResolvedHookClass, type ResolvedJob, type ResolvedWebhook, RouteOptions, SchemaDef, type SchemaJSON, type SignatureSpec, type StackNames, type TableJSON, TraceId, type TransportConfig, User, Webhook, type WebhookEventHandler, type WebhookMeta, type WebhookOptions, type WebhookProvider, type WebhookRequest, __resetDefaultAuth, __resetRegisteredControllers, assertZeroArgConstructor, buildModuleClients, defineChannels, defineDefaultAuth, defineError, getErrorRegistry, getHookConfig, getJobConfig, getRegisteredControllers, getWebhookConfig, makeEnvDts, makeHttpClient, makeStackDts, ownerOnly, publicChannel, resolveEffectiveAuth, toSchemaJSON };
922
+ export { type AuthHookEvent, Body, type ChannelAuthorizeCtx, type ChannelEntry, type ChannelGrant, type ChannelsDef, type ChannelsInput, Client, type ColumnJSON, Controller, type ControllerOptions, type DefinedError, type DefinedErrorWithData, Delete, Deny, type DocumentHookEvent, type FileDeletedEvent, type FileUploadedEvent, Get, Headers, Hook, type HookFn, type HookMeta, HttpError, Job, type JobMeta, type JobOptions, type ModuleClientsConfig, type ModuleTransport, On, OnAuthorize, OnEmpty, OnFirst, OnJoin, OnLeave, OnMessage, OptionalUser, PalbaseModuleError, PalbaseResult, Param, Patch, type PolicyJSON, Post, Put, Query, QueryParams, type RegisteredError, Req, RequestId, type RequestOptions, type ResolvedHookClass, type ResolvedJob, type ResolvedWebhook, Room, type RoomOptions, RouteOptions, SchemaDef, type SchemaJSON, type SignatureSpec, type StackNames, type TableJSON, TraceId, type TransportConfig, User, Webhook, type WebhookEventHandler, type WebhookMeta, type WebhookOptions, type WebhookProvider, type WebhookRequest, __resetDefaultAuth, __resetRegisteredControllers, assertZeroArgConstructor, buildModuleClients, defineChannels, defineDefaultAuth, defineError, getErrorRegistry, getHookConfig, getJobConfig, getRegisteredControllers, getWebhookConfig, makeEnvDts, makeHttpClient, makeStackDts, ownerOnly, publicChannel, resolveEffectiveAuth, toSchemaJSON };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { h as PalbaseResult, A as AuthSpec, H as HttpError } from './endpoint-DMwJjEHQ.js';
2
2
  export { i as AuthConfig, B as BadRequest, C as CacheClient, j as ClientInfo, k as Conflict, D as DBClient, f as DBOps, E as ErrorDef, l as ErrorMap, m as ErrorThrowers, F as FileContext, n as Forbidden, o as HttpMethod, L as Logger, M as Materialized, p as Middleware, q as MiddlewareContext, r as MiddlewareHandler, N as NotFound, s as PBRequest, t as PalError, u as PalbaseAnalyticsClient, v as PalbaseAnalyticsManagementNamespace, w as PalbaseAnalyticsProperties, x as PalbaseAnalyticsQueryNamespace, y as PalbaseAttestAndroidParams, z as PalbaseAttestAndroidResult, G as PalbaseAttestiOSParams, I as PalbaseAttestiOSResult, J as PalbaseAuthClient, K as PalbaseBatchOverrideOperation, O as PalbaseBatchSetOverridesResult, Q as PalbaseBindDeviceParams, e as PalbaseBucketClient, U as PalbaseClearAllOverridesResult, V as PalbaseClearOverrideResult, W as PalbaseCohortQueryInput, X as PalbaseCohortResult, Y as PalbaseCollectionRef, Z as PalbaseCountQueryInput, _ as PalbaseCountResult, $ as PalbaseCreateLinkParams, a0 as PalbaseDeviceInfo, a1 as PalbaseDeviceTokenView, P as PalbaseDocsClient, a2 as PalbaseDocumentRef, a3 as PalbaseDocumentSnapshot, a4 as PalbaseEmailClient, a5 as PalbaseEmailSendParams, a6 as PalbaseEmailSendResponse, a7 as PalbaseEventNamesResult, a8 as PalbaseEventsQueryInput, a9 as PalbaseEventsResult, aa as PalbaseFileObject, ab as PalbaseFlag, ac as PalbaseFlagContext, ad as PalbaseFlagSource, ae as PalbaseFlagValue, af as PalbaseFlagVariant, a as PalbaseFlagsClient, ag as PalbaseFlagsServiceClient, ah as PalbaseFunctionsClient, ai as PalbaseFunnelQueryInput, aj as PalbaseFunnelResult, ak as PalbaseIdentifyTraits, al as PalbaseInboxClient, am as PalbaseInboxListOptions, an as PalbaseInboxListResult, ao as PalbaseInboxMessage, ap as PalbaseInboxSendParams, aq as PalbaseInboxSendResponse, ar as PalbaseInitialLink, as as PalbaseInvokeOptions, at as PalbaseLink, au as PalbaseLinkAnalytics, av as PalbaseLinkDetails, aw as PalbaseLinksClient, ax as PalbaseListLinksOptions, ay as PalbaseListLinksResult, az as PalbaseListOptions, aA as PalbaseMatchParams, aB as PalbaseMultiChannelResponse, b as PalbaseNotificationsClient, aC as PalbaseOverviewResult, aD as PalbasePreferences, aE as PalbasePreferencesClient, aF as PalbasePushClient, aG as PalbasePushSendParams, aH as PalbasePushSendResponse, aI as PalbaseQrCodeOptions, aJ as PalbaseQuerySnapshot, c as PalbaseRealtimeClient, aK as PalbaseRegisterDeviceParams, aL as PalbaseRetentionQueryInput, aM as PalbaseRetentionResult, aN as PalbaseSession, aO as PalbaseSetOverrideResult, aP as PalbaseSetOverridesResult, aQ as PalbaseSignedUrlResponse, aR as PalbaseSmsClient, aS as PalbaseSmsSendParams, aT as PalbaseSmsSendResponse, d as PalbaseStorageClient, aU as PalbaseTransformOptions, aV as PalbaseUpdateLinkParams, aW as PalbaseUploadOptions, aX as PalbaseUser, aY as PalbaseUserDetailResult, aZ as PalbaseUsersQueryInput, a_ as PalbaseUsersResult, a$ as PalbaseVerifyRequestSignatureParams, b0 as PalbaseWhereOperator, R as RateLimitConfig, b1 as Ref, S as SecretsService, b2 as TooManyRequests, b3 as TxColumnExpr, b4 as TxInsertShape, b5 as TxInsertValue, b6 as TxNow, T as TxPlanBody, b7 as TxPlanError, b8 as TxPlanHandle, b9 as TxPlanOpResult, ba as TxPlanRejection, g as TxPlanResponse, bb as TxRefError, bc as TxRow, bd as TxRows, be as TxSelectOptions, bf as TxSetShape, bg as TxSetValue, bh as TxTable, bi as TxWhere, bj as TxWireExpr, bk as TxWireGuard, bl as TxWireOp, bm as TxWireRef, bn as TxWireValue, bo as Unauthorized, bp as UniqueViolation, bq as UserT, br as VerifiedDevice, bs as dec, bt as defineMiddleware, bu as inc, bv as now } from './endpoint-DMwJjEHQ.js';
3
- import { M as ModuleClients } from './index-DEneI8Mn.js';
4
- export { C as Cache, D as Database, a as Documents, F as Flags, L as LifecycleHook, b as Log, N as Notifications, R as Realtime, c as RequestStore, d as RuntimeServices, S as Secrets, e as ShutdownRunner, f as Storage, _ as __getRuntime, g as __requestALS, h as __resetLifecycleHooks, i as __runStartHooks, j as __runWithRuntime, k as __setRuntime, o as onShutdown, l as onStart } from './index-DEneI8Mn.js';
5
- import { S as SchemaDef } from './index-BTMYod_l.js';
6
- export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EmbeddingModelRef, f as EnvServiceDatabase, g as EnvTables, E as EnvTypedDatabase, h as EnvTypedTable, 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 RawConstraintDef, n as RowShape, o as SchemaInput, T as TableDef, p as TableInput, q as TxPlan, r as TxTables, s as TypedDB, t as TypedTable, u as TypedTx, v as bigint, w as boolean, x as defineSchema, y as enumType, z as integer, A as isPalbaseExtension, B as jsonb, D as makeTypedDB, F as numeric, G as openai, H as policy, J as raw, K as text, L as timestamp, M as uuid, N as vector } from './index-BTMYod_l.js';
3
+ import { M as ModuleClients } from './index-BF1f0DfA.js';
4
+ export { C as Cache, D as Database, a as Documents, F as Flags, L as LifecycleHook, b as Log, N as Notifications, R as Realtime, c as RequestStore, d as RuntimeServices, S as Secrets, e as ShutdownRunner, f as Storage, _ as __getRuntime, g as __requestALS, h as __resetLifecycleHooks, i as __runStartHooks, j as __runWithRuntime, k as __setRuntime, o as onShutdown, l as onStart } from './index-BF1f0DfA.js';
5
+ import { S as SchemaDef } from './index-Ct1iiB4N.js';
6
+ export { A as AnyColumn, C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EmbeddingModelRef, f as EnvSchemas, g as EnvServiceDatabase, h as EnvTables, E as EnvTypedDatabase, i as EnvTypedTable, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, j as PalbaseExtension, k as PolicyBuilder, l as PolicyCommand, m as PolicyDef, n as PolicyMode, R as RawConstraintDef, o as RowShape, p as SchemaInput, T as TABLE_META, q as TableDef, r as TableHandle, s as TableInput, t as TxPlan, u as TxTables, v as TypedDB, w as TypedTable, x as TypedTx, y as bigint, z as boolean, B as defineSchema, D as defineTable, F as enumType, G as installationRef, H as integer, J as isPalbaseExtension, K as jsonb, L as makeTypedDB, M as numeric, N as openai, Q as ownedByUser, U as policy, V as raw, W as text, X as timestamp, Y as userRef, Z as uuid, _ as vector } from './index-Ct1iiB4N.js';
7
7
  export { TableTypes, Tables } from './db/env.js';
8
8
  export { PalbaseBucketName, PalbaseFlagKey, PalbaseSecretName } from './stack.js';
9
9
  import { a as RouteOptions } from './registry-B8pld3fj.js';
@@ -160,6 +160,14 @@ interface PolicyJSON {
160
160
  }
161
161
  /** One table. Mirrors Go's `schema.TableJSON`. */
162
162
  interface TableJSON {
163
+ /**
164
+ * The schema this table lives in. `public` unless declared otherwise.
165
+ *
166
+ * The table carries it because the diff iterates over KEYS but passes the
167
+ * VALUE around: a bare name inside a qualified key space writes the migration
168
+ * into the wrong schema, silently.
169
+ */
170
+ schema: string;
163
171
  name: string;
164
172
  columns: Record<string, ColumnJSON>;
165
173
  rls: boolean;
@@ -200,6 +208,19 @@ interface MemoryJSON {
200
208
  interface SchemaJSON {
201
209
  tables: Record<string, TableJSON>;
202
210
  extensions: string[];
211
+ /**
212
+ * Every declared schema, with its HTTP reachability.
213
+ *
214
+ * The flag has nowhere else to live: `/v1/db` must know which schemas are
215
+ * reachable, and introspection must know which schemas the project DECLARED —
216
+ * a live database also contains internal module schemas that are none of the
217
+ * diff's business.
218
+ */
219
+ schemas: SchemaMetaJSON[];
220
+ }
221
+ interface SchemaMetaJSON {
222
+ name: string;
223
+ exposed: boolean;
203
224
  }
204
225
  /** C-4 wire şekli — Go'nun SearchJSON'ıyla ALAN ADI sözleşmesi (C-5).
205
226
  * `mode`/`chunks` yalnız yeni-biçim chunk-modunda emit edilir (D-010);
@@ -233,13 +254,12 @@ interface SearchJSON {
233
254
  validity?: boolean;
234
255
  }
235
256
  /**
236
- * Serialize a `defineSchema(...)` result into the JSON the deploy applies.
257
+ * Serialize declared schemas into the JSON the deploy applies.
237
258
  *
238
- * Keyed by the SQL table name rather than by the author's object key, because
239
- * that is the name the live database answers to and the diff on the other side
240
- * compares against what it introspected.
259
+ * Takes every schema the project declares one file per schema because a
260
+ * cross-schema foreign key can only be checked when both ends are in hand.
241
261
  */
242
- declare function toSchemaJSON(schema: SchemaDef): SchemaJSON;
262
+ declare function toSchemaJSON(schemas: readonly SchemaDef[]): SchemaJSON;
243
263
 
244
264
  /**
245
265
  * channels.ts — the realtime channel authorization DSL (spec C-5).
@@ -352,14 +372,22 @@ declare function defineChannels(map: ChannelsInput): ChannelsDef;
352
372
  */
353
373
 
354
374
  /**
355
- * Generate the full `palbase-env.d.ts` text for a schema.
375
+ * Generate the full `palbase-env.d.ts` text for the project's schemas.
376
+ *
377
+ * The emitted file ends in `export {};` — same as `makeStackDts`. Without it the
378
+ * `.d.ts` is a global script, and `declare module "…"` there DECLARES an ambient
379
+ * module (shadowing the real one, so every export of `@palbase/backend/env`
380
+ * silently becomes invalid) instead of AUGMENTING it. Measured on a minimal tsc
381
+ * repro: with the line, exit 0; without it, `TS2305: Module '"…"' has no
382
+ * exported member`. The line was dropped once in a rewrite and nothing caught
383
+ * it, so `env-gen.test.ts` now gates it directly.
356
384
  *
357
385
  * @example
358
386
  * import { makeEnvDts } from "@palbase/backend";
359
387
  * import schema from "./db/schema.js";
360
- * writeFileSync("palbase-env.d.ts", makeEnvDts(schema));
388
+ * writeFileSync("palbase-env.d.ts", makeEnvDts([schema]));
361
389
  */
362
- declare function makeEnvDts(schema: SchemaDef): string;
390
+ declare function makeEnvDts(schemas: readonly SchemaDef[]): string;
363
391
 
364
392
  /**
365
393
  * stack-gen.ts — generate the `palbase-stack.d.ts` text from the names the
@@ -497,20 +525,20 @@ declare function Controller(basePath: string, options?: ControllerOptions): <T e
497
525
  declare function assertZeroArgConstructor(Ctrl: unknown, kind: string): void;
498
526
 
499
527
  /** A legacy method decorator. */
500
- type MethodDecorator = (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void;
528
+ type MethodDecorator$1 = (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void;
501
529
  /** `@Get(subpath, options?)` — declare a GET route. */
502
- declare const Get: (subpath: string, options?: RouteOptions) => MethodDecorator;
530
+ declare const Get: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
503
531
  /** `@Post(subpath, options?)` — declare a POST route. */
504
- declare const Post: (subpath: string, options?: RouteOptions) => MethodDecorator;
532
+ declare const Post: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
505
533
  /** `@Put(subpath, options?)` — declare a PUT route. */
506
- declare const Put: (subpath: string, options?: RouteOptions) => MethodDecorator;
534
+ declare const Put: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
507
535
  /** `@Patch(subpath, options?)` — declare a PATCH route. */
508
- declare const Patch: (subpath: string, options?: RouteOptions) => MethodDecorator;
536
+ declare const Patch: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
509
537
  /** `@Delete(subpath, options?)` — declare a DELETE route. */
510
- declare const Delete: (subpath: string, options?: RouteOptions) => MethodDecorator;
538
+ declare const Delete: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
511
539
  /** `@Query(subpath, options?)` — declare an HTTP QUERY route (RFC 10008):
512
540
  * safe + idempotent like GET, body-carrying like POST. Input rides `@Body`. */
513
- declare const Query: (subpath: string, options?: RouteOptions) => MethodDecorator;
541
+ declare const Query: (subpath: string, options?: RouteOptions) => MethodDecorator$1;
514
542
 
515
543
  /**
516
544
  * The payloads a hook handler receives, and nothing else.
@@ -649,6 +677,80 @@ declare function Hook(event: string): (target: object, fnName: string | symbol)
649
677
  * here supplies them, so the field would be `undefined` on every event. */
650
678
  declare function getHookConfig(ctor: object): ResolvedHookClass;
651
679
 
680
+ interface RoomOptions {
681
+ /**
682
+ * The events this room sends to its clients, by name.
683
+ *
684
+ * Declared rather than inferred, because a room emits from anywhere in the
685
+ * class — there is no return type to read. The map is the room's public
686
+ * surface: it becomes a Swift enum and a TypeScript union in the generated
687
+ * clients, so a device gets `case .tick(n:)` instead of an opaque bag.
688
+ *
689
+ * Per-event rather than one blob because realtime is event-ADDRESSED all the
690
+ * way down (`Realtime.broadcast(channel, EVENT, payload)`).
691
+ */
692
+ events: Record<string, ZodTypeAny>;
693
+ /**
694
+ * How long a room is held after its last sign of life, in milliseconds.
695
+ *
696
+ * Default 60_000, and the floor is not a matter of taste: the decision must
697
+ * survive the SLOWEST client's heartbeat gap twice over, and the web SDK
698
+ * beats every 25 s (palbe/src/realtime/connection.ts:133) against iOS's 2 s
699
+ * (RealtimeConnection.swift:162). A shorter default would declare healthy web
700
+ * clients dead between two beats.
701
+ *
702
+ * Raise it for an upstream that is expensive to restart; lower it (never
703
+ * below ~50 s while web beats at 25 s) for one that is cheap.
704
+ */
705
+ graceMs?: number;
706
+ }
707
+ /**
708
+ * Declare a class as a room.
709
+ *
710
+ * ```ts
711
+ * @Room("chat:{roomId}", { events: { message: Message } })
712
+ * class ChatRoom {
713
+ * @OnAuthorize() can({ user, params }) { … }
714
+ * @OnFirst() open(ctx) { … } // the room filled
715
+ * @OnEmpty() close(ctx) { … } // nobody is watching any more
716
+ * @OnMessage("say", Say) say(ctx) { … }
717
+ * }
718
+ * ```
719
+ *
720
+ * The pattern is the topic: `chat:{roomId}` addresses `chat:42`. A room is
721
+ * marked by the PRESENCE of this config — never by a name, a base class or a
722
+ * naming convention.
723
+ */
724
+ declare function Room(pattern: string, options: RoomOptions): <T extends abstract new (...args: never[]) => object>(ctor: T) => T;
725
+ /** Who may enter. Return a grant to admit, `null` to refuse. */
726
+ declare const OnAuthorize: () => MethodDecorator;
727
+ /**
728
+ * The room is occupied and nobody owns it — start whatever the room needs.
729
+ *
730
+ * Deliberately a CONDITION rather than a 0→1 transition, and the difference is
731
+ * load-bearing: a runtime restart, a deploy pointer swap (the previous release
732
+ * is never torn down) and an owner that died all leave a full room with nobody
733
+ * holding it. A transition would fire once and never again; a condition
734
+ * recovers every time.
735
+ *
736
+ * Exactly one runtime in the cluster enters this hook for a given room, so
737
+ * three devices never open three upstreams.
738
+ */
739
+ declare const OnFirst: () => MethodDecorator;
740
+ /** A device arrived. Anything emitted here reaches ONLY that device. */
741
+ declare const OnJoin: () => MethodDecorator;
742
+ /** A device left. */
743
+ declare const OnLeave: () => MethodDecorator;
744
+ /** Nobody is watching any more — stop whatever `@OnFirst` started. */
745
+ declare const OnEmpty: () => MethodDecorator;
746
+ /**
747
+ * A message from a client, validated against `schema` before the method runs.
748
+ *
749
+ * A payload that fails the schema never reaches the method: the client is told
750
+ * why, and the room's code only ever sees the shape it declared.
751
+ */
752
+ declare function OnMessage(name: string, schema: ZodTypeAny): MethodDecorator;
753
+
652
754
  /** A legacy parameter decorator. */
653
755
  type ParameterDecorator = (target: object, propertyKey: string | symbol, parameterIndex: number) => void;
654
756
  /** `@Body(schema)` — inject the request body, validated against `schema`. The
@@ -817,4 +919,4 @@ interface ResolvedJob {
817
919
  declare function Job(options: JobOptions): <T extends abstract new (...args: never[]) => object>(ctor: T) => T;
818
920
  declare function getJobConfig(ctor: object): ResolvedJob;
819
921
 
820
- export { type AuthHookEvent, Body, type ChannelAuthorizeCtx, type ChannelEntry, type ChannelGrant, type ChannelsDef, type ChannelsInput, Client, type ColumnJSON, Controller, type ControllerOptions, type DefinedError, type DefinedErrorWithData, Delete, Deny, type DocumentHookEvent, type FileDeletedEvent, type FileUploadedEvent, Get, Headers, Hook, type HookFn, type HookMeta, HttpError, Job, type JobMeta, type JobOptions, type ModuleClientsConfig, type ModuleTransport, On, OptionalUser, PalbaseModuleError, PalbaseResult, Param, Patch, type PolicyJSON, Post, Put, Query, QueryParams, type RegisteredError, Req, RequestId, type RequestOptions, type ResolvedHookClass, type ResolvedJob, type ResolvedWebhook, RouteOptions, SchemaDef, type SchemaJSON, type SignatureSpec, type StackNames, type TableJSON, TraceId, type TransportConfig, User, Webhook, type WebhookEventHandler, type WebhookMeta, type WebhookOptions, type WebhookProvider, type WebhookRequest, __resetDefaultAuth, __resetRegisteredControllers, assertZeroArgConstructor, buildModuleClients, defineChannels, defineDefaultAuth, defineError, getErrorRegistry, getHookConfig, getJobConfig, getRegisteredControllers, getWebhookConfig, makeEnvDts, makeHttpClient, makeStackDts, ownerOnly, publicChannel, resolveEffectiveAuth, toSchemaJSON };
922
+ export { type AuthHookEvent, Body, type ChannelAuthorizeCtx, type ChannelEntry, type ChannelGrant, type ChannelsDef, type ChannelsInput, Client, type ColumnJSON, Controller, type ControllerOptions, type DefinedError, type DefinedErrorWithData, Delete, Deny, type DocumentHookEvent, type FileDeletedEvent, type FileUploadedEvent, Get, Headers, Hook, type HookFn, type HookMeta, HttpError, Job, type JobMeta, type JobOptions, type ModuleClientsConfig, type ModuleTransport, On, OnAuthorize, OnEmpty, OnFirst, OnJoin, OnLeave, OnMessage, OptionalUser, PalbaseModuleError, PalbaseResult, Param, Patch, type PolicyJSON, Post, Put, Query, QueryParams, type RegisteredError, Req, RequestId, type RequestOptions, type ResolvedHookClass, type ResolvedJob, type ResolvedWebhook, Room, type RoomOptions, RouteOptions, SchemaDef, type SchemaJSON, type SignatureSpec, type StackNames, type TableJSON, TraceId, type TransportConfig, User, Webhook, type WebhookEventHandler, type WebhookMeta, type WebhookOptions, type WebhookProvider, type WebhookRequest, __resetDefaultAuth, __resetRegisteredControllers, assertZeroArgConstructor, buildModuleClients, defineChannels, defineDefaultAuth, defineError, getErrorRegistry, getHookConfig, getJobConfig, getRegisteredControllers, getWebhookConfig, makeEnvDts, makeHttpClient, makeStackDts, ownerOnly, publicChannel, resolveEffectiveAuth, toSchemaJSON };