@jterrazz/test 8.0.0 → 9.1.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 +209 -230
- package/dist/checker.d.ts +1 -0
- package/dist/checker.js +741 -0
- package/dist/index.d.ts +1249 -728
- package/dist/index.js +3133 -1538
- package/dist/intercept.js +129 -299
- package/dist/match.js +153 -0
- package/dist/oxlint.cjs +2931 -0
- package/dist/oxlint.d.cts +150 -0
- package/dist/oxlint.d.ts +150 -0
- package/dist/oxlint.js +2925 -0
- package/package.json +47 -41
- package/dist/chunk.cjs +0 -28
- package/dist/index.cjs +0 -2264
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -980
- package/dist/index.js.map +0 -1
- package/dist/intercept.cjs +0 -323
- package/dist/intercept.cjs.map +0 -1
- package/dist/intercept.d.cts +0 -115
- package/dist/intercept.d.ts +0 -115
- package/dist/intercept.js.map +0 -1
- package/dist/intercept2.cjs +0 -81
- package/dist/intercept2.cjs.map +0 -1
- package/dist/intercept2.js +0 -81
- package/dist/intercept2.js.map +0 -1
- package/dist/mock-of.cjs +0 -32
- package/dist/mock-of.cjs.map +0 -1
- package/dist/mock-of.d.cts +0 -27
- package/dist/mock-of.d.ts +0 -27
- package/dist/mock-of.js +0 -19
- package/dist/mock-of.js.map +0 -1
- package/dist/mock.cjs +0 -4
- package/dist/mock.d.cts +0 -2
- package/dist/mock.d.ts +0 -2
- package/dist/mock.js +0 -2
- package/dist/services.cjs +0 -5
- package/dist/services.d.cts +0 -2
- package/dist/services.d.ts +0 -2
- package/dist/services.js +0 -2
- package/dist/sqlite.cjs +0 -350
- package/dist/sqlite.cjs.map +0 -1
- package/dist/sqlite.d.cts +0 -209
- package/dist/sqlite.d.ts +0 -209
- package/dist/sqlite.js +0 -331
- package/dist/sqlite.js.map +0 -1
- package/dist/types.d.cts +0 -42
- package/dist/types.d.ts +0 -42
package/dist/intercept.cjs
DELETED
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
//#region src/spec/intercept/adapters/anthropic.ts
|
|
3
|
-
const ANTHROPIC_MESSAGES_URL = "https://api.anthropic.com/v1/messages";
|
|
4
|
-
function matchesFilter(body, filter) {
|
|
5
|
-
if (filter.model) {
|
|
6
|
-
const model = body?.model;
|
|
7
|
-
if (typeof filter.model === "string" && model !== filter.model) return false;
|
|
8
|
-
if (filter.model instanceof RegExp && !filter.model.test(model ?? "")) return false;
|
|
9
|
-
}
|
|
10
|
-
if (filter.system) {
|
|
11
|
-
const system = typeof body?.system === "string" ? body.system : "";
|
|
12
|
-
if (typeof filter.system === "string" && !system.includes(filter.system)) return false;
|
|
13
|
-
if (filter.system instanceof RegExp && !filter.system.test(system)) return false;
|
|
14
|
-
}
|
|
15
|
-
if (filter.user) {
|
|
16
|
-
const userMsg = body?.messages?.find((m) => m.role === "user")?.content ?? "";
|
|
17
|
-
const text = typeof userMsg === "string" ? userMsg : JSON.stringify(userMsg);
|
|
18
|
-
if (typeof filter.user === "string" && !text.includes(filter.user)) return false;
|
|
19
|
-
if (filter.user instanceof RegExp && !filter.user.test(text)) return false;
|
|
20
|
-
}
|
|
21
|
-
if (filter.tools) {
|
|
22
|
-
const names = body?.tools?.map((t) => t.name).filter(Boolean) ?? [];
|
|
23
|
-
if (!filter.tools.every((t) => names.includes(t))) return false;
|
|
24
|
-
}
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
function buildReply(data) {
|
|
28
|
-
return {
|
|
29
|
-
status: 200,
|
|
30
|
-
body: {
|
|
31
|
-
id: "msg-test",
|
|
32
|
-
type: "message",
|
|
33
|
-
role: "assistant",
|
|
34
|
-
content: [{
|
|
35
|
-
type: "text",
|
|
36
|
-
text: typeof data === "string" ? data : JSON.stringify(data)
|
|
37
|
-
}],
|
|
38
|
-
model: "claude-sonnet-4-20250514",
|
|
39
|
-
stop_reason: "end_turn",
|
|
40
|
-
usage: {
|
|
41
|
-
input_tokens: 10,
|
|
42
|
-
output_tokens: 10
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Anthropic API intercept helpers.
|
|
49
|
-
*/
|
|
50
|
-
const anthropic = {
|
|
51
|
-
request(filter) {
|
|
52
|
-
return {
|
|
53
|
-
adapter: "anthropic",
|
|
54
|
-
method: "POST",
|
|
55
|
-
url: ANTHROPIC_MESSAGES_URL,
|
|
56
|
-
match: filter ? (body) => matchesFilter(body, filter) : void 0,
|
|
57
|
-
wrap: buildReply
|
|
58
|
-
};
|
|
59
|
-
},
|
|
60
|
-
message(filter, url) {
|
|
61
|
-
return {
|
|
62
|
-
adapter: "anthropic",
|
|
63
|
-
method: "POST",
|
|
64
|
-
url: url ?? ANTHROPIC_MESSAGES_URL,
|
|
65
|
-
match: filter ? (body) => matchesFilter(body, filter) : void 0,
|
|
66
|
-
wrap(data) {
|
|
67
|
-
if (data && typeof data === "object" && !Array.isArray(data)) return {
|
|
68
|
-
status: 200,
|
|
69
|
-
body: data
|
|
70
|
-
};
|
|
71
|
-
return buildReply(data);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
},
|
|
75
|
-
reply: buildReply,
|
|
76
|
-
error(status, message) {
|
|
77
|
-
return {
|
|
78
|
-
status,
|
|
79
|
-
body: {
|
|
80
|
-
type: "error",
|
|
81
|
-
error: {
|
|
82
|
-
type: status === 429 ? "rate_limit_error" : "api_error",
|
|
83
|
-
message: message ?? `Anthropic error (${status})`
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
},
|
|
88
|
-
timeout() {
|
|
89
|
-
return {
|
|
90
|
-
status: 200,
|
|
91
|
-
body: {},
|
|
92
|
-
delay: 3e4
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* Alias for {@link anthropic} — matches consumers that call the vendor "claude".
|
|
98
|
-
* Re-exposed as a spread copy so downstream tooling (Knip, dts rollup) sees a
|
|
99
|
-
* distinct export and not a duplicate of `anthropic`.
|
|
100
|
-
*/
|
|
101
|
-
const claude = { ...anthropic };
|
|
102
|
-
//#endregion
|
|
103
|
-
//#region src/spec/intercept/adapters/http.ts
|
|
104
|
-
function wrapJson(data) {
|
|
105
|
-
return {
|
|
106
|
-
status: 200,
|
|
107
|
-
body: data
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Generic HTTP intercept helpers for any URL.
|
|
112
|
-
*
|
|
113
|
-
* @example
|
|
114
|
-
* .intercept(http.get('https://api.example.com/data'), 'http/response.json')
|
|
115
|
-
*/
|
|
116
|
-
const http = {
|
|
117
|
-
get(url) {
|
|
118
|
-
return {
|
|
119
|
-
adapter: "http",
|
|
120
|
-
method: "GET",
|
|
121
|
-
url,
|
|
122
|
-
wrap: wrapJson
|
|
123
|
-
};
|
|
124
|
-
},
|
|
125
|
-
post(url) {
|
|
126
|
-
return {
|
|
127
|
-
adapter: "http",
|
|
128
|
-
method: "POST",
|
|
129
|
-
url,
|
|
130
|
-
wrap: wrapJson
|
|
131
|
-
};
|
|
132
|
-
},
|
|
133
|
-
put(url) {
|
|
134
|
-
return {
|
|
135
|
-
adapter: "http",
|
|
136
|
-
method: "PUT",
|
|
137
|
-
url,
|
|
138
|
-
wrap: wrapJson
|
|
139
|
-
};
|
|
140
|
-
},
|
|
141
|
-
delete(url) {
|
|
142
|
-
return {
|
|
143
|
-
adapter: "http",
|
|
144
|
-
method: "DELETE",
|
|
145
|
-
url,
|
|
146
|
-
wrap: wrapJson
|
|
147
|
-
};
|
|
148
|
-
},
|
|
149
|
-
any(url) {
|
|
150
|
-
return {
|
|
151
|
-
adapter: "http",
|
|
152
|
-
method: "*",
|
|
153
|
-
url,
|
|
154
|
-
wrap: wrapJson
|
|
155
|
-
};
|
|
156
|
-
},
|
|
157
|
-
json(data, status = 200) {
|
|
158
|
-
return {
|
|
159
|
-
status,
|
|
160
|
-
body: data
|
|
161
|
-
};
|
|
162
|
-
},
|
|
163
|
-
error(status, message) {
|
|
164
|
-
return {
|
|
165
|
-
status,
|
|
166
|
-
body: { error: message ?? `HTTP ${status}` }
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
//#endregion
|
|
171
|
-
//#region src/spec/intercept/adapters/openai.ts
|
|
172
|
-
const OPENAI_CHAT_URL = "https://api.openai.com/v1/chat/completions";
|
|
173
|
-
const OPENAI_RESPONSES_URL = "https://api.openai.com/v1/responses";
|
|
174
|
-
function matchesChatFilter(body, filter) {
|
|
175
|
-
if (filter.model) {
|
|
176
|
-
const model = body?.model;
|
|
177
|
-
if (typeof filter.model === "string" && model !== filter.model) return false;
|
|
178
|
-
if (filter.model instanceof RegExp && !filter.model.test(model ?? "")) return false;
|
|
179
|
-
}
|
|
180
|
-
if (filter.system) {
|
|
181
|
-
const msg = body?.messages?.find((m) => m.role === "system")?.content ?? "";
|
|
182
|
-
if (typeof filter.system === "string" && !msg.includes(filter.system)) return false;
|
|
183
|
-
if (filter.system instanceof RegExp && !filter.system.test(msg)) return false;
|
|
184
|
-
}
|
|
185
|
-
if (filter.user) {
|
|
186
|
-
const msg = body?.messages?.find((m) => m.role === "user")?.content ?? "";
|
|
187
|
-
if (typeof filter.user === "string" && !msg.includes(filter.user)) return false;
|
|
188
|
-
if (filter.user instanceof RegExp && !filter.user.test(msg)) return false;
|
|
189
|
-
}
|
|
190
|
-
if (filter.tools) {
|
|
191
|
-
const names = body?.tools?.map((t) => t.function?.name).filter(Boolean) ?? [];
|
|
192
|
-
if (!filter.tools.every((t) => names.includes(t))) return false;
|
|
193
|
-
}
|
|
194
|
-
if (filter.temperature !== void 0 && body?.temperature !== filter.temperature) return false;
|
|
195
|
-
return true;
|
|
196
|
-
}
|
|
197
|
-
function matchesResponsesFilter(body, filter) {
|
|
198
|
-
if (filter.model) {
|
|
199
|
-
const model = body?.model;
|
|
200
|
-
if (typeof filter.model === "string" && model !== filter.model) return false;
|
|
201
|
-
if (filter.model instanceof RegExp && !filter.model.test(model ?? "")) return false;
|
|
202
|
-
}
|
|
203
|
-
if (filter.system) {
|
|
204
|
-
const instructions = body?.instructions ?? "";
|
|
205
|
-
const systemInput = body?.input?.find?.((m) => m.role === "system")?.content ?? "";
|
|
206
|
-
const text = instructions || systemInput;
|
|
207
|
-
if (typeof filter.system === "string" && !text.includes(filter.system)) return false;
|
|
208
|
-
if (filter.system instanceof RegExp && !filter.system.test(text)) return false;
|
|
209
|
-
}
|
|
210
|
-
if (filter.user) {
|
|
211
|
-
const msgs = (body?.input ?? []).filter((m) => m.role === "user").map((m) => typeof m.content === "string" ? m.content : JSON.stringify(m.content)).join(" ");
|
|
212
|
-
if (typeof filter.user === "string" && !msgs.includes(filter.user)) return false;
|
|
213
|
-
if (filter.user instanceof RegExp && !filter.user.test(msgs)) return false;
|
|
214
|
-
}
|
|
215
|
-
if (filter.tools) {
|
|
216
|
-
const names = body?.tools?.map((t) => t.name ?? t.function?.name).filter(Boolean) ?? [];
|
|
217
|
-
if (!filter.tools.every((t) => names.includes(t))) return false;
|
|
218
|
-
}
|
|
219
|
-
return true;
|
|
220
|
-
}
|
|
221
|
-
function buildChatReply(data) {
|
|
222
|
-
const content = typeof data === "string" ? data : JSON.stringify(data);
|
|
223
|
-
return {
|
|
224
|
-
status: 200,
|
|
225
|
-
body: {
|
|
226
|
-
id: "chatcmpl-test",
|
|
227
|
-
object: "chat.completion",
|
|
228
|
-
created: Math.floor(Date.now() / 1e3),
|
|
229
|
-
model: "gpt-4o-test",
|
|
230
|
-
choices: [{
|
|
231
|
-
index: 0,
|
|
232
|
-
message: {
|
|
233
|
-
role: "assistant",
|
|
234
|
-
content
|
|
235
|
-
},
|
|
236
|
-
finish_reason: "stop"
|
|
237
|
-
}],
|
|
238
|
-
usage: {
|
|
239
|
-
prompt_tokens: 10,
|
|
240
|
-
completion_tokens: 10,
|
|
241
|
-
total_tokens: 20
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
function buildResponsesReply(data) {
|
|
247
|
-
const text = typeof data === "string" ? data : JSON.stringify(data);
|
|
248
|
-
return {
|
|
249
|
-
status: 200,
|
|
250
|
-
body: {
|
|
251
|
-
id: "resp-test",
|
|
252
|
-
object: "response",
|
|
253
|
-
created_at: Math.floor(Date.now() / 1e3),
|
|
254
|
-
model: "gpt-4o-test",
|
|
255
|
-
output: [{
|
|
256
|
-
type: "message",
|
|
257
|
-
id: "msg-test",
|
|
258
|
-
role: "assistant",
|
|
259
|
-
content: [{
|
|
260
|
-
type: "output_text",
|
|
261
|
-
text,
|
|
262
|
-
annotations: []
|
|
263
|
-
}]
|
|
264
|
-
}],
|
|
265
|
-
usage: {
|
|
266
|
-
input_tokens: 10,
|
|
267
|
-
output_tokens: 10,
|
|
268
|
-
total_tokens: 20
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* OpenAI API intercept helpers.
|
|
275
|
-
*/
|
|
276
|
-
const openai = {
|
|
277
|
-
request(filter) {
|
|
278
|
-
return {
|
|
279
|
-
adapter: "openai",
|
|
280
|
-
method: "POST",
|
|
281
|
-
url: OPENAI_CHAT_URL,
|
|
282
|
-
match: filter ? (body) => matchesChatFilter(body, filter) : void 0,
|
|
283
|
-
wrap: buildChatReply
|
|
284
|
-
};
|
|
285
|
-
},
|
|
286
|
-
agent(filter, url) {
|
|
287
|
-
return {
|
|
288
|
-
adapter: "openai",
|
|
289
|
-
method: "POST",
|
|
290
|
-
url: url ?? OPENAI_RESPONSES_URL,
|
|
291
|
-
match: filter ? (body) => matchesResponsesFilter(body, filter) : void 0,
|
|
292
|
-
wrap: buildResponsesReply
|
|
293
|
-
};
|
|
294
|
-
},
|
|
295
|
-
reply: buildChatReply,
|
|
296
|
-
error(status, message) {
|
|
297
|
-
return {
|
|
298
|
-
status,
|
|
299
|
-
body: { error: {
|
|
300
|
-
message: message ?? `OpenAI error (${status})`,
|
|
301
|
-
type: status === 429 ? "rate_limit_error" : "api_error",
|
|
302
|
-
code: status === 429 ? "rate_limit_exceeded" : null
|
|
303
|
-
} }
|
|
304
|
-
};
|
|
305
|
-
},
|
|
306
|
-
malformed(content) {
|
|
307
|
-
return buildChatReply(content);
|
|
308
|
-
},
|
|
309
|
-
timeout() {
|
|
310
|
-
return {
|
|
311
|
-
status: 200,
|
|
312
|
-
body: {},
|
|
313
|
-
delay: 3e4
|
|
314
|
-
};
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
//#endregion
|
|
318
|
-
exports.anthropic = anthropic;
|
|
319
|
-
exports.claude = claude;
|
|
320
|
-
exports.http = http;
|
|
321
|
-
exports.openai = openai;
|
|
322
|
-
|
|
323
|
-
//# sourceMappingURL=intercept.cjs.map
|
package/dist/intercept.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"intercept.cjs","names":[],"sources":["../src/spec/intercept/adapters/anthropic.ts","../src/spec/intercept/adapters/http.ts","../src/spec/intercept/adapters/openai.ts"],"sourcesContent":["import type { InterceptResponse, InterceptTrigger } from '../types.js';\n\nconst ANTHROPIC_MESSAGES_URL = 'https://api.anthropic.com/v1/messages';\n\nexport interface AnthropicMessagesFilter {\n model?: RegExp | string;\n system?: RegExp | string;\n user?: RegExp | string;\n tools?: string[];\n}\n\nfunction matchesFilter(body: any, filter: AnthropicMessagesFilter): boolean {\n if (filter.model) {\n const model = body?.model;\n if (typeof filter.model === 'string' && model !== filter.model) {\n return false;\n }\n if (filter.model instanceof RegExp && !filter.model.test(model ?? '')) {\n return false;\n }\n }\n if (filter.system) {\n const system = typeof body?.system === 'string' ? body.system : '';\n if (typeof filter.system === 'string' && !system.includes(filter.system)) {\n return false;\n }\n if (filter.system instanceof RegExp && !filter.system.test(system)) {\n return false;\n }\n }\n if (filter.user) {\n const userMsg = body?.messages?.find((m: any) => m.role === 'user')?.content ?? '';\n const text = typeof userMsg === 'string' ? userMsg : JSON.stringify(userMsg);\n if (typeof filter.user === 'string' && !text.includes(filter.user)) {\n return false;\n }\n if (filter.user instanceof RegExp && !filter.user.test(text)) {\n return false;\n }\n }\n if (filter.tools) {\n const names = body?.tools?.map((t: any) => t.name).filter(Boolean) ?? [];\n if (!filter.tools.every((t) => names.includes(t))) {\n return false;\n }\n }\n return true;\n}\n\nfunction buildReply(data: unknown): InterceptResponse {\n const content = typeof data === 'string' ? data : JSON.stringify(data);\n return {\n status: 200,\n body: {\n id: 'msg-test',\n type: 'message',\n role: 'assistant',\n content: [{ type: 'text', text: content }],\n model: 'claude-sonnet-4-20250514',\n stop_reason: 'end_turn',\n usage: { input_tokens: 10, output_tokens: 10 },\n },\n };\n}\n\n/**\n * Anthropic API intercept helpers.\n */\nexport const anthropic = {\n /**\n * Trigger: match Anthropic messages API requests.\n *\n * @example\n * anthropic.request()\n * anthropic.request({ system: /classify/ })\n */\n request(filter?: AnthropicMessagesFilter): InterceptTrigger {\n return {\n adapter: 'anthropic',\n method: 'POST',\n url: ANTHROPIC_MESSAGES_URL,\n match: filter ? (body: unknown) => matchesFilter(body, filter) : undefined,\n wrap: buildReply,\n };\n },\n\n /**\n * Trigger: match `messages.create` calls, optionally routed through a\n * custom gateway URL. Mirrors `openai.agent()`. When used with a JSON\n * fixture file, the data is returned as-is (no wrapping) because Anthropic\n * fixtures are typically already in the `messages.create` response shape.\n *\n * @example\n * anthropic.message({ user: /classify/ }, GATEWAY)\n * claude.message({ system: /journal/ }, GATEWAY)\n */\n message(filter?: AnthropicMessagesFilter, url?: string): InterceptTrigger {\n return {\n adapter: 'anthropic',\n method: 'POST',\n url: url ?? ANTHROPIC_MESSAGES_URL,\n match: filter ? (body: unknown) => matchesFilter(body, filter) : undefined,\n // Fixture files are already in the messages.create response shape;\n // Pass them through verbatim. Falls back to wrapping for strings.\n wrap(data: unknown): InterceptResponse {\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n return { status: 200, body: data as Record<string, unknown> };\n }\n return buildReply(data);\n },\n };\n },\n\n /** Response: wrap data in Anthropic messages format. */\n reply: buildReply,\n\n /** Response: return an Anthropic error. */\n error(status: number, message?: string): InterceptResponse {\n return {\n status,\n body: {\n type: 'error',\n error: {\n type: status === 429 ? 'rate_limit_error' : 'api_error',\n message: message ?? `Anthropic error (${status})`,\n },\n },\n };\n },\n\n /** Response: simulate a timeout. */\n timeout(): InterceptResponse {\n return { status: 200, body: {}, delay: 30_000 };\n },\n};\n\n/**\n * Alias for {@link anthropic} — matches consumers that call the vendor \"claude\".\n * Re-exposed as a spread copy so downstream tooling (Knip, dts rollup) sees a\n * distinct export and not a duplicate of `anthropic`.\n */\nexport const claude: typeof anthropic = { ...anthropic };\n","import type { InterceptResponse, InterceptTrigger } from '../types.js';\n\nfunction wrapJson(data: unknown): InterceptResponse {\n return { status: 200, body: data };\n}\n\n/**\n * Generic HTTP intercept helpers for any URL.\n *\n * @example\n * .intercept(http.get('https://api.example.com/data'), 'http/response.json')\n */\nexport const http = {\n get(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'GET', url, wrap: wrapJson };\n },\n\n post(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'POST', url, wrap: wrapJson };\n },\n\n put(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'PUT', url, wrap: wrapJson };\n },\n\n delete(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'DELETE', url, wrap: wrapJson };\n },\n\n any(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: '*', url, wrap: wrapJson };\n },\n\n /** Response: simple JSON success. */\n json(data: unknown, status = 200): InterceptResponse {\n return { status, body: data };\n },\n\n /** Response: error with message. */\n error(status: number, message?: string): InterceptResponse {\n return { status, body: { error: message ?? `HTTP ${status}` } };\n },\n};\n","import type { InterceptResponse, InterceptTrigger } from '../types.js';\n\nconst OPENAI_CHAT_URL = 'https://api.openai.com/v1/chat/completions';\nconst OPENAI_RESPONSES_URL = 'https://api.openai.com/v1/responses';\n\n// ── Chat Completions filters ──\n\nexport interface OpenAIChatFilter {\n model?: RegExp | string;\n system?: RegExp | string;\n user?: RegExp | string;\n tools?: string[];\n temperature?: number;\n}\n\nfunction matchesChatFilter(body: any, filter: OpenAIChatFilter): boolean {\n if (filter.model) {\n const model = body?.model;\n if (typeof filter.model === 'string' && model !== filter.model) {\n return false;\n }\n if (filter.model instanceof RegExp && !filter.model.test(model ?? '')) {\n return false;\n }\n }\n if (filter.system) {\n const msg = body?.messages?.find((m: any) => m.role === 'system')?.content ?? '';\n if (typeof filter.system === 'string' && !msg.includes(filter.system)) {\n return false;\n }\n if (filter.system instanceof RegExp && !filter.system.test(msg)) {\n return false;\n }\n }\n if (filter.user) {\n const msg = body?.messages?.find((m: any) => m.role === 'user')?.content ?? '';\n if (typeof filter.user === 'string' && !msg.includes(filter.user)) {\n return false;\n }\n if (filter.user instanceof RegExp && !filter.user.test(msg)) {\n return false;\n }\n }\n if (filter.tools) {\n const names = body?.tools?.map((t: any) => t.function?.name).filter(Boolean) ?? [];\n if (!filter.tools.every((t) => names.includes(t))) {\n return false;\n }\n }\n if (filter.temperature !== undefined && body?.temperature !== filter.temperature) {\n return false;\n }\n return true;\n}\n\n// ── Responses API filters ──\n\nexport interface OpenAIResponsesFilter {\n model?: RegExp | string;\n system?: RegExp | string;\n user?: RegExp | string;\n tools?: string[];\n}\n\nfunction matchesResponsesFilter(body: any, filter: OpenAIResponsesFilter): boolean {\n if (filter.model) {\n const model = body?.model;\n if (typeof filter.model === 'string' && model !== filter.model) {\n return false;\n }\n if (filter.model instanceof RegExp && !filter.model.test(model ?? '')) {\n return false;\n }\n }\n if (filter.system) {\n const instructions = body?.instructions ?? '';\n const systemInput = body?.input?.find?.((m: any) => m.role === 'system')?.content ?? '';\n const text = instructions || systemInput;\n if (typeof filter.system === 'string' && !text.includes(filter.system)) {\n return false;\n }\n if (filter.system instanceof RegExp && !filter.system.test(text)) {\n return false;\n }\n }\n if (filter.user) {\n const msgs = (body?.input ?? [])\n .filter((m: any) => m.role === 'user')\n .map((m: any) =>\n typeof m.content === 'string' ? m.content : JSON.stringify(m.content),\n )\n .join(' ');\n if (typeof filter.user === 'string' && !msgs.includes(filter.user)) {\n return false;\n }\n if (filter.user instanceof RegExp && !filter.user.test(msgs)) {\n return false;\n }\n }\n if (filter.tools) {\n const names =\n body?.tools?.map((t: any) => t.name ?? t.function?.name).filter(Boolean) ?? [];\n if (!filter.tools.every((t) => names.includes(t))) {\n return false;\n }\n }\n return true;\n}\n\n// ── Response builders ──\n\nfunction buildChatReply(data: unknown): InterceptResponse {\n const content = typeof data === 'string' ? data : JSON.stringify(data);\n return {\n status: 200,\n body: {\n id: 'chatcmpl-test',\n object: 'chat.completion',\n created: Math.floor(Date.now() / 1000),\n model: 'gpt-4o-test',\n choices: [{ index: 0, message: { role: 'assistant', content }, finish_reason: 'stop' }],\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n },\n };\n}\n\nfunction buildResponsesReply(data: unknown): InterceptResponse {\n const text = typeof data === 'string' ? data : JSON.stringify(data);\n return {\n status: 200,\n body: {\n id: 'resp-test',\n object: 'response',\n created_at: Math.floor(Date.now() / 1000),\n model: 'gpt-4o-test',\n output: [\n {\n type: 'message',\n id: 'msg-test',\n role: 'assistant',\n content: [{ type: 'output_text', text, annotations: [] }],\n },\n ],\n usage: { input_tokens: 10, output_tokens: 10, total_tokens: 20 },\n },\n };\n}\n\n// ── Public API ──\n\n/**\n * OpenAI API intercept helpers.\n */\nexport const openai = {\n /**\n * Trigger: match Chat Completions API requests.\n *\n * @example\n * openai.request() // any chat call\n * openai.request({ model: 'gpt-4o' }) // specific model\n * openai.request({ system: /classify/ }) // system prompt match\n */\n request(filter?: OpenAIChatFilter): InterceptTrigger {\n return {\n adapter: 'openai',\n method: 'POST',\n url: OPENAI_CHAT_URL,\n match: filter ? (body: unknown) => matchesChatFilter(body, filter) : undefined,\n wrap: buildChatReply,\n };\n },\n\n /**\n * Trigger: match Responses API requests (AI SDK v5+) with auto-wrapping.\n * When used with a JSON file, the data is automatically wrapped in the\n * Responses API envelope.\n *\n * @param filter - Optional body filters.\n * @param url - Custom gateway URL (default: api.openai.com).\n *\n * @example\n * openai.agent({ user: /Report Ingestion/ }, GATEWAY)\n */\n agent(filter?: OpenAIResponsesFilter, url?: string): InterceptTrigger {\n return {\n adapter: 'openai',\n method: 'POST',\n url: url ?? OPENAI_RESPONSES_URL,\n match: filter ? (body: unknown) => matchesResponsesFilter(body, filter) : undefined,\n wrap: buildResponsesReply,\n };\n },\n\n /**\n * Response: wrap data in Chat Completions format.\n *\n * @example\n * openai.reply({ categories: ['TECH'] })\n */\n reply: buildChatReply,\n\n /** Response: return an OpenAI error. */\n error(status: number, message?: string): InterceptResponse {\n return {\n status,\n body: {\n error: {\n message: message ?? `OpenAI error (${status})`,\n type: status === 429 ? 'rate_limit_error' : 'api_error',\n code: status === 429 ? 'rate_limit_exceeded' : null,\n },\n },\n };\n },\n\n /** Response: return malformed content. */\n malformed(content: string): InterceptResponse {\n return buildChatReply(content);\n },\n\n /** Response: simulate a timeout. */\n timeout(): InterceptResponse {\n return { status: 200, body: {}, delay: 30_000 };\n },\n};\n"],"mappings":"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"}
|
package/dist/intercept.d.cts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { n as InterceptResponse, r as InterceptTrigger, t as InterceptEntry } from "./types.cjs";
|
|
2
|
-
|
|
3
|
-
//#region src/spec/intercept/adapters/anthropic.d.ts
|
|
4
|
-
interface AnthropicMessagesFilter {
|
|
5
|
-
model?: RegExp | string;
|
|
6
|
-
system?: RegExp | string;
|
|
7
|
-
user?: RegExp | string;
|
|
8
|
-
tools?: string[];
|
|
9
|
-
}
|
|
10
|
-
declare function buildReply(data: unknown): InterceptResponse;
|
|
11
|
-
/**
|
|
12
|
-
* Anthropic API intercept helpers.
|
|
13
|
-
*/
|
|
14
|
-
declare const anthropic: {
|
|
15
|
-
/**
|
|
16
|
-
* Trigger: match Anthropic messages API requests.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* anthropic.request()
|
|
20
|
-
* anthropic.request({ system: /classify/ })
|
|
21
|
-
*/
|
|
22
|
-
request(filter?: AnthropicMessagesFilter): InterceptTrigger;
|
|
23
|
-
/**
|
|
24
|
-
* Trigger: match `messages.create` calls, optionally routed through a
|
|
25
|
-
* custom gateway URL. Mirrors `openai.agent()`. When used with a JSON
|
|
26
|
-
* fixture file, the data is returned as-is (no wrapping) because Anthropic
|
|
27
|
-
* fixtures are typically already in the `messages.create` response shape.
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* anthropic.message({ user: /classify/ }, GATEWAY)
|
|
31
|
-
* claude.message({ system: /journal/ }, GATEWAY)
|
|
32
|
-
*/
|
|
33
|
-
message(filter?: AnthropicMessagesFilter, url?: string): InterceptTrigger; /** Response: wrap data in Anthropic messages format. */
|
|
34
|
-
reply: typeof buildReply; /** Response: return an Anthropic error. */
|
|
35
|
-
error(status: number, message?: string): InterceptResponse; /** Response: simulate a timeout. */
|
|
36
|
-
timeout(): InterceptResponse;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* Alias for {@link anthropic} — matches consumers that call the vendor "claude".
|
|
40
|
-
* Re-exposed as a spread copy so downstream tooling (Knip, dts rollup) sees a
|
|
41
|
-
* distinct export and not a duplicate of `anthropic`.
|
|
42
|
-
*/
|
|
43
|
-
declare const claude: typeof anthropic;
|
|
44
|
-
//#endregion
|
|
45
|
-
//#region src/spec/intercept/adapters/http.d.ts
|
|
46
|
-
/**
|
|
47
|
-
* Generic HTTP intercept helpers for any URL.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* .intercept(http.get('https://api.example.com/data'), 'http/response.json')
|
|
51
|
-
*/
|
|
52
|
-
declare const http: {
|
|
53
|
-
get(url: RegExp | string): InterceptTrigger;
|
|
54
|
-
post(url: RegExp | string): InterceptTrigger;
|
|
55
|
-
put(url: RegExp | string): InterceptTrigger;
|
|
56
|
-
delete(url: RegExp | string): InterceptTrigger;
|
|
57
|
-
any(url: RegExp | string): InterceptTrigger; /** Response: simple JSON success. */
|
|
58
|
-
json(data: unknown, status?: number): InterceptResponse; /** Response: error with message. */
|
|
59
|
-
error(status: number, message?: string): InterceptResponse;
|
|
60
|
-
};
|
|
61
|
-
//#endregion
|
|
62
|
-
//#region src/spec/intercept/adapters/openai.d.ts
|
|
63
|
-
interface OpenAIChatFilter {
|
|
64
|
-
model?: RegExp | string;
|
|
65
|
-
system?: RegExp | string;
|
|
66
|
-
user?: RegExp | string;
|
|
67
|
-
tools?: string[];
|
|
68
|
-
temperature?: number;
|
|
69
|
-
}
|
|
70
|
-
interface OpenAIResponsesFilter {
|
|
71
|
-
model?: RegExp | string;
|
|
72
|
-
system?: RegExp | string;
|
|
73
|
-
user?: RegExp | string;
|
|
74
|
-
tools?: string[];
|
|
75
|
-
}
|
|
76
|
-
declare function buildChatReply(data: unknown): InterceptResponse;
|
|
77
|
-
/**
|
|
78
|
-
* OpenAI API intercept helpers.
|
|
79
|
-
*/
|
|
80
|
-
declare const openai: {
|
|
81
|
-
/**
|
|
82
|
-
* Trigger: match Chat Completions API requests.
|
|
83
|
-
*
|
|
84
|
-
* @example
|
|
85
|
-
* openai.request() // any chat call
|
|
86
|
-
* openai.request({ model: 'gpt-4o' }) // specific model
|
|
87
|
-
* openai.request({ system: /classify/ }) // system prompt match
|
|
88
|
-
*/
|
|
89
|
-
request(filter?: OpenAIChatFilter): InterceptTrigger;
|
|
90
|
-
/**
|
|
91
|
-
* Trigger: match Responses API requests (AI SDK v5+) with auto-wrapping.
|
|
92
|
-
* When used with a JSON file, the data is automatically wrapped in the
|
|
93
|
-
* Responses API envelope.
|
|
94
|
-
*
|
|
95
|
-
* @param filter - Optional body filters.
|
|
96
|
-
* @param url - Custom gateway URL (default: api.openai.com).
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* openai.agent({ user: /Report Ingestion/ }, GATEWAY)
|
|
100
|
-
*/
|
|
101
|
-
agent(filter?: OpenAIResponsesFilter, url?: string): InterceptTrigger;
|
|
102
|
-
/**
|
|
103
|
-
* Response: wrap data in Chat Completions format.
|
|
104
|
-
*
|
|
105
|
-
* @example
|
|
106
|
-
* openai.reply({ categories: ['TECH'] })
|
|
107
|
-
*/
|
|
108
|
-
reply: typeof buildChatReply; /** Response: return an OpenAI error. */
|
|
109
|
-
error(status: number, message?: string): InterceptResponse; /** Response: return malformed content. */
|
|
110
|
-
malformed(content: string): InterceptResponse; /** Response: simulate a timeout. */
|
|
111
|
-
timeout(): InterceptResponse;
|
|
112
|
-
};
|
|
113
|
-
//#endregion
|
|
114
|
-
export { type InterceptEntry, type InterceptResponse, type InterceptTrigger, anthropic, claude, http, openai };
|
|
115
|
-
//# sourceMappingURL=intercept.d.cts.map
|
package/dist/intercept.d.ts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { n as InterceptResponse, r as InterceptTrigger, t as InterceptEntry } from "./types.js";
|
|
2
|
-
|
|
3
|
-
//#region src/spec/intercept/adapters/anthropic.d.ts
|
|
4
|
-
interface AnthropicMessagesFilter {
|
|
5
|
-
model?: RegExp | string;
|
|
6
|
-
system?: RegExp | string;
|
|
7
|
-
user?: RegExp | string;
|
|
8
|
-
tools?: string[];
|
|
9
|
-
}
|
|
10
|
-
declare function buildReply(data: unknown): InterceptResponse;
|
|
11
|
-
/**
|
|
12
|
-
* Anthropic API intercept helpers.
|
|
13
|
-
*/
|
|
14
|
-
declare const anthropic: {
|
|
15
|
-
/**
|
|
16
|
-
* Trigger: match Anthropic messages API requests.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* anthropic.request()
|
|
20
|
-
* anthropic.request({ system: /classify/ })
|
|
21
|
-
*/
|
|
22
|
-
request(filter?: AnthropicMessagesFilter): InterceptTrigger;
|
|
23
|
-
/**
|
|
24
|
-
* Trigger: match `messages.create` calls, optionally routed through a
|
|
25
|
-
* custom gateway URL. Mirrors `openai.agent()`. When used with a JSON
|
|
26
|
-
* fixture file, the data is returned as-is (no wrapping) because Anthropic
|
|
27
|
-
* fixtures are typically already in the `messages.create` response shape.
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* anthropic.message({ user: /classify/ }, GATEWAY)
|
|
31
|
-
* claude.message({ system: /journal/ }, GATEWAY)
|
|
32
|
-
*/
|
|
33
|
-
message(filter?: AnthropicMessagesFilter, url?: string): InterceptTrigger; /** Response: wrap data in Anthropic messages format. */
|
|
34
|
-
reply: typeof buildReply; /** Response: return an Anthropic error. */
|
|
35
|
-
error(status: number, message?: string): InterceptResponse; /** Response: simulate a timeout. */
|
|
36
|
-
timeout(): InterceptResponse;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* Alias for {@link anthropic} — matches consumers that call the vendor "claude".
|
|
40
|
-
* Re-exposed as a spread copy so downstream tooling (Knip, dts rollup) sees a
|
|
41
|
-
* distinct export and not a duplicate of `anthropic`.
|
|
42
|
-
*/
|
|
43
|
-
declare const claude: typeof anthropic;
|
|
44
|
-
//#endregion
|
|
45
|
-
//#region src/spec/intercept/adapters/http.d.ts
|
|
46
|
-
/**
|
|
47
|
-
* Generic HTTP intercept helpers for any URL.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* .intercept(http.get('https://api.example.com/data'), 'http/response.json')
|
|
51
|
-
*/
|
|
52
|
-
declare const http: {
|
|
53
|
-
get(url: RegExp | string): InterceptTrigger;
|
|
54
|
-
post(url: RegExp | string): InterceptTrigger;
|
|
55
|
-
put(url: RegExp | string): InterceptTrigger;
|
|
56
|
-
delete(url: RegExp | string): InterceptTrigger;
|
|
57
|
-
any(url: RegExp | string): InterceptTrigger; /** Response: simple JSON success. */
|
|
58
|
-
json(data: unknown, status?: number): InterceptResponse; /** Response: error with message. */
|
|
59
|
-
error(status: number, message?: string): InterceptResponse;
|
|
60
|
-
};
|
|
61
|
-
//#endregion
|
|
62
|
-
//#region src/spec/intercept/adapters/openai.d.ts
|
|
63
|
-
interface OpenAIChatFilter {
|
|
64
|
-
model?: RegExp | string;
|
|
65
|
-
system?: RegExp | string;
|
|
66
|
-
user?: RegExp | string;
|
|
67
|
-
tools?: string[];
|
|
68
|
-
temperature?: number;
|
|
69
|
-
}
|
|
70
|
-
interface OpenAIResponsesFilter {
|
|
71
|
-
model?: RegExp | string;
|
|
72
|
-
system?: RegExp | string;
|
|
73
|
-
user?: RegExp | string;
|
|
74
|
-
tools?: string[];
|
|
75
|
-
}
|
|
76
|
-
declare function buildChatReply(data: unknown): InterceptResponse;
|
|
77
|
-
/**
|
|
78
|
-
* OpenAI API intercept helpers.
|
|
79
|
-
*/
|
|
80
|
-
declare const openai: {
|
|
81
|
-
/**
|
|
82
|
-
* Trigger: match Chat Completions API requests.
|
|
83
|
-
*
|
|
84
|
-
* @example
|
|
85
|
-
* openai.request() // any chat call
|
|
86
|
-
* openai.request({ model: 'gpt-4o' }) // specific model
|
|
87
|
-
* openai.request({ system: /classify/ }) // system prompt match
|
|
88
|
-
*/
|
|
89
|
-
request(filter?: OpenAIChatFilter): InterceptTrigger;
|
|
90
|
-
/**
|
|
91
|
-
* Trigger: match Responses API requests (AI SDK v5+) with auto-wrapping.
|
|
92
|
-
* When used with a JSON file, the data is automatically wrapped in the
|
|
93
|
-
* Responses API envelope.
|
|
94
|
-
*
|
|
95
|
-
* @param filter - Optional body filters.
|
|
96
|
-
* @param url - Custom gateway URL (default: api.openai.com).
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* openai.agent({ user: /Report Ingestion/ }, GATEWAY)
|
|
100
|
-
*/
|
|
101
|
-
agent(filter?: OpenAIResponsesFilter, url?: string): InterceptTrigger;
|
|
102
|
-
/**
|
|
103
|
-
* Response: wrap data in Chat Completions format.
|
|
104
|
-
*
|
|
105
|
-
* @example
|
|
106
|
-
* openai.reply({ categories: ['TECH'] })
|
|
107
|
-
*/
|
|
108
|
-
reply: typeof buildChatReply; /** Response: return an OpenAI error. */
|
|
109
|
-
error(status: number, message?: string): InterceptResponse; /** Response: return malformed content. */
|
|
110
|
-
malformed(content: string): InterceptResponse; /** Response: simulate a timeout. */
|
|
111
|
-
timeout(): InterceptResponse;
|
|
112
|
-
};
|
|
113
|
-
//#endregion
|
|
114
|
-
export { type InterceptEntry, type InterceptResponse, type InterceptTrigger, anthropic, claude, http, openai };
|
|
115
|
-
//# sourceMappingURL=intercept.d.ts.map
|
package/dist/intercept.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"intercept.js","names":[],"sources":["../src/spec/intercept/adapters/anthropic.ts","../src/spec/intercept/adapters/http.ts","../src/spec/intercept/adapters/openai.ts"],"sourcesContent":["import type { InterceptResponse, InterceptTrigger } from '../types.js';\n\nconst ANTHROPIC_MESSAGES_URL = 'https://api.anthropic.com/v1/messages';\n\nexport interface AnthropicMessagesFilter {\n model?: RegExp | string;\n system?: RegExp | string;\n user?: RegExp | string;\n tools?: string[];\n}\n\nfunction matchesFilter(body: any, filter: AnthropicMessagesFilter): boolean {\n if (filter.model) {\n const model = body?.model;\n if (typeof filter.model === 'string' && model !== filter.model) {\n return false;\n }\n if (filter.model instanceof RegExp && !filter.model.test(model ?? '')) {\n return false;\n }\n }\n if (filter.system) {\n const system = typeof body?.system === 'string' ? body.system : '';\n if (typeof filter.system === 'string' && !system.includes(filter.system)) {\n return false;\n }\n if (filter.system instanceof RegExp && !filter.system.test(system)) {\n return false;\n }\n }\n if (filter.user) {\n const userMsg = body?.messages?.find((m: any) => m.role === 'user')?.content ?? '';\n const text = typeof userMsg === 'string' ? userMsg : JSON.stringify(userMsg);\n if (typeof filter.user === 'string' && !text.includes(filter.user)) {\n return false;\n }\n if (filter.user instanceof RegExp && !filter.user.test(text)) {\n return false;\n }\n }\n if (filter.tools) {\n const names = body?.tools?.map((t: any) => t.name).filter(Boolean) ?? [];\n if (!filter.tools.every((t) => names.includes(t))) {\n return false;\n }\n }\n return true;\n}\n\nfunction buildReply(data: unknown): InterceptResponse {\n const content = typeof data === 'string' ? data : JSON.stringify(data);\n return {\n status: 200,\n body: {\n id: 'msg-test',\n type: 'message',\n role: 'assistant',\n content: [{ type: 'text', text: content }],\n model: 'claude-sonnet-4-20250514',\n stop_reason: 'end_turn',\n usage: { input_tokens: 10, output_tokens: 10 },\n },\n };\n}\n\n/**\n * Anthropic API intercept helpers.\n */\nexport const anthropic = {\n /**\n * Trigger: match Anthropic messages API requests.\n *\n * @example\n * anthropic.request()\n * anthropic.request({ system: /classify/ })\n */\n request(filter?: AnthropicMessagesFilter): InterceptTrigger {\n return {\n adapter: 'anthropic',\n method: 'POST',\n url: ANTHROPIC_MESSAGES_URL,\n match: filter ? (body: unknown) => matchesFilter(body, filter) : undefined,\n wrap: buildReply,\n };\n },\n\n /**\n * Trigger: match `messages.create` calls, optionally routed through a\n * custom gateway URL. Mirrors `openai.agent()`. When used with a JSON\n * fixture file, the data is returned as-is (no wrapping) because Anthropic\n * fixtures are typically already in the `messages.create` response shape.\n *\n * @example\n * anthropic.message({ user: /classify/ }, GATEWAY)\n * claude.message({ system: /journal/ }, GATEWAY)\n */\n message(filter?: AnthropicMessagesFilter, url?: string): InterceptTrigger {\n return {\n adapter: 'anthropic',\n method: 'POST',\n url: url ?? ANTHROPIC_MESSAGES_URL,\n match: filter ? (body: unknown) => matchesFilter(body, filter) : undefined,\n // Fixture files are already in the messages.create response shape;\n // Pass them through verbatim. Falls back to wrapping for strings.\n wrap(data: unknown): InterceptResponse {\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n return { status: 200, body: data as Record<string, unknown> };\n }\n return buildReply(data);\n },\n };\n },\n\n /** Response: wrap data in Anthropic messages format. */\n reply: buildReply,\n\n /** Response: return an Anthropic error. */\n error(status: number, message?: string): InterceptResponse {\n return {\n status,\n body: {\n type: 'error',\n error: {\n type: status === 429 ? 'rate_limit_error' : 'api_error',\n message: message ?? `Anthropic error (${status})`,\n },\n },\n };\n },\n\n /** Response: simulate a timeout. */\n timeout(): InterceptResponse {\n return { status: 200, body: {}, delay: 30_000 };\n },\n};\n\n/**\n * Alias for {@link anthropic} — matches consumers that call the vendor \"claude\".\n * Re-exposed as a spread copy so downstream tooling (Knip, dts rollup) sees a\n * distinct export and not a duplicate of `anthropic`.\n */\nexport const claude: typeof anthropic = { ...anthropic };\n","import type { InterceptResponse, InterceptTrigger } from '../types.js';\n\nfunction wrapJson(data: unknown): InterceptResponse {\n return { status: 200, body: data };\n}\n\n/**\n * Generic HTTP intercept helpers for any URL.\n *\n * @example\n * .intercept(http.get('https://api.example.com/data'), 'http/response.json')\n */\nexport const http = {\n get(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'GET', url, wrap: wrapJson };\n },\n\n post(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'POST', url, wrap: wrapJson };\n },\n\n put(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'PUT', url, wrap: wrapJson };\n },\n\n delete(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'DELETE', url, wrap: wrapJson };\n },\n\n any(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: '*', url, wrap: wrapJson };\n },\n\n /** Response: simple JSON success. */\n json(data: unknown, status = 200): InterceptResponse {\n return { status, body: data };\n },\n\n /** Response: error with message. */\n error(status: number, message?: string): InterceptResponse {\n return { status, body: { error: message ?? `HTTP ${status}` } };\n },\n};\n","import type { InterceptResponse, InterceptTrigger } from '../types.js';\n\nconst OPENAI_CHAT_URL = 'https://api.openai.com/v1/chat/completions';\nconst OPENAI_RESPONSES_URL = 'https://api.openai.com/v1/responses';\n\n// ── Chat Completions filters ──\n\nexport interface OpenAIChatFilter {\n model?: RegExp | string;\n system?: RegExp | string;\n user?: RegExp | string;\n tools?: string[];\n temperature?: number;\n}\n\nfunction matchesChatFilter(body: any, filter: OpenAIChatFilter): boolean {\n if (filter.model) {\n const model = body?.model;\n if (typeof filter.model === 'string' && model !== filter.model) {\n return false;\n }\n if (filter.model instanceof RegExp && !filter.model.test(model ?? '')) {\n return false;\n }\n }\n if (filter.system) {\n const msg = body?.messages?.find((m: any) => m.role === 'system')?.content ?? '';\n if (typeof filter.system === 'string' && !msg.includes(filter.system)) {\n return false;\n }\n if (filter.system instanceof RegExp && !filter.system.test(msg)) {\n return false;\n }\n }\n if (filter.user) {\n const msg = body?.messages?.find((m: any) => m.role === 'user')?.content ?? '';\n if (typeof filter.user === 'string' && !msg.includes(filter.user)) {\n return false;\n }\n if (filter.user instanceof RegExp && !filter.user.test(msg)) {\n return false;\n }\n }\n if (filter.tools) {\n const names = body?.tools?.map((t: any) => t.function?.name).filter(Boolean) ?? [];\n if (!filter.tools.every((t) => names.includes(t))) {\n return false;\n }\n }\n if (filter.temperature !== undefined && body?.temperature !== filter.temperature) {\n return false;\n }\n return true;\n}\n\n// ── Responses API filters ──\n\nexport interface OpenAIResponsesFilter {\n model?: RegExp | string;\n system?: RegExp | string;\n user?: RegExp | string;\n tools?: string[];\n}\n\nfunction matchesResponsesFilter(body: any, filter: OpenAIResponsesFilter): boolean {\n if (filter.model) {\n const model = body?.model;\n if (typeof filter.model === 'string' && model !== filter.model) {\n return false;\n }\n if (filter.model instanceof RegExp && !filter.model.test(model ?? '')) {\n return false;\n }\n }\n if (filter.system) {\n const instructions = body?.instructions ?? '';\n const systemInput = body?.input?.find?.((m: any) => m.role === 'system')?.content ?? '';\n const text = instructions || systemInput;\n if (typeof filter.system === 'string' && !text.includes(filter.system)) {\n return false;\n }\n if (filter.system instanceof RegExp && !filter.system.test(text)) {\n return false;\n }\n }\n if (filter.user) {\n const msgs = (body?.input ?? [])\n .filter((m: any) => m.role === 'user')\n .map((m: any) =>\n typeof m.content === 'string' ? m.content : JSON.stringify(m.content),\n )\n .join(' ');\n if (typeof filter.user === 'string' && !msgs.includes(filter.user)) {\n return false;\n }\n if (filter.user instanceof RegExp && !filter.user.test(msgs)) {\n return false;\n }\n }\n if (filter.tools) {\n const names =\n body?.tools?.map((t: any) => t.name ?? t.function?.name).filter(Boolean) ?? [];\n if (!filter.tools.every((t) => names.includes(t))) {\n return false;\n }\n }\n return true;\n}\n\n// ── Response builders ──\n\nfunction buildChatReply(data: unknown): InterceptResponse {\n const content = typeof data === 'string' ? data : JSON.stringify(data);\n return {\n status: 200,\n body: {\n id: 'chatcmpl-test',\n object: 'chat.completion',\n created: Math.floor(Date.now() / 1000),\n model: 'gpt-4o-test',\n choices: [{ index: 0, message: { role: 'assistant', content }, finish_reason: 'stop' }],\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n },\n };\n}\n\nfunction buildResponsesReply(data: unknown): InterceptResponse {\n const text = typeof data === 'string' ? data : JSON.stringify(data);\n return {\n status: 200,\n body: {\n id: 'resp-test',\n object: 'response',\n created_at: Math.floor(Date.now() / 1000),\n model: 'gpt-4o-test',\n output: [\n {\n type: 'message',\n id: 'msg-test',\n role: 'assistant',\n content: [{ type: 'output_text', text, annotations: [] }],\n },\n ],\n usage: { input_tokens: 10, output_tokens: 10, total_tokens: 20 },\n },\n };\n}\n\n// ── Public API ──\n\n/**\n * OpenAI API intercept helpers.\n */\nexport const openai = {\n /**\n * Trigger: match Chat Completions API requests.\n *\n * @example\n * openai.request() // any chat call\n * openai.request({ model: 'gpt-4o' }) // specific model\n * openai.request({ system: /classify/ }) // system prompt match\n */\n request(filter?: OpenAIChatFilter): InterceptTrigger {\n return {\n adapter: 'openai',\n method: 'POST',\n url: OPENAI_CHAT_URL,\n match: filter ? (body: unknown) => matchesChatFilter(body, filter) : undefined,\n wrap: buildChatReply,\n };\n },\n\n /**\n * Trigger: match Responses API requests (AI SDK v5+) with auto-wrapping.\n * When used with a JSON file, the data is automatically wrapped in the\n * Responses API envelope.\n *\n * @param filter - Optional body filters.\n * @param url - Custom gateway URL (default: api.openai.com).\n *\n * @example\n * openai.agent({ user: /Report Ingestion/ }, GATEWAY)\n */\n agent(filter?: OpenAIResponsesFilter, url?: string): InterceptTrigger {\n return {\n adapter: 'openai',\n method: 'POST',\n url: url ?? OPENAI_RESPONSES_URL,\n match: filter ? (body: unknown) => matchesResponsesFilter(body, filter) : undefined,\n wrap: buildResponsesReply,\n };\n },\n\n /**\n * Response: wrap data in Chat Completions format.\n *\n * @example\n * openai.reply({ categories: ['TECH'] })\n */\n reply: buildChatReply,\n\n /** Response: return an OpenAI error. */\n error(status: number, message?: string): InterceptResponse {\n return {\n status,\n body: {\n error: {\n message: message ?? `OpenAI error (${status})`,\n type: status === 429 ? 'rate_limit_error' : 'api_error',\n code: status === 429 ? 'rate_limit_exceeded' : null,\n },\n },\n };\n },\n\n /** Response: return malformed content. */\n malformed(content: string): InterceptResponse {\n return buildChatReply(content);\n },\n\n /** Response: simulate a timeout. */\n timeout(): InterceptResponse {\n return { status: 200, body: {}, delay: 30_000 };\n },\n};\n"],"mappings":"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"}
|