@fuzdev/fuz_app 0.111.0 → 0.112.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 (179) hide show
  1. package/dist/actions/CLAUDE.md +15 -11
  2. package/dist/actions/action_rpc.d.ts +1 -1
  3. package/dist/actions/action_rpc.d.ts.map +1 -1
  4. package/dist/actions/action_rpc.js +4 -6
  5. package/dist/actions/peer_ping.d.ts +8 -0
  6. package/dist/actions/peer_ping.d.ts.map +1 -1
  7. package/dist/actions/peer_ping.js +8 -0
  8. package/dist/actions/peer_request.d.ts +1 -1
  9. package/dist/actions/peer_request.js +1 -1
  10. package/dist/actions/perform_action.d.ts +16 -9
  11. package/dist/actions/perform_action.d.ts.map +1 -1
  12. package/dist/actions/perform_action.js +30 -21
  13. package/dist/actions/register_action_ws.d.ts +1 -1
  14. package/dist/actions/register_action_ws.d.ts.map +1 -1
  15. package/dist/actions/register_action_ws.js +88 -21
  16. package/dist/auth/CLAUDE.md +37 -7
  17. package/dist/auth/account_actions.d.ts.map +1 -1
  18. package/dist/auth/account_actions.js +10 -1
  19. package/dist/auth/account_queries.d.ts.map +1 -1
  20. package/dist/auth/account_queries.js +36 -16
  21. package/dist/auth/account_schema.d.ts +20 -0
  22. package/dist/auth/account_schema.d.ts.map +1 -1
  23. package/dist/auth/account_schema.js +22 -1
  24. package/dist/auth/actor_search_actions.d.ts +3 -3
  25. package/dist/auth/actor_search_actions.d.ts.map +1 -1
  26. package/dist/auth/actor_search_actions.js +10 -6
  27. package/dist/auth/api_token_queries.d.ts.map +1 -1
  28. package/dist/auth/api_token_queries.js +11 -5
  29. package/dist/auth/app_settings_queries.d.ts.map +1 -1
  30. package/dist/auth/app_settings_queries.js +6 -4
  31. package/dist/auth/audit_log_queries.d.ts +6 -0
  32. package/dist/auth/audit_log_queries.d.ts.map +1 -1
  33. package/dist/auth/audit_log_queries.js +11 -5
  34. package/dist/auth/cell_actions.d.ts.map +1 -1
  35. package/dist/auth/cell_actions.js +3 -8
  36. package/dist/auth/cell_audit_actions.d.ts.map +1 -1
  37. package/dist/auth/cell_audit_actions.js +1 -1
  38. package/dist/auth/cell_field_actions.js +1 -1
  39. package/dist/auth/cell_grant_actions.js +1 -1
  40. package/dist/auth/cell_item_actions.js +1 -1
  41. package/dist/auth/invite_queries.d.ts.map +1 -1
  42. package/dist/auth/invite_queries.js +10 -8
  43. package/dist/auth/role_grant_offer_ddl.d.ts +11 -0
  44. package/dist/auth/role_grant_offer_ddl.d.ts.map +1 -1
  45. package/dist/auth/role_grant_offer_ddl.js +20 -2
  46. package/dist/auth/role_grant_offer_queries.d.ts.map +1 -1
  47. package/dist/auth/role_grant_offer_queries.js +29 -15
  48. package/dist/auth/role_grant_queries.d.ts.map +1 -1
  49. package/dist/auth/role_grant_queries.js +21 -7
  50. package/dist/auth/session_queries.d.ts.map +1 -1
  51. package/dist/auth/session_queries.js +9 -4
  52. package/dist/db/CLAUDE.md +21 -2
  53. package/dist/db/cell_audit_queries.js +2 -2
  54. package/dist/db/cell_field_queries.d.ts +1 -1
  55. package/dist/db/cell_field_queries.d.ts.map +1 -1
  56. package/dist/db/cell_field_queries.js +8 -6
  57. package/dist/db/cell_grant_queries.d.ts +1 -1
  58. package/dist/db/cell_grant_queries.d.ts.map +1 -1
  59. package/dist/db/cell_grant_queries.js +12 -10
  60. package/dist/db/cell_item_queries.d.ts +1 -1
  61. package/dist/db/cell_item_queries.d.ts.map +1 -1
  62. package/dist/db/cell_item_queries.js +9 -7
  63. package/dist/db/cell_queries.d.ts +3 -3
  64. package/dist/db/cell_queries.d.ts.map +1 -1
  65. package/dist/db/cell_queries.js +6 -4
  66. package/dist/db/fact_queries.d.ts.map +1 -1
  67. package/dist/db/fact_queries.js +9 -3
  68. package/dist/db/sql_columns.d.ts +80 -3
  69. package/dist/db/sql_columns.d.ts.map +1 -1
  70. package/dist/db/sql_columns.js +91 -4
  71. package/dist/http/CLAUDE.md +3 -1
  72. package/dist/http/jsonrpc_helpers.d.ts +13 -0
  73. package/dist/http/jsonrpc_helpers.d.ts.map +1 -1
  74. package/dist/http/jsonrpc_helpers.js +13 -0
  75. package/dist/server/serve_fact_route.d.ts.map +1 -1
  76. package/dist/server/serve_fact_route.js +7 -2
  77. package/dist/testing/CLAUDE.md +53 -27
  78. package/dist/testing/admin_integration.d.ts +0 -3
  79. package/dist/testing/admin_integration.d.ts.map +1 -1
  80. package/dist/testing/admin_integration.js +0 -1
  81. package/dist/testing/adversarial_404.d.ts.map +1 -1
  82. package/dist/testing/adversarial_404.js +4 -1
  83. package/dist/testing/adversarial_input.d.ts.map +1 -1
  84. package/dist/testing/adversarial_input.js +5 -4
  85. package/dist/testing/app_server.d.ts +4 -3
  86. package/dist/testing/app_server.d.ts.map +1 -1
  87. package/dist/testing/app_server.js +11 -5
  88. package/dist/testing/attack_surface.d.ts +16 -0
  89. package/dist/testing/attack_surface.d.ts.map +1 -1
  90. package/dist/testing/attack_surface.js +36 -13
  91. package/dist/testing/audit_completeness.d.ts +0 -3
  92. package/dist/testing/audit_completeness.d.ts.map +1 -1
  93. package/dist/testing/audit_completeness.js +0 -1
  94. package/dist/testing/auth_apps.d.ts +9 -2
  95. package/dist/testing/auth_apps.d.ts.map +1 -1
  96. package/dist/testing/auth_apps.js +9 -2
  97. package/dist/testing/cross_backend/account_lifecycle.d.ts +5 -4
  98. package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -1
  99. package/dist/testing/cross_backend/account_lifecycle.js +7 -0
  100. package/dist/testing/cross_backend/action_manifest.d.ts +19 -3
  101. package/dist/testing/cross_backend/action_manifest.d.ts.map +1 -1
  102. package/dist/testing/cross_backend/action_manifest.js +10 -4
  103. package/dist/testing/cross_backend/action_manifest_parity.d.ts +9 -3
  104. package/dist/testing/cross_backend/action_manifest_parity.d.ts.map +1 -1
  105. package/dist/testing/cross_backend/action_manifest_parity.js +6 -0
  106. package/dist/testing/cross_backend/actor_lookup.d.ts +3 -2
  107. package/dist/testing/cross_backend/actor_lookup.d.ts.map +1 -1
  108. package/dist/testing/cross_backend/body_size.d.ts +4 -2
  109. package/dist/testing/cross_backend/body_size.d.ts.map +1 -1
  110. package/dist/testing/cross_backend/body_size.js +1 -1
  111. package/dist/testing/cross_backend/cell_crud.d.ts +2 -2
  112. package/dist/testing/cross_backend/cell_crud.d.ts.map +1 -1
  113. package/dist/testing/cross_backend/cell_crud.js +10 -0
  114. package/dist/testing/cross_backend/cell_gated_create.d.ts +3 -3
  115. package/dist/testing/cross_backend/cell_gated_create.d.ts.map +1 -1
  116. package/dist/testing/cross_backend/cell_grant_role.d.ts +2 -2
  117. package/dist/testing/cross_backend/cell_grant_role.d.ts.map +1 -1
  118. package/dist/testing/cross_backend/cell_relations.d.ts +2 -2
  119. package/dist/testing/cross_backend/cell_relations.d.ts.map +1 -1
  120. package/dist/testing/cross_backend/fact_serving.d.ts +2 -2
  121. package/dist/testing/cross_backend/fact_serving.d.ts.map +1 -1
  122. package/dist/testing/cross_backend/make_cross_backend_project.d.ts +17 -2
  123. package/dist/testing/cross_backend/make_cross_backend_project.d.ts.map +1 -1
  124. package/dist/testing/cross_backend/make_cross_backend_project.js +23 -3
  125. package/dist/testing/cross_backend/origin.d.ts +4 -2
  126. package/dist/testing/cross_backend/origin.d.ts.map +1 -1
  127. package/dist/testing/cross_backend/origin.js +1 -1
  128. package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -1
  129. package/dist/testing/cross_backend/peer_ping_ws.js +11 -7
  130. package/dist/testing/cross_backend/query_shape.d.ts +6 -5
  131. package/dist/testing/cross_backend/query_shape.d.ts.map +1 -1
  132. package/dist/testing/cross_backend/ready.d.ts +2 -2
  133. package/dist/testing/cross_backend/ready.d.ts.map +1 -1
  134. package/dist/testing/cross_backend/role_grant_offer_enumeration.d.ts.map +1 -1
  135. package/dist/testing/cross_backend/role_grant_offer_enumeration.js +7 -1
  136. package/dist/testing/cross_backend/setup.d.ts +26 -6
  137. package/dist/testing/cross_backend/setup.d.ts.map +1 -1
  138. package/dist/testing/cross_backend/standard.d.ts +5 -1
  139. package/dist/testing/cross_backend/standard.d.ts.map +1 -1
  140. package/dist/testing/cross_backend/standard.js +1 -5
  141. package/dist/testing/cross_backend/testing_backdoor.js +1 -1
  142. package/dist/testing/cross_backend/testing_reset_actions.d.ts +5 -0
  143. package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
  144. package/dist/testing/cross_backend/token_lifetime.d.ts.map +1 -1
  145. package/dist/testing/cross_backend/token_lifetime.js +6 -0
  146. package/dist/testing/cross_backend/token_scope_surface.d.ts +2 -2
  147. package/dist/testing/cross_backend/token_scope_surface.d.ts.map +1 -1
  148. package/dist/testing/cross_backend/wire_shapes.d.ts +22 -0
  149. package/dist/testing/cross_backend/wire_shapes.d.ts.map +1 -0
  150. package/dist/testing/cross_backend/wire_shapes.js +41 -0
  151. package/dist/testing/data_exposure.d.ts +0 -3
  152. package/dist/testing/data_exposure.d.ts.map +1 -1
  153. package/dist/testing/data_exposure.js +0 -1
  154. package/dist/testing/db.d.ts +44 -7
  155. package/dist/testing/db.d.ts.map +1 -1
  156. package/dist/testing/db.js +62 -27
  157. package/dist/testing/integration.d.ts.map +1 -1
  158. package/dist/testing/integration.js +15 -2
  159. package/dist/testing/round_trip.d.ts +0 -3
  160. package/dist/testing/round_trip.d.ts.map +1 -1
  161. package/dist/testing/round_trip.js +0 -4
  162. package/dist/testing/rpc_attack_surface.js +2 -2
  163. package/dist/testing/rpc_round_trip.d.ts +0 -3
  164. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  165. package/dist/testing/rpc_round_trip.js +0 -1
  166. package/dist/testing/schema_generators.d.ts +15 -0
  167. package/dist/testing/schema_generators.d.ts.map +1 -1
  168. package/dist/testing/schema_generators.js +45 -11
  169. package/dist/testing/standard.d.ts +5 -1
  170. package/dist/testing/standard.d.ts.map +1 -1
  171. package/dist/testing/standard.js +2 -7
  172. package/dist/timestamp.d.ts +58 -0
  173. package/dist/timestamp.d.ts.map +1 -0
  174. package/dist/timestamp.js +57 -0
  175. package/dist/ui/RoleGrantOfferHistory.svelte +3 -1
  176. package/dist/ui/RoleGrantOfferHistory.svelte.d.ts.map +1 -1
  177. package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -1
  178. package/dist/ui/role_grant_offers_state.svelte.js +6 -2
  179. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"cell_field_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_field_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAInD,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,2DAKuB,CAAC;AAEvD,wCAAwC;AACxC,MAAM,WAAW,sBAAsB;IACtC,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,OAAO,sBAAsB,KAC3B,OAAO,CAAC,YAAY,CAUtB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,MAAM,MAAM,KACV,OAAO,CAAC,YAAY,GAAG,IAAI,CAM7B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GACnC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,MAAM,MAAM,KACV,OAAO,CAAC,YAAY,GAAG,IAAI,CAO7B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,KAC/C,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAa7B,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1B,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAS5B,CAAC"}
1
+ {"version":3,"file":"cell_field_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_field_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAInD,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,2DAKuB,CAAC;AAKvD,wCAAwC;AACxC,MAAM,WAAW,sBAAsB;IACtC,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,OAAO,sBAAsB,KAC3B,OAAO,CAAC,YAAY,CAUtB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,MAAM,MAAM,KACV,OAAO,CAAC,YAAY,GAAG,IAAI,CAM7B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GACnC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,MAAM,MAAM,KACV,OAAO,CAAC,YAAY,GAAG,IAAI,CAO7B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,KAC/C,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAa7B,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1B,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAS5B,CAAC"}
@@ -17,7 +17,7 @@
17
17
  * @module
18
18
  */
19
19
  import { assert_row } from './assert_row.js';
20
- import { columns_sql, qualify_columns } from './sql_columns.js';
20
+ import { columns_sql, iso8601_timestamp_expr, qualify_columns } from './sql_columns.js';
21
21
  /**
22
22
  * The full `cell_field` column set, named explicitly so a row read fails
23
23
  * loud on schema drift (see `CELL_COLUMNS` in `db/cell_queries.ts`). Column
@@ -30,6 +30,8 @@ export const CELL_FIELD_COLUMNS = [
30
30
  'target_id',
31
31
  'created_at'
32
32
  ];
33
+ /** The `cell_field` timestamp override, by row qualifier (`''` bare, `f` for the cell-joined reads). */
34
+ const cell_field_expr = iso8601_timestamp_expr(CELL_FIELD_COLUMNS, ['created_at']);
33
35
  /**
34
36
  * Insert or update a field row.
35
37
  *
@@ -48,7 +50,7 @@ export const query_cell_field_set = async (deps, input) => {
48
50
  VALUES ($1, $2, $3)
49
51
  ON CONFLICT (source_id, name)
50
52
  DO UPDATE SET target_id = EXCLUDED.target_id, created_at = NOW()
51
- RETURNING ${columns_sql(CELL_FIELD_COLUMNS)}`, [input.source_id, input.name, input.target_id]);
53
+ RETURNING ${columns_sql(CELL_FIELD_COLUMNS, cell_field_expr(''))}`, [input.source_id, input.name, input.target_id]);
52
54
  return assert_row(row, 'INSERT INTO cell_field');
53
55
  };
54
56
  /**
@@ -64,7 +66,7 @@ export const query_cell_field_set = async (deps, input) => {
64
66
  * @returns the row or `null` when not found
65
67
  */
66
68
  export const query_cell_field_get = async (deps, source_id, name) => {
67
- const row = await deps.db.query_one(`SELECT ${columns_sql(CELL_FIELD_COLUMNS)} FROM cell_field WHERE source_id = $1 AND name = $2`, [source_id, name]);
69
+ const row = await deps.db.query_one(`SELECT ${columns_sql(CELL_FIELD_COLUMNS, cell_field_expr(''))} FROM cell_field WHERE source_id = $1 AND name = $2`, [source_id, name]);
68
70
  return row ?? null;
69
71
  };
70
72
  /**
@@ -77,7 +79,7 @@ export const query_cell_field_get = async (deps, source_id, name) => {
77
79
  */
78
80
  export const query_cell_field_delete = async (deps, source_id, name) => {
79
81
  const row = await deps.db.query_one(`DELETE FROM cell_field WHERE source_id = $1 AND name = $2
80
- RETURNING ${columns_sql(CELL_FIELD_COLUMNS)}`, [source_id, name]);
82
+ RETURNING ${columns_sql(CELL_FIELD_COLUMNS, cell_field_expr(''))}`, [source_id, name]);
81
83
  return row ?? null;
82
84
  };
83
85
  /**
@@ -96,7 +98,7 @@ export const query_cell_field_delete = async (deps, source_id, name) => {
96
98
  export const query_cell_field_list_for_source = async (deps, source_id, options) => {
97
99
  const limit = options?.limit ?? null;
98
100
  const name_after = options?.name_after ?? null;
99
- return deps.db.query(`SELECT ${qualify_columns(CELL_FIELD_COLUMNS, 'f')} FROM cell_field f
101
+ return deps.db.query(`SELECT ${qualify_columns(CELL_FIELD_COLUMNS, 'f', cell_field_expr('f'))} FROM cell_field f
100
102
  JOIN cell t ON t.id = f.target_id
101
103
  WHERE f.source_id = $1
102
104
  AND t.deleted_at IS NULL
@@ -121,7 +123,7 @@ export const query_cell_field_list_for_source = async (deps, source_id, options)
121
123
  * @param options - `limit` caps the row count
122
124
  * @returns matching rows, oldest field first (by the field row's `created_at`)
123
125
  */
124
- export const query_cell_field_list_for_target = async (deps, target_id, options) => deps.db.query(`SELECT ${qualify_columns(CELL_FIELD_COLUMNS, 'f')} FROM cell_field f
126
+ export const query_cell_field_list_for_target = async (deps, target_id, options) => deps.db.query(`SELECT ${qualify_columns(CELL_FIELD_COLUMNS, 'f', cell_field_expr('f'))} FROM cell_field f
125
127
  JOIN cell s ON s.id = f.source_id
126
128
  WHERE f.target_id = $1
127
129
  AND s.deleted_at IS NULL
@@ -33,7 +33,7 @@ export interface CellGrantRow {
33
33
  role: string | null;
34
34
  scope_id: Uuid | null;
35
35
  granted_by: Uuid | null;
36
- created_at: Date;
36
+ created_at: string;
37
37
  }
38
38
  /**
39
39
  * The full `cell_grant` column set, named explicitly so a row read fails
@@ -1 +1 @@
1
- {"version":3,"file":"cell_grant_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_grant_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAIzE,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,iGASuB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,4BAA4B,GACvC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAA;CAAE,CAAC;AAE3F,2CAA2C;AAC3C,MAAM,WAAW,yBAAyB;IACzC,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,EAAE,4BAA4B,CAAC;IACxC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,uBAAuB,GACnC,MAAM,SAAS,EACf,OAAO,yBAAyB,KAC9B,OAAO,CAAC,YAAY,CAsBtB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,UAAU,IAAI,KACZ,OAAO,CAAC,YAAY,GAAG,IAAI,CAM7B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,uBAAuB,GACnC,MAAM,SAAS,EACf,UAAU,IAAI,KACZ,OAAO,CAAC,YAAY,GAAG,IAAI,CAM7B,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,8BAA8B,GAC1C,MAAM,SAAS,EACf,SAAS,IAAI,KACX,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAM5B,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,+BAA+B,GAC3C,MAAM,SAAS,EACf,UAAU,aAAa,CAAC,IAAI,CAAC,KAC3B,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAQ7B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qCAAqC,GACjD,MAAM,SAAS,EACf,UAAU,aAAa,CAAC,IAAI,CAAC,EAC7B,iBAAiB,IAAI,GAAG,IAAI,EAC5B,kBAAkB,aAAa,CAAC,MAAM,CAAC,EACvC,sBAAsB,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC,KAC9C,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAmB7B,CAAC"}
1
+ {"version":3,"file":"cell_grant_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_grant_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAIzE,kDAAkD;AAClD,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,iGASuB,CAAC;AAKvD;;;;;GAKG;AACH,MAAM,MAAM,4BAA4B,GACvC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAA;CAAE,CAAC;AAE3F,2CAA2C;AAC3C,MAAM,WAAW,yBAAyB;IACzC,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,EAAE,4BAA4B,CAAC;IACxC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,uBAAuB,GACnC,MAAM,SAAS,EACf,OAAO,yBAAyB,KAC9B,OAAO,CAAC,YAAY,CAsBtB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,UAAU,IAAI,KACZ,OAAO,CAAC,YAAY,GAAG,IAAI,CAM7B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,uBAAuB,GACnC,MAAM,SAAS,EACf,UAAU,IAAI,KACZ,OAAO,CAAC,YAAY,GAAG,IAAI,CAM7B,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,8BAA8B,GAC1C,MAAM,SAAS,EACf,SAAS,IAAI,KACX,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAM5B,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,+BAA+B,GAC3C,MAAM,SAAS,EACf,UAAU,aAAa,CAAC,IAAI,CAAC,KAC3B,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAQ7B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qCAAqC,GACjD,MAAM,SAAS,EACf,UAAU,aAAa,CAAC,IAAI,CAAC,EAC7B,iBAAiB,IAAI,GAAG,IAAI,EAC5B,kBAAkB,aAAa,CAAC,MAAM,CAAC,EACvC,sBAAsB,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC,KAC9C,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAmB7B,CAAC"}
@@ -22,7 +22,7 @@
22
22
  * @module
23
23
  */
24
24
  import { assert_row } from './assert_row.js';
25
- import { columns_sql, qualify_columns } from './sql_columns.js';
25
+ import { columns_sql, iso8601_timestamp_expr, qualify_columns } from './sql_columns.js';
26
26
  /**
27
27
  * The full `cell_grant` column set, named explicitly so a row read fails
28
28
  * loud on schema drift (see `CELL_COLUMNS` in `db/cell_queries.ts`). Column
@@ -39,6 +39,8 @@ export const CELL_GRANT_COLUMNS = [
39
39
  'granted_by',
40
40
  'created_at'
41
41
  ];
42
+ /** The `cell_grant` timestamp override, by row qualifier (`''` bare, `g` for the cell-joined reads). */
43
+ const cell_grant_expr = iso8601_timestamp_expr(CELL_GRANT_COLUMNS, ['created_at']);
42
44
  /**
43
45
  * Insert a grant, or update the existing row's `level` + `granted_by` when
44
46
  * one already exists for the same `(cell_id, principal)` pair.
@@ -60,14 +62,14 @@ export const query_cell_grant_create = async (deps, input) => {
60
62
  VALUES ($1, $2, $3, $4)
61
63
  ON CONFLICT (cell_id, actor_id) WHERE actor_id IS NOT NULL
62
64
  DO UPDATE SET level = EXCLUDED.level, granted_by = EXCLUDED.granted_by
63
- RETURNING ${columns_sql(CELL_GRANT_COLUMNS)}`, [cell_id, level, principal.actor_id, granted_by]);
65
+ RETURNING ${columns_sql(CELL_GRANT_COLUMNS, cell_grant_expr(''))}`, [cell_id, level, principal.actor_id, granted_by]);
64
66
  return assert_row(row, 'INSERT INTO cell_grant (actor)');
65
67
  }
66
68
  const row = await deps.db.query_one(`INSERT INTO cell_grant (cell_id, level, role, scope_id, granted_by)
67
69
  VALUES ($1, $2, $3, $4, $5)
68
70
  ON CONFLICT (cell_id, role, scope_id) WHERE role IS NOT NULL
69
71
  DO UPDATE SET level = EXCLUDED.level, granted_by = EXCLUDED.granted_by
70
- RETURNING ${columns_sql(CELL_GRANT_COLUMNS)}`, [cell_id, level, principal.role, principal.scope_id, granted_by]);
72
+ RETURNING ${columns_sql(CELL_GRANT_COLUMNS, cell_grant_expr(''))}`, [cell_id, level, principal.role, principal.scope_id, granted_by]);
71
73
  return assert_row(row, 'INSERT INTO cell_grant (role)');
72
74
  };
73
75
  /**
@@ -78,7 +80,7 @@ export const query_cell_grant_create = async (deps, input) => {
78
80
  * @returns the row or `null` when not found
79
81
  */
80
82
  export const query_cell_grant_get = async (deps, grant_id) => {
81
- const row = await deps.db.query_one(`SELECT ${columns_sql(CELL_GRANT_COLUMNS)} FROM cell_grant WHERE id = $1`, [grant_id]);
83
+ const row = await deps.db.query_one(`SELECT ${columns_sql(CELL_GRANT_COLUMNS, cell_grant_expr(''))} FROM cell_grant WHERE id = $1`, [grant_id]);
82
84
  return row ?? null;
83
85
  };
84
86
  /**
@@ -94,7 +96,7 @@ export const query_cell_grant_get = async (deps, grant_id) => {
94
96
  * @mutates `cell_grant` - deletes one row
95
97
  */
96
98
  export const query_cell_grant_delete = async (deps, grant_id) => {
97
- const row = await deps.db.query_one(`DELETE FROM cell_grant WHERE id = $1 RETURNING ${columns_sql(CELL_GRANT_COLUMNS)}`, [grant_id]);
99
+ const row = await deps.db.query_one(`DELETE FROM cell_grant WHERE id = $1 RETURNING ${columns_sql(CELL_GRANT_COLUMNS, cell_grant_expr(''))}`, [grant_id]);
98
100
  return row ?? null;
99
101
  };
100
102
  /**
@@ -107,9 +109,9 @@ export const query_cell_grant_delete = async (deps, grant_id) => {
107
109
  * @param cell_id - cell id
108
110
  * @returns matching rows
109
111
  */
110
- export const query_cell_grant_list_for_cell = async (deps, cell_id) => deps.db.query(`SELECT ${columns_sql(CELL_GRANT_COLUMNS)} FROM cell_grant
112
+ export const query_cell_grant_list_for_cell = async (deps, cell_id) => deps.db.query(`SELECT ${columns_sql(CELL_GRANT_COLUMNS, cell_grant_expr(''))} FROM cell_grant
111
113
  WHERE cell_id = $1
112
- ORDER BY created_at ASC`, [cell_id]);
114
+ ORDER BY cell_grant.created_at ASC`, [cell_id]);
113
115
  /**
114
116
  * List all grants across a set of cells, ordered by cell then creation.
115
117
  * Used by the strict relation-read filter to test `can_view_cell` per
@@ -124,9 +126,9 @@ export const query_cell_grant_list_for_cell = async (deps, cell_id) => deps.db.q
124
126
  export const query_cell_grant_list_for_cells = async (deps, cell_ids) => {
125
127
  if (cell_ids.length === 0)
126
128
  return [];
127
- return deps.db.query(`SELECT ${columns_sql(CELL_GRANT_COLUMNS)} FROM cell_grant
129
+ return deps.db.query(`SELECT ${columns_sql(CELL_GRANT_COLUMNS, cell_grant_expr(''))} FROM cell_grant
128
130
  WHERE cell_id = ANY($1::uuid[])
129
- ORDER BY cell_id, created_at ASC`, [cell_ids]);
131
+ ORDER BY cell_grant.cell_id, cell_grant.created_at ASC`, [cell_ids]);
130
132
  };
131
133
  /**
132
134
  * Load grants that admit the caller (by actor or role-scoped role_grants) across
@@ -146,7 +148,7 @@ export const query_cell_grants_for_caller_in_cells = async (deps, cell_ids, call
146
148
  if (cell_ids.length === 0) {
147
149
  return [];
148
150
  }
149
- return deps.db.query(`SELECT ${qualify_columns(CELL_GRANT_COLUMNS, 'g')} FROM cell_grant g
151
+ return deps.db.query(`SELECT ${qualify_columns(CELL_GRANT_COLUMNS, 'g', cell_grant_expr('g'))} FROM cell_grant g
150
152
  WHERE g.cell_id = ANY($1::uuid[])
151
153
  AND (
152
154
  g.actor_id = $2
@@ -26,7 +26,7 @@ export interface CellItemRow {
26
26
  parent_id: Uuid;
27
27
  position: string;
28
28
  child_id: Uuid;
29
- created_at: Date;
29
+ created_at: string;
30
30
  }
31
31
  /**
32
32
  * The full `cell_item` column set, named explicitly so a row read fails
@@ -1 +1 @@
1
- {"version":3,"file":"cell_item_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_item_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAInD,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,IAAI,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,8DAKuB,CAAC;AAEtD,0CAA0C;AAC1C,MAAM,WAAW,wBAAwB;IACxC,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,IAAI,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,SAAS,EACf,OAAO,wBAAwB,KAC7B,OAAO,CAAC,WAAW,CAQrB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU,MAAM,KACd,OAAO,CAAC,WAAW,GAAG,IAAI,CAM5B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,cAAc,MAAM,EACpB,cAAc,MAAM,KAClB,OAAO,CAAC,WAAW,GAAG,IAAI,CAS5B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU,MAAM,KACd,OAAO,CAAC,WAAW,GAAG,IAAI,CAO5B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,+BAA+B,GAC3C,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,KACnD,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAa5B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,8BAA8B,GAC1C,MAAM,SAAS,EACf,UAAU,IAAI,EACd,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1B,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAS3B,CAAC"}
1
+ {"version":3,"file":"cell_item_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_item_queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAInD,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,IAAI,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,8DAKuB,CAAC;AAKtD,0CAA0C;AAC1C,MAAM,WAAW,wBAAwB;IACxC,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,IAAI,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,SAAS,EACf,OAAO,wBAAwB,KAC7B,OAAO,CAAC,WAAW,CAQrB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU,MAAM,KACd,OAAO,CAAC,WAAW,GAAG,IAAI,CAM5B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,cAAc,MAAM,EACpB,cAAc,MAAM,KAClB,OAAO,CAAC,WAAW,GAAG,IAAI,CAS5B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,GAClC,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU,MAAM,KACd,OAAO,CAAC,WAAW,GAAG,IAAI,CAO5B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,+BAA+B,GAC3C,MAAM,SAAS,EACf,WAAW,IAAI,EACf,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,KACnD,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAa5B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,8BAA8B,GAC1C,MAAM,SAAS,EACf,UAAU,IAAI,EACd,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1B,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAS3B,CAAC"}
@@ -20,7 +20,7 @@
20
20
  * @module
21
21
  */
22
22
  import { assert_row } from './assert_row.js';
23
- import { columns_sql, qualify_columns } from './sql_columns.js';
23
+ import { columns_sql, iso8601_timestamp_expr, qualify_columns } from './sql_columns.js';
24
24
  /**
25
25
  * The full `cell_item` column set, named explicitly so a row read fails
26
26
  * loud on schema drift (see `CELL_COLUMNS` in `db/cell_queries.ts`). Column
@@ -33,6 +33,8 @@ export const CELL_ITEM_COLUMNS = [
33
33
  'child_id',
34
34
  'created_at'
35
35
  ];
36
+ /** The `cell_item` timestamp override, by row qualifier (`''` bare, `i` for the cell-joined reads). */
37
+ const cell_item_expr = iso8601_timestamp_expr(CELL_ITEM_COLUMNS, ['created_at']);
36
38
  /**
37
39
  * Insert one item row at the caller-supplied `position`.
38
40
  *
@@ -47,7 +49,7 @@ export const CELL_ITEM_COLUMNS = [
47
49
  export const query_cell_item_insert = async (deps, input) => {
48
50
  const row = await deps.db.query_one(`INSERT INTO cell_item (parent_id, position, child_id)
49
51
  VALUES ($1, $2, $3)
50
- RETURNING ${columns_sql(CELL_ITEM_COLUMNS)}`, [input.parent_id, input.position, input.child_id]);
52
+ RETURNING ${columns_sql(CELL_ITEM_COLUMNS, cell_item_expr(''))}`, [input.parent_id, input.position, input.child_id]);
51
53
  return assert_row(row, 'INSERT INTO cell_item');
52
54
  };
53
55
  /**
@@ -57,7 +59,7 @@ export const query_cell_item_insert = async (deps, input) => {
57
59
  * @returns the row or `null` when not found
58
60
  */
59
61
  export const query_cell_item_get = async (deps, parent_id, position) => {
60
- const row = await deps.db.query_one(`SELECT ${columns_sql(CELL_ITEM_COLUMNS)} FROM cell_item WHERE parent_id = $1 AND position = $2`, [parent_id, position]);
62
+ const row = await deps.db.query_one(`SELECT ${columns_sql(CELL_ITEM_COLUMNS, cell_item_expr(''))} FROM cell_item WHERE parent_id = $1 AND position = $2`, [parent_id, position]);
61
63
  return row ?? null;
62
64
  };
63
65
  /**
@@ -77,7 +79,7 @@ export const query_cell_item_move = async (deps, parent_id, position_old, positi
77
79
  const row = await deps.db.query_one(`UPDATE cell_item
78
80
  SET position = $3
79
81
  WHERE parent_id = $1 AND position = $2
80
- RETURNING ${columns_sql(CELL_ITEM_COLUMNS)}`, [parent_id, position_old, position_new]);
82
+ RETURNING ${columns_sql(CELL_ITEM_COLUMNS, cell_item_expr(''))}`, [parent_id, position_old, position_new]);
81
83
  return row ?? null;
82
84
  };
83
85
  /**
@@ -90,7 +92,7 @@ export const query_cell_item_move = async (deps, parent_id, position_old, positi
90
92
  */
91
93
  export const query_cell_item_delete = async (deps, parent_id, position) => {
92
94
  const row = await deps.db.query_one(`DELETE FROM cell_item WHERE parent_id = $1 AND position = $2
93
- RETURNING ${columns_sql(CELL_ITEM_COLUMNS)}`, [parent_id, position]);
95
+ RETURNING ${columns_sql(CELL_ITEM_COLUMNS, cell_item_expr(''))}`, [parent_id, position]);
94
96
  return row ?? null;
95
97
  };
96
98
  /**
@@ -109,7 +111,7 @@ export const query_cell_item_delete = async (deps, parent_id, position) => {
109
111
  export const query_cell_item_list_for_parent = async (deps, parent_id, options) => {
110
112
  const limit = options?.limit ?? null;
111
113
  const position_after = options?.position_after ?? null;
112
- return deps.db.query(`SELECT ${qualify_columns(CELL_ITEM_COLUMNS, 'i')} FROM cell_item i
114
+ return deps.db.query(`SELECT ${qualify_columns(CELL_ITEM_COLUMNS, 'i', cell_item_expr('i'))} FROM cell_item i
113
115
  JOIN cell c ON c.id = i.child_id
114
116
  WHERE i.parent_id = $1
115
117
  AND c.deleted_at IS NULL
@@ -129,7 +131,7 @@ export const query_cell_item_list_for_parent = async (deps, parent_id, options)
129
131
  * inbound-linked child can't force an unbounded fetch + per-parent authz
130
132
  * pass on the public, IP-rate-limited reverse endpoint.
131
133
  */
132
- export const query_cell_item_list_for_child = async (deps, child_id, options) => deps.db.query(`SELECT ${qualify_columns(CELL_ITEM_COLUMNS, 'i')} FROM cell_item i
134
+ export const query_cell_item_list_for_child = async (deps, child_id, options) => deps.db.query(`SELECT ${qualify_columns(CELL_ITEM_COLUMNS, 'i', cell_item_expr('i'))} FROM cell_item i
133
135
  JOIN cell p ON p.id = i.parent_id
134
136
  WHERE i.child_id = $1
135
137
  AND p.deleted_at IS NULL
@@ -49,9 +49,9 @@ export interface CellRow {
49
49
  parent_id: Uuid | null;
50
50
  root_id: Uuid | null;
51
51
  moderation: string | null;
52
- created_at: Date;
53
- updated_at: Date | null;
54
- deleted_at: Date | null;
52
+ created_at: string;
53
+ updated_at: string | null;
54
+ deleted_at: string | null;
55
55
  created_by: Uuid | null;
56
56
  updated_by: Uuid | null;
57
57
  grant_count: number;
@@ -1 +1 @@
1
- {"version":3,"file":"cell_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_queries.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cell_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_queries.ts"],"names":[],"mappings":"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"}
@@ -22,7 +22,7 @@
22
22
  */
23
23
  import { fact_hash_extract_refs } from '@fuzdev/fuz_util/fact_hash.ts';
24
24
  import { assert_row } from './assert_row.js';
25
- import { qualify_columns } from './sql_columns.js';
25
+ import { iso8601_timestamp_expr, qualify_columns } from './sql_columns.js';
26
26
  /**
27
27
  * The full `cell` column set, named explicitly so a row read fails loud on
28
28
  * schema drift — a `SELECT *` silently omits a dropped column and the
@@ -49,6 +49,8 @@ export const CELL_COLUMNS = [
49
49
  'created_by',
50
50
  'updated_by'
51
51
  ];
52
+ /** The `cell` timestamp override, by row qualifier — the one `cell_row_projection` is given. */
53
+ const cell_expr = iso8601_timestamp_expr(CELL_COLUMNS, ['created_at', 'updated_at', 'deleted_at']);
52
54
  /**
53
55
  * The full `CellRow` projection — `CELL_COLUMNS` qualified by `alias` plus
54
56
  * the derived `grant_count` (a correlated subquery against `cell_grant`,
@@ -66,7 +68,7 @@ export const CELL_COLUMNS = [
66
68
  * `CellRow` but fails at `to_cell_json` — this is the projection that
67
69
  * actually produces one.
68
70
  */
69
- export const cell_row_projection = (alias) => `${qualify_columns(CELL_COLUMNS, alias)}, (SELECT COUNT(*)::int FROM cell_grant WHERE cell_id = ${alias}.id) AS grant_count`;
71
+ export const cell_row_projection = (alias) => `${qualify_columns(CELL_COLUMNS, alias, cell_expr(alias))}, (SELECT COUNT(*)::int FROM cell_grant WHERE cell_id = ${alias}.id) AS grant_count`;
70
72
  /**
71
73
  * Insert a cell row, deriving `refs` from `data`.
72
74
  *
@@ -248,7 +250,7 @@ export const query_cell_list_by_kind = async (deps, kind, options) => deps.db.qu
248
250
  FROM cell
249
251
  WHERE kind = $1
250
252
  AND deleted_at IS NULL
251
- ORDER BY created_at DESC
253
+ ORDER BY cell.created_at DESC
252
254
  LIMIT $2 OFFSET $3`, [kind, options?.limit ?? null, options?.offset ?? 0]);
253
255
  /**
254
256
  * List active cells created by an actor, newest first. Backed by the
@@ -262,7 +264,7 @@ export const query_cell_list_by_kind = async (deps, kind, options) => deps.db.qu
262
264
  export const query_cell_list_by_creator = async (deps, actor_id, options) => deps.db.query(`SELECT ${cell_row_projection('cell')}
263
265
  FROM cell
264
266
  WHERE created_by = $1 AND deleted_at IS NULL
265
- ORDER BY created_at DESC
267
+ ORDER BY cell.created_at DESC
266
268
  LIMIT $2 OFFSET $3`, [actor_id, options?.limit ?? null, options?.offset ?? 0]);
267
269
  /**
268
270
  * Filterable list query for the generic `cell_list` RPC.
@@ -1 +1 @@
1
- {"version":3,"file":"fact_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/fact_queries.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fact_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/fact_queries.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * @module
13
13
  */
14
- import { columns_sql, omit_columns } from './sql_columns.js';
14
+ import { columns_sql, iso8601_timestamp_column, omit_columns } from './sql_columns.js';
15
15
  /**
16
16
  * The full `fact` column set, named explicitly so a row read fails loud on
17
17
  * schema drift (see `ACCOUNT_COLUMNS` in `auth/account_queries.ts` for the
@@ -26,6 +26,12 @@ export const FACT_COLUMNS = [
26
26
  'size',
27
27
  'created_at'
28
28
  ];
29
+ // `created_at` is deliberately *not* projected through
30
+ // `iso8601_timestamp_column` here, unlike every other table: these rows feed
31
+ // `PgFactStore`, whose `FactMeta.created_at` is a `Date` in the
32
+ // `@fuzdev/fuz_util` `FactStore` contract, and nothing serializes them. The
33
+ // one fact timestamp that does reach the wire — the orphan-sweep sample in
34
+ // `query_orphan_facts_list` — projects the ISO-8601 wire string.
29
35
  /** `FACT_COLUMNS` minus the payload — the `FactMetaRow` projection. */
30
36
  const FACT_META_COLUMNS = omit_columns(FACT_COLUMNS, 'bytes');
31
37
  /**
@@ -137,7 +143,7 @@ export const query_orphan_facts_list = async (deps, older_than, sample_limit) =>
137
143
  AND c.deleted_at IS NULL
138
144
  )
139
145
  AND ($1::timestamptz IS NULL OR f.created_at < $1::timestamptz)`, [older_than]);
140
- const sample_rows = await deps.db.query(`SELECT hash, size, created_at, external_url
146
+ const sample_rows = await deps.db.query(`SELECT hash, size, ${iso8601_timestamp_column('f', 'created_at')} AS created_at, external_url
141
147
  FROM fact f
142
148
  WHERE NOT EXISTS (
143
149
  SELECT 1 FROM cell c
@@ -153,7 +159,7 @@ export const query_orphan_facts_list = async (deps, older_than, sample_limit) =>
153
159
  sample: sample_rows.map((r) => ({
154
160
  hash: r.hash,
155
161
  size: Number(r.size),
156
- created_at: typeof r.created_at === 'string' ? r.created_at : r.created_at.toISOString(),
162
+ created_at: r.created_at,
157
163
  external_url: r.external_url
158
164
  }))
159
165
  };
@@ -10,7 +10,16 @@
10
10
  * client-safe subset — rather than spelling a second column list, so the
11
11
  * drift guard on the base const (`assert_columns_match_live` in
12
12
  * `testing/db.ts`) covers every derived projection too. Twin of the Rust
13
- * spine's `*_COLUMNS` consts + `fuz_db::qualify_columns`.
13
+ * spine's `*_COLUMNS` consts + `fuz_db::qualify_columns` / `omit_columns`.
14
+ *
15
+ * A read that needs a column rendered as something other than the bare
16
+ * reference passes a `ColumnExpr` — the `expr` override, twin of the third
17
+ * argument to `fuz_db::qualify_columns`. Every timestamp that reaches the
18
+ * wire projects through `iso8601_timestamp_column` so both spines serialize
19
+ * the same instant to the same bytes; each query module builds its override
20
+ * with `iso8601_timestamp_expr` over its table const. An override costs one
21
+ * rule — a projected `ORDER BY` must qualify its column — stated on
22
+ * `qualify_columns`.
14
23
  *
15
24
  * Placement rule: a const lives in its table's query module. When two query
16
25
  * modules project the same table (the revoke cascades in
@@ -26,13 +35,68 @@
26
35
  *
27
36
  * @module
28
37
  */
38
+ /**
39
+ * Per-column expression override for a projection — return the SQL to
40
+ * project for `column`, or `undefined` to keep the bare column reference.
41
+ *
42
+ * Twin of the `expr` closure `fuz_db::qualify_columns` takes. The Rust side
43
+ * decodes rows positionally, so its overrides need no output name; TS reads
44
+ * rows by name, so `columns_sql` / `qualify_columns` alias every override
45
+ * back to its column (`… AS created_at`) — otherwise a `to_char(…)`
46
+ * projection would arrive under Postgres' derived name and read as
47
+ * `undefined`.
48
+ *
49
+ * `undefined` is the *only* decline sentinel. An empty string is a returned
50
+ * expression, not a decline: it renders ` AS created_at` and the query fails
51
+ * to parse. This is documented rather than guarded — every override in the
52
+ * repo is a literal lookup returning a fragment or nothing, and a malformed
53
+ * projection failing loud at the first query beats silently swallowing an
54
+ * expression the caller meant to supply.
55
+ */
56
+ export type ColumnExpr = (column: string) => string | undefined;
57
+ /**
58
+ * Build a `to_char({alias}.{column} AT TIME ZONE 'UTC',
59
+ * 'YYYY-MM-DD"T"HH24:MI:SS"Z"')` fragment for embedding in a SELECT
60
+ * projection, via a `ColumnExpr` override.
61
+ *
62
+ * The format literal is the spine's canonical timestamp wire shape —
63
+ * second-precision UTC ISO-8601, exactly 20 characters — byte-identical to
64
+ * `fuz_db::iso8601_timestamp_column`, so the two backends serialize the same
65
+ * instant to the same bytes. `to_iso8601_seconds` (`timestamp.ts`) is the
66
+ * same shape for stamps minted in TS rather than read from Postgres.
67
+ *
68
+ * @param alias - the table alias or name to qualify the column with, or the
69
+ * empty string for an unqualified reference
70
+ * @param column - the timestamp column name
71
+ * @returns the `to_char(…)` fragment
72
+ */
73
+ export declare const iso8601_timestamp_column: (alias: string, column: string) => string;
74
+ /**
75
+ * Build a table's timestamp override: a `ColumnExpr` factory that projects
76
+ * each of `timestamp_columns` through `iso8601_timestamp_column` and declines
77
+ * every other column. The result takes the row qualifier — the empty string
78
+ * for a bare-table read, the alias for a JOIN — so one definition per query
79
+ * module serves every read in it.
80
+ *
81
+ * `timestamp_columns` is typed against `columns` (and checked at build time),
82
+ * so a misspelled name is a compile error and a stale one throws at module
83
+ * load rather than silently leaving a column projected as a `Date`.
84
+ *
85
+ * @param columns - the table's `*_COLUMNS` const
86
+ * @param timestamp_columns - the members of `columns` that carry timestamps
87
+ * @returns `(alias) => ColumnExpr`
88
+ * @throws Error when a name in `timestamp_columns` is not in `columns`
89
+ */
90
+ export declare const iso8601_timestamp_expr: <T extends string>(columns: ReadonlyArray<T>, timestamp_columns: ReadonlyArray<NoInfer<T>>) => ((alias: string) => ColumnExpr);
29
91
  /**
30
92
  * Render a `*_COLUMNS` const as a SQL select list, in projection order.
31
93
  *
32
94
  * @param columns - the column names
95
+ * @param expr - optional per-column expression override; an overridden
96
+ * column is aliased back to its own name
33
97
  * @returns `a, b, c`
34
98
  */
35
- export declare const columns_sql: (columns: ReadonlyArray<string>) => string;
99
+ export declare const columns_sql: (columns: ReadonlyArray<string>, expr?: ColumnExpr) => string;
36
100
  /**
37
101
  * Render a `*_COLUMNS` const as a SQL select list with every column qualified
38
102
  * by a table alias, for reads that alias the table (JOINs, the `c`-aliased
@@ -43,12 +107,25 @@ export declare const columns_sql: (columns: ReadonlyArray<string>) => string;
43
107
  * alias through gets a thrown error instead of a malformed (or injectable)
44
108
  * projection.
45
109
  *
110
+ * **An `expr` override costs one rule: an `ORDER BY` in a projected SELECT
111
+ * must qualify its column.** An override is aliased back to its own name
112
+ * (`… AS created_at`), and Postgres resolves a bare `ORDER BY created_at`
113
+ * against the *output* names first, so it would sort on the `to_char(…)`
114
+ * text — collapsing sub-second order into ties and losing the btree index (a
115
+ * `Sort` node over the expression instead of an `Index Scan`). Writing
116
+ * `ORDER BY <alias>.created_at` (or `<table>.created_at`) names the input
117
+ * column and both go away. The Rust twin needs no such rule: it decodes
118
+ * positionally, so `fuz_db::qualify_columns` emits no alias and its bare
119
+ * `ORDER BY created_at` already means the column.
120
+ *
46
121
  * @param columns - the column names
47
122
  * @param alias - the table alias or name to prefix each column with
123
+ * @param expr - optional per-column expression override; an overridden
124
+ * column is aliased back to its own name
48
125
  * @returns `alias.a, alias.b, alias.c`
49
126
  * @throws Error when `alias` is not a valid SQL identifier
50
127
  */
51
- export declare const qualify_columns: (columns: ReadonlyArray<string>, alias: string) => string;
128
+ export declare const qualify_columns: (columns: ReadonlyArray<string>, alias: string, expr?: ColumnExpr) => string;
52
129
  /**
53
130
  * Drop named columns from a `*_COLUMNS` const, preserving projection order —
54
131
  * for a read that deliberately narrows the row (a client-safe listing, a
@@ -1 +1 @@
1
- {"version":3,"file":"sql_columns.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/sql_columns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,aAAa,CAAC,MAAM,CAAC,KAAG,MAA4B,CAAC;AAE1F;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,GAAI,SAAS,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,MAAM,KAAG,MAG/E,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,MAAM,EAC5C,SAAS,aAAa,CAAC,CAAC,CAAC,EACzB,GAAG,SAAS,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAC3B,aAAa,CAAC,CAAC,CAOjB,CAAC"}
1
+ {"version":3,"file":"sql_columns.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/sql_columns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAIH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAEhE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAG,MAGS,CAAC;AAEnF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,MAAM,EACtD,SAAS,aAAa,CAAC,CAAC,CAAC,EACzB,mBAAmB,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAC1C,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,UAAU,CAYhC,CAAC;AAqBF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,UAAU,KAAG,MACvB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,eAAe,GAC3B,SAAS,aAAa,CAAC,MAAM,CAAC,EAC9B,OAAO,MAAM,EACb,OAAO,UAAU,KACf,MAGF,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,MAAM,EAC5C,SAAS,aAAa,CAAC,CAAC,CAAC,EACzB,GAAG,SAAS,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAC3B,aAAa,CAAC,CAAC,CAOjB,CAAC"}