@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.
@@ -11,7 +11,7 @@ import type { SessionOptions } from '../auth/session_cookie.js';
11
11
  * a factory that takes an `AppServerContext` and returns endpoint specs. The
12
12
  * factory form is required when action handlers must close over the
13
13
  * per-test `ctx.app_settings` / `ctx.deps` (e.g. the canonical
14
- * `create_admin_rpc_actions(ctx.deps, {app_settings: ctx.app_settings})`
14
+ * `create_standard_rpc_actions(ctx.deps, {app_settings: ctx.app_settings})`
15
15
  * pattern). `create_app_server` resolves either shape natively; test helpers
16
16
  * forward the raw value to `app_options.rpc_endpoints` for live dispatch.
17
17
  */
@@ -28,9 +28,9 @@ export type RpcEndpointsSuiteOption = Array<RpcEndpointSpec> | ((ctx: AppServerC
28
28
  *
29
29
  * Safe as long as the factory is pure with respect to the endpoint `path`
30
30
  * and the action `spec.method` list — the canonical helpers
31
- * (`create_admin_rpc_actions`, `create_account_actions`, etc.) are. Factories
32
- * that return a different `path` based on `ctx` will produce a setup/runtime
33
- * mismatch; don't do that.
31
+ * (`create_standard_rpc_actions`, `create_admin_actions`, `create_account_actions`,
32
+ * etc.) are. Factories that return a different `path` based on `ctx` will
33
+ * produce a setup/runtime mismatch; don't do that.
34
34
  */
35
35
  export declare const resolve_rpc_endpoints_for_setup: (rpc_endpoints: RpcEndpointsSuiteOption, session_options: SessionOptions<string>) => Array<RpcEndpointSpec>;
36
36
  /**
@@ -24,9 +24,9 @@ import { create_stub_app_server_context } from './stubs.js';
24
24
  *
25
25
  * Safe as long as the factory is pure with respect to the endpoint `path`
26
26
  * and the action `spec.method` list — the canonical helpers
27
- * (`create_admin_rpc_actions`, `create_account_actions`, etc.) are. Factories
28
- * that return a different `path` based on `ctx` will produce a setup/runtime
29
- * mismatch; don't do that.
27
+ * (`create_standard_rpc_actions`, `create_admin_actions`, `create_account_actions`,
28
+ * etc.) are. Factories that return a different `path` based on `ctx` will
29
+ * produce a setup/runtime mismatch; don't do that.
30
30
  */
31
31
  export const resolve_rpc_endpoints_for_setup = (rpc_endpoints, session_options) => typeof rpc_endpoints === 'function'
32
32
  ? rpc_endpoints(create_stub_app_server_context(session_options))
@@ -1 +1 @@
1
- {"version":3,"file":"schema_generators.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/schema_generators.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,yBAAyB,CAAC;AAIjC;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,MAAM,GAAG,IAShE,CAAC;AA+BF,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,GAAI,OAAO,YAAY,EAAE,cAAc,CAAC,CAAC,OAAO,KAAG,OAkDnF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,gBAAgB,CAAC,CAAC,SAAS,KAAG,MAa9E,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC/B,cAAc,CAAC,CAAC,OAAO,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAkB5B,CAAC"}
1
+ {"version":3,"file":"schema_generators.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/schema_generators.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,yBAAyB,CAAC;AAIjC;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,MAAM,GAAG,IAShE,CAAC;AA+FF,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,GAAI,OAAO,YAAY,EAAE,cAAc,CAAC,CAAC,OAAO,KAAG,OAkDnF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,gBAAgB,CAAC,CAAC,SAAS,KAAG,MAa9E,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC/B,cAAc,CAAC,CAAC,OAAO,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAkB5B,CAAC"}
@@ -28,16 +28,71 @@ export const detect_format = (field_schema) => {
28
28
  }
29
29
  return null;
30
30
  };
31
- /** Generate a string that satisfies minLength/maxLength constraints via JSON Schema. */
31
+ /**
32
+ * Extract a candidate value from a JSON Schema `pattern` when the shape is
33
+ * a fixed-length hex character class — covers blake3 (64-char lowercase hex),
34
+ * sha256, md5, and similar digest refinements. Returns `null` when the
35
+ * pattern doesn't match the expected shape.
36
+ */
37
+ const generate_hex_pattern_value = (pattern) => {
38
+ const match = /^\^\[0-9a-f(?:A-F)?\]\{(\d+)\}\$$/.exec(pattern);
39
+ if (!match)
40
+ return null;
41
+ const n = Number(match[1]);
42
+ if (!Number.isInteger(n) || n <= 0)
43
+ return null;
44
+ return '0'.repeat(n);
45
+ };
46
+ /**
47
+ * Extract a candidate value from a JSON Schema `pattern` when the shape is a
48
+ * prefix-lengthed slug — a fixed literal prefix followed by `_` and a
49
+ * base64url-style character class of fixed length. Covers `ApiTokenId`
50
+ * (`tok_[A-Za-z0-9_-]{12}`) and any similarly-shaped branded id.
51
+ *
52
+ * Returns the prefix followed by the right number of `x` characters (which
53
+ * satisfy every base64url-style character class). Returns `null` when the
54
+ * pattern doesn't match the expected shape.
55
+ *
56
+ * Coverage today:
57
+ * - Prefix must start with a letter and be alphanumeric (e.g. `tok_`, `ses_`).
58
+ * - Character class must be exactly `[A-Za-z0-9_-]` (Zod passes the regex
59
+ * source through verbatim — no character-class reordering).
60
+ * - Fixed-length quantifier `{N}`.
61
+ *
62
+ * Known gaps (will fall through to the absolute-path / URL candidates or
63
+ * the base `xxxxxxxxxx` string — may or may not satisfy the refinement):
64
+ * - Digit-only classes (e.g. `^ord_\d{8}$`) — `x`-fill fails.
65
+ * - Base64 with `+/=` (e.g. `^b64_[A-Za-z0-9+/=]{N}$`) — character class
66
+ * doesn't match the detection regex. `x`-fill would still satisfy the
67
+ * refinement if the detection were widened.
68
+ * - No-prefix fixed-length slugs (e.g. `^[A-Za-z0-9_-]{43}$` — daemon
69
+ * token shape) are not matched here; see `generate_hex_pattern_value`
70
+ * for the hex variant.
71
+ * Widen the detection regex when a new branded shape surfaces.
72
+ */
73
+ const generate_prefix_slug_pattern_value = (pattern) => {
74
+ const match = /^\^([A-Za-z][A-Za-z0-9]*)_\[A-Za-z0-9_-\]\{(\d+)\}\$$/.exec(pattern);
75
+ if (!match)
76
+ return null;
77
+ const prefix = match[1];
78
+ const n = Number(match[2]);
79
+ if (!Number.isInteger(n) || n <= 0)
80
+ return null;
81
+ return `${prefix}_${'x'.repeat(n)}`;
82
+ };
83
+ /** Generate a string that satisfies minLength/maxLength/pattern constraints via JSON Schema. */
32
84
  const generate_valid_string = (field_schema) => {
33
85
  let min_length = 0;
34
86
  let max_length = Infinity;
87
+ let pattern = null;
35
88
  try {
36
89
  const json = z.toJSONSchema(field_schema);
37
90
  if (typeof json.minLength === 'number')
38
91
  min_length = json.minLength;
39
92
  if (typeof json.maxLength === 'number')
40
93
  max_length = json.maxLength;
94
+ if (typeof json.pattern === 'string')
95
+ pattern = json.pattern;
41
96
  }
42
97
  catch {
43
98
  // no constraints
@@ -48,6 +103,18 @@ const generate_valid_string = (field_schema) => {
48
103
  // If the base string fails, try common patterns before giving up.
49
104
  if (field_schema.safeParse(base).success)
50
105
  return base;
106
+ // Fixed-length hex refinement (blake3, sha256, etc.)
107
+ if (pattern) {
108
+ const hex = generate_hex_pattern_value(pattern);
109
+ if (hex !== null && field_schema.safeParse(hex).success)
110
+ return hex;
111
+ }
112
+ // Prefix-lengthed slug refinement (e.g. ApiTokenId: tok_[A-Za-z0-9_-]{12})
113
+ if (pattern) {
114
+ const slug = generate_prefix_slug_pattern_value(pattern);
115
+ if (slug !== null && field_schema.safeParse(slug).success)
116
+ return slug;
117
+ }
51
118
  // Absolute path refinement (e.g. DiskfilePath)
52
119
  const with_slash = '/' + base;
53
120
  if (field_schema.safeParse(with_slash).success)
@@ -4,7 +4,16 @@
4
4
  * Bridges a typed `rpc_call`-shaped function to the four narrow admin RPC
5
5
  * interfaces the state classes consume — `AdminAccountsRpc`,
6
6
  * `AdminInvitesRpc`, `AuditLogRpc`, `AppSettingsRpc`. Two calls at the
7
- * admin shell layout wire everything:
7
+ * admin shell layout wire everything.
8
+ *
9
+ * Intentionally admin-only despite the backend-side
10
+ * `create_standard_rpc_actions` rename (admin + permit-offer + account).
11
+ * Account-surface methods flow through `account_sessions_rpc_context`
12
+ * (wired at the self-service layout), and permit-offer methods that
13
+ * surface in the admin UI (`permit_offer_create`, `permit_revoke`,
14
+ * `permit_offer_retract`) live inside the `AdminAccountsRpc` interface —
15
+ * they belong to the admin UX, not a separate wire pairing. The UI side
16
+ * and backend factory names diverge by design.
8
17
  *
9
18
  * ```ts
10
19
  * import {create_throwing_rpc_call} from '@fuzdev/fuz_app/actions/rpc_client.js';
@@ -1 +1 @@
1
- {"version":3,"file":"admin_rpc_adapters.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/admin_rpc_adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAA6B,KAAK,gBAAgB,EAAC,MAAM,kCAAkC,CAAC;AACnG,OAAO,EAA4B,KAAK,eAAe,EAAC,MAAM,iCAAiC,CAAC;AAChG,OAAO,EAAwB,KAAK,WAAW,EAAC,MAAM,6BAA6B,CAAC;AACpF,OAAO,EAA2B,KAAK,cAAc,EAAC,MAAM,gCAAgC,CAAC;AAE7F;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GAAG,eAAe,CAAC;AAE3C,sEAAsE;AACtE,MAAM,WAAW,gBAAgB;IAChC,cAAc,EAAE,gBAAgB,CAAC;IACjC,aAAa,EAAE,eAAe,CAAC;IAC/B,SAAS,EAAE,WAAW,CAAC;IACvB,YAAY,EAAE,cAAc,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,yBAAyB,GAAI,UAAU,YAAY,KAAG,gBAuBjE,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0BAA0B,GAAI,UAAU,gBAAgB,KAAG,IAKvE,CAAC"}
1
+ {"version":3,"file":"admin_rpc_adapters.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/admin_rpc_adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAA6B,KAAK,gBAAgB,EAAC,MAAM,kCAAkC,CAAC;AACnG,OAAO,EAA4B,KAAK,eAAe,EAAC,MAAM,iCAAiC,CAAC;AAChG,OAAO,EAAwB,KAAK,WAAW,EAAC,MAAM,6BAA6B,CAAC;AACpF,OAAO,EAA2B,KAAK,cAAc,EAAC,MAAM,gCAAgC,CAAC;AAE7F;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GAAG,eAAe,CAAC;AAE3C,sEAAsE;AACtE,MAAM,WAAW,gBAAgB;IAChC,cAAc,EAAE,gBAAgB,CAAC;IACjC,aAAa,EAAE,eAAe,CAAC;IAC/B,SAAS,EAAE,WAAW,CAAC;IACvB,YAAY,EAAE,cAAc,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,yBAAyB,GAAI,UAAU,YAAY,KAAG,gBAuBjE,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0BAA0B,GAAI,UAAU,gBAAgB,KAAG,IAKvE,CAAC"}
@@ -4,7 +4,16 @@
4
4
  * Bridges a typed `rpc_call`-shaped function to the four narrow admin RPC
5
5
  * interfaces the state classes consume — `AdminAccountsRpc`,
6
6
  * `AdminInvitesRpc`, `AuditLogRpc`, `AppSettingsRpc`. Two calls at the
7
- * admin shell layout wire everything:
7
+ * admin shell layout wire everything.
8
+ *
9
+ * Intentionally admin-only despite the backend-side
10
+ * `create_standard_rpc_actions` rename (admin + permit-offer + account).
11
+ * Account-surface methods flow through `account_sessions_rpc_context`
12
+ * (wired at the self-service layout), and permit-offer methods that
13
+ * surface in the admin UI (`permit_offer_create`, `permit_revoke`,
14
+ * `permit_offer_retract`) live inside the `AdminAccountsRpc` interface —
15
+ * they belong to the admin UX, not a separate wire pairing. The UI side
16
+ * and backend factory names diverge by design.
8
17
  *
9
18
  * ```ts
10
19
  * import {create_throwing_rpc_call} from '@fuzdev/fuz_app/actions/rpc_client.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzdev/fuz_app",
3
- "version": "0.33.0",
3
+ "version": "0.35.0",
4
4
  "description": "fullstack app library",
5
5
  "glyph": "🗝",
6
6
  "logo": "logo.svg",
@@ -1,49 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,32 +0,0 @@
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
- ];