raven-mcp 1.7.0 → 1.8.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.
@@ -0,0 +1,36 @@
1
+ export type ShapeSchema = {
2
+ required?: string[];
3
+ types?: Record<string, "string" | "number" | "boolean" | "object" | "array">;
4
+ };
5
+ export type Query = {
6
+ name: string;
7
+ method?: "GET" | "POST";
8
+ path?: string;
9
+ headers?: Record<string, string>;
10
+ body?: unknown;
11
+ expect?: {
12
+ contains?: string[];
13
+ equals?: Record<string, unknown>;
14
+ };
15
+ };
16
+ export type QueryVerdict = {
17
+ name: string;
18
+ verdict: "shape-valid" | "shape-invalid" | "confident-wrong" | "uncertain";
19
+ reason: string;
20
+ offending?: string;
21
+ status?: number;
22
+ };
23
+ export type ApiContractResult = {
24
+ results: QueryVerdict[];
25
+ shape_valid_count: number;
26
+ confident_wrong_count: number;
27
+ shape_invalid_count: number;
28
+ uncertain_count: number;
29
+ };
30
+ export declare function getPath(obj: unknown, path: string): unknown;
31
+ export declare function validateShape(response: unknown, schema: ShapeSchema): {
32
+ valid: boolean;
33
+ offending?: string;
34
+ reason: string;
35
+ };
36
+ export declare function runApiContract(endpointUrl: string, queries: Query[], schema: ShapeSchema): Promise<ApiContractResult>;
@@ -0,0 +1,235 @@
1
+ export function getPath(obj, path) {
2
+ const segments = path.split(".");
3
+ let current = obj;
4
+ for (let index = 0; index < segments.length; index += 1) {
5
+ const segment = segments[index];
6
+ if (Array.isArray(current)) {
7
+ if (!isArrayIndex(segment)) {
8
+ return undefined;
9
+ }
10
+ const arrayIndex = Number(segment);
11
+ if (arrayIndex >= current.length) {
12
+ return undefined;
13
+ }
14
+ current = current[arrayIndex];
15
+ continue;
16
+ }
17
+ if (!isRecord(current)) {
18
+ return undefined;
19
+ }
20
+ if (!Object.prototype.hasOwnProperty.call(current, segment)) {
21
+ return undefined;
22
+ }
23
+ current = current[segment];
24
+ }
25
+ return current;
26
+ }
27
+ export function validateShape(response, schema) {
28
+ const required = schema.required || [];
29
+ for (let index = 0; index < required.length; index += 1) {
30
+ const path = required[index];
31
+ if (getPath(response, path) === undefined) {
32
+ return {
33
+ valid: false,
34
+ offending: path,
35
+ reason: "missing required path: " + path
36
+ };
37
+ }
38
+ }
39
+ const types = schema.types || {};
40
+ const entries = Object.entries(types);
41
+ for (let index = 0; index < entries.length; index += 1) {
42
+ const path = entries[index][0];
43
+ const expected = entries[index][1];
44
+ const value = getPath(response, path);
45
+ if (value === undefined) {
46
+ continue;
47
+ }
48
+ if (!matchesType(value, expected)) {
49
+ return {
50
+ valid: false,
51
+ offending: path,
52
+ reason: "type mismatch at " + path + ": expected " + expected
53
+ };
54
+ }
55
+ }
56
+ return { valid: true, reason: "all checks passed" };
57
+ }
58
+ export async function runApiContract(endpointUrl, queries, schema) {
59
+ const results = [];
60
+ for (let index = 0; index < queries.length; index += 1) {
61
+ const query = queries[index];
62
+ const controller = new AbortController();
63
+ const timeout = setTimeout(function abortRequest() {
64
+ controller.abort();
65
+ }, 10000);
66
+ let response;
67
+ try {
68
+ response = await fetch(endpointUrl + (query.path || ""), {
69
+ method: query.method || "GET",
70
+ headers: requestHeaders(query),
71
+ body: query.method === "POST" ? JSON.stringify(query.body) : undefined,
72
+ signal: controller.signal
73
+ });
74
+ }
75
+ catch (error) {
76
+ results.push({
77
+ name: query.name,
78
+ verdict: "uncertain",
79
+ reason: errorMessage(error)
80
+ });
81
+ clearTimeout(timeout);
82
+ continue;
83
+ }
84
+ clearTimeout(timeout);
85
+ let parsed;
86
+ try {
87
+ parsed = await response.json();
88
+ }
89
+ catch {
90
+ results.push({
91
+ name: query.name,
92
+ verdict: "uncertain",
93
+ reason: "non-JSON response",
94
+ status: response.status
95
+ });
96
+ continue;
97
+ }
98
+ if (response.status < 200 || response.status >= 300) {
99
+ results.push({
100
+ name: query.name,
101
+ verdict: "uncertain",
102
+ reason: "HTTP " + response.status,
103
+ status: response.status
104
+ });
105
+ continue;
106
+ }
107
+ const shape = validateShape(parsed, schema);
108
+ if (!shape.valid) {
109
+ results.push({
110
+ name: query.name,
111
+ verdict: "shape-invalid",
112
+ reason: shape.reason,
113
+ offending: shape.offending,
114
+ status: response.status
115
+ });
116
+ continue;
117
+ }
118
+ const expected = query.expect;
119
+ const confidentWrong = expected ? checkExpectations(parsed, expected) : null;
120
+ if (confidentWrong) {
121
+ results.push({
122
+ name: query.name,
123
+ verdict: "confident-wrong",
124
+ reason: confidentWrong.reason,
125
+ offending: confidentWrong.offending,
126
+ status: response.status
127
+ });
128
+ continue;
129
+ }
130
+ results.push({
131
+ name: query.name,
132
+ verdict: "shape-valid",
133
+ reason: "all checks passed",
134
+ status: response.status
135
+ });
136
+ }
137
+ return tallyResults(results);
138
+ }
139
+ function isArrayIndex(segment) {
140
+ return /^\d+$/.test(segment);
141
+ }
142
+ function isRecord(value) {
143
+ return typeof value === "object" && value !== null;
144
+ }
145
+ function matchesType(value, expected) {
146
+ if (expected === "array") {
147
+ return Array.isArray(value);
148
+ }
149
+ if (expected === "object") {
150
+ return typeof value === "object" && value !== null && !Array.isArray(value);
151
+ }
152
+ return typeof value === expected;
153
+ }
154
+ function requestHeaders(query) {
155
+ if (!query.headers && query.method !== "POST") {
156
+ return undefined;
157
+ }
158
+ const headers = { ...(query.headers || {}) };
159
+ if (query.method === "POST" && !hasHeader(headers, "content-type")) {
160
+ headers["Content-Type"] = "application/json";
161
+ }
162
+ return headers;
163
+ }
164
+ function hasHeader(headers, name) {
165
+ const names = Object.keys(headers);
166
+ const target = name.toLowerCase();
167
+ for (let index = 0; index < names.length; index += 1) {
168
+ if (names[index].toLowerCase() === target) {
169
+ return true;
170
+ }
171
+ }
172
+ return false;
173
+ }
174
+ function checkExpectations(parsed, expected) {
175
+ const serialized = JSON.stringify(parsed);
176
+ const contains = expected.contains || [];
177
+ for (let index = 0; index < contains.length; index += 1) {
178
+ const expectedString = contains[index];
179
+ if (!serialized.includes(expectedString)) {
180
+ return {
181
+ reason: "expected string not found: " + expectedString,
182
+ offending: expectedString
183
+ };
184
+ }
185
+ }
186
+ const equals = expected.equals || {};
187
+ const entries = Object.entries(equals);
188
+ for (let index = 0; index < entries.length; index += 1) {
189
+ const path = entries[index][0];
190
+ const expectedValue = entries[index][1];
191
+ const actualValue = getPath(parsed, path);
192
+ if (JSON.stringify(actualValue) !== JSON.stringify(expectedValue)) {
193
+ return {
194
+ reason: "value mismatch at " + path,
195
+ offending: path
196
+ };
197
+ }
198
+ }
199
+ return null;
200
+ }
201
+ function tallyResults(results) {
202
+ let shapeValidCount = 0;
203
+ let confidentWrongCount = 0;
204
+ let shapeInvalidCount = 0;
205
+ let uncertainCount = 0;
206
+ for (let index = 0; index < results.length; index += 1) {
207
+ const result = results[index];
208
+ if (result.verdict === "shape-valid") {
209
+ shapeValidCount += 1;
210
+ }
211
+ else if (result.verdict === "confident-wrong") {
212
+ confidentWrongCount += 1;
213
+ }
214
+ else if (result.verdict === "shape-invalid") {
215
+ shapeInvalidCount += 1;
216
+ }
217
+ else if (result.verdict === "uncertain") {
218
+ uncertainCount += 1;
219
+ }
220
+ }
221
+ return {
222
+ results,
223
+ shape_valid_count: shapeValidCount,
224
+ confident_wrong_count: confidentWrongCount,
225
+ shape_invalid_count: shapeInvalidCount,
226
+ uncertain_count: uncertainCount
227
+ };
228
+ }
229
+ function errorMessage(error) {
230
+ if (error instanceof Error) {
231
+ return error.message;
232
+ }
233
+ return String(error);
234
+ }
235
+ //# sourceMappingURL=api-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-contract.js","sourceRoot":"","sources":["../src/api-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export type ContractSpec = {
2
+ mode?: "tokens" | "envelope";
3
+ tokens?: string[];
4
+ fields?: string[];
5
+ schemaVersionPattern?: string;
6
+ };
7
+ export type FileInput = {
8
+ path: string;
9
+ content: string;
10
+ };
11
+ export type LayerReport = {
12
+ path: string;
13
+ present: string[];
14
+ missing: string[];
15
+ ordering_issues: string[];
16
+ schema_version?: string | null;
17
+ };
18
+ export type ContractResult = {
19
+ verdict: "PASS" | "BLOCK";
20
+ mode: string;
21
+ layers: LayerReport[];
22
+ cross_layer: {
23
+ inconsistent_tokens: string[];
24
+ schema_versions?: Record<string, string | null>;
25
+ missing_fields?: Record<string, string[]>;
26
+ };
27
+ block_reasons: string[];
28
+ };
29
+ export declare function auditContract(spec: ContractSpec, files: FileInput[]): ContractResult;
@@ -0,0 +1,310 @@
1
+ export function auditContract(spec, files) {
2
+ const mode = resolveMode(spec);
3
+ if (files.length === 0 || isEmptySpec(spec)) {
4
+ return emptyResult(mode);
5
+ }
6
+ if (mode === "envelope") {
7
+ return auditEnvelopeContract(spec, files);
8
+ }
9
+ return auditTokenContract(spec, files);
10
+ }
11
+ function resolveMode(spec) {
12
+ if (spec.mode) {
13
+ return spec.mode;
14
+ }
15
+ if (spec.tokens && spec.tokens.length > 0) {
16
+ return "tokens";
17
+ }
18
+ if (spec.fields && spec.fields.length > 0) {
19
+ return "envelope";
20
+ }
21
+ if (Array.isArray(spec.tokens)) {
22
+ return "tokens";
23
+ }
24
+ if (Array.isArray(spec.fields)) {
25
+ return "envelope";
26
+ }
27
+ return "tokens";
28
+ }
29
+ function isEmptySpec(spec) {
30
+ return (!spec.mode &&
31
+ !Array.isArray(spec.tokens) &&
32
+ !Array.isArray(spec.fields) &&
33
+ typeof spec.schemaVersionPattern !== "string");
34
+ }
35
+ function emptyResult(mode) {
36
+ return {
37
+ verdict: "PASS",
38
+ mode,
39
+ layers: [],
40
+ cross_layer: {
41
+ inconsistent_tokens: []
42
+ },
43
+ block_reasons: []
44
+ };
45
+ }
46
+ function auditTokenContract(spec, files) {
47
+ const tokens = spec.tokens || [];
48
+ const distinctTokens = uniqueStrings(tokens);
49
+ const layers = [];
50
+ for (let i = 0; i < files.length; i += 1) {
51
+ const file = files[i];
52
+ layers.push(auditTokenLayer(file, tokens, distinctTokens));
53
+ }
54
+ const inconsistentTokens = findInconsistentTokens(distinctTokens, layers);
55
+ const blockReasons = tokenBlockReasons(layers, inconsistentTokens);
56
+ return {
57
+ verdict: blockReasons.length > 0 ? "BLOCK" : "PASS",
58
+ mode: "tokens",
59
+ layers,
60
+ cross_layer: {
61
+ inconsistent_tokens: inconsistentTokens
62
+ },
63
+ block_reasons: blockReasons
64
+ };
65
+ }
66
+ function auditTokenLayer(file, tokens, distinctTokens) {
67
+ const present = [];
68
+ const missing = [];
69
+ for (let i = 0; i < tokens.length; i += 1) {
70
+ const token = tokens[i];
71
+ if (file.content.indexOf(token) !== -1) {
72
+ present.push(token);
73
+ }
74
+ else {
75
+ missing.push(token);
76
+ }
77
+ }
78
+ return {
79
+ path: file.path,
80
+ present,
81
+ missing,
82
+ ordering_issues: findOrderingIssues(file.content, distinctTokens)
83
+ };
84
+ }
85
+ function findOrderingIssues(content, tokens) {
86
+ const issues = [];
87
+ for (let i = 0; i < tokens.length; i += 1) {
88
+ const shorter = tokens[i];
89
+ const shorterIndex = content.indexOf(shorter);
90
+ if (shorterIndex === -1) {
91
+ continue;
92
+ }
93
+ for (let j = 0; j < tokens.length; j += 1) {
94
+ const longer = tokens[j];
95
+ if (shorter === longer || !hasOrderingRisk(shorter, longer)) {
96
+ continue;
97
+ }
98
+ const longerIndex = content.indexOf(longer);
99
+ if (longerIndex !== -1 && shorterIndex < longerIndex) {
100
+ issues.push("token '" +
101
+ shorter +
102
+ "' appears before longer '" +
103
+ longer +
104
+ "' — prefix-ordering risk (match longer tokens first)");
105
+ }
106
+ }
107
+ }
108
+ return issues;
109
+ }
110
+ function hasOrderingRisk(shorter, longer) {
111
+ if (longer.length <= shorter.length) {
112
+ return false;
113
+ }
114
+ if (longer.indexOf(shorter) !== -1) {
115
+ return true;
116
+ }
117
+ const shorterParts = splitTokenPrefix(shorter);
118
+ const longerParts = splitTokenPrefix(longer);
119
+ if (shorterParts.prefix === "" ||
120
+ shorterParts.prefix !== longerParts.prefix ||
121
+ shorterParts.body === "" ||
122
+ shorterParts.body === longerParts.body) {
123
+ return false;
124
+ }
125
+ return longerParts.body.indexOf(shorterParts.body) !== -1;
126
+ }
127
+ function splitTokenPrefix(token) {
128
+ const match = /^[^A-Za-z0-9_]+/.exec(token);
129
+ const prefix = match ? match[0] : "";
130
+ return {
131
+ prefix,
132
+ body: token.slice(prefix.length)
133
+ };
134
+ }
135
+ function findInconsistentTokens(tokens, layers) {
136
+ const inconsistentTokens = [];
137
+ for (let i = 0; i < tokens.length; i += 1) {
138
+ const token = tokens[i];
139
+ let foundPresent = false;
140
+ let foundMissing = false;
141
+ for (let j = 0; j < layers.length; j += 1) {
142
+ const layer = layers[j];
143
+ if (layer.present.indexOf(token) !== -1) {
144
+ foundPresent = true;
145
+ }
146
+ if (layer.missing.indexOf(token) !== -1) {
147
+ foundMissing = true;
148
+ }
149
+ }
150
+ if (foundPresent && foundMissing) {
151
+ inconsistentTokens.push(token);
152
+ }
153
+ }
154
+ return inconsistentTokens;
155
+ }
156
+ function tokenBlockReasons(layers, inconsistentTokens) {
157
+ const blockReasons = [];
158
+ for (let i = 0; i < layers.length; i += 1) {
159
+ const layer = layers[i];
160
+ if (layer.missing.length > 0) {
161
+ blockReasons.push(layer.path + ": missing tokens " + quoteList(layer.missing));
162
+ }
163
+ for (let j = 0; j < layer.ordering_issues.length; j += 1) {
164
+ blockReasons.push(layer.path + ": " + layer.ordering_issues[j]);
165
+ }
166
+ }
167
+ for (let i = 0; i < inconsistentTokens.length; i += 1) {
168
+ const token = inconsistentTokens[i];
169
+ blockReasons.push("token '" +
170
+ token +
171
+ "' inconsistent across layers: present in " +
172
+ formatPaths(pathsWithToken(layers, token, true)) +
173
+ ", missing in " +
174
+ formatPaths(pathsWithToken(layers, token, false)));
175
+ }
176
+ return blockReasons;
177
+ }
178
+ function auditEnvelopeContract(spec, files) {
179
+ const fields = spec.fields || [];
180
+ const hasSchemaVersionPattern = typeof spec.schemaVersionPattern === "string";
181
+ const schemaVersionPattern = typeof spec.schemaVersionPattern === "string"
182
+ ? new RegExp(spec.schemaVersionPattern)
183
+ : null;
184
+ const schemaVersions = {};
185
+ const missingFields = {};
186
+ const layers = [];
187
+ for (let i = 0; i < files.length; i += 1) {
188
+ const file = files[i];
189
+ const layer = {
190
+ path: file.path,
191
+ present: [],
192
+ missing: [],
193
+ ordering_issues: []
194
+ };
195
+ if (schemaVersionPattern) {
196
+ const match = schemaVersionPattern.exec(file.content);
197
+ const schemaVersion = match && typeof match[1] === "string" ? match[1] : null;
198
+ layer.schema_version = schemaVersion;
199
+ schemaVersions[file.path] = schemaVersion;
200
+ }
201
+ const fileMissingFields = missingLiteralFields(fields, file.content);
202
+ if (fileMissingFields.length > 0) {
203
+ missingFields[file.path] = fileMissingFields;
204
+ }
205
+ layers.push(layer);
206
+ }
207
+ const crossLayer = {
208
+ inconsistent_tokens: [],
209
+ missing_fields: missingFields
210
+ };
211
+ if (hasSchemaVersionPattern) {
212
+ crossLayer.schema_versions = schemaVersions;
213
+ }
214
+ const blockReasons = envelopeBlockReasons(spec.schemaVersionPattern, layers, schemaVersions, missingFields);
215
+ return {
216
+ verdict: blockReasons.length > 0 ? "BLOCK" : "PASS",
217
+ mode: "envelope",
218
+ layers,
219
+ cross_layer: crossLayer,
220
+ block_reasons: blockReasons
221
+ };
222
+ }
223
+ function missingLiteralFields(fields, content) {
224
+ const missingFields = [];
225
+ for (let i = 0; i < fields.length; i += 1) {
226
+ const field = fields[i];
227
+ if (content.indexOf(field) === -1) {
228
+ missingFields.push(field);
229
+ }
230
+ }
231
+ return missingFields;
232
+ }
233
+ function envelopeBlockReasons(schemaVersionPattern, layers, schemaVersions, missingFields) {
234
+ const blockReasons = [];
235
+ if (typeof schemaVersionPattern === "string") {
236
+ for (let i = 0; i < layers.length; i += 1) {
237
+ const layer = layers[i];
238
+ if (layer.schema_version === null) {
239
+ blockReasons.push(layer.path + ": missing schema version using pattern '" + schemaVersionPattern + "'");
240
+ }
241
+ }
242
+ const versionGroups = groupSchemaVersionPaths(schemaVersions);
243
+ if (versionGroups.versions.length > 1) {
244
+ blockReasons.push("schema versions differ across layers: " + formatVersionGroups(versionGroups));
245
+ }
246
+ }
247
+ const missingFieldPaths = Object.keys(missingFields);
248
+ for (let i = 0; i < missingFieldPaths.length; i += 1) {
249
+ const path = missingFieldPaths[i];
250
+ blockReasons.push(path + ": missing fields " + quoteList(missingFields[path]));
251
+ }
252
+ return blockReasons;
253
+ }
254
+ function groupSchemaVersionPaths(schemaVersions) {
255
+ const versions = [];
256
+ const pathsByVersion = {};
257
+ const paths = Object.keys(schemaVersions);
258
+ for (let i = 0; i < paths.length; i += 1) {
259
+ const path = paths[i];
260
+ const version = schemaVersions[path];
261
+ if (version === null) {
262
+ continue;
263
+ }
264
+ if (!pathsByVersion[version]) {
265
+ pathsByVersion[version] = [];
266
+ versions.push(version);
267
+ }
268
+ pathsByVersion[version].push(path);
269
+ }
270
+ return { versions, pathsByVersion };
271
+ }
272
+ function pathsWithToken(layers, token, present) {
273
+ const paths = [];
274
+ for (let i = 0; i < layers.length; i += 1) {
275
+ const layer = layers[i];
276
+ const tokenList = present ? layer.present : layer.missing;
277
+ if (tokenList.indexOf(token) !== -1) {
278
+ paths.push(layer.path);
279
+ }
280
+ }
281
+ return paths;
282
+ }
283
+ function uniqueStrings(values) {
284
+ const uniqueValues = [];
285
+ for (let i = 0; i < values.length; i += 1) {
286
+ if (uniqueValues.indexOf(values[i]) === -1) {
287
+ uniqueValues.push(values[i]);
288
+ }
289
+ }
290
+ return uniqueValues;
291
+ }
292
+ function quoteList(values) {
293
+ const quotedValues = [];
294
+ for (let i = 0; i < values.length; i += 1) {
295
+ quotedValues.push("'" + values[i] + "'");
296
+ }
297
+ return quotedValues.join(", ");
298
+ }
299
+ function formatPaths(paths) {
300
+ return "[" + quoteList(paths) + "]";
301
+ }
302
+ function formatVersionGroups(versionGroups) {
303
+ const formattedGroups = [];
304
+ for (let i = 0; i < versionGroups.versions.length; i += 1) {
305
+ const version = versionGroups.versions[i];
306
+ formattedGroups.push("'" + version + "' in " + formatPaths(versionGroups.pathsByVersion[version]));
307
+ }
308
+ return formattedGroups.join(", ");
309
+ }
310
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}