@fuzdev/fuz_app 0.65.0 → 0.66.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/dist/actions/CLAUDE.md +65 -86
  2. package/dist/actions/action_codegen.d.ts +1 -1
  3. package/dist/actions/action_codegen.js +1 -1
  4. package/dist/actions/action_event_data.d.ts +1 -1
  5. package/dist/auth/CLAUDE.md +83 -104
  6. package/dist/auth/audit_log_schema.js +2 -2
  7. package/dist/auth/daemon_token_middleware.d.ts +15 -5
  8. package/dist/auth/daemon_token_middleware.d.ts.map +1 -1
  9. package/dist/auth/daemon_token_middleware.js +24 -15
  10. package/dist/auth/invite_queries.d.ts +17 -7
  11. package/dist/auth/invite_queries.d.ts.map +1 -1
  12. package/dist/auth/invite_queries.js +19 -8
  13. package/dist/auth/signup_routes.d.ts +47 -1
  14. package/dist/auth/signup_routes.d.ts.map +1 -1
  15. package/dist/auth/signup_routes.js +103 -52
  16. package/dist/env/resolve.d.ts +44 -7
  17. package/dist/env/resolve.d.ts.map +1 -1
  18. package/dist/env/resolve.js +94 -27
  19. package/dist/http/CLAUDE.md +47 -52
  20. package/dist/http/jsonrpc.d.ts +23 -7
  21. package/dist/http/jsonrpc.d.ts.map +1 -1
  22. package/dist/http/jsonrpc.js +19 -3
  23. package/dist/http/surface.d.ts +9 -2
  24. package/dist/http/surface.d.ts.map +1 -1
  25. package/dist/runtime/mock.d.ts +1 -1
  26. package/dist/runtime/mock.js +1 -1
  27. package/dist/testing/CLAUDE.md +659 -511
  28. package/dist/testing/admin_integration.d.ts +5 -5
  29. package/dist/testing/admin_integration.d.ts.map +1 -1
  30. package/dist/testing/admin_integration.js +95 -39
  31. package/dist/testing/app_server.d.ts +16 -1
  32. package/dist/testing/app_server.d.ts.map +1 -1
  33. package/dist/testing/app_server.js +18 -3
  34. package/dist/testing/audit_completeness.d.ts +7 -5
  35. package/dist/testing/audit_completeness.d.ts.map +1 -1
  36. package/dist/testing/audit_completeness.js +5 -9
  37. package/dist/testing/bootstrap_success.js +2 -2
  38. package/dist/testing/cross_backend/backend_config.d.ts +113 -0
  39. package/dist/testing/cross_backend/backend_config.d.ts.map +1 -0
  40. package/dist/testing/cross_backend/backend_config.js +1 -0
  41. package/dist/testing/cross_backend/bench/bench_report.d.ts +46 -0
  42. package/dist/testing/cross_backend/bench/bench_report.d.ts.map +1 -0
  43. package/dist/testing/cross_backend/bench/bench_report.js +83 -0
  44. package/dist/testing/cross_backend/bench/run_cross_impl_bench.d.ts +44 -0
  45. package/dist/testing/cross_backend/bench/run_cross_impl_bench.d.ts.map +1 -0
  46. package/dist/testing/cross_backend/bench/run_cross_impl_bench.js +38 -0
  47. package/dist/testing/cross_backend/bench/scenario.d.ts +57 -0
  48. package/dist/testing/cross_backend/bench/scenario.d.ts.map +1 -0
  49. package/dist/testing/cross_backend/bench/scenario.js +28 -0
  50. package/dist/testing/cross_backend/bootstrap_backend.d.ts +41 -0
  51. package/dist/testing/cross_backend/bootstrap_backend.d.ts.map +1 -0
  52. package/dist/testing/cross_backend/bootstrap_backend.js +34 -0
  53. package/dist/testing/cross_backend/build_test_backend_paths.d.ts +24 -0
  54. package/dist/testing/cross_backend/build_test_backend_paths.d.ts.map +1 -0
  55. package/dist/testing/cross_backend/build_test_backend_paths.js +33 -0
  56. package/dist/testing/cross_backend/capabilities.d.ts +3 -2
  57. package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
  58. package/dist/testing/cross_backend/default_backend_configs.d.ts +122 -0
  59. package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -0
  60. package/dist/testing/cross_backend/default_backend_configs.js +111 -0
  61. package/dist/testing/cross_backend/default_secrets.d.ts +40 -0
  62. package/dist/testing/cross_backend/default_secrets.d.ts.map +1 -0
  63. package/dist/testing/cross_backend/default_secrets.js +39 -0
  64. package/dist/testing/cross_backend/default_spine_surface.d.ts +64 -0
  65. package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -0
  66. package/dist/testing/cross_backend/default_spine_surface.js +121 -0
  67. package/dist/testing/cross_backend/setup.d.ts +270 -34
  68. package/dist/testing/cross_backend/setup.d.ts.map +1 -1
  69. package/dist/testing/cross_backend/setup.js +495 -15
  70. package/dist/testing/cross_backend/spawn_backend.d.ts +58 -0
  71. package/dist/testing/cross_backend/spawn_backend.d.ts.map +1 -0
  72. package/dist/testing/cross_backend/spawn_backend.js +229 -0
  73. package/dist/testing/cross_backend/spine_stub_backend_config.d.ts +66 -0
  74. package/dist/testing/cross_backend/spine_stub_backend_config.d.ts.map +1 -0
  75. package/dist/testing/cross_backend/spine_stub_backend_config.js +49 -0
  76. package/dist/testing/cross_backend/sse_round_trip.d.ts +37 -0
  77. package/dist/testing/cross_backend/sse_round_trip.d.ts.map +1 -0
  78. package/dist/testing/cross_backend/sse_round_trip.js +137 -0
  79. package/dist/testing/cross_backend/standard.d.ts +96 -0
  80. package/dist/testing/cross_backend/standard.d.ts.map +1 -0
  81. package/dist/testing/cross_backend/standard.js +49 -0
  82. package/dist/testing/cross_backend/testing_reset_actions.d.ts +171 -0
  83. package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -0
  84. package/dist/testing/cross_backend/testing_reset_actions.js +213 -0
  85. package/dist/testing/cross_backend/testing_server_bun.d.ts +5 -0
  86. package/dist/testing/cross_backend/testing_server_bun.d.ts.map +1 -0
  87. package/dist/testing/cross_backend/testing_server_bun.js +59 -0
  88. package/dist/testing/cross_backend/testing_server_core.d.ts +140 -0
  89. package/dist/testing/cross_backend/testing_server_core.d.ts.map +1 -0
  90. package/dist/testing/cross_backend/testing_server_core.js +68 -0
  91. package/dist/testing/cross_backend/testing_server_deno.d.ts +5 -0
  92. package/dist/testing/cross_backend/testing_server_deno.d.ts.map +1 -0
  93. package/dist/testing/cross_backend/testing_server_deno.js +37 -0
  94. package/dist/testing/cross_backend/testing_server_node.d.ts +5 -0
  95. package/dist/testing/cross_backend/testing_server_node.d.ts.map +1 -0
  96. package/dist/testing/cross_backend/testing_server_node.js +50 -0
  97. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts +72 -0
  98. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -0
  99. package/dist/testing/cross_backend/ts_spine_backend_config.js +112 -0
  100. package/dist/testing/cross_backend/ws_round_trip.d.ts +35 -0
  101. package/dist/testing/cross_backend/ws_round_trip.d.ts.map +1 -0
  102. package/dist/testing/cross_backend/ws_round_trip.js +113 -0
  103. package/dist/testing/data_exposure.d.ts +4 -6
  104. package/dist/testing/data_exposure.d.ts.map +1 -1
  105. package/dist/testing/data_exposure.js +1 -5
  106. package/dist/testing/db_entities.d.ts +18 -7
  107. package/dist/testing/db_entities.d.ts.map +1 -1
  108. package/dist/testing/db_entities.js +18 -7
  109. package/dist/testing/integration.d.ts +27 -6
  110. package/dist/testing/integration.d.ts.map +1 -1
  111. package/dist/testing/integration.js +93 -58
  112. package/dist/testing/round_trip.d.ts +4 -5
  113. package/dist/testing/round_trip.d.ts.map +1 -1
  114. package/dist/testing/round_trip.js +1 -5
  115. package/dist/testing/rpc_helpers.d.ts +10 -4
  116. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  117. package/dist/testing/rpc_helpers.js +1 -1
  118. package/dist/testing/rpc_round_trip.d.ts +5 -5
  119. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  120. package/dist/testing/rpc_round_trip.js +1 -5
  121. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  122. package/dist/testing/sse_round_trip.js +1 -68
  123. package/dist/testing/standard.d.ts +4 -5
  124. package/dist/testing/standard.d.ts.map +1 -1
  125. package/dist/testing/stubs.d.ts +10 -3
  126. package/dist/testing/stubs.d.ts.map +1 -1
  127. package/dist/testing/stubs.js +9 -2
  128. package/dist/testing/testing_rate_limiter.d.ts +59 -0
  129. package/dist/testing/testing_rate_limiter.d.ts.map +1 -0
  130. package/dist/testing/testing_rate_limiter.js +74 -0
  131. package/dist/testing/transports/bootstrap.d.ts +52 -0
  132. package/dist/testing/transports/bootstrap.d.ts.map +1 -0
  133. package/dist/testing/transports/bootstrap.js +70 -0
  134. package/dist/testing/transports/fetch_transport.d.ts +81 -0
  135. package/dist/testing/transports/fetch_transport.d.ts.map +1 -0
  136. package/dist/testing/transports/fetch_transport.js +74 -0
  137. package/dist/testing/transports/sse_frame_reader.d.ts +41 -0
  138. package/dist/testing/transports/sse_frame_reader.d.ts.map +1 -0
  139. package/dist/testing/transports/sse_frame_reader.js +84 -0
  140. package/dist/testing/transports/sse_transport.d.ts +54 -0
  141. package/dist/testing/transports/sse_transport.d.ts.map +1 -0
  142. package/dist/testing/transports/sse_transport.js +51 -0
  143. package/dist/testing/transports/ws_client.d.ts +108 -0
  144. package/dist/testing/transports/ws_client.d.ts.map +1 -0
  145. package/dist/testing/transports/ws_client.js +56 -0
  146. package/dist/testing/transports/ws_transport.d.ts +43 -0
  147. package/dist/testing/transports/ws_transport.d.ts.map +1 -0
  148. package/dist/testing/transports/ws_transport.js +169 -0
  149. package/dist/testing/ws_round_trip.d.ts +21 -103
  150. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  151. package/dist/testing/ws_round_trip.js +42 -40
  152. package/dist/ui/CLAUDE.md +5 -3
  153. package/dist/ui/MenuLink.svelte +16 -16
  154. package/dist/ui/MenuLink.svelte.d.ts +13 -4
  155. package/dist/ui/MenuLink.svelte.d.ts.map +1 -1
  156. package/package.json +7 -1
  157. package/dist/testing/transports/surface_source.d.ts +0 -51
  158. package/dist/testing/transports/surface_source.d.ts.map +0 -1
  159. package/dist/testing/transports/surface_source.js +0 -19
@@ -2,9 +2,9 @@ import './assert_dev_env.js';
2
2
  import type { SessionOptions } from '../auth/session_cookie.js';
3
3
  import { type RoleSchemaResult } from '../auth/role_schema.js';
4
4
  import { type RpcEndpointsSuiteOption } from './rpc_helpers.js';
5
+ import type { AppSurfaceSpec } from '../http/surface.js';
5
6
  import type { BackendCapabilities } from './cross_backend/capabilities.js';
6
7
  import type { SetupTest } from './cross_backend/setup.js';
7
- import type { SurfaceSource } from './transports/surface_source.js';
8
8
  /**
9
9
  * Configuration for `describe_standard_admin_integration_tests`.
10
10
  */
@@ -16,11 +16,11 @@ export interface StandardAdminIntegrationTestOptions {
16
16
  */
17
17
  setup_test: SetupTest;
18
18
  /**
19
- * Source of the app surface for route iteration and error-coverage
20
- * scoping. Currently requires `kind: 'inline'` the cross-process
21
- * snapshot variant lands alongside the spawned-backend transport plumbing.
19
+ * App surface (with route specs + middleware specs) for route iteration
20
+ * and error-coverage scoping. Constructed in TS by the consumer (same
21
+ * shape for in-process and cross-process tests).
22
22
  */
23
- surface_source: SurfaceSource;
23
+ surface_source: AppSurfaceSpec;
24
24
  /** Backend capability declarations. */
25
25
  capabilities: BackendCapabilities;
26
26
  /** Session config — needed for cookie_name + factory-form rpc_endpoints resolution. */
@@ -1 +1 @@
1
- {"version":3,"file":"admin_integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/admin_integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgC7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAA0B,KAAK,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AAWtF,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAiB1B,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EAAC,SAAS,EAAc,MAAM,0BAA0B,CAAC;AACrE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,gCAAgC,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD;;;;OAIG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,aAAa,CAAC;IAC9B,uCAAuC;IACvC,YAAY,EAAE,mBAAmB,CAAC;IAClC,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,4GAA4G;IAC5G,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;OAGG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAiBD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,mCAAmC,KAC1C,IAqzBF,CAAC"}
1
+ {"version":3,"file":"admin_integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/admin_integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgC7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAa,KAAK,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AAUzE,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAkB1B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EAAC,SAAS,EAAc,MAAM,0BAA0B,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD;;;;OAIG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,uCAAuC;IACvC,YAAY,EAAE,mBAAmB,CAAC;IAClC,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,4GAA4G;IAC5G,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;OAGG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAiBD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,mCAAmC,KAC1C,IAi3BF,CAAC"}
@@ -26,16 +26,15 @@ import './assert_dev_env.js';
26
26
  * @module
27
27
  */
28
28
  import { describe, test, assert, afterAll } from 'vitest';
29
- import { ROLE_KEEPER, ROLE_ADMIN } from '../auth/role_schema.js';
29
+ import { ROLE_ADMIN } from '../auth/role_schema.js';
30
30
  import { GRANT_PATH_ADMIN } from '../auth/grant_path_schema.js';
31
- import {} from './app_server.js';
32
- import { create_test_role_grant_direct } from './db_entities.js';
31
+ import { DEFAULT_TEST_PASSWORD } from './app_server.js';
33
32
  import { role_grant_offer_and_accept } from './role_grant_helpers.js';
34
33
  import { find_auth_route } from './integration_helpers.js';
35
34
  import { ErrorCoverageCollector, assert_error_coverage, DEFAULT_INTEGRATION_ERROR_COVERAGE, } from './error_coverage.js';
36
35
  import { rpc_call_for_spec, require_rpc_endpoint_path, resolve_rpc_endpoints_for_setup, } from './rpc_helpers.js';
37
36
  import { role_grant_offer_create_action_spec, role_grant_revoke_action_spec, } from '../auth/role_grant_offer_action_specs.js';
38
- import { admin_account_list_action_spec, admin_session_list_action_spec, admin_session_revoke_all_action_spec, admin_token_revoke_all_action_spec, audit_log_list_action_spec, audit_log_role_grant_history_action_spec, } from '../auth/admin_action_specs.js';
37
+ import { admin_account_list_action_spec, ADMIN_ACCOUNT_LIST_LIMIT_MAX, admin_session_list_action_spec, admin_session_revoke_all_action_spec, admin_token_revoke_all_action_spec, audit_log_list_action_spec, audit_log_role_grant_history_action_spec, } from '../auth/admin_action_specs.js';
39
38
  import { account_token_create_action_spec, account_verify_action_spec, } from '../auth/account_action_specs.js';
40
39
  /**
41
40
  * Pick a role for admin-grant testing, preferring a non-admin app-defined
@@ -65,11 +64,7 @@ const pick_grantable_role = (role_specs) => {
65
64
  * see a clear setup error rather than `method not found` mid-suite.
66
65
  */
67
66
  export const describe_standard_admin_integration_tests = (options) => {
68
- if (options.surface_source.kind !== 'inline') {
69
- throw new Error("describe_standard_admin_integration_tests requires surface_source.kind === 'inline' — " +
70
- 'the cross-process snapshot variant lands with the spawned-backend transport');
71
- }
72
- const route_specs = options.surface_source.spec.route_specs;
67
+ const route_specs = options.surface_source.route_specs;
73
68
  // Hard-fail early so consumers see a clear setup error instead of a
74
69
  // confusing test failure when `rpc_endpoints` is missing.
75
70
  const rpc_endpoints_for_setup = resolve_rpc_endpoints_for_setup(options.rpc_endpoints, options.session_options);
@@ -122,11 +117,19 @@ export const describe_standard_admin_integration_tests = (options) => {
122
117
  test('admin can list all accounts', async () => {
123
118
  const fixture = await options.setup_test();
124
119
  const user_two = await fixture.create_account({ username: 'user_two' });
120
+ // Request the max page size — cross-process the backend persists
121
+ // accounts across tests (`globalSetup` bootstraps once), so a
122
+ // long-running suite accumulates well past the default 50 and
123
+ // `user_two` (newest, `ORDER BY created_at ASC`) falls off the
124
+ // first page. The MAX (200) carries this suite as written; once
125
+ // the suite consistently grows past it, swap to an
126
+ // account-scoped admin RPC (search-by-id, ORDER BY DESC, etc.)
127
+ // rather than chase the limit upward.
125
128
  const res = await rpc_call_for_spec({
126
129
  app: { request: fixture.transport },
127
130
  path: rpc_path,
128
131
  spec: admin_account_list_action_spec,
129
- params: {},
132
+ params: { limit: ADMIN_ACCOUNT_LIST_LIMIT_MAX },
130
133
  headers: fixture.create_session_headers(),
131
134
  });
132
135
  assert.ok(res.ok, `admin_account_list failed: ${res.ok ? '' : JSON.stringify(res.error)}`);
@@ -139,22 +142,47 @@ export const describe_standard_admin_integration_tests = (options) => {
139
142
  });
140
143
  test('non-admin cannot list accounts', async () => {
141
144
  const fixture = await options.setup_test();
142
- // Default keeper has both ROLE_KEEPER + ROLE_ADMIN; mint a fresh
143
- // account with only ROLE_KEEPER (no admin) to probe the 403 path.
144
- const keeper_only = await fixture.create_account({
145
- username: 'keeper_only',
146
- roles: [ROLE_KEEPER],
147
- });
145
+ // Mint a fresh no-roles account fresh signups default to no
146
+ // roles, so the per-test account is non-admin by construction.
147
+ const non_admin = await fixture.create_account({ username: 'non_admin_user' });
148
148
  const res = await rpc_call_for_spec({
149
149
  app: { request: fixture.transport },
150
150
  path: rpc_path,
151
151
  spec: admin_account_list_action_spec,
152
152
  params: {},
153
- headers: keeper_only.create_session_headers(),
153
+ headers: non_admin.create_session_headers(),
154
154
  });
155
155
  assert.ok(!res.ok, 'Expected admin_account_list to fail for non-admin');
156
156
  assert.strictEqual(res.status, 403);
157
157
  });
158
+ // Probe the keeper-vs-admin separation specifically: a keeper-only
159
+ // account (no admin role) must still 403 on admin RPCs. ROLE_KEEPER
160
+ // is bootstrap-only-grantable, so the only way to seed this account
161
+ // is via `extra_accounts` at the test-binary bootstrap-equivalent
162
+ // step. Consumers that want this probe wire
163
+ // `extra_accounts: [{username: 'non_admin_keeper', roles: [ROLE_KEEPER]}]`
164
+ // into their `default_*_suite_options(...)` call; otherwise the
165
+ // test runtime-skips and the looser no-roles probe above carries
166
+ // the suite's "non-admin gets 403" assertion alone.
167
+ test('keeper-only account cannot list accounts (keeper ≠ admin)', async (ctx) => {
168
+ const fixture = await options.setup_test();
169
+ const non_admin_keeper = fixture.extra_accounts.non_admin_keeper;
170
+ if (!non_admin_keeper) {
171
+ ctx.skip(`no \`extra_accounts['non_admin_keeper']\` declared on the fixture — wire ` +
172
+ `\`extra_accounts: [{username: 'non_admin_keeper', roles: [ROLE_KEEPER]}]\` ` +
173
+ `in the consumer's suite options to enable the keeper-vs-admin probe.`);
174
+ return;
175
+ }
176
+ const res = await rpc_call_for_spec({
177
+ app: { request: fixture.transport },
178
+ path: rpc_path,
179
+ spec: admin_account_list_action_spec,
180
+ params: {},
181
+ headers: non_admin_keeper.create_session_headers(),
182
+ });
183
+ assert.ok(!res.ok, 'Expected admin_account_list to fail for keeper-only account');
184
+ assert.strictEqual(res.status, 403);
185
+ });
158
186
  });
159
187
  // --- 2. Role grant create/revoke lifecycle ---
160
188
  // Role grant create/revoke are RPC-only (see `role_grant_offer_create` /
@@ -242,9 +270,14 @@ export const describe_standard_admin_integration_tests = (options) => {
242
270
  test('admin can revoke all tokens for another account', async () => {
243
271
  const fixture = await options.setup_test();
244
272
  const user_two = await fixture.create_account({ username: 'user_two' });
245
- // Verify user_two's bearer token works via `account_verify` RPC
273
+ // Verify user_two's bearer token works via `account_verify` RPC.
274
+ // Fresh transport — admin's session cookie in `fixture.transport`'s
275
+ // jar would otherwise give a false 200 here, masking whether the
276
+ // bearer credential is the one being validated. `origin: null` so
277
+ // the transport doesn't auto-add a default Origin (which would
278
+ // discard the bearer as browser-context cross-process).
246
279
  const before = await rpc_call_for_spec({
247
- app: { request: fixture.transport },
280
+ app: { request: fixture.fresh_transport({ origin: null }) },
248
281
  path: rpc_path,
249
282
  spec: account_verify_action_spec,
250
283
  params: undefined,
@@ -263,9 +296,10 @@ export const describe_standard_admin_integration_tests = (options) => {
263
296
  assert.ok(res.ok, `admin_token_revoke_all failed: ${res.ok ? '' : JSON.stringify(res.error)}`);
264
297
  assert.strictEqual(res.result.ok, true);
265
298
  assert.ok(res.result.count >= 1, 'Expected at least 1 revoked token');
266
- // Verify user_two's bearer token no longer works
299
+ // Verify user_two's bearer token no longer works — fresh transport
300
+ // same reason as the `before` call above.
267
301
  const after = await rpc_call_for_spec({
268
- app: { request: fixture.transport },
302
+ app: { request: fixture.fresh_transport({ origin: null }) },
269
303
  path: rpc_path,
270
304
  spec: account_verify_action_spec,
271
305
  params: undefined,
@@ -341,19 +375,26 @@ export const describe_standard_admin_integration_tests = (options) => {
341
375
  describe('admin audit trail', () => {
342
376
  test('role_grant revoke creates audit event', async () => {
343
377
  const fixture = await options.setup_test();
344
- assert(fixture.in_process, 'direct role_grant seed requires in-process db');
345
378
  const user_two = await fixture.create_account({ username: 'user_two' });
346
- const role_grant = await create_test_role_grant_direct(fixture.backend_internals.deps.db, {
347
- actor_id: user_two.actor.id,
379
+ // Drive the production consent flow so the role_grant exists
380
+ // via the same code path real users go through. The
381
+ // audit_log_list filter below pulls only `role_grant_revoke`
382
+ // events so the extra `role_grant_offer_create` /
383
+ // `role_grant_offer_accepted` audits emitted upstream don't
384
+ // affect the assertion.
385
+ const { role_grant_id } = await role_grant_offer_and_accept({
386
+ app: { request: fixture.transport },
387
+ rpc_path,
388
+ grantor: fixture,
389
+ recipient: user_two,
348
390
  role: grantable_role,
349
- granted_by: fixture.actor.id,
350
391
  });
351
392
  // Revoke via RPC
352
393
  const revoke_res = await rpc_call_for_spec({
353
394
  app: { request: fixture.transport },
354
395
  path: rpc_path,
355
396
  spec: role_grant_revoke_action_spec,
356
- params: { actor_id: user_two.actor.id, role_grant_id: role_grant.id },
397
+ params: { actor_id: user_two.actor.id, role_grant_id },
357
398
  headers: fixture.create_session_headers(),
358
399
  });
359
400
  assert.ok(revoke_res.ok, `role_grant_revoke failed: ${revoke_res.ok ? '' : JSON.stringify(revoke_res.error)}`);
@@ -492,24 +533,36 @@ export const describe_standard_admin_integration_tests = (options) => {
492
533
  if (!login_route || !logout_route || !password_route)
493
534
  return;
494
535
  const user_two = await fixture.create_account({ username: 'audit_user' });
495
- // 1. login (user_two logs in)
496
- const login_res = await fixture.transport(login_route.path, {
536
+ // 1. login (user_two logs in) — fresh transport because the per-test
537
+ // session cookie in `fixture.transport`'s jar would otherwise be sent
538
+ // alongside this unauthenticated login attempt, and the route can
539
+ // reject the "already-authed" cookie-collision case with 401.
540
+ // Read the actual username off the returned account — the fresh-DB
541
+ // contract makes the supplied literal `'audit_user'` survive
542
+ // unchanged, but reading from `.account.username` is structurally
543
+ // robust against any future username-mangling at the mint layer.
544
+ const login_res = await fixture.fresh_transport()(login_route.path, {
497
545
  method: 'POST',
498
546
  headers: {
499
547
  host: 'localhost',
500
548
  origin: 'http://localhost:5173',
501
549
  'content-type': 'application/json',
502
550
  },
503
- body: JSON.stringify({ username: 'audit_user', password: 'test-password-123' }),
551
+ body: JSON.stringify({
552
+ username: user_two.account.username,
553
+ password: DEFAULT_TEST_PASSWORD,
554
+ }),
504
555
  });
505
556
  assert.strictEqual(login_res.status, 200);
506
557
  // extract user_two session cookie for logout
507
558
  const set_cookie = login_res.headers.get('set-cookie');
508
559
  const cookie_match = new RegExp(`${cookie_name}=([^;]+)`).exec(set_cookie ?? '');
509
560
  const user_two_cookie = cookie_match?.[1];
510
- // 2. logout (user_two logs out)
561
+ // 2. logout (user_two logs out) — fresh transport with the explicit
562
+ // user_two cookie, so the per-test session cookie can't interfere with
563
+ // the logout target.
511
564
  if (user_two_cookie) {
512
- await fixture.transport(logout_route.path, {
565
+ await fixture.fresh_transport()(logout_route.path, {
513
566
  method: 'POST',
514
567
  headers: {
515
568
  host: 'localhost',
@@ -552,7 +605,7 @@ export const describe_standard_admin_integration_tests = (options) => {
552
605
  'content-type': 'application/json',
553
606
  }),
554
607
  body: JSON.stringify({
555
- current_password: 'test-password-123',
608
+ current_password: DEFAULT_TEST_PASSWORD,
556
609
  new_password: 'new-audit-password-789',
557
610
  }),
558
611
  });
@@ -617,20 +670,23 @@ export const describe_standard_admin_integration_tests = (options) => {
617
670
  username: 'admin_b_iso',
618
671
  roles: ['admin'],
619
672
  });
620
- // Seed an active role_grant directly the revoke IDOR check is the
621
- // subject of this test, not the grant→accept cycle.
622
- assert(fixture.in_process, 'direct role_grant seed requires in-process db');
623
- const role_grant = await create_test_role_grant_direct(fixture.backend_internals.deps.db, {
624
- actor_id: admin_b.actor.id,
673
+ // Seed an active role_grant for admin B via the production
674
+ // consent flow. The revoke IDOR check is the subject of this
675
+ // test; the grant path is precondition setup, exercised
676
+ // via the same RPCs production drives.
677
+ const { role_grant_id } = await role_grant_offer_and_accept({
678
+ app: { request: fixture.transport },
679
+ rpc_path,
680
+ grantor: fixture,
681
+ recipient: admin_b,
625
682
  role: grantable_role,
626
- granted_by: fixture.actor.id,
627
683
  });
628
684
  // Admin B revokes their own role_grant via RPC — should succeed
629
685
  const revoke_res = await rpc_call_for_spec({
630
686
  app: { request: fixture.transport },
631
687
  path: rpc_path,
632
688
  spec: role_grant_revoke_action_spec,
633
- params: { actor_id: admin_b.actor.id, role_grant_id: role_grant.id },
689
+ params: { actor_id: admin_b.actor.id, role_grant_id },
634
690
  headers: create_headers(admin_b.session_cookie),
635
691
  });
636
692
  assert.ok(revoke_res.ok, `role_grant_revoke failed: ${revoke_res.ok ? '' : JSON.stringify(revoke_res.error)}`);
@@ -32,6 +32,21 @@ import type { RpcEndpointsSuiteOption } from './rpc_helpers.js';
32
32
  export declare const stub_password_deps: PasswordHashDeps;
33
33
  /** 64-hex-char test cookie secret — deterministic, never used in production. */
34
34
  export declare const TEST_COOKIE_SECRET: string;
35
+ /**
36
+ * Default password for bootstrapped test accounts. Shared between the
37
+ * in-process keeper bootstrap (`bootstrap_test_keeper`,
38
+ * `create_test_account_with_credentials`, `create_test_app_server`,
39
+ * `TestApp.create_account`) and the cross-process bootstrap
40
+ * (`cross_backend/setup.ts`). The two paths MUST agree — when they
41
+ * diverged during the 3d cross-process lift, ~20 login tests 401'd
42
+ * silently against the cross-process backend because the per-test
43
+ * fixture minted accounts under a different default than the
44
+ * integration suite's hardcoded login bodies expected. Consumers
45
+ * hardcoding the literal string in test bodies should import this
46
+ * constant instead so a future divergence becomes a typecheck miss
47
+ * rather than a runtime password mismatch.
48
+ */
49
+ export declare const DEFAULT_TEST_PASSWORD = "test-password-123";
35
50
  /**
36
51
  * Options for `bootstrap_test_keeper` and `create_test_account_with_credentials`.
37
52
  *
@@ -135,7 +150,7 @@ export interface TestAppServerOptions {
135
150
  password?: PasswordHashDeps;
136
151
  /** Username for the bootstrapped account. Default: `'keeper'`. */
137
152
  username?: string;
138
- /** Password for the bootstrapped account. Default: `'test-password-123'`. */
153
+ /** Password for the bootstrapped account. Default: `DEFAULT_TEST_PASSWORD`. */
139
154
  password_value?: string;
140
155
  /** Roles to grant. Default: `[ROLE_KEEPER]`. */
141
156
  roles?: Array<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/app_server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/app_server.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,21 @@ export const stub_password_deps = {
28
28
  };
29
29
  /** 64-hex-char test cookie secret — deterministic, never used in production. */
30
30
  export const TEST_COOKIE_SECRET = 'a'.repeat(64);
31
+ /**
32
+ * Default password for bootstrapped test accounts. Shared between the
33
+ * in-process keeper bootstrap (`bootstrap_test_keeper`,
34
+ * `create_test_account_with_credentials`, `create_test_app_server`,
35
+ * `TestApp.create_account`) and the cross-process bootstrap
36
+ * (`cross_backend/setup.ts`). The two paths MUST agree — when they
37
+ * diverged during the 3d cross-process lift, ~20 login tests 401'd
38
+ * silently against the cross-process backend because the per-test
39
+ * fixture minted accounts under a different default than the
40
+ * integration suite's hardcoded login bodies expected. Consumers
41
+ * hardcoding the literal string in test bodies should import this
42
+ * constant instead so a future divergence becomes a typecheck miss
43
+ * rather than a runtime password mismatch.
44
+ */
45
+ export const DEFAULT_TEST_PASSWORD = 'test-password-123';
31
46
  // Module-level PGlite factory for create_test_app_server when no db is provided.
32
47
  // Shares the WASM instance cache from test_db.ts, avoiding redundant cold starts
33
48
  // within the same vitest worker thread. Schema is reset on each create() call.
@@ -48,7 +63,7 @@ const fallback_pglite_factory = create_pglite_factory(async (db) => {
48
63
  * `role_grant` (one per role), `api_token`, and `auth_session`.
49
64
  */
50
65
  export const create_test_account_with_credentials = async (options) => {
51
- const { db, keyring, session_options, password, username = 'keeper', password_value = 'test-password-123', roles = [], } = options;
66
+ const { db, keyring, session_options, password, username = 'keeper', password_value = DEFAULT_TEST_PASSWORD, roles = [], } = options;
52
67
  const deps = { db };
53
68
  const password_hash = await password.hash_password(password_value);
54
69
  const { account, actor } = await query_create_account_with_actor(deps, {
@@ -166,7 +181,7 @@ const _build_test_backend = async (options) => {
166
181
  return { backend, keyring: keyring_result.keyring };
167
182
  };
168
183
  export const create_test_app_server = async (options) => {
169
- const { session_options, password = stub_password_deps, username = 'keeper', password_value = 'test-password-123', roles = [ROLE_KEEPER], } = options;
184
+ const { session_options, password = stub_password_deps, username = 'keeper', password_value = DEFAULT_TEST_PASSWORD, roles = [ROLE_KEEPER], } = options;
170
185
  const { backend, keyring } = await _build_test_backend(options);
171
186
  const bootstrapped = await bootstrap_test_keeper({
172
187
  db: backend.deps.db,
@@ -253,7 +268,7 @@ export const create_test_app = async (options) => {
253
268
  session_options: options.session_options,
254
269
  password,
255
270
  username: account_options?.username ?? `test_user_${account_counter}`,
256
- password_value: account_options?.password_value ?? 'test-password-123',
271
+ password_value: account_options?.password_value ?? DEFAULT_TEST_PASSWORD,
257
272
  roles: account_options?.roles ?? [],
258
273
  });
259
274
  return {
@@ -1,9 +1,9 @@
1
1
  import './assert_dev_env.js';
2
2
  import type { SessionOptions } from '../auth/session_cookie.js';
3
3
  import { type RpcEndpointsSuiteOption } from './rpc_helpers.js';
4
+ import type { AppSurfaceSpec } from '../http/surface.js';
4
5
  import type { BackendCapabilities } from './cross_backend/capabilities.js';
5
6
  import type { SetupTest } from './cross_backend/setup.js';
6
- import type { SurfaceSource } from './transports/surface_source.js';
7
7
  /**
8
8
  * Configuration for `describe_audit_completeness_tests`.
9
9
  */
@@ -16,11 +16,13 @@ export interface AuditCompletenessTestOptions {
16
16
  */
17
17
  setup_test: SetupTest;
18
18
  /**
19
- * Source of the app surface. Currently requires `kind: 'inline'`
20
- * the cross-process snapshot variant lands alongside the spawned-backend
21
- * transport plumbing.
19
+ * App surface (with route specs). Constructed in TS by the consumer;
20
+ * same shape for in-process and cross-process tests. The audit suite is
21
+ * Tier 2 today (stays in-process per the cross-backend-integration
22
+ * design), but takes the same surface shape as Tier 1 suites for
23
+ * options uniformity.
22
24
  */
23
- surface_source: SurfaceSource;
25
+ surface_source: AppSurfaceSpec;
24
26
  /** Backend capability declarations. */
25
27
  capabilities: BackendCapabilities;
26
28
  /** Session config — needed for factory-form rpc_endpoints resolution. */
@@ -1 +1 @@
1
- {"version":3,"file":"audit_completeness.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/audit_completeness.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA4B7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAS9D,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAwB1B,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EAAC,SAAS,EAAc,MAAM,0BAA0B,CAAC;AACrE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,gCAAgC,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C;;;;;OAKG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,aAAa,CAAC;IAC9B,uCAAuC;IACvC,YAAY,EAAE,mBAAmB,CAAC;IAClC,yEAAyE;IACzE,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC;;;OAGG;IACH,aAAa,EAAE,uBAAuB,CAAC;CACvC;AA8FD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iCAAiC,GAAI,SAAS,4BAA4B,KAAG,IA6hBzF,CAAC"}
1
+ {"version":3,"file":"audit_completeness.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/audit_completeness.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA4B7B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAS9D,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAwB1B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,iCAAiC,CAAC;AACzE,OAAO,KAAK,EAAC,SAAS,EAAc,MAAM,0BAA0B,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC5C;;;;;OAKG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;;;OAMG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,uCAAuC;IACvC,YAAY,EAAE,mBAAmB,CAAC;IAClC,yEAAyE;IACzE,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC;;;OAGG;IACH,aAAa,EAAE,uBAAuB,CAAC;CACvC;AA8FD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iCAAiC,GAAI,SAAS,4BAA4B,KAAG,IAuhBzF,CAAC"}
@@ -25,7 +25,7 @@ import './assert_dev_env.js';
25
25
  import { describe, test, assert } from 'vitest';
26
26
  import { ROLE_ADMIN } from '../auth/role_schema.js';
27
27
  import { AUDIT_EVENT_TYPES, } from '../auth/audit_log_schema.js';
28
- import {} from './app_server.js';
28
+ import { DEFAULT_TEST_PASSWORD } from './app_server.js';
29
29
  import { find_auth_route } from './integration_helpers.js';
30
30
  import { rpc_call_for_spec, require_rpc_endpoint_path, resolve_rpc_endpoints_for_setup, } from './rpc_helpers.js';
31
31
  import { role_grant_offer_and_accept } from './role_grant_helpers.js';
@@ -106,11 +106,7 @@ const json_session_headers = (fixture, extra) => fixture.create_session_headers(
106
106
  * `require_rpc_endpoint_path`.
107
107
  */
108
108
  export const describe_audit_completeness_tests = (options) => {
109
- if (options.surface_source.kind !== 'inline') {
110
- throw new Error("describe_audit_completeness_tests requires surface_source.kind === 'inline' — " +
111
- 'the cross-process snapshot variant lands with the spawned-backend transport');
112
- }
113
- const route_specs = options.surface_source.spec.route_specs;
109
+ const route_specs = options.surface_source.route_specs;
114
110
  // Hard-fail early so consumers see a clear setup error instead of a
115
111
  // confusing test failure when `rpc_endpoints` is missing.
116
112
  const rpc_endpoints_for_setup = resolve_rpc_endpoints_for_setup(options.rpc_endpoints, options.session_options);
@@ -129,7 +125,7 @@ export const describe_audit_completeness_tests = (options) => {
129
125
  headers: UNAUTHENTICATED_JSON_HEADERS,
130
126
  body: JSON.stringify({
131
127
  username: fixture.account.username,
132
- password: 'test-password-123',
128
+ password: DEFAULT_TEST_PASSWORD,
133
129
  }),
134
130
  });
135
131
  assert.strictEqual(res.status, 200);
@@ -218,7 +214,7 @@ export const describe_audit_completeness_tests = (options) => {
218
214
  headers: UNAUTHENTICATED_JSON_HEADERS,
219
215
  body: JSON.stringify({
220
216
  username: fixture.account.username,
221
- password: 'test-password-123',
217
+ password: DEFAULT_TEST_PASSWORD,
222
218
  }),
223
219
  });
224
220
  // get session IDs (newest first — `account_session_list` orders DESC
@@ -271,7 +267,7 @@ export const describe_audit_completeness_tests = (options) => {
271
267
  method: 'POST',
272
268
  headers: json_session_headers(fixture),
273
269
  body: JSON.stringify({
274
- current_password: 'test-password-123',
270
+ current_password: DEFAULT_TEST_PASSWORD,
275
271
  new_password: 'new-password-456',
276
272
  }),
277
273
  });
@@ -7,8 +7,8 @@ import './assert_dev_env.js';
7
7
  * observable state — account exists, `bootstrap_lock.bootstrapped` is
8
8
  * true, audit row emitted, response body shape — rather than
9
9
  * `on_bootstrap` callback invocation, so the suite stays cross-impl
10
- * friendly when Phase 3 cross-process testing wires it against a
11
- * spawned Rust backend.
10
+ * friendly when cross-process testing wires it against a spawned
11
+ * Rust backend.
12
12
  *
13
13
  * Folded into `describe_standard_tests` with a `bootstrap.mode === 'live'`
14
14
  * silent-skip gate; consumers wiring live bootstrap pick up success-path
@@ -0,0 +1,113 @@
1
+ import '../assert_dev_env.js';
2
+ /**
3
+ * Cross-process backend configuration.
4
+ *
5
+ * `BackendConfig` describes a spawnable test binary — argv, mount paths,
6
+ * env vars, bootstrap credentials, daemon-token discovery path, declared
7
+ * capabilities. Consumer projects ship per-backend factories
8
+ * (`deno_backend_config()`, `rust_backend_config()`,
9
+ * `spine_stub_backend_config()`) that produce this shape; `spawn_backend`
10
+ * consumes it.
11
+ *
12
+ * fuz_app ships `spine_stub_backend_config()` as a convenience preset
13
+ * (operational dep on `testing_spine_stub` — path-based discovery, no
14
+ * `package.json` coupling to the stub's source package). Otherwise backend-specific
15
+ * knowledge (binary paths, port choices, env vars) is a consumer
16
+ * concern; fuz_app's testing library knows nothing about Deno, Cargo, or
17
+ * any specific runtime beyond that preset.
18
+ *
19
+ * @module
20
+ */
21
+ import type { BackendCapabilities } from './capabilities.js';
22
+ /**
23
+ * Auth-bootstrap configuration for a spawnable test binary. The runner
24
+ * writes `token` to `token_path` before launching the child, then POSTs
25
+ * `bootstrap_path` (default `/api/account/bootstrap`) with the token plus
26
+ * the `username` / `password` to mint the keeper account and capture the
27
+ * session cookie. After health-probe, the runner reads
28
+ * `daemon_token_path` to load the binary's deterministic daemon token,
29
+ * which `default_cross_process_setup` threads onto the per-test
30
+ * `TestFixture` for `_testing_reset` calls and other keeper-credential
31
+ * operations.
32
+ */
33
+ export interface BackendBootstrapConfig {
34
+ /** Path the binary reads for the bootstrap token (env: `*_BOOTSTRAP_TOKEN_PATH`). */
35
+ readonly token_path: string;
36
+ /** Token text written to `token_path` before spawn. */
37
+ readonly token: string;
38
+ /** Username for the bootstrapped keeper. */
39
+ readonly username: string;
40
+ /** Password for the bootstrapped keeper. */
41
+ readonly password: string;
42
+ /**
43
+ * Path the test binary writes its daemon-token JSON to on boot
44
+ * (env: `*_DAEMON_TOKEN_PATH`). `spawn_backend` reads this file once
45
+ * after the health probe succeeds and threads the token onto
46
+ * `BackendHandle.daemon_token` for `_testing_reset` calls plus any
47
+ * other admin/keeper-gated cross-process tests.
48
+ */
49
+ readonly daemon_token_path: string;
50
+ }
51
+ /**
52
+ * Configuration for one spawnable test backend. Consumer factories
53
+ * (`deno_backend_config()`, `rust_backend_config()`) produce these and
54
+ * the runner consumes them through `spawn_backend`.
55
+ *
56
+ * Path defaults match the standard fuz_app surface — Deno + Rust spine
57
+ * (`zzz_server`, `fuz_forge_server`, `testing_spine_stub`) all converge on
58
+ * `/api/account/{bootstrap,login,logout,password}`,
59
+ * `/api/rpc`, `/api/ws`, `/health`. Override only when a backend
60
+ * deliberately diverges (which it shouldn't, per the contract).
61
+ */
62
+ export interface BackendConfig {
63
+ /** Diagnostic label (`"deno"`, `"rust"`, `"spine_stub"`). Surfaces in test output. */
64
+ readonly name: string;
65
+ /** argv passed to the spawn. The first entry is the binary path. */
66
+ readonly start_command: ReadonlyArray<string>;
67
+ /** Base URL for HTTP requests, including port (e.g. `http://localhost:8788`). */
68
+ readonly base_url: string;
69
+ /** JSON-RPC endpoint mount point. Default `/api/rpc`. */
70
+ readonly rpc_path: string;
71
+ /** WebSocket endpoint mount point. Default `/api/ws`. */
72
+ readonly ws_path: string;
73
+ /**
74
+ * SSE stream mount point — drives the cross-process SSE suite's stream
75
+ * path. Optional: only backends advertising `capabilities.sse` serve a
76
+ * stream, and the suite defaults to `/api/admin/audit/stream` (the
77
+ * standard fuz_app audit-log stream) when omitted. Set it only when a
78
+ * backend mounts its stream elsewhere.
79
+ */
80
+ readonly sse_path?: string;
81
+ /** Readiness probe path. Default `/health`. */
82
+ readonly health_path: string;
83
+ /** Bootstrap POST path. Default `/api/account/bootstrap`. */
84
+ readonly bootstrap_path: string;
85
+ /**
86
+ * Session cookie name the backend issues. Default `fuz_session` per
87
+ * the ecosystem convergence; consumers using a custom session name
88
+ * (legacy `zzz_session`, etc.) override. `default_cross_process_setup`
89
+ * extracts the per-account session value from the transport jar by
90
+ * this name so the cross-process `TestAccount.session_cookie` matches
91
+ * the in-process shape.
92
+ */
93
+ readonly cookie_name: string;
94
+ /** How long to wait for the health probe (ms) before giving up. */
95
+ readonly startup_timeout_ms: number;
96
+ /**
97
+ * Env vars merged into the child process. Must include the binary's
98
+ * `*_BOOTSTRAP_TOKEN_PATH` + `*_DAEMON_TOKEN_PATH` env var names so
99
+ * the binary reads/writes the right files. Also must include the
100
+ * binary's `*_ALLOWED_ORIGINS` (typically
101
+ * `'http://localhost:*'` for cross-process tests).
102
+ */
103
+ readonly env: Readonly<Record<string, string>>;
104
+ /** Auth bootstrap details — see `BackendBootstrapConfig`. */
105
+ readonly bootstrap: BackendBootstrapConfig;
106
+ /**
107
+ * Capabilities this backend supports — drives `test_if(capabilities.X, ...)`
108
+ * gating in suite bodies. See `capabilities.ts` for the vocabulary and
109
+ * existing flags. Cross-process backends set `in_process_only: false`.
110
+ */
111
+ readonly capabilities: BackendCapabilities;
112
+ }
113
+ //# sourceMappingURL=backend_config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend_config.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/backend_config.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,MAAM,WAAW,sBAAsB;IACtC,qFAAqF;IACrF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,aAAa;IAC7B,sFAAsF;IACtF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C,iFAAiF;IACjF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,+CAA+C;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/C,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;CAC3C"}
@@ -0,0 +1 @@
1
+ import '../assert_dev_env.js';