@fuzdev/fuz_app 0.31.0 → 0.33.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 (44) hide show
  1. package/dist/actions/rpc_client.d.ts +29 -0
  2. package/dist/actions/rpc_client.d.ts.map +1 -1
  3. package/dist/actions/rpc_client.js +31 -0
  4. package/dist/auth/CLAUDE.md +22 -0
  5. package/dist/auth/admin_rpc_actions.d.ts +49 -0
  6. package/dist/auth/admin_rpc_actions.d.ts.map +1 -0
  7. package/dist/auth/admin_rpc_actions.js +32 -0
  8. package/dist/server/app_server.d.ts +13 -2
  9. package/dist/server/app_server.d.ts.map +1 -1
  10. package/dist/server/app_server.js +12 -1
  11. package/dist/testing/CLAUDE.md +26 -10
  12. package/dist/testing/admin_integration.d.ts +14 -4
  13. package/dist/testing/admin_integration.d.ts.map +1 -1
  14. package/dist/testing/admin_integration.js +7 -4
  15. package/dist/testing/app_server.d.ts +10 -0
  16. package/dist/testing/app_server.d.ts.map +1 -1
  17. package/dist/testing/audit_completeness.d.ts +13 -4
  18. package/dist/testing/audit_completeness.d.ts.map +1 -1
  19. package/dist/testing/audit_completeness.js +8 -5
  20. package/dist/testing/integration.d.ts +14 -4
  21. package/dist/testing/integration.d.ts.map +1 -1
  22. package/dist/testing/integration.js +16 -6
  23. package/dist/testing/rate_limiting.d.ts +13 -4
  24. package/dist/testing/rate_limiting.d.ts.map +1 -1
  25. package/dist/testing/rate_limiting.js +9 -3
  26. package/dist/testing/rpc_helpers.d.ts +29 -0
  27. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  28. package/dist/testing/rpc_helpers.js +20 -0
  29. package/dist/testing/rpc_round_trip.d.ts +16 -5
  30. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  31. package/dist/testing/rpc_round_trip.js +11 -5
  32. package/dist/testing/sse_round_trip.d.ts +13 -5
  33. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  34. package/dist/testing/sse_round_trip.js +11 -5
  35. package/dist/testing/standard.d.ts +7 -2
  36. package/dist/testing/standard.d.ts.map +1 -1
  37. package/dist/testing/stubs.d.ts +10 -2
  38. package/dist/testing/stubs.d.ts.map +1 -1
  39. package/dist/testing/stubs.js +17 -2
  40. package/dist/ui/CLAUDE.md +12 -0
  41. package/dist/ui/admin_rpc_adapters.d.ts +94 -0
  42. package/dist/ui/admin_rpc_adapters.d.ts.map +1 -0
  43. package/dist/ui/admin_rpc_adapters.js +100 -0
  44. package/package.json +1 -1
@@ -65,4 +65,33 @@ export declare const create_rpc_client: (options: CreateRpcClientOptions) => Rec
65
65
  */
66
66
  export interface RpcClientCallOptions extends ActionPeerSendOptions {
67
67
  }
68
+ /**
69
+ * `method, input -> unwrapped output` signature for adapter wiring.
70
+ *
71
+ * The typed `create_rpc_client` Proxy returns `Result<T, JsonrpcErrorObject>`
72
+ * on every call. UI adapters (e.g. `admin_rpc_adapters.ts`) want a
73
+ * throw-on-error shape so form components can match on `error.data.reason`
74
+ * via catch blocks. `create_throwing_rpc_call` bridges the two.
75
+ */
76
+ export type ThrowingRpcCall = <TOutput = unknown>(method: string, input?: unknown) => Promise<TOutput>;
77
+ /**
78
+ * Wrap a typed RPC client so every call returns its unwrapped value or throws.
79
+ *
80
+ * On `{ok: false}`, throws an `Error` with the JSON-RPC error object's
81
+ * `{code, message, data}` spread onto it — so catch blocks that inspect
82
+ * `err.data?.reason` continue to work. On unknown method, throws a clear
83
+ * "rpc method not found" error instead of the cryptic `undefined is not a
84
+ * function` that would otherwise surface.
85
+ *
86
+ * Invariant upheld by `create_rpc_client`: every `{ok: false}` return
87
+ * carries a well-formed `JsonrpcErrorObject` with `code` + `message`.
88
+ * Callers must still use optional chaining on `err.data` because the
89
+ * JSON-RPC `data` field is spec-level optional — a handler that throws
90
+ * `jsonrpc_errors.forbidden()` without a `data` argument produces
91
+ * `err.data === undefined`.
92
+ *
93
+ * @param api - typed RPC client from `create_rpc_client` (or any Proxy-like
94
+ * object mapping method names to `(input) => Promise<Result<T, error>>`)
95
+ */
96
+ export declare const create_throwing_rpc_call: (api: Record<string, ((input?: any) => Promise<any>) | undefined>) => ThrowingRpcCall;
68
97
  //# sourceMappingURL=rpc_client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rpc_client.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/rpc_client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,yBAAyB,CAAC;AAOpE,OAAO,KAAK,EAAC,UAAU,EAAE,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAGnD;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;AAM/E,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACtC,aAAa,EAAE,CAAC,IAAI,EAAE;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,oBAAoB,CAAA;KAAC,KAC5E;QACA,sBAAsB,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;KAC5C,GACD,SAAS,CAAC;CACb;AAED,uCAAuC;AACvC,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,sBAAsB,CAAC;IACpC,kEAAkE;IAClE,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;CAC1C;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,GAC7B,SAAS,sBAAsB,KAC7B,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAgB7C,CAAC;AA2DF;;;;;GAKG;AACH,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;CAAG"}
1
+ {"version":3,"file":"rpc_client.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/rpc_client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,yBAAyB,CAAC;AAOpE,OAAO,KAAK,EAAC,UAAU,EAAE,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAGnD;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;AAM/E,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACtC,aAAa,EAAE,CAAC,IAAI,EAAE;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,oBAAoB,CAAA;KAAC,KAC5E;QACA,sBAAsB,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;KAC5C,GACD,SAAS,CAAC;CACb;AAED,uCAAuC;AACvC,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,sBAAsB,CAAC;IACpC,kEAAkE;IAClE,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;CAC1C;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,GAC7B,SAAS,sBAAsB,KAC7B,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAgB7C,CAAC;AA2DF;;;;;GAKG;AACH,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;CAAG;AAgItE;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,GAAG,OAAO,EAC/C,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,OAAO,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,wBAAwB,GACpC,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,KAC9D,eAUF,CAAC"}
@@ -168,3 +168,34 @@ const create_remote_notification_method = (peer, environment, spec, actions, tra
168
168
  return extract_action_result(event);
169
169
  };
170
170
  };
171
+ /**
172
+ * Wrap a typed RPC client so every call returns its unwrapped value or throws.
173
+ *
174
+ * On `{ok: false}`, throws an `Error` with the JSON-RPC error object's
175
+ * `{code, message, data}` spread onto it — so catch blocks that inspect
176
+ * `err.data?.reason` continue to work. On unknown method, throws a clear
177
+ * "rpc method not found" error instead of the cryptic `undefined is not a
178
+ * function` that would otherwise surface.
179
+ *
180
+ * Invariant upheld by `create_rpc_client`: every `{ok: false}` return
181
+ * carries a well-formed `JsonrpcErrorObject` with `code` + `message`.
182
+ * Callers must still use optional chaining on `err.data` because the
183
+ * JSON-RPC `data` field is spec-level optional — a handler that throws
184
+ * `jsonrpc_errors.forbidden()` without a `data` argument produces
185
+ * `err.data === undefined`.
186
+ *
187
+ * @param api - typed RPC client from `create_rpc_client` (or any Proxy-like
188
+ * object mapping method names to `(input) => Promise<Result<T, error>>`)
189
+ */
190
+ export const create_throwing_rpc_call = (api) => {
191
+ return async (method, input) => {
192
+ const fn = api[method];
193
+ if (!fn)
194
+ throw new Error(`rpc method not found: ${method}`);
195
+ const result = await fn(input);
196
+ if (!result.ok) {
197
+ throw Object.assign(new Error(result.error?.message ?? 'rpc error'), result.error);
198
+ }
199
+ return result.value;
200
+ };
201
+ };
@@ -836,6 +836,28 @@ Options:
836
836
  `all_permit_offer_action_specs: Array<RequestResponseActionSpec>` —
837
837
  codegen-ready registry.
838
838
 
839
+ ### `admin_rpc_actions.ts` — combined admin + permit-offer factory
840
+
841
+ `create_admin_rpc_actions(deps, options)` spreads
842
+ `create_admin_actions` and `create_permit_offer_actions` into a single
843
+ `Array<RpcAction>`, so consumers that mount the stock fuz_app admin
844
+ surface don't hand-wire the two factories. `roles` is shared between
845
+ both factories; `app_settings` flows to admin only; `default_ttl_ms`
846
+ and `authorize` flow to permit-offer only; `notification_sender` is
847
+ wired through to permit-offer (admin ignores it).
848
+
849
+ `AdminRpcActionsOptions` composes `AdminActionOptions` +
850
+ `PermitOfferActionOptions`. `AdminRpcActionsDeps` is the same shape as
851
+ `PermitOfferActionDeps` — `log`, `on_audit_event`, optional
852
+ `notification_sender`.
853
+
854
+ Pair this with `create_app_server`'s `rpc_endpoints` factory form
855
+ (`(ctx) => Array<RpcEndpointSpec>`) so the combined action list gets
856
+ `ctx.deps` + `ctx.app_settings` — `create_app_server` auto-mounts the
857
+ endpoint via `create_rpc_endpoint`, so consumers don't need to mount it
858
+ again in `create_route_specs`. See `../../../docs/usage.md` §Server
859
+ Assembly.
860
+
839
861
  ### `account_action_specs.ts` + `account_actions.ts` — seven self-service RPC actions
840
862
 
841
863
  Counterpart to `account_routes.ts`. Cookie-lifecycle flows (`login`,
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Combined admin + permit-offer RPC actions for fuz_app consumers.
3
+ *
4
+ * Consumers that want the stock fuz_app admin surface spread into their
5
+ * JSON-RPC endpoint import this helper instead of hand-wiring
6
+ * `create_admin_actions` + `create_permit_offer_actions`. The shared `roles`
7
+ * schema flows to both factories; `app_settings` goes to admin only;
8
+ * `default_ttl_ms` and `authorize` go to permit-offer only;
9
+ * `notification_sender` reaches permit-offer transparently (admin ignores it).
10
+ *
11
+ * Paired with `create_admin_rpc_adapters` on the UI side — same "admin RPC
12
+ * surface" concept expressed on each wire endpoint.
13
+ *
14
+ * @module
15
+ */
16
+ import { type AdminActionOptions } from './admin_actions.js';
17
+ import { type PermitOfferActionDeps, type PermitOfferActionOptions } from './permit_offer_actions.js';
18
+ import type { RpcAction } from '../actions/action_rpc.js';
19
+ /**
20
+ * Options for `create_admin_rpc_actions`.
21
+ *
22
+ * Composes `AdminActionOptions` (`roles`, `app_settings`) with
23
+ * `PermitOfferActionOptions` (`roles`, `default_ttl_ms`, `authorize`). `roles`
24
+ * is shared between both factories — the caller supplies it once and the
25
+ * helper threads the same reference to both.
26
+ */
27
+ export interface AdminRpcActionsOptions extends AdminActionOptions, PermitOfferActionOptions {
28
+ }
29
+ /**
30
+ * Dependencies for `create_admin_rpc_actions`.
31
+ *
32
+ * Same shape as `PermitOfferActionDeps` — `log`, `on_audit_event`, and an
33
+ * optional `notification_sender` for permit-offer WS fan-out. The admin
34
+ * factory only reads `log` + `on_audit_event`; the extra field is harmless.
35
+ */
36
+ export type AdminRpcActionsDeps = PermitOfferActionDeps;
37
+ /**
38
+ * Build the combined admin + permit-offer RPC action set.
39
+ *
40
+ * Spreads `create_admin_actions(deps, {roles, app_settings})` and
41
+ * `create_permit_offer_actions(deps, {roles, default_ttl_ms, authorize})`.
42
+ * The shared `roles` option flows to both.
43
+ *
44
+ * @param deps - stateless capabilities (log, on_audit_event, optional notification_sender)
45
+ * @param options - role schema, optional app-settings ref, permit-offer TTL and authorize
46
+ * @returns RPC actions to pass as `rpc_endpoints` or spread into `create_rpc_endpoint`
47
+ */
48
+ export declare const create_admin_rpc_actions: (deps: AdminRpcActionsDeps, options?: AdminRpcActionsOptions) => Array<RpcAction>;
49
+ //# sourceMappingURL=admin_rpc_actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin_rpc_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/admin_rpc_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAuB,KAAK,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAEN,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAExD;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAuB,SAAQ,kBAAkB,EAAE,wBAAwB;CAAG;AAE/F;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAExD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,GACpC,MAAM,mBAAmB,EACzB,UAAS,sBAA2B,KAClC,KAAK,CAAC,SAAS,CAGjB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Combined admin + permit-offer RPC actions for fuz_app consumers.
3
+ *
4
+ * Consumers that want the stock fuz_app admin surface spread into their
5
+ * JSON-RPC endpoint import this helper instead of hand-wiring
6
+ * `create_admin_actions` + `create_permit_offer_actions`. The shared `roles`
7
+ * schema flows to both factories; `app_settings` goes to admin only;
8
+ * `default_ttl_ms` and `authorize` go to permit-offer only;
9
+ * `notification_sender` reaches permit-offer transparently (admin ignores it).
10
+ *
11
+ * Paired with `create_admin_rpc_adapters` on the UI side — same "admin RPC
12
+ * surface" concept expressed on each wire endpoint.
13
+ *
14
+ * @module
15
+ */
16
+ import { create_admin_actions } from './admin_actions.js';
17
+ import { create_permit_offer_actions, } from './permit_offer_actions.js';
18
+ /**
19
+ * Build the combined admin + permit-offer RPC action set.
20
+ *
21
+ * Spreads `create_admin_actions(deps, {roles, app_settings})` and
22
+ * `create_permit_offer_actions(deps, {roles, default_ttl_ms, authorize})`.
23
+ * The shared `roles` option flows to both.
24
+ *
25
+ * @param deps - stateless capabilities (log, on_audit_event, optional notification_sender)
26
+ * @param options - role schema, optional app-settings ref, permit-offer TTL and authorize
27
+ * @returns RPC actions to pass as `rpc_endpoints` or spread into `create_rpc_endpoint`
28
+ */
29
+ export const create_admin_rpc_actions = (deps, options = {}) => [
30
+ ...create_admin_actions(deps, options),
31
+ ...create_permit_offer_actions(deps, options),
32
+ ];
@@ -129,8 +129,19 @@ export interface AppServerOptions {
129
129
  };
130
130
  /** SSE event specs for surface generation. Defaults to `[]` (no SSE events). */
131
131
  event_specs?: Array<EventSpec>;
132
- /** RPC endpoint specs for surface generation. */
133
- rpc_endpoints?: Array<RpcEndpointSpec>;
132
+ /**
133
+ * RPC endpoint specs — single source of truth for both surface generation
134
+ * *and* live dispatch. Each entry is mounted via `create_rpc_endpoint`
135
+ * against the assembled Hono app, so consumers no longer call
136
+ * `create_rpc_endpoint` themselves inside `create_route_specs`.
137
+ *
138
+ * Accepts either an array (evaluated eagerly) or a factory
139
+ * `(ctx: AppServerContext) => Array<RpcEndpointSpec>` (evaluated after the
140
+ * server context is assembled). Use the factory form when action lists
141
+ * depend on `ctx.deps` / `ctx.app_settings` — e.g.
142
+ * `create_admin_rpc_actions(ctx.deps, {app_settings: ctx.app_settings})`.
143
+ */
144
+ rpc_endpoints?: Array<RpcEndpointSpec> | ((context: AppServerContext) => Array<RpcEndpointSpec>);
134
145
  /** Env schema for surface generation. Pass `z.object({})` when there are no env vars beyond `BaseServerEnv`. */
135
146
  env_schema: z.ZodObject;
136
147
  /** Middleware applied after routes, before static serving. Included in surface. */
@@ -1 +1 @@
1
- {"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_server.ts"],"names":[],"mappings":"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"}
@@ -31,6 +31,7 @@ import { create_surface_route_spec } from '../http/common_routes.js';
31
31
  import { create_auth_middleware_specs } from '../auth/middleware.js';
32
32
  import { fuz_auth_guard_resolver } from '../auth/route_guards.js';
33
33
  import { ERROR_PAYLOAD_TOO_LARGE } from '../http/error_schemas.js';
34
+ import { create_rpc_endpoint } from '../actions/action_rpc.js';
34
35
  /** Default maximum request body size: 1 MiB. */
35
36
  export const DEFAULT_MAX_BODY_SIZE = 1024 * 1024;
36
37
  /**
@@ -133,6 +134,16 @@ export const create_app_server = async (options) => {
133
134
  const prefix = options.bootstrap.route_prefix ?? '/api/account';
134
135
  factory_routes.push(...prefix_route_specs(prefix, bootstrap_routes));
135
136
  }
137
+ // RPC endpoint auto-mount — resolve specs then append their routes so
138
+ // surface generation and live dispatch share one source of truth.
139
+ const resolved_rpc_endpoints = typeof options.rpc_endpoints === 'function'
140
+ ? options.rpc_endpoints(context)
141
+ : options.rpc_endpoints;
142
+ if (resolved_rpc_endpoints) {
143
+ for (const endpoint of resolved_rpc_endpoints) {
144
+ factory_routes.push(...create_rpc_endpoint({ path: endpoint.path, actions: endpoint.actions, log }));
145
+ }
146
+ }
136
147
  // Surface route (default: enabled)
137
148
  if (options.surface_route !== false) {
138
149
  factory_routes.push(create_surface_route_spec(surface_ref));
@@ -151,7 +162,7 @@ export const create_app_server = async (options) => {
151
162
  route_specs,
152
163
  env_schema: options.env_schema,
153
164
  event_specs: all_event_specs,
154
- rpc_endpoints: options.rpc_endpoints,
165
+ rpc_endpoints: resolved_rpc_endpoints,
155
166
  });
156
167
  // Config-level diagnostics (concatenated after spec-level from generate_app_surface)
157
168
  const config_diagnostics = [];
@@ -538,13 +538,25 @@ lifecycle (via `permit_offer_create` + `permit_revoke` RPC flows —
538
538
  **not** REST; see `../auth/CLAUDE.md` for `permit_offer_action_specs.ts` + `permit_offer_actions.ts`), session / token management, audit log reads (RPC),
539
539
  admin-to-admin isolation, error coverage, response schema validation.
540
540
 
541
- Required options: `{session_options, create_route_specs, roles: RoleSchemaResult, rpc_endpoints: Array<RpcEndpointSpec>, admin_prefix?, app_options?, db_factories?}`.
542
-
543
- **Hard-fails via `require_rpc_endpoint_path(options.rpc_endpoints)`** at
544
- setup time when `rpc_endpoints` is empty admin permit grant/revoke
545
- plus session/token revoke-all plus audit-log list/history are all
546
- RPC-only since the 2026-04-22 migration. A confusing test failure
547
- mid-suite is worse than a clear setup error.
541
+ Required options: `{session_options, create_route_specs, roles: RoleSchemaResult, rpc_endpoints: RpcEndpointsSuiteOption, admin_prefix?, app_options?, db_factories?}`.
542
+
543
+ `rpc_endpoints` is `Array<RpcEndpointSpec> | ((ctx: AppServerContext) => Array<RpcEndpointSpec>)` —
544
+ the same `RpcEndpointsSuiteOption` union every DB-backed suite accepts
545
+ (`integration`, `admin_integration`, `audit_completeness`, `rate_limiting`,
546
+ `rpc_round_trip`, `sse_round_trip`). Prefer the factory form: it forwards
547
+ raw to `app_options.rpc_endpoints` so `create_app_server` resolves it per-test
548
+ with the real ctx — the only way action handlers can close over
549
+ `ctx.deps` / `ctx.app_settings` (e.g. `create_admin_rpc_actions(ctx.deps,
550
+ {app_settings: ctx.app_settings})`). Factory must return the same endpoint
551
+ `path` regardless of ctx — `resolve_rpc_endpoints_for_setup` invokes it
552
+ once with a stub ctx for path lookup and `create_app_server` invokes it
553
+ again per-test for live dispatch.
554
+
555
+ **Hard-fails via `require_rpc_endpoint_path`** at setup time when
556
+ `rpc_endpoints` is empty — admin permit grant/revoke plus session/token
557
+ revoke-all plus audit-log list/history are all RPC-only since the
558
+ 2026-04-22 migration. A confusing test failure mid-suite is worse than a
559
+ clear setup error.
548
560
 
549
561
  Error-coverage scope is narrowed to the REST suffixes still on the
550
562
  admin surface (`/sessions`, `/audit-log/stream`); the RPC surface is
@@ -569,9 +581,11 @@ provide the filesystem token state; covered separately in
569
581
 
570
582
  Convenience wrapper: always runs `describe_standard_integration_tests`;
571
583
  runs `describe_standard_admin_integration_tests` only when `roles` is
572
- provided. `rpc_endpoints` is a required field on `StandardTestOptions`
573
- — the admin suite's requirement is enforced at the type level, so a
574
- missing `rpc_endpoints` is a compile error rather than a runtime throw.
584
+ provided. `rpc_endpoints: RpcEndpointsSuiteOption` is a required field on
585
+ `StandardTestOptions` — the admin suite's requirement is enforced at the
586
+ type level, so a missing `rpc_endpoints` is a compile error rather than a
587
+ runtime throw. Round-trips the union through unchanged so consumers can
588
+ pass either an eager array or the factory form.
575
589
 
576
590
  ## RPC helpers
577
591
 
@@ -613,6 +627,8 @@ Registry lookups:
613
627
  - `find_rpc_action(rpc_endpoints, method)` — endpoint path + `RpcAction` source.
614
628
  - `find_rpc_method(rpc_endpoints, method)` — surface-shape lookup over `AppSurfaceRpcEndpoint[]` (generated by `generate_app_surface`).
615
629
  - `require_rpc_endpoint_path(rpc_endpoints)` — returns the single endpoint path; throws descriptively on zero or multiple endpoints. Used by the admin/audit suites to hard-fail at setup.
630
+ - `RpcEndpointsSuiteOption` — union `Array<RpcEndpointSpec> | ((ctx: AppServerContext) => Array<RpcEndpointSpec>)` accepted by every DB-backed suite's `rpc_endpoints` field.
631
+ - `resolve_rpc_endpoints_for_setup(rpc_endpoints, session_options)` — resolves the union to an array for setup-time inspection (path lookup, `find_rpc_action` presence checks). Factory form is invoked once with a stub `AppServerContext`; the produced actions are discarded because `create_app_server` invokes the factory a second time per-test with its real ctx. Safe when the factory is pure wrt endpoint `path` and action `spec.method` list.
616
632
 
617
633
  ### `rpc_attack_surface.ts` — `describe_rpc_attack_surface_tests`
618
634
 
@@ -1,10 +1,11 @@
1
1
  import './assert_dev_env.js';
2
2
  import type { SessionOptions } from '../auth/session_cookie.js';
3
- import type { AppServerContext, AppServerOptions } from '../server/app_server.js';
3
+ import type { AppServerContext } from '../server/app_server.js';
4
4
  import type { RouteSpec } from '../http/route_spec.js';
5
5
  import { type RoleSchemaResult } from '../auth/role_schema.js';
6
+ import { type SuiteAppOptions } from './app_server.js';
6
7
  import { type DbFactory } from './db.js';
7
- import type { RpcEndpointSpec } from '../http/surface.js';
8
+ import { type RpcEndpointsSuiteOption } from './rpc_helpers.js';
8
9
  /**
9
10
  * Configuration for `describe_standard_admin_integration_tests`.
10
11
  */
@@ -18,8 +19,17 @@ export interface StandardAdminIntegrationTestOptions {
18
19
  /**
19
20
  * RPC endpoint specs — the source `RpcAction` arrays. Required; permit
20
21
  * grant/revoke are RPC-only and the suite hard-fails without them.
22
+ *
23
+ * Accepts either an array (eager) or a factory
24
+ * `(ctx: AppServerContext) => Array<RpcEndpointSpec>` — the factory form
25
+ * is required when action handlers must close over the per-test
26
+ * `ctx.app_settings` / `ctx.deps` (e.g. the canonical
27
+ * `create_admin_rpc_actions(ctx.deps, {app_settings: ctx.app_settings})`
28
+ * pattern). The factory must return the same endpoint `path` regardless
29
+ * of ctx — it is invoked once at setup with a stub ctx for path lookup
30
+ * and again per-test by `create_app_server` for live dispatch.
21
31
  */
22
- rpc_endpoints: Array<RpcEndpointSpec>;
32
+ rpc_endpoints: RpcEndpointsSuiteOption;
23
33
  /**
24
34
  * Path prefix where admin routes are mounted (e.g., `'/api/admin'`).
25
35
  * Used by the schema validation test to scope to fuz_app admin routes only,
@@ -28,7 +38,7 @@ export interface StandardAdminIntegrationTestOptions {
28
38
  */
29
39
  admin_prefix?: string;
30
40
  /** Optional overrides for `AppServerOptions`. */
31
- app_options?: Partial<Omit<AppServerOptions, 'backend' | 'session_options' | 'create_route_specs'>>;
41
+ app_options?: SuiteAppOptions;
32
42
  /**
33
43
  * Database factories to run tests against. Default: pglite only.
34
44
  * Pass consumer factories (e.g. `[pglite_factory, pg_factory]`) to also test against PostgreSQL.
@@ -1 +1 @@
1
- {"version":3,"file":"admin_integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/admin_integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAA0B,KAAK,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AAGtF,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AASjB,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,oBAAoB,CAAC;AAsBxD;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,4GAA4G;IAC5G,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;OAGG;IACH,aAAa,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACtC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CACpB,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,iBAAiB,GAAG,oBAAoB,CAAC,CAC5E,CAAC;IACF;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CAChC;AAgCD;;;;;;;;GAQG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,mCAAmC,KAC1C,IAo2BF,CAAC"}
1
+ {"version":3,"file":"admin_integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/admin_integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAA0B,KAAK,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AAEtF,OAAO,EAA6C,KAAK,eAAe,EAAC,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AASjB,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAqB1B;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,4GAA4G;IAC5G,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;;;;;;;;;;OAYG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CAChC;AAgCD;;;;;;;;GAQG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,mCAAmC,KAC1C,IA02BF,CAAC"}
@@ -20,7 +20,7 @@ import { create_pglite_factory, create_describe_db, AUTH_INTEGRATION_TRUNCATE_TA
20
20
  import { find_auth_route, assert_response_matches_spec } from './integration_helpers.js';
21
21
  import { run_migrations } from '../db/migrate.js';
22
22
  import { ErrorCoverageCollector, assert_error_coverage, DEFAULT_INTEGRATION_ERROR_COVERAGE, } from './error_coverage.js';
23
- import { rpc_call, rpc_call_non_browser, require_rpc_endpoint_path } from './rpc_helpers.js';
23
+ import { rpc_call, rpc_call_non_browser, require_rpc_endpoint_path, resolve_rpc_endpoints_for_setup, } from './rpc_helpers.js';
24
24
  import { permit_offer_create_action_spec, permit_revoke_action_spec, } from '../auth/permit_offer_action_specs.js';
25
25
  import { admin_account_list_action_spec, admin_session_list_action_spec, admin_session_revoke_all_action_spec, admin_token_revoke_all_action_spec, audit_log_list_action_spec, audit_log_permit_history_action_spec, } from '../auth/admin_action_specs.js';
26
26
  import { account_token_create_action_spec, account_verify_action_spec, } from '../auth/account_action_specs.js';
@@ -46,8 +46,8 @@ const build_admin_test_app_options = (options, db, roles) => ({
46
46
  db,
47
47
  roles: roles ?? [ROLE_KEEPER, ROLE_ADMIN],
48
48
  app_options: {
49
- rpc_endpoints: options.rpc_endpoints,
50
49
  ...options.app_options,
50
+ rpc_endpoints: options.rpc_endpoints,
51
51
  },
52
52
  });
53
53
  /**
@@ -61,8 +61,11 @@ const build_admin_test_app_options = (options, db, roles) => ({
61
61
  */
62
62
  export const describe_standard_admin_integration_tests = (options) => {
63
63
  // Hard-fail early so consumers see a clear setup error instead of a
64
- // confusing test failure when `rpc_endpoints` is missing.
65
- const rpc_path = require_rpc_endpoint_path(options.rpc_endpoints);
64
+ // confusing test failure when `rpc_endpoints` is missing. Factory-form
65
+ // callers are resolved with a stub ctx purely to extract the endpoint
66
+ // path; real handlers run per-test via `app_options.rpc_endpoints`.
67
+ const rpc_endpoints_for_setup = resolve_rpc_endpoints_for_setup(options.rpc_endpoints, options.session_options);
68
+ const rpc_path = require_rpc_endpoint_path(rpc_endpoints_for_setup);
66
69
  const init_schema = async (db) => {
67
70
  await run_migrations(db, [AUTH_MIGRATION_NS]);
68
71
  };
@@ -121,6 +121,16 @@ export interface CreateTestAppOptions extends TestAppServerOptions {
121
121
  /** Optional overrides for `AppServerOptions` (backend, session_options, and create_route_specs are managed). */
122
122
  app_options?: Partial<Omit<AppServerOptions, 'backend' | 'session_options' | 'create_route_specs'>>;
123
123
  }
124
+ /**
125
+ * `app_options` shape accepted by DB-backed suite helpers
126
+ * (`describe_standard_integration_tests`, `describe_audit_completeness_tests`,
127
+ * etc.). Excludes `rpc_endpoints` on top of the fields `CreateTestAppOptions`
128
+ * excludes — suites require `rpc_endpoints` at the suite level (hard-failed
129
+ * by `require_rpc_endpoint_path`) so setup-time path lookup and runtime
130
+ * dispatch read from one source of truth. Low-level `create_test_app`
131
+ * callers still pass `rpc_endpoints` via `app_options`.
132
+ */
133
+ export type SuiteAppOptions = Partial<Omit<AppServerOptions, 'backend' | 'session_options' | 'create_route_specs' | 'rpc_endpoints'>>;
124
134
  /**
125
135
  * A bootstrapped test account with credentials.
126
136
  */
@@ -1 +1 @@
1
- {"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/app_server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/app_server.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  import './assert_dev_env.js';
2
2
  import type { SessionOptions } from '../auth/session_cookie.js';
3
- import type { AppServerContext, AppServerOptions } from '../server/app_server.js';
3
+ import type { AppServerContext } from '../server/app_server.js';
4
4
  import type { RouteSpec } from '../http/route_spec.js';
5
+ import { type SuiteAppOptions } from './app_server.js';
5
6
  import { type DbFactory } from './db.js';
6
- import type { RpcEndpointSpec } from '../http/surface.js';
7
+ import { type RpcEndpointsSuiteOption } from './rpc_helpers.js';
7
8
  /**
8
9
  * Configuration for `describe_audit_completeness_tests`.
9
10
  */
@@ -15,10 +16,18 @@ export interface AuditCompletenessTestOptions {
15
16
  /**
16
17
  * RPC endpoint specs — the source `RpcAction` arrays. Required; the
17
18
  * admin permit flow is RPC-only and the suite hard-fails without it.
19
+ *
20
+ * Accepts either an array (eager) or a factory
21
+ * `(ctx: AppServerContext) => Array<RpcEndpointSpec>` — the factory form
22
+ * is required when action handlers must close over the per-test
23
+ * `ctx.app_settings` / `ctx.deps` (e.g. exercising `app_settings_update`).
24
+ * The factory must return the same endpoint `path` regardless of ctx —
25
+ * it is invoked once at setup with a stub ctx for path lookup and again
26
+ * per-test by `create_app_server` for live dispatch.
18
27
  */
19
- rpc_endpoints: Array<RpcEndpointSpec>;
28
+ rpc_endpoints: RpcEndpointsSuiteOption;
20
29
  /** Optional overrides for `AppServerOptions`. */
21
- app_options?: Partial<Omit<AppServerOptions, 'backend' | 'session_options' | 'create_route_specs'>>;
30
+ app_options?: SuiteAppOptions;
22
31
  /** Database factories to run tests against. Default: pglite only. */
23
32
  db_factories?: Array<DbFactory>;
24
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"audit_completeness.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/audit_completeness.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAMrD,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AA0BjB,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,oBAAoB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE;;;OAGG;IACH,aAAa,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACtC,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CACpB,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,iBAAiB,GAAG,oBAAoB,CAAC,CAC5E,CAAC;IACF,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CAChC;AAoDD;;;;;;;;GAQG;AACH,eAAO,MAAM,iCAAiC,GAAI,SAAS,4BAA4B,KAAG,IAgezF,CAAC"}
1
+ {"version":3,"file":"audit_completeness.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/audit_completeness.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAKrD,OAAO,EAGN,KAAK,eAAe,EAEpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAKjB,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAsB1B;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE;;;;;;;;;;;OAWG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CAChC;AAoDD;;;;;;;;GAQG;AACH,eAAO,MAAM,iCAAiC,GAAI,SAAS,4BAA4B,KAAG,IAsezF,CAAC"}
@@ -16,12 +16,12 @@ import { describe, test, assert } from 'vitest';
16
16
  import { ROLE_KEEPER, ROLE_ADMIN } from '../auth/role_schema.js';
17
17
  import { AUDIT_EVENT_TYPES } from '../auth/audit_log_schema.js';
18
18
  import { AUTH_MIGRATION_NS } from '../auth/migrations.js';
19
- import { create_test_app } from './app_server.js';
19
+ import { create_test_app, } from './app_server.js';
20
20
  import { create_pglite_factory, create_describe_db, AUTH_INTEGRATION_TRUNCATE_TABLES, } from './db.js';
21
21
  import { find_auth_route } from './integration_helpers.js';
22
22
  import { run_migrations } from '../db/migrate.js';
23
23
  import { query_accept_offer } from '../auth/permit_offer_queries.js';
24
- import { rpc_call, require_rpc_endpoint_path } from './rpc_helpers.js';
24
+ import { rpc_call, require_rpc_endpoint_path, resolve_rpc_endpoints_for_setup, } from './rpc_helpers.js';
25
25
  import { permit_offer_create_action_spec, permit_revoke_action_spec, } from '../auth/permit_offer_action_specs.js';
26
26
  import { admin_session_revoke_all_action_spec, admin_token_revoke_all_action_spec, app_settings_update_action_spec, invite_create_action_spec, invite_delete_action_spec, } from '../auth/admin_action_specs.js';
27
27
  import { account_session_list_action_spec, account_session_revoke_action_spec, account_session_revoke_all_action_spec, account_token_create_action_spec, account_token_list_action_spec, account_token_revoke_action_spec, } from '../auth/account_action_specs.js';
@@ -41,8 +41,8 @@ const build_options = (options, db) => ({
41
41
  db,
42
42
  roles: [ROLE_KEEPER, ROLE_ADMIN],
43
43
  app_options: {
44
- rpc_endpoints: options.rpc_endpoints,
45
44
  ...options.app_options,
45
+ rpc_endpoints: options.rpc_endpoints,
46
46
  },
47
47
  });
48
48
  /** Headers for unauthenticated JSON requests (login, signup). */
@@ -67,8 +67,11 @@ const json_session_headers = (test_app, extra) => test_app.create_session_header
67
67
  */
68
68
  export const describe_audit_completeness_tests = (options) => {
69
69
  // Hard-fail early so consumers see a clear setup error instead of a
70
- // confusing test failure when `rpc_endpoints` is missing.
71
- const rpc_path = require_rpc_endpoint_path(options.rpc_endpoints);
70
+ // confusing test failure when `rpc_endpoints` is missing. Factory-form
71
+ // callers are resolved with a stub ctx purely to extract the endpoint
72
+ // path; real handlers run per-test via `app_options.rpc_endpoints`.
73
+ const rpc_endpoints_for_setup = resolve_rpc_endpoints_for_setup(options.rpc_endpoints, options.session_options);
74
+ const rpc_path = require_rpc_endpoint_path(rpc_endpoints_for_setup);
72
75
  const init_schema = async (db) => {
73
76
  await run_migrations(db, [AUTH_MIGRATION_NS]);
74
77
  };
@@ -1,9 +1,10 @@
1
1
  import './assert_dev_env.js';
2
2
  import type { SessionOptions } from '../auth/session_cookie.js';
3
- import type { AppServerContext, AppServerOptions } from '../server/app_server.js';
3
+ import type { AppServerContext } from '../server/app_server.js';
4
4
  import type { RouteSpec } from '../http/route_spec.js';
5
+ import { type SuiteAppOptions } from './app_server.js';
5
6
  import { type DbFactory } from './db.js';
6
- import type { RpcEndpointSpec } from '../http/surface.js';
7
+ import { type RpcEndpointsSuiteOption } from './rpc_helpers.js';
7
8
  /**
8
9
  * Configuration for `describe_standard_integration_tests`.
9
10
  */
@@ -13,7 +14,7 @@ export interface StandardIntegrationTestOptions {
13
14
  /** Route spec factory — same one used in production. */
14
15
  create_route_specs: (ctx: AppServerContext) => Array<RouteSpec>;
15
16
  /** Optional overrides for `AppServerOptions`. */
16
- app_options?: Partial<Omit<AppServerOptions, 'backend' | 'session_options' | 'create_route_specs'>>;
17
+ app_options?: SuiteAppOptions;
17
18
  /**
18
19
  * Database factories to run tests against. Default: pglite only.
19
20
  * Pass consumer factories (e.g. `[pglite_factory, pg_factory]`) to also test against PostgreSQL.
@@ -26,8 +27,17 @@ export interface StandardIntegrationTestOptions {
26
27
  * nginx shim with no payload). Hard-fails via
27
28
  * `require_rpc_endpoint_path` on setup so consumer projects see a
28
29
  * clear setup error instead of confusing test failures.
30
+ *
31
+ * Accepts either an array (eager) or a factory
32
+ * `(ctx: AppServerContext) => Array<RpcEndpointSpec>` — the factory form
33
+ * is required when action handlers must close over the per-test
34
+ * `ctx.app_settings` / `ctx.deps` (e.g. the canonical
35
+ * `create_admin_rpc_actions(ctx.deps, {app_settings: ctx.app_settings})`
36
+ * pattern). The factory must return the same endpoint `path` regardless
37
+ * of ctx — it is invoked once at setup with a stub ctx for path lookup
38
+ * and again per-test by `create_app_server` for live dispatch.
29
39
  */
30
- rpc_endpoints: Array<RpcEndpointSpec>;
40
+ rpc_endpoints: RpcEndpointsSuiteOption;
31
41
  }
32
42
  /**
33
43
  * Standard integration test suite for fuz_app auth routes.
@@ -1 +1 @@
1
- {"version":3,"file":"integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAsB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAGrD,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAsBjB,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,oBAAoB,CAAC;AAYxD;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC9C,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CACpB,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,iBAAiB,GAAG,oBAAoB,CAAC,CAC5E,CAAC;IACF;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;;;;;OAOG;IACH,aAAa,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;CACtC;AAeD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mCAAmC,GAC/C,SAAS,8BAA8B,KACrC,IAm3CF,CAAC"}
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAsB7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAA6C,KAAK,eAAe,EAAC,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAOjB,OAAO,EAMN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAqB1B;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC9C,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,EAAE,uBAAuB,CAAC;CACvC;AAsBD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mCAAmC,GAC/C,SAAS,8BAA8B,KACrC,IAy3CF,CAAC"}