@palbase/backend 9.0.1 → 10.1.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/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { C as CacheClient, b as PalbaseDocsClient, c as PalbaseFlagsClient, L as Logger, d as PalbaseNotificationsClient, Q as QueueClient, e as PalbaseRealtimeClient, D as DBClient, f as PalbaseStorageClient, A as AuthSpec, R as RateLimitConfig, H as HttpError, U as User$1 } from './endpoint-CGI5cZMg.js';
2
- export { g as AuthConfig, B as BadRequest, h as ClientInfo, i as Conflict, j as DBOps, E as ErrorDef, k as ErrorMap, l as ErrorThrowers, F as FileContext, m as Forbidden, n as HttpMethod, M as Middleware, o as MiddlewareContext, p as MiddlewareHandler, N as NotFound, P as PBRequest, q as PalError, r as PalbaseAnalyticsClient, s as PalbaseAnalyticsManagementNamespace, t as PalbaseAnalyticsProperties, u as PalbaseAnalyticsQueryNamespace, v as PalbaseAttestAndroidParams, w as PalbaseAttestAndroidResult, x as PalbaseAttestiOSParams, y as PalbaseAttestiOSResult, z as PalbaseAuthClient, G as PalbaseBatchOverrideOperation, I as PalbaseBatchSetOverridesResult, J as PalbaseBindDeviceParams, K as PalbaseBucketClient, O as PalbaseClearAllOverridesResult, S as PalbaseClearOverrideResult, T as PalbaseCohortQueryInput, V as PalbaseCohortResult, W as PalbaseCollectionRef, X as PalbaseCountQueryInput, Y as PalbaseCountResult, Z as PalbaseCreateLinkParams, _ as PalbaseDeviceInfo, $ as PalbaseDeviceTokenView, a0 as PalbaseDocumentRef, a1 as PalbaseDocumentSnapshot, a2 as PalbaseEmailClient, a3 as PalbaseEmailSendParams, a4 as PalbaseEmailSendResponse, a5 as PalbaseEventNamesResult, a6 as PalbaseEventsQueryInput, a7 as PalbaseEventsResult, a8 as PalbaseFileObject, a9 as PalbaseFlag, aa as PalbaseFlagContext, ab as PalbaseFlagSource, ac as PalbaseFlagValue, ad as PalbaseFlagVariant, ae as PalbaseFlagsServiceClient, af as PalbaseFunctionsClient, ag as PalbaseFunnelQueryInput, ah as PalbaseFunnelResult, ai as PalbaseIdentifyTraits, aj as PalbaseInboxClient, ak as PalbaseInboxListOptions, al as PalbaseInboxListResult, am as PalbaseInboxMessage, an as PalbaseInboxSendParams, ao as PalbaseInboxSendResponse, ap as PalbaseInitialLink, aq as PalbaseInvokeOptions, ar as PalbaseLink, as as PalbaseLinkAnalytics, at as PalbaseLinkDetails, au as PalbaseLinksClient, av as PalbaseListLinksOptions, aw as PalbaseListLinksResult, ax as PalbaseListOptions, ay as PalbaseMatchParams, az as PalbaseMultiChannelResponse, aA as PalbaseOverviewResult, aB as PalbasePreferences, aC as PalbasePreferencesClient, aD as PalbasePublicUrlResponse, aE as PalbasePushClient, aF as PalbasePushSendParams, aG as PalbasePushSendResponse, aH as PalbaseQrCodeOptions, aI as PalbaseQuerySnapshot, aJ as PalbaseRegisterDeviceParams, aK as PalbaseResult, 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, 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, b1 as TooManyRequests, b2 as TxClient, b3 as Unauthorized, b4 as defineMiddleware } from './endpoint-CGI5cZMg.js';
1
+ import { C as CacheClient, b as PalbaseDocsClient, c as PalbaseFlagsClient, L as Logger, d as PalbaseNotificationsClient, Q as QueueClient, e as PalbaseRealtimeClient, D as DBClient, f as PalbaseStorageClient, A as AuthSpec, R as RateLimitConfig, H as HttpError, U as User$1 } from './endpoint-Cn3ICGTf.js';
2
+ export { g as AuthConfig, B as BadRequest, h as ClientInfo, i as Conflict, j as DBOps, E as ErrorDef, k as ErrorMap, l as ErrorThrowers, F as FileContext, m as Forbidden, n as HttpMethod, M as Middleware, o as MiddlewareContext, p as MiddlewareHandler, N as NotFound, P as PBRequest, q as PalError, r as PalbaseAnalyticsClient, s as PalbaseAnalyticsManagementNamespace, t as PalbaseAnalyticsProperties, u as PalbaseAnalyticsQueryNamespace, v as PalbaseAttestAndroidParams, w as PalbaseAttestAndroidResult, x as PalbaseAttestiOSParams, y as PalbaseAttestiOSResult, z as PalbaseAuthClient, G as PalbaseBatchOverrideOperation, I as PalbaseBatchSetOverridesResult, J as PalbaseBindDeviceParams, K as PalbaseBucketClient, O as PalbaseClearAllOverridesResult, S as PalbaseClearOverrideResult, T as PalbaseCohortQueryInput, V as PalbaseCohortResult, W as PalbaseCollectionRef, X as PalbaseCountQueryInput, Y as PalbaseCountResult, Z as PalbaseCreateLinkParams, _ as PalbaseDeviceInfo, $ as PalbaseDeviceTokenView, a0 as PalbaseDocumentRef, a1 as PalbaseDocumentSnapshot, a2 as PalbaseEmailClient, a3 as PalbaseEmailSendParams, a4 as PalbaseEmailSendResponse, a5 as PalbaseEventNamesResult, a6 as PalbaseEventsQueryInput, a7 as PalbaseEventsResult, a8 as PalbaseFileObject, a9 as PalbaseFlag, aa as PalbaseFlagContext, ab as PalbaseFlagSource, ac as PalbaseFlagValue, ad as PalbaseFlagVariant, ae as PalbaseFlagsServiceClient, af as PalbaseFunctionsClient, ag as PalbaseFunnelQueryInput, ah as PalbaseFunnelResult, ai as PalbaseIdentifyTraits, aj as PalbaseInboxClient, ak as PalbaseInboxListOptions, al as PalbaseInboxListResult, am as PalbaseInboxMessage, an as PalbaseInboxSendParams, ao as PalbaseInboxSendResponse, ap as PalbaseInitialLink, aq as PalbaseInvokeOptions, ar as PalbaseLink, as as PalbaseLinkAnalytics, at as PalbaseLinkDetails, au as PalbaseLinksClient, av as PalbaseListLinksOptions, aw as PalbaseListLinksResult, ax as PalbaseListOptions, ay as PalbaseMatchParams, az as PalbaseMultiChannelResponse, aA as PalbaseOverviewResult, aB as PalbasePreferences, aC as PalbasePreferencesClient, aD as PalbasePublicUrlResponse, aE as PalbasePushClient, aF as PalbasePushSendParams, aG as PalbasePushSendResponse, aH as PalbaseQrCodeOptions, aI as PalbaseQuerySnapshot, aJ as PalbaseRegisterDeviceParams, aK as PalbaseResult, 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, 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, b1 as TooManyRequests, b2 as TxClient, b3 as Unauthorized, b4 as VerifiedDevice, b5 as defineMiddleware } from './endpoint-Cn3ICGTf.js';
3
3
  import { AsyncLocalStorage } from 'node:async_hooks';
4
- import { E as EnvTypedDatabase, S as SchemaDef } from './index--dH5i4Nu.js';
5
- export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, f as EnvTables, g as EnvTypedTable, h as EnvTypedTx, 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 TypedDB, r as TypedTable, s as TypedTx, t as bigint, u as boolean, v as defineSchema, w as enumType, x as integer, y as isPalbaseExtension, z as jsonb, A as makeTypedDB, B as numeric, D as policy, F as raw, G as text, H as timestamp, J as uuid } from './index--dH5i4Nu.js';
6
- export { TableTypes, Tables } from './db/env.js';
4
+ import { E as EnvTypedDatabase, S as SchemaDef } from './index-V0ealeY-.js';
5
+ export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, f as EnvTables, g as EnvTypedTable, h as EnvTypedTx, 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 TypedDB, r as TypedTable, s as TypedTx, t as bigint, u as boolean, v as defineSchema, w as enumType, x as integer, y as isPalbaseExtension, z as jsonb, A as makeTypedDB, B as numeric, D as policy, F as raw, G as text, H as timestamp, J as uuid } from './index-V0ealeY-.js';
6
+ import { TableTypes, Tables } from './db/env.js';
7
7
  import { ZodTypeAny, z } from 'zod';
8
8
  export { z } from 'zod';
9
9
 
@@ -307,6 +307,47 @@ declare function bucket(opts?: BucketOptions): BucketDef;
307
307
  */
308
308
  declare function defineStorage(input: StorageInput): StorageConfig;
309
309
 
310
+ /**
311
+ * egress.ts — the tenant outbound-HTTP allowlist config-as-code DSL.
312
+ *
313
+ * `defineEgress({ hosts })` declares the external hosts a backend may fetch().
314
+ * config/egress.ts default-exports it; the deploy evals it to JSON
315
+ * (SchemaExtractor.EvaluateConfigFile → config_extract.js) and bakes the
316
+ * allowlist into the artifact manifest → the isolate loader → Tenant.egressAllow.
317
+ * The tenantFetch capability rejects any host NOT on it. NO config/egress.ts (or
318
+ * an empty list) ⇒ the backend has NO outbound network — fail-closed.
319
+ *
320
+ * @example
321
+ * // config/egress.ts
322
+ * import { defineEgress } from "@palbase/backend";
323
+ * export default defineEgress({
324
+ * hosts: ["api.open-meteo.com", "restcountries.com", "zenquotes.io"],
325
+ * });
326
+ *
327
+ * Each host is a bare hostname (no scheme/port/path/wildcard). A leading dot,
328
+ * `.example.com`, also covers subdomains (Squid dstdomain semantics). Egress is
329
+ * https-only on :443; the deploy REJECTS a malformed / IP-literal / internal host
330
+ * (fail-closed — a security allowlist is never best-effort).
331
+ *
332
+ * Emits: { __config: "egress", hosts: [...] }
333
+ */
334
+ /** The discriminant written under `__config` so the deploy eval knows the kind. */
335
+ declare const EGRESS_CONFIG_KIND: "egress";
336
+ /** The author-facing input to defineEgress. */
337
+ interface EgressInput {
338
+ hosts: string[];
339
+ }
340
+ /** The evaluated config/egress.ts default export (what the deploy reads). */
341
+ interface EgressConfig {
342
+ __config: typeof EGRESS_CONFIG_KIND;
343
+ hosts: string[];
344
+ }
345
+ /**
346
+ * Declare the backend's outbound-HTTP allowlist. Client-side this only shapes +
347
+ * validates the list; the authoritative fail-closed validation runs at deploy.
348
+ */
349
+ declare function defineEgress(input: EgressInput): EgressConfig;
350
+
310
351
  /**
311
352
  * notifications.ts — the notification-providers config-as-code DSL.
312
353
  *
@@ -554,6 +595,190 @@ declare function defineNotifications(input: NotificationsInput): NotificationsCo
554
595
  */
555
596
  declare function reservedSecretKey(provider: ProviderName, secretField: string): string;
556
597
 
598
+ /**
599
+ * test-users.ts — the test-user fixtures config-as-code DSL.
600
+ *
601
+ * `defineTestUsers({ users })` is a MODULE config-as-code surface (a sibling of
602
+ * `config/storage.ts`'s `defineStorage` and `config/flags.ts`'s `defineFlags`).
603
+ * A `config/test-users.ts` file default-exports a `defineTestUsers(...)` result;
604
+ * on deploy the runtime evaluates it to JSON and hands it to Studio, which owns
605
+ * the single apply engine (mint + seed). Studio, the CLI and the deploy all go
606
+ * through that one engine — there is no second interpreter of this JSON.
607
+ *
608
+ * TWO SHAPES, ONE DSL:
609
+ *
610
+ * - `email` GIVEN → a FIXTURE. Deploy materializes it create-if-missing, so
611
+ * the app can always be signed into with the same credentials. Deliberately
612
+ * NOT applied to a production Environment (the password lives in git).
613
+ * - `email` OMITTED → a TEMPLATE. Deploy creates nothing; Studio and the CLI
614
+ * mint as many fresh instances from it as you want (random credentials).
615
+ *
616
+ * Every minted user is an `is_test` user: excluded from MAU/billing, carrying
617
+ * `test: true` in its token, and refused by the Test Data write path if it ever
618
+ * turns out not to be one.
619
+ *
620
+ * @example
621
+ * import { defineTestUsers, testUser } from "@palbase/backend";
622
+ *
623
+ * export default defineTestUsers({
624
+ * users: {
625
+ * demo: testUser({
626
+ * email: "demo@test.local",
627
+ * password: "demo-password-1234",
628
+ * seed: {
629
+ * profiles: [{ display_name: "Demo", tier: "pro" }],
630
+ * lists: [
631
+ * { title: "Groceries", todos: [{ title: "Milk" }, { title: "Eggs", done: true }] },
632
+ * ],
633
+ * },
634
+ * }),
635
+ * heavy_user: testUser({ seed: { lists: [{ title: "L", todos: [{ title: "t" }] }] } }),
636
+ * },
637
+ * });
638
+ *
639
+ * The returned value is the EXACT JSON shape the runtime's generic config
640
+ * extractor emits and the apply engine consumes:
641
+ * { __config: "test-users", users: { <name>: { email, password, seed } } }
642
+ * `email` / `password` are the string or `null`; `seed` is `{}` when omitted.
643
+ */
644
+
645
+ /** The `__config` discriminant the eval/apply reads to confirm a config/*.ts is
646
+ * a test-users config. */
647
+ declare const TEST_USERS_CONFIG_KIND: "test-users";
648
+ /**
649
+ * A table graph in the shape the env `Tables` interface carries. The
650
+ * derivations below are parameterized over it (rather than reading the global
651
+ * `Tables` directly) so they can be type-tested against a fixture graph without
652
+ * augmenting the global interface — augmentation is program-wide and would leak
653
+ * into every other type test.
654
+ *
655
+ * The `Record<keyof G, …>` constraint is deliberate: a plain
656
+ * `Record<string, TableTypes>` would reject the `Tables` INTERFACE, which has
657
+ * no index signature.
658
+ */
659
+ type TableGraph = Record<string, TableTypes>;
660
+ /** The user-rooted tables of `G` — the ones a test user owns rows in directly. */
661
+ type OwnedTablesOf<G extends Record<keyof G, TableTypes>> = {
662
+ [T in keyof G]: G[T]["owner"] extends string ? T : never;
663
+ }[keyof G];
664
+ /**
665
+ * One authored seed row for table `T` of graph `G`.
666
+ *
667
+ * Starts from the table's INSERT shape and removes the two columns the engine
668
+ * owns: the owner column (set to the minted user) and `Via` — the FK column
669
+ * this row hangs off its parent by, when the row is nested under one. What
670
+ * remains is extended with the table's children, each an optional array of
671
+ * their own seed rows.
672
+ *
673
+ * Recursion terminates because `makeEnvDts` drops self-FKs and cycle
674
+ * back-edges when it emits `children`.
675
+ *
676
+ * Name collision note: if a table has a COLUMN whose name equals a CHILD
677
+ * table's name, the intersection makes that key unusable (its type collapses).
678
+ * That is a schema-naming problem the author sees at compile time; the apply
679
+ * engine resolves the same ambiguity live in favour of the column, because it
680
+ * introspects the real table.
681
+ */
682
+ type SeedRowFor<G extends Record<keyof G, TableTypes>, T extends keyof G, Via extends string = never> = Omit<G[T]["insert"], (G[T]["owner"] & string) | Via> & {
683
+ [C in keyof G[T]["children"]]?: Array<SeedRowFor<G, C & keyof G, G[T]["children"][C] & string>>;
684
+ };
685
+ /** The typed seed over graph `G`: top-level keys are user-rooted tables only;
686
+ * everything else is reached by nesting under its parent. */
687
+ type SeedFor<G extends Record<keyof G, TableTypes>> = {
688
+ [T in OwnedTablesOf<G>]?: Array<SeedRowFor<G, T>>;
689
+ };
690
+ /** The serialized seed — what travels as JSON and what the engine receives. */
691
+ type SeedJson = Record<string, Array<Record<string, unknown>>>;
692
+ /**
693
+ * The author-facing seed type. Falls back to the loose shape when `Tables` is
694
+ * still empty (no `db/schema.ts`, or `palbase-env.d.ts` not generated yet) so
695
+ * an unseeded project gets a usable DSL instead of an inscrutable `{}` error.
696
+ */
697
+ type Seed = [keyof Tables] extends [never] ? SeedJson : SeedFor<Tables>;
698
+ /**
699
+ * The options for one declared test user.
700
+ *
701
+ * - `email` / `password`: supply BOTH to make this a fixture with stable
702
+ * credentials (deploy materializes it, the app signs in with them), or
703
+ * NEITHER to make it a template the server generates credentials for.
704
+ * - `seed`: the user's data tree, derived from `db/schema.ts`. Top-level keys
705
+ * are user-rooted tables; FK children nest inside their parent's rows.
706
+ */
707
+ interface TestUserOptions {
708
+ email?: string;
709
+ password?: string;
710
+ /**
711
+ * A verified phone for this fixture, E.164 (`+905551112233`). Requires
712
+ * {@link TestUserOptions.otp}: nothing can receive an SMS at a fabricated
713
+ * number, so a phone fixture without a knowable code is one no test could
714
+ * ever sign in as.
715
+ */
716
+ phone?: string;
717
+ /**
718
+ * The fixed code this fixture's phone accepts. Honoured ONLY for the
719
+ * `is_test` user it belongs to — the real rail is untouched, and no
720
+ * verification is ever sent (or billed) for a fixture.
721
+ */
722
+ otp?: string;
723
+ seed?: Seed;
724
+ }
725
+ /** The compiled, serializable test-user definition — the EXACT shape emitted to
726
+ * JSON and consumed by the apply engine. */
727
+ interface TestUserDef {
728
+ /** Fixed login e-mail (fixture), or `null` when the server should generate one. */
729
+ email: string | null;
730
+ /** Fixed password (fixture), or `null` when the server should generate one. */
731
+ password: string | null;
732
+ /** Verified phone in E.164, or `null` for an e-mail-only fixture. */
733
+ phone: string | null;
734
+ /** The code that phone accepts, or `null` when there is no phone. */
735
+ otp: string | null;
736
+ /** The user's data tree; `{}` when nothing is seeded. */
737
+ seed: SeedJson;
738
+ }
739
+ /** A test-users config: the discriminant + the declared users by name. */
740
+ interface TestUsersConfig {
741
+ __config: typeof TEST_USERS_CONFIG_KIND;
742
+ users: Record<string, TestUserDef>;
743
+ }
744
+ /** The author-facing input to `defineTestUsers`. */
745
+ interface TestUsersInput {
746
+ users: Record<string, TestUserDef>;
747
+ }
748
+ /**
749
+ * Define a single test user. The NAME is supplied by the object key in
750
+ * `defineTestUsers({ users: { <name>: testUser({...}) } })`, so `testUser()`
751
+ * takes only the options.
752
+ *
753
+ * Validates eagerly (at config-author time):
754
+ * - `email` and `password` are supplied together or not at all — half a
755
+ * credential pair would silently degrade a fixture into a template.
756
+ * - `email` looks like an address; `password` is at least
757
+ * {@link MIN_PASSWORD_LENGTH} characters.
758
+ * - `seed` is structurally `{ <table>: [ {...}, ... ] }` with non-empty arrays.
759
+ *
760
+ * The user NAME is validated by `defineTestUsers`, which is where it is known.
761
+ */
762
+ declare function testUser(opts?: TestUserOptions): TestUserDef;
763
+ /**
764
+ * Define a project's test users. The user NAME comes from each object key
765
+ * (authors never repeat it). Returns the discriminated {@link TestUsersConfig}
766
+ * the runtime config extractor serializes and the apply engine consumes.
767
+ *
768
+ * Validates eagerly:
769
+ * - each name matches `^[a-zA-Z][a-zA-Z0-9_]*$` (the CLI's `--template <name>`
770
+ * and control-pg's scenario name share this vocabulary).
771
+ * - no two fixtures declare the SAME e-mail — they would race to
772
+ * create-if-missing the one account and the second would silently adopt the
773
+ * first one's data tree.
774
+ *
775
+ * @example
776
+ * export default defineTestUsers({
777
+ * users: { demo: testUser({ email: "demo@test.local", password: "demo-password-1234" }) },
778
+ * });
779
+ */
780
+ declare function defineTestUsers(input: TestUsersInput): TestUsersConfig;
781
+
557
782
  /**
558
783
  * flags.ts — the feature-flag-definitions config-as-code DSL.
559
784
  *
@@ -804,6 +1029,21 @@ interface RouteOptions {
804
1029
  * runs as the completion handler. See {@link UploadConfig} (decorators/upload.ts). */
805
1030
  uploadConfig?: UploadConfig;
806
1031
  }
1032
+ /** The kind of value a parameter decorator injects. Drives both dispatch
1033
+ * (which request slice to inject) and codegen (which OpenAPI parameter source a
1034
+ * schema-bearing kind maps to). */
1035
+ type ParamKind = "body" | "query" | "param" | "headers" | "user" | "optionalUser" | "client" | "requestId" | "traceId" | "req" | "uploadedObject";
1036
+ /** One parameter decorator's recorded metadata. `index` is the parameter
1037
+ * position esbuild/tsc preserve; `schema` is present for the schema-bearing
1038
+ * kinds (`body`/`query`/`headers`); `name` is the path-param name for `param`. */
1039
+ interface ParamMeta {
1040
+ index: number;
1041
+ kind: ParamKind;
1042
+ /** Zod schema for `body`/`query`/`headers` (validation + codegen source). */
1043
+ schema?: ZodTypeAny;
1044
+ /** Path-param name for `@Param("id")`. */
1045
+ name?: string;
1046
+ }
807
1047
  /** One inferred throw site: the error CLASS name (e.g. "TodoLocked") and its
808
1048
  * wire code (e.g. "todo_locked"). `status`, `hasData`, and the data JSON schema
809
1049
  * are NOT carried here — they resolve from the error registry by `code` at
@@ -812,12 +1052,37 @@ interface ThrowDescriptor {
812
1052
  name: string;
813
1053
  code: string;
814
1054
  }
1055
+ /** One route's recorded metadata: the verb + subpath + method name + options,
1056
+ * the ordered parameter metas, and the resolved return schema (injected by the
1057
+ * codegen step — see `returnSchema`). */
1058
+ interface RouteMeta {
1059
+ method: HttpMethodUpper;
1060
+ subpath: string;
1061
+ fnName: string;
1062
+ options: RouteOptions;
1063
+ params: ParamMeta[];
1064
+ /** Response schema for the route, if any. Derived from the method's RETURN
1065
+ * TYPE by codegen and written here via `recordReturn` (a generated top-level
1066
+ * IIFE injected per controller), not by an author-written decorator. */
1067
+ returnSchema?: ZodTypeAny;
1068
+ /** Error classes this route can throw, if inferred. Derived from the method
1069
+ * body + service call graph by the deploy stager's throw analysis and written
1070
+ * here via `recordThrows` (a generated top-level IIFE injected per controller,
1071
+ * the `recordReturn` twin), not by an author-written decorator. */
1072
+ throws?: ThrowDescriptor[];
1073
+ }
815
1074
  /** Attach the inferred throw descriptors to the route for `fnName` (called by
816
1075
  * the stager-injected IIFE that carries the throw analysis result — the
817
1076
  * `recordReturn` twin). If the route does not exist yet, the descriptors are
818
1077
  * buffered (THROWS_BUFFER) and drained into the route by `recordRoute` when the
819
1078
  * method decorator runs. */
820
1079
  declare function recordThrows(target: object, fnName: string, throws: ThrowDescriptor[]): void;
1080
+ /** Read the route metadata for a controller class (the deploy/dispatch entry
1081
+ * point). Applies any buffered return schemas + throw descriptors (for the
1082
+ * recordReturn/recordThrows-runs-before orderings) and returns a defensive copy
1083
+ * so callers cannot mutate the registry.
1084
+ */
1085
+ declare function getRoutes(ctor: object): RouteMeta[];
821
1086
 
822
1087
  /** A legacy method decorator. */
823
1088
  type MethodDecorator = (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => void;
@@ -906,13 +1171,13 @@ declare function defineError(code: string, status: number): DefinedError;
906
1171
  /** Non-service, per-invocation data for background worker handlers.
907
1172
  * Services (Database, Log, …) are imported as singletons, not passed here. */
908
1173
  interface WorkerMeta {
909
- /** Branch-scoped env vars. */
1174
+ /** Environment-scoped env vars. */
910
1175
  env: Record<string, string>;
911
1176
  /** The user that enqueued the job, if any (background jobs are usually system-initiated). */
912
1177
  user: User$1 | null;
913
1178
  /** Per-invocation id for correlation. */
914
1179
  requestId: string;
915
- projectId: string;
1180
+ /** The globally unique Environment runtime identifier. */
916
1181
  environmentId: string;
917
1182
  }
918
1183
  /** Backoff strategy for worker retries. */
@@ -961,9 +1226,9 @@ declare function defineWorker<TPayload = unknown>(config: WorkerConfig<TPayload>
961
1226
  /** Non-service, per-invocation data for job handlers.
962
1227
  * Services (Database, Log, …) are imported as singletons, not passed here. */
963
1228
  interface JobMeta {
964
- /** Branch-scoped env vars. */
1229
+ /** Environment-scoped env vars. */
965
1230
  env: Record<string, string>;
966
- projectId: string;
1231
+ /** The globally unique Environment runtime identifier. */
967
1232
  environmentId: string;
968
1233
  }
969
1234
  /** Configuration for defining a scheduled job. */
@@ -1009,11 +1274,11 @@ type WebhookProvider = "stripe" | "github" | "twilio" | "sendgrid" | "slack" | "
1009
1274
  /** Non-service, per-invocation data for webhook handlers.
1010
1275
  * Services (Database, Log, …) are imported as singletons, not passed here. */
1011
1276
  interface WebhookMeta {
1012
- /** Branch-scoped env vars. */
1277
+ /** Environment-scoped env vars. */
1013
1278
  env: Record<string, string>;
1014
1279
  /** Per-invocation id for correlation. */
1015
1280
  requestId: string;
1016
- projectId: string;
1281
+ /** The globally unique Environment runtime identifier. */
1017
1282
  environmentId: string;
1018
1283
  }
1019
1284
  /** Secret reference — resolves from environment variables at runtime. */
@@ -1241,9 +1506,9 @@ declare function __shutdownResources(): Promise<void>;
1241
1506
  /** Non-service, per-invocation data for hook handlers.
1242
1507
  * Services (Database, Log, …) are imported as singletons, not passed here. */
1243
1508
  interface HookMeta {
1244
- /** Branch-scoped env vars. */
1509
+ /** Environment-scoped env vars. */
1245
1510
  env: Record<string, string>;
1246
- projectId: string;
1511
+ /** The globally unique Environment runtime identifier. */
1247
1512
  environmentId: string;
1248
1513
  }
1249
1514
  /** Payload for auth.onUserCreated hook. */
@@ -1355,4 +1620,4 @@ declare const documents: {
1355
1620
  onDocumentDeleted(handler: HookHandler<DocumentDeletedEvent>): ResolvedHook<DocumentDeletedEvent>;
1356
1621
  };
1357
1622
 
1358
- export { type AcsOptions, type ApnsOptions, type BackoffStrategy, Body, type BucketDef, type BucketOptions, Cache, CacheClient, Client, Controller, type ControllerOptions, type CustomWebhookConfig, DBClient, Database, type DefinedError, type DefinedErrorWithData, Delete, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, type EnvSecretRef, EnvTypedDatabase, FLAGS_CONFIG_KIND, type FcmOptions, type FileDeletedEvent, type FileUploadedEvent, type FlagDef, type FlagOptions, type FlagType, type FlagValue, Flags, type FlagsConfig, type FlagsInput, Get, Headers, type HookHandler, type HookMeta, HttpError, type HttpMethodUpper, type JobConfig, type JobMeta, Log, Logger, NOTIFICATIONS_CONFIG_KIND, Notifications, type NotificationsConfig, type NotificationsInput, OptionalUser, PROVIDER_CATALOG, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseRealtimeClient, PalbaseStorageClient, Param, type PasswordResetEvent, Patch, Post, type ProviderCatalogEntry, type ProviderDef, type ProviderEventMap, type ProviderName, type ProviderOptions, type ProviderWebhookConfig, Put, Query, QueryParams, Queue, QueueClient, RESERVED_SECRET_PREFIX, RateLimitConfig, Realtime, type RegisteredError, Req, RequestId, type ResolvedCustomWebhook, type ResolvedHook, type ResolvedJobConfig, type ResolvedProviderWebhook, type ResolvedWebhookConfig, type ResolvedWorkerConfig, Resource, type ResourceEnv, type RouteOptions, type RuntimeServices, STORAGE_CONFIG_KIND, SchemaDef, type SendgridOptions, type SesOptions, type SignInEvent, type SignOutEvent, type SmtpOptions, Storage, type StorageConfig, type StorageInput, type ThrowDescriptor, TraceId, type TwilioOptions, Upload, type UploadConfig, UploadedObject, User, type UserCreatedEvent, User$1 as UserT, type WebhookEventHandler, type WebhookMeta, type WebhookProvider, type WebhookRequest, type WorkerConfig, type WorkerMeta, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, bucket, buildProvider, defineError, defineFlags, defineJob, defineNotifications, defineStorage, defineWebhook, defineWorker, documents, flag, getErrorRegistry, makeEnvDts, parseFileSizeLimit, recordThrows, reservedSecretKey, storage, validateUploadAgainstStorage };
1623
+ export { type AcsOptions, type ApnsOptions, type BackoffStrategy, Body, type BucketDef, type BucketOptions, Cache, CacheClient, Client, Controller, type ControllerOptions, type CustomWebhookConfig, DBClient, Database, type DefinedError, type DefinedErrorWithData, Delete, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, EGRESS_CONFIG_KIND, type EgressConfig, type EgressInput, type EnvSecretRef, EnvTypedDatabase, FLAGS_CONFIG_KIND, type FcmOptions, type FileDeletedEvent, type FileUploadedEvent, type FlagDef, type FlagOptions, type FlagType, type FlagValue, Flags, type FlagsConfig, type FlagsInput, Get, Headers, type HookHandler, type HookMeta, HttpError, type HttpMethodUpper, type JobConfig, type JobMeta, Log, Logger, NOTIFICATIONS_CONFIG_KIND, Notifications, type NotificationsConfig, type NotificationsInput, OptionalUser, type OwnedTablesOf, PROVIDER_CATALOG, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseRealtimeClient, PalbaseStorageClient, Param, type ParamKind, type ParamMeta, type PasswordResetEvent, Patch, Post, type ProviderCatalogEntry, type ProviderDef, type ProviderEventMap, type ProviderName, type ProviderOptions, type ProviderWebhookConfig, Put, Query, QueryParams, Queue, QueueClient, RESERVED_SECRET_PREFIX, RateLimitConfig, Realtime, type RegisteredError, Req, RequestId, type ResolvedCustomWebhook, type ResolvedHook, type ResolvedJobConfig, type ResolvedProviderWebhook, type ResolvedWebhookConfig, type ResolvedWorkerConfig, Resource, type ResourceEnv, type RouteMeta, type RouteOptions, type RuntimeServices, STORAGE_CONFIG_KIND, SchemaDef, type Seed, type SeedFor, type SeedJson, type SeedRowFor, type SendgridOptions, type SesOptions, type SignInEvent, type SignOutEvent, type SmtpOptions, Storage, type StorageConfig, type StorageInput, TEST_USERS_CONFIG_KIND, type TableGraph, TableTypes, Tables, type TestUserDef, type TestUserOptions, type TestUsersConfig, type TestUsersInput, type ThrowDescriptor, TraceId, type TwilioOptions, Upload, type UploadConfig, UploadedObject, User, type UserCreatedEvent, User$1 as UserT, type WebhookEventHandler, type WebhookMeta, type WebhookProvider, type WebhookRequest, type WorkerConfig, type WorkerMeta, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, bucket, buildProvider, defineEgress, defineError, defineFlags, defineJob, defineNotifications, defineStorage, defineTestUsers, defineWebhook, defineWorker, documents, flag, getErrorRegistry, getRoutes, makeEnvDts, parseFileSizeLimit, recordThrows, reservedSecretKey, storage, testUser, validateUploadAgainstStorage };