@fuzdev/fuz_app 0.143.0 → 0.145.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/auth/CLAUDE.md +8 -0
- package/dist/auth/cell_action_specs.d.ts +13 -0
- package/dist/auth/cell_action_specs.d.ts.map +1 -1
- package/dist/auth/cell_action_specs.js +13 -0
- package/dist/auth/cell_actions.d.ts +7 -0
- package/dist/auth/cell_actions.d.ts.map +1 -1
- package/dist/auth/cell_actions.js +30 -0
- package/dist/auth/cell_ref_admission.d.ts +51 -0
- package/dist/auth/cell_ref_admission.d.ts.map +1 -0
- package/dist/auth/cell_ref_admission.js +69 -0
- package/dist/auth/deps.d.ts +6 -3
- package/dist/auth/deps.d.ts.map +1 -1
- package/dist/db/CLAUDE.md +40 -23
- package/dist/db/cell_ddl.d.ts +3 -2
- package/dist/db/cell_ddl.d.ts.map +1 -1
- package/dist/db/cell_ddl.js +3 -2
- package/dist/db/cell_queries.d.ts +31 -6
- package/dist/db/cell_queries.d.ts.map +1 -1
- package/dist/db/cell_queries.js +45 -18
- package/dist/db/fact_ddl.d.ts +30 -4
- package/dist/db/fact_ddl.d.ts.map +1 -1
- package/dist/db/fact_ddl.js +44 -4
- package/dist/db/fact_holder_queries.d.ts +70 -0
- package/dist/db/fact_holder_queries.d.ts.map +1 -0
- package/dist/db/fact_holder_queries.js +79 -0
- package/dist/db/fact_queries.d.ts +19 -14
- package/dist/db/fact_queries.d.ts.map +1 -1
- package/dist/db/fact_queries.js +31 -10
- package/dist/db/fact_store.d.ts +65 -9
- package/dist/db/fact_store.d.ts.map +1 -1
- package/dist/db/fact_store.js +49 -20
- package/dist/server/fact_security_headers.d.ts +54 -0
- package/dist/server/fact_security_headers.d.ts.map +1 -0
- package/dist/server/fact_security_headers.js +53 -0
- package/dist/server/serve_fact_route.d.ts +33 -7
- package/dist/server/serve_fact_route.d.ts.map +1 -1
- package/dist/server/serve_fact_route.js +36 -32
- package/dist/server/x_accel.d.ts +106 -30
- package/dist/server/x_accel.d.ts.map +1 -1
- package/dist/server/x_accel.js +533 -86
- package/dist/testing/CLAUDE.md +25 -1
- package/dist/testing/cross_backend/cell_crud.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_crud.js +6 -3
- package/dist/testing/cross_backend/cell_gated_create.d.ts.map +1 -1
- package/dist/testing/cross_backend/cell_gated_create.js +25 -16
- package/dist/testing/cross_backend/cell_ref_admission.d.ts +4 -0
- package/dist/testing/cross_backend/cell_ref_admission.d.ts.map +1 -0
- package/dist/testing/cross_backend/cell_ref_admission.js +268 -0
- package/dist/testing/cross_backend/expected_schema.json +66 -10
- package/dist/testing/cross_backend/fact_serving.d.ts +19 -1
- package/dist/testing/cross_backend/fact_serving.d.ts.map +1 -1
- package/dist/testing/cross_backend/fact_serving.js +31 -9
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +6 -2
- package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.js +13 -3
- package/package.json +3 -3
|
@@ -26,7 +26,10 @@ import '../assert_dev_env.js';
|
|
|
26
26
|
*
|
|
27
27
|
* Facts are seeded **embedded** via `_testing_put_fact` (the cross-process
|
|
28
28
|
* driver has no DB handle); the referencing cell via the `cell_create` RPC
|
|
29
|
-
* (
|
|
29
|
+
* (the hash, a whole string value in `data`, is derived into `cell.refs`). A
|
|
30
|
+
* non-admin owner's cell may reference only a fact it holds, so a fact a
|
|
31
|
+
* non-admin references is put with that owner as its `holder` (the keeper is
|
|
32
|
+
* a global admin, whom ref admission doesn't gate). Gated
|
|
30
33
|
* on `capabilities.fact_serving`; runs under every `cross_backend_*` project —
|
|
31
34
|
* the TS spine binary and the Rust `testing_spine_stub` both mount the serve
|
|
32
35
|
* routes + the seeder.
|
|
@@ -52,6 +55,21 @@ const NIL_UUID = '00000000-0000-0000-0000-000000000000';
|
|
|
52
55
|
* fails here rather than silently downstream.
|
|
53
56
|
*/
|
|
54
57
|
const TestingPutFactOutput = z.strictObject({ hash: FactHashSchema });
|
|
58
|
+
/**
|
|
59
|
+
* Seed an embedded fact over the daemon channel via `_testing_put_fact`;
|
|
60
|
+
* returns its `blake3:` hash. A `holder` is recorded in `fact_holder` (a
|
|
61
|
+
* deduplicated put included), as a real upload records its uploader.
|
|
62
|
+
*
|
|
63
|
+
* @param fixture - the test fixture (its daemon token drives the backdoor)
|
|
64
|
+
* @param rpc_path - the backend's RPC path
|
|
65
|
+
* @param input - the content, optional content type, and optional holder
|
|
66
|
+
* @returns the fact hash
|
|
67
|
+
*/
|
|
68
|
+
export const cross_put_fact = async (fixture, rpc_path, input) => expect_output(await cross_rpc_call(
|
|
69
|
+
// Origin-free transport — the daemon-token middleware discards the
|
|
70
|
+
// credential when an `Origin` / `Referer` is present (browser
|
|
71
|
+
// context), and cross-process `fixture.transport` auto-adds `Origin`.
|
|
72
|
+
fixture.fresh_transport({ origin: null }), rpc_path, '_testing_put_fact', input, fixture.create_daemon_token_headers()), TestingPutFactOutput).hash;
|
|
55
73
|
/** GET a fact over a cross-process `FetchTransport`; returns `{status, content_type, text}`. */
|
|
56
74
|
const fact_get = async (transport, path, headers) => {
|
|
57
75
|
const res = await transport(path, { method: 'GET', headers });
|
|
@@ -64,12 +82,8 @@ const fact_get = async (transport, path, headers) => {
|
|
|
64
82
|
export const describe_fact_serving_cross_tests = (options) => {
|
|
65
83
|
const { setup_test, setup_test_multi_actor, capabilities } = options;
|
|
66
84
|
const rpc_path = options.rpc_path ?? SPINE_RPC_PATH;
|
|
67
|
-
/** Seed an embedded fact
|
|
68
|
-
const put_fact =
|
|
69
|
-
// Origin-free transport — the daemon-token middleware discards the
|
|
70
|
-
// credential when an `Origin` / `Referer` is present (browser
|
|
71
|
-
// context), and cross-process `fixture.transport` auto-adds `Origin`.
|
|
72
|
-
fixture.fresh_transport({ origin: null }), rpc_path, '_testing_put_fact', content_type === undefined ? { content } : { content, content_type }, fixture.create_daemon_token_headers()), TestingPutFactOutput).hash;
|
|
85
|
+
/** Seed an embedded system-put fact; returns its `blake3:` hash. */
|
|
86
|
+
const put_fact = (fixture, content, content_type) => cross_put_fact(fixture, rpc_path, content_type === undefined ? { content } : { content, content_type });
|
|
73
87
|
/**
|
|
74
88
|
* Create a cell referencing `hash` (`extract_refs` lifts it into `cell.refs`).
|
|
75
89
|
* Pass `acting` when the caller's account holds more than one actor —
|
|
@@ -96,8 +110,16 @@ export const describe_fact_serving_cross_tests = (options) => {
|
|
|
96
110
|
const fixture = await setup_test();
|
|
97
111
|
const a = await fixture.create_account({ username: 'fact_owner_a' });
|
|
98
112
|
const b = await fixture.create_account({ username: 'fact_owner_b' });
|
|
99
|
-
// One fact, identical bytes
|
|
100
|
-
|
|
113
|
+
// One fact, identical bytes put by both owners — deduped to a single
|
|
114
|
+
// row, each owner a holder.
|
|
115
|
+
const hash = await cross_put_fact(fixture, rpc_path, {
|
|
116
|
+
content: 'shared-deduped-bytes',
|
|
117
|
+
holder: a.actor.id
|
|
118
|
+
});
|
|
119
|
+
assert.strictEqual(await cross_put_fact(fixture, rpc_path, {
|
|
120
|
+
content: 'shared-deduped-bytes',
|
|
121
|
+
holder: b.actor.id
|
|
122
|
+
}), hash);
|
|
101
123
|
const t = fixture.fresh_transport();
|
|
102
124
|
const a_cell = await create_cell_with_ref(t, a.create_session_headers(), hash, 'private');
|
|
103
125
|
const b_cell = await create_cell_with_ref(t, b.create_session_headers(), hash, 'public');
|
|
@@ -261,8 +261,11 @@ export declare const create_testing_drain_effects_action: (audit: AuditEmitter)
|
|
|
261
261
|
* cross-process fact-serving suite, which drives over real HTTP and has no
|
|
262
262
|
* `PgFactStore` to call. Hashes the UTF-8 `content` (blake3, via
|
|
263
263
|
* `fact_hash_bytes` — the same hash the Rust `_testing_put_fact` computes),
|
|
264
|
-
* inserts the row idempotently, and returns `{hash}`.
|
|
265
|
-
*
|
|
264
|
+
* inserts the row idempotently, and returns `{hash}`. `holder` names the actor
|
|
265
|
+
* the put is on behalf of — recorded in `fact_holder` (deduplicated puts
|
|
266
|
+
* included), as a real upload records its uploader, so the suites can drive
|
|
267
|
+
* cell ref admission; absent, the put is a system put with no holder. The
|
|
268
|
+
* referencing cell is seeded separately via the `cell_create` RPC. Embedded-only is enough for the
|
|
266
269
|
* authz assertions (cell-scoped admit, cross-owner-no-leak, 404-mask, bare-hash
|
|
267
270
|
* admin-only); external / X-Accel parity stays covered by the forge's own gate.
|
|
268
271
|
*
|
|
@@ -283,6 +286,7 @@ export declare const testing_put_fact_action_spec: {
|
|
|
283
286
|
readonly input: z.ZodObject<{
|
|
284
287
|
content: z.ZodString;
|
|
285
288
|
content_type: z.ZodOptional<z.ZodString>;
|
|
289
|
+
holder: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
|
|
286
290
|
}, z.core.$strict>;
|
|
287
291
|
readonly output: z.ZodObject<{
|
|
288
292
|
hash: z.ZodString & z.ZodType<import("@fuzdev/fuz_util/hash_schemas.js").FactHash, string, z.core.$ZodTypeInternals<import("@fuzdev/fuz_util/hash_schemas.js").FactHash, string>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing_reset_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/testing_reset_actions.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"testing_reset_actions.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/testing_reset_actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -83,6 +83,7 @@ import { jsonrpc_errors } from '../../http/jsonrpc_errors.js';
|
|
|
83
83
|
import { emit_after_commit } from '../../http/pending_effects.js';
|
|
84
84
|
import { protocol_action_specs } from '../../actions/protocol.js';
|
|
85
85
|
import { query_put_fact } from '../../db/fact_queries.js';
|
|
86
|
+
import { query_put_fact_holder } from '../../db/fact_holder_queries.js';
|
|
86
87
|
import { ROLE_ADMIN, ROLE_KEEPER } from '../../auth/role_schema.js';
|
|
87
88
|
import { query_schema_snapshot, SchemaSnapshot, query_migration_tracker, MigrationTracker } from '../schema_introspect.js';
|
|
88
89
|
import { ActionManifest, build_action_manifest } from './action_manifest.js';
|
|
@@ -262,8 +263,11 @@ export const create_testing_drain_effects_action = (audit) => rpc_action(testing
|
|
|
262
263
|
* cross-process fact-serving suite, which drives over real HTTP and has no
|
|
263
264
|
* `PgFactStore` to call. Hashes the UTF-8 `content` (blake3, via
|
|
264
265
|
* `fact_hash_bytes` — the same hash the Rust `_testing_put_fact` computes),
|
|
265
|
-
* inserts the row idempotently, and returns `{hash}`.
|
|
266
|
-
*
|
|
266
|
+
* inserts the row idempotently, and returns `{hash}`. `holder` names the actor
|
|
267
|
+
* the put is on behalf of — recorded in `fact_holder` (deduplicated puts
|
|
268
|
+
* included), as a real upload records its uploader, so the suites can drive
|
|
269
|
+
* cell ref admission; absent, the put is a system put with no holder. The
|
|
270
|
+
* referencing cell is seeded separately via the `cell_create` RPC. Embedded-only is enough for the
|
|
267
271
|
* authz assertions (cell-scoped admit, cross-owner-no-leak, 404-mask, bare-hash
|
|
268
272
|
* admin-only); external / X-Accel parity stays covered by the forge's own gate.
|
|
269
273
|
*
|
|
@@ -279,7 +283,8 @@ export const testing_put_fact_action_spec = {
|
|
|
279
283
|
side_effects: true,
|
|
280
284
|
input: z.strictObject({
|
|
281
285
|
content: z.string(),
|
|
282
|
-
content_type: z.string().optional()
|
|
286
|
+
content_type: z.string().optional(),
|
|
287
|
+
holder: Uuid.optional()
|
|
283
288
|
}),
|
|
284
289
|
output: z.strictObject({ hash: FactHashSchema }),
|
|
285
290
|
async: true,
|
|
@@ -719,6 +724,11 @@ export const create_testing_actions = (deps, options) => {
|
|
|
719
724
|
content_type: input.content_type ?? null,
|
|
720
725
|
size: bytes.length
|
|
721
726
|
});
|
|
727
|
+
// the holder row, on a dedup hit too (`PgFactStore`'s put records it the
|
|
728
|
+
// same way); an unknown actor fails the FK
|
|
729
|
+
if (input.holder !== undefined) {
|
|
730
|
+
await query_put_fact_holder({ db: ctx.db }, input.holder, hash);
|
|
731
|
+
}
|
|
722
732
|
return { hash };
|
|
723
733
|
}),
|
|
724
734
|
create_testing_drain_effects_action(deps.audit),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuzdev/fuz_app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.145.0",
|
|
4
4
|
"description": "fullstack app library",
|
|
5
5
|
"glyph": "🗝",
|
|
6
6
|
"logo": "logo.svg",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@fuzdev/fuz_css": ">=0.70.0",
|
|
37
37
|
"@fuzdev/fuz_schema": "^0.5.0",
|
|
38
38
|
"@fuzdev/fuz_util": ">=0.77.0",
|
|
39
|
-
"@fuzdev/pglet-wasm": ">=0.1.
|
|
39
|
+
"@fuzdev/pglet-wasm": ">=0.1.2",
|
|
40
40
|
"@hono/bun": ">=1",
|
|
41
41
|
"@hono/deno": ">=1",
|
|
42
42
|
"@hono/node-server": ">=1",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"@fuzdev/fuz_util": "^0.77.0",
|
|
99
99
|
"@fuzdev/gro": "^0.220.0",
|
|
100
100
|
"@fuzdev/mdz": "^0.6.0",
|
|
101
|
-
"@fuzdev/pglet-wasm": "^0.1.
|
|
101
|
+
"@fuzdev/pglet-wasm": "^0.1.2",
|
|
102
102
|
"@hono/bun": "^1.0.1",
|
|
103
103
|
"@hono/deno": "^1.0.3",
|
|
104
104
|
"@hono/node-server": "^1.19.14",
|