@fuzdev/fuz_app 0.33.0 → 0.35.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.
@@ -1 +1 @@
1
- {"version":3,"file":"action_rpc.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAExE,OAAO,EAAgC,KAAK,cAAc,EAAC,MAAM,4BAA4B,CAAC;AAE9F,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,OAAO,EAGN,KAAK,gBAAgB,EAGrB,MAAM,oBAAoB,CAAC;AAW5B;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,+DAA+D;IAC/D,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,iDAAiD;IACjD,UAAU,EAAE,gBAAgB,CAAC;IAC7B,8DAA8D;IAC9D,EAAE,EAAE,EAAE,CAAC;IACP,oFAAoF;IACpF,aAAa,EAAE,EAAE,CAAC;IAClB,2EAA2E;IAC3E,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;OAQG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD;;;;OAIG;IACH,MAAM,EAAE,WAAW,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,CACxD,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,aAAa,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,EAAE,aAAa,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU,GAAI,KAAK,SAAS,yBAAyB,EACjE,MAAM,KAAK,EACX,SAAS,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KACvE,SAGD,CAAC;AAEH,yCAAyC;AACzC,MAAM,WAAW,wBAAwB;IACxC,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC1B,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;CACZ;AA4DD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,wBAAwB,KAAG,KAAK,CAAC,SAAS,CAwPtF,CAAC"}
1
+ {"version":3,"file":"action_rpc.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAExE,OAAO,EAAgC,KAAK,cAAc,EAAC,MAAM,4BAA4B,CAAC;AAE9F,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,OAAO,EAGN,KAAK,gBAAgB,EAGrB,MAAM,oBAAoB,CAAC;AAW5B;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,+DAA+D;IAC/D,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,iDAAiD;IACjD,UAAU,EAAE,gBAAgB,CAAC;IAC7B,8DAA8D;IAC9D,EAAE,EAAE,EAAE,CAAC;IACP,oFAAoF;IACpF,aAAa,EAAE,EAAE,CAAC;IAClB,2EAA2E;IAC3E,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;OAQG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD;;;;OAIG;IACH,MAAM,EAAE,WAAW,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,CACxD,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,aAAa,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,EAAE,aAAa,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU,GAAI,KAAK,SAAS,yBAAyB,EACjE,MAAM,KAAK,EACX,SAAS,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KACvE,SAGD,CAAC;AAEH,yCAAyC;AACzC,MAAM,WAAW,wBAAwB;IACxC,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC1B,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;CACZ;AA4DD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,wBAAwB,KAAG,KAAK,CAAC,SAAS,CA6PtF,CAAC"}
@@ -163,7 +163,12 @@ export const create_rpc_endpoint = (options) => {
163
163
  return c.json(error, jsonrpc_error_code_to_http_status(auth_error.code));
164
164
  }
165
165
  // step 4: validate params
166
- const params = raw_params ?? (is_null_schema(action.spec.input) ? null : undefined);
166
+ // Missing `params` on the envelope maps to `null` for `z.null()` input
167
+ // schemas and `{}` for object inputs — matches HTTP's "empty body = empty
168
+ // object" convention so callers of all-optional-object RPC methods can
169
+ // omit `params` on the wire (JSON-RPC envelope still serializes without
170
+ // a `params` field; no protocol-level change).
171
+ const params = raw_params ?? (is_null_schema(action.spec.input) ? null : {});
167
172
  const parse_result = action.spec.input.safeParse(params);
168
173
  if (!parse_result.success) {
169
174
  const error = jsonrpc_error_response(id, jsonrpc_error_messages.invalid_params('invalid params', {
@@ -77,11 +77,12 @@ export type ThrowingRpcCall = <TOutput = unknown>(method: string, input?: unknow
77
77
  /**
78
78
  * Wrap a typed RPC client so every call returns its unwrapped value or throws.
79
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.
80
+ * On `{ok: false}`, throws an `Error` whose `message` comes from the
81
+ * JSON-RPC error object, plus `{code, data}` as own properties — so
82
+ * catch blocks reading `err.message` / `err.code` / `err.data?.reason`
83
+ * all work. On unknown method, throws a clear "rpc method not found"
84
+ * error instead of the cryptic `undefined is not a function` that
85
+ * would otherwise surface.
85
86
  *
86
87
  * Invariant upheld by `create_rpc_client`: every `{ok: false}` return
87
88
  * carries a well-formed `JsonrpcErrorObject` with `code` + `message`.
@@ -90,8 +91,22 @@ export type ThrowingRpcCall = <TOutput = unknown>(method: string, input?: unknow
90
91
  * `jsonrpc_errors.forbidden()` without a `data` argument produces
91
92
  * `err.data === undefined`.
92
93
  *
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>>`)
94
+ * Only `{code, data}` cross onto the thrown Error — `message` flows
95
+ * through the `Error` constructor argument, and `name` / `stack` are
96
+ * left as the Error's own so attacker-shaped `result.error` payloads
97
+ * cannot overwrite them.
98
+ *
99
+ * The mapped-type generic constraint accepts both shapes without a cast:
100
+ * a codegen-derived typed `ActionsApi` (named-method interface, e.g.
101
+ * `{account_verify: (input) => Promise<Result<...>>, ...}`) and a loose
102
+ * `Record<string, (input?: any) => Promise<any>>`. Using `keyof TApi` in
103
+ * the constraint avoids the index-signature requirement that would
104
+ * otherwise force consumers to `as unknown as Record<string, …>` their
105
+ * generated client.
106
+ *
107
+ * @param api - typed RPC client from `create_rpc_client` (or any object
108
+ * whose values are all `(input?) => Promise<...>` functions — notably
109
+ * the consumer's generated `ActionsApi` interface)
95
110
  */
96
- export declare const create_throwing_rpc_call: (api: Record<string, ((input?: any) => Promise<any>) | undefined>) => ThrowingRpcCall;
111
+ export declare const create_throwing_rpc_call: <TApi extends Record<keyof TApi, (input?: any) => Promise<any>>>(api: TApi) => ThrowingRpcCall;
97
112
  //# 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;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"}
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,wBAAwB,GACpC,IAAI,SAAS,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,EAE9D,KAAK,IAAI,KACP,eAcF,CAAC"}
@@ -171,11 +171,12 @@ const create_remote_notification_method = (peer, environment, spec, actions, tra
171
171
  /**
172
172
  * Wrap a typed RPC client so every call returns its unwrapped value or throws.
173
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.
174
+ * On `{ok: false}`, throws an `Error` whose `message` comes from the
175
+ * JSON-RPC error object, plus `{code, data}` as own properties — so
176
+ * catch blocks reading `err.message` / `err.code` / `err.data?.reason`
177
+ * all work. On unknown method, throws a clear "rpc method not found"
178
+ * error instead of the cryptic `undefined is not a function` that
179
+ * would otherwise surface.
179
180
  *
180
181
  * Invariant upheld by `create_rpc_client`: every `{ok: false}` return
181
182
  * carries a well-formed `JsonrpcErrorObject` with `code` + `message`.
@@ -184,17 +185,35 @@ const create_remote_notification_method = (peer, environment, spec, actions, tra
184
185
  * `jsonrpc_errors.forbidden()` without a `data` argument produces
185
186
  * `err.data === undefined`.
186
187
  *
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>>`)
188
+ * Only `{code, data}` cross onto the thrown Error — `message` flows
189
+ * through the `Error` constructor argument, and `name` / `stack` are
190
+ * left as the Error's own so attacker-shaped `result.error` payloads
191
+ * cannot overwrite them.
192
+ *
193
+ * The mapped-type generic constraint accepts both shapes without a cast:
194
+ * a codegen-derived typed `ActionsApi` (named-method interface, e.g.
195
+ * `{account_verify: (input) => Promise<Result<...>>, ...}`) and a loose
196
+ * `Record<string, (input?: any) => Promise<any>>`. Using `keyof TApi` in
197
+ * the constraint avoids the index-signature requirement that would
198
+ * otherwise force consumers to `as unknown as Record<string, …>` their
199
+ * generated client.
200
+ *
201
+ * @param api - typed RPC client from `create_rpc_client` (or any object
202
+ * whose values are all `(input?) => Promise<...>` functions — notably
203
+ * the consumer's generated `ActionsApi` interface)
189
204
  */
190
205
  export const create_throwing_rpc_call = (api) => {
206
+ const rec = api;
191
207
  return async (method, input) => {
192
- const fn = api[method];
208
+ const fn = rec[method];
193
209
  if (!fn)
194
210
  throw new Error(`rpc method not found: ${method}`);
195
211
  const result = await fn(input);
196
212
  if (!result.ok) {
197
- throw Object.assign(new Error(result.error?.message ?? 'rpc error'), result.error);
213
+ throw Object.assign(new Error(result.error?.message ?? 'rpc error'), {
214
+ code: result.error?.code,
215
+ data: result.error?.data,
216
+ });
198
217
  }
199
218
  return result.value;
200
219
  };
@@ -836,20 +836,25 @@ 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`.
839
+ ### `standard_rpc_actions.ts` — combined admin + permit-offer + account factory
840
+
841
+ `create_standard_rpc_actions(deps, options)` spreads
842
+ `create_admin_actions`, `create_permit_offer_actions`, and
843
+ `create_account_actions` into a single `Array<RpcAction>` the
844
+ canonical fuz_app "standard" RPC surface (25 actions with
845
+ `app_settings` wired, 23 without). Consumers that want a narrower
846
+ surface drop down to the per-domain factories directly.
847
+
848
+ Option routing: `roles` is shared between admin and permit-offer;
849
+ `app_settings` flows to admin only; `default_ttl_ms` and `authorize`
850
+ flow to permit-offer only; `max_tokens` flows to account only;
851
+ `notification_sender` is wired through to permit-offer (admin +
852
+ account ignore it).
853
+
854
+ `StandardRpcActionsOptions` composes `AdminActionOptions` +
855
+ `PermitOfferActionOptions` + `AccountActionOptions`.
856
+ `StandardRpcActionsDeps` is the same shape as `PermitOfferActionDeps`
857
+ — `log`, `on_audit_event`, optional `notification_sender`.
853
858
 
854
859
  Pair this with `create_app_server`'s `rpc_endpoints` factory form
855
860
  (`(ctx) => Array<RpcEndpointSpec>`) so the combined action list gets
@@ -858,6 +863,15 @@ endpoint via `create_rpc_endpoint`, so consumers don't need to mount it
858
863
  again in `create_route_specs`. See `../../../docs/usage.md` §Server
859
864
  Assembly.
860
865
 
866
+ Pre-bundle consumers spread `create_admin_actions` and
867
+ `create_permit_offer_actions` separately, then also
868
+ `create_account_actions`. The bundled helper replaces all three —
869
+ bundling account actions into the "standard" surface is deliberate:
870
+ the admin integration suite exercises `account_token_create` /
871
+ `account_token_revoke` (cross-account isolation scenarios), so a
872
+ consumer wiring the admin surface without account actions will hit
873
+ `method not found` on first admin-suite run.
874
+
861
875
  ### `account_action_specs.ts` + `account_actions.ts` — seven self-service RPC actions
862
876
 
863
877
  Counterpart to `account_routes.ts`. Cookie-lifecycle flows (`login`,
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Combined admin + permit-offer + account RPC actions for fuz_app consumers.
3
+ *
4
+ * The canonical "standard" RPC surface: every stock fuz_app RPC action a
5
+ * typical web consumer wants on one endpoint. Consumers that want a
6
+ * narrower surface drop down to the per-domain factories directly
7
+ * (`create_admin_actions` / `create_permit_offer_actions` /
8
+ * `create_account_actions`).
9
+ *
10
+ * Option routing: shared `roles` flows to both admin and permit-offer;
11
+ * `app_settings` goes to admin only; `default_ttl_ms` and `authorize` go
12
+ * to permit-offer only; `max_tokens` goes to account only;
13
+ * `notification_sender` reaches permit-offer transparently (admin + account
14
+ * ignore it).
15
+ *
16
+ * Paired with `create_admin_rpc_adapters` on the UI side.
17
+ *
18
+ * @module
19
+ */
20
+ import { type AdminActionOptions } from './admin_actions.js';
21
+ import { type PermitOfferActionDeps, type PermitOfferActionOptions } from './permit_offer_actions.js';
22
+ import { type AccountActionOptions } from './account_actions.js';
23
+ import type { RpcAction } from '../actions/action_rpc.js';
24
+ /**
25
+ * Options for `create_standard_rpc_actions`.
26
+ *
27
+ * Composes `AdminActionOptions` (`roles`, `app_settings`),
28
+ * `PermitOfferActionOptions` (`roles`, `default_ttl_ms`, `authorize`), and
29
+ * `AccountActionOptions` (`max_tokens`). `roles` is shared between admin
30
+ * and permit-offer — the caller supplies it once and the helper threads
31
+ * the same reference to both.
32
+ */
33
+ export interface StandardRpcActionsOptions extends AdminActionOptions, PermitOfferActionOptions, AccountActionOptions {
34
+ }
35
+ /**
36
+ * Dependencies for `create_standard_rpc_actions`.
37
+ *
38
+ * Same shape as `PermitOfferActionDeps` — `log`, `on_audit_event`, and an
39
+ * optional `notification_sender` for permit-offer WS fan-out. Admin and
40
+ * account factories only read `log` + `on_audit_event`; the extra field
41
+ * is harmless.
42
+ */
43
+ export type StandardRpcActionsDeps = PermitOfferActionDeps;
44
+ /**
45
+ * Build the combined admin + permit-offer + account RPC action set.
46
+ *
47
+ * Spreads `create_admin_actions(deps, {roles, app_settings})`,
48
+ * `create_permit_offer_actions(deps, {roles, default_ttl_ms, authorize})`,
49
+ * and `create_account_actions(deps, {max_tokens})`. The shared `roles`
50
+ * option flows to admin + permit-offer.
51
+ *
52
+ * @param deps - stateless capabilities (log, on_audit_event, optional notification_sender)
53
+ * @param options - role schema, optional app-settings ref, permit-offer config, account config
54
+ * @returns RPC actions to pass as `rpc_endpoints` or spread into `create_rpc_endpoint`
55
+ */
56
+ export declare const create_standard_rpc_actions: (deps: StandardRpcActionsDeps, options?: StandardRpcActionsOptions) => Array<RpcAction>;
57
+ //# sourceMappingURL=standard_rpc_actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard_rpc_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/standard_rpc_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAuB,KAAK,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAEN,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAyB,KAAK,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AACvF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,WAAW,yBAChB,SAAQ,kBAAkB,EAAE,wBAAwB,EAAE,oBAAoB;CAAG;AAE9E;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,2BAA2B,GACvC,MAAM,sBAAsB,EAC5B,UAAS,yBAA8B,KACrC,KAAK,CAAC,SAAS,CAIjB,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Combined admin + permit-offer + account RPC actions for fuz_app consumers.
3
+ *
4
+ * The canonical "standard" RPC surface: every stock fuz_app RPC action a
5
+ * typical web consumer wants on one endpoint. Consumers that want a
6
+ * narrower surface drop down to the per-domain factories directly
7
+ * (`create_admin_actions` / `create_permit_offer_actions` /
8
+ * `create_account_actions`).
9
+ *
10
+ * Option routing: shared `roles` flows to both admin and permit-offer;
11
+ * `app_settings` goes to admin only; `default_ttl_ms` and `authorize` go
12
+ * to permit-offer only; `max_tokens` goes to account only;
13
+ * `notification_sender` reaches permit-offer transparently (admin + account
14
+ * ignore it).
15
+ *
16
+ * Paired with `create_admin_rpc_adapters` on the UI side.
17
+ *
18
+ * @module
19
+ */
20
+ import { create_admin_actions } from './admin_actions.js';
21
+ import { create_permit_offer_actions, } from './permit_offer_actions.js';
22
+ import { create_account_actions } from './account_actions.js';
23
+ /**
24
+ * Build the combined admin + permit-offer + account RPC action set.
25
+ *
26
+ * Spreads `create_admin_actions(deps, {roles, app_settings})`,
27
+ * `create_permit_offer_actions(deps, {roles, default_ttl_ms, authorize})`,
28
+ * and `create_account_actions(deps, {max_tokens})`. The shared `roles`
29
+ * option flows to admin + permit-offer.
30
+ *
31
+ * @param deps - stateless capabilities (log, on_audit_event, optional notification_sender)
32
+ * @param options - role schema, optional app-settings ref, permit-offer config, account config
33
+ * @returns RPC actions to pass as `rpc_endpoints` or spread into `create_rpc_endpoint`
34
+ */
35
+ export const create_standard_rpc_actions = (deps, options = {}) => [
36
+ ...create_admin_actions(deps, options),
37
+ ...create_permit_offer_actions(deps, options),
38
+ ...create_account_actions(deps, options),
39
+ ];
@@ -139,7 +139,7 @@ export interface AppServerOptions {
139
139
  * `(ctx: AppServerContext) => Array<RpcEndpointSpec>` (evaluated after the
140
140
  * server context is assembled). Use the factory form when action lists
141
141
  * depend on `ctx.deps` / `ctx.app_settings` — e.g.
142
- * `create_admin_rpc_actions(ctx.deps, {app_settings: ctx.app_settings})`.
142
+ * `create_standard_rpc_actions(ctx.deps, {app_settings: ctx.app_settings})`.
143
143
  */
144
144
  rpc_endpoints?: Array<RpcEndpointSpec> | ((context: AppServerContext) => Array<RpcEndpointSpec>);
145
145
  /** Env schema for surface generation. Pass `z.object({})` when there are no env vars beyond `BaseServerEnv`. */
@@ -267,8 +267,13 @@ Walks Zod schemas to generate valid values for adversarial/round-trip tests.
267
267
  - `generate_valid_value(field, field_schema)` — base-type switch
268
268
  producing a valid sample (UUIDs → nil UUID, strings → `'xxxxxxxxxx'`,
269
269
  numbers → `1`, objects → recurse, enums → first entry, etc.).
270
- Falls back through `/` + URL prefixes if a branded-string refinement
271
- rejects the plain base.
270
+ For branded-string refinements, walks a fallback chain synthesized
271
+ from the `pattern` string the JSON Schema representation exposes:
272
+ fixed-length hex (`^[0-9a-f]{N}$` — blake3 / sha256 / md5 digests;
273
+ `0`.repeat(N)), prefix-lengthed slug (`^<prefix>_[A-Za-z0-9_-]{N}$`
274
+ — `ApiTokenId`-style ids; `<prefix>_` + `x`.repeat(N)), absolute
275
+ path prefix, URL prefix. First candidate that `safeParse` accepts
276
+ is used.
272
277
  - `resolve_valid_path(path, params_schema?)` — swaps `:param` for
273
278
  valid-format values (nil UUID for UUID params, `test_param` otherwise).
274
279
  - `generate_valid_body(input_schema) => Record<string, unknown> | undefined` —
@@ -546,7 +551,7 @@ the same `RpcEndpointsSuiteOption` union every DB-backed suite accepts
546
551
  `rpc_round_trip`, `sse_round_trip`). Prefer the factory form: it forwards
547
552
  raw to `app_options.rpc_endpoints` so `create_app_server` resolves it per-test
548
553
  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,
554
+ `ctx.deps` / `ctx.app_settings` (e.g. `create_standard_rpc_actions(ctx.deps,
550
555
  {app_settings: ctx.app_settings})`). Factory must return the same endpoint
551
556
  `path` regardless of ctx — `resolve_rpc_endpoints_for_setup` invokes it
552
557
  once with a stub ctx for path lookup and `create_app_server` invokes it
@@ -558,9 +563,23 @@ revoke-all plus audit-log list/history are all RPC-only since the
558
563
  2026-04-22 migration. A confusing test failure mid-suite is worse than a
559
564
  clear setup error.
560
565
 
566
+ The suite also exercises `account_token_create` (and
567
+ `account_token_revoke`) for the cross-admin isolation + audit-trail
568
+ scenarios. Wire the account actions alongside admin / permit-offer —
569
+ the easiest path is `create_standard_rpc_actions`, which bundles all
570
+ three. Consumers that only wire admin will hit `method not found:
571
+ account_token_create` on first run.
572
+
561
573
  Error-coverage scope is narrowed to the REST suffixes still on the
562
- admin surface (`/sessions`, `/audit-log/stream`); the RPC surface is
563
- covered by `describe_rpc_round_trip_tests`.
574
+ admin surface (`/audit-log/stream`); the RPC surface is covered by
575
+ `describe_rpc_round_trip_tests`. Post-RPC-migration that surface is
576
+ 0–1 routes — when the scoped count is ≤1, the `afterAll` hook logs
577
+ `[error coverage] skipped admin REST coverage assertion — …` and
578
+ does not fail. The 20% `DEFAULT_INTEGRATION_ERROR_COVERAGE` baseline
579
+ is a REST-era threshold; the RPC surface has its own coverage via
580
+ `describe_rpc_round_trip_tests`. TODO: move this error-coverage
581
+ collector to the RPC round-trip suite entirely and delete this skip
582
+ branch.
564
583
 
565
584
  ### `audit_completeness.ts` — `describe_audit_completeness_tests`
566
585
 
@@ -24,7 +24,7 @@ export interface StandardAdminIntegrationTestOptions {
24
24
  * `(ctx: AppServerContext) => Array<RpcEndpointSpec>` — the factory form
25
25
  * is required when action handlers must close over the per-test
26
26
  * `ctx.app_settings` / `ctx.deps` (e.g. the canonical
27
- * `create_admin_rpc_actions(ctx.deps, {app_settings: ctx.app_settings})`
27
+ * `create_standard_rpc_actions(ctx.deps, {app_settings: ctx.app_settings})`
28
28
  * pattern). The factory must return the same endpoint `path` regardless
29
29
  * of ctx — it is invoked once at setup with a stub ctx for path lookup
30
30
  * and again per-test by `create_app_server` for live dispatch.
@@ -32,9 +32,9 @@ export interface StandardAdminIntegrationTestOptions {
32
32
  rpc_endpoints: RpcEndpointsSuiteOption;
33
33
  /**
34
34
  * Path prefix where admin routes are mounted (e.g., `'/api/admin'`).
35
- * Used by the schema validation test to scope to fuz_app admin routes only,
36
- * avoiding app-specific admin-gated routes that may use stub deps.
37
- * Default `'/api/admin'`.
35
+ * Used by the 401/403 error-coverage probe to scope to fuz_app admin
36
+ * routes only, avoiding app-specific admin-gated routes that may use
37
+ * stub deps. Default `'/api/admin'`.
38
38
  */
39
39
  admin_prefix?: string;
40
40
  /** Optional overrides for `AppServerOptions`. */
@@ -49,8 +49,10 @@ export interface StandardAdminIntegrationTestOptions {
49
49
  * Standard admin integration test suite for fuz_app admin routes.
50
50
  *
51
51
  * Exercises account listing, permit grant/revoke (via RPC), session
52
- * management, token management, audit log routes, admin-to-admin isolation,
53
- * and response schema validation.
52
+ * management, token management, audit log reads, admin-to-admin
53
+ * isolation, and 401/403 error-coverage on the admin REST surface.
54
+ * Output-schema conformance is not in scope — see the module docstring
55
+ * for the suites that cover it.
54
56
  *
55
57
  * @param options - session config, route factory, role schema, RPC endpoints
56
58
  */
@@ -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,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"}
1
+ {"version":3,"file":"admin_integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/admin_integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA+B7B,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;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,mCAAmC,KAC1C,IAy1BF,CAAC"}