@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.
- package/dist/actions/CLAUDE.md +15 -11
- package/dist/actions/action_rpc.d.ts +1 -1
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +4 -6
- package/dist/actions/peer_ping.d.ts +8 -0
- package/dist/actions/peer_ping.d.ts.map +1 -1
- package/dist/actions/peer_ping.js +8 -0
- package/dist/actions/peer_request.d.ts +1 -1
- package/dist/actions/peer_request.js +1 -1
- package/dist/actions/perform_action.d.ts +16 -9
- package/dist/actions/perform_action.d.ts.map +1 -1
- package/dist/actions/perform_action.js +30 -21
- package/dist/actions/register_action_ws.d.ts +1 -1
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/actions/register_action_ws.js +88 -21
- package/dist/auth/CLAUDE.md +37 -7
- package/dist/auth/account_actions.d.ts.map +1 -1
- package/dist/auth/account_actions.js +10 -1
- package/dist/auth/account_queries.d.ts.map +1 -1
- package/dist/auth/account_queries.js +36 -16
- package/dist/auth/account_schema.d.ts +20 -0
- package/dist/auth/account_schema.d.ts.map +1 -1
- package/dist/auth/account_schema.js +22 -1
- package/dist/auth/actor_search_actions.d.ts +3 -3
- package/dist/auth/actor_search_actions.d.ts.map +1 -1
- package/dist/auth/actor_search_actions.js +10 -6
- package/dist/auth/api_token_queries.d.ts.map +1 -1
- package/dist/auth/api_token_queries.js +11 -5
- package/dist/auth/app_settings_queries.d.ts.map +1 -1
- package/dist/auth/app_settings_queries.js +6 -4
- package/dist/auth/audit_log_queries.d.ts +6 -0
- package/dist/auth/audit_log_queries.d.ts.map +1 -1
- package/dist/auth/audit_log_queries.js +11 -5
- package/dist/auth/cell_actions.d.ts.map +1 -1
- package/dist/auth/cell_actions.js +3 -8
- package/dist/auth/cell_audit_actions.d.ts.map +1 -1
- package/dist/auth/cell_audit_actions.js +1 -1
- package/dist/auth/cell_field_actions.js +1 -1
- package/dist/auth/cell_grant_actions.js +1 -1
- package/dist/auth/cell_item_actions.js +1 -1
- package/dist/auth/invite_queries.d.ts.map +1 -1
- package/dist/auth/invite_queries.js +10 -8
- package/dist/auth/role_grant_offer_ddl.d.ts +11 -0
- package/dist/auth/role_grant_offer_ddl.d.ts.map +1 -1
- package/dist/auth/role_grant_offer_ddl.js +20 -2
- package/dist/auth/role_grant_offer_queries.d.ts.map +1 -1
- package/dist/auth/role_grant_offer_queries.js +29 -15
- package/dist/auth/role_grant_queries.d.ts.map +1 -1
- package/dist/auth/role_grant_queries.js +21 -7
- package/dist/auth/session_queries.d.ts.map +1 -1
- package/dist/auth/session_queries.js +9 -4
- package/dist/db/CLAUDE.md +21 -2
- package/dist/db/cell_audit_queries.js +2 -2
- package/dist/db/cell_field_queries.d.ts +1 -1
- package/dist/db/cell_field_queries.d.ts.map +1 -1
- package/dist/db/cell_field_queries.js +8 -6
- package/dist/db/cell_grant_queries.d.ts +1 -1
- package/dist/db/cell_grant_queries.d.ts.map +1 -1
- package/dist/db/cell_grant_queries.js +12 -10
- package/dist/db/cell_item_queries.d.ts +1 -1
- package/dist/db/cell_item_queries.d.ts.map +1 -1
- package/dist/db/cell_item_queries.js +9 -7
- package/dist/db/cell_queries.d.ts +3 -3
- package/dist/db/cell_queries.d.ts.map +1 -1
- package/dist/db/cell_queries.js +6 -4
- package/dist/db/fact_queries.d.ts.map +1 -1
- package/dist/db/fact_queries.js +9 -3
- package/dist/db/sql_columns.d.ts +80 -3
- package/dist/db/sql_columns.d.ts.map +1 -1
- package/dist/db/sql_columns.js +91 -4
- package/dist/http/CLAUDE.md +3 -1
- package/dist/http/jsonrpc_helpers.d.ts +13 -0
- package/dist/http/jsonrpc_helpers.d.ts.map +1 -1
- package/dist/http/jsonrpc_helpers.js +13 -0
- package/dist/server/serve_fact_route.d.ts.map +1 -1
- package/dist/server/serve_fact_route.js +7 -2
- package/dist/testing/CLAUDE.md +53 -27
- package/dist/testing/admin_integration.d.ts +0 -3
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +0 -1
- package/dist/testing/adversarial_404.d.ts.map +1 -1
- package/dist/testing/adversarial_404.js +4 -1
- package/dist/testing/adversarial_input.d.ts.map +1 -1
- package/dist/testing/adversarial_input.js +5 -4
- package/dist/testing/app_server.d.ts +4 -3
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +11 -5
- package/dist/testing/attack_surface.d.ts +16 -0
- package/dist/testing/attack_surface.d.ts.map +1 -1
- package/dist/testing/attack_surface.js +36 -13
- package/dist/testing/audit_completeness.d.ts +0 -3
- package/dist/testing/audit_completeness.d.ts.map +1 -1
- package/dist/testing/audit_completeness.js +0 -1
- package/dist/testing/auth_apps.d.ts +9 -2
- package/dist/testing/auth_apps.d.ts.map +1 -1
- package/dist/testing/auth_apps.js +9 -2
- package/dist/testing/cross_backend/account_lifecycle.d.ts +5 -4
- package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -1
- package/dist/testing/cross_backend/account_lifecycle.js +7 -0
- package/dist/testing/cross_backend/action_manifest.d.ts +19 -3
- package/dist/testing/cross_backend/action_manifest.d.ts.map +1 -1
- package/dist/testing/cross_backend/action_manifest.js +10 -4
- package/dist/testing/cross_backend/action_manifest_parity.d.ts +9 -3
- package/dist/testing/cross_backend/action_manifest_parity.d.ts.map +1 -1
- package/dist/testing/cross_backend/action_manifest_parity.js +6 -0
- package/dist/testing/cross_backend/actor_lookup.d.ts +3 -2
- package/dist/testing/cross_backend/actor_lookup.d.ts.map +1 -1
- package/dist/testing/cross_backend/body_size.d.ts +4 -2
- package/dist/testing/cross_backend/body_size.d.ts.map +1 -1
- package/dist/testing/cross_backend/body_size.js +1 -1
- package/dist/testing/cross_backend/cell_crud.d.ts +2 -2
- package/dist/testing/cross_backend/cell_crud.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_crud.js +10 -0
- package/dist/testing/cross_backend/cell_gated_create.d.ts +3 -3
- package/dist/testing/cross_backend/cell_gated_create.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_grant_role.d.ts +2 -2
- package/dist/testing/cross_backend/cell_grant_role.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_relations.d.ts +2 -2
- package/dist/testing/cross_backend/cell_relations.d.ts.map +1 -1
- package/dist/testing/cross_backend/fact_serving.d.ts +2 -2
- package/dist/testing/cross_backend/fact_serving.d.ts.map +1 -1
- package/dist/testing/cross_backend/make_cross_backend_project.d.ts +17 -2
- package/dist/testing/cross_backend/make_cross_backend_project.d.ts.map +1 -1
- package/dist/testing/cross_backend/make_cross_backend_project.js +23 -3
- package/dist/testing/cross_backend/origin.d.ts +4 -2
- package/dist/testing/cross_backend/origin.d.ts.map +1 -1
- package/dist/testing/cross_backend/origin.js +1 -1
- package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -1
- package/dist/testing/cross_backend/peer_ping_ws.js +11 -7
- package/dist/testing/cross_backend/query_shape.d.ts +6 -5
- package/dist/testing/cross_backend/query_shape.d.ts.map +1 -1
- package/dist/testing/cross_backend/ready.d.ts +2 -2
- package/dist/testing/cross_backend/ready.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_offer_enumeration.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_offer_enumeration.js +7 -1
- package/dist/testing/cross_backend/setup.d.ts +26 -6
- package/dist/testing/cross_backend/setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/standard.d.ts +5 -1
- package/dist/testing/cross_backend/standard.d.ts.map +1 -1
- package/dist/testing/cross_backend/standard.js +1 -5
- package/dist/testing/cross_backend/testing_backdoor.js +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +5 -0
- package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
- package/dist/testing/cross_backend/token_lifetime.d.ts.map +1 -1
- package/dist/testing/cross_backend/token_lifetime.js +6 -0
- package/dist/testing/cross_backend/token_scope_surface.d.ts +2 -2
- package/dist/testing/cross_backend/token_scope_surface.d.ts.map +1 -1
- package/dist/testing/cross_backend/wire_shapes.d.ts +22 -0
- package/dist/testing/cross_backend/wire_shapes.d.ts.map +1 -0
- package/dist/testing/cross_backend/wire_shapes.js +41 -0
- package/dist/testing/data_exposure.d.ts +0 -3
- package/dist/testing/data_exposure.d.ts.map +1 -1
- package/dist/testing/data_exposure.js +0 -1
- package/dist/testing/db.d.ts +44 -7
- package/dist/testing/db.d.ts.map +1 -1
- package/dist/testing/db.js +62 -27
- package/dist/testing/integration.d.ts.map +1 -1
- package/dist/testing/integration.js +15 -2
- package/dist/testing/round_trip.d.ts +0 -3
- package/dist/testing/round_trip.d.ts.map +1 -1
- package/dist/testing/round_trip.js +0 -4
- package/dist/testing/rpc_attack_surface.js +2 -2
- package/dist/testing/rpc_round_trip.d.ts +0 -3
- package/dist/testing/rpc_round_trip.d.ts.map +1 -1
- package/dist/testing/rpc_round_trip.js +0 -1
- package/dist/testing/schema_generators.d.ts +15 -0
- package/dist/testing/schema_generators.d.ts.map +1 -1
- package/dist/testing/schema_generators.js +45 -11
- package/dist/testing/standard.d.ts +5 -1
- package/dist/testing/standard.d.ts.map +1 -1
- package/dist/testing/standard.js +2 -7
- package/dist/timestamp.d.ts +58 -0
- package/dist/timestamp.d.ts.map +1 -0
- package/dist/timestamp.js +57 -0
- package/dist/ui/RoleGrantOfferHistory.svelte +3 -1
- package/dist/ui/RoleGrantOfferHistory.svelte.d.ts.map +1 -1
- package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -1
- package/dist/ui/role_grant_offers_state.svelte.js +6 -2
- 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,
|
|
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
|
|
@@ -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,
|
|
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
|
|
@@ -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,
|
|
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:
|
|
53
|
-
updated_at:
|
|
54
|
-
deleted_at:
|
|
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":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAIjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,OAAO;IACvB,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,cAAc,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"cell_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/cell_queries.ts"],"names":[],"mappings":"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"}
|
package/dist/db/cell_queries.js
CHANGED
|
@@ -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":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAGjE,0CAA0C;AAC1C,MAAM,WAAW,OAAO;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAK5B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,UAAU,EAAE,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,kFAOwB,CAAC;
|
|
1
|
+
{"version":3,"file":"fact_queries.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/fact_queries.ts"],"names":[],"mappings":"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"}
|
package/dist/db/fact_queries.js
CHANGED
|
@@ -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:
|
|
162
|
+
created_at: r.created_at,
|
|
157
163
|
external_url: r.external_url
|
|
158
164
|
}))
|
|
159
165
|
};
|
package/dist/db/sql_columns.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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"}
|