@fuzdev/fuz_app 0.38.1 → 0.40.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 (70) hide show
  1. package/dist/auth/CLAUDE.md +124 -36
  2. package/dist/auth/account_actions.d.ts +5 -3
  3. package/dist/auth/account_actions.d.ts.map +1 -1
  4. package/dist/auth/account_actions.js +5 -6
  5. package/dist/auth/account_routes.d.ts.map +1 -1
  6. package/dist/auth/account_routes.js +7 -7
  7. package/dist/auth/admin_action_specs.d.ts +6 -138
  8. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  9. package/dist/auth/admin_action_specs.js +4 -2
  10. package/dist/auth/admin_actions.d.ts +4 -3
  11. package/dist/auth/admin_actions.d.ts.map +1 -1
  12. package/dist/auth/admin_actions.js +8 -9
  13. package/dist/auth/audit_log_queries.d.ts +32 -20
  14. package/dist/auth/audit_log_queries.d.ts.map +1 -1
  15. package/dist/auth/audit_log_queries.js +52 -40
  16. package/dist/auth/audit_log_schema.d.ts +105 -84
  17. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  18. package/dist/auth/audit_log_schema.js +84 -12
  19. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  20. package/dist/auth/bootstrap_routes.js +3 -3
  21. package/dist/auth/cleanup.d.ts +9 -1
  22. package/dist/auth/cleanup.d.ts.map +1 -1
  23. package/dist/auth/cleanup.js +2 -2
  24. package/dist/auth/deps.d.ts +13 -1
  25. package/dist/auth/deps.d.ts.map +1 -1
  26. package/dist/auth/permit_offer_actions.d.ts +16 -2
  27. package/dist/auth/permit_offer_actions.d.ts.map +1 -1
  28. package/dist/auth/permit_offer_actions.js +26 -8
  29. package/dist/auth/role_schema.d.ts +10 -1
  30. package/dist/auth/role_schema.d.ts.map +1 -1
  31. package/dist/auth/role_schema.js +10 -1
  32. package/dist/auth/self_service_role_actions.d.ts +136 -0
  33. package/dist/auth/self_service_role_actions.d.ts.map +1 -0
  34. package/dist/auth/self_service_role_actions.js +198 -0
  35. package/dist/auth/signup_routes.d.ts.map +1 -1
  36. package/dist/auth/signup_routes.js +2 -2
  37. package/dist/auth/standard_rpc_actions.d.ts +1 -1
  38. package/dist/auth/standard_rpc_actions.js +1 -1
  39. package/dist/http/jsonrpc_errors.d.ts +27 -75
  40. package/dist/http/jsonrpc_errors.d.ts.map +1 -1
  41. package/dist/http/jsonrpc_errors.js +16 -9
  42. package/dist/server/app_backend.d.ts +26 -7
  43. package/dist/server/app_backend.d.ts.map +1 -1
  44. package/dist/server/app_backend.js +29 -7
  45. package/dist/server/app_server.d.ts +6 -7
  46. package/dist/server/app_server.d.ts.map +1 -1
  47. package/dist/server/app_server.js +16 -29
  48. package/dist/ui/AdminAccounts.svelte +19 -0
  49. package/dist/ui/AdminAccounts.svelte.d.ts +2 -17
  50. package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
  51. package/dist/ui/AdminPermitHistory.svelte +23 -2
  52. package/dist/ui/AdminPermitHistory.svelte.d.ts +2 -17
  53. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +1 -1
  54. package/dist/ui/CLAUDE.md +11 -0
  55. package/dist/ui/PermitOfferHistory.svelte +11 -5
  56. package/dist/ui/PermitOfferHistory.svelte.d.ts +7 -1
  57. package/dist/ui/PermitOfferHistory.svelte.d.ts.map +1 -1
  58. package/dist/ui/PermitOfferInbox.svelte +12 -7
  59. package/dist/ui/PermitOfferInbox.svelte.d.ts +8 -3
  60. package/dist/ui/PermitOfferInbox.svelte.d.ts.map +1 -1
  61. package/dist/ui/admin_rpc_adapters.d.ts +16 -1
  62. package/dist/ui/admin_rpc_adapters.d.ts.map +1 -1
  63. package/dist/ui/admin_rpc_adapters.js +12 -1
  64. package/dist/ui/format_scope.d.ts +45 -0
  65. package/dist/ui/format_scope.d.ts.map +1 -0
  66. package/dist/ui/format_scope.js +34 -0
  67. package/dist/ui/ui_format.d.ts +2 -3
  68. package/dist/ui/ui_format.d.ts.map +1 -1
  69. package/dist/ui/ui_format.js +1 -1
  70. package/package.json +1 -1
@@ -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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"}
@@ -16,8 +16,6 @@ import { SESSION_COOKIE_OPTIONS, } from '../auth/session_cookie.js';
16
16
  import { create_audit_log_sse, AUDIT_LOG_EVENT_SPECS, } from '../realtime/sse_auth_guard.js';
17
17
  import { query_app_settings_load } from '../auth/app_settings_queries.js';
18
18
  import { create_rate_limiter, DEFAULT_LOGIN_ACCOUNT_RATE_LIMIT, } from '../rate_limiter.js';
19
- import { run_migrations } from '../db/migrate.js';
20
- import { AUTH_MIGRATION_NAMESPACE } from '../auth/migrations.js';
21
19
  // Side-effect import: augments Hono's ContextVariableMap so consumers
22
20
  // that import app_server get type-safe c.get('auth_session_id') etc.
23
21
  import '../hono_context.js';
@@ -37,9 +35,10 @@ export const DEFAULT_MAX_BODY_SIZE = 1024 * 1024;
37
35
  /**
38
36
  * Create a fully assembled Hono app with auth, middleware, and routes.
39
37
  *
40
- * Handles the full lifecycle: consumer migrationsproxy middleware →
41
- * auth middleware → bootstrap status → route specs → surface generation →
42
- * Hono app assembly static serving.
38
+ * Handles the assembly lifecycle: proxy middlewareauth middleware →
39
+ * bootstrap status → route specs → surface generation → Hono app assembly →
40
+ * static serving. Database migrations belong to the backend lifecycle —
41
+ * pass `migration_namespaces` to `create_app_backend`.
43
42
  *
44
43
  * @param options - server configuration
45
44
  * @returns assembled Hono app, backend, surface build, and bootstrap status
@@ -47,19 +46,7 @@ export const DEFAULT_MAX_BODY_SIZE = 1024 * 1024;
47
46
  export const create_app_server = async (options) => {
48
47
  const { backend } = options;
49
48
  const { log } = backend.deps;
50
- // 1. Consumer migrations
51
- let all_migration_results = backend.migration_results;
52
- if (options.migration_namespaces?.length) {
53
- // guard against namespace collision with fuz_app's internal migrations
54
- for (const ns of options.migration_namespaces) {
55
- if (ns.namespace === AUTH_MIGRATION_NAMESPACE) {
56
- throw new Error(`Migration namespace "${AUTH_MIGRATION_NAMESPACE}" is reserved by fuz_app — choose a different namespace`);
57
- }
58
- }
59
- const consumer_results = await run_migrations(backend.deps.db, options.migration_namespaces);
60
- all_migration_results = [...backend.migration_results, ...consumer_results];
61
- }
62
- // 2. Rate limiter defaults (undefined = default, null = disable)
49
+ // Rate limiter defaults (undefined = default, null = disable)
63
50
  const ip_rate_limiter = options.ip_rate_limiter === undefined ? create_rate_limiter() : options.ip_rate_limiter;
64
51
  const login_account_rate_limiter = options.login_account_rate_limiter === undefined
65
52
  ? create_rate_limiter(DEFAULT_LOGIN_ACCOUNT_RATE_LIMIT)
@@ -70,7 +57,7 @@ export const create_app_server = async (options) => {
70
57
  const bearer_ip_rate_limiter = options.bearer_ip_rate_limiter === undefined
71
58
  ? create_rate_limiter()
72
59
  : options.bearer_ip_rate_limiter;
73
- // 3. Factory-managed audit SSE (shallow copy deps, no mutation of backend.deps)
60
+ // Factory-managed audit SSE (shallow copy deps, no mutation of backend.deps)
74
61
  const audit_sse = options.audit_log_sse
75
62
  ? create_audit_log_sse({
76
63
  log,
@@ -86,9 +73,9 @@ export const create_app_server = async (options) => {
86
73
  },
87
74
  }
88
75
  : backend.deps;
89
- // 4. Proxy middleware
76
+ // Proxy middleware
90
77
  const proxy_spec = create_proxy_middleware_spec({ ...options.proxy, log });
91
- // 5. Auth middleware
78
+ // Auth middleware
92
79
  const auth_middleware = await create_auth_middleware_specs(deps, {
93
80
  allowed_origins: options.allowed_origins,
94
81
  session_options: options.session_options,
@@ -99,16 +86,16 @@ export const create_app_server = async (options) => {
99
86
  if (options.transform_middleware) {
100
87
  middleware_specs = options.transform_middleware(middleware_specs);
101
88
  }
102
- // 6. Bootstrap status + app settings
89
+ // Bootstrap status + app settings
103
90
  const bootstrap_status = options.bootstrap
104
91
  ? await check_bootstrap_status(deps, { token_path: options.bootstrap.token_path })
105
92
  : { available: false, token_path: null };
106
93
  const app_settings = await query_app_settings_load({ db: deps.db });
107
- // 7. Surface route ref — factory manages the circular ref
94
+ // Surface route ref — factory manages the circular ref
108
95
  const surface_ref = {
109
96
  surface: { middleware: [], routes: [], rpc_endpoints: [], env: [], events: [], diagnostics: [] },
110
97
  };
111
- // 8. Route specs (consumer routes + factory-managed routes)
98
+ // Route specs (consumer routes + factory-managed routes)
112
99
  const context = {
113
100
  deps,
114
101
  backend,
@@ -149,7 +136,7 @@ export const create_app_server = async (options) => {
149
136
  factory_routes.push(create_surface_route_spec(surface_ref));
150
137
  }
151
138
  const route_specs = [...consumer_routes, ...factory_routes];
152
- // 9. Surface + logging
139
+ // Surface + logging
153
140
  const surface_middleware = options.post_route_middleware
154
141
  ? [...middleware_specs, ...options.post_route_middleware]
155
142
  : middleware_specs;
@@ -210,7 +197,7 @@ export const create_app_server = async (options) => {
210
197
  // Backfill the surface ref — factory owns this lifecycle
211
198
  surface_ref.surface = surface_spec.surface;
212
199
  log_startup_summary(surface_spec.surface, log, options.env_values);
213
- // 10. Hono app assembly
200
+ // Hono app assembly
214
201
  const app = new Hono();
215
202
  // Pending effects — collects fire-and-forget promises (audit logs, usage tracking).
216
203
  // In test mode, effects are awaited before the response returns.
@@ -255,11 +242,11 @@ export const create_app_server = async (options) => {
255
242
  }
256
243
  apply_middleware_specs(app, middleware_specs);
257
244
  apply_route_specs(app, route_specs, fuz_auth_guard_resolver, log, deps.db);
258
- // 11. Post-route middleware (before static serving)
245
+ // Post-route middleware (before static serving)
259
246
  if (options.post_route_middleware) {
260
247
  apply_middleware_specs(app, options.post_route_middleware);
261
248
  }
262
- // 12. Static file serving
249
+ // Static file serving
263
250
  if (options.static_serving) {
264
251
  const { serve_static, spa_fallback } = options.static_serving;
265
252
  for (const mw of create_static_middleware(serve_static, { spa_fallback })) {
@@ -271,7 +258,7 @@ export const create_app_server = async (options) => {
271
258
  surface_spec,
272
259
  bootstrap_status,
273
260
  app_settings,
274
- migration_results: all_migration_results,
261
+ migration_results: backend.migration_results,
275
262
  audit_sse,
276
263
  close: backend.close,
277
264
  };
@@ -5,9 +5,16 @@
5
5
  import type {DatatableColumn} from './datatable.js';
6
6
  import type {AdminAccountEntryJson} from '../auth/account_schema.js';
7
7
  import {format_relative_time, format_datetime_local} from './ui_format.js';
8
+ import {format_scope_context, resolve_scope_label} from './format_scope.js';
8
9
 
9
10
  const get_rpc = admin_accounts_rpc_context.get();
10
11
  const admin_accounts = new AdminAccountsState({get_rpc});
12
+ const get_format_scope = format_scope_context.get();
13
+ const format_scope = $derived(get_format_scope());
14
+
15
+ // `null` global label: global permits render no scope chip — the implicit default in admin tables.
16
+ const scope_label = (scope_id: string | null, role: string): string | null =>
17
+ resolve_scope_label(scope_id, role, format_scope, null);
11
18
 
12
19
  void admin_accounts.fetch();
13
20
 
@@ -57,8 +64,14 @@
57
64
  {/if}
58
65
  {:else if column.key === 'permits'}
59
66
  {#each row.permits as permit (permit.id)}
67
+ {@const scope = scope_label(permit.scope_id, permit.role)}
60
68
  <div class="row">
61
69
  <span class="chip color_b">{permit.role}</span>
70
+ {#if scope !== null}
71
+ <span class="text_50 font_size_sm" title={permit.scope_id ?? undefined}>
72
+ {scope}
73
+ </span>
74
+ {/if}
62
75
  {#if permit.expires_at}
63
76
  <span class="text_50 font_size_sm" title={format_datetime_local(permit.expires_at)}>
64
77
  expires {format_relative_time(permit.expires_at)}
@@ -80,6 +93,7 @@
80
93
  </div>
81
94
  {/each}
82
95
  {#each row.pending_offers as offer (offer.id)}
96
+ {@const offer_scope = scope_label(offer.scope_id, offer.role)}
83
97
  <div class="row">
84
98
  <span
85
99
  class="chip"
@@ -87,6 +101,11 @@
87
101
  >
88
102
  {offer.role} (pending from @{offer.from_username})
89
103
  </span>
104
+ {#if offer_scope !== null}
105
+ <span class="text_50 font_size_sm" title={offer.scope_id ?? undefined}>
106
+ {offer_scope}
107
+ </span>
108
+ {/if}
90
109
  {#if admin_accounts.has_rpc}
91
110
  <ConfirmButton
92
111
  onconfirm={() => admin_accounts.retract_offer(offer.id)}
@@ -1,19 +1,4 @@
1
- interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
- new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
- $$bindings?: Bindings;
4
- } & Exports;
5
- (internal: unknown, props: {
6
- $$events?: Events;
7
- $$slots?: Slots;
8
- }): Exports & {
9
- $set?: any;
10
- $on?: any;
11
- };
12
- z_$$bindings?: Bindings;
13
- }
14
- declare const AdminAccounts: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
- [evt: string]: CustomEvent<any>;
16
- }, {}, {}, string>;
17
- type AdminAccounts = InstanceType<typeof AdminAccounts>;
1
+ declare const AdminAccounts: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type AdminAccounts = ReturnType<typeof AdminAccounts>;
18
3
  export default AdminAccounts;
19
4
  //# sourceMappingURL=AdminAccounts.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdminAccounts.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/AdminAccounts.svelte"],"names":[],"mappings":"AAgIA,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,aAAa;;kBAA+E,CAAC;AACjF,KAAK,aAAa,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAC1D,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"AdminAccounts.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/AdminAccounts.svelte"],"names":[],"mappings":"AAoJA,QAAA,MAAM,aAAa,2DAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -4,19 +4,28 @@
4
4
  import Datatable from './Datatable.svelte';
5
5
  import type {DatatableColumn} from './datatable.js';
6
6
  import type {PermitHistoryEventJson} from '../auth/audit_log_schema.js';
7
+ import {format_scope_context, resolve_scope_label} from './format_scope.js';
7
8
 
8
9
  const get_rpc = audit_log_rpc_context.get();
9
10
  const audit_log = new AuditLogState({get_rpc});
11
+ const get_format_scope = format_scope_context.get();
12
+ const format_scope = $derived(get_format_scope());
10
13
 
11
14
  void audit_log.fetch_permit_history();
12
15
 
13
16
  const columns: Array<DatatableColumn<PermitHistoryEventJson>> = [
14
17
  {key: 'event_type', label: 'action', width: 100},
15
- {key: 'metadata', label: 'role', width: 100},
18
+ {key: 'metadata', label: 'role', width: 160},
16
19
  {key: 'username', label: 'by', width: 140},
17
20
  {key: 'target_username', label: 'target', width: 140},
18
21
  {key: 'created_at', label: 'time', width: 100},
19
22
  ];
23
+
24
+ // Metadata is `Record<string, unknown>`; narrow before reusing `resolve_scope_label`.
25
+ const scope_label_from_metadata = (scope_id: unknown, role: string): string | null => {
26
+ if (typeof scope_id !== 'string' || scope_id === '') return null;
27
+ return resolve_scope_label(scope_id, role, format_scope, null);
28
+ };
20
29
  </script>
21
30
 
22
31
  <section>
@@ -39,7 +48,19 @@
39
48
  </span>
40
49
  {:else if column.key === 'metadata'}
41
50
  {#if row.metadata}
42
- <code>{row.metadata.role ?? ''}</code>
51
+ {@const role = typeof row.metadata.role === 'string' ? row.metadata.role : ''}
52
+ <code>{role}</code>
53
+ {@const scope = scope_label_from_metadata(row.metadata.scope_id, role)}
54
+ {#if scope !== null}
55
+ <span
56
+ class="text_50 font_size_sm"
57
+ title={typeof row.metadata.scope_id === 'string'
58
+ ? row.metadata.scope_id
59
+ : undefined}
60
+ >
61
+ {scope}
62
+ </span>
63
+ {/if}
43
64
  {/if}
44
65
  {:else if column.key === 'username'}
45
66
  <span class="text_50">{row.username ?? truncate_uuid(row.account_id ?? '?')}</span>
@@ -1,19 +1,4 @@
1
- interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
- new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
- $$bindings?: Bindings;
4
- } & Exports;
5
- (internal: unknown, props: {
6
- $$events?: Events;
7
- $$slots?: Slots;
8
- }): Exports & {
9
- $set?: any;
10
- $on?: any;
11
- };
12
- z_$$bindings?: Bindings;
13
- }
14
- declare const AdminPermitHistory: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
- [evt: string]: CustomEvent<any>;
16
- }, {}, {}, string>;
17
- type AdminPermitHistory = InstanceType<typeof AdminPermitHistory>;
1
+ declare const AdminPermitHistory: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type AdminPermitHistory = ReturnType<typeof AdminPermitHistory>;
18
3
  export default AdminPermitHistory;
19
4
  //# sourceMappingURL=AdminPermitHistory.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdminPermitHistory.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/AdminPermitHistory.svelte"],"names":[],"mappings":"AAoEA,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,kBAAkB;;kBAA+E,CAAC;AACtF,KAAK,kBAAkB,GAAG,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACpE,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"AdminPermitHistory.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/AdminPermitHistory.svelte"],"names":[],"mappings":"AAuFA,QAAA,MAAM,kBAAkB,2DAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
package/dist/ui/CLAUDE.md CHANGED
@@ -303,6 +303,17 @@ provisioner pattern.
303
303
  directly. Consumed by `PermitOfferInbox`, `PermitOfferForm`,
304
304
  `PermitOfferHistory`. Wiring is ctor-bound (RPC + account/actor
305
305
  getters), so there's no separate `permit_offers_rpc_context`.
306
+ - `format_scope_context` — `() => FormatScope` (getter shape, matching
307
+ the RPC contexts above). `FormatScope = ({scope_id, role}) => string |
308
+ null`; default returns `null` so callers fall back to the raw uuid.
309
+ Provisioned by `provide_admin_rpc_contexts(adapters, {format_scope})`.
310
+ Consumed by `AdminAccounts`, `AdminPermitHistory`, `PermitOfferInbox`,
311
+ `PermitOfferHistory` via the `resolve_scope_label(scope_id, role,
312
+ format_scope, global_label)` helper — `global_label = null` renders no
313
+ chip (admin tables); `'global'` renders an explicit label (offer
314
+ surfaces). `PermitOfferInbox` / `PermitOfferHistory` accept a
315
+ `format_scope?: FormatScope` prop — same shape as the context, prop
316
+ wins when supplied.
306
317
  - `sidebar_state_context` — `() => SidebarState`. Provisioned by
307
318
  `AppShell`.
308
319
 
@@ -16,6 +16,7 @@
16
16
  import type {DatatableColumn} from './datatable.js';
17
17
  import {format_relative_time, format_datetime_local, truncate_uuid} from './ui_format.js';
18
18
  import type {PermitOfferJson} from '../auth/permit_offer_schema.js';
19
+ import {format_scope_context, resolve_scope_label, type FormatScope} from './format_scope.js';
19
20
 
20
21
  const {
21
22
  current_actor_id,
@@ -26,11 +27,18 @@
26
27
  /** Used to label a row as sent vs received. When `null`, direction shows as `-`. */
27
28
  current_actor_id: string | null;
28
29
  format_actor?: (from_actor_id: string) => string;
29
- format_scope?: (scope_id: string | null, role: string) => string;
30
+ /**
31
+ * Display label for an offer's scope. Bypasses `format_scope_context`
32
+ * when supplied — return `null` to fall back to a truncated uuid (or
33
+ * `'global'` for null scope_id). Omit to use the context value directly.
34
+ */
35
+ format_scope?: FormatScope;
30
36
  format_role?: (role: string) => string;
31
37
  } = $props();
32
38
 
33
39
  const permit_offers = permit_offers_state_context.get();
40
+ const get_format_scope = format_scope_context.get();
41
+ const format_scope_from_context = $derived(get_format_scope());
34
42
 
35
43
  const now = $state.raw(Date.now());
36
44
 
@@ -59,10 +67,8 @@
59
67
  }
60
68
  };
61
69
 
62
- const scope_label = (scope_id: string | null, role: string): string => {
63
- if (format_scope) return format_scope(scope_id, role);
64
- return scope_id === null ? 'global' : truncate_uuid(scope_id);
65
- };
70
+ const scope_label = (scope_id: string | null, role: string): string =>
71
+ resolve_scope_label(scope_id, role, format_scope ?? format_scope_from_context, 'global');
66
72
 
67
73
  const columns: Array<DatatableColumn<PermitOfferJson>> = [
68
74
  {key: 'from_actor_id', label: 'direction', width: 110},
@@ -1,8 +1,14 @@
1
+ import { type FormatScope } from './format_scope.js';
1
2
  type $$ComponentProps = {
2
3
  /** Used to label a row as sent vs received. When `null`, direction shows as `-`. */
3
4
  current_actor_id: string | null;
4
5
  format_actor?: (from_actor_id: string) => string;
5
- format_scope?: (scope_id: string | null, role: string) => string;
6
+ /**
7
+ * Display label for an offer's scope. Bypasses `format_scope_context`
8
+ * when supplied — return `null` to fall back to a truncated uuid (or
9
+ * `'global'` for null scope_id). Omit to use the context value directly.
10
+ */
11
+ format_scope?: FormatScope;
6
12
  format_role?: (role: string) => string;
7
13
  };
8
14
  declare const PermitOfferHistory: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -1 +1 @@
1
- {"version":3,"file":"PermitOfferHistory.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/PermitOfferHistory.svelte"],"names":[],"mappings":"AAoBC,KAAK,gBAAgB,GAAI;IACxB,oFAAoF;IACpF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACjE,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC,CAAC;AAiGH,QAAA,MAAM,kBAAkB,sDAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"PermitOfferHistory.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/PermitOfferHistory.svelte"],"names":[],"mappings":"AAmBA,OAAO,EAA4C,KAAK,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAE7F,KAAK,gBAAgB,GAAI;IACxB,oFAAoF;IACpF,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD;;;;OAIG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC,CAAC;AAkGH,QAAA,MAAM,kBAAkB,sDAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
@@ -16,6 +16,7 @@
16
16
  import ConfirmButton from './ConfirmButton.svelte';
17
17
  import {format_relative_time, format_datetime_local, truncate_uuid} from './ui_format.js';
18
18
  import {PERMIT_OFFER_MESSAGE_LENGTH_MAX} from '../auth/permit_offer_schema.js';
19
+ import {format_scope_context, resolve_scope_label, type FormatScope} from './format_scope.js';
19
20
 
20
21
  const {
21
22
  format_actor = truncate_uuid,
@@ -24,18 +25,22 @@
24
25
  }: {
25
26
  /** Display label for `from_actor_id`. Defaults to a truncated uuid. */
26
27
  format_actor?: (from_actor_id: string) => string;
27
- /** Display label for an offer's scope. Defaults to truncated uuid or "global" when `null`. */
28
- format_scope?: (scope_id: string | null, role: string) => string;
29
- /** Display label for a role constant. Defaults to identity (role name as stored). */
28
+ /**
29
+ * Display label for an offer's scope. Bypasses `format_scope_context`
30
+ * when supplied return `null` to fall back to a truncated uuid (or
31
+ * `'global'` for null scope_id). Omit to use the context value directly.
32
+ */
33
+ format_scope?: FormatScope;
34
+ /** Display label for a role constant. Defaults to identity. */
30
35
  format_role?: (role: string) => string;
31
36
  } = $props();
32
37
 
33
38
  const permit_offers = permit_offers_state_context.get();
39
+ const get_format_scope = format_scope_context.get();
40
+ const format_scope_from_context = $derived(get_format_scope());
34
41
 
35
- const scope_label = (scope_id: string | null, role: string): string => {
36
- if (format_scope) return format_scope(scope_id, role);
37
- return scope_id === null ? 'global' : truncate_uuid(scope_id);
38
- };
42
+ const scope_label = (scope_id: string | null, role: string): string =>
43
+ resolve_scope_label(scope_id, role, format_scope ?? format_scope_from_context, 'global');
39
44
 
40
45
  const decline_reasons: SvelteMap<string, string> = new SvelteMap();
41
46
  </script>
@@ -1,9 +1,14 @@
1
+ import { type FormatScope } from './format_scope.js';
1
2
  type $$ComponentProps = {
2
3
  /** Display label for `from_actor_id`. Defaults to a truncated uuid. */
3
4
  format_actor?: (from_actor_id: string) => string;
4
- /** Display label for an offer's scope. Defaults to truncated uuid or "global" when `null`. */
5
- format_scope?: (scope_id: string | null, role: string) => string;
6
- /** Display label for a role constant. Defaults to identity (role name as stored). */
5
+ /**
6
+ * Display label for an offer's scope. Bypasses `format_scope_context`
7
+ * when supplied return `null` to fall back to a truncated uuid (or
8
+ * `'global'` for null scope_id). Omit to use the context value directly.
9
+ */
10
+ format_scope?: FormatScope;
11
+ /** Display label for a role constant. Defaults to identity. */
7
12
  format_role?: (role: string) => string;
8
13
  };
9
14
  declare const PermitOfferInbox: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -1 +1 @@
1
- {"version":3,"file":"PermitOfferInbox.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/PermitOfferInbox.svelte"],"names":[],"mappings":"AAoBC,KAAK,gBAAgB,GAAI;IACxB,uEAAuE;IACvE,YAAY,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD,8FAA8F;IAC9F,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACjE,qFAAqF;IACrF,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC,CAAC;AA0FH,QAAA,MAAM,gBAAgB,sDAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"PermitOfferInbox.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/PermitOfferInbox.svelte"],"names":[],"mappings":"AAmBA,OAAO,EAA4C,KAAK,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAE7F,KAAK,gBAAgB,GAAI;IACxB,uEAAuE;IACvE,YAAY,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,CAAC;IACjD;;;;OAIG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC,CAAC;AA2FH,QAAA,MAAM,gBAAgB,sDAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
@@ -39,6 +39,7 @@ import { type AdminAccountsRpc } from './admin_accounts_state.svelte.js';
39
39
  import { type AdminInvitesRpc } from './admin_invites_state.svelte.js';
40
40
  import { type AuditLogRpc } from './audit_log_state.svelte.js';
41
41
  import { type AppSettingsRpc } from './app_settings_state.svelte.js';
42
+ import { type FormatScope } from './format_scope.js';
42
43
  /**
43
44
  * Function-shaped contract for dispatching an RPC call by method name.
44
45
  *
@@ -87,6 +88,14 @@ export interface AdminRpcAdapters {
87
88
  * admin surfaces they mount.
88
89
  */
89
90
  export declare const create_admin_rpc_adapters: (rpc_call: AdminRpcCall) => AdminRpcAdapters;
91
+ /** Optional knobs alongside the adapters when wiring admin contexts. */
92
+ export interface ProvideAdminRpcContextsOptions {
93
+ /**
94
+ * Render `{scope_id, role}` as a human label across permit-display
95
+ * components. Omit (or return `null`) to fall back to the raw uuid.
96
+ */
97
+ format_scope?: FormatScope;
98
+ }
90
99
  /**
91
100
  * Wire all four admin RPC contexts in a single call.
92
101
  *
@@ -98,6 +107,12 @@ export declare const create_admin_rpc_adapters: (rpc_call: AdminRpcCall) => Admi
98
107
  * mutating an adapter field on the same object propagates. Replacing the
99
108
  * whole adapter set requires calling `provide_admin_rpc_contexts` again
100
109
  * during init — in practice this is one-shot at layout mount.
110
+ *
111
+ * Pass `options.format_scope` to render permit/offer `scope_id` values as
112
+ * human labels across `AdminAccounts`, `AdminPermitHistory`,
113
+ * `PermitOfferInbox`, `PermitOfferForm`, and `PermitOfferHistory`.
114
+ * Components that accept a `format_scope` prop honor the prop first; the
115
+ * context is the fallback.
101
116
  */
102
- export declare const provide_admin_rpc_contexts: (adapters: AdminRpcAdapters) => void;
117
+ export declare const provide_admin_rpc_contexts: (adapters: AdminRpcAdapters, options?: ProvideAdminRpcContextsOptions) => void;
103
118
  //# sourceMappingURL=admin_rpc_adapters.d.ts.map
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
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;AAC7F,OAAO,EAAuB,KAAK,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAEzE;;;;;;;;;;;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,wEAAwE;AACxE,MAAM,WAAW,8BAA8B;IAC9C;;;OAGG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,0BAA0B,GACtC,UAAU,gBAAgB,EAC1B,UAAU,8BAA8B,KACtC,IASF,CAAC"}
@@ -38,6 +38,7 @@ import { admin_accounts_rpc_context } from './admin_accounts_state.svelte.js';
38
38
  import { admin_invites_rpc_context } from './admin_invites_state.svelte.js';
39
39
  import { audit_log_rpc_context } from './audit_log_state.svelte.js';
40
40
  import { app_settings_rpc_context } from './app_settings_state.svelte.js';
41
+ import { format_scope_context } from './format_scope.js';
41
42
  /**
42
43
  * Build the four admin RPC adapters from a single typed `rpc_call`.
43
44
  *
@@ -100,10 +101,20 @@ export const create_admin_rpc_adapters = (rpc_call) => ({
100
101
  * mutating an adapter field on the same object propagates. Replacing the
101
102
  * whole adapter set requires calling `provide_admin_rpc_contexts` again
102
103
  * during init — in practice this is one-shot at layout mount.
104
+ *
105
+ * Pass `options.format_scope` to render permit/offer `scope_id` values as
106
+ * human labels across `AdminAccounts`, `AdminPermitHistory`,
107
+ * `PermitOfferInbox`, `PermitOfferForm`, and `PermitOfferHistory`.
108
+ * Components that accept a `format_scope` prop honor the prop first; the
109
+ * context is the fallback.
103
110
  */
104
- export const provide_admin_rpc_contexts = (adapters) => {
111
+ export const provide_admin_rpc_contexts = (adapters, options) => {
105
112
  admin_accounts_rpc_context.set(() => adapters.admin_accounts);
106
113
  admin_invites_rpc_context.set(() => adapters.admin_invites);
107
114
  audit_log_rpc_context.set(() => adapters.audit_log);
108
115
  app_settings_rpc_context.set(() => adapters.app_settings);
116
+ if (options?.format_scope) {
117
+ const { format_scope } = options;
118
+ format_scope_context.set(() => format_scope);
119
+ }
109
120
  };
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Shared `format_scope` callback contract for permit-display components.
3
+ *
4
+ * Permits and offers carry a `scope_id` that names a consumer-owned resource
5
+ * (e.g. a classroom uuid). The default render is the raw uuid. Consumers wire
6
+ * a `FormatScope` via context to render a human label without per-page
7
+ * lookup or forking the components.
8
+ *
9
+ * @module
10
+ */
11
+ /**
12
+ * Render a `{scope_id, role}` pair as a human label. Return `null` to fall
13
+ * back to the raw scope uuid (or a caller-chosen `global_label` when
14
+ * `scope_id` is `null`).
15
+ *
16
+ * Returning `null` for unknown scope ids (stale cache, revoked resource) is
17
+ * the recommended pattern — components show the raw uuid rather than a
18
+ * misleading blank.
19
+ */
20
+ export type FormatScope = (args: {
21
+ scope_id: string | null;
22
+ role: string;
23
+ }) => string | null;
24
+ /** Default `FormatScope` — always returns `null` so callers fall back to the raw uuid. */
25
+ export declare const default_format_scope: FormatScope;
26
+ /**
27
+ * Svelte context carrying a getter for the consumer's `FormatScope`.
28
+ * Provisioned by `provide_admin_rpc_contexts` from its `format_scope` option.
29
+ * Default getter returns `default_format_scope` so unprovisioned trees render
30
+ * the raw uuid.
31
+ */
32
+ export declare const format_scope_context: {
33
+ get: () => () => FormatScope;
34
+ set: (value?: (() => FormatScope) | undefined) => () => FormatScope;
35
+ };
36
+ /**
37
+ * Resolve a scope label across the context → raw-uuid fallback chain.
38
+ *
39
+ * `global_label` is returned for `scope_id === null`. Callers pass `null`
40
+ * to render no chip (admin tables — global is the implicit default) or
41
+ * `'global'` for explicit labels (offer surfaces). The return type
42
+ * propagates `null` only when `global_label` is `null`.
43
+ */
44
+ export declare const resolve_scope_label: <G extends string | null>(scope_id: string | null, role: string, format_scope: FormatScope, global_label: G) => string | G;
45
+ //# sourceMappingURL=format_scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format_scope.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/format_scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,KAAK,MAAM,GAAG,IAAI,CAAC;AAE3F,0FAA0F;AAC1F,eAAO,MAAM,oBAAoB,EAAE,WAAwB,CAAC;AAE5D;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;qBAAwB,WAAW;yBAAX,WAAW,wBAAX,WAAW;CAEnE,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,MAAM,GAAG,IAAI,EAC1D,UAAU,MAAM,GAAG,IAAI,EACvB,MAAM,MAAM,EACZ,cAAc,WAAW,EACzB,cAAc,CAAC,KACb,MAAM,GAAG,CAGX,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Shared `format_scope` callback contract for permit-display components.
3
+ *
4
+ * Permits and offers carry a `scope_id` that names a consumer-owned resource
5
+ * (e.g. a classroom uuid). The default render is the raw uuid. Consumers wire
6
+ * a `FormatScope` via context to render a human label without per-page
7
+ * lookup or forking the components.
8
+ *
9
+ * @module
10
+ */
11
+ import { create_context } from '@fuzdev/fuz_ui/context_helpers.js';
12
+ import { truncate_uuid } from './ui_format.js';
13
+ /** Default `FormatScope` — always returns `null` so callers fall back to the raw uuid. */
14
+ export const default_format_scope = () => null;
15
+ /**
16
+ * Svelte context carrying a getter for the consumer's `FormatScope`.
17
+ * Provisioned by `provide_admin_rpc_contexts` from its `format_scope` option.
18
+ * Default getter returns `default_format_scope` so unprovisioned trees render
19
+ * the raw uuid.
20
+ */
21
+ export const format_scope_context = create_context(() => () => default_format_scope);
22
+ /**
23
+ * Resolve a scope label across the context → raw-uuid fallback chain.
24
+ *
25
+ * `global_label` is returned for `scope_id === null`. Callers pass `null`
26
+ * to render no chip (admin tables — global is the implicit default) or
27
+ * `'global'` for explicit labels (offer surfaces). The return type
28
+ * propagates `null` only when `global_label` is `null`.
29
+ */
30
+ export const resolve_scope_label = (scope_id, role, format_scope, global_label) => {
31
+ if (scope_id === null)
32
+ return global_label;
33
+ return format_scope({ scope_id, role }) ?? truncate_uuid(scope_id);
34
+ };
@@ -6,7 +6,6 @@
6
6
  *
7
7
  * @module
8
8
  */
9
- import type { AuditEventType } from '../auth/audit_log_schema.js';
10
9
  /**
11
10
  * Format a timestamp as a relative time string.
12
11
  *
@@ -55,9 +54,9 @@ export declare const format_datetime_local: (timestamp: string | number | Date)
55
54
  /**
56
55
  * Format audit event metadata for display based on event type.
57
56
  *
58
- * @param event_type - the audit event type
57
+ * @param event_type - the audit event type (builtin or consumer-registered)
59
58
  * @param metadata - the metadata object (may be null)
60
59
  * @returns human-readable summary string
61
60
  */
62
- export declare const format_audit_metadata: (event_type: AuditEventType, metadata: Record<string, unknown> | null) => string;
61
+ export declare const format_audit_metadata: (event_type: string, metadata: Record<string, unknown> | null) => string;
63
62
  //# sourceMappingURL=ui_format.d.ts.map