@fuzdev/fuz_app 0.132.0 → 0.132.1
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/action_dispatcher.js +1 -0
- package/dist/actions/action_event_data.d.ts +2 -2
- package/dist/actions/action_event_types.d.ts +2 -2
- package/dist/actions/action_rpc.js +1 -0
- package/dist/actions/action_spec.d.ts +19 -19
- package/dist/actions/perform_action.js +1 -0
- package/dist/actions/register_action_ws.js +1 -0
- package/dist/auth/account_routes.js +1 -1
- package/dist/auth/audit_log_schema.d.ts +5 -5
- package/dist/auth/cell_action_specs.d.ts +3 -3
- package/dist/auth/credential_type_schema.d.ts +1 -1
- package/dist/cli/daemon.js +1 -0
- package/dist/cli/logger.js +1 -0
- package/dist/env/load.js +1 -0
- package/dist/hono_context.d.ts +1 -1
- package/dist/http/CLAUDE.md +2 -2
- package/dist/http/auth_shape.d.ts +6 -6
- package/dist/http/error_schemas.d.ts +7 -2
- package/dist/http/error_schemas.d.ts.map +1 -1
- package/dist/http/error_schemas.js +5 -1
- package/dist/http/surface.js +1 -0
- package/dist/realtime/sse.js +1 -0
- package/dist/server/app_server.js +1 -0
- package/dist/testing/CLAUDE.md +1 -0
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +2 -1
- package/dist/testing/adversarial_404.d.ts.map +1 -1
- package/dist/testing/adversarial_404.js +5 -3
- package/dist/testing/adversarial_input.d.ts.map +1 -1
- package/dist/testing/adversarial_input.js +9 -3
- package/dist/testing/attack_surface.js +4 -4
- package/dist/testing/cross_backend/action_manifest.d.ts +10 -10
- package/dist/testing/cross_backend/standard.d.ts +6 -0
- package/dist/testing/cross_backend/standard.d.ts.map +1 -1
- package/dist/testing/cross_backend/standard.js +2 -1
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +5 -5
- package/dist/testing/data_exposure.d.ts.map +1 -1
- package/dist/testing/data_exposure.js +11 -8
- package/dist/testing/round_trip.d.ts.map +1 -1
- package/dist/testing/round_trip.js +3 -9
- package/dist/testing/rpc_helpers.js +1 -0
- package/dist/testing/schema_generators.d.ts +12 -0
- package/dist/testing/schema_generators.d.ts.map +1 -1
- package/dist/testing/schema_generators.js +10 -0
- package/dist/testing/transports/ws_client.js +1 -0
- package/package.json +2 -2
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
|
+
import { JsonrpcMessageFromClientToServer, JsonrpcMessageFromServerToClient, JsonrpcNotification, JsonrpcRequest, JsonrpcResponseOrError, JsonrpcErrorResponse } from '../http/jsonrpc.js';
|
|
9
10
|
import { create_jsonrpc_error_response, create_jsonrpc_error_response_from_thrown, to_jsonrpc_message_id, is_jsonrpc_request, is_jsonrpc_notification } from '../http/jsonrpc_helpers.js';
|
|
10
11
|
import { jsonrpc_error_messages } from '../http/jsonrpc_errors.js';
|
|
11
12
|
import { to_input_params } from '../http/schema_helpers.js';
|
|
@@ -28,11 +28,11 @@ export declare const ActionEventData: z.ZodObject<{
|
|
|
28
28
|
execute: "execute";
|
|
29
29
|
}>;
|
|
30
30
|
step: z.ZodEnum<{
|
|
31
|
-
failed: "failed";
|
|
32
|
-
parsed: "parsed";
|
|
33
31
|
initial: "initial";
|
|
32
|
+
parsed: "parsed";
|
|
34
33
|
handling: "handling";
|
|
35
34
|
handled: "handled";
|
|
35
|
+
failed: "failed";
|
|
36
36
|
}>;
|
|
37
37
|
method: z.ZodString;
|
|
38
38
|
executor: z.ZodEnum<{
|
|
@@ -12,11 +12,11 @@ export declare const ActionExecutor: z.ZodEnum<{
|
|
|
12
12
|
}>;
|
|
13
13
|
export type ActionExecutor = z.infer<typeof ActionExecutor>;
|
|
14
14
|
export declare const ActionEventStep: z.ZodEnum<{
|
|
15
|
-
failed: "failed";
|
|
16
|
-
parsed: "parsed";
|
|
17
15
|
initial: "initial";
|
|
16
|
+
parsed: "parsed";
|
|
18
17
|
handling: "handling";
|
|
19
18
|
handled: "handled";
|
|
19
|
+
failed: "failed";
|
|
20
20
|
}>;
|
|
21
21
|
export type ActionEventStep = z.infer<typeof ActionEventStep>;
|
|
22
22
|
export declare const action_event_step_transitions: Record<ActionEventStep, ReadonlyArray<ActionEventStep>>;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { z } from 'zod';
|
|
15
15
|
import { DEV } from 'esm-env';
|
|
16
|
+
import {} from '../http/route_spec.js';
|
|
16
17
|
import { get_client_ip } from '../http/client_ip.js';
|
|
17
18
|
import { get_request_context } from '../auth/request_context.js';
|
|
18
19
|
import { ACCOUNT_ID_KEY, CREDENTIAL_TYPE_KEY, TOKEN_SCOPE_KEY, TEST_CONTEXT_PRESET_KEY } from '../hono_context.js';
|
|
@@ -51,14 +51,14 @@ export declare const ActionSpec: z.ZodObject<{
|
|
|
51
51
|
*/
|
|
52
52
|
auth: z.ZodNullable<z.ZodObject<{
|
|
53
53
|
account: z.ZodEnum<{
|
|
54
|
-
required: "required";
|
|
55
|
-
none: "none";
|
|
56
54
|
optional: "optional";
|
|
55
|
+
none: "none";
|
|
56
|
+
required: "required";
|
|
57
57
|
}>;
|
|
58
58
|
actor: z.ZodEnum<{
|
|
59
|
-
required: "required";
|
|
60
|
-
none: "none";
|
|
61
59
|
optional: "optional";
|
|
60
|
+
none: "none";
|
|
61
|
+
required: "required";
|
|
62
62
|
}>;
|
|
63
63
|
roles: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
64
64
|
credential_types: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
@@ -108,9 +108,9 @@ export declare const ActionSpec: z.ZodObject<{
|
|
|
108
108
|
* dispatchers don't read it.
|
|
109
109
|
*/
|
|
110
110
|
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
111
|
-
both: "both";
|
|
112
111
|
account: "account";
|
|
113
112
|
ip: "ip";
|
|
113
|
+
both: "both";
|
|
114
114
|
}>>;
|
|
115
115
|
}, z.core.$strict>;
|
|
116
116
|
export type ActionSpec = z.infer<typeof ActionSpec>;
|
|
@@ -128,21 +128,21 @@ export declare const RequestResponseActionSpec: z.ZodObject<{
|
|
|
128
128
|
streams: z.ZodOptional<z.ZodString>;
|
|
129
129
|
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
130
130
|
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
131
|
-
both: "both";
|
|
132
131
|
account: "account";
|
|
133
132
|
ip: "ip";
|
|
133
|
+
both: "both";
|
|
134
134
|
}>>;
|
|
135
135
|
kind: z.ZodDefault<z.ZodLiteral<"request_response">>;
|
|
136
136
|
auth: z.ZodObject<{
|
|
137
137
|
account: z.ZodEnum<{
|
|
138
|
-
required: "required";
|
|
139
|
-
none: "none";
|
|
140
138
|
optional: "optional";
|
|
139
|
+
none: "none";
|
|
140
|
+
required: "required";
|
|
141
141
|
}>;
|
|
142
142
|
actor: z.ZodEnum<{
|
|
143
|
-
required: "required";
|
|
144
|
-
none: "none";
|
|
145
143
|
optional: "optional";
|
|
144
|
+
none: "none";
|
|
145
|
+
required: "required";
|
|
146
146
|
}>;
|
|
147
147
|
roles: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
148
148
|
credential_types: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
@@ -163,9 +163,9 @@ export declare const RemoteNotificationActionSpec: z.ZodObject<{
|
|
|
163
163
|
streams: z.ZodOptional<z.ZodString>;
|
|
164
164
|
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
165
165
|
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
166
|
-
both: "both";
|
|
167
166
|
account: "account";
|
|
168
167
|
ip: "ip";
|
|
168
|
+
both: "both";
|
|
169
169
|
}>>;
|
|
170
170
|
kind: z.ZodDefault<z.ZodLiteral<"remote_notification">>;
|
|
171
171
|
auth: z.ZodDefault<z.ZodNull>;
|
|
@@ -193,9 +193,9 @@ export declare const LocalCallActionSpec: z.ZodObject<{
|
|
|
193
193
|
streams: z.ZodOptional<z.ZodString>;
|
|
194
194
|
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
195
195
|
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
196
|
-
both: "both";
|
|
197
196
|
account: "account";
|
|
198
197
|
ip: "ip";
|
|
198
|
+
both: "both";
|
|
199
199
|
}>>;
|
|
200
200
|
kind: z.ZodDefault<z.ZodLiteral<"local_call">>;
|
|
201
201
|
auth: z.ZodDefault<z.ZodNull>;
|
|
@@ -215,21 +215,21 @@ export declare const ActionSpecUnion: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
215
215
|
streams: z.ZodOptional<z.ZodString>;
|
|
216
216
|
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
217
217
|
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
218
|
-
both: "both";
|
|
219
218
|
account: "account";
|
|
220
219
|
ip: "ip";
|
|
220
|
+
both: "both";
|
|
221
221
|
}>>;
|
|
222
222
|
kind: z.ZodDefault<z.ZodLiteral<"request_response">>;
|
|
223
223
|
auth: z.ZodObject<{
|
|
224
224
|
account: z.ZodEnum<{
|
|
225
|
-
required: "required";
|
|
226
|
-
none: "none";
|
|
227
225
|
optional: "optional";
|
|
226
|
+
none: "none";
|
|
227
|
+
required: "required";
|
|
228
228
|
}>;
|
|
229
229
|
actor: z.ZodEnum<{
|
|
230
|
-
required: "required";
|
|
231
|
-
none: "none";
|
|
232
230
|
optional: "optional";
|
|
231
|
+
none: "none";
|
|
232
|
+
required: "required";
|
|
233
233
|
}>;
|
|
234
234
|
roles: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
235
235
|
credential_types: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
@@ -248,9 +248,9 @@ export declare const ActionSpecUnion: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
248
248
|
streams: z.ZodOptional<z.ZodString>;
|
|
249
249
|
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
250
250
|
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
251
|
-
both: "both";
|
|
252
251
|
account: "account";
|
|
253
252
|
ip: "ip";
|
|
253
|
+
both: "both";
|
|
254
254
|
}>>;
|
|
255
255
|
kind: z.ZodDefault<z.ZodLiteral<"remote_notification">>;
|
|
256
256
|
auth: z.ZodDefault<z.ZodNull>;
|
|
@@ -272,9 +272,9 @@ export declare const ActionSpecUnion: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
272
272
|
streams: z.ZodOptional<z.ZodString>;
|
|
273
273
|
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
274
274
|
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
275
|
-
both: "both";
|
|
276
275
|
account: "account";
|
|
277
276
|
ip: "ip";
|
|
277
|
+
both: "both";
|
|
278
278
|
}>>;
|
|
279
279
|
kind: z.ZodDefault<z.ZodLiteral<"local_call">>;
|
|
280
280
|
auth: z.ZodDefault<z.ZodNull>;
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
*/
|
|
57
57
|
import { DEV } from 'esm-env';
|
|
58
58
|
import { apply_authorization_phase, has_any_scoped_role } from '../auth/request_context.js';
|
|
59
|
+
import {} from '../hono_context.js';
|
|
59
60
|
import { to_input_params } from '../http/schema_helpers.js';
|
|
60
61
|
import { dispatch_with_post_commit_rollback } from '../http/pending_effects.js';
|
|
61
62
|
import { JSONRPC_VERSION } from '../http/jsonrpc.js';
|
|
@@ -104,6 +104,7 @@ import { JsonrpcRequest } from '../http/jsonrpc.js';
|
|
|
104
104
|
import { dev_only, jsonrpc_error_messages } from '../http/jsonrpc_errors.js';
|
|
105
105
|
import { create_jsonrpc_error_response, create_jsonrpc_notification, to_jsonrpc_envelope_id, to_jsonrpc_message_id, to_jsonrpc_params, is_jsonrpc_object, is_jsonrpc_request, is_jsonrpc_request_id } from '../http/jsonrpc_helpers.js';
|
|
106
106
|
import { TOKEN_SCOPE_KEY, TEST_CONTEXT_PRESET_KEY } from '../hono_context.js';
|
|
107
|
+
import {} from './action_types.js';
|
|
107
108
|
import { compile_action_registry } from './compile_action_registry.js';
|
|
108
109
|
import { cancel_action_spec, CancelNotificationParams } from './cancel.js';
|
|
109
110
|
import { DEFAULT_WS_MAX_MESSAGE_BYTES, WS_CLOSE_INTERNAL_ERROR, WS_CLOSE_MESSAGE_TOO_BIG, WS_CLOSE_POLICY_VIOLATION, WS_CLOSE_SERVER_HEARTBEAT_TIMEOUT, WS_CLOSE_SESSION_REVOKED, WS_CLOSE_SESSION_REVOKED_REASON, utf8_length, utf8_length_over } from './transports.js';
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* @module
|
|
23
23
|
*/
|
|
24
24
|
import { clear_session_cookie, create_session_and_set_cookie } from './session_middleware.js';
|
|
25
|
-
import { to_session_account } from './account_schema.js';
|
|
25
|
+
import { RoleGrantSummaryJson, to_session_account } from './account_schema.js';
|
|
26
26
|
import { account_status_route_shape, create_account_route_shapes, DEFAULT_MAX_SESSIONS } from './account_route_schema.js';
|
|
27
27
|
import { hash_session_token, query_session_revoke_all_for_account, query_session_revoke_by_hash_unscoped } from './session_queries.js';
|
|
28
28
|
import { query_account_by_username_or_email, query_update_account_password } from './account_queries.js';
|
|
@@ -141,16 +141,16 @@ export declare const audit_metadata_schemas: Readonly<{
|
|
|
141
141
|
concurrent_change: "concurrent_change";
|
|
142
142
|
}>>;
|
|
143
143
|
credential_type: z.ZodOptional<z.ZodEnum<{
|
|
144
|
-
session: "session";
|
|
145
144
|
daemon_token: "daemon_token";
|
|
145
|
+
session: "session";
|
|
146
146
|
api_token: "api_token";
|
|
147
147
|
}>>;
|
|
148
148
|
}, z.core.$loose>>;
|
|
149
149
|
session_revoke: z.ZodObject<{
|
|
150
150
|
session_id: z.core.$ZodBranded<z.ZodString, "SessionId", "out">;
|
|
151
151
|
credential_type: z.ZodOptional<z.ZodEnum<{
|
|
152
|
-
session: "session";
|
|
153
152
|
daemon_token: "daemon_token";
|
|
153
|
+
session: "session";
|
|
154
154
|
api_token: "api_token";
|
|
155
155
|
}>>;
|
|
156
156
|
}, z.core.$loose>;
|
|
@@ -159,8 +159,8 @@ export declare const audit_metadata_schemas: Readonly<{
|
|
|
159
159
|
reason: z.ZodOptional<z.ZodString>;
|
|
160
160
|
attempted_account_id: z.ZodOptional<z.core.$ZodBranded<z.ZodUUID, "Uuid", "out">>;
|
|
161
161
|
credential_type: z.ZodOptional<z.ZodEnum<{
|
|
162
|
-
session: "session";
|
|
163
162
|
daemon_token: "daemon_token";
|
|
163
|
+
session: "session";
|
|
164
164
|
api_token: "api_token";
|
|
165
165
|
}>>;
|
|
166
166
|
}, z.core.$loose>;
|
|
@@ -168,16 +168,16 @@ export declare const audit_metadata_schemas: Readonly<{
|
|
|
168
168
|
token_id: z.ZodString;
|
|
169
169
|
name: z.ZodString;
|
|
170
170
|
credential_type: z.ZodOptional<z.ZodEnum<{
|
|
171
|
-
session: "session";
|
|
172
171
|
daemon_token: "daemon_token";
|
|
172
|
+
session: "session";
|
|
173
173
|
api_token: "api_token";
|
|
174
174
|
}>>;
|
|
175
175
|
}, z.core.$loose>;
|
|
176
176
|
token_revoke: z.ZodObject<{
|
|
177
177
|
token_id: z.ZodString;
|
|
178
178
|
credential_type: z.ZodOptional<z.ZodEnum<{
|
|
179
|
-
session: "session";
|
|
180
179
|
daemon_token: "daemon_token";
|
|
180
|
+
session: "session";
|
|
181
181
|
api_token: "api_token";
|
|
182
182
|
}>>;
|
|
183
183
|
}, z.core.$loose>;
|
|
@@ -385,8 +385,8 @@ export declare const CellListInput: z.ZodDefault<z.ZodObject<{
|
|
|
385
385
|
updated_at: "updated_at";
|
|
386
386
|
}>>;
|
|
387
387
|
order_direction: z.ZodOptional<z.ZodEnum<{
|
|
388
|
-
desc: "desc";
|
|
389
388
|
asc: "asc";
|
|
389
|
+
desc: "desc";
|
|
390
390
|
}>>;
|
|
391
391
|
limit: z.ZodOptional<z.ZodNumber>;
|
|
392
392
|
offset: z.ZodOptional<z.ZodNumber>;
|
|
@@ -737,8 +737,8 @@ export declare const cell_list_action_spec: {
|
|
|
737
737
|
updated_at: "updated_at";
|
|
738
738
|
}>>;
|
|
739
739
|
order_direction: z.ZodOptional<z.ZodEnum<{
|
|
740
|
-
desc: "desc";
|
|
741
740
|
asc: "asc";
|
|
741
|
+
desc: "desc";
|
|
742
742
|
}>>;
|
|
743
743
|
limit: z.ZodOptional<z.ZodNumber>;
|
|
744
744
|
offset: z.ZodOptional<z.ZodNumber>;
|
|
@@ -1090,8 +1090,8 @@ export declare const all_cell_action_specs: readonly [{
|
|
|
1090
1090
|
updated_at: "updated_at";
|
|
1091
1091
|
}>>;
|
|
1092
1092
|
order_direction: z.ZodOptional<z.ZodEnum<{
|
|
1093
|
-
desc: "desc";
|
|
1094
1093
|
asc: "asc";
|
|
1094
|
+
desc: "desc";
|
|
1095
1095
|
}>>;
|
|
1096
1096
|
limit: z.ZodOptional<z.ZodNumber>;
|
|
1097
1097
|
offset: z.ZodOptional<z.ZodNumber>;
|
|
@@ -45,8 +45,8 @@ export declare const CREDENTIAL_TYPE_DAEMON_TOKEN = "daemon_token";
|
|
|
45
45
|
export declare const BUILTIN_CREDENTIAL_TYPES: readonly ["session", "api_token", "daemon_token"];
|
|
46
46
|
/** Zod enum for builtin credential types only. */
|
|
47
47
|
export declare const BuiltinCredentialType: z.ZodEnum<{
|
|
48
|
-
session: "session";
|
|
49
48
|
daemon_token: "daemon_token";
|
|
49
|
+
session: "session";
|
|
50
50
|
api_token: "api_token";
|
|
51
51
|
}>;
|
|
52
52
|
export type BuiltinCredentialType = z.infer<typeof BuiltinCredentialType>;
|
package/dist/cli/daemon.js
CHANGED
package/dist/cli/logger.js
CHANGED
package/dist/env/load.js
CHANGED
package/dist/hono_context.d.ts
CHANGED
|
@@ -24,8 +24,8 @@ import type { RequestContext } from './auth/request_context.js';
|
|
|
24
24
|
export declare const CREDENTIAL_TYPES: readonly ["session", "api_token", "daemon_token"];
|
|
25
25
|
/** Credential type — how a request was authenticated. */
|
|
26
26
|
export declare const CredentialType: z.ZodEnum<{
|
|
27
|
-
session: "session";
|
|
28
27
|
daemon_token: "daemon_token";
|
|
28
|
+
session: "session";
|
|
29
29
|
api_token: "api_token";
|
|
30
30
|
}>;
|
|
31
31
|
export type CredentialType = z.infer<typeof CredentialType>;
|
package/dist/http/CLAUDE.md
CHANGED
|
@@ -151,7 +151,7 @@ WS); see ../../../docs/architecture.md §DEV-only Output Validation.
|
|
|
151
151
|
`http/error_schemas.ts` is the **declarative** error surface:
|
|
152
152
|
|
|
153
153
|
- `ERROR_*` `snake_case` string constants — single source of truth; use `.literal(ERROR_*)` in Zod schemas and inline checks in handlers
|
|
154
|
-
- `ApiError`, `ValidationError`, `PermissionError`, `CredentialTypeRequiredError`, `RateLimitError`, `PayloadTooLargeError`, `ForeignKeyError` — standard shapes
|
|
154
|
+
- `ApiError`, `ValidationError`, `PermissionError`, `CredentialTypeRequiredError`, `RateLimitError`, `PayloadTooLargeError`, `UnsupportedContentTypeError`, `ForeignKeyError` — standard shapes
|
|
155
155
|
- `RouteErrorSchemas = Partial<Record<number, z.ZodType>>`
|
|
156
156
|
- `RateLimitKey = 'ip' | 'account' | 'both'`
|
|
157
157
|
|
|
@@ -173,7 +173,7 @@ merges three layers, later overrides earlier at the same status code:
|
|
|
173
173
|
- `auth.roles?.length` → 403 `PermissionError` (carries `required_roles`)
|
|
174
174
|
- `auth.credential_types?.length` → 403 `CredentialTypeRequiredError` (carries `required_credential_types`; both gates set yields `z.union([PermissionError, CredentialTypeRequiredError])`)
|
|
175
175
|
- `rate_limit` → 429 `RateLimitError`
|
|
176
|
-
- `checks_content_type` (every `POST`) → 415 `
|
|
176
|
+
- `checks_content_type` (every `POST`) → 415 `UnsupportedContentTypeError`
|
|
177
177
|
- `auth.actor !== 'none'` → widens 400 to a union with `ActorRequiredError` / `ActorNotOnAccountError` and adds 500 union of `NoActorsOnAccountError` / `AccountVanishedError`. Mirrors what the dispatcher's authorization phase actually emits on routes whose input declares `acting?: ActingActor` (per registry-time invariant 2) — so DEV-mode error-schema validation doesn't reject the auth phase's body.
|
|
178
178
|
2. **Middleware** — from `MiddlewareSpec.errors` that apply to the route's path (via `middleware_applies`)
|
|
179
179
|
3. **Explicit** — `RouteSpec.errors` — always wins
|
|
@@ -91,9 +91,9 @@ export declare const parse_acting: (value: unknown) => string | undefined;
|
|
|
91
91
|
* without an actor binding).
|
|
92
92
|
*/
|
|
93
93
|
export declare const AuthAxisState: z.ZodEnum<{
|
|
94
|
-
required: "required";
|
|
95
|
-
none: "none";
|
|
96
94
|
optional: "optional";
|
|
95
|
+
none: "none";
|
|
96
|
+
required: "required";
|
|
97
97
|
}>;
|
|
98
98
|
export type AuthAxisState = z.infer<typeof AuthAxisState>;
|
|
99
99
|
/**
|
|
@@ -123,14 +123,14 @@ export type AuthAxisState = z.infer<typeof AuthAxisState>;
|
|
|
123
123
|
*/
|
|
124
124
|
export declare const RouteAuth: z.ZodObject<{
|
|
125
125
|
account: z.ZodEnum<{
|
|
126
|
-
required: "required";
|
|
127
|
-
none: "none";
|
|
128
126
|
optional: "optional";
|
|
127
|
+
none: "none";
|
|
128
|
+
required: "required";
|
|
129
129
|
}>;
|
|
130
130
|
actor: z.ZodEnum<{
|
|
131
|
-
required: "required";
|
|
132
|
-
none: "none";
|
|
133
131
|
optional: "optional";
|
|
132
|
+
none: "none";
|
|
133
|
+
required: "required";
|
|
134
134
|
}>;
|
|
135
135
|
roles: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
136
136
|
credential_types: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
@@ -236,6 +236,11 @@ export declare const PayloadTooLargeError: z.ZodObject<{
|
|
|
236
236
|
error: z.ZodLiteral<"payload_too_large">;
|
|
237
237
|
}, z.core.$loose>;
|
|
238
238
|
export type PayloadTooLargeError = z.infer<typeof PayloadTooLargeError>;
|
|
239
|
+
/** Unsupported content type error — returned when a `POST` route refuses the request's `Content-Type`. */
|
|
240
|
+
export declare const UnsupportedContentTypeError: z.ZodObject<{
|
|
241
|
+
error: z.ZodLiteral<"unsupported_content_type">;
|
|
242
|
+
}, z.core.$loose>;
|
|
243
|
+
export type UnsupportedContentTypeError = z.infer<typeof UnsupportedContentTypeError>;
|
|
239
244
|
/** Foreign key violation error — returned when a delete is blocked by references. */
|
|
240
245
|
export declare const ForeignKeyError: z.ZodObject<{
|
|
241
246
|
error: z.ZodLiteral<"foreign_key_violation">;
|
|
@@ -296,9 +301,9 @@ export type RouteErrorSchemas = Partial<Record<number, z.ZodType>>;
|
|
|
296
301
|
* - `'both'` — both keys.
|
|
297
302
|
*/
|
|
298
303
|
export declare const RateLimitKey: z.ZodEnum<{
|
|
299
|
-
both: "both";
|
|
300
304
|
account: "account";
|
|
301
305
|
ip: "ip";
|
|
306
|
+
both: "both";
|
|
302
307
|
}>;
|
|
303
308
|
export type RateLimitKey = z.infer<typeof RateLimitKey>;
|
|
304
309
|
/**
|
|
@@ -326,7 +331,7 @@ export type RateLimitKey = z.infer<typeof RateLimitKey>;
|
|
|
326
331
|
* of `NoActorsOnAccountError` / `AccountVanishedError`. The dispatcher's
|
|
327
332
|
* authorization phase emits these whenever it tries to resolve an actor.
|
|
328
333
|
* - **rate_limit**: 429 (`RateLimitError` with `retry_after`).
|
|
329
|
-
* - **checks_content_type**: 415 (`
|
|
334
|
+
* - **checks_content_type**: 415 (`UnsupportedContentTypeError`) —
|
|
330
335
|
* every `POST` route (see `is_post_content_type_refused` in
|
|
331
336
|
* `http/simple_request.ts`).
|
|
332
337
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error_schemas.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/error_schemas.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"error_schemas.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/error_schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -239,6 +239,10 @@ export const RateLimitError = z.looseObject({
|
|
|
239
239
|
export const PayloadTooLargeError = z.looseObject({
|
|
240
240
|
error: z.literal(ERROR_PAYLOAD_TOO_LARGE)
|
|
241
241
|
});
|
|
242
|
+
/** Unsupported content type error — returned when a `POST` route refuses the request's `Content-Type`. */
|
|
243
|
+
export const UnsupportedContentTypeError = z.looseObject({
|
|
244
|
+
error: z.literal(ERROR_UNSUPPORTED_CONTENT_TYPE)
|
|
245
|
+
});
|
|
242
246
|
/** Foreign key violation error — returned when a delete is blocked by references. */
|
|
243
247
|
export const ForeignKeyError = z.looseObject({
|
|
244
248
|
error: z.literal(ERROR_FOREIGN_KEY_VIOLATION)
|
|
@@ -327,7 +331,7 @@ export const derive_error_schemas = ({ auth, has_input = false, has_params = fal
|
|
|
327
331
|
errors[429] = RateLimitError;
|
|
328
332
|
}
|
|
329
333
|
if (checks_content_type) {
|
|
330
|
-
errors[415] =
|
|
334
|
+
errors[415] = UnsupportedContentTypeError;
|
|
331
335
|
}
|
|
332
336
|
return errors;
|
|
333
337
|
};
|
package/dist/http/surface.js
CHANGED
package/dist/realtime/sse.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { Hono } from 'hono';
|
|
11
11
|
import { logger } from 'hono/logger';
|
|
12
12
|
import { bodyLimit } from 'hono/body-limit';
|
|
13
|
+
import { z } from 'zod';
|
|
13
14
|
import { session_cookie_options } from '../auth/session_cookie.js';
|
|
14
15
|
import { create_audit_log_sse, create_sse_connection_closer, audit_log_event_specs } from '../realtime/sse_auth_guard.js';
|
|
15
16
|
import { BaseServerEnv } from './env.js';
|
package/dist/testing/CLAUDE.md
CHANGED
|
@@ -383,6 +383,7 @@ Walks Zod schemas to generate valid values for adversarial/round-trip tests.
|
|
|
383
383
|
- `detect_format(field_schema)` — reads `format` / `pattern` from the JSON Schema representation.
|
|
384
384
|
- `generate_valid_value(field, field_schema)` — base-type switch producing a valid sample (UUIDs → nil UUID, strings → `'xxxxxxxxxx'`, numbers → `1`, objects → recurse, enums → first entry, etc.). For branded-string refinements, walks a fallback chain synthesized from the `pattern` string the JSON Schema representation exposes: fixed-length hex (`^[0-9a-f]{N}$` — blake3 / sha256 / md5 digests; `0`.repeat(N)), prefix-lengthed slug (`^<prefix>_[A-Za-z0-9_-]{N}$` — `ApiTokenId`-style ids; `<prefix>_` + `x`.repeat(N)), absolute path prefix, URL prefix. First candidate that `safeParse` accepts is used.
|
|
385
385
|
- `resolve_valid_path(path, params_schema?)` — swaps `:param` for a value the params schema accepts. Prefers `test_<name>` wherever the field schema admits it (the param name keeps failure messages readable); otherwise a UUID param takes the nil UUID and anything else is synthesized from the schema, percent-encoded. A synthesized value containing `/` is refused (it would route elsewhere) and falls back to `test_<name>`.
|
|
386
|
+
- `to_route_content_type(route)` — the `Content-Type` a well-formed request to the route sends: `application/json`, or `application/octet-stream` for a `raw_body` route. Every `POST` route refuses anything else with 415 before its other gates, so every probe in the harnesses (auth, params and query fuzz, 404, data exposure, round trip) sends it, body or not.
|
|
386
387
|
- `generate_valid_body(input_schema) => Record<string, unknown> | undefined` — builds a body satisfying the input schema. Throws with Zod `issues` if the generated body fails validation — surfaces broken generation logic with a descriptive error rather than a confusing 400 downstream.
|
|
387
388
|
|
|
388
389
|
### `integration_helpers.ts` — route lookup + body checks
|
|
@@ -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,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW3E,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAmB1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,0BAA0B,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,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW3E,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAmB1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,0BAA0B,CAAC;AAavE;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD;;;;OAIG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,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,IAm5BF,CAAC"}
|
|
@@ -36,6 +36,7 @@ import { rpc_call_for_spec, require_rpc_endpoint_path, resolve_rpc_endpoints_for
|
|
|
36
36
|
import { role_grant_offer_create_action_spec, role_grant_revoke_action_spec } from '../auth/role_grant_offer_action_specs.js';
|
|
37
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';
|
|
38
38
|
import { account_token_create_action_spec, account_verify_action_spec } from '../auth/account_action_specs.js';
|
|
39
|
+
import { to_route_content_type } from './schema_generators.js';
|
|
39
40
|
/**
|
|
40
41
|
* How long a failure-audit read waits for the pool-routed row to land.
|
|
41
42
|
*/
|
|
@@ -805,7 +806,7 @@ export const describe_standard_admin_integration_tests = (options) => {
|
|
|
805
806
|
for (const route of admin_routes) {
|
|
806
807
|
const res = await fixture.transport(route.path, {
|
|
807
808
|
method: route.method,
|
|
808
|
-
headers: { host: 'localhost' }
|
|
809
|
+
headers: { host: 'localhost', 'content-type': to_route_content_type(route) }
|
|
809
810
|
});
|
|
810
811
|
if (res.status === 401 || res.status === 403) {
|
|
811
812
|
error_collector.record(route_specs, route.method, route.path, res.status);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adversarial_404.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/adversarial_404.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAoB7B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"adversarial_404.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/adversarial_404.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAoB7B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AA6BlE;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,sBAAsB,KAAG,IA+E1E,CAAC"}
|
|
@@ -14,7 +14,7 @@ import { test, assert, describe } from 'vitest';
|
|
|
14
14
|
import { z } from 'zod';
|
|
15
15
|
import { is_null_schema } from '../http/schema_helpers.js';
|
|
16
16
|
import { create_auth_test_apps, create_route_skip_filter, select_auth_app } from './auth_apps.js';
|
|
17
|
-
import { resolve_valid_path, generate_valid_body } from './schema_generators.js';
|
|
17
|
+
import { resolve_valid_path, generate_valid_body, to_route_content_type } from './schema_generators.js';
|
|
18
18
|
/**
|
|
19
19
|
* Extract the error code from a 404 Zod schema for use in the stub handler.
|
|
20
20
|
*
|
|
@@ -98,12 +98,14 @@ export const describe_adversarial_404 = (options) => {
|
|
|
98
98
|
const route = surface.routes.find((r) => `${r.method} ${r.path}` === key);
|
|
99
99
|
const app = select_auth_app(apps, route.auth);
|
|
100
100
|
const url = resolve_valid_path(route.path, spec.params);
|
|
101
|
-
const request_init = {
|
|
101
|
+
const request_init = {
|
|
102
|
+
method: route.method,
|
|
103
|
+
headers: { 'content-type': to_route_content_type(spec) }
|
|
104
|
+
};
|
|
102
105
|
// Send valid body for routes with input
|
|
103
106
|
if (!is_null_schema(spec.input)) {
|
|
104
107
|
const body = generate_valid_body(spec.input);
|
|
105
108
|
if (body !== undefined) {
|
|
106
|
-
request_init.headers = { 'Content-Type': 'application/json' };
|
|
107
109
|
request_init.body = JSON.stringify(body);
|
|
108
110
|
}
|
|
109
111
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adversarial_input.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/adversarial_input.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAiB7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,OAAO,EAEN,0BAA0B,EAC1B,uBAAuB,EAGvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"adversarial_input.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/adversarial_input.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAiB7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,OAAO,EAEN,0BAA0B,EAC1B,uBAAuB,EAGvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAmDlE,UAAU,aAAa;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,EAAE,OAAO,0BAA0B,GAAG,OAAO,uBAAuB,CAAC;CACnF;AAED,UAAU,cAAc;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,UAAU,aAAa;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAID;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,KAAK,CAAC,aAAa,CAsMtF,CAAC;AAIF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GAAI,eAAe,CAAC,CAAC,SAAS,KAAG,KAAK,CAAC,cAAc,CA+B3F,CAAC;AAIF;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAc,CAAC,CAAC,SAAS,KAAG,KAAK,CAAC,aAAa,CA4CxF,CAAC;AAqBF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GAAI,SAAS,sBAAsB,KAAG,IAyN5E,CAAC"}
|
|
@@ -19,7 +19,7 @@ import { is_null_schema } from '../http/schema_helpers.js';
|
|
|
19
19
|
import { filter_routes_with_input, filter_routes_with_params, filter_routes_with_query } from '../http/surface_query.js';
|
|
20
20
|
import { ValidationError, ERROR_INVALID_REQUEST_BODY, ERROR_INVALID_JSON_BODY, ERROR_INVALID_ROUTE_PARAMS, ERROR_INVALID_QUERY_PARAMS } from '../http/error_schemas.js';
|
|
21
21
|
import { create_auth_test_apps, create_route_skip_filter, select_auth_app } from './auth_apps.js';
|
|
22
|
-
import { detect_format, generate_valid_value, resolve_valid_path } from './schema_generators.js';
|
|
22
|
+
import { detect_format, generate_valid_value, resolve_valid_path, to_route_content_type } from './schema_generators.js';
|
|
23
23
|
// --- Payload generation ---
|
|
24
24
|
/** One wrong-type value per base type — one representative is sufficient. */
|
|
25
25
|
const wrong_type_for = (base_type) => {
|
|
@@ -466,7 +466,10 @@ export const describe_adversarial_input = (options) => {
|
|
|
466
466
|
for (const tc of test_cases) {
|
|
467
467
|
test(tc.label, async () => {
|
|
468
468
|
const url = build_fuzz_url(route.path, tc.params);
|
|
469
|
-
const res = await app.request(url, {
|
|
469
|
+
const res = await app.request(url, {
|
|
470
|
+
method: route.method,
|
|
471
|
+
headers: { 'content-type': to_route_content_type(route) }
|
|
472
|
+
});
|
|
470
473
|
assert.strictEqual(res.status, 400, `Expected 400 for ${key} [${tc.label}], got ${res.status}`);
|
|
471
474
|
const body = await res.json();
|
|
472
475
|
assert.strictEqual(body.error, ERROR_INVALID_ROUTE_PARAMS, `Expected ${ERROR_INVALID_ROUTE_PARAMS} for ${key} [${tc.label}], got: ${body.error}`);
|
|
@@ -504,7 +507,10 @@ export const describe_adversarial_input = (options) => {
|
|
|
504
507
|
for (const tc of test_cases) {
|
|
505
508
|
test(tc.label, async () => {
|
|
506
509
|
const url = build_query_url(base_url, tc.query);
|
|
507
|
-
const res = await app.request(url, {
|
|
510
|
+
const res = await app.request(url, {
|
|
511
|
+
method: route.method,
|
|
512
|
+
headers: { 'content-type': to_route_content_type(route) }
|
|
513
|
+
});
|
|
508
514
|
assert.strictEqual(res.status, 400, `Expected 400 for ${key} [${tc.label}], got ${res.status}`);
|
|
509
515
|
const body = await res.json();
|
|
510
516
|
assert.strictEqual(body.error, ERROR_INVALID_QUERY_PARAMS, `Expected ${ERROR_INVALID_QUERY_PARAMS} for ${key} [${tc.label}], got: ${body.error}`);
|
|
@@ -19,7 +19,7 @@ import { assert_surface_invariants, assert_rpc_ws_surface_invariants, assert_sur
|
|
|
19
19
|
import { describe_adversarial_input } from './adversarial_input.js';
|
|
20
20
|
import { describe_adversarial_404 } from './adversarial_404.js';
|
|
21
21
|
import { create_auth_test_apps, create_route_skip_filter, select_auth_app } from './auth_apps.js';
|
|
22
|
-
import { resolve_valid_path } from './schema_generators.js';
|
|
22
|
+
import { resolve_valid_path, to_route_content_type } from './schema_generators.js';
|
|
23
23
|
import { assert_surface_matches_snapshot, assert_surface_deterministic, assert_only_expected_public_routes, assert_full_middleware_stack, assert_error_schema_valid } from './assertions.js';
|
|
24
24
|
import { merge_error_schemas } from '../http/schema_helpers.js';
|
|
25
25
|
import { collect_middleware_errors } from '../http/surface.js';
|
|
@@ -91,11 +91,11 @@ export const describe_adversarial_auth = (options) => {
|
|
|
91
91
|
const spec_lookup = build_route_spec_lookup(route_specs);
|
|
92
92
|
const test_path = (route) => resolve_valid_path(route.path, spec_lookup.get(`${route.method} ${route.path}`)?.params);
|
|
93
93
|
const apps = create_auth_test_apps(route_specs, roles);
|
|
94
|
-
// every
|
|
95
|
-
//
|
|
94
|
+
// every probe carries the content type a real client sends, so the
|
|
95
|
+
// per-route content-type check (415) never answers ahead of the auth gate
|
|
96
96
|
const probe_init = (route) => ({
|
|
97
97
|
method: route.method,
|
|
98
|
-
headers: { 'content-type':
|
|
98
|
+
headers: { 'content-type': to_route_content_type(route) }
|
|
99
99
|
});
|
|
100
100
|
describe('adversarial HTTP auth enforcement', () => {
|
|
101
101
|
describe('unauthenticated → 401', () => {
|
|
@@ -49,15 +49,15 @@ export declare const ActionManifestEntry: z.ZodObject<{
|
|
|
49
49
|
side_effects: z.ZodBoolean;
|
|
50
50
|
/** The `account` auth axis. */
|
|
51
51
|
account: z.ZodEnum<{
|
|
52
|
-
required: "required";
|
|
53
|
-
none: "none";
|
|
54
52
|
optional: "optional";
|
|
53
|
+
none: "none";
|
|
54
|
+
required: "required";
|
|
55
55
|
}>;
|
|
56
56
|
/** The `actor` auth axis. */
|
|
57
57
|
actor: z.ZodEnum<{
|
|
58
|
-
required: "required";
|
|
59
|
-
none: "none";
|
|
60
58
|
optional: "optional";
|
|
59
|
+
none: "none";
|
|
60
|
+
required: "required";
|
|
61
61
|
}>;
|
|
62
62
|
/** Required roles (any-of), sorted; `[]` when the action declares no role gate. */
|
|
63
63
|
roles: z.ZodArray<z.ZodString>;
|
|
@@ -65,9 +65,9 @@ export declare const ActionManifestEntry: z.ZodObject<{
|
|
|
65
65
|
credential_types: z.ZodArray<z.ZodString>;
|
|
66
66
|
/** Per-action rate-limit class, or `null` when the action declares none. */
|
|
67
67
|
rate_limit: z.ZodNullable<z.ZodEnum<{
|
|
68
|
-
both: "both";
|
|
69
68
|
account: "account";
|
|
70
69
|
ip: "ip";
|
|
70
|
+
both: "both";
|
|
71
71
|
}>>;
|
|
72
72
|
}, z.core.$strict>;
|
|
73
73
|
export type ActionManifestEntry = z.infer<typeof ActionManifestEntry>;
|
|
@@ -80,15 +80,15 @@ export declare const ActionManifest: z.ZodObject<{
|
|
|
80
80
|
side_effects: z.ZodBoolean;
|
|
81
81
|
/** The `account` auth axis. */
|
|
82
82
|
account: z.ZodEnum<{
|
|
83
|
-
required: "required";
|
|
84
|
-
none: "none";
|
|
85
83
|
optional: "optional";
|
|
84
|
+
none: "none";
|
|
85
|
+
required: "required";
|
|
86
86
|
}>;
|
|
87
87
|
/** The `actor` auth axis. */
|
|
88
88
|
actor: z.ZodEnum<{
|
|
89
|
-
required: "required";
|
|
90
|
-
none: "none";
|
|
91
89
|
optional: "optional";
|
|
90
|
+
none: "none";
|
|
91
|
+
required: "required";
|
|
92
92
|
}>;
|
|
93
93
|
/** Required roles (any-of), sorted; `[]` when the action declares no role gate. */
|
|
94
94
|
roles: z.ZodArray<z.ZodString>;
|
|
@@ -96,9 +96,9 @@ export declare const ActionManifest: z.ZodObject<{
|
|
|
96
96
|
credential_types: z.ZodArray<z.ZodString>;
|
|
97
97
|
/** Per-action rate-limit class, or `null` when the action declares none. */
|
|
98
98
|
rate_limit: z.ZodNullable<z.ZodEnum<{
|
|
99
|
-
both: "both";
|
|
100
99
|
account: "account";
|
|
101
100
|
ip: "ip";
|
|
101
|
+
both: "both";
|
|
102
102
|
}>>;
|
|
103
103
|
}, z.core.$strict>>;
|
|
104
104
|
}, z.core.$strict>;
|
|
@@ -98,6 +98,12 @@ export interface StandardCrossProcessTestOptions {
|
|
|
98
98
|
* / `info/refs`) which stream git protocol bytes.
|
|
99
99
|
*/
|
|
100
100
|
round_trip_skip_routes?: Array<string>;
|
|
101
|
+
/**
|
|
102
|
+
* Forwarded to `describe_data_exposure_tests` as `skip_routes`
|
|
103
|
+
* (`'METHOD /path'` keys), as the in-process bundle's consumers pass it
|
|
104
|
+
* directly.
|
|
105
|
+
*/
|
|
106
|
+
data_exposure_skip_routes?: Array<string>;
|
|
101
107
|
/**
|
|
102
108
|
* Forwarded to `describe_rpc_round_trip_tests` as `success_fixtures`
|
|
103
109
|
* (method name → async params factory). Drives a populated **success**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standard.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/standard.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM5D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,WAAW,+BAA+B;IAC/C,2CAA2C;IAC3C,UAAU,EAAE,SAAS,CAAC;IACtB;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B;;;;OAIG;IACH,YAAY,EAAE,mBAAmB,CAAC;IAClC,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;OAKG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvC;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC/F;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,GAAG,CAC1B,MAAM,EACN,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CACnF,CAAC;CACF;AAED;;;;GAIG;AACH,eAAO,MAAM,qCAAqC,GACjD,SAAS,+BAA+B,KACtC,
|
|
1
|
+
{"version":3,"file":"standard.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/standard.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM5D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,WAAW,+BAA+B;IAC/C,2CAA2C;IAC3C,UAAU,EAAE,SAAS,CAAC;IACtB;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B;;;;OAIG;IACH,YAAY,EAAE,mBAAmB,CAAC;IAClC,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;OAKG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvC;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1C;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC/F;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,GAAG,CAC1B,MAAM,EACN,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CACnF,CAAC;CACF;AAED;;;;GAIG;AACH,eAAO,MAAM,qCAAqC,GACjD,SAAS,+BAA+B,KACtC,IAqCF,CAAC"}
|
|
@@ -33,7 +33,8 @@ export const describe_standard_cross_process_tests = (options) => {
|
|
|
33
33
|
});
|
|
34
34
|
describe_data_exposure_tests({
|
|
35
35
|
setup_test: options.setup_test,
|
|
36
|
-
surface_source: options.surface_source
|
|
36
|
+
surface_source: options.surface_source,
|
|
37
|
+
skip_routes: options.data_exposure_skip_routes
|
|
37
38
|
});
|
|
38
39
|
if (options.roles) {
|
|
39
40
|
describe_standard_admin_integration_tests({
|
|
@@ -427,21 +427,21 @@ export declare const testing_action_manifest_action_spec: {
|
|
|
427
427
|
method: z.ZodString;
|
|
428
428
|
side_effects: z.ZodBoolean;
|
|
429
429
|
account: z.ZodEnum<{
|
|
430
|
-
required: "required";
|
|
431
|
-
none: "none";
|
|
432
430
|
optional: "optional";
|
|
431
|
+
none: "none";
|
|
432
|
+
required: "required";
|
|
433
433
|
}>;
|
|
434
434
|
actor: z.ZodEnum<{
|
|
435
|
-
required: "required";
|
|
436
|
-
none: "none";
|
|
437
435
|
optional: "optional";
|
|
436
|
+
none: "none";
|
|
437
|
+
required: "required";
|
|
438
438
|
}>;
|
|
439
439
|
roles: z.ZodArray<z.ZodString>;
|
|
440
440
|
credential_types: z.ZodArray<z.ZodString>;
|
|
441
441
|
rate_limit: z.ZodNullable<z.ZodEnum<{
|
|
442
|
-
both: "both";
|
|
443
442
|
account: "account";
|
|
444
443
|
ip: "ip";
|
|
444
|
+
both: "both";
|
|
445
445
|
}>>;
|
|
446
446
|
}, z.core.$strict>>;
|
|
447
447
|
}, z.core.$strict>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data_exposure.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/data_exposure.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAqB7B,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"data_exposure.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/data_exposure.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAqB7B,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAgBrE,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,0BAA0B,CAAC;AAIvE;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,GAAI,QAAQ,OAAO,KAAG,GAAG,CAAC,MAAM,CAuB9E,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,UAAU,EACnB,mBAAkB,aAAa,CAAC,MAAM,CAA6B,KACjE,IAWF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,wCAAwC,GACpD,SAAS,UAAU,EACnB,oBAAmB,aAAa,CAAC,MAAM,CAA8B,KACnE,IAgBF,CAAC;AAIF,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACvC,kEAAkE;IAClE,UAAU,EAAE,SAAS,CAAC;IACtB;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,2FAA2F;IAC3F,gBAAgB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,iGAAiG;IACjG,iBAAiB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,kDAAkD;IAClD,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,GAAI,SAAS,uBAAuB,KAAG,IA4L/E,CAAC"}
|
|
@@ -17,7 +17,7 @@ import './assert_dev_env.js';
|
|
|
17
17
|
*/
|
|
18
18
|
import { describe, test, beforeAll, assert } from 'vitest';
|
|
19
19
|
import { ROLE_ADMIN } from '../auth/role_schema.js';
|
|
20
|
-
import { resolve_valid_path, generate_valid_body } from './schema_generators.js';
|
|
20
|
+
import { resolve_valid_path, generate_valid_body, to_route_content_type } from './schema_generators.js';
|
|
21
21
|
import { is_null_schema, is_strict_object_schema } from '../http/schema_helpers.js';
|
|
22
22
|
import { is_keeper_auth, is_public_auth } from '../http/auth_shape.js';
|
|
23
23
|
import { sensitive_field_blocklist, admin_only_field_blocklist, assert_no_sensitive_fields_in_json, pick_auth_headers } from './integration_helpers.js';
|
|
@@ -142,7 +142,11 @@ export const describe_data_exposure_tests = (options) => {
|
|
|
142
142
|
const url = resolve_valid_path(spec.path, spec.params);
|
|
143
143
|
const res = await fixture.transport(url, {
|
|
144
144
|
method: spec.method,
|
|
145
|
-
headers: {
|
|
145
|
+
headers: {
|
|
146
|
+
host: 'localhost',
|
|
147
|
+
origin: 'http://localhost:5173',
|
|
148
|
+
'content-type': to_route_content_type(spec)
|
|
149
|
+
}
|
|
146
150
|
});
|
|
147
151
|
if (res.headers.get('Content-Type')?.includes('text/event-stream')) {
|
|
148
152
|
await res.body?.cancel();
|
|
@@ -167,10 +171,12 @@ export const describe_data_exposure_tests = (options) => {
|
|
|
167
171
|
if (skip_set.has(route_key))
|
|
168
172
|
continue;
|
|
169
173
|
const url = resolve_valid_path(spec.path, spec.params);
|
|
170
|
-
const headers = authed_account.create_session_headers();
|
|
171
174
|
const res = await fixture.transport(url, {
|
|
172
175
|
method: spec.method,
|
|
173
|
-
headers
|
|
176
|
+
headers: {
|
|
177
|
+
...authed_account.create_session_headers(),
|
|
178
|
+
'content-type': to_route_content_type(spec)
|
|
179
|
+
}
|
|
174
180
|
});
|
|
175
181
|
assert.strictEqual(res.status, 403, `${route_key} should return 403 for non-admin user`);
|
|
176
182
|
let error_body;
|
|
@@ -207,10 +213,7 @@ export const describe_data_exposure_tests = (options) => {
|
|
|
207
213
|
const headers = pick_auth_headers(spec, fixture, authed_account, admin_account);
|
|
208
214
|
const request_init = {
|
|
209
215
|
method: spec.method,
|
|
210
|
-
headers: {
|
|
211
|
-
...headers,
|
|
212
|
-
...(body ? { 'content-type': 'application/json' } : {})
|
|
213
|
-
},
|
|
216
|
+
headers: { ...headers, 'content-type': to_route_content_type(spec) },
|
|
214
217
|
...(body ? { body: JSON.stringify(body) } : {})
|
|
215
218
|
};
|
|
216
219
|
const res = await fixture.transport(url, request_init);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA+B7B,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,oDAAoD;AACpD,MAAM,WAAW,oBAAoB;IACpC;;;;;OAKG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,kDAAkD;IAClD,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5B,+EAA+E;IAC/E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD;;;;;;;;;;;;;OAaG;IACH,gBAAgB,CAAC,EAAE,GAAG,CACrB,MAAM,EACN,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CACnF,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,8BAA8B,GAAI,SAAS,oBAAoB,KAAG,IAmI9E,CAAC"}
|
|
@@ -20,7 +20,7 @@ import { describe, test, beforeAll, assert } from 'vitest';
|
|
|
20
20
|
import { ROLE_ADMIN } from '../auth/role_schema.js';
|
|
21
21
|
import { is_public_auth, needs_actor, input_schema_declares_acting } from '../http/auth_shape.js';
|
|
22
22
|
import { assert_response_matches_spec, pick_auth_headers } from './integration_helpers.js';
|
|
23
|
-
import { resolve_valid_path, generate_valid_body } from './schema_generators.js';
|
|
23
|
+
import { resolve_valid_path, generate_valid_body, to_route_content_type } from './schema_generators.js';
|
|
24
24
|
/**
|
|
25
25
|
* Run schema-driven round-trip validation tests.
|
|
26
26
|
*
|
|
@@ -98,10 +98,7 @@ export const describe_round_trip_validation = (options) => {
|
|
|
98
98
|
}
|
|
99
99
|
const request_init = {
|
|
100
100
|
method: spec.method,
|
|
101
|
-
headers: {
|
|
102
|
-
...headers,
|
|
103
|
-
...(body ? { 'content-type': 'application/json' } : {})
|
|
104
|
-
},
|
|
101
|
+
headers: { ...headers, 'content-type': to_route_content_type(spec) },
|
|
105
102
|
...(body ? { body: JSON.stringify(body) } : {})
|
|
106
103
|
};
|
|
107
104
|
const res = await fixture.transport(request_url, request_init);
|
|
@@ -132,10 +129,7 @@ export const describe_round_trip_validation = (options) => {
|
|
|
132
129
|
const headers = pick_auth_headers(spec, fixture, authed_account, admin_account);
|
|
133
130
|
const res = await fixture.transport(url, {
|
|
134
131
|
method: spec.method,
|
|
135
|
-
headers: {
|
|
136
|
-
...headers,
|
|
137
|
-
...(body ? { 'content-type': 'application/json' } : {})
|
|
138
|
-
},
|
|
132
|
+
headers: { ...headers, 'content-type': to_route_content_type(spec) },
|
|
139
133
|
...(body ? { body: JSON.stringify(body) } : {})
|
|
140
134
|
});
|
|
141
135
|
try {
|
|
@@ -9,6 +9,7 @@ import './assert_dev_env.js';
|
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
11
|
import { assert } from 'vitest';
|
|
12
|
+
import { z } from 'zod';
|
|
12
13
|
import { JSONRPC_VERSION, JsonrpcErrorResponse, JsonrpcResponse } from '../http/jsonrpc.js';
|
|
13
14
|
import { create_stub_app_server_context } from './stubs.js';
|
|
14
15
|
/**
|
|
@@ -17,6 +17,18 @@ import { type ZodFieldInfo } from '@fuzdev/fuz_util/zod.ts';
|
|
|
17
17
|
export declare const detect_format: (field_schema: z.ZodType) => string | null;
|
|
18
18
|
/** Generate a valid-ish value for a field based on its base type. */
|
|
19
19
|
export declare const generate_valid_value: (field: ZodFieldInfo, field_schema: z.ZodType) => unknown;
|
|
20
|
+
/**
|
|
21
|
+
* The `Content-Type` a well-formed request to a route sends: `application/json`,
|
|
22
|
+
* or `application/octet-stream` for a `raw_body` route. Every `POST` route
|
|
23
|
+
* refuses anything else with 415 before its other gates run (see
|
|
24
|
+
* `http/simple_request.ts`), so a probe of those gates must send it, body or
|
|
25
|
+
* not. Other methods don't check it, so sending it there is harmless.
|
|
26
|
+
*
|
|
27
|
+
* @param route - the route spec or surface route (reads `raw_body`)
|
|
28
|
+
*/
|
|
29
|
+
export declare const to_route_content_type: (route: {
|
|
30
|
+
raw_body?: boolean;
|
|
31
|
+
}) => string;
|
|
20
32
|
/**
|
|
21
33
|
* Resolve a route path with valid-ish param values so params validation passes.
|
|
22
34
|
* Used when testing input on routes that also have params.
|
|
@@ -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,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,yBAAyB,CAAC;AAIjC;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,MAAM,GAAG,IAkBhE,CAAC;AAmHF,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,GAAI,OAAO,YAAY,EAAE,cAAc,CAAC,CAAC,OAAO,KAAG,OAgGnF,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,gBAAgB,CAAC,CAAC,SAAS,KAAG,MAiB9E,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,GAC/B,cAAc,CAAC,CAAC,OAAO,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SA+B5B,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,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,yBAAyB,CAAC;AAIjC;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,MAAM,GAAG,IAkBhE,CAAC;AAmHF,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,GAAI,OAAO,YAAY,EAAE,cAAc,CAAC,CAAC,OAAO,KAAG,OAgGnF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,KAAG,MACL,CAAC;AAElE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,gBAAgB,CAAC,CAAC,SAAS,KAAG,MAiB9E,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,GAC/B,cAAc,CAAC,CAAC,OAAO,KACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SA+B5B,CAAC"}
|
|
@@ -264,6 +264,16 @@ export const generate_valid_value = (field, field_schema) => {
|
|
|
264
264
|
return 'test_value';
|
|
265
265
|
}
|
|
266
266
|
};
|
|
267
|
+
/**
|
|
268
|
+
* The `Content-Type` a well-formed request to a route sends: `application/json`,
|
|
269
|
+
* or `application/octet-stream` for a `raw_body` route. Every `POST` route
|
|
270
|
+
* refuses anything else with 415 before its other gates run (see
|
|
271
|
+
* `http/simple_request.ts`), so a probe of those gates must send it, body or
|
|
272
|
+
* not. Other methods don't check it, so sending it there is harmless.
|
|
273
|
+
*
|
|
274
|
+
* @param route - the route spec or surface route (reads `raw_body`)
|
|
275
|
+
*/
|
|
276
|
+
export const to_route_content_type = (route) => route.raw_body ? 'application/octet-stream' : 'application/json';
|
|
267
277
|
/**
|
|
268
278
|
* Resolve a route path with valid-ish param values so params validation passes.
|
|
269
279
|
* Used when testing input on routes that also have params.
|
|
@@ -19,6 +19,7 @@ import '../assert_dev_env.js';
|
|
|
19
19
|
* @module
|
|
20
20
|
*/
|
|
21
21
|
import { create_jsonrpc_error_response, create_jsonrpc_response, is_jsonrpc_error_response, is_jsonrpc_notification, is_jsonrpc_request, is_jsonrpc_response } from '../../http/jsonrpc_helpers.js';
|
|
22
|
+
import { JSONRPC_VERSION } from '../../http/jsonrpc.js';
|
|
22
23
|
// ---------------------------------------------------------------------
|
|
23
24
|
// Predicates — compose with `WsClient.wait_for` and
|
|
24
25
|
// `messages.filter(...)`. Both in-process and cross-process tests use
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuzdev/fuz_app",
|
|
3
|
-
"version": "0.132.
|
|
3
|
+
"version": "0.132.1",
|
|
4
4
|
"description": "fullstack app library",
|
|
5
5
|
"glyph": "🗝",
|
|
6
6
|
"logo": "logo.svg",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"@fuzdev/fuz_css": "^0.66.1",
|
|
91
91
|
"@fuzdev/fuz_ui": "^0.213.0",
|
|
92
92
|
"@fuzdev/fuz_util": "^0.72.0",
|
|
93
|
-
"@fuzdev/gro": "^0.
|
|
93
|
+
"@fuzdev/gro": "^0.216.0",
|
|
94
94
|
"@fuzdev/mdz": "^0.4.0",
|
|
95
95
|
"@hono/bun": "^1.0.1",
|
|
96
96
|
"@hono/deno": "^1.0.3",
|