@fuzdev/fuz_app 0.67.1 → 0.68.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 (164) hide show
  1. package/dist/auth/CLAUDE.md +99 -5
  2. package/dist/auth/account_queries.d.ts +87 -4
  3. package/dist/auth/account_queries.d.ts.map +1 -1
  4. package/dist/auth/account_queries.js +107 -17
  5. package/dist/auth/account_schema.d.ts +19 -0
  6. package/dist/auth/account_schema.d.ts.map +1 -1
  7. package/dist/auth/account_schema.js +8 -0
  8. package/dist/auth/admin_action_specs.d.ts +168 -0
  9. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  10. package/dist/auth/admin_action_specs.js +146 -1
  11. package/dist/auth/admin_actions.d.ts.map +1 -1
  12. package/dist/auth/admin_actions.js +218 -4
  13. package/dist/auth/audit_log_ddl.d.ts +10 -1
  14. package/dist/auth/audit_log_ddl.d.ts.map +1 -1
  15. package/dist/auth/audit_log_ddl.js +13 -4
  16. package/dist/auth/audit_log_schema.d.ts +34 -1
  17. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  18. package/dist/auth/audit_log_schema.js +73 -0
  19. package/dist/auth/auth_ddl.d.ts +2 -2
  20. package/dist/auth/auth_ddl.d.ts.map +1 -1
  21. package/dist/auth/auth_ddl.js +10 -2
  22. package/dist/auth/cell_action_specs.d.ts +1295 -0
  23. package/dist/auth/cell_action_specs.d.ts.map +1 -0
  24. package/dist/auth/cell_action_specs.js +397 -0
  25. package/dist/auth/cell_actions.d.ts +63 -0
  26. package/dist/auth/cell_actions.d.ts.map +1 -0
  27. package/dist/auth/cell_actions.js +546 -0
  28. package/dist/auth/cell_audit_action_specs.d.ts +131 -0
  29. package/dist/auth/cell_audit_action_specs.d.ts.map +1 -0
  30. package/dist/auth/cell_audit_action_specs.js +70 -0
  31. package/dist/auth/cell_audit_actions.d.ts +18 -0
  32. package/dist/auth/cell_audit_actions.d.ts.map +1 -0
  33. package/dist/auth/cell_audit_actions.js +59 -0
  34. package/dist/auth/cell_audit_events.d.ts +28 -0
  35. package/dist/auth/cell_audit_events.d.ts.map +1 -0
  36. package/dist/auth/cell_audit_events.js +42 -0
  37. package/dist/auth/cell_audit_metadata.d.ts +48 -0
  38. package/dist/auth/cell_audit_metadata.d.ts.map +1 -0
  39. package/dist/auth/cell_audit_metadata.js +46 -0
  40. package/dist/auth/cell_authorize.d.ts +88 -0
  41. package/dist/auth/cell_authorize.d.ts.map +1 -0
  42. package/dist/auth/cell_authorize.js +172 -0
  43. package/dist/auth/cell_data_schema.d.ts +44 -0
  44. package/dist/auth/cell_data_schema.d.ts.map +1 -0
  45. package/dist/auth/cell_data_schema.js +42 -0
  46. package/dist/auth/cell_field_action_specs.d.ts +244 -0
  47. package/dist/auth/cell_field_action_specs.d.ts.map +1 -0
  48. package/dist/auth/cell_field_action_specs.js +136 -0
  49. package/dist/auth/cell_field_actions.d.ts +34 -0
  50. package/dist/auth/cell_field_actions.d.ts.map +1 -0
  51. package/dist/auth/cell_field_actions.js +153 -0
  52. package/dist/auth/cell_field_audit_metadata.d.ts +30 -0
  53. package/dist/auth/cell_field_audit_metadata.d.ts.map +1 -0
  54. package/dist/auth/cell_field_audit_metadata.js +28 -0
  55. package/dist/auth/cell_grant_action_specs.d.ts +333 -0
  56. package/dist/auth/cell_grant_action_specs.d.ts.map +1 -0
  57. package/dist/auth/cell_grant_action_specs.js +148 -0
  58. package/dist/auth/cell_grant_actions.d.ts +50 -0
  59. package/dist/auth/cell_grant_actions.d.ts.map +1 -0
  60. package/dist/auth/cell_grant_actions.js +208 -0
  61. package/dist/auth/cell_grant_audit_metadata.d.ts +75 -0
  62. package/dist/auth/cell_grant_audit_metadata.d.ts.map +1 -0
  63. package/dist/auth/cell_grant_audit_metadata.js +54 -0
  64. package/dist/auth/cell_item_action_specs.d.ts +331 -0
  65. package/dist/auth/cell_item_action_specs.d.ts.map +1 -0
  66. package/dist/auth/cell_item_action_specs.js +182 -0
  67. package/dist/auth/cell_item_actions.d.ts +37 -0
  68. package/dist/auth/cell_item_actions.d.ts.map +1 -0
  69. package/dist/auth/cell_item_actions.js +204 -0
  70. package/dist/auth/cell_item_audit_metadata.d.ts +35 -0
  71. package/dist/auth/cell_item_audit_metadata.d.ts.map +1 -0
  72. package/dist/auth/cell_item_audit_metadata.js +32 -0
  73. package/dist/auth/cell_relation_visibility.d.ts +32 -0
  74. package/dist/auth/cell_relation_visibility.d.ts.map +1 -0
  75. package/dist/auth/cell_relation_visibility.js +57 -0
  76. package/dist/auth/deps.d.ts +9 -0
  77. package/dist/auth/deps.d.ts.map +1 -1
  78. package/dist/auth/role_grant_queries.d.ts +30 -0
  79. package/dist/auth/role_grant_queries.d.ts.map +1 -1
  80. package/dist/auth/role_grant_queries.js +54 -0
  81. package/dist/db/CLAUDE.md +118 -0
  82. package/dist/db/cell_audit_queries.d.ts +26 -0
  83. package/dist/db/cell_audit_queries.d.ts.map +1 -0
  84. package/dist/db/cell_audit_queries.js +53 -0
  85. package/dist/db/cell_ddl.d.ts +151 -0
  86. package/dist/db/cell_ddl.d.ts.map +1 -0
  87. package/dist/db/cell_ddl.js +247 -0
  88. package/dist/db/cell_field_queries.d.ts +105 -0
  89. package/dist/db/cell_field_queries.d.ts.map +1 -0
  90. package/dist/db/cell_field_queries.js +113 -0
  91. package/dist/db/cell_grant_queries.d.ts +132 -0
  92. package/dist/db/cell_grant_queries.d.ts.map +1 -0
  93. package/dist/db/cell_grant_queries.js +145 -0
  94. package/dist/db/cell_history_ddl.d.ts +38 -0
  95. package/dist/db/cell_history_ddl.d.ts.map +1 -0
  96. package/dist/db/cell_history_ddl.js +61 -0
  97. package/dist/db/cell_item_queries.d.ts +107 -0
  98. package/dist/db/cell_item_queries.d.ts.map +1 -0
  99. package/dist/db/cell_item_queries.js +119 -0
  100. package/dist/db/cell_queries.d.ts +327 -0
  101. package/dist/db/cell_queries.d.ts.map +1 -0
  102. package/dist/db/cell_queries.js +431 -0
  103. package/dist/db/fact_ddl.d.ts +38 -0
  104. package/dist/db/fact_ddl.d.ts.map +1 -0
  105. package/dist/db/fact_ddl.js +71 -0
  106. package/dist/db/fact_queries.d.ts +140 -0
  107. package/dist/db/fact_queries.d.ts.map +1 -0
  108. package/dist/db/fact_queries.js +161 -0
  109. package/dist/db/fact_store.d.ts +112 -0
  110. package/dist/db/fact_store.d.ts.map +1 -0
  111. package/dist/db/fact_store.js +225 -0
  112. package/dist/server/env.d.ts +2 -0
  113. package/dist/server/env.d.ts.map +1 -1
  114. package/dist/server/env.js +6 -0
  115. package/dist/server/fact_write.d.ts +32 -0
  116. package/dist/server/fact_write.d.ts.map +1 -0
  117. package/dist/server/fact_write.js +56 -0
  118. package/dist/server/file_fact_fetcher.d.ts +42 -0
  119. package/dist/server/file_fact_fetcher.d.ts.map +1 -0
  120. package/dist/server/file_fact_fetcher.js +60 -0
  121. package/dist/server/file_fact_url.d.ts +53 -0
  122. package/dist/server/file_fact_url.d.ts.map +1 -0
  123. package/dist/server/file_fact_url.js +52 -0
  124. package/dist/server/serve_fact_route.d.ts +78 -0
  125. package/dist/server/serve_fact_route.d.ts.map +1 -0
  126. package/dist/server/serve_fact_route.js +205 -0
  127. package/dist/testing/CLAUDE.md +58 -5
  128. package/dist/testing/app_server.d.ts +12 -0
  129. package/dist/testing/app_server.d.ts.map +1 -1
  130. package/dist/testing/app_server.js +36 -2
  131. package/dist/testing/audit_completeness.d.ts.map +1 -1
  132. package/dist/testing/audit_completeness.js +67 -1
  133. package/dist/testing/cross_backend/account_lifecycle.d.ts +10 -0
  134. package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -0
  135. package/dist/testing/cross_backend/account_lifecycle.js +76 -0
  136. package/dist/testing/cross_backend/capabilities.d.ts +31 -0
  137. package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
  138. package/dist/testing/cross_backend/capabilities.js +3 -0
  139. package/dist/testing/cross_backend/cell_cross_helpers.d.ts +39 -0
  140. package/dist/testing/cross_backend/cell_cross_helpers.d.ts.map +1 -0
  141. package/dist/testing/cross_backend/cell_cross_helpers.js +45 -0
  142. package/dist/testing/cross_backend/cell_crud.d.ts +4 -0
  143. package/dist/testing/cross_backend/cell_crud.d.ts.map +1 -0
  144. package/dist/testing/cross_backend/cell_crud.js +168 -0
  145. package/dist/testing/cross_backend/cell_relations.d.ts +4 -0
  146. package/dist/testing/cross_backend/cell_relations.d.ts.map +1 -0
  147. package/dist/testing/cross_backend/cell_relations.js +229 -0
  148. package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
  149. package/dist/testing/cross_backend/default_backend_configs.js +6 -0
  150. package/dist/testing/cross_backend/setup.d.ts.map +1 -1
  151. package/dist/testing/cross_backend/setup.js +5 -0
  152. package/dist/testing/entities.d.ts.map +1 -1
  153. package/dist/testing/entities.js +4 -0
  154. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  155. package/dist/testing/ws_round_trip.js +4 -0
  156. package/dist/ui/AdminAccounts.svelte +58 -0
  157. package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
  158. package/dist/ui/admin_accounts_state.svelte.d.ts +30 -2
  159. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  160. package/dist/ui/admin_accounts_state.svelte.js +45 -1
  161. package/dist/ui/admin_rpc_adapters.d.ts +6 -2
  162. package/dist/ui/admin_rpc_adapters.d.ts.map +1 -1
  163. package/dist/ui/admin_rpc_adapters.js +5 -1
  164. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cell_audit_action_specs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_audit_action_specs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAMtB;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;kBAO7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,2EAA2E;AAC3E,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAEhD,eAAO,MAAM,kBAAkB;;;kBAG7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;kBAE9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAWH,CAAC;AAEtC,+DAA+D;AAC/D,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAyC,CAAC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * `cell_audit_list` RPC — per-cell audit timeline.
3
+ *
4
+ * Returns audit-log rows whose metadata names this cell on any of the
5
+ * `(cell_id, source_id, parent_id, child_id, target_id, new_id)` keys
6
+ * used by the cell-domain event types. The handler 404-masks for
7
+ * callers who are not in the cell's manage tier (`can_manage_cell` =
8
+ * admin / owner) — the timeline reveals who-touched-the-cell, so it is
9
+ * gated above `can_view_cell`.
10
+ *
11
+ * Read-only; no audit side effect. Returns the most-recent
12
+ * `CELL_AUDIT_LIST_DEFAULT_LIMIT` events; pagination is intentionally
13
+ * not on the wire yet — the only consumer renders a single page. Add
14
+ * `{before, limit}` input + `{next_before}` output together when a
15
+ * paginating consumer surfaces.
16
+ *
17
+ * @module
18
+ */
19
+ import { z } from 'zod';
20
+ import { Uuid } from '@fuzdev/fuz_util/id.js';
21
+ import { ActingActor } from '../http/auth_shape.js';
22
+ /**
23
+ * Wire shape for a single cell-audit row. Narrower than
24
+ * `AuditLogEventJson` — `account_id` and `target_account_id` are
25
+ * deliberately omitted so this verb does NOT surface the actor↔account
26
+ * join. `target_actor_id` and `metadata` are dropped too: `target_actor_id`
27
+ * is NULL for every cell-domain event (the grant recipient lives inside
28
+ * `metadata.principal` on grant rows, not on the audit-log top-level
29
+ * field); `metadata` is unread by the timeline UI.
30
+ *
31
+ * `ip` is also omitted: it is PII about the actors who touched the cell,
32
+ * and even at the manage tier this per-cell timeline has no need for it
33
+ * (admins reach the full `audit_log` surface, which carries `ip`, through
34
+ * the admin audit verbs). Keeping it off this wire avoids leaking
35
+ * collaborators' IPs to a cell's owner.
36
+ *
37
+ * All omitted fields can be re-added under a richer admin-only
38
+ * event-detail view later — keep the wire surface honest about what
39
+ * consumers use.
40
+ */
41
+ export const CellAuditEventJson = z.strictObject({
42
+ id: Uuid,
43
+ seq: z.number(),
44
+ event_type: z.string(),
45
+ outcome: z.enum(['success', 'failure']),
46
+ actor_id: Uuid.nullable(),
47
+ created_at: z.string(),
48
+ });
49
+ /** Page size for `cell_audit_list`. Single page at MVP; no cursor wire. */
50
+ export const CELL_AUDIT_LIST_DEFAULT_LIMIT = 50;
51
+ export const CellAuditListInput = z.strictObject({
52
+ cell_id: Uuid.meta({ description: 'Cell whose audit trail to fetch.' }),
53
+ acting: ActingActor,
54
+ });
55
+ export const CellAuditListOutput = z.strictObject({
56
+ events: z.array(CellAuditEventJson),
57
+ });
58
+ export const cell_audit_list_action_spec = {
59
+ method: 'cell_audit_list',
60
+ kind: 'request_response',
61
+ initiator: 'frontend',
62
+ auth: { account: 'required', actor: 'required' },
63
+ side_effects: false,
64
+ input: CellAuditListInput,
65
+ output: CellAuditListOutput,
66
+ async: true,
67
+ description: 'List the most-recent audit events referencing the cell on any of `cell_id`, `source_id`, `parent_id`, `child_id`, `target_id`, or `new_id` metadata keys. Manage-tier only (admin / owner) — the timeline reveals who touched the cell, so viewers and editors get the IDOR-mask 404. 404 on miss or unauthorized — same shape as `cell_get` so private-cell existence does not leak.',
68
+ };
69
+ /** Registry export to compose into `all_cell_action_specs`. */
70
+ export const all_cell_audit_action_specs = [cell_audit_list_action_spec];
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `cell_audit_list` handler — per-cell audit timeline read.
3
+ *
4
+ * Authz is **manage-tier** (`can_manage_cell` = admin / owner), NOT
5
+ * `can_view_cell`. The timeline surfaces the `actor_id` of every account
6
+ * that touched the cell (including via `cell_field` / `cell_item` / clone
7
+ * edges where the cell is the target / child / source); exposing that to
8
+ * mere viewers — or, for a public cell, to any authenticated caller —
9
+ * leaks who-touched-what. Gating to admin / owner mirrors
10
+ * `cell_grant_list` ("the audit trail is the manager's to read"). Misses +
11
+ * unauthorized reads both 404 with `cell_not_found` — private-cell
12
+ * existence stays masked. No audit side effect (read-only).
13
+ *
14
+ * @module
15
+ */
16
+ import { type RpcAction } from '../actions/action_rpc.js';
17
+ export declare const create_cell_audit_actions: () => Array<RpcAction>;
18
+ //# sourceMappingURL=cell_audit_actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cell_audit_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_audit_actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAsC,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAgC7F,eAAO,MAAM,yBAAyB,QAAO,KAAK,CAAC,SAAS,CA0B3D,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * `cell_audit_list` handler — per-cell audit timeline read.
3
+ *
4
+ * Authz is **manage-tier** (`can_manage_cell` = admin / owner), NOT
5
+ * `can_view_cell`. The timeline surfaces the `actor_id` of every account
6
+ * that touched the cell (including via `cell_field` / `cell_item` / clone
7
+ * edges where the cell is the target / child / source); exposing that to
8
+ * mere viewers — or, for a public cell, to any authenticated caller —
9
+ * leaks who-touched-what. Gating to admin / owner mirrors
10
+ * `cell_grant_list` ("the audit trail is the manager's to read"). Misses +
11
+ * unauthorized reads both 404 with `cell_not_found` — private-cell
12
+ * existence stays masked. No audit side effect (read-only).
13
+ *
14
+ * @module
15
+ */
16
+ import { rpc_action } from '../actions/action_rpc.js';
17
+ import { jsonrpc_errors } from '../http/jsonrpc_errors.js';
18
+ import { cell_audit_list_action_spec, CELL_AUDIT_LIST_DEFAULT_LIMIT, } from './cell_audit_action_specs.js';
19
+ import { ERROR_CELL_NOT_FOUND } from './cell_action_specs.js';
20
+ import { query_cell_get } from '../db/cell_queries.js';
21
+ import { query_audit_log_list_by_cell } from '../db/cell_audit_queries.js';
22
+ import { can_manage_cell } from './cell_authorize.js';
23
+ /**
24
+ * Project a DB row onto the narrowed wire shape. `account_id` /
25
+ * `target_account_id` / `target_actor_id` / `metadata` / `ip` are
26
+ * deliberately omitted — see `CellAuditEventJson` docstring for the
27
+ * rationale.
28
+ */
29
+ const to_cell_audit_event_json = (row) => ({
30
+ id: row.id,
31
+ seq: row.seq,
32
+ event_type: row.event_type,
33
+ outcome: row.outcome,
34
+ actor_id: row.actor_id,
35
+ created_at: typeof row.created_at === 'string' ? row.created_at : row.created_at.toISOString(),
36
+ });
37
+ export const create_cell_audit_actions = () => {
38
+ const handler = async (input, ctx) => {
39
+ const auth = ctx.auth;
40
+ const cell = await query_cell_get(ctx, input.cell_id);
41
+ if (!cell) {
42
+ throw jsonrpc_errors.not_found('cell', { reason: ERROR_CELL_NOT_FOUND });
43
+ }
44
+ // Manage-tier gate (admin / owner). A populated timeline leaks both
45
+ // the existence of the cell and the actor IDs that touched it (incl.
46
+ // across `cell_field` / `cell_item` / clone edges), so viewers — and
47
+ // any authed caller on a public cell — must NOT read it. Non-managers
48
+ // get the same 404 as a non-viewer on `cell_get` (IDOR mask). Grants
49
+ // aren't consulted (manage tier is owner/admin only).
50
+ if (!can_manage_cell(auth, cell)) {
51
+ throw jsonrpc_errors.not_found('cell', { reason: ERROR_CELL_NOT_FOUND });
52
+ }
53
+ const rows = await query_audit_log_list_by_cell(ctx, cell.id, {
54
+ limit: CELL_AUDIT_LIST_DEFAULT_LIMIT,
55
+ });
56
+ return { events: rows.map(to_cell_audit_event_json) };
57
+ };
58
+ return [rpc_action(cell_audit_list_action_spec, handler)];
59
+ };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Canonical cell-layer audit event registry.
3
+ *
4
+ * Maps every cell-domain `event_type` a cell handler emits to its
5
+ * metadata schema. Consumers register the whole bundle in one shot via
6
+ * `create_audit_log_config({extra_events: {...cell_audit_events, ...}})`
7
+ * so the cell handlers' `deps.audit.emit(...)` calls validate against the
8
+ * extended registry. Spreading lets an app fold its own event types in
9
+ * alongside.
10
+ *
11
+ * Aggregator module by design — not a compat shim. The per-event metadata
12
+ * schemas live in their own files (`cell_audit_metadata.ts`,
13
+ * `cell_grant_audit_metadata.ts`, `cell_field_audit_metadata.ts`,
14
+ * `cell_item_audit_metadata.ts`); this module is the single registration
15
+ * surface that keeps the keys in lockstep with the handlers.
16
+ *
17
+ * @module
18
+ */
19
+ import type { z } from 'zod';
20
+ /**
21
+ * Cell-layer `event_type → metadata schema` map for `extra_events`.
22
+ *
23
+ * Covers the six generic cell verbs' mutation events plus the grant /
24
+ * field / item relation events. Read-only verbs (`cell_get`, `cell_list`,
25
+ * `cell_*_list`, `cell_audit_list`) emit nothing and are absent here.
26
+ */
27
+ export declare const cell_audit_events: Readonly<Record<string, z.ZodType>>;
28
+ //# sourceMappingURL=cell_audit_events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cell_audit_events.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_audit_events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAiB3B;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAYjE,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Canonical cell-layer audit event registry.
3
+ *
4
+ * Maps every cell-domain `event_type` a cell handler emits to its
5
+ * metadata schema. Consumers register the whole bundle in one shot via
6
+ * `create_audit_log_config({extra_events: {...cell_audit_events, ...}})`
7
+ * so the cell handlers' `deps.audit.emit(...)` calls validate against the
8
+ * extended registry. Spreading lets an app fold its own event types in
9
+ * alongside.
10
+ *
11
+ * Aggregator module by design — not a compat shim. The per-event metadata
12
+ * schemas live in their own files (`cell_audit_metadata.ts`,
13
+ * `cell_grant_audit_metadata.ts`, `cell_field_audit_metadata.ts`,
14
+ * `cell_item_audit_metadata.ts`); this module is the single registration
15
+ * surface that keeps the keys in lockstep with the handlers.
16
+ *
17
+ * @module
18
+ */
19
+ import { CellAuditMetadata, CellCloneAuditMetadata } from './cell_audit_metadata.js';
20
+ import { CellGrantCreateAuditMetadata, CellGrantRevokeAuditMetadata, } from './cell_grant_audit_metadata.js';
21
+ import { CellFieldSetAuditMetadata, CellFieldDeleteAuditMetadata, } from './cell_field_audit_metadata.js';
22
+ import { CellItemInsertAuditMetadata, CellItemMoveAuditMetadata, CellItemDeleteAuditMetadata, } from './cell_item_audit_metadata.js';
23
+ /**
24
+ * Cell-layer `event_type → metadata schema` map for `extra_events`.
25
+ *
26
+ * Covers the six generic cell verbs' mutation events plus the grant /
27
+ * field / item relation events. Read-only verbs (`cell_get`, `cell_list`,
28
+ * `cell_*_list`, `cell_audit_list`) emit nothing and are absent here.
29
+ */
30
+ export const cell_audit_events = {
31
+ cell_create: CellAuditMetadata,
32
+ cell_update: CellAuditMetadata,
33
+ cell_delete: CellAuditMetadata,
34
+ cell_clone: CellCloneAuditMetadata,
35
+ cell_grant_create: CellGrantCreateAuditMetadata,
36
+ cell_grant_revoke: CellGrantRevokeAuditMetadata,
37
+ cell_field_set: CellFieldSetAuditMetadata,
38
+ cell_field_delete: CellFieldDeleteAuditMetadata,
39
+ cell_item_insert: CellItemInsertAuditMetadata,
40
+ cell_item_move: CellItemMoveAuditMetadata,
41
+ cell_item_delete: CellItemDeleteAuditMetadata,
42
+ };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Audit-log metadata schemas for the cell layer's mutation events.
3
+ *
4
+ * Apps register these via `extra_events:` on `create_audit_log_config`
5
+ * alongside any app-defined event types.
6
+ *
7
+ * @module
8
+ */
9
+ import { z } from 'zod';
10
+ /**
11
+ * Shared metadata envelope for cell mutations. `kind` and `path` are
12
+ * captured at emit-time so the audit-log viewer can show useful context
13
+ * for soft-deleted rows even after the cell snapshot is gone. Relation
14
+ * membership is tracked independently via the `cell_item_*` /
15
+ * `cell_field_*` per-row audit events.
16
+ *
17
+ * Loose object: per-kind handlers may extend the metadata without spec
18
+ * churn.
19
+ */
20
+ export declare const CellAuditMetadata: z.ZodObject<{
21
+ cell_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
22
+ kind: z.ZodOptional<z.ZodString>;
23
+ path: z.ZodOptional<z.ZodNullable<z.ZodString>>;
24
+ }, z.core.$loose>;
25
+ export type CellAuditMetadata = z.infer<typeof CellAuditMetadata>;
26
+ /**
27
+ * Metadata envelope for `cell_clone`.
28
+ *
29
+ * `source_id` and `new_id` capture the parent → clone edge. `deep` flags
30
+ * whether children were walked. `item_count` reports the number of
31
+ * children actually cloned (post-skip). `kind` is captured at emit-time so
32
+ * an operator can filter the audit log by source shape (e.g., "every
33
+ * collection clone").
34
+ *
35
+ * No skipped-child count is recorded: surfacing how many children the
36
+ * caller couldn't view would leak the source's hidden-child count to the
37
+ * cloner (who owns — and can audit — the clone). Non-viewable children are
38
+ * dropped silently (D8).
39
+ */
40
+ export declare const CellCloneAuditMetadata: z.ZodObject<{
41
+ source_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
42
+ new_id: z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">;
43
+ deep: z.ZodBoolean;
44
+ item_count: z.ZodNumber;
45
+ kind: z.ZodOptional<z.ZodString>;
46
+ }, z.core.$loose>;
47
+ export type CellCloneAuditMetadata = z.infer<typeof CellCloneAuditMetadata>;
48
+ //# sourceMappingURL=cell_audit_metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cell_audit_metadata.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_audit_metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAGtB;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB;;;;iBAI5B,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,sBAAsB;;;;;;iBAMjC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Audit-log metadata schemas for the cell layer's mutation events.
3
+ *
4
+ * Apps register these via `extra_events:` on `create_audit_log_config`
5
+ * alongside any app-defined event types.
6
+ *
7
+ * @module
8
+ */
9
+ import { z } from 'zod';
10
+ import { Uuid } from '@fuzdev/fuz_util/id.js';
11
+ /**
12
+ * Shared metadata envelope for cell mutations. `kind` and `path` are
13
+ * captured at emit-time so the audit-log viewer can show useful context
14
+ * for soft-deleted rows even after the cell snapshot is gone. Relation
15
+ * membership is tracked independently via the `cell_item_*` /
16
+ * `cell_field_*` per-row audit events.
17
+ *
18
+ * Loose object: per-kind handlers may extend the metadata without spec
19
+ * churn.
20
+ */
21
+ export const CellAuditMetadata = z.looseObject({
22
+ cell_id: Uuid,
23
+ kind: z.string().optional(),
24
+ path: z.string().nullable().optional(),
25
+ });
26
+ /**
27
+ * Metadata envelope for `cell_clone`.
28
+ *
29
+ * `source_id` and `new_id` capture the parent → clone edge. `deep` flags
30
+ * whether children were walked. `item_count` reports the number of
31
+ * children actually cloned (post-skip). `kind` is captured at emit-time so
32
+ * an operator can filter the audit log by source shape (e.g., "every
33
+ * collection clone").
34
+ *
35
+ * No skipped-child count is recorded: surfacing how many children the
36
+ * caller couldn't view would leak the source's hidden-child count to the
37
+ * cloner (who owns — and can audit — the clone). Non-viewable children are
38
+ * dropped silently (D8).
39
+ */
40
+ export const CellCloneAuditMetadata = z.looseObject({
41
+ source_id: Uuid,
42
+ new_id: Uuid,
43
+ deep: z.boolean(),
44
+ item_count: z.number().int().nonnegative(),
45
+ kind: z.string().optional(),
46
+ });
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Cell view + edit + manage authorization helpers.
3
+ *
4
+ * Pure functions over `(auth, cell, grants)`. No DB I/O; the caller is
5
+ * responsible for loading the cell row and the cell's grant list out-of-
6
+ * band, then handing both to the predicate.
7
+ *
8
+ * Unauthenticated callers pass `null` for `auth` — public pages can
9
+ * resolve `cell.visibility === 'public'` cells without a session, and
10
+ * that branch is the only path that admits them. Callers may pass `null`
11
+ * for `grants` in that case (and any case where they know they don't
12
+ * need to consider grants); `grant_admits` short-circuits on null.
13
+ *
14
+ * Three tiers:
15
+ *
16
+ * - `can_view_cell` — admin / public / owner / any `viewer`+ grant.
17
+ * - `can_edit_cell` — admin / owner / `editor` grant. NULL `created_by`
18
+ * is admin-only (system-origin defense-in-depth).
19
+ * - `can_manage_cell` — admin / owner only. Not delegable, not a grant
20
+ * level. Gates the manage tier: `visibility` writes and all grant
21
+ * management (`cell_grant_create` / `_list` / `_revoke`).
22
+ *
23
+ * Grant-admit branches: per-`actor_id` grants admit the matching
24
+ * actor; `(role, scope_id?)` grants admit any holder of an active
25
+ * role_grant matching those literals (`scope_id IS NULL` admits any-scope
26
+ * role_grant). The grant's `level` (`viewer` / `editor`) gates which
27
+ * predicate it satisfies.
28
+ *
29
+ * @module
30
+ */
31
+ import { type RequestContext } from './request_context.js';
32
+ import type { CellRow } from '../db/cell_queries.js';
33
+ import type { CellGrantRow } from '../db/cell_grant_queries.js';
34
+ /**
35
+ * View authorization for a cell.
36
+ *
37
+ * - Admin: always allowed.
38
+ * - `cell.visibility === 'public'`: allowed for everyone, including
39
+ * unauthenticated callers (e.g. a public landing cell).
40
+ * - Owner (`cell.created_by === auth.actor.id`): allowed.
41
+ * - Any active grant on the cell admits the caller (actor-shaped:
42
+ * match on actor_id; role-shaped: match on `(role, scope_id?)`
43
+ * against an active role_grant).
44
+ * - Otherwise: false.
45
+ *
46
+ * @param auth - request context, or `null` for unauthenticated callers
47
+ * @param cell - the cell row
48
+ * @param grants - the cell's grant list, or `null` to skip the grant branch
49
+ * @returns whether the caller may view the cell
50
+ */
51
+ export declare const can_view_cell: (auth: RequestContext | null, cell: CellRow, grants: ReadonlyArray<CellGrantRow> | null) => boolean;
52
+ /**
53
+ * Edit authorization for a cell.
54
+ *
55
+ * Unauthenticated callers can never edit. Admin always allowed.
56
+ *
57
+ * IMPORTANT: the `cell.created_by === null` branch is **explicit
58
+ * defense-in-depth**. NULL `created_by` means system origin (well-known
59
+ * cells seeded by migration, future daemon/agent cells). Non-admin edits
60
+ * MUST be denied — editor-level grants do NOT bypass this guard,
61
+ * because system cells are policy-controlled at admin level. Do NOT
62
+ * collapse into a single equality check that would silently return
63
+ * `false` for NULL via JS equality semantics — the explicit branch
64
+ * survives refactors and reads as a load-bearing security property.
65
+ *
66
+ * @param auth - request context, or `null` for unauthenticated callers
67
+ * @param cell - the cell row
68
+ * @param grants - the cell's grant list, or `null` to skip the grant branch
69
+ * @returns whether the caller may edit the cell
70
+ */
71
+ export declare const can_edit_cell: (auth: RequestContext | null, cell: CellRow, grants: ReadonlyArray<CellGrantRow> | null) => boolean;
72
+ /**
73
+ * Manage authorization for a cell — `admin || owner`.
74
+ *
75
+ * The implicit tier above editor: gates `visibility` writes and all grant
76
+ * management (`cell_grant_create` / `_list` / `_revoke`). NOT delegable and
77
+ * NOT a grant level — an editor-grant holder is never a manager. Grants are
78
+ * not consulted.
79
+ *
80
+ * NULL `created_by` (system origin) has no owner, so manage falls to
81
+ * admin only — the explicit NULL guard lives in `is_owner`.
82
+ *
83
+ * @param auth - request context, or `null` for unauthenticated callers
84
+ * @param cell - the cell row
85
+ * @returns whether the caller is in the manage tier for the cell
86
+ */
87
+ export declare const can_manage_cell: (auth: RequestContext | null, cell: CellRow) => boolean;
88
+ //# sourceMappingURL=cell_authorize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cell_authorize.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_authorize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAW,KAAK,cAAc,EAAC,MAAM,sBAAsB,CAAC;AAInE,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,6BAA6B,CAAC;AA+D9D;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,GACzB,MAAM,cAAc,GAAG,IAAI,EAC3B,MAAM,OAAO,EACb,QAAQ,aAAa,CAAC,YAAY,CAAC,GAAG,IAAI,KACxC,OAMF,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,aAAa,GACzB,MAAM,cAAc,GAAG,IAAI,EAC3B,MAAM,OAAO,EACb,QAAQ,aAAa,CAAC,YAAY,CAAC,GAAG,IAAI,KACxC,OAUF,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,cAAc,GAAG,IAAI,EAAE,MAAM,OAAO,KAAG,OAI5E,CAAC"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Cell view + edit + manage authorization helpers.
3
+ *
4
+ * Pure functions over `(auth, cell, grants)`. No DB I/O; the caller is
5
+ * responsible for loading the cell row and the cell's grant list out-of-
6
+ * band, then handing both to the predicate.
7
+ *
8
+ * Unauthenticated callers pass `null` for `auth` — public pages can
9
+ * resolve `cell.visibility === 'public'` cells without a session, and
10
+ * that branch is the only path that admits them. Callers may pass `null`
11
+ * for `grants` in that case (and any case where they know they don't
12
+ * need to consider grants); `grant_admits` short-circuits on null.
13
+ *
14
+ * Three tiers:
15
+ *
16
+ * - `can_view_cell` — admin / public / owner / any `viewer`+ grant.
17
+ * - `can_edit_cell` — admin / owner / `editor` grant. NULL `created_by`
18
+ * is admin-only (system-origin defense-in-depth).
19
+ * - `can_manage_cell` — admin / owner only. Not delegable, not a grant
20
+ * level. Gates the manage tier: `visibility` writes and all grant
21
+ * management (`cell_grant_create` / `_list` / `_revoke`).
22
+ *
23
+ * Grant-admit branches: per-`actor_id` grants admit the matching
24
+ * actor; `(role, scope_id?)` grants admit any holder of an active
25
+ * role_grant matching those literals (`scope_id IS NULL` admits any-scope
26
+ * role_grant). The grant's `level` (`viewer` / `editor`) gates which
27
+ * predicate it satisfies.
28
+ *
29
+ * @module
30
+ */
31
+ import { has_role } from './request_context.js';
32
+ import { is_role_grant_active } from './account_schema.js';
33
+ import { ROLE_ADMIN } from './role_schema.js';
34
+ const cell_is_public = (cell) => cell.visibility === 'public';
35
+ /**
36
+ * Whether any grant admits `auth` at the given level.
37
+ *
38
+ * `null` grants short-circuits to false — callers who skipped the load
39
+ * (e.g. unauthenticated requests, where no grant could admit anyway)
40
+ * pass null instead of allocating an empty array. Authenticated
41
+ * callers that loaded a list pass it as-is; an empty array is
42
+ * semantically distinct ("loaded, no grants exist") and walks to false
43
+ * via the empty `for...of`.
44
+ *
45
+ * Actor-shaped grants match `auth.actor.id`. Role-shaped grants walk
46
+ * `auth.role_grants` for an active role_grant with matching role and either a
47
+ * matching `scope_id` or `g.scope_id IS NULL` (any scope). The active-
48
+ * role_grant recheck via `is_role_grant_active` is belt-and-suspenders for
49
+ * long-lived requests crossing an expiration boundary; middleware
50
+ * already filtered to active role_grants at request entry.
51
+ */
52
+ const grant_admits = (auth, grants, required_level) => {
53
+ if (grants === null)
54
+ return false;
55
+ const now = new Date();
56
+ for (const g of grants) {
57
+ // Editor-required filters out viewer-level grants up front.
58
+ if (required_level === 'editor' && g.level !== 'editor')
59
+ continue;
60
+ if (g.actor_id !== null) {
61
+ // Actor-shaped grants only match a resolved acting actor. Account-
62
+ // grain auth (no `acting` declared on input → `actor: null`) cannot
63
+ // match an actor-id grant by definition.
64
+ if (auth.actor !== null && g.actor_id === auth.actor.id)
65
+ return true;
66
+ continue;
67
+ }
68
+ // Role-shaped principal. The CHECK constraint on cell_grant
69
+ // guarantees `role IS NOT NULL` here (actor_id xor role).
70
+ const matched = auth.role_grants.some((p) => p.role === g.role &&
71
+ (g.scope_id === null || p.scope_id === g.scope_id) &&
72
+ is_role_grant_active(p, now));
73
+ if (matched)
74
+ return true;
75
+ }
76
+ return false;
77
+ };
78
+ /**
79
+ * Whether `auth` owns `cell` (the implicit manage tier below admin).
80
+ *
81
+ * Owner is the `cell.created_by` actor field — not a role, not a
82
+ * delegable grant level. NULL `created_by` (system origin) is never
83
+ * owned by anyone; the explicit `created_by !== null` guard keeps that
84
+ * a load-bearing property rather than relying on JS equality returning
85
+ * false for NULL.
86
+ */
87
+ const is_owner = (auth, cell) => auth.actor !== null && cell.created_by !== null && cell.created_by === auth.actor.id;
88
+ /**
89
+ * View authorization for a cell.
90
+ *
91
+ * - Admin: always allowed.
92
+ * - `cell.visibility === 'public'`: allowed for everyone, including
93
+ * unauthenticated callers (e.g. a public landing cell).
94
+ * - Owner (`cell.created_by === auth.actor.id`): allowed.
95
+ * - Any active grant on the cell admits the caller (actor-shaped:
96
+ * match on actor_id; role-shaped: match on `(role, scope_id?)`
97
+ * against an active role_grant).
98
+ * - Otherwise: false.
99
+ *
100
+ * @param auth - request context, or `null` for unauthenticated callers
101
+ * @param cell - the cell row
102
+ * @param grants - the cell's grant list, or `null` to skip the grant branch
103
+ * @returns whether the caller may view the cell
104
+ */
105
+ export const can_view_cell = (auth, cell, grants) => {
106
+ if (auth && has_role(auth, ROLE_ADMIN))
107
+ return true;
108
+ if (cell_is_public(cell))
109
+ return true;
110
+ if (auth && is_owner(auth, cell))
111
+ return true;
112
+ if (auth && grant_admits(auth, grants, 'viewer'))
113
+ return true;
114
+ return false;
115
+ };
116
+ /**
117
+ * Edit authorization for a cell.
118
+ *
119
+ * Unauthenticated callers can never edit. Admin always allowed.
120
+ *
121
+ * IMPORTANT: the `cell.created_by === null` branch is **explicit
122
+ * defense-in-depth**. NULL `created_by` means system origin (well-known
123
+ * cells seeded by migration, future daemon/agent cells). Non-admin edits
124
+ * MUST be denied — editor-level grants do NOT bypass this guard,
125
+ * because system cells are policy-controlled at admin level. Do NOT
126
+ * collapse into a single equality check that would silently return
127
+ * `false` for NULL via JS equality semantics — the explicit branch
128
+ * survives refactors and reads as a load-bearing security property.
129
+ *
130
+ * @param auth - request context, or `null` for unauthenticated callers
131
+ * @param cell - the cell row
132
+ * @param grants - the cell's grant list, or `null` to skip the grant branch
133
+ * @returns whether the caller may edit the cell
134
+ */
135
+ export const can_edit_cell = (auth, cell, grants) => {
136
+ if (!auth)
137
+ return false;
138
+ if (has_role(auth, ROLE_ADMIN))
139
+ return true;
140
+ if (cell.created_by === null)
141
+ return false; // explicit: NULL = admin-only
142
+ // Owner check requires a resolved acting actor — account-grain auth
143
+ // (`actor: null`) cannot match an actor-id `created_by`. Grant-admit
144
+ // fallback below handles the actor-grain editor-grant path.
145
+ if (is_owner(auth, cell))
146
+ return true;
147
+ if (grant_admits(auth, grants, 'editor'))
148
+ return true;
149
+ return false;
150
+ };
151
+ /**
152
+ * Manage authorization for a cell — `admin || owner`.
153
+ *
154
+ * The implicit tier above editor: gates `visibility` writes and all grant
155
+ * management (`cell_grant_create` / `_list` / `_revoke`). NOT delegable and
156
+ * NOT a grant level — an editor-grant holder is never a manager. Grants are
157
+ * not consulted.
158
+ *
159
+ * NULL `created_by` (system origin) has no owner, so manage falls to
160
+ * admin only — the explicit NULL guard lives in `is_owner`.
161
+ *
162
+ * @param auth - request context, or `null` for unauthenticated callers
163
+ * @param cell - the cell row
164
+ * @returns whether the caller is in the manage tier for the cell
165
+ */
166
+ export const can_manage_cell = (auth, cell) => {
167
+ if (!auth)
168
+ return false;
169
+ if (has_role(auth, ROLE_ADMIN))
170
+ return true;
171
+ return is_owner(auth, cell);
172
+ };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Generic cell-data base schema.
3
+ *
4
+ * The wire-side shape every cell consumer can read without per-kind
5
+ * knowledge: a permissive bag with three universally-relevant typed
6
+ * fields. Per-kind schemas extend this and narrow `kind` to a literal.
7
+ *
8
+ * Loose object: arbitrary additional fields pass through unvalidated,
9
+ * preserving the "unknown kinds ship without RPC churn" property. Per-kind
10
+ * shape enforcement is opt-in via the `validate_data` deps slot — see
11
+ * `cell_actions.ts`.
12
+ *
13
+ * **Discipline**: a field joins `CellData` only when at least two
14
+ * consumers in different domains read it generically. `kind` (editor
15
+ * dispatch + sub-API registry), `label` (list/index rendering), and
16
+ * `summary` (card subtitle + share-target description) meet this bar.
17
+ * Future candidates require evidence of generic usage — otherwise they
18
+ * stay per-kind.
19
+ *
20
+ * **Visibility is not in here.** Access control is a peer of `cell_grant`,
21
+ * not content metadata — `cell.visibility` lives as a top-level column on
22
+ * `CellJson` and `CellRow` (the `CellVisibility` enum is defined in
23
+ * `cell_action_specs.ts` next to the wire fields that use it), and is
24
+ * enforced by `can_view_cell` reading the column directly (no JSON dive).
25
+ *
26
+ * @module
27
+ */
28
+ import { z } from 'zod';
29
+ /**
30
+ * Base cell-data shape. All fields optional; loose mode admits arbitrary
31
+ * additional keys so apps can attach metadata or stage new kinds without
32
+ * touching the wire schema.
33
+ *
34
+ * `kind` is optional because cells without a registered kind are valid —
35
+ * admin-curated content, in-development types, or unknown shapes pass
36
+ * through. Known kinds get richer validation via the per-kind sub-API.
37
+ */
38
+ export declare const CellData: z.ZodObject<{
39
+ kind: z.ZodOptional<z.ZodString>;
40
+ label: z.ZodOptional<z.ZodString>;
41
+ summary: z.ZodOptional<z.ZodString>;
42
+ }, z.core.$loose>;
43
+ export type CellData = z.infer<typeof CellData>;
44
+ //# sourceMappingURL=cell_data_schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cell_data_schema.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/cell_data_schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ;;;;iBAInB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC"}