@fuzdev/fuz_app 0.139.0 → 0.141.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/CLAUDE.md +62 -17
- package/dist/actions/action_rpc.d.ts +5 -1
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +9 -1
- package/dist/actions/connection_closer.d.ts +25 -2
- package/dist/actions/connection_closer.d.ts.map +1 -1
- package/dist/actions/connection_closer.js +8 -1
- package/dist/actions/register_action_ws.d.ts +42 -6
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/actions/register_action_ws.js +87 -19
- package/dist/actions/register_ws_endpoint.d.ts +15 -6
- package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
- package/dist/actions/register_ws_endpoint.js +5 -2
- package/dist/actions/socket.svelte.d.ts +19 -4
- package/dist/actions/socket.svelte.d.ts.map +1 -1
- package/dist/actions/socket.svelte.js +31 -4
- package/dist/actions/transports.d.ts +30 -1
- package/dist/actions/transports.d.ts.map +1 -1
- package/dist/actions/transports.js +30 -1
- package/dist/actions/transports_ws_auth_guard.d.ts +13 -6
- package/dist/actions/transports_ws_auth_guard.d.ts.map +1 -1
- package/dist/actions/transports_ws_auth_guard.js +24 -10
- package/dist/actions/transports_ws_backend.d.ts +51 -5
- package/dist/actions/transports_ws_backend.d.ts.map +1 -1
- package/dist/actions/transports_ws_backend.js +62 -9
- package/dist/actions/ws_endpoint_spec.d.ts +11 -10
- package/dist/actions/ws_endpoint_spec.d.ts.map +1 -1
- package/dist/auth/CLAUDE.md +11 -9
- package/dist/auth/account_route_schema.d.ts +1 -0
- package/dist/auth/account_route_schema.d.ts.map +1 -1
- package/dist/auth/account_route_schema.js +4 -0
- package/dist/auth/api_token.d.ts +20 -0
- package/dist/auth/api_token.d.ts.map +1 -1
- package/dist/auth/api_token.js +21 -1
- package/dist/auth/api_token_queries.d.ts +22 -4
- package/dist/auth/api_token_queries.d.ts.map +1 -1
- package/dist/auth/api_token_queries.js +11 -6
- package/dist/auth/audit_log_routes.d.ts +10 -0
- package/dist/auth/audit_log_routes.d.ts.map +1 -1
- package/dist/auth/audit_log_routes.js +20 -0
- package/dist/auth/audit_log_schema.d.ts +30 -5
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.js +30 -0
- package/dist/auth/bearer_auth.d.ts +4 -2
- package/dist/auth/bearer_auth.d.ts.map +1 -1
- package/dist/auth/bearer_auth.js +19 -8
- package/dist/auth/bootstrap_route_schema.d.ts +1 -0
- package/dist/auth/bootstrap_route_schema.d.ts.map +1 -1
- package/dist/auth/bootstrap_route_schema.js +1 -0
- package/dist/auth/cleanup.d.ts +9 -9
- package/dist/auth/cleanup.js +9 -9
- package/dist/auth/credential_deadline.d.ts +95 -0
- package/dist/auth/credential_deadline.d.ts.map +1 -0
- package/dist/auth/credential_deadline.js +139 -0
- package/dist/auth/daemon_token_middleware.d.ts.map +1 -1
- package/dist/auth/daemon_token_middleware.js +4 -1
- package/dist/auth/middleware.d.ts +90 -12
- package/dist/auth/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js +115 -16
- package/dist/auth/request_context.d.ts +4 -2
- package/dist/auth/request_context.d.ts.map +1 -1
- package/dist/auth/request_context.js +14 -3
- package/dist/auth/resolved_auth.d.ts +13 -2
- package/dist/auth/resolved_auth.d.ts.map +1 -1
- package/dist/auth/resolved_auth.js +5 -4
- package/dist/auth/session_cookie.d.ts +4 -0
- package/dist/auth/session_cookie.d.ts.map +1 -1
- package/dist/auth/session_cookie.js +3 -2
- package/dist/auth/session_middleware.d.ts +1 -1
- package/dist/auth/session_middleware.d.ts.map +1 -1
- package/dist/auth/session_middleware.js +4 -1
- package/dist/auth/session_queries.d.ts +19 -2
- package/dist/auth/session_queries.d.ts.map +1 -1
- package/dist/auth/session_queries.js +8 -2
- package/dist/auth/signup_route_schema.d.ts.map +1 -1
- package/dist/auth/signup_route_schema.js +1 -0
- package/dist/hono_context.d.ts +23 -0
- package/dist/hono_context.d.ts.map +1 -1
- package/dist/hono_context.js +19 -0
- package/dist/http/CLAUDE.md +41 -15
- package/dist/http/middleware_spec.d.ts +16 -0
- package/dist/http/middleware_spec.d.ts.map +1 -1
- package/dist/http/origin.d.ts +113 -18
- package/dist/http/origin.d.ts.map +1 -1
- package/dist/http/origin.js +247 -127
- package/dist/http/route_spec.d.ts +21 -0
- package/dist/http/route_spec.d.ts.map +1 -1
- package/dist/http/schema_helpers.d.ts +22 -0
- package/dist/http/schema_helpers.d.ts.map +1 -1
- package/dist/http/schema_helpers.js +24 -0
- package/dist/http/surface.d.ts +6 -1
- package/dist/http/surface.d.ts.map +1 -1
- package/dist/http/surface.js +12 -5
- package/dist/realtime/sse_auth_guard.d.ts +22 -6
- package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
- package/dist/realtime/sse_auth_guard.js +31 -12
- package/dist/realtime/subscriber_registry.d.ts +10 -1
- package/dist/realtime/subscriber_registry.d.ts.map +1 -1
- package/dist/realtime/subscriber_registry.js +10 -1
- package/dist/server/app_server.d.ts +20 -7
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +8 -3
- package/dist/server/env.d.ts +2 -1
- package/dist/server/env.d.ts.map +1 -1
- package/dist/server/env.js +7 -17
- package/dist/server/serve_fact_route.d.ts.map +1 -1
- package/dist/server/serve_fact_route.js +1 -0
- package/dist/testing/CLAUDE.md +154 -22
- package/dist/testing/adversarial_headers.d.ts.map +1 -1
- package/dist/testing/adversarial_headers.js +13 -6
- package/dist/testing/connection_closer_helpers.d.ts +6 -1
- package/dist/testing/connection_closer_helpers.d.ts.map +1 -1
- package/dist/testing/connection_closer_helpers.js +4 -0
- package/dist/testing/cross_backend/body_size.d.ts.map +1 -1
- package/dist/testing/cross_backend/body_size.js +14 -65
- package/dist/testing/cross_backend/capabilities.d.ts +26 -2
- package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
- package/dist/testing/cross_backend/capabilities.js +9 -3
- package/dist/testing/cross_backend/conformance_case.d.ts +11 -3
- package/dist/testing/cross_backend/conformance_case.d.ts.map +1 -1
- package/dist/testing/cross_backend/conformance_case.js +6 -0
- package/dist/testing/cross_backend/conformance_table.d.ts.map +1 -1
- package/dist/testing/cross_backend/conformance_table.js +20 -19
- package/dist/testing/cross_backend/credential_deadline.d.ts +25 -0
- package/dist/testing/cross_backend/credential_deadline.d.ts.map +1 -0
- package/dist/testing/cross_backend/credential_deadline.js +185 -0
- package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_backend_configs.js +13 -2
- package/dist/testing/cross_backend/full_spine_mount.d.ts +3 -0
- package/dist/testing/cross_backend/full_spine_mount.d.ts.map +1 -1
- package/dist/testing/cross_backend/full_spine_mount.js +7 -1
- package/dist/testing/cross_backend/narrowed_api_token.d.ts +23 -0
- package/dist/testing/cross_backend/narrowed_api_token.d.ts.map +1 -0
- package/dist/testing/cross_backend/narrowed_api_token.js +40 -0
- package/dist/testing/cross_backend/origin.d.ts.map +1 -1
- package/dist/testing/cross_backend/origin.js +6 -26
- package/dist/testing/cross_backend/origin_conformance.d.ts +152 -0
- package/dist/testing/cross_backend/origin_conformance.d.ts.map +1 -0
- package/dist/testing/cross_backend/origin_conformance.js +136 -0
- package/dist/testing/cross_backend/origin_conformance.json +1679 -0
- package/dist/testing/cross_backend/origin_scope.d.ts +16 -0
- package/dist/testing/cross_backend/origin_scope.d.ts.map +1 -0
- package/dist/testing/cross_backend/origin_scope.js +140 -0
- package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts +35 -0
- package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts.map +1 -0
- package/dist/testing/cross_backend/role_grant_cross_helpers.js +64 -0
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts +8 -0
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts.map +1 -1
- package/dist/testing/cross_backend/role_grant_offer_notification_ws.js +44 -33
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.js +6 -4
- package/dist/testing/cross_backend/spine_surface_constants.d.ts +19 -0
- package/dist/testing/cross_backend/spine_surface_constants.d.ts.map +1 -1
- package/dist/testing/cross_backend/spine_surface_constants.js +22 -0
- package/dist/testing/cross_backend/testing_backdoor.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_backdoor.js +20 -7
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +180 -5
- package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.js +154 -5
- package/dist/testing/cross_backend/token_scope_surface.d.ts.map +1 -1
- package/dist/testing/cross_backend/token_scope_surface.js +25 -21
- package/dist/testing/cross_backend/transport_composition.d.ts +60 -0
- package/dist/testing/cross_backend/transport_composition.d.ts.map +1 -0
- package/dist/testing/cross_backend/transport_composition.js +364 -0
- package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/ts_spine_backend_config.js +21 -6
- package/dist/testing/cross_backend/ws_role_gated.d.ts +38 -0
- package/dist/testing/cross_backend/ws_role_gated.d.ts.map +1 -0
- package/dist/testing/cross_backend/ws_role_gated.js +142 -0
- package/dist/testing/entities.d.ts +23 -0
- package/dist/testing/entities.d.ts.map +1 -1
- package/dist/testing/entities.js +37 -0
- package/dist/testing/integration.d.ts.map +1 -1
- package/dist/testing/integration.js +3 -1
- package/dist/testing/middleware.d.ts +10 -0
- package/dist/testing/middleware.d.ts.map +1 -1
- package/dist/testing/middleware.js +31 -7
- package/dist/testing/stubs.d.ts +16 -3
- package/dist/testing/stubs.d.ts.map +1 -1
- package/dist/testing/stubs.js +20 -7
- package/dist/testing/surface_invariants.js +2 -2
- package/package.json +12 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/entities.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAiB7B,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,sFAAsF;AACtF,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC,GAAG;IAC/F,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,GAAI,YAAY,oBAAoB,KAAG,OAarE,CAAC;AAEH,oFAAoF;AACpF,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC,GAAG;IAC3F,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,GAAI,YAAY,kBAAkB,KAAG,KAUjE,CAAC;AAEH,yFAAyF;AACzF,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAC3C,IAAI,CACH,SAAS,EACT,IAAI,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,GAAG,YAAY,GAAG,YAAY,GAAG,iBAAiB,CAC/F,CACD,GAAG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,sBAAsB,GAAI,YAAY,sBAAsB,KAAG,SAgB3E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAC/B,cAAa,KAAK,CAAC,sBAAsB,CAAQ,KAC/C,mBAID,CAAC;AAEH,0FAA0F;AAC1F,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAC5C,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,UAAU,GAAG,YAAY,GAAG,mBAAmB,GAAG,iBAAiB,CAAC,CAC/F,GAAG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,uBAAuB,GAAI,YAAY,uBAAuB,KAAG,aAa5E,CAAC"}
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/entities.ts"],"names":[],"mappings":"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"}
|
package/dist/testing/entities.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import './assert_dev_env.js';
|
|
2
|
+
import { API_TOKEN_BODY_LENGTH, API_TOKEN_PREFIX } from '../auth/api_token.js';
|
|
3
|
+
import { token_scope_full } from '../auth/token_scope.js';
|
|
2
4
|
/** Create a test `Account` with sensible defaults. */
|
|
3
5
|
export const create_test_account = (overrides) => ({
|
|
4
6
|
id: 'acct-test',
|
|
@@ -68,3 +70,38 @@ export const create_test_audit_event = (overrides) => ({
|
|
|
68
70
|
metadata: null,
|
|
69
71
|
...overrides
|
|
70
72
|
});
|
|
73
|
+
/**
|
|
74
|
+
* Create a well-formed raw API token for tests that need a bearer value to
|
|
75
|
+
* pass the `is_api_token_shaped` precheck and reach token validation. The
|
|
76
|
+
* body is `label` padded with `A` to the generated length, so distinct labels
|
|
77
|
+
* give distinct tokens and a token in a failure message reads back to its
|
|
78
|
+
* test. Not a real credential — it authenticates only where a test mocks the
|
|
79
|
+
* lookup.
|
|
80
|
+
*
|
|
81
|
+
* @param label - base64url characters (`A-Z a-z 0-9 - _`) that start the token body
|
|
82
|
+
* @returns `API_TOKEN_PREFIX` plus an `API_TOKEN_BODY_LENGTH`-char body
|
|
83
|
+
* @throws Error when `label` is longer than the body or not base64url
|
|
84
|
+
*/
|
|
85
|
+
export const create_test_raw_api_token = (label = 'test') => {
|
|
86
|
+
if (label.length > API_TOKEN_BODY_LENGTH || !/^[A-Za-z0-9_-]*$/.test(label)) {
|
|
87
|
+
throw new Error(`create_test_raw_api_token: label must be at most ${API_TOKEN_BODY_LENGTH} base64url chars, got '${label}'`);
|
|
88
|
+
}
|
|
89
|
+
return API_TOKEN_PREFIX + label.padEnd(API_TOKEN_BODY_LENGTH, 'A');
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Create a test `ValidatedApiToken` — what `query_validate_api_token` returns
|
|
93
|
+
* for a live token — with a `full` scope by default.
|
|
94
|
+
*/
|
|
95
|
+
export const create_test_validated_api_token = (overrides) => ({
|
|
96
|
+
id: 'tok_test',
|
|
97
|
+
account_id: 'acct-test',
|
|
98
|
+
name: 'test token',
|
|
99
|
+
token_hash: 'hash',
|
|
100
|
+
expires_at: null,
|
|
101
|
+
last_used_at: null,
|
|
102
|
+
last_used_ip: null,
|
|
103
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
104
|
+
scope: token_scope_full(),
|
|
105
|
+
expires_in_ms: null,
|
|
106
|
+
...overrides
|
|
107
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAsB7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAMhE,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAkB1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAW,KAAK,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAKpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAsB7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAMhE,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAkB1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAW,KAAK,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAKpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAI1D;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC9C;;;;OAIG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;;;;;;OASG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,kEAAkE;IAClE,YAAY,EAAE,mBAAmB,CAAC;IAClC;;;;OAIG;IACH,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;;;;;;;;OAYG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,mCAAmC,GAC/C,SAAS,8BAA8B,KACrC,IAy+CF,CAAC"}
|
|
@@ -27,6 +27,7 @@ import { LoginOutput, AccountStatusOutput } from '../auth/account_route_schema.j
|
|
|
27
27
|
import { test_if } from './cross_backend/capabilities.js';
|
|
28
28
|
import { assert_iso8601_seconds, assert_iso8601_seconds_nullable } from './cross_backend/wire_shapes.js';
|
|
29
29
|
import { DEFAULT_TEST_PASSWORD } from './test_credentials.js';
|
|
30
|
+
import { create_test_raw_api_token } from './entities.js';
|
|
30
31
|
/**
|
|
31
32
|
* Standard integration test suite for fuz_app auth routes.
|
|
32
33
|
*
|
|
@@ -611,7 +612,8 @@ export const describe_standard_integration_tests = (options) => {
|
|
|
611
612
|
path: rpc_path,
|
|
612
613
|
spec: account_verify_action_spec,
|
|
613
614
|
params: undefined,
|
|
614
|
-
|
|
615
|
+
// well-formed, so the refusal is the lookup's, not the shape precheck's
|
|
616
|
+
headers: { authorization: `Bearer ${create_test_raw_api_token('invalid')}` },
|
|
615
617
|
suppress_default_origin: true
|
|
616
618
|
});
|
|
617
619
|
assert.strictEqual(res.status, 401);
|
|
@@ -12,6 +12,7 @@ import { vi } from 'vitest';
|
|
|
12
12
|
import { Hono } from 'hono';
|
|
13
13
|
import type { z } from 'zod';
|
|
14
14
|
import { type RequestContext } from '../auth/request_context.js';
|
|
15
|
+
import type { TokenScope } from '../auth/token_scope.js';
|
|
15
16
|
/** Mock configuration for bearer auth middleware test setup. */
|
|
16
17
|
export interface BearerAuthTestOptions {
|
|
17
18
|
/** Test description. */
|
|
@@ -45,6 +46,14 @@ export interface BearerAuthTestCase extends BearerAuthTestOptions {
|
|
|
45
46
|
expected_account_id?: string;
|
|
46
47
|
/** If set, assert `AUTH_API_TOKEN_ID_KEY` was set to this value after a successful bearer auth. */
|
|
47
48
|
expected_api_token_id?: string;
|
|
49
|
+
/** If set, assert `TOKEN_SCOPE_KEY` was set to this scope after a successful bearer auth. */
|
|
50
|
+
expected_token_scope?: TokenScope;
|
|
51
|
+
/**
|
|
52
|
+
* If set, assert `CREDENTIAL_DEADLINE_KEY` after a successful bearer auth:
|
|
53
|
+
* `null` for none (an eternal token), or the milliseconds it should lie
|
|
54
|
+
* ahead, within a second.
|
|
55
|
+
*/
|
|
56
|
+
expected_credential_deadline_ms?: number | null;
|
|
48
57
|
/** If true, assert the pre-existing session `ACCOUNT_ID_KEY` and credential type are preserved. */
|
|
49
58
|
assert_context_preserved?: boolean;
|
|
50
59
|
/** Optional callback for custom spy assertions on the mocks bundle. */
|
|
@@ -118,6 +127,7 @@ export interface TestMiddlewareStackApp {
|
|
|
118
127
|
* @returns the app and mock spies (reconfigure via `mockImplementation` for valid-token paths)
|
|
119
128
|
* @mutates module-level `vi.mock` registrations for the four bearer-auth query
|
|
120
129
|
* modules — each call resets the spies before wiring the stack.
|
|
130
|
+
* @throws Error when `allowed_origins` is not a valid allowlist
|
|
121
131
|
*/
|
|
122
132
|
export declare const create_test_middleware_stack_app: (options?: TestMiddlewareStackOptions) => TestMiddlewareStackApp;
|
|
123
133
|
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;GAQG;AAEH,OAAO,EAAE,EAAE,EAA0B,MAAM,QAAQ,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,15 +12,15 @@ import { vi, test, assert, describe } from 'vitest';
|
|
|
12
12
|
import { Hono } from 'hono';
|
|
13
13
|
import { Logger } from '@fuzdev/fuz_util/log.ts';
|
|
14
14
|
import { create_bearer_auth_middleware } from '../auth/bearer_auth.js';
|
|
15
|
-
import { AUTH_MIDDLEWARE_PATH } from '../auth/middleware.js';
|
|
15
|
+
import { AUTH_MIDDLEWARE_PATH, ORIGIN_MIDDLEWARE_PATH } from '../auth/middleware.js';
|
|
16
16
|
import { query_validate_api_token } from '../auth/api_token_queries.js';
|
|
17
17
|
import { query_account_by_id, query_actor_by_id, query_active_actors_by_account } from '../auth/account_queries.js';
|
|
18
18
|
import { query_role_grant_find_active_for_actor } from '../auth/role_grant_queries.js';
|
|
19
19
|
import { create_proxy_middleware } from '../http/proxy.js';
|
|
20
20
|
import { get_client_ip } from '../http/client_ip.js';
|
|
21
|
-
import { verify_request_source, parse_allowed_origins } from '../http/origin.js';
|
|
21
|
+
import { verify_request_source, parse_allowed_origins, format_allowed_origins_error } from '../http/origin.js';
|
|
22
22
|
import { REQUEST_CONTEXT_KEY } from '../auth/request_context.js';
|
|
23
|
-
import { ACCOUNT_ID_KEY, AUTH_API_TOKEN_ID_KEY, CREDENTIAL_TYPE_KEY, TEST_CONTEXT_PRESET_KEY } from '../hono_context.js';
|
|
23
|
+
import { ACCOUNT_ID_KEY, AUTH_API_TOKEN_ID_KEY, CREDENTIAL_DEADLINE_KEY, CREDENTIAL_TYPE_KEY, TEST_CONTEXT_PRESET_KEY, TOKEN_SCOPE_KEY } from '../hono_context.js';
|
|
24
24
|
import { ApiError } from '../http/error_schemas.js';
|
|
25
25
|
// Mock the query modules so test cases can control return values.
|
|
26
26
|
// vi.mock() is hoisted by vitest, so these run before any imports resolve.
|
|
@@ -121,19 +121,25 @@ export const create_bearer_auth_test_app = (tc) => {
|
|
|
121
121
|
app.use(AUTH_MIDDLEWARE_PATH, bearer_middleware);
|
|
122
122
|
// route handler echoes the account-grain identity the middleware writes
|
|
123
123
|
// (bearer auth sets `ACCOUNT_ID_KEY` + `CREDENTIAL_TYPE_KEY` +
|
|
124
|
-
// `AUTH_API_TOKEN_ID_KEY`; it never builds the full request context —
|
|
124
|
+
// `AUTH_API_TOKEN_ID_KEY` + `TOKEN_SCOPE_KEY`; it never builds the full request context —
|
|
125
125
|
// that is the dispatcher's authorization phase). `request_context_set`
|
|
126
126
|
// is only true when a test pre-populates it via `pre_context`.
|
|
127
127
|
app.get('/api/test', (c) => {
|
|
128
128
|
const account_id = c.get(ACCOUNT_ID_KEY);
|
|
129
129
|
const cred = c.get(CREDENTIAL_TYPE_KEY);
|
|
130
130
|
const api_token_id = c.get(AUTH_API_TOKEN_ID_KEY);
|
|
131
|
+
const token_scope = c.get(TOKEN_SCOPE_KEY);
|
|
132
|
+
const credential_deadline = c.get(CREDENTIAL_DEADLINE_KEY) ?? null;
|
|
131
133
|
const ctx = c.get(REQUEST_CONTEXT_KEY);
|
|
132
134
|
return c.json({
|
|
133
135
|
ok: true,
|
|
134
136
|
account_id: account_id ?? null,
|
|
135
137
|
credential_type: cred ?? null,
|
|
136
138
|
api_token_id: api_token_id ?? null,
|
|
139
|
+
token_scope: token_scope ?? null,
|
|
140
|
+
// how far ahead the deadline lies, since the monotonic value itself
|
|
141
|
+
// means nothing outside this process
|
|
142
|
+
credential_deadline_in_ms: credential_deadline === null ? null : credential_deadline - performance.now(),
|
|
137
143
|
request_context_set: ctx != null
|
|
138
144
|
});
|
|
139
145
|
});
|
|
@@ -182,6 +188,20 @@ export const describe_bearer_auth_cases = (suite_name, cases) => {
|
|
|
182
188
|
if (tc.expected_api_token_id !== undefined) {
|
|
183
189
|
assert.strictEqual(body.api_token_id, tc.expected_api_token_id, 'AUTH_API_TOKEN_ID_KEY should match the validated api_token.id');
|
|
184
190
|
}
|
|
191
|
+
if (tc.expected_token_scope !== undefined) {
|
|
192
|
+
assert.deepStrictEqual(body.token_scope, tc.expected_token_scope, 'TOKEN_SCOPE_KEY should be the scope the validated api_token carries');
|
|
193
|
+
}
|
|
194
|
+
if (tc.expected_credential_deadline_ms !== undefined) {
|
|
195
|
+
if (tc.expected_credential_deadline_ms === null) {
|
|
196
|
+
assert.strictEqual(body.credential_deadline_in_ms, null, 'CREDENTIAL_DEADLINE_KEY should be null for a token with no expiry');
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
const ahead = body.credential_deadline_in_ms;
|
|
200
|
+
assert.ok(typeof ahead === 'number' &&
|
|
201
|
+
ahead <= tc.expected_credential_deadline_ms &&
|
|
202
|
+
ahead > tc.expected_credential_deadline_ms - 1000, `CREDENTIAL_DEADLINE_KEY should lie ${tc.expected_credential_deadline_ms}ms ahead, got ${String(ahead)}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
185
205
|
if (tc.assert_context_preserved) {
|
|
186
206
|
assert.ok(body.account_id, 'pre-existing account_id should be preserved');
|
|
187
207
|
assert.strictEqual(body.credential_type, 'session', 'credential type should remain session');
|
|
@@ -205,6 +225,7 @@ export const TEST_MIDDLEWARE_PATH = '/api/test';
|
|
|
205
225
|
* @returns the app and mock spies (reconfigure via `mockImplementation` for valid-token paths)
|
|
206
226
|
* @mutates module-level `vi.mock` registrations for the four bearer-auth query
|
|
207
227
|
* modules — each call resets the spies before wiring the stack.
|
|
228
|
+
* @throws Error when `allowed_origins` is not a valid allowlist
|
|
208
229
|
*/
|
|
209
230
|
export const create_test_middleware_stack_app = (options) => {
|
|
210
231
|
const trusted_proxies = options?.trusted_proxies ?? ['10.0.0.1'];
|
|
@@ -226,12 +247,15 @@ export const create_test_middleware_stack_app = (options) => {
|
|
|
226
247
|
trusted_proxies,
|
|
227
248
|
get_connection_ip: get_connection_ip
|
|
228
249
|
});
|
|
229
|
-
const
|
|
230
|
-
|
|
250
|
+
const parsed_origins = parse_allowed_origins(allowed_origins_str);
|
|
251
|
+
if (!parsed_origins.ok) {
|
|
252
|
+
throw new Error(`create_test_middleware_stack_app: invalid allowed_origins: ${parsed_origins.errors.map(format_allowed_origins_error).join('; ')}`);
|
|
253
|
+
}
|
|
254
|
+
const origin_mw = verify_request_source(parsed_origins.origins);
|
|
231
255
|
const bearer_mw = create_bearer_auth_middleware(STUB_DEPS, new Logger('test', { level: 'off' }));
|
|
232
256
|
const app = new Hono();
|
|
233
257
|
app.use('*', proxy_mw);
|
|
234
|
-
app.use(
|
|
258
|
+
app.use(ORIGIN_MIDDLEWARE_PATH, origin_mw);
|
|
235
259
|
app.use(AUTH_MIDDLEWARE_PATH, bearer_mw);
|
|
236
260
|
// echo route for assertions — exposes the account-grain identity bearer
|
|
237
261
|
// auth writes (`ACCOUNT_ID_KEY`); the full request context is the
|
package/dist/testing/stubs.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import './assert_dev_env.js';
|
|
2
2
|
import type { z } from 'zod';
|
|
3
3
|
import type { SessionOptions } from '../auth/session_cookie.js';
|
|
4
|
-
import type { MiddlewareSpec } from '../http/middleware_spec.js';
|
|
4
|
+
import type { MiddlewareCarveOut, MiddlewareSpec } from '../http/middleware_spec.js';
|
|
5
5
|
import type { AppDeps } from '../auth/deps.js';
|
|
6
6
|
import type { AuditEmitter } from '../auth/audit_emitter.js';
|
|
7
7
|
import type { BootstrapServerOptions } from '../server/app_server.js';
|
|
@@ -111,6 +111,8 @@ export declare const create_stub_app_backend: (options?: CreateStubAppBackendOpt
|
|
|
111
111
|
export declare const create_stub_api_middleware: (options?: {
|
|
112
112
|
/** Include the daemon_token middleware layer. */
|
|
113
113
|
include_daemon_token?: boolean;
|
|
114
|
+
/** The origin check's carve-outs, as `create_auth_middleware_specs` records them. */
|
|
115
|
+
origin_carve_outs?: ReadonlyArray<MiddlewareCarveOut>;
|
|
114
116
|
}) => Array<MiddlewareSpec>;
|
|
115
117
|
/**
|
|
116
118
|
* Create a stub `AppServerContext` for attack surface testing.
|
|
@@ -169,6 +171,14 @@ export interface CreateTestAppSurfaceSpecOptions {
|
|
|
169
171
|
* (`assert_middleware_stack_mounted`).
|
|
170
172
|
*/
|
|
171
173
|
transform_middleware?: (specs: Array<MiddlewareSpec>) => Array<MiddlewareSpec>;
|
|
174
|
+
/**
|
|
175
|
+
* The origin check's carve-outs — `AppServerOptions.origin_carve_outs`.
|
|
176
|
+
* Recorded on the stub origin spec, so the surface leaves the check's `403`
|
|
177
|
+
* off the carved-out routes as the live server's does; refused, like
|
|
178
|
+
* `create_app_server`, when one has no reason or overlaps the auth
|
|
179
|
+
* middleware's scope.
|
|
180
|
+
*/
|
|
181
|
+
origin_carve_outs?: Array<MiddlewareCarveOut>;
|
|
172
182
|
/**
|
|
173
183
|
* Bootstrap config — symmetric with `AppServerOptions.bootstrap`. Discriminated
|
|
174
184
|
* by `mode`: `'disabled'` skips the route (same as omission), `'surface_only'`
|
|
@@ -212,7 +222,9 @@ export interface CreateTestAppSurfaceSpecOptions {
|
|
|
212
222
|
* `GET /api/surface` (with `surface_route: true`), then surface
|
|
213
223
|
* generation — including its
|
|
214
224
|
* refusal of an `rpc_endpoints` or `ws_endpoints` path outside the auth
|
|
215
|
-
* middleware's scope (`assert_endpoint_in_auth_scope`)
|
|
225
|
+
* middleware's scope (`assert_endpoint_in_auth_scope`), of a route that
|
|
226
|
+
* reads or mints a credential outside it
|
|
227
|
+
* (`assert_credential_routes_in_auth_scope`), and of a
|
|
216
228
|
* `transform_middleware` that doesn't keep the proxy and auth stack mounted
|
|
217
229
|
* (`assert_middleware_stack_mounted`). The middleware list mirrors the real
|
|
218
230
|
* one: a stub `trusted_proxy` spec at `'*'`, then the stub auth stack (with
|
|
@@ -222,7 +234,8 @@ export interface CreateTestAppSurfaceSpecOptions {
|
|
|
222
234
|
*
|
|
223
235
|
* @param options - surface spec options
|
|
224
236
|
* @returns the surface spec for the standard suites
|
|
225
|
-
* @throws Error when an endpoint path
|
|
237
|
+
* @throws Error when an endpoint path, or a route that reads or mints a
|
|
238
|
+
* credential, is outside `AUTH_MIDDLEWARE_PATH`, a
|
|
226
239
|
* `ws_endpoints` spec declares no `allowed_origins` and no `allowed_origins`
|
|
227
240
|
* option is given, or `transform_middleware` moves, drops, duplicates,
|
|
228
241
|
* reorders, wraps, or replaces the stub proxy spec or a stub auth spec
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stubs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/stubs.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAa7B,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"stubs.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/stubs.ts"],"names":[],"mappings":"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"}
|
package/dist/testing/stubs.js
CHANGED
|
@@ -19,8 +19,9 @@ import { create_app_surface_spec } from '../http/surface.js';
|
|
|
19
19
|
import { resolve_ws_endpoints } from '../actions/ws_endpoint_spec.js';
|
|
20
20
|
import { AUDIT_LOG_SSE_MAX_PER_SCOPE } from '../realtime/sse_auth_guard.js';
|
|
21
21
|
import { SubscriberRegistry } from '../realtime/subscriber_registry.js';
|
|
22
|
+
import { ROLE_ADMIN } from '../auth/role_schema.js';
|
|
22
23
|
import { BaseServerEnv } from '../server/env.js';
|
|
23
|
-
import { AUTH_MIDDLEWARE_PATH, assert_endpoint_in_auth_scope, assert_middleware_stack_mounted } from '../auth/middleware.js';
|
|
24
|
+
import { AUTH_MIDDLEWARE_PATH, ORIGIN_MIDDLEWARE_PATH, assert_credential_routes_in_auth_scope, assert_endpoint_in_auth_scope, assert_middleware_stack_mounted, assert_origin_carve_outs_valid, freeze_origin_carve_outs } from '../auth/middleware.js';
|
|
24
25
|
/**
|
|
25
26
|
* Create a Proxy that throws descriptive errors on any property access or method call.
|
|
26
27
|
*
|
|
@@ -133,7 +134,8 @@ export const create_stub_audit_sse = () => {
|
|
|
133
134
|
return {
|
|
134
135
|
log: new Logger('test:audit_sse', { level: 'off' }),
|
|
135
136
|
on_audit_event: () => { },
|
|
136
|
-
registry
|
|
137
|
+
registry,
|
|
138
|
+
required_role: ROLE_ADMIN
|
|
137
139
|
};
|
|
138
140
|
};
|
|
139
141
|
/**
|
|
@@ -177,12 +179,15 @@ const create_stub_mw = () => async (_c, next) => next();
|
|
|
177
179
|
* `assert_middleware_stack_mounted` can tell the layers apart by identity.
|
|
178
180
|
*/
|
|
179
181
|
export const create_stub_api_middleware = (options) => {
|
|
182
|
+
const origin_carve_outs = freeze_origin_carve_outs(options?.origin_carve_outs ?? []);
|
|
183
|
+
assert_origin_carve_outs_valid(origin_carve_outs);
|
|
180
184
|
const specs = [
|
|
181
185
|
{
|
|
182
186
|
name: 'origin',
|
|
183
|
-
path:
|
|
187
|
+
path: ORIGIN_MIDDLEWARE_PATH,
|
|
184
188
|
handler: create_stub_mw(),
|
|
185
|
-
errors: { 403: ApiError }
|
|
189
|
+
errors: { 403: ApiError },
|
|
190
|
+
...(origin_carve_outs.length > 0 && { carve_outs: origin_carve_outs })
|
|
186
191
|
},
|
|
187
192
|
{ name: 'session', path: AUTH_MIDDLEWARE_PATH, handler: create_stub_mw() },
|
|
188
193
|
{ name: 'request_context', path: AUTH_MIDDLEWARE_PATH, handler: create_stub_mw() },
|
|
@@ -258,7 +263,9 @@ const to_self_resolved_ws_endpoint = (endpoint) => {
|
|
|
258
263
|
* `GET /api/surface` (with `surface_route: true`), then surface
|
|
259
264
|
* generation — including its
|
|
260
265
|
* refusal of an `rpc_endpoints` or `ws_endpoints` path outside the auth
|
|
261
|
-
* middleware's scope (`assert_endpoint_in_auth_scope`)
|
|
266
|
+
* middleware's scope (`assert_endpoint_in_auth_scope`), of a route that
|
|
267
|
+
* reads or mints a credential outside it
|
|
268
|
+
* (`assert_credential_routes_in_auth_scope`), and of a
|
|
262
269
|
* `transform_middleware` that doesn't keep the proxy and auth stack mounted
|
|
263
270
|
* (`assert_middleware_stack_mounted`). The middleware list mirrors the real
|
|
264
271
|
* one: a stub `trusted_proxy` spec at `'*'`, then the stub auth stack (with
|
|
@@ -268,7 +275,8 @@ const to_self_resolved_ws_endpoint = (endpoint) => {
|
|
|
268
275
|
*
|
|
269
276
|
* @param options - surface spec options
|
|
270
277
|
* @returns the surface spec for the standard suites
|
|
271
|
-
* @throws Error when an endpoint path
|
|
278
|
+
* @throws Error when an endpoint path, or a route that reads or mints a
|
|
279
|
+
* credential, is outside `AUTH_MIDDLEWARE_PATH`, a
|
|
272
280
|
* `ws_endpoints` spec declares no `allowed_origins` and no `allowed_origins`
|
|
273
281
|
* option is given, or `transform_middleware` moves, drops, duplicates,
|
|
274
282
|
* reorders, wraps, or replaces the stub proxy spec or a stub auth spec
|
|
@@ -339,10 +347,15 @@ export const create_test_app_surface_spec = (options) => {
|
|
|
339
347
|
...rpc_route_specs,
|
|
340
348
|
...surface_route_specs
|
|
341
349
|
];
|
|
350
|
+
// refused like `create_app_server` refuses it
|
|
351
|
+
assert_credential_routes_in_auth_scope(route_specs);
|
|
342
352
|
// mirrors `create_app_server`'s `[proxy_spec, ...auth_middleware]`
|
|
343
353
|
const stack_specs = [
|
|
344
354
|
{ name: 'trusted_proxy', path: '*', handler: create_stub_mw() },
|
|
345
|
-
...create_stub_api_middleware({
|
|
355
|
+
...create_stub_api_middleware({
|
|
356
|
+
include_daemon_token: options.daemon_token,
|
|
357
|
+
origin_carve_outs: options.origin_carve_outs
|
|
358
|
+
})
|
|
346
359
|
];
|
|
347
360
|
let middleware_specs = stack_specs;
|
|
348
361
|
if (options.transform_middleware) {
|
|
@@ -17,7 +17,7 @@ import './assert_dev_env.js';
|
|
|
17
17
|
* @module
|
|
18
18
|
*/
|
|
19
19
|
import { assert } from 'vitest';
|
|
20
|
-
import {
|
|
20
|
+
import { middleware_spec_applies } from '../http/schema_helpers.js';
|
|
21
21
|
import { filter_protected_routes, filter_role_routes, filter_keeper_routes, filter_credential_gated_routes, filter_routes_with_input, filter_routes_with_params, filter_routes_with_query, filter_public_routes, format_route_key } from '../http/surface_query.js';
|
|
22
22
|
import { PROTOCOL_ACTION_METHODS } from '../actions/action_codegen.js';
|
|
23
23
|
// --- Structural invariants ---
|
|
@@ -100,7 +100,7 @@ export const assert_middleware_errors_propagated = (surface) => {
|
|
|
100
100
|
const middleware_with_errors = surface.middleware.filter((m) => m.error_schemas !== null);
|
|
101
101
|
for (const route of surface.routes) {
|
|
102
102
|
for (const mw of middleware_with_errors) {
|
|
103
|
-
if (!
|
|
103
|
+
if (!middleware_spec_applies(mw, route.path))
|
|
104
104
|
continue;
|
|
105
105
|
for (const status of Object.keys(mw.error_schemas)) {
|
|
106
106
|
assert.ok(route.error_schemas && status in route.error_schemas, `${format_route_key(route)} missing status ${status} from middleware '${mw.name}'`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuzdev/fuz_app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.141.0",
|
|
4
4
|
"description": "fullstack app library",
|
|
5
5
|
"glyph": "🗝",
|
|
6
6
|
"logo": "logo.svg",
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@electric-sql/pglite": ">=0.4",
|
|
35
35
|
"@fuzdev/blake3-wasm": ">=0.2.0",
|
|
36
|
-
"@fuzdev/fuz_css": ">=0.
|
|
37
|
-
"@fuzdev/fuz_schema": "^0.
|
|
38
|
-
"@fuzdev/fuz_util": ">=0.
|
|
36
|
+
"@fuzdev/fuz_css": ">=0.70.0",
|
|
37
|
+
"@fuzdev/fuz_schema": "^0.5.0",
|
|
38
|
+
"@fuzdev/fuz_util": ">=0.77.0",
|
|
39
39
|
"@fuzdev/pglet-wasm": ">=0.1.1",
|
|
40
40
|
"@hono/bun": ">=1",
|
|
41
41
|
"@hono/deno": ">=1",
|
|
@@ -91,20 +91,20 @@
|
|
|
91
91
|
"devDependencies": {
|
|
92
92
|
"@electric-sql/pglite": "^0.5.8",
|
|
93
93
|
"@fuzdev/blake3-wasm": "^0.2.0",
|
|
94
|
-
"@fuzdev/fuz_code": "^0.
|
|
95
|
-
"@fuzdev/fuz_css": "^0.
|
|
96
|
-
"@fuzdev/fuz_schema": "^0.
|
|
97
|
-
"@fuzdev/fuz_ui": "^0.
|
|
98
|
-
"@fuzdev/fuz_util": "^0.
|
|
99
|
-
"@fuzdev/gro": "^0.
|
|
100
|
-
"@fuzdev/mdz": "^0.
|
|
94
|
+
"@fuzdev/fuz_code": "^0.54.0",
|
|
95
|
+
"@fuzdev/fuz_css": "^0.70.0",
|
|
96
|
+
"@fuzdev/fuz_schema": "^0.5.0",
|
|
97
|
+
"@fuzdev/fuz_ui": "^0.217.0",
|
|
98
|
+
"@fuzdev/fuz_util": "^0.77.0",
|
|
99
|
+
"@fuzdev/gro": "^0.220.0",
|
|
100
|
+
"@fuzdev/mdz": "^0.6.0",
|
|
101
101
|
"@fuzdev/pglet-wasm": "^0.1.1",
|
|
102
102
|
"@hono/bun": "^1.0.1",
|
|
103
103
|
"@hono/deno": "^1.0.3",
|
|
104
104
|
"@hono/node-server": "^1.19.14",
|
|
105
105
|
"@hono/node-ws": "^1.3.1",
|
|
106
106
|
"@node-rs/argon2": "^2.0.2",
|
|
107
|
-
"@ryanatkn/eslint-config": "^0.13.
|
|
107
|
+
"@ryanatkn/eslint-config": "^0.13.1",
|
|
108
108
|
"@sveltejs/acorn-typescript": "^1.0.9",
|
|
109
109
|
"@sveltejs/adapter-static": "^4.0.0",
|
|
110
110
|
"@sveltejs/kit": "^3.0.1",
|