@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.
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +6 -1
- package/dist/actions/rpc_client.d.ts +23 -8
- package/dist/actions/rpc_client.d.ts.map +1 -1
- package/dist/actions/rpc_client.js +28 -9
- package/dist/auth/CLAUDE.md +28 -14
- package/dist/auth/standard_rpc_actions.d.ts +57 -0
- package/dist/auth/standard_rpc_actions.d.ts.map +1 -0
- package/dist/auth/standard_rpc_actions.js +39 -0
- package/dist/server/app_server.d.ts +1 -1
- package/dist/testing/CLAUDE.md +24 -5
- package/dist/testing/admin_integration.d.ts +8 -6
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +167 -146
- package/dist/testing/audit_completeness.d.ts.map +1 -1
- package/dist/testing/audit_completeness.js +34 -31
- package/dist/testing/integration.d.ts +3 -3
- package/dist/testing/integration.d.ts.map +1 -1
- package/dist/testing/integration.js +187 -124
- package/dist/testing/rpc_helpers.d.ts +4 -4
- package/dist/testing/rpc_helpers.js +3 -3
- package/dist/testing/schema_generators.d.ts.map +1 -1
- package/dist/testing/schema_generators.js +68 -1
- package/dist/ui/admin_rpc_adapters.d.ts +10 -1
- package/dist/ui/admin_rpc_adapters.d.ts.map +1 -1
- package/dist/ui/admin_rpc_adapters.js +10 -1
- package/package.json +1 -1
- package/dist/auth/admin_rpc_actions.d.ts +0 -49
- package/dist/auth/admin_rpc_actions.d.ts.map +0 -1
- package/dist/auth/admin_rpc_actions.js +0 -32
|
@@ -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,
|
|
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
|
-
|
|
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`
|
|
81
|
-
* `{code,
|
|
82
|
-
* `err.
|
|
83
|
-
*
|
|
84
|
-
*
|
|
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
|
-
*
|
|
94
|
-
*
|
|
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:
|
|
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
|
|
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`
|
|
175
|
-
* `{code,
|
|
176
|
-
* `err.
|
|
177
|
-
*
|
|
178
|
-
*
|
|
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
|
-
*
|
|
188
|
-
*
|
|
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 =
|
|
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'),
|
|
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
|
};
|
package/dist/auth/CLAUDE.md
CHANGED
|
@@ -836,20 +836,25 @@ Options:
|
|
|
836
836
|
`all_permit_offer_action_specs: Array<RequestResponseActionSpec>` —
|
|
837
837
|
codegen-ready registry.
|
|
838
838
|
|
|
839
|
-
### `
|
|
840
|
-
|
|
841
|
-
`
|
|
842
|
-
`create_admin_actions
|
|
843
|
-
`Array<RpcAction
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
`
|
|
850
|
-
|
|
851
|
-
`
|
|
852
|
-
|
|
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
|
-
* `
|
|
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`. */
|
package/dist/testing/CLAUDE.md
CHANGED
|
@@ -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
|
-
|
|
271
|
-
|
|
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. `
|
|
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 (`/
|
|
563
|
-
|
|
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
|
-
* `
|
|
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
|
|
36
|
-
* avoiding app-specific admin-gated routes that may use
|
|
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
|
|
53
|
-
* and
|
|
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;
|
|
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"}
|