testflow-ai 0.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.
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Flow executor — runs HTTP requests, captures variables, and evaluates assertions.
3
+ */
4
+ import type { TestFlow, TestStep, FlowResult, StepResult, AssertionResult, AssertionDefinition, ProjectContext, AiConfig } from './types.js';
5
+ /** Extract a value from a nested object using dot-notation (supports array indices). */
6
+ export declare function extractValue(obj: unknown, path: string): unknown;
7
+ /** Interpolate `${var}` references in a string. */
8
+ export declare function interpolate(str: string, variables: Record<string, unknown>): string;
9
+ /** Evaluate a single assertion against an actual value. */
10
+ export declare function evaluateAssertion(assertion: AssertionDefinition, actual: unknown): AssertionResult;
11
+ export declare class FlowExecutor {
12
+ private variables;
13
+ private context?;
14
+ private aiConfig?;
15
+ private verbose;
16
+ constructor(context?: ProjectContext, verbose?: boolean, aiConfig?: Partial<AiConfig>);
17
+ /** Execute a complete test flow (all steps in sequence). */
18
+ executeFlow(flow: TestFlow): Promise<FlowResult>;
19
+ /** Execute a single step: request → capture → assert. */
20
+ executeStep(step: TestStep): Promise<StepResult>;
21
+ private poll;
22
+ private runAiAssertion;
23
+ private resolveUrl;
24
+ private resolveVariables;
25
+ private interpolateStr;
26
+ private parseJsonStrings;
27
+ }
28
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EACV,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,QAAQ,EACT,MAAM,YAAY,CAAC;AAIpB,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAiBhE;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CASnF;AAED,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,mBAAmB,EAC9B,MAAM,EAAE,OAAO,GACd,eAAe,CA8EjB;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,OAAO,CAAC,CAAiB;IACjC,OAAO,CAAC,QAAQ,CAAC,CAAW;IAC5B,OAAO,CAAC,OAAO,CAAU;gBAEb,OAAO,CAAC,EAAE,cAAc,EAAE,OAAO,UAAQ,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC;IAYnF,4DAA4D;IACtD,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAsBtD,yDAAyD;IACnD,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;YAmHxC,IAAI;YAmDJ,cAAc;IAqB5B,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;CAYzB"}
@@ -0,0 +1,390 @@
1
+ "use strict";
2
+ /**
3
+ * Flow executor — runs HTTP requests, captures variables, and evaluates assertions.
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.FlowExecutor = void 0;
10
+ exports.extractValue = extractValue;
11
+ exports.interpolate = interpolate;
12
+ exports.evaluateAssertion = evaluateAssertion;
13
+ const axios_1 = __importDefault(require("axios"));
14
+ const ai_js_1 = require("./ai.js");
15
+ // -- Public utilities (also used by tests) --
16
+ /** Extract a value from a nested object using dot-notation (supports array indices). */
17
+ function extractValue(obj, path) {
18
+ let current = obj;
19
+ for (const part of path.split('.')) {
20
+ if (current === null || current === undefined)
21
+ return undefined;
22
+ const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
23
+ if (arrayMatch) {
24
+ current = current[arrayMatch[1]];
25
+ if (Array.isArray(current))
26
+ current = current[parseInt(arrayMatch[2], 10)];
27
+ else
28
+ return undefined;
29
+ }
30
+ else {
31
+ current = current[part];
32
+ }
33
+ }
34
+ return current;
35
+ }
36
+ /** Interpolate `${var}` references in a string. */
37
+ function interpolate(str, variables) {
38
+ if (!str || typeof str !== 'string')
39
+ return str || '';
40
+ return str.replace(/\$\{(\w+(?:\[\d+\])?(?:\.\w+(?:\[\d+\])?)*)\}/g, (_, varPath) => {
41
+ const value = extractValue(variables, varPath);
42
+ if (value === undefined)
43
+ return `\${${varPath}}`;
44
+ if (typeof value === 'object' && value !== null)
45
+ return JSON.stringify(value);
46
+ return String(value);
47
+ });
48
+ }
49
+ /** Evaluate a single assertion against an actual value. */
50
+ function evaluateAssertion(assertion, actual) {
51
+ let success = false;
52
+ let message = '';
53
+ switch (assertion.operator) {
54
+ case 'equals':
55
+ success = JSON.stringify(actual) === JSON.stringify(assertion.value);
56
+ message = success
57
+ ? `${assertion.path} equals ${JSON.stringify(assertion.value)}`
58
+ : `Expected ${assertion.path} to equal ${JSON.stringify(assertion.value)}, got ${JSON.stringify(actual)}`;
59
+ break;
60
+ case 'notEquals':
61
+ success = JSON.stringify(actual) !== JSON.stringify(assertion.value);
62
+ message = success
63
+ ? `${assertion.path} does not equal ${JSON.stringify(assertion.value)}`
64
+ : `Expected ${assertion.path} to not equal ${JSON.stringify(assertion.value)}`;
65
+ break;
66
+ case 'contains':
67
+ if (typeof actual === 'string')
68
+ success = actual.includes(String(assertion.value));
69
+ else if (Array.isArray(actual))
70
+ success = actual.includes(assertion.value);
71
+ message = success
72
+ ? `${assertion.path} contains ${JSON.stringify(assertion.value)}`
73
+ : `Expected ${assertion.path} to contain ${JSON.stringify(assertion.value)}`;
74
+ break;
75
+ case 'notContains':
76
+ if (typeof actual === 'string')
77
+ success = !actual.includes(String(assertion.value));
78
+ else if (Array.isArray(actual))
79
+ success = !actual.includes(assertion.value);
80
+ else
81
+ success = true;
82
+ message = success
83
+ ? `${assertion.path} does not contain ${JSON.stringify(assertion.value)}`
84
+ : `Expected ${assertion.path} to not contain ${JSON.stringify(assertion.value)}`;
85
+ break;
86
+ case 'exists':
87
+ success = actual !== undefined && actual !== null;
88
+ message = success ? `${assertion.path} exists` : `Expected ${assertion.path} to exist`;
89
+ break;
90
+ case 'notExists':
91
+ success = actual === undefined || actual === null;
92
+ message = success
93
+ ? `${assertion.path} does not exist`
94
+ : `Expected ${assertion.path} to not exist`;
95
+ break;
96
+ case 'greaterThan':
97
+ success = typeof actual === 'number' && actual > assertion.value;
98
+ message = success
99
+ ? `${assertion.path} (${actual}) > ${assertion.value}`
100
+ : `Expected ${assertion.path} to be > ${assertion.value}, got ${actual}`;
101
+ break;
102
+ case 'lessThan':
103
+ success = typeof actual === 'number' && actual < assertion.value;
104
+ message = success
105
+ ? `${assertion.path} (${actual}) < ${assertion.value}`
106
+ : `Expected ${assertion.path} to be < ${assertion.value}, got ${actual}`;
107
+ break;
108
+ case 'matches':
109
+ if (typeof actual === 'string' && typeof assertion.value === 'string') {
110
+ success = new RegExp(assertion.value).test(actual);
111
+ }
112
+ message = success
113
+ ? `${assertion.path} matches ${assertion.value}`
114
+ : `Expected ${assertion.path} to match ${assertion.value}`;
115
+ break;
116
+ case 'ai-evaluate':
117
+ // Handled asynchronously in the executor; sync fallback.
118
+ message = 'AI evaluation requires async execution';
119
+ break;
120
+ }
121
+ return { assertion, success, actual, message: assertion.message || message };
122
+ }
123
+ // -- FlowExecutor --
124
+ class FlowExecutor {
125
+ variables = {};
126
+ context;
127
+ aiConfig;
128
+ verbose;
129
+ constructor(context, verbose = false, aiConfig) {
130
+ this.context = context;
131
+ this.verbose = verbose;
132
+ // Resolve AI config from explicit param, context file, or defaults.
133
+ if (aiConfig) {
134
+ this.aiConfig = (0, ai_js_1.resolveAiConfig)(aiConfig);
135
+ }
136
+ else if (context?.ai) {
137
+ this.aiConfig = (0, ai_js_1.resolveAiConfig)(context.ai);
138
+ }
139
+ }
140
+ /** Execute a complete test flow (all steps in sequence). */
141
+ async executeFlow(flow) {
142
+ const start = Date.now();
143
+ const stepResults = [];
144
+ let success = true;
145
+ this.variables = {};
146
+ if (this.verbose) {
147
+ console.log(`\n📋 Flow: ${flow.name}`);
148
+ if (flow.description)
149
+ console.log(` ${flow.description}`);
150
+ console.log(` Steps: ${flow.steps.length}`);
151
+ }
152
+ for (let i = 0; i < flow.steps.length; i++) {
153
+ if (this.verbose)
154
+ console.log(`\n[${i + 1}/${flow.steps.length}]`);
155
+ const result = await this.executeStep(flow.steps[i]);
156
+ stepResults.push(result);
157
+ if (!result.success)
158
+ success = false;
159
+ }
160
+ return { flow, success, duration: Date.now() - start, steps: stepResults, variables: { ...this.variables } };
161
+ }
162
+ /** Execute a single step: request → capture → assert. */
163
+ async executeStep(step) {
164
+ const start = Date.now();
165
+ const captures = {};
166
+ const assertions = [];
167
+ if (this.verbose) {
168
+ console.log(`\n🧪 Step: ${step.name}`);
169
+ if (step.description)
170
+ console.log(` ${step.description}`);
171
+ }
172
+ try {
173
+ const resolved = this.resolveVariables(step.request);
174
+ const url = this.resolveUrl(resolved.url);
175
+ let body = resolved.body;
176
+ // GraphQL
177
+ if (resolved.graphql) {
178
+ const query = resolved.graphql.query ? this.interpolateStr(resolved.graphql.query) : undefined;
179
+ let variables = resolved.graphql.variables
180
+ ? this.resolveVariables(resolved.graphql.variables)
181
+ : undefined;
182
+ if (variables && typeof variables === 'object')
183
+ variables = this.parseJsonStrings(variables);
184
+ body = { query, variables, operationName: resolved.graphql.operationName };
185
+ if (this.verbose) {
186
+ const op = resolved.graphql.operationName || query?.match(/(?:mutation|query)\s+(\w+)/)?.[1] || 'operation';
187
+ console.log(` 📡 GraphQL ${op} → ${url}`);
188
+ }
189
+ }
190
+ else if (this.verbose) {
191
+ console.log(` 📡 ${resolved.method} ${url}`);
192
+ }
193
+ // HTTP request
194
+ const reqStart = Date.now();
195
+ let response = await (0, axios_1.default)({
196
+ method: resolved.method,
197
+ url,
198
+ headers: resolved.headers,
199
+ data: body,
200
+ validateStatus: () => true,
201
+ });
202
+ if (this.verbose) {
203
+ const emoji = response.status >= 200 && response.status < 300 ? '✅' : '❌';
204
+ console.log(` ${emoji} ${response.status} (${Date.now() - reqStart}ms)`);
205
+ }
206
+ // Polling (waitUntil)
207
+ if (step.waitUntil) {
208
+ response = await this.poll(step.waitUntil, resolved, url, body, response);
209
+ }
210
+ // GraphQL errors
211
+ if (resolved.graphql && response.data?.errors && this.verbose) {
212
+ for (const err of response.data.errors) {
213
+ console.log(` ⚠️ ${err.message || 'GraphQL error'}`);
214
+ }
215
+ }
216
+ // Capture
217
+ if (step.capture) {
218
+ for (const cap of step.capture) {
219
+ const val = extractValue(response.data, cap.path);
220
+ captures[cap.name] = val;
221
+ this.variables[cap.name] = val;
222
+ if (this.verbose) {
223
+ const display = val != null
224
+ ? (typeof val === 'string' ? val.substring(0, 40) : JSON.stringify(val).substring(0, 40))
225
+ : String(val);
226
+ console.log(` 📦 ${cap.name} = ${display}`);
227
+ }
228
+ }
229
+ }
230
+ // Assertions
231
+ if (step.assertions) {
232
+ for (const a of step.assertions) {
233
+ const actual = a.path === 'httpStatus' || (a.path === 'status' && typeof a.value === 'number')
234
+ ? response.status
235
+ : extractValue(response.data, a.path);
236
+ if (a.operator === 'ai-evaluate') {
237
+ assertions.push(await this.runAiAssertion(a, actual));
238
+ }
239
+ else {
240
+ assertions.push(evaluateAssertion(a, actual));
241
+ }
242
+ }
243
+ }
244
+ return {
245
+ step,
246
+ success: assertions.every((a) => a.success),
247
+ duration: Date.now() - start,
248
+ request: { method: resolved.method, url, body },
249
+ response: { status: response.status, headers: response.headers, body: response.data },
250
+ captures,
251
+ assertions,
252
+ };
253
+ }
254
+ catch (error) {
255
+ return {
256
+ step,
257
+ success: false,
258
+ duration: Date.now() - start,
259
+ request: { method: step.request.method, url: step.request.url },
260
+ captures,
261
+ assertions,
262
+ error: error.message || String(error),
263
+ };
264
+ }
265
+ }
266
+ // -- Private helpers --
267
+ async poll(config, resolved, url, body, initial) {
268
+ const timeout = config.timeout || 30_000;
269
+ const interval = config.interval || 2_000;
270
+ const waitStart = Date.now();
271
+ let response = initial;
272
+ if (this.verbose) {
273
+ console.log(` ⏳ Polling ${config.path} ${config.operator} ${config.value !== undefined ? JSON.stringify(config.value) : ''} (max ${timeout}ms)`);
274
+ }
275
+ while (Date.now() - waitStart < timeout) {
276
+ const actual = extractValue(response.data, config.path);
277
+ let met = false;
278
+ switch (config.operator) {
279
+ case 'equals':
280
+ met = JSON.stringify(actual) === JSON.stringify(config.value);
281
+ break;
282
+ case 'notEquals':
283
+ met = JSON.stringify(actual) !== JSON.stringify(config.value);
284
+ break;
285
+ case 'exists':
286
+ met = actual !== undefined && actual !== null;
287
+ break;
288
+ case 'notExists':
289
+ met = actual === undefined || actual === null;
290
+ break;
291
+ }
292
+ if (met) {
293
+ if (this.verbose)
294
+ console.log(` ✅ Condition met: ${config.path} = ${JSON.stringify(actual)}`);
295
+ return response;
296
+ }
297
+ await new Promise((r) => setTimeout(r, interval));
298
+ response = await (0, axios_1.default)({
299
+ method: resolved.method,
300
+ url,
301
+ headers: resolved.headers,
302
+ data: body,
303
+ validateStatus: () => true,
304
+ });
305
+ if (this.verbose) {
306
+ console.log(` 🔄 Polling… (${Date.now() - waitStart}ms elapsed)`);
307
+ }
308
+ }
309
+ if (this.verbose)
310
+ console.log(` ⚠️ Timeout after ${Date.now() - waitStart}ms`);
311
+ return response;
312
+ }
313
+ async runAiAssertion(assertion, actual) {
314
+ if (!this.aiConfig) {
315
+ return {
316
+ assertion,
317
+ success: false,
318
+ actual,
319
+ message: assertion.message || 'AI evaluation requires Ollama configuration. See docs for setup.',
320
+ };
321
+ }
322
+ const evaluation = await (0, ai_js_1.evaluateWithAi)(this.aiConfig, actual, String(assertion.value));
323
+ return {
324
+ assertion,
325
+ success: evaluation.pass,
326
+ actual,
327
+ message: assertion.message || (evaluation.pass
328
+ ? `AI passed (${(evaluation.confidence * 100).toFixed(0)}%): ${evaluation.reason}`
329
+ : `AI failed: ${evaluation.reason}`),
330
+ };
331
+ }
332
+ resolveUrl(url) {
333
+ if (url.startsWith('http://') || url.startsWith('https://'))
334
+ return url;
335
+ const m = url.match(/^\{(\w+)\}(.*)$/);
336
+ if (m && this.context?.baseUrls[m[1]])
337
+ return this.context.baseUrls[m[1]] + m[2];
338
+ if (this.context?.baseUrls) {
339
+ const defaultBase = Object.values(this.context.baseUrls)[0];
340
+ if (defaultBase)
341
+ return defaultBase + url;
342
+ }
343
+ return url;
344
+ }
345
+ resolveVariables(obj) {
346
+ if (typeof obj === 'string') {
347
+ const result = this.interpolateStr(obj);
348
+ if (result.trim().startsWith('{') || result.trim().startsWith('[')) {
349
+ try {
350
+ return JSON.parse(result);
351
+ }
352
+ catch { /* keep string */ }
353
+ }
354
+ return result;
355
+ }
356
+ if (Array.isArray(obj))
357
+ return obj.map((item) => this.resolveVariables(item));
358
+ if (obj && typeof obj === 'object') {
359
+ const out = {};
360
+ for (const [k, v] of Object.entries(obj))
361
+ out[k] = this.resolveVariables(v);
362
+ return out;
363
+ }
364
+ return obj;
365
+ }
366
+ interpolateStr(str) {
367
+ return interpolate(str, this.variables);
368
+ }
369
+ parseJsonStrings(obj) {
370
+ if (typeof obj === 'string' && (obj.trim().startsWith('{') || obj.trim().startsWith('['))) {
371
+ try {
372
+ return JSON.parse(obj);
373
+ }
374
+ catch {
375
+ return obj;
376
+ }
377
+ }
378
+ if (Array.isArray(obj))
379
+ return obj.map((i) => this.parseJsonStrings(i));
380
+ if (obj && typeof obj === 'object') {
381
+ const out = {};
382
+ for (const [k, v] of Object.entries(obj))
383
+ out[k] = this.parseJsonStrings(v);
384
+ return out;
385
+ }
386
+ return obj;
387
+ }
388
+ }
389
+ exports.FlowExecutor = FlowExecutor;
390
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * testflow-ai
3
+ *
4
+ * Declarative API testing powered by YAML flows.
5
+ * Define test sequences in YAML, run them against any HTTP/GraphQL backend,
6
+ * capture variables between steps, and assert outcomes — with optional
7
+ * AI-powered evaluation via a local Ollama instance.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { runTests } from 'testflow-ai';
12
+ *
13
+ * const report = await runTests({
14
+ * contextFile: './context.md',
15
+ * testDir: './tests',
16
+ * format: 'console',
17
+ * });
18
+ *
19
+ * process.exit(report.failedFlows > 0 ? 1 : 0);
20
+ * ```
21
+ */
22
+ export type { ProjectContext, EndpointDefinition, AiContextConfig, TestFlow, TestStep, RequestDefinition, GraphQLRequest, CaptureDefinition, AssertionDefinition, WaitUntilConfig, FlowResult, StepResult, AssertionResult, TestReport, AiConfig, AiEvaluation, } from './types.js';
23
+ export { parseYaml, parseYamlFile, parseContext, parseContextFile, discoverTestFiles } from './parser.js';
24
+ export { FlowExecutor, extractValue, interpolate, evaluateAssertion } from './executor.js';
25
+ export { generateNarrative, generateTechnicalReport, printConsoleReport, toJSON, toMarkdown } from './reporter.js';
26
+ export { TestRunner, runTests, type RunnerOptions } from './runner.js';
27
+ export { evaluateWithAi, resolveAiConfig } from './ai.js';
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,UAAU,EACV,UAAU,EACV,eAAe,EACf,UAAU,EACV,QAAQ,EACR,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG1G,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAG3F,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGnH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAGvE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ /**
3
+ * testflow-ai
4
+ *
5
+ * Declarative API testing powered by YAML flows.
6
+ * Define test sequences in YAML, run them against any HTTP/GraphQL backend,
7
+ * capture variables between steps, and assert outcomes — with optional
8
+ * AI-powered evaluation via a local Ollama instance.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { runTests } from 'testflow-ai';
13
+ *
14
+ * const report = await runTests({
15
+ * contextFile: './context.md',
16
+ * testDir: './tests',
17
+ * format: 'console',
18
+ * });
19
+ *
20
+ * process.exit(report.failedFlows > 0 ? 1 : 0);
21
+ * ```
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.resolveAiConfig = exports.evaluateWithAi = exports.runTests = exports.TestRunner = exports.toMarkdown = exports.toJSON = exports.printConsoleReport = exports.generateTechnicalReport = exports.generateNarrative = exports.evaluateAssertion = exports.interpolate = exports.extractValue = exports.FlowExecutor = exports.discoverTestFiles = exports.parseContextFile = exports.parseContext = exports.parseYamlFile = exports.parseYaml = void 0;
25
+ // Parser
26
+ var parser_js_1 = require("./parser.js");
27
+ Object.defineProperty(exports, "parseYaml", { enumerable: true, get: function () { return parser_js_1.parseYaml; } });
28
+ Object.defineProperty(exports, "parseYamlFile", { enumerable: true, get: function () { return parser_js_1.parseYamlFile; } });
29
+ Object.defineProperty(exports, "parseContext", { enumerable: true, get: function () { return parser_js_1.parseContext; } });
30
+ Object.defineProperty(exports, "parseContextFile", { enumerable: true, get: function () { return parser_js_1.parseContextFile; } });
31
+ Object.defineProperty(exports, "discoverTestFiles", { enumerable: true, get: function () { return parser_js_1.discoverTestFiles; } });
32
+ // Executor
33
+ var executor_js_1 = require("./executor.js");
34
+ Object.defineProperty(exports, "FlowExecutor", { enumerable: true, get: function () { return executor_js_1.FlowExecutor; } });
35
+ Object.defineProperty(exports, "extractValue", { enumerable: true, get: function () { return executor_js_1.extractValue; } });
36
+ Object.defineProperty(exports, "interpolate", { enumerable: true, get: function () { return executor_js_1.interpolate; } });
37
+ Object.defineProperty(exports, "evaluateAssertion", { enumerable: true, get: function () { return executor_js_1.evaluateAssertion; } });
38
+ // Reporter
39
+ var reporter_js_1 = require("./reporter.js");
40
+ Object.defineProperty(exports, "generateNarrative", { enumerable: true, get: function () { return reporter_js_1.generateNarrative; } });
41
+ Object.defineProperty(exports, "generateTechnicalReport", { enumerable: true, get: function () { return reporter_js_1.generateTechnicalReport; } });
42
+ Object.defineProperty(exports, "printConsoleReport", { enumerable: true, get: function () { return reporter_js_1.printConsoleReport; } });
43
+ Object.defineProperty(exports, "toJSON", { enumerable: true, get: function () { return reporter_js_1.toJSON; } });
44
+ Object.defineProperty(exports, "toMarkdown", { enumerable: true, get: function () { return reporter_js_1.toMarkdown; } });
45
+ // Runner
46
+ var runner_js_1 = require("./runner.js");
47
+ Object.defineProperty(exports, "TestRunner", { enumerable: true, get: function () { return runner_js_1.TestRunner; } });
48
+ Object.defineProperty(exports, "runTests", { enumerable: true, get: function () { return runner_js_1.runTests; } });
49
+ // AI
50
+ var ai_js_1 = require("./ai.js");
51
+ Object.defineProperty(exports, "evaluateWithAi", { enumerable: true, get: function () { return ai_js_1.evaluateWithAi; } });
52
+ Object.defineProperty(exports, "resolveAiConfig", { enumerable: true, get: function () { return ai_js_1.resolveAiConfig; } });
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAsBH,SAAS;AACT,yCAA0G;AAAjG,sGAAA,SAAS,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,yGAAA,YAAY,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAEpF,WAAW;AACX,6CAA2F;AAAlF,2GAAA,YAAY,OAAA;AAAE,2GAAA,YAAY,OAAA;AAAE,0GAAA,WAAW,OAAA;AAAE,gHAAA,iBAAiB,OAAA;AAEnE,WAAW;AACX,6CAAmH;AAA1G,gHAAA,iBAAiB,OAAA;AAAE,sHAAA,uBAAuB,OAAA;AAAE,iHAAA,kBAAkB,OAAA;AAAE,qGAAA,MAAM,OAAA;AAAE,yGAAA,UAAU,OAAA;AAE3F,SAAS;AACT,yCAAuE;AAA9D,uGAAA,UAAU,OAAA;AAAE,qGAAA,QAAQ,OAAA;AAE7B,KAAK;AACL,iCAA0D;AAAjD,uGAAA,cAAc,OAAA;AAAE,wGAAA,eAAe,OAAA"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * YAML and Markdown parsers for test flows and project context.
3
+ */
4
+ import type { TestFlow, ProjectContext } from './types.js';
5
+ /** Parse a YAML string into a TestFlow. */
6
+ export declare function parseYaml(content: string): TestFlow;
7
+ /** Read and parse a YAML test file. */
8
+ export declare function parseYamlFile(filePath: string): Promise<TestFlow>;
9
+ /** Parse a markdown string into ProjectContext. */
10
+ export declare function parseContext(content: string, fallbackName?: string): ProjectContext;
11
+ /** Read and parse a markdown context file. */
12
+ export declare function parseContextFile(filePath: string): Promise<ProjectContext>;
13
+ /** Recursively find all `.yaml` / `.yml` test files in a directory. */
14
+ export declare function discoverTestFiles(dir: string): Promise<string[]>;
15
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAY,cAAc,EAAE,MAAM,YAAY,CAAC;AAIrE,2CAA2C;AAC3C,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAGnD;AAED,uCAAuC;AACvC,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAGvE;AA4CD,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,SAAQ,GAAG,cAAc,CAWlF;AAED,8CAA8C;AAC9C,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAGhF;AA6ED,uEAAuE;AACvE,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGtE"}