@fuzdev/fuz_app 0.89.0 → 0.91.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 +7 -0
- package/dist/auth/account_action_specs.d.ts +1 -1
- package/dist/auth/account_route_schema.d.ts +2 -2
- package/dist/auth/account_schema.d.ts +3 -3
- package/dist/auth/admin_action_specs.d.ts +8 -8
- package/dist/auth/all_cell_actions.d.ts +35 -0
- package/dist/auth/all_cell_actions.d.ts.map +1 -0
- package/dist/auth/all_cell_actions.js +32 -0
- package/dist/auth/audit_log_schema.d.ts +1 -1
- package/dist/auth/invite_schema.d.ts +2 -2
- package/dist/auth/signup_route_schema.d.ts +2 -2
- package/dist/auth/signup_route_schema.d.ts.map +1 -1
- package/dist/auth/signup_route_schema.js +2 -2
- package/dist/primitive_schemas.d.ts +27 -1
- package/dist/primitive_schemas.d.ts.map +1 -1
- package/dist/primitive_schemas.js +55 -2
- package/dist/server/env.d.ts +1 -1
- package/dist/server/env.d.ts.map +1 -1
- package/dist/server/env.js +15 -3
- package/dist/testing/CLAUDE.md +135 -10
- package/dist/testing/app_server.d.ts +16 -5
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +3 -1
- package/dist/testing/cross_backend/action_manifest.d.ts +113 -0
- package/dist/testing/cross_backend/action_manifest.d.ts.map +1 -0
- package/dist/testing/cross_backend/action_manifest.js +89 -0
- package/dist/testing/cross_backend/action_manifest_parity.d.ts +67 -0
- package/dist/testing/cross_backend/action_manifest_parity.d.ts.map +1 -0
- package/dist/testing/cross_backend/action_manifest_parity.js +88 -0
- package/dist/testing/cross_backend/capabilities.d.ts +47 -30
- package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
- package/dist/testing/cross_backend/capabilities.js +19 -4
- package/dist/testing/cross_backend/default_backend_configs.d.ts +31 -15
- package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_backend_configs.js +30 -14
- package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_spine_surface.js +6 -0
- package/dist/testing/cross_backend/full_spine_mount.d.ts +81 -0
- package/dist/testing/cross_backend/full_spine_mount.d.ts.map +1 -0
- package/dist/testing/cross_backend/full_spine_mount.js +49 -0
- package/dist/testing/cross_backend/identity_parity.d.ts +13 -0
- package/dist/testing/cross_backend/identity_parity.d.ts.map +1 -0
- package/dist/testing/cross_backend/identity_parity.js +465 -0
- package/dist/testing/cross_backend/method_coverage.d.ts +71 -0
- package/dist/testing/cross_backend/method_coverage.d.ts.map +1 -0
- package/dist/testing/cross_backend/method_coverage.js +89 -0
- package/dist/testing/cross_backend/setup.d.ts +21 -0
- package/dist/testing/cross_backend/setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/setup.js +33 -1
- package/dist/testing/cross_backend/testing_backdoor.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_backdoor.js +9 -5
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +76 -2
- package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.js +63 -2
- package/dist/testing/schema_generators.d.ts.map +1 -1
- package/dist/testing/schema_generators.js +7 -0
- package/package.json +2 -2
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import '../assert_dev_env.js';
|
|
2
|
+
/** The auth axes compared as scalars (`'none' | 'optional' | 'required'`). */
|
|
3
|
+
const AUTH_SCALAR_FIELDS = ['account', 'actor'];
|
|
4
|
+
/** The auth axes compared as sorted string lists. */
|
|
5
|
+
const AUTH_LIST_FIELDS = ['roles', 'credential_types'];
|
|
6
|
+
/** Positional string-list equality (entries are pre-sorted by `build_action_manifest`). */
|
|
7
|
+
const string_lists_equal = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
|
|
8
|
+
/**
|
|
9
|
+
* Structural diff between two manifests — empty array means parity holds.
|
|
10
|
+
*
|
|
11
|
+
* Order is deterministic: methods in sorted order, with each method's
|
|
12
|
+
* side-effect + auth-field sub-diffs grouped together.
|
|
13
|
+
*/
|
|
14
|
+
export const diff_action_manifests = (a, b) => {
|
|
15
|
+
const diffs = [];
|
|
16
|
+
const a_by = new Map(a.methods.map((m) => [m.method, m]));
|
|
17
|
+
const b_by = new Map(b.methods.map((m) => [m.method, m]));
|
|
18
|
+
const all_methods = new Set([...a_by.keys(), ...b_by.keys()]);
|
|
19
|
+
for (const method of [...all_methods].sort()) {
|
|
20
|
+
const ea = a_by.get(method);
|
|
21
|
+
const eb = b_by.get(method);
|
|
22
|
+
if (!ea) {
|
|
23
|
+
diffs.push({ kind: 'method_only_in', where: 'b', method });
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (!eb) {
|
|
27
|
+
diffs.push({ kind: 'method_only_in', where: 'a', method });
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (ea.side_effects !== eb.side_effects) {
|
|
31
|
+
diffs.push({ kind: 'side_effects_differ', method, a: ea.side_effects, b: eb.side_effects });
|
|
32
|
+
}
|
|
33
|
+
for (const field of AUTH_SCALAR_FIELDS) {
|
|
34
|
+
if (ea[field] !== eb[field]) {
|
|
35
|
+
diffs.push({ kind: 'auth_field_differs', method, field, a: ea[field], b: eb[field] });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (const field of AUTH_LIST_FIELDS) {
|
|
39
|
+
if (!string_lists_equal(ea[field], eb[field])) {
|
|
40
|
+
diffs.push({ kind: 'auth_field_differs', method, field, a: ea[field], b: eb[field] });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return diffs;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Render a diff list as a human-readable multi-line string. Empty diffs
|
|
48
|
+
* produce an empty string.
|
|
49
|
+
*/
|
|
50
|
+
export const format_action_manifest_diffs = (diffs, labels = {}) => {
|
|
51
|
+
if (diffs.length === 0)
|
|
52
|
+
return '';
|
|
53
|
+
const label_a = labels.a ?? 'a';
|
|
54
|
+
const label_b = labels.b ?? 'b';
|
|
55
|
+
const where_label = (where) => (where === 'a' ? label_a : label_b);
|
|
56
|
+
const lines = [];
|
|
57
|
+
for (const d of diffs) {
|
|
58
|
+
switch (d.kind) {
|
|
59
|
+
case 'method_only_in':
|
|
60
|
+
lines.push(` method ${d.method} only in ${where_label(d.where)}`);
|
|
61
|
+
break;
|
|
62
|
+
case 'side_effects_differ':
|
|
63
|
+
lines.push(` ${d.method} side_effects differs: ${label_a}=${d.a}, ${label_b}=${d.b}`);
|
|
64
|
+
break;
|
|
65
|
+
case 'auth_field_differs':
|
|
66
|
+
lines.push(` ${d.method} auth.${d.field} differs: ${label_a}=${JSON.stringify(d.a)}, ${label_b}=${JSON.stringify(d.b)}`);
|
|
67
|
+
break;
|
|
68
|
+
default:
|
|
69
|
+
// Compile-time exhaustiveness — a new variant without a case here
|
|
70
|
+
// makes `d` non-never and fails type-check.
|
|
71
|
+
d;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return lines.join('\n');
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Throw if the two manifests disagree. The error message names the impls
|
|
79
|
+
* (via `labels`) and lists every diff, so the failure is self-diagnosing.
|
|
80
|
+
*/
|
|
81
|
+
export const assert_action_manifests_equal = (a, b, labels = {}) => {
|
|
82
|
+
const diffs = diff_action_manifests(a, b);
|
|
83
|
+
if (diffs.length === 0)
|
|
84
|
+
return;
|
|
85
|
+
const label_a = labels.a ?? 'a';
|
|
86
|
+
const label_b = labels.b ?? 'b';
|
|
87
|
+
throw new Error(`Action-manifest parity failed: ${diffs.length} diff(s) between ${label_a} and ${label_b}\n${format_action_manifest_diffs(diffs, labels)}`);
|
|
88
|
+
};
|
|
@@ -1,40 +1,45 @@
|
|
|
1
1
|
import '../assert_dev_env.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Backend wiring facts recorded for documentation — **not** gating flags.
|
|
4
|
+
*
|
|
5
|
+
* The companion to `BackendCapabilities`: where each capability flag has a
|
|
6
|
+
* `test_if(capabilities.X, ...)` reader that skips a suite the backend doesn't
|
|
7
|
+
* implement, nothing reads these. They record middleware / limiter wiring that
|
|
8
|
+
* differs between the TS and Rust families (a backend-shape record) but gates
|
|
9
|
+
* no cross test today. They live in their own type precisely so
|
|
10
|
+
* `BackendCapabilities` stops claiming gating power it doesn't have — fold a
|
|
11
|
+
* flag in here the moment it has no `test_if` reader, and promote it back the
|
|
12
|
+
* day a suite genuinely gates on it.
|
|
6
13
|
*/
|
|
7
|
-
export interface
|
|
14
|
+
export interface BackendShapeNotes {
|
|
8
15
|
/**
|
|
9
|
-
* Bearer
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* this flag — the bearer-token cases in `describe_standard_integration_tests`
|
|
14
|
-
* / `describe_rate_limiting_tests` run unconditionally (every spine wires
|
|
15
|
-
* bearer auth). Fold into a typed capability taxonomy if these gain real
|
|
16
|
-
* gating readers.
|
|
16
|
+
* Bearer-token auth (`Authorization: Bearer <token>`) is wired through the
|
|
17
|
+
* backend's middleware stack. `true` on every spine — the bearer-token cases
|
|
18
|
+
* in `describe_standard_integration_tests` / `describe_rate_limiting_tests`
|
|
19
|
+
* run unconditionally.
|
|
17
20
|
*/
|
|
18
21
|
readonly bearer_auth: boolean;
|
|
19
22
|
/**
|
|
20
|
-
* Trusted-proxy XFF parsing
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* the proxy-default difference between the TS family (`false`) and the Rust
|
|
25
|
-
* family (`true`). Fold into a typed capability taxonomy if it gains real
|
|
26
|
-
* gating readers.
|
|
23
|
+
* Trusted-proxy XFF parsing (`X-Forwarded-For` etc.) is wired. Records the
|
|
24
|
+
* proxy-default difference between the TS family (`false` — the test binary
|
|
25
|
+
* leaves proxy parsing off) and the Rust family (`true` — the client-IP
|
|
26
|
+
* middleware is always wired; the env-gate only chooses XFF vs the TCP peer).
|
|
27
27
|
*/
|
|
28
28
|
readonly trusted_proxy: boolean;
|
|
29
29
|
/**
|
|
30
|
-
* Per-account login rate limiting is wired.
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* this flag; the `describe_rate_limiting_tests` per-account cases are
|
|
34
|
-
* in-process-only and don't cross a process boundary. Fold into a typed
|
|
35
|
-
* capability taxonomy if it gains real gating readers.
|
|
30
|
+
* Per-account login rate limiting is wired. `false` for the TS family (the
|
|
31
|
+
* canonical path leaves the limiter null in test mode), `true` for the Rust
|
|
32
|
+
* family (env-gated bucket on `/login` + `/password`).
|
|
36
33
|
*/
|
|
37
34
|
readonly login_rate_limit: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Optional behaviors a backend may support. Each flag's TSDoc names the
|
|
38
|
+
* tests that gate on it; add a new flag here before referencing it from
|
|
39
|
+
* a suite body, and document the gating tests inline. Wiring facts that gate
|
|
40
|
+
* nothing belong in `BackendShapeNotes`, not here.
|
|
41
|
+
*/
|
|
42
|
+
export interface BackendCapabilities {
|
|
38
43
|
/**
|
|
39
44
|
* WebSocket transport is reachable end-to-end. Gates the cross-process
|
|
40
45
|
* WS round-trip suite; the in-process `describe_ws_round_trip_tests`
|
|
@@ -73,10 +78,16 @@ export interface BackendCapabilities {
|
|
|
73
78
|
* The account-lifecycle admin verbs (`account_delete` soft-delete,
|
|
74
79
|
* `account_undelete` reactivation, `account_purge` keeper hard-delete)
|
|
75
80
|
* are live-mounted on the backend's RPC path. Gates the dedicated
|
|
76
|
-
* `describe_account_lifecycle_cross_tests` suite.
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
81
|
+
* `describe_account_lifecycle_cross_tests` suite.
|
|
82
|
+
*
|
|
83
|
+
* Unlike cells / fact-serving / ws / sse, these verbs **are** on the
|
|
84
|
+
* standard declared surface — they live in `create_admin_actions`, so
|
|
85
|
+
* `create_spine_surface_spec` carries them and the spec-derived round-trip
|
|
86
|
+
* + attack-surface suites already auto-enumerate their wire shape + auth.
|
|
87
|
+
* This flag gates the *behavioral* parity the generic round-trip can't
|
|
88
|
+
* provide: it can't drive verbs that delete their own subject (soft-delete →
|
|
89
|
+
* undelete round-trip, keeper-confirmed purge, the keeper-guard refusal), so
|
|
90
|
+
* the dedicated cross suite adds them.
|
|
80
91
|
*/
|
|
81
92
|
readonly account_lifecycle: boolean;
|
|
82
93
|
/**
|
|
@@ -136,13 +147,19 @@ export interface BackendCapabilities {
|
|
|
136
147
|
* declare each flag explicitly per backend.
|
|
137
148
|
*/
|
|
138
149
|
export declare const in_process_capabilities: BackendCapabilities;
|
|
150
|
+
/**
|
|
151
|
+
* Shape notes for the in-process Hono transport — every wiring fact present
|
|
152
|
+
* (the in-process app exercises the full middleware stack). Documentation
|
|
153
|
+
* only, like every `BackendShapeNotes` (nothing reads it).
|
|
154
|
+
*/
|
|
155
|
+
export declare const in_process_shape_notes: BackendShapeNotes;
|
|
139
156
|
/**
|
|
140
157
|
* Conditional `test()` wrapper — registers a vitest case only when
|
|
141
158
|
* `cond` is true; otherwise registers it as `.skip` so the run still
|
|
142
159
|
* surfaces the gated coverage in the report.
|
|
143
160
|
*
|
|
144
161
|
* Thin wrapper around vitest's `test.skipIf(!cond)` with the argument
|
|
145
|
-
* order flipped to match the more readable `test_if(capabilities.
|
|
162
|
+
* order flipped to match the more readable `test_if(capabilities.ws, ...)`
|
|
146
163
|
* call pattern.
|
|
147
164
|
*/
|
|
148
165
|
export declare const test_if: (cond: boolean, name: string, fn: () => void | Promise<void>) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAwC9B;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,kCAAkC,EAAE,OAAO,CAAC;CACrD;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,mBAUpC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,iBAInC,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,EAAE,IAAI,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAG,IAMrF,CAAC"}
|
|
@@ -24,6 +24,14 @@ import '../assert_dev_env.js';
|
|
|
24
24
|
* - `rust_spine_stub_capabilities` — fuz_app's Rust spine-stub preset, in
|
|
25
25
|
* `rust_spine_stub_backend_config.ts` (delta off the rust family default).
|
|
26
26
|
*
|
|
27
|
+
* **Gating flags vs shape notes.** `BackendCapabilities` holds only flags a
|
|
28
|
+
* suite actually gates on (each has a `test_if(capabilities.X, ...)` reader).
|
|
29
|
+
* Wiring facts that gate nothing — `bearer_auth` / `trusted_proxy` /
|
|
30
|
+
* `login_rate_limit` — live in the parallel `BackendShapeNotes` record
|
|
31
|
+
* (`in_process_shape_notes` here, `ts_default_shape_notes` /
|
|
32
|
+
* `rust_default_shape_notes` in `default_backend_configs.ts`) so the
|
|
33
|
+
* capability type never claims gating power it doesn't have.
|
|
34
|
+
*
|
|
27
35
|
* @module
|
|
28
36
|
*/
|
|
29
37
|
import { test } from 'vitest';
|
|
@@ -34,9 +42,6 @@ import { test } from 'vitest';
|
|
|
34
42
|
* declare each flag explicitly per backend.
|
|
35
43
|
*/
|
|
36
44
|
export const in_process_capabilities = Object.freeze({
|
|
37
|
-
bearer_auth: true,
|
|
38
|
-
trusted_proxy: true,
|
|
39
|
-
login_rate_limit: true,
|
|
40
45
|
ws: true,
|
|
41
46
|
sse: true,
|
|
42
47
|
cell_crud: true,
|
|
@@ -47,13 +52,23 @@ export const in_process_capabilities = Object.freeze({
|
|
|
47
52
|
account_status: true,
|
|
48
53
|
oversized_reject_closes_connection: true,
|
|
49
54
|
});
|
|
55
|
+
/**
|
|
56
|
+
* Shape notes for the in-process Hono transport — every wiring fact present
|
|
57
|
+
* (the in-process app exercises the full middleware stack). Documentation
|
|
58
|
+
* only, like every `BackendShapeNotes` (nothing reads it).
|
|
59
|
+
*/
|
|
60
|
+
export const in_process_shape_notes = Object.freeze({
|
|
61
|
+
bearer_auth: true,
|
|
62
|
+
trusted_proxy: true,
|
|
63
|
+
login_rate_limit: true,
|
|
64
|
+
});
|
|
50
65
|
/**
|
|
51
66
|
* Conditional `test()` wrapper — registers a vitest case only when
|
|
52
67
|
* `cond` is true; otherwise registers it as `.skip` so the run still
|
|
53
68
|
* surfaces the gated coverage in the report.
|
|
54
69
|
*
|
|
55
70
|
* Thin wrapper around vitest's `test.skipIf(!cond)` with the argument
|
|
56
|
-
* order flipped to match the more readable `test_if(capabilities.
|
|
71
|
+
* order flipped to match the more readable `test_if(capabilities.ws, ...)`
|
|
57
72
|
* call pattern.
|
|
58
73
|
*/
|
|
59
74
|
export const test_if = (cond, name, fn) => {
|
|
@@ -11,13 +11,15 @@ import '../assert_dev_env.js';
|
|
|
11
11
|
*
|
|
12
12
|
* Defaults baked in by family:
|
|
13
13
|
*
|
|
14
|
-
* - **TS** — `'memory://'` PGlite, 30s startup window
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* - **TS** — `'memory://'` PGlite, 30s startup window. Its shape notes
|
|
15
|
+
* (`ts_default_shape_notes`) record `trusted_proxy: false` /
|
|
16
|
+
* `login_rate_limit: false` — the TS canonical path leaves those limiters
|
|
17
|
+
* null in test mode.
|
|
17
18
|
* - **Rust** — caller-supplied real Postgres URL (PGlite isn't reachable
|
|
18
|
-
* from `tokio-postgres`), 120s startup window (cargo first-build cost),
|
|
19
|
-
*
|
|
20
|
-
* `
|
|
19
|
+
* from `tokio-postgres`), 120s startup window (cargo first-build cost), the
|
|
20
|
+
* `FUZ_TESTING_RESET_DB_ON_STARTUP=true` self-wipe gate, and shape notes
|
|
21
|
+
* (`rust_default_shape_notes`) recording `trusted_proxy: true` +
|
|
22
|
+
* `login_rate_limit: true`.
|
|
21
23
|
*
|
|
22
24
|
* Both builders default `port_env_var` to `'PORT'`. Consumers whose
|
|
23
25
|
* binary reads a different name (e.g. zzz's `ZZZ_PORT`) override.
|
|
@@ -31,22 +33,36 @@ import '../assert_dev_env.js';
|
|
|
31
33
|
* @module
|
|
32
34
|
*/
|
|
33
35
|
import type { BackendBootstrapConfig, BackendConfig } from './backend_config.js';
|
|
34
|
-
import type { BackendCapabilities } from './capabilities.js';
|
|
36
|
+
import type { BackendCapabilities, BackendShapeNotes } from './capabilities.js';
|
|
35
37
|
import { type TestBackendPaths } from './build_test_backend_paths.js';
|
|
36
38
|
/**
|
|
37
|
-
* Capabilities shared by TS-family backends — same canonical
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* limit (the TS canonical path leaves the limiter null in test mode).
|
|
39
|
+
* Capabilities shared by TS-family backends — same canonical implementation,
|
|
40
|
+
* same feature set. The non-gating wiring facts (`bearer_auth` /
|
|
41
|
+
* `trusted_proxy` / `login_rate_limit`) live in `ts_default_shape_notes`.
|
|
41
42
|
*/
|
|
42
43
|
export declare const ts_default_capabilities: BackendCapabilities;
|
|
43
44
|
/**
|
|
44
|
-
* Capabilities for the Rust family.
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* `login_rate_limit: true` (env-gated bucket on `/login` + `/password`).
|
|
45
|
+
* Capabilities for the Rust family. The non-gating wiring facts live in
|
|
46
|
+
* `rust_default_shape_notes` (which records the family's `trusted_proxy` +
|
|
47
|
+
* `login_rate_limit` differences from the TS family).
|
|
48
48
|
*/
|
|
49
49
|
export declare const rust_default_capabilities: BackendCapabilities;
|
|
50
|
+
/**
|
|
51
|
+
* Shape notes for TS-family backends — wiring facts, not gating flags.
|
|
52
|
+
* `trusted_proxy: false` (the test binary doesn't enable proxy parsing) and
|
|
53
|
+
* `login_rate_limit: false` (the TS canonical path leaves the limiter null in
|
|
54
|
+
* test mode); bearer auth is always wired. Documentation only — see
|
|
55
|
+
* `BackendShapeNotes`.
|
|
56
|
+
*/
|
|
57
|
+
export declare const ts_default_shape_notes: BackendShapeNotes;
|
|
58
|
+
/**
|
|
59
|
+
* Shape notes for Rust-family backends — wiring facts, not gating flags. Adds
|
|
60
|
+
* `trusted_proxy: true` (the Rust spine's client-IP middleware is always wired;
|
|
61
|
+
* the env-gate only chooses XFF vs the TCP peer IP) and `login_rate_limit: true`
|
|
62
|
+
* (env-gated bucket on `/login` + `/password`). Documentation only — see
|
|
63
|
+
* `BackendShapeNotes`.
|
|
64
|
+
*/
|
|
65
|
+
export declare const rust_default_shape_notes: BackendShapeNotes;
|
|
50
66
|
export interface MakeDefaultTsBackendConfigOptions {
|
|
51
67
|
/** Diagnostic label; also used as the tmpdir prefix when `paths` is omitted. */
|
|
52
68
|
readonly name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default_backend_configs.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/default_backend_configs.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B
|
|
1
|
+
{"version":3,"file":"default_backend_configs.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/default_backend_configs.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAC,sBAAsB,EAAE,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAC,mBAAmB,EAAE,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAA2B,KAAK,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAQ9F;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,mBAiBpC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,mBAgBtC,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,iBAInC,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,EAAE,iBAIrC,CAAC;AAeH,MAAM,WAAW,iCAAiC;IACjD,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C,oDAAoD;IACpD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,6CAA6C;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAC5C,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC/D;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,GAC1C,MAAM,iCAAiC,KACrC,aAoCF,CAAC;AAEF,MAAM,WAAW,mCAAmC;IACnD,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,+CAA+C;IAC/C,QAAQ,CAAC,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAC5C,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC/D;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,mCAAmC,KACvC,aA4CF,CAAC"}
|
|
@@ -2,15 +2,11 @@ import '../assert_dev_env.js';
|
|
|
2
2
|
import { build_test_backend_paths } from './build_test_backend_paths.js';
|
|
3
3
|
import { default_test_bootstrap_token, default_test_cookie_keys, default_test_keeper_password, default_test_keeper_username, } from './default_secrets.js';
|
|
4
4
|
/**
|
|
5
|
-
* Capabilities shared by TS-family backends — same canonical
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* limit (the TS canonical path leaves the limiter null in test mode).
|
|
5
|
+
* Capabilities shared by TS-family backends — same canonical implementation,
|
|
6
|
+
* same feature set. The non-gating wiring facts (`bearer_auth` /
|
|
7
|
+
* `trusted_proxy` / `login_rate_limit`) live in `ts_default_shape_notes`.
|
|
9
8
|
*/
|
|
10
9
|
export const ts_default_capabilities = Object.freeze({
|
|
11
|
-
bearer_auth: true,
|
|
12
|
-
trusted_proxy: false,
|
|
13
|
-
login_rate_limit: false,
|
|
14
10
|
ws: true,
|
|
15
11
|
sse: false,
|
|
16
12
|
cell_crud: true,
|
|
@@ -29,15 +25,11 @@ export const ts_default_capabilities = Object.freeze({
|
|
|
29
25
|
oversized_reject_closes_connection: true,
|
|
30
26
|
});
|
|
31
27
|
/**
|
|
32
|
-
* Capabilities for the Rust family.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* `login_rate_limit: true` (env-gated bucket on `/login` + `/password`).
|
|
28
|
+
* Capabilities for the Rust family. The non-gating wiring facts live in
|
|
29
|
+
* `rust_default_shape_notes` (which records the family's `trusted_proxy` +
|
|
30
|
+
* `login_rate_limit` differences from the TS family).
|
|
36
31
|
*/
|
|
37
32
|
export const rust_default_capabilities = Object.freeze({
|
|
38
|
-
bearer_auth: true,
|
|
39
|
-
trusted_proxy: true,
|
|
40
|
-
login_rate_limit: true,
|
|
41
33
|
ws: true,
|
|
42
34
|
sse: false,
|
|
43
35
|
cell_crud: true,
|
|
@@ -54,6 +46,30 @@ export const rust_default_capabilities = Object.freeze({
|
|
|
54
46
|
// and the pipelined request is never reached.
|
|
55
47
|
oversized_reject_closes_connection: true,
|
|
56
48
|
});
|
|
49
|
+
/**
|
|
50
|
+
* Shape notes for TS-family backends — wiring facts, not gating flags.
|
|
51
|
+
* `trusted_proxy: false` (the test binary doesn't enable proxy parsing) and
|
|
52
|
+
* `login_rate_limit: false` (the TS canonical path leaves the limiter null in
|
|
53
|
+
* test mode); bearer auth is always wired. Documentation only — see
|
|
54
|
+
* `BackendShapeNotes`.
|
|
55
|
+
*/
|
|
56
|
+
export const ts_default_shape_notes = Object.freeze({
|
|
57
|
+
bearer_auth: true,
|
|
58
|
+
trusted_proxy: false,
|
|
59
|
+
login_rate_limit: false,
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* Shape notes for Rust-family backends — wiring facts, not gating flags. Adds
|
|
63
|
+
* `trusted_proxy: true` (the Rust spine's client-IP middleware is always wired;
|
|
64
|
+
* the env-gate only chooses XFF vs the TCP peer IP) and `login_rate_limit: true`
|
|
65
|
+
* (env-gated bucket on `/login` + `/password`). Documentation only — see
|
|
66
|
+
* `BackendShapeNotes`.
|
|
67
|
+
*/
|
|
68
|
+
export const rust_default_shape_notes = Object.freeze({
|
|
69
|
+
bearer_auth: true,
|
|
70
|
+
trusted_proxy: true,
|
|
71
|
+
login_rate_limit: true,
|
|
72
|
+
});
|
|
57
73
|
/** Bootstrap block built from the default secrets + supplied paths. */
|
|
58
74
|
const build_default_bootstrap = (paths, overrides) => ({
|
|
59
75
|
token_path: paths.bootstrap_token_path,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default_spine_surface.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/default_spine_surface.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAIpD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,8CAA8C,CAAC;AACrF,OAAO,EAAqB,KAAK,gBAAgB,EAAC,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAwB,KAAK,cAAc,EAAC,MAAM,8BAA8B,CAAC;AAIxF,OAAO,EAAqB,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EAAC,cAAc,EAAE,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,oCAAoC,CAAC;AAGzE;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC,MAAM,CAAwC,CAAC;AAElG;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,gBAExB,CAAC;AAEH,iEAAiE;AACjE,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,4BAA4B,CAAC;AAExD,+CAA+C;AAC/C,MAAM,WAAW,wBAAwB;IACxC;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACzD;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,GAC/B,KAAK,gBAAgB,EACrB,UAAU,wBAAwB,KAChC,KAAK,CAAC,eAAe,CAQvB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,GAAI,KAAK,gBAAgB,KAAG,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"default_spine_surface.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/default_spine_surface.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAIpD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,8CAA8C,CAAC;AACrF,OAAO,EAAqB,KAAK,gBAAgB,EAAC,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAwB,KAAK,cAAc,EAAC,MAAM,8BAA8B,CAAC;AAIxF,OAAO,EAAqB,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EAAC,cAAc,EAAE,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,oCAAoC,CAAC;AAGzE;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC,MAAM,CAAwC,CAAC;AAElG;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,gBAExB,CAAC;AAEH,iEAAiE;AACjE,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,4BAA4B,CAAC;AAExD,+CAA+C;AAC/C,MAAM,WAAW,wBAAwB;IACxC;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACzD;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,GAC/B,KAAK,gBAAgB,EACrB,UAAU,wBAAwB,KAChC,KAAK,CAAC,eAAe,CAQvB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,GAAI,KAAK,gBAAgB,KAAG,KAAK,CAAC,SAAS,CAwB/E,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,EAAE,GAAwD,CAAC;AAEjG;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,GAAI,MAAM,MAAM,KAAG,SAC6B,CAAC;AAE3F;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,QAAO,cAM1C,CAAC"}
|
|
@@ -86,6 +86,12 @@ export const create_spine_route_specs = (ctx) => [
|
|
|
86
86
|
session_options: spine_session_options,
|
|
87
87
|
ip_rate_limiter: null,
|
|
88
88
|
signup_account_rate_limiter: null,
|
|
89
|
+
// Disable the denial floor so the identity-parity suite's accepted
|
|
90
|
+
// cases (valid username/email, no invite → 403 no-matching-invite)
|
|
91
|
+
// don't each pay the 250ms timing floor. Mirrors `login_fail_floor_ms: 0`
|
|
92
|
+
// above — the floor is a production timing-oracle defense, not
|
|
93
|
+
// behavior any cross test asserts.
|
|
94
|
+
signup_fail_floor_ms: 0,
|
|
89
95
|
}),
|
|
90
96
|
]),
|
|
91
97
|
...(ctx.audit_sse
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import '../assert_dev_env.js';
|
|
2
|
+
/**
|
|
3
|
+
* The **full** live RPC mount for fuz_app's own spine test binary — the
|
|
4
|
+
* complete action set `testing_spine_server.ts` exposes on a single RPC
|
|
5
|
+
* endpoint, in one place.
|
|
6
|
+
*
|
|
7
|
+
* Where `default_spine_surface.ts` defines the **declared** surface
|
|
8
|
+
* (`create_spine_surface_spec` / `spine_rpc_endpoints` — the
|
|
9
|
+
* `create_standard_rpc_actions` bundle the spec-derived suites
|
|
10
|
+
* auto-enumerate), this module defines its superset: the standard bundle
|
|
11
|
+
* **plus** the families the binary live-mounts but keeps off the declared
|
|
12
|
+
* surface —
|
|
13
|
+
*
|
|
14
|
+
* - the `_testing_*` daemon-token backdoors (`create_testing_actions`),
|
|
15
|
+
* - the full cell verb set (CRUD + grant + field + item + audit),
|
|
16
|
+
* - the opt-in `actor_lookup` / `actor_search` resolvers,
|
|
17
|
+
* - the `_testing_action_manifest` backdoor, appended last (it dumps the live
|
|
18
|
+
* method set for the cross-impl manifest-parity gate, so it must enumerate
|
|
19
|
+
* every method above it).
|
|
20
|
+
*
|
|
21
|
+
* Single-sourcing the mount here lets the binary, the in-process parity
|
|
22
|
+
* setup, and the `spine_method_coverage` reconciliation test all build the
|
|
23
|
+
* same list — so a method can never be mounted in one place and forgotten
|
|
24
|
+
* in another. The reconciliation test enumerates `build_full_spine_rpc_actions`
|
|
25
|
+
* with stub deps and asserts the live method set equals the tagged coverage
|
|
26
|
+
* manifest; see `src/test/cross_backend/spine_method_coverage.ts`.
|
|
27
|
+
*
|
|
28
|
+
* **`$lib`-free by contract** — like `default_spine_surface.ts`, this module
|
|
29
|
+
* is reached by the spawned TS binary under Gro's loader (which resolves
|
|
30
|
+
* `.js`→`.ts` but not the `$lib` alias), so every import is relative. Keep
|
|
31
|
+
* it that way.
|
|
32
|
+
*
|
|
33
|
+
* @module
|
|
34
|
+
*/
|
|
35
|
+
import type { RpcAction } from '../../actions/action_rpc.js';
|
|
36
|
+
import type { AppDeps } from '../../auth/deps.js';
|
|
37
|
+
import type { DaemonTokenState } from '../../auth/daemon_token.js';
|
|
38
|
+
import type { NotificationSender } from '../../auth/role_grant_offer_notifications.js';
|
|
39
|
+
import type { RpcEndpointSpec } from '../../http/surface.js';
|
|
40
|
+
import type { AppServerContext } from '../../server/app_server_context.js';
|
|
41
|
+
/** Options for {@link build_full_spine_rpc_actions} / {@link full_spine_rpc_endpoints}. */
|
|
42
|
+
export interface FullSpineMountOptions {
|
|
43
|
+
/**
|
|
44
|
+
* Daemon-token runtime state threaded into `create_testing_actions` — the
|
|
45
|
+
* `_testing_reset` handler mutates `keeper_account_id` after re-seeding.
|
|
46
|
+
* Pass the same instance the daemon-token middleware reads. For the
|
|
47
|
+
* coverage test (method enumeration only, handlers never run) any stub
|
|
48
|
+
* state satisfies it.
|
|
49
|
+
*/
|
|
50
|
+
readonly daemon_token_state: DaemonTokenState;
|
|
51
|
+
/**
|
|
52
|
+
* WS notification sender for the role-grant-offer fan-out. Pass the SAME
|
|
53
|
+
* `BackendWebsocketTransport` the WS endpoint registers connections against
|
|
54
|
+
* (the transport is the connection registry). Omitted for enumeration.
|
|
55
|
+
*/
|
|
56
|
+
readonly notification_sender?: NotificationSender | null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Build the complete live RPC action list the spine test binary mounts on
|
|
60
|
+
* its single endpoint: the declared `create_standard_rpc_actions` bundle plus
|
|
61
|
+
* the off-surface families (`_testing_*` backdoors, cells, actor resolvers).
|
|
62
|
+
*
|
|
63
|
+
* Mirrors the previous inline assembly in `testing_spine_server.ts` exactly —
|
|
64
|
+
* `session_options` is pinned to `spine_session_options` (the binary's cookie
|
|
65
|
+
* config) and `roles` to `spine_roles` (carrying `cell_editor`), so the only
|
|
66
|
+
* runtime-varying inputs are the daemon-token state + notification sender.
|
|
67
|
+
*
|
|
68
|
+
* @param deps - the backend `AppDeps` (stub deps suffice for method enumeration)
|
|
69
|
+
* @param options - daemon-token state + optional WS notification sender
|
|
70
|
+
* @returns every `RpcAction` the binary exposes, in mount order
|
|
71
|
+
*/
|
|
72
|
+
export declare const build_full_spine_rpc_actions: (deps: AppDeps, options: FullSpineMountOptions) => Array<RpcAction>;
|
|
73
|
+
/**
|
|
74
|
+
* Factory-form full mount at {@link SPINE_RPC_PATH}, the shape
|
|
75
|
+
* `create_app_server`'s `rpc_endpoints` slot accepts. The spine binary wires
|
|
76
|
+
* this directly; the surface builder (`create_spine_surface_spec`) keeps using
|
|
77
|
+
* the narrower `spine_rpc_endpoints` so the declared surface stays the
|
|
78
|
+
* standard bundle only.
|
|
79
|
+
*/
|
|
80
|
+
export declare const full_spine_rpc_endpoints: (ctx: AppServerContext, options: FullSpineMountOptions) => Array<RpcEndpointSpec>;
|
|
81
|
+
//# sourceMappingURL=full_spine_mount.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"full_spine_mount.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/full_spine_mount.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,6BAA6B,CAAC;AAC3D,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,8CAA8C,CAAC;AAKrF,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,oCAAoC,CAAC;AAOzE,2FAA2F;AAC3F,MAAM,WAAW,qBAAqB;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACzD;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,4BAA4B,GACxC,MAAM,OAAO,EACb,SAAS,qBAAqB,KAC5B,KAAK,CAAC,SAAS,CAoBjB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,GACpC,KAAK,gBAAgB,EACrB,SAAS,qBAAqB,KAC5B,KAAK,CAAC,eAAe,CAEvB,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import '../assert_dev_env.js';
|
|
2
|
+
import { create_standard_rpc_actions } from '../../auth/standard_rpc_actions.js';
|
|
3
|
+
import { create_all_cell_actions } from '../../auth/all_cell_actions.js';
|
|
4
|
+
import { create_actor_lookup_actions } from '../../auth/actor_lookup_actions.js';
|
|
5
|
+
import { create_actor_search_actions } from '../../auth/actor_search_actions.js';
|
|
6
|
+
import { create_testing_action_manifest_action, create_testing_actions, } from './testing_reset_actions.js';
|
|
7
|
+
import { SPINE_RPC_PATH, spine_roles, spine_session_options } from './default_spine_surface.js';
|
|
8
|
+
/**
|
|
9
|
+
* Build the complete live RPC action list the spine test binary mounts on
|
|
10
|
+
* its single endpoint: the declared `create_standard_rpc_actions` bundle plus
|
|
11
|
+
* the off-surface families (`_testing_*` backdoors, cells, actor resolvers).
|
|
12
|
+
*
|
|
13
|
+
* Mirrors the previous inline assembly in `testing_spine_server.ts` exactly —
|
|
14
|
+
* `session_options` is pinned to `spine_session_options` (the binary's cookie
|
|
15
|
+
* config) and `roles` to `spine_roles` (carrying `cell_editor`), so the only
|
|
16
|
+
* runtime-varying inputs are the daemon-token state + notification sender.
|
|
17
|
+
*
|
|
18
|
+
* @param deps - the backend `AppDeps` (stub deps suffice for method enumeration)
|
|
19
|
+
* @param options - daemon-token state + optional WS notification sender
|
|
20
|
+
* @returns every `RpcAction` the binary exposes, in mount order
|
|
21
|
+
*/
|
|
22
|
+
export const build_full_spine_rpc_actions = (deps, options) => {
|
|
23
|
+
const actions = [
|
|
24
|
+
...create_standard_rpc_actions({ ...deps, notification_sender: options.notification_sender ?? null }, { roles: spine_roles }),
|
|
25
|
+
...create_testing_actions(deps, {
|
|
26
|
+
session_options: spine_session_options,
|
|
27
|
+
daemon_token_state: options.daemon_token_state,
|
|
28
|
+
}),
|
|
29
|
+
...create_all_cell_actions(deps, { roles: spine_roles }),
|
|
30
|
+
...create_actor_lookup_actions(deps),
|
|
31
|
+
...create_actor_search_actions(deps),
|
|
32
|
+
];
|
|
33
|
+
// Append the `_testing_action_manifest` backdoor last — it closes over the
|
|
34
|
+
// complete `actions` list (plus its own spec) to dump the live method set
|
|
35
|
+
// for the cross-impl manifest-parity gate, so it must come after every
|
|
36
|
+
// method it enumerates.
|
|
37
|
+
actions.push(create_testing_action_manifest_action(actions));
|
|
38
|
+
return actions;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Factory-form full mount at {@link SPINE_RPC_PATH}, the shape
|
|
42
|
+
* `create_app_server`'s `rpc_endpoints` slot accepts. The spine binary wires
|
|
43
|
+
* this directly; the surface builder (`create_spine_surface_spec`) keeps using
|
|
44
|
+
* the narrower `spine_rpc_endpoints` so the declared surface stays the
|
|
45
|
+
* standard bundle only.
|
|
46
|
+
*/
|
|
47
|
+
export const full_spine_rpc_endpoints = (ctx, options) => [
|
|
48
|
+
{ path: SPINE_RPC_PATH, actions: build_full_spine_rpc_actions(ctx.deps, options) },
|
|
49
|
+
];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import '../assert_dev_env.js';
|
|
2
|
+
import type { SetupTest } from './setup.js';
|
|
3
|
+
/** Options for the identity-primitive parity suite. */
|
|
4
|
+
export interface IdentityParityCrossTestOptions {
|
|
5
|
+
/** Per-test fixture producer (in-process or cross-process). */
|
|
6
|
+
readonly setup_test: SetupTest;
|
|
7
|
+
/** REST login route path. Default `/api/account/login` (the spine convention). */
|
|
8
|
+
readonly login_path?: string;
|
|
9
|
+
/** REST signup route path. Default `/api/account/signup` (the spine convention). */
|
|
10
|
+
readonly signup_path?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const describe_identity_parity_cross_tests: (options: IdentityParityCrossTestOptions) => void;
|
|
13
|
+
//# sourceMappingURL=identity_parity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity_parity.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/identity_parity.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAqG9B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,YAAY,CAAC;AAkB1C,uDAAuD;AACvD,MAAM,WAAW,8BAA8B;IAC9C,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,kFAAkF;IAClF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,oFAAoF;IACpF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B;AA0JD,eAAO,MAAM,oCAAoC,GAChD,SAAS,8BAA8B,KACrC,IA2TF,CAAC"}
|