@fuzdev/fuz_app 0.88.0 → 0.90.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 (49) hide show
  1. package/dist/auth/account_action_specs.d.ts +1 -1
  2. package/dist/auth/account_route_schema.d.ts +12 -6
  3. package/dist/auth/account_route_schema.d.ts.map +1 -1
  4. package/dist/auth/account_route_schema.js +11 -5
  5. package/dist/auth/account_routes.d.ts +18 -4
  6. package/dist/auth/account_routes.d.ts.map +1 -1
  7. package/dist/auth/account_routes.js +13 -5
  8. package/dist/auth/account_schema.d.ts +3 -3
  9. package/dist/auth/admin_action_specs.d.ts +8 -8
  10. package/dist/auth/audit_log_schema.d.ts +1 -1
  11. package/dist/auth/invite_schema.d.ts +2 -2
  12. package/dist/auth/signup_route_schema.d.ts +2 -2
  13. package/dist/auth/signup_route_schema.d.ts.map +1 -1
  14. package/dist/auth/signup_route_schema.js +2 -2
  15. package/dist/primitive_schemas.d.ts +27 -1
  16. package/dist/primitive_schemas.d.ts.map +1 -1
  17. package/dist/primitive_schemas.js +55 -2
  18. package/dist/server/env.d.ts +1 -1
  19. package/dist/server/env.d.ts.map +1 -1
  20. package/dist/server/env.js +15 -3
  21. package/dist/testing/CLAUDE.md +62 -2
  22. package/dist/testing/app_server.d.ts +16 -5
  23. package/dist/testing/app_server.d.ts.map +1 -1
  24. package/dist/testing/app_server.js +3 -1
  25. package/dist/testing/cross_backend/body_size_smuggling.d.ts +12 -0
  26. package/dist/testing/cross_backend/body_size_smuggling.d.ts.map +1 -1
  27. package/dist/testing/cross_backend/body_size_smuggling.js +68 -41
  28. package/dist/testing/cross_backend/capabilities.d.ts +29 -0
  29. package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
  30. package/dist/testing/cross_backend/capabilities.js +15 -0
  31. package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
  32. package/dist/testing/cross_backend/default_backend_configs.js +13 -0
  33. package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -1
  34. package/dist/testing/cross_backend/default_spine_surface.js +7 -0
  35. package/dist/testing/cross_backend/identity_parity.d.ts +13 -0
  36. package/dist/testing/cross_backend/identity_parity.d.ts.map +1 -0
  37. package/dist/testing/cross_backend/identity_parity.js +465 -0
  38. package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts.map +1 -1
  39. package/dist/testing/cross_backend/rust_spine_stub_backend_config.js +13 -6
  40. package/dist/testing/cross_backend/setup.d.ts +9 -0
  41. package/dist/testing/cross_backend/setup.d.ts.map +1 -1
  42. package/dist/testing/cross_backend/setup.js +14 -1
  43. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
  44. package/dist/testing/cross_backend/ts_spine_backend_config.js +16 -1
  45. package/dist/testing/integration.d.ts.map +1 -1
  46. package/dist/testing/integration.js +13 -16
  47. package/dist/testing/schema_generators.d.ts.map +1 -1
  48. package/dist/testing/schema_generators.js +7 -0
  49. package/package.json +3 -3
@@ -24,7 +24,7 @@ import { is_public_auth } from '../http/auth_shape.js';
24
24
  import { account_verify_action_spec, account_session_list_action_spec, account_session_revoke_action_spec, account_session_revoke_all_action_spec, account_token_create_action_spec, account_token_list_action_spec, account_token_revoke_action_spec, } from '../auth/account_action_specs.js';
25
25
  import { invite_create_action_spec } from '../auth/admin_action_specs.js';
26
26
  import { LoginOutput, AccountStatusOutput } from '../auth/account_route_schema.js';
27
- import {} from './cross_backend/capabilities.js';
27
+ import { test_if } from './cross_backend/capabilities.js';
28
28
  import { DEFAULT_TEST_PASSWORD } from './test_credentials.js';
29
29
  /**
30
30
  * Standard integration test suite for fuz_app auth routes.
@@ -316,15 +316,15 @@ export const describe_standard_integration_tests = (options) => {
316
316
  // fixture keeper is single-actor, so `actor` must be non-null and
317
317
  // `role_grants` populated (keeper holds keeper + admin globally).
318
318
  //
319
- // `/status` is mounted at `create_app_server` time (it needs the
320
- // `bootstrap_available` runtime state), not by `create_account_route_specs`
321
- // and not listed in the declared surface, so we can't gate on `route_specs`.
322
- // A backend that mounts only the account-route factory (e.g. a minimal
323
- // in-process route set) doesn't serve it — probe at runtime and skip on
324
- // 404. The full spine surfaces (in-process + cross-process) serve it, so
325
- // the gate runs there. `find_auth_route` can't be used: `/status` isn't a
326
- // `RestAuthRouteSuffix`.
327
- test('authenticated status body strict-parses against AccountStatusOutput', async (ctx) => {
319
+ // `/status` is bundled into `create_account_route_specs` (relative
320
+ // `/status`, prefixed to `/api/account/status`), so every account
321
+ // surface serves it — matching the Rust `account_router`. Gated on the
322
+ // declared `account_status` capability rather than a runtime 404-sniff:
323
+ // a backend that mounts account routes declares `account_status: true`
324
+ // and the gate **fails loud** if `/status` is missing (no more silent
325
+ // skip swallowing the coverage); a backend without it skips explicitly.
326
+ // `find_auth_route` can't be used: `/status` isn't a `RestAuthRouteSuffix`.
327
+ test_if(options.capabilities.account_status, 'authenticated status body strict-parses against AccountStatusOutput', async () => {
328
328
  const fixture = await options.setup_test();
329
329
  const login_route = find_auth_route(route_specs, '/login', 'POST');
330
330
  assert.ok(login_route, 'Expected POST /login route — ensure create_route_specs includes account routes');
@@ -334,12 +334,9 @@ export const describe_standard_integration_tests = (options) => {
334
334
  method: 'GET',
335
335
  headers: fixture.create_session_headers({ host: 'localhost' }),
336
336
  });
337
- if (res.status === 404) {
338
- // Backend doesn't mount /status (minimal route set) — nothing to gate.
339
- ctx.skip();
340
- return;
341
- }
342
- assert.strictEqual(res.status, 200);
337
+ assert.strictEqual(res.status, 200, `expected 200 from ${status_path} — capabilities.account_status is true, so the ` +
338
+ `account surface must bundle GET /status. A 404 means the backend declares the ` +
339
+ `capability but doesn't mount the route.`);
343
340
  const body = await res.json();
344
341
  // Throws on any extra/missing field across account/actor/role_grants.
345
342
  const parsed = AccountStatusOutput.parse(body);
@@ -1 +1 @@
1
- {"version":3,"file":"schema_generators.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/schema_generators.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,yBAAyB,CAAC;AAIjC;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,MAAM,GAAG,IAkBhE,CAAC;AA+FF,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,GAAI,OAAO,YAAY,EAAE,cAAc,CAAC,CAAC,OAAO,KAAG,OAgGnF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,gBAAgB,CAAC,CAAC,SAAS,KAAG,MAa9E,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,GAC/B,cAAc,CAAC,CAAC,OAAO,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SA6B5B,CAAC"}
1
+ {"version":3,"file":"schema_generators.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/schema_generators.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,yBAAyB,CAAC;AAIjC;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,MAAM,GAAG,IAkBhE,CAAC;AAsGF,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,GAAI,OAAO,YAAY,EAAE,cAAc,CAAC,CAAC,OAAO,KAAG,OAgGnF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,gBAAgB,CAAC,CAAC,SAAS,KAAG,MAa9E,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,GAC/B,cAAc,CAAC,CAAC,OAAO,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SA6B5B,CAAC"}
@@ -127,6 +127,13 @@ const generate_valid_string = (field_schema) => {
127
127
  if (slug !== null && field_schema.safeParse(slug).success)
128
128
  return slug;
129
129
  }
130
+ // Email-shaped refinement (the `Email` primitive: loose `local@domain.tld`).
131
+ // The base `x`-fill has no `@`, so an email-pattern field needs a shaped
132
+ // candidate — the `z.string().regex()` form exposes a `pattern`, not the
133
+ // `format: 'email'` the `case 'email'` switch arm keys on.
134
+ const as_email = 'test@example.com';
135
+ if (field_schema.safeParse(as_email).success)
136
+ return as_email;
130
137
  // Absolute path refinement (e.g. DiskfilePath)
131
138
  const with_slash = '/' + base;
132
139
  if (field_schema.safeParse(with_slash).success)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzdev/fuz_app",
3
- "version": "0.88.0",
3
+ "version": "0.90.0",
4
4
  "description": "fullstack app library",
5
5
  "glyph": "🗝",
6
6
  "logo": "logo.svg",
@@ -69,9 +69,9 @@
69
69
  "devDependencies": {
70
70
  "@electric-sql/pglite": "^0.4.5",
71
71
  "@fuzdev/blake3_wasm": "^0.1.1",
72
- "@fuzdev/fuz_code": "^0.46.0",
72
+ "@fuzdev/fuz_code": "^0.46.1",
73
73
  "@fuzdev/fuz_css": "^0.63.2",
74
- "@fuzdev/fuz_ui": "^0.205.0",
74
+ "@fuzdev/fuz_ui": "^0.205.1",
75
75
  "@fuzdev/fuz_util": "^0.65.1",
76
76
  "@fuzdev/gro": "^0.204.0",
77
77
  "@fuzdev/mdz": "^0.1.0",