@nifrajs/core 1.12.0 → 2.0.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/README.md +10 -1
- package/dist/assurance.d.ts +11 -2
- package/dist/assurance.d.ts.map +1 -1
- package/dist/assurance.js +20 -0
- package/dist/assurance.js.map +1 -1
- package/dist/effect-ledger.d.ts +9 -0
- package/dist/effect-ledger.d.ts.map +1 -0
- package/dist/effect-ledger.js +8 -0
- package/dist/effect-ledger.js.map +1 -0
- package/dist/idempotency-plugin.d.ts +8 -0
- package/dist/idempotency-plugin.d.ts.map +1 -0
- package/dist/idempotency-plugin.js +8 -0
- package/dist/idempotency-plugin.js.map +1 -0
- package/dist/index.d.ts +6 -34
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -30
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +7 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +56 -0
- package/dist/mcp.js.map +1 -0
- package/dist/node-direct.d.ts +5 -0
- package/dist/node-direct.d.ts.map +1 -0
- package/dist/node-direct.js +27 -0
- package/dist/node-direct.js.map +1 -0
- package/dist/reflection.d.ts +5 -0
- package/dist/reflection.d.ts.map +1 -1
- package/dist/reflection.js +2 -0
- package/dist/reflection.js.map +1 -1
- package/dist/router/pattern.d.ts +42 -0
- package/dist/router/pattern.d.ts.map +1 -0
- package/dist/router/pattern.js +127 -0
- package/dist/router/pattern.js.map +1 -0
- package/dist/router/router.d.ts +2 -1
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/router.js +11 -48
- package/dist/router/router.js.map +1 -1
- package/dist/server/client-ip.d.ts +35 -0
- package/dist/server/client-ip.d.ts.map +1 -0
- package/dist/server/client-ip.js +42 -0
- package/dist/server/client-ip.js.map +1 -0
- package/dist/server/context.d.ts +47 -2
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/contract.d.ts +37 -10
- package/dist/server/contract.d.ts.map +1 -1
- package/dist/server/contract.js +33 -8
- package/dist/server/contract.js.map +1 -1
- package/dist/server/http.d.ts +14 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +45 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/idempotency-lane.d.ts +44 -0
- package/dist/server/idempotency-lane.d.ts.map +1 -0
- package/dist/server/idempotency-lane.js +181 -0
- package/dist/server/idempotency-lane.js.map +1 -0
- package/dist/server/install.d.ts +21 -0
- package/dist/server/install.d.ts.map +1 -0
- package/dist/server/install.js +21 -0
- package/dist/server/install.js.map +1 -0
- package/dist/server/ledger-lane.d.ts +53 -0
- package/dist/server/ledger-lane.d.ts.map +1 -0
- package/dist/server/ledger-lane.js +82 -0
- package/dist/server/ledger-lane.js.map +1 -0
- package/dist/server/mcp-hook.d.ts +28 -0
- package/dist/server/mcp-hook.d.ts.map +1 -0
- package/dist/server/mcp-hook.js +2 -0
- package/dist/server/mcp-hook.js.map +1 -0
- package/dist/server/node-outcome-hook.d.ts +9 -0
- package/dist/server/node-outcome-hook.d.ts.map +1 -0
- package/dist/server/node-outcome-hook.js +2 -0
- package/dist/server/node-outcome-hook.js.map +1 -0
- package/dist/server/node-outcome.d.ts +37 -0
- package/dist/server/node-outcome.d.ts.map +1 -0
- package/dist/server/node-outcome.js +75 -0
- package/dist/server/node-outcome.js.map +1 -0
- package/dist/server/plugin.d.ts +78 -0
- package/dist/server/plugin.d.ts.map +1 -0
- package/dist/server/plugin.js +57 -0
- package/dist/server/plugin.js.map +1 -0
- package/dist/server/query.d.ts +18 -0
- package/dist/server/query.d.ts.map +1 -0
- package/dist/server/query.js +102 -0
- package/dist/server/query.js.map +1 -0
- package/dist/server/registry.d.ts +31 -6
- package/dist/server/registry.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +51 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +184 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/server/respond.d.ts +17 -0
- package/dist/server/respond.d.ts.map +1 -0
- package/dist/server/respond.js +81 -0
- package/dist/server/respond.js.map +1 -0
- package/dist/server/runtime-core.d.ts +36 -0
- package/dist/server/runtime-core.d.ts.map +1 -0
- package/dist/server/runtime-core.js +51 -0
- package/dist/server/runtime-core.js.map +1 -0
- package/dist/server/server-types.d.ts +203 -0
- package/dist/server/server-types.d.ts.map +1 -0
- package/dist/server/server-types.js +2 -0
- package/dist/server/server-types.js.map +1 -0
- package/dist/server/server.d.ts +135 -358
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +476 -1065
- package/dist/server/server.js.map +1 -1
- package/dist/server/sse-hook.d.ts +10 -0
- package/dist/server/sse-hook.d.ts.map +1 -0
- package/dist/server/sse-hook.js +2 -0
- package/dist/server/sse-hook.js.map +1 -0
- package/dist/server/sse.d.ts +7 -23
- package/dist/server/sse.d.ts.map +1 -1
- package/dist/server/sse.js +18 -0
- package/dist/server/sse.js.map +1 -1
- package/dist/server/websocket.d.ts +17 -1
- package/dist/server/websocket.d.ts.map +1 -1
- package/dist/server/websocket.js.map +1 -1
- package/dist/server/ws-hook.d.ts +8 -11
- package/dist/server/ws-hook.d.ts.map +1 -1
- package/dist/server/ws-hook.js +7 -14
- package/dist/server/ws-hook.js.map +1 -1
- package/dist/server.d.ts +21 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +16 -0
- package/dist/server.js.map +1 -0
- package/dist/ws.d.ts +16 -7
- package/dist/ws.d.ts.map +1 -1
- package/dist/ws.js +25 -10
- package/dist/ws.js.map +1 -1
- package/package.json +82 -6
- package/src/assurance.ts +36 -1
- package/src/effect-ledger.ts +9 -0
- package/src/idempotency-plugin.ts +7 -0
- package/src/index.ts +6 -132
- package/src/mcp.ts +65 -0
- package/src/node-direct.ts +37 -0
- package/src/reflection.ts +7 -0
- package/src/router/pattern.ts +176 -0
- package/src/router/router.ts +11 -69
- package/src/server/client-ip.ts +60 -0
- package/src/server/context.ts +50 -2
- package/src/server/contract.ts +68 -25
- package/src/server/http.ts +58 -0
- package/src/server/idempotency-lane.ts +287 -0
- package/src/server/install.ts +28 -0
- package/src/server/ledger-lane.ts +125 -0
- package/src/server/mcp-hook.ts +41 -0
- package/src/server/node-outcome-hook.ts +9 -0
- package/src/server/node-outcome.ts +112 -0
- package/src/server/plugin.ts +92 -0
- package/src/server/query.ts +119 -0
- package/src/server/registry.ts +36 -6
- package/src/server/request-context.ts +271 -0
- package/src/server/respond.ts +93 -0
- package/src/server/runtime-core.ts +74 -0
- package/src/server/server-types.ts +204 -0
- package/src/server/server.ts +863 -1657
- package/src/server/sse-hook.ts +14 -0
- package/src/server/sse.ts +26 -0
- package/src/server/websocket.ts +20 -0
- package/src/server/ws-hook.ts +8 -19
- package/src/server.ts +92 -0
- package/src/ws.ts +33 -10
- package/dist/invariants.d.ts +0 -70
- package/dist/invariants.d.ts.map +0 -1
- package/dist/invariants.js +0 -487
- package/dist/invariants.js.map +0 -1
- package/src/invariants.ts +0 -604
package/dist/invariants.js
DELETED
|
@@ -1,487 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Contract-generated invariant tests: the declared contract *is* the test suite.
|
|
3
|
-
*
|
|
4
|
-
* `runContractInvariants(app)` reads each route's reflected contract (schemas, classification) and
|
|
5
|
-
* verifies, with deterministic seeded fuzzing, the properties the contract already promises:
|
|
6
|
-
*
|
|
7
|
-
* 1. **Classification consistency** (static) — a route whose response fields are tagged more
|
|
8
|
-
* sensitive than its declared route-level classification is understating what it emits.
|
|
9
|
-
* 2. **Valid input never crashes** (dynamic) — schema-generated valid requests must not produce 5xx.
|
|
10
|
-
* 3. **Response conformance** (dynamic) — a 2xx response body must validate against the declared
|
|
11
|
-
* response schema; an undeclared response shape is exactly where sensitive data leaks.
|
|
12
|
-
* 4. **Validation fails closed** (dynamic) — schema-violating bodies must be rejected (4xx), never
|
|
13
|
-
* accepted (2xx) and never crash (5xx).
|
|
14
|
-
*
|
|
15
|
-
* Everything is deterministic: a seeded PRNG (no ambient randomness, no wall clock), so a failing
|
|
16
|
-
* case reproduces from its seed. Routes whose inputs cannot be generated from their JSON Schema are
|
|
17
|
-
* reported in `skipped` — never silently dropped.
|
|
18
|
-
*/
|
|
19
|
-
import { classificationAtLeast, isDataClassification, reflectClassification, } from "./classification.js";
|
|
20
|
-
import { reflectRoutes } from "./reflection.js";
|
|
21
|
-
/**
|
|
22
|
-
* The route-level classification exactly as DECLARED (`schema.classification`). Reflection merges the
|
|
23
|
-
* declared value with field tags into one maximum, which erases the understatement signal — so the
|
|
24
|
-
* consistency check reads the raw descriptor instead.
|
|
25
|
-
*/
|
|
26
|
-
function declaredClassifications(app) {
|
|
27
|
-
const declared = new Map();
|
|
28
|
-
const routes = app.routes?.();
|
|
29
|
-
if (!Array.isArray(routes))
|
|
30
|
-
return declared;
|
|
31
|
-
for (const candidate of routes) {
|
|
32
|
-
const route = recordOf(candidate);
|
|
33
|
-
const schema = recordOf(route?.schema);
|
|
34
|
-
const value = schema?.classification;
|
|
35
|
-
if (typeof route?.method === "string" &&
|
|
36
|
-
typeof route.path === "string" &&
|
|
37
|
-
isDataClassification(value)) {
|
|
38
|
-
declared.set(`${route.method.toUpperCase()}\n${route.path}`, value);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return declared;
|
|
42
|
-
}
|
|
43
|
-
/** Deterministic PRNG (mulberry32). Ambient randomness would make failures unreproducible. */
|
|
44
|
-
export function createSeededRandom(seed) {
|
|
45
|
-
let state = seed >>> 0;
|
|
46
|
-
return () => {
|
|
47
|
-
state = (state + 0x6d2b79f5) >>> 0;
|
|
48
|
-
let t = state;
|
|
49
|
-
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
50
|
-
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
51
|
-
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
const recordOf = (value) => value !== null && typeof value === "object" && !Array.isArray(value)
|
|
55
|
-
? value
|
|
56
|
-
: undefined;
|
|
57
|
-
class UngeneratableSchemaError extends Error {
|
|
58
|
-
}
|
|
59
|
-
const SAFE_TOKEN = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
60
|
-
function randomToken(rng, length) {
|
|
61
|
-
let out = "";
|
|
62
|
-
for (let index = 0; index < length; index++) {
|
|
63
|
-
out += SAFE_TOKEN[Math.floor(rng() * SAFE_TOKEN.length)];
|
|
64
|
-
}
|
|
65
|
-
return out;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Generate one value satisfying a JSON Schema (the introspectable subset nifra schemas emit).
|
|
69
|
-
* Throws {@link UngeneratableSchemaError} for shapes it cannot honor — the route is then skipped
|
|
70
|
-
* (and reported), never fuzzed with garbage that would produce false findings.
|
|
71
|
-
*/
|
|
72
|
-
function generateFromJsonSchema(schema, rng, depth = 0) {
|
|
73
|
-
if (depth > 8)
|
|
74
|
-
throw new UngeneratableSchemaError("schema nesting exceeds the generator depth");
|
|
75
|
-
const node = recordOf(schema);
|
|
76
|
-
if (node === undefined)
|
|
77
|
-
throw new UngeneratableSchemaError("schema node is not an object");
|
|
78
|
-
if (node.const !== undefined)
|
|
79
|
-
return node.const;
|
|
80
|
-
if (Array.isArray(node.enum) && node.enum.length > 0) {
|
|
81
|
-
return node.enum[Math.floor(rng() * node.enum.length)];
|
|
82
|
-
}
|
|
83
|
-
for (const key of ["anyOf", "oneOf"]) {
|
|
84
|
-
const variants = node[key];
|
|
85
|
-
if (Array.isArray(variants) && variants.length > 0) {
|
|
86
|
-
return generateFromJsonSchema(variants[Math.floor(rng() * variants.length)], rng, depth + 1);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const type = Array.isArray(node.type) ? node.type[0] : node.type;
|
|
90
|
-
switch (type) {
|
|
91
|
-
case "string": {
|
|
92
|
-
const minLength = node.minLength === undefined ? 0 : node.minLength;
|
|
93
|
-
const maxLength = node.maxLength === undefined ? Math.max(12, minLength) : node.maxLength;
|
|
94
|
-
if (node.pattern !== undefined || node.format !== undefined) {
|
|
95
|
-
throw new UngeneratableSchemaError("string pattern/format generation is not supported");
|
|
96
|
-
}
|
|
97
|
-
if (!Number.isSafeInteger(minLength) ||
|
|
98
|
-
!Number.isSafeInteger(maxLength) ||
|
|
99
|
-
minLength < 0 ||
|
|
100
|
-
maxLength < minLength ||
|
|
101
|
-
minLength > 4_096) {
|
|
102
|
-
throw new UngeneratableSchemaError("string length bounds cannot be generated safely");
|
|
103
|
-
}
|
|
104
|
-
const upper = Math.min(maxLength, minLength + 12);
|
|
105
|
-
const length = minLength + Math.floor(rng() * (upper - minLength + 1));
|
|
106
|
-
return randomToken(rng, length);
|
|
107
|
-
}
|
|
108
|
-
case "number":
|
|
109
|
-
case "integer": {
|
|
110
|
-
if (node.exclusiveMinimum !== undefined ||
|
|
111
|
-
node.exclusiveMaximum !== undefined ||
|
|
112
|
-
node.multipleOf !== undefined) {
|
|
113
|
-
throw new UngeneratableSchemaError("exclusive/multiple numeric constraints are not supported");
|
|
114
|
-
}
|
|
115
|
-
const minimum = typeof node.minimum === "number" ? node.minimum : 0;
|
|
116
|
-
const maximum = typeof node.maximum === "number" ? node.maximum : minimum + 1000;
|
|
117
|
-
if (!Number.isFinite(minimum) || !Number.isFinite(maximum) || maximum < minimum) {
|
|
118
|
-
throw new UngeneratableSchemaError("numeric bounds cannot be generated");
|
|
119
|
-
}
|
|
120
|
-
if (type === "integer") {
|
|
121
|
-
const lower = Math.ceil(minimum);
|
|
122
|
-
const upper = Math.floor(maximum);
|
|
123
|
-
if (!Number.isSafeInteger(lower) || !Number.isSafeInteger(upper) || upper < lower) {
|
|
124
|
-
throw new UngeneratableSchemaError("integer bounds cannot be generated safely");
|
|
125
|
-
}
|
|
126
|
-
return lower + Math.floor(rng() * (upper - lower + 1));
|
|
127
|
-
}
|
|
128
|
-
return minimum + rng() * (maximum - minimum);
|
|
129
|
-
}
|
|
130
|
-
case "boolean":
|
|
131
|
-
return rng() < 0.5;
|
|
132
|
-
case "null":
|
|
133
|
-
return null;
|
|
134
|
-
case "array": {
|
|
135
|
-
if (node.uniqueItems === true || node.contains !== undefined) {
|
|
136
|
-
throw new UngeneratableSchemaError("array uniqueItems/contains generation is not supported");
|
|
137
|
-
}
|
|
138
|
-
const minItems = node.minItems === undefined ? 0 : node.minItems;
|
|
139
|
-
const maxItems = node.maxItems === undefined ? minItems + 2 : node.maxItems;
|
|
140
|
-
if (!Number.isSafeInteger(minItems) ||
|
|
141
|
-
!Number.isSafeInteger(maxItems) ||
|
|
142
|
-
minItems < 0 ||
|
|
143
|
-
maxItems < minItems ||
|
|
144
|
-
minItems > 256) {
|
|
145
|
-
throw new UngeneratableSchemaError("array bounds cannot be generated safely");
|
|
146
|
-
}
|
|
147
|
-
const count = minItems +
|
|
148
|
-
Math.floor(rng() *
|
|
149
|
-
(Math.min(maxItems, minItems + 2) - minItems + 1));
|
|
150
|
-
if (node.items === undefined) {
|
|
151
|
-
return Array.from({ length: count }, () => null);
|
|
152
|
-
}
|
|
153
|
-
const out = [];
|
|
154
|
-
for (let index = 0; index < count; index++) {
|
|
155
|
-
out.push(generateFromJsonSchema(node.items, rng, depth + 1));
|
|
156
|
-
}
|
|
157
|
-
return out;
|
|
158
|
-
}
|
|
159
|
-
case "object": {
|
|
160
|
-
const properties = recordOf(node.properties) ?? {};
|
|
161
|
-
const requiredValues = Array.isArray(node.required) ? node.required : [];
|
|
162
|
-
if (requiredValues.some((value) => typeof value !== "string" || !(value in properties))) {
|
|
163
|
-
throw new UngeneratableSchemaError("required object property has no schema");
|
|
164
|
-
}
|
|
165
|
-
if (node.minProperties !== undefined ||
|
|
166
|
-
node.maxProperties !== undefined ||
|
|
167
|
-
node.dependentRequired !== undefined ||
|
|
168
|
-
node.dependentSchemas !== undefined) {
|
|
169
|
-
throw new UngeneratableSchemaError("advanced object cardinality/dependency generation is not supported");
|
|
170
|
-
}
|
|
171
|
-
const required = new Set(requiredValues);
|
|
172
|
-
const out = {};
|
|
173
|
-
for (const [name, child] of Object.entries(properties)) {
|
|
174
|
-
// Required properties always; optional ones half the time — both branches get exercised.
|
|
175
|
-
if (required.has(name) || rng() < 0.5) {
|
|
176
|
-
out[name] = generateFromJsonSchema(child, rng, depth + 1);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return out;
|
|
180
|
-
}
|
|
181
|
-
default:
|
|
182
|
-
throw new UngeneratableSchemaError(`unsupported schema type ${JSON.stringify(type)}`);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
/** Mutate a valid object body so it unambiguously violates its schema (remove a required property). */
|
|
186
|
-
function mutateInvalid(schema, valid) {
|
|
187
|
-
const node = recordOf(schema);
|
|
188
|
-
const properties = recordOf(node?.properties);
|
|
189
|
-
const required = Array.isArray(node?.required) ? node.required : [];
|
|
190
|
-
const target = required[0];
|
|
191
|
-
if (node?.type !== "object" ||
|
|
192
|
-
properties === undefined ||
|
|
193
|
-
target === undefined ||
|
|
194
|
-
recordOf(valid) === undefined) {
|
|
195
|
-
return undefined;
|
|
196
|
-
}
|
|
197
|
-
const invalid = { ...valid };
|
|
198
|
-
delete invalid[target];
|
|
199
|
-
return invalid;
|
|
200
|
-
}
|
|
201
|
-
function fillPathParams(pattern, rng) {
|
|
202
|
-
return pattern
|
|
203
|
-
.split("/")
|
|
204
|
-
.map((segment) => {
|
|
205
|
-
if (segment.startsWith(":"))
|
|
206
|
-
return randomToken(rng, 8);
|
|
207
|
-
if (segment.startsWith("*") || segment === "*")
|
|
208
|
-
return randomToken(rng, 8);
|
|
209
|
-
return segment;
|
|
210
|
-
})
|
|
211
|
-
.join("/");
|
|
212
|
-
}
|
|
213
|
-
function querySearchOf(query) {
|
|
214
|
-
const record = recordOf(query);
|
|
215
|
-
if (record === undefined)
|
|
216
|
-
return "";
|
|
217
|
-
const params = new URLSearchParams();
|
|
218
|
-
for (const [key, value] of Object.entries(record)) {
|
|
219
|
-
if (Array.isArray(value)) {
|
|
220
|
-
for (const item of value) {
|
|
221
|
-
if (item !== null && typeof item === "object") {
|
|
222
|
-
throw new UngeneratableSchemaError("nested query values are not serializable");
|
|
223
|
-
}
|
|
224
|
-
params.append(key, String(item));
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
else if (value !== undefined && value !== null && typeof value !== "object") {
|
|
228
|
-
params.set(key, String(value));
|
|
229
|
-
}
|
|
230
|
-
else if (value !== undefined && value !== null) {
|
|
231
|
-
throw new UngeneratableSchemaError("nested query values are not serializable");
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
const text = params.toString();
|
|
235
|
-
return text === "" ? "" : `?${text}`;
|
|
236
|
-
}
|
|
237
|
-
async function validateAgainst(standard, value) {
|
|
238
|
-
const result = standard["~standard"].validate(value);
|
|
239
|
-
const settled = result instanceof Promise ? await result : result;
|
|
240
|
-
return settled.issues;
|
|
241
|
-
}
|
|
242
|
-
const FUZZABLE_METHODS = new Set(["GET", "POST", "PUT", "PATCH", "DELETE"]);
|
|
243
|
-
/** Run the contract-derived invariant suite against a reflectable app. Pure; no ambient state. */
|
|
244
|
-
/**
|
|
245
|
-
* @deprecated Use `runAdversarialContract` from `@nifrajs/testing`. The testing package is the
|
|
246
|
-
* authoritative deep contract laboratory and powers CLI L4; this export remains for compatibility.
|
|
247
|
-
*/
|
|
248
|
-
export async function runContractInvariants(app, options = {}) {
|
|
249
|
-
const seed = options.seed ?? 1;
|
|
250
|
-
if (!Number.isSafeInteger(seed))
|
|
251
|
-
throw new TypeError("invariants: seed must be a safe integer");
|
|
252
|
-
const casesPerRoute = options.casesPerRoute ?? 8;
|
|
253
|
-
const invalidCasesPerRoute = options.invalidCasesPerRoute ?? 4;
|
|
254
|
-
if (!Number.isSafeInteger(casesPerRoute) ||
|
|
255
|
-
!Number.isSafeInteger(invalidCasesPerRoute) ||
|
|
256
|
-
casesPerRoute < 1 ||
|
|
257
|
-
invalidCasesPerRoute < 0) {
|
|
258
|
-
throw new RangeError("invariants: case counts must be safe integers and valid");
|
|
259
|
-
}
|
|
260
|
-
if (options.executor !== undefined && typeof options.executor !== "function") {
|
|
261
|
-
throw new TypeError("invariants: executor must be a function");
|
|
262
|
-
}
|
|
263
|
-
const findings = [];
|
|
264
|
-
const tested = [];
|
|
265
|
-
const skipped = [];
|
|
266
|
-
const declared = declaredClassifications(app);
|
|
267
|
-
for (const route of reflectRoutes(app)) {
|
|
268
|
-
// 1. Static classification consistency — needs no requests at all.
|
|
269
|
-
const declaredMax = declared.get(`${route.method}\n${route.path}`);
|
|
270
|
-
const fieldReflected = reflectClassification(route.schema?.response?.standard);
|
|
271
|
-
if (declaredMax !== undefined &&
|
|
272
|
-
fieldReflected !== undefined &&
|
|
273
|
-
!classificationAtLeast(declaredMax, fieldReflected.max)) {
|
|
274
|
-
findings.push({
|
|
275
|
-
code: "classification-understated",
|
|
276
|
-
method: route.method,
|
|
277
|
-
path: route.path,
|
|
278
|
-
message: `${route.method} ${route.path} declares ${declaredMax} but its response fields are tagged ${fieldReflected.max}`,
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
if (!FUZZABLE_METHODS.has(route.method)) {
|
|
282
|
-
skipped.push({ method: route.method, path: route.path, reason: "method not fuzzable" });
|
|
283
|
-
continue;
|
|
284
|
-
}
|
|
285
|
-
if (options.executor === undefined) {
|
|
286
|
-
skipped.push({
|
|
287
|
-
method: route.method,
|
|
288
|
-
path: route.path,
|
|
289
|
-
reason: "no isolated executor configured",
|
|
290
|
-
});
|
|
291
|
-
continue;
|
|
292
|
-
}
|
|
293
|
-
const body = route.schema?.body;
|
|
294
|
-
const query = route.schema?.query;
|
|
295
|
-
if (body !== undefined && body.jsonSchema === undefined) {
|
|
296
|
-
skipped.push({
|
|
297
|
-
method: route.method,
|
|
298
|
-
path: route.path,
|
|
299
|
-
reason: "body schema exposes no JSON Schema metadata",
|
|
300
|
-
});
|
|
301
|
-
continue;
|
|
302
|
-
}
|
|
303
|
-
if (query !== undefined && query.jsonSchema === undefined) {
|
|
304
|
-
skipped.push({
|
|
305
|
-
method: route.method,
|
|
306
|
-
path: route.path,
|
|
307
|
-
reason: "query schema exposes no JSON Schema metadata",
|
|
308
|
-
});
|
|
309
|
-
continue;
|
|
310
|
-
}
|
|
311
|
-
if (route.schema?.sse !== undefined) {
|
|
312
|
-
skipped.push({ method: route.method, path: route.path, reason: "streaming route" });
|
|
313
|
-
continue;
|
|
314
|
-
}
|
|
315
|
-
const plan = {
|
|
316
|
-
route,
|
|
317
|
-
...(body !== undefined ? { body } : {}),
|
|
318
|
-
...(query !== undefined ? { query } : {}),
|
|
319
|
-
};
|
|
320
|
-
const outcome = await fuzzRoute(options.executor, plan, seed, casesPerRoute, invalidCasesPerRoute, findings);
|
|
321
|
-
if (outcome === "tested")
|
|
322
|
-
tested.push({ method: route.method, path: route.path });
|
|
323
|
-
else
|
|
324
|
-
skipped.push({ method: route.method, path: route.path, reason: outcome });
|
|
325
|
-
}
|
|
326
|
-
return Object.freeze({
|
|
327
|
-
ok: findings.length === 0,
|
|
328
|
-
tested: Object.freeze(tested),
|
|
329
|
-
skipped: Object.freeze(skipped),
|
|
330
|
-
findings: Object.freeze(findings),
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
async function fuzzRoute(execute, plan, baseSeed, casesPerRoute, invalidCasesPerRoute, findings) {
|
|
334
|
-
const { route } = plan;
|
|
335
|
-
for (let caseIndex = 0; caseIndex < casesPerRoute; caseIndex++) {
|
|
336
|
-
const caseSeed = baseSeed * 1000 + caseIndex;
|
|
337
|
-
const rng = createSeededRandom(caseSeed);
|
|
338
|
-
let bodyValue;
|
|
339
|
-
let queryValue;
|
|
340
|
-
try {
|
|
341
|
-
bodyValue =
|
|
342
|
-
plan.body === undefined ? undefined : generateFromJsonSchema(plan.body.jsonSchema, rng);
|
|
343
|
-
queryValue =
|
|
344
|
-
plan.query?.jsonSchema === undefined
|
|
345
|
-
? undefined
|
|
346
|
-
: generateFromJsonSchema(plan.query.jsonSchema, rng);
|
|
347
|
-
// Query values must survive URL serialization; fail honestly instead of silently dropping
|
|
348
|
-
// nested values and calling the resulting request schema-valid.
|
|
349
|
-
querySearchOf(queryValue);
|
|
350
|
-
}
|
|
351
|
-
catch (err) {
|
|
352
|
-
return err instanceof UngeneratableSchemaError ? err.message : String(err);
|
|
353
|
-
}
|
|
354
|
-
const path = `${fillPathParams(route.path, rng)}${querySearchOf(queryValue)}`;
|
|
355
|
-
const request = new Request(`http://invariants.local${path}`, {
|
|
356
|
-
method: route.method,
|
|
357
|
-
...(bodyValue !== undefined
|
|
358
|
-
? {
|
|
359
|
-
headers: { "content-type": "application/json" },
|
|
360
|
-
body: JSON.stringify(bodyValue),
|
|
361
|
-
}
|
|
362
|
-
: {}),
|
|
363
|
-
});
|
|
364
|
-
let response;
|
|
365
|
-
try {
|
|
366
|
-
response = await execute(request);
|
|
367
|
-
if (!(response instanceof Response))
|
|
368
|
-
throw new TypeError("executor returned a non-Response");
|
|
369
|
-
}
|
|
370
|
-
catch {
|
|
371
|
-
findings.push({
|
|
372
|
-
code: "server-error-on-valid-input",
|
|
373
|
-
method: route.method,
|
|
374
|
-
path: route.path,
|
|
375
|
-
seed: caseSeed,
|
|
376
|
-
message: `${route.method} ${route.path} executor threw for a schema-valid input (seed ${caseSeed})`,
|
|
377
|
-
});
|
|
378
|
-
continue;
|
|
379
|
-
}
|
|
380
|
-
// 2. Valid input must never crash.
|
|
381
|
-
if (response.status >= 500) {
|
|
382
|
-
findings.push({
|
|
383
|
-
code: "server-error-on-valid-input",
|
|
384
|
-
method: route.method,
|
|
385
|
-
path: route.path,
|
|
386
|
-
seed: caseSeed,
|
|
387
|
-
message: `${route.method} ${route.path} returned ${response.status} for a schema-valid input (seed ${caseSeed})`,
|
|
388
|
-
});
|
|
389
|
-
continue;
|
|
390
|
-
}
|
|
391
|
-
// 3. A 2xx JSON response must conform to the declared response contract.
|
|
392
|
-
const responseStandard = plan.route.schema?.response?.standard;
|
|
393
|
-
if (responseStandard !== undefined && response.status < 300) {
|
|
394
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
395
|
-
if (!contentType.includes("application/json")) {
|
|
396
|
-
findings.push({
|
|
397
|
-
code: "response-schema-violation",
|
|
398
|
-
method: route.method,
|
|
399
|
-
path: route.path,
|
|
400
|
-
seed: caseSeed,
|
|
401
|
-
message: `${route.method} ${route.path} returned non-JSON content for its declared response schema (seed ${caseSeed})`,
|
|
402
|
-
});
|
|
403
|
-
continue;
|
|
404
|
-
}
|
|
405
|
-
let responseValue;
|
|
406
|
-
try {
|
|
407
|
-
responseValue = await response.clone().json();
|
|
408
|
-
}
|
|
409
|
-
catch {
|
|
410
|
-
findings.push({
|
|
411
|
-
code: "response-schema-violation",
|
|
412
|
-
method: route.method,
|
|
413
|
-
path: route.path,
|
|
414
|
-
seed: caseSeed,
|
|
415
|
-
message: `${route.method} ${route.path} returned malformed JSON for its declared response schema (seed ${caseSeed})`,
|
|
416
|
-
});
|
|
417
|
-
continue;
|
|
418
|
-
}
|
|
419
|
-
const issues = await validateAgainst(responseStandard, responseValue);
|
|
420
|
-
if (issues !== undefined) {
|
|
421
|
-
findings.push({
|
|
422
|
-
code: "response-schema-violation",
|
|
423
|
-
method: route.method,
|
|
424
|
-
path: route.path,
|
|
425
|
-
seed: caseSeed,
|
|
426
|
-
message: `${route.method} ${route.path} response violates its declared schema (seed ${caseSeed}): ${issues[0]?.message ?? "invalid"}`,
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
// 4. Schema-violating bodies must be rejected — 4xx, never accepted, never a crash.
|
|
432
|
-
if (plan.body?.jsonSchema !== undefined) {
|
|
433
|
-
for (let caseIndex = 0; caseIndex < invalidCasesPerRoute; caseIndex++) {
|
|
434
|
-
const caseSeed = baseSeed * 1000 + 500 + caseIndex;
|
|
435
|
-
const rng = createSeededRandom(caseSeed);
|
|
436
|
-
let invalid;
|
|
437
|
-
try {
|
|
438
|
-
invalid = mutateInvalid(plan.body.jsonSchema, generateFromJsonSchema(plan.body.jsonSchema, rng));
|
|
439
|
-
}
|
|
440
|
-
catch {
|
|
441
|
-
invalid = undefined;
|
|
442
|
-
}
|
|
443
|
-
if (invalid === undefined)
|
|
444
|
-
break;
|
|
445
|
-
let response;
|
|
446
|
-
try {
|
|
447
|
-
response = await execute(new Request(`http://invariants.local${fillPathParams(route.path, rng)}`, {
|
|
448
|
-
method: route.method,
|
|
449
|
-
headers: { "content-type": "application/json" },
|
|
450
|
-
body: JSON.stringify(invalid),
|
|
451
|
-
}));
|
|
452
|
-
if (!(response instanceof Response))
|
|
453
|
-
throw new TypeError("executor returned a non-Response");
|
|
454
|
-
}
|
|
455
|
-
catch {
|
|
456
|
-
findings.push({
|
|
457
|
-
code: "server-error-on-invalid-input",
|
|
458
|
-
method: route.method,
|
|
459
|
-
path: route.path,
|
|
460
|
-
seed: caseSeed,
|
|
461
|
-
message: `${route.method} ${route.path} executor threw on a schema-violating body (seed ${caseSeed})`,
|
|
462
|
-
});
|
|
463
|
-
continue;
|
|
464
|
-
}
|
|
465
|
-
if (response.status < 300) {
|
|
466
|
-
findings.push({
|
|
467
|
-
code: "validation-bypass",
|
|
468
|
-
method: route.method,
|
|
469
|
-
path: route.path,
|
|
470
|
-
seed: caseSeed,
|
|
471
|
-
message: `${route.method} ${route.path} accepted a schema-violating body (seed ${caseSeed})`,
|
|
472
|
-
});
|
|
473
|
-
}
|
|
474
|
-
else if (response.status >= 500) {
|
|
475
|
-
findings.push({
|
|
476
|
-
code: "server-error-on-invalid-input",
|
|
477
|
-
method: route.method,
|
|
478
|
-
path: route.path,
|
|
479
|
-
seed: caseSeed,
|
|
480
|
-
message: `${route.method} ${route.path} crashed (${response.status}) on a schema-violating body (seed ${caseSeed})`,
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
return "tested";
|
|
486
|
-
}
|
|
487
|
-
//# sourceMappingURL=invariants.js.map
|
package/dist/invariants.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"invariants.js","sourceRoot":"","sources":["../src/invariants.ts"],"names":[],"mappings":"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"}
|