ai-evaluate 2.1.8 → 2.3.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.
Files changed (74) hide show
  1. package/README.md +16 -0
  2. package/dist/evaluate.d.ts.map +1 -1
  3. package/dist/evaluate.js +10 -10
  4. package/dist/evaluate.js.map +1 -1
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/miniflare-pool.d.ts.map +1 -1
  8. package/dist/miniflare-pool.js +1 -1
  9. package/dist/miniflare-pool.js.map +1 -1
  10. package/dist/node.d.ts.map +1 -1
  11. package/dist/node.js.map +1 -1
  12. package/dist/repl.js +6 -6
  13. package/dist/repl.js.map +1 -1
  14. package/dist/shared.d.ts.map +1 -1
  15. package/dist/shared.js +5 -2
  16. package/dist/shared.js.map +1 -1
  17. package/dist/static/index.d.ts +111 -0
  18. package/dist/static/index.d.ts.map +1 -0
  19. package/dist/static/index.js +347 -0
  20. package/dist/static/index.js.map +1 -0
  21. package/dist/type-guards.d.ts.map +1 -1
  22. package/dist/type-guards.js +64 -62
  23. package/dist/type-guards.js.map +1 -1
  24. package/dist/worker-template/core.d.ts.map +1 -1
  25. package/dist/worker-template/core.js +1 -1
  26. package/dist/worker-template/core.js.map +1 -1
  27. package/package.json +19 -6
  28. package/public/capnweb.mjs +220 -0
  29. package/public/index.mjs +426 -0
  30. package/public/scaffold.mjs +198 -0
  31. package/.turbo/turbo-build.log +0 -4
  32. package/.turbo/turbo-test.log +0 -54
  33. package/.turbo/turbo-typecheck.log +0 -4
  34. package/CHANGELOG.md +0 -48
  35. package/dist/worker-template.d.ts +0 -41
  36. package/dist/worker-template.d.ts.map +0 -1
  37. package/dist/worker-template.js +0 -3748
  38. package/dist/worker-template.js.map +0 -1
  39. package/example/package.json +0 -20
  40. package/example/src/index.ts +0 -221
  41. package/example/wrangler.jsonc +0 -25
  42. package/src/capnweb-bundle.ts +0 -2596
  43. package/src/evaluate.ts +0 -329
  44. package/src/index.ts +0 -23
  45. package/src/miniflare-pool.ts +0 -395
  46. package/src/node.ts +0 -245
  47. package/src/repl.ts +0 -228
  48. package/src/shared.ts +0 -186
  49. package/src/type-guards.ts +0 -323
  50. package/src/types.ts +0 -196
  51. package/src/validation.ts +0 -120
  52. package/src/worker-template/code-transforms.ts +0 -32
  53. package/src/worker-template/core.ts +0 -557
  54. package/src/worker-template/helpers.ts +0 -90
  55. package/src/worker-template/index.ts +0 -23
  56. package/src/worker-template/sdk-generator.ts +0 -2515
  57. package/src/worker-template/test-generator.ts +0 -358
  58. package/test/evaluate-extended.test.js +0 -429
  59. package/test/evaluate-extended.test.ts +0 -469
  60. package/test/evaluate.test.js +0 -235
  61. package/test/evaluate.test.ts +0 -253
  62. package/test/index.test.js +0 -77
  63. package/test/index.test.ts +0 -95
  64. package/test/miniflare-pool.test.ts +0 -246
  65. package/test/node.test.ts +0 -467
  66. package/test/security.test.ts +0 -1009
  67. package/test/shared.test.ts +0 -105
  68. package/test/type-guards.test.ts +0 -303
  69. package/test/validation.test.ts +0 -240
  70. package/test/worker-template.test.js +0 -365
  71. package/test/worker-template.test.ts +0 -432
  72. package/tsconfig.json +0 -22
  73. package/vitest.config.js +0 -21
  74. package/vitest.config.ts +0 -28
@@ -0,0 +1,426 @@
1
+ /**
2
+ * ai-evaluate v2.2.0
3
+ * Static worker template for evaluate.workers.do
4
+ * Generated: 2026-05-26T11:50:49.389Z
5
+ *
6
+ * @license MIT
7
+ */
8
+
9
+ // Full worker template with capnweb RPC support
10
+ // Import capnweb from the capnweb.js module
11
+
12
+ import { RpcTarget, newWorkersRpcResponse } from 'capnweb.js';
13
+
14
+ const logs = [];
15
+
16
+
17
+ // ============================================================
18
+ // Global .should Chainable Assertions
19
+ // ============================================================
20
+
21
+ const __createShouldChain__ = (actual, negated = false) => {
22
+ const check = (condition, message) => {
23
+ const passes = negated ? !condition : condition;
24
+ if (!passes) throw new Error(negated ? 'Expected NOT: ' + message : message);
25
+ };
26
+
27
+ const stringify = (val) => {
28
+ try {
29
+ return JSON.stringify(val);
30
+ } catch {
31
+ return String(val);
32
+ }
33
+ };
34
+
35
+ // Create a lazy chain getter - returns 'this' assertion for chaining
36
+ const assertion = {};
37
+
38
+ // Core assertion methods
39
+ assertion.equal = (expected) => {
40
+ check(actual === expected, 'Expected ' + stringify(actual) + ' to equal ' + stringify(expected));
41
+ return assertion;
42
+ };
43
+ assertion.deep = {
44
+ equal: (expected) => {
45
+ check(stringify(actual) === stringify(expected), 'Expected deep equal to ' + stringify(expected));
46
+ return assertion;
47
+ },
48
+ include: (expected) => {
49
+ const actualStr = stringify(actual);
50
+ const expectedStr = stringify(expected);
51
+ // Check if expected properties exist with same values
52
+ const matches = Object.entries(expected || {}).every(([k, v]) =>
53
+ actual && stringify(actual[k]) === stringify(v)
54
+ );
55
+ check(matches, 'Expected ' + actualStr + ' to deeply include ' + expectedStr);
56
+ return assertion;
57
+ }
58
+ };
59
+ assertion.include = (value) => {
60
+ if (typeof actual === 'string') check(actual.includes(String(value)), 'Expected "' + actual + '" to include "' + value + '"');
61
+ else if (Array.isArray(actual)) check(actual.includes(value), 'Expected array to include ' + stringify(value));
62
+ return assertion;
63
+ };
64
+ assertion.contain = assertion.include;
65
+ assertion.lengthOf = (n) => {
66
+ check(actual?.length === n, 'Expected length ' + n + ', got ' + actual?.length);
67
+ return assertion;
68
+ };
69
+ assertion.match = (regex) => {
70
+ const str = String(actual);
71
+ check(regex.test(str), 'Expected "' + str + '" to match ' + regex);
72
+ return assertion;
73
+ };
74
+ assertion.matches = assertion.match;
75
+
76
+ // .be accessor with type checks
77
+ Object.defineProperty(assertion, 'be', {
78
+ get: () => {
79
+ const beObj = {
80
+ a: (type) => {
81
+ const actualType = actual === null ? 'null' : Array.isArray(actual) ? 'array' : actual instanceof Date ? 'date' : typeof actual;
82
+ check(actualType === type.toLowerCase(), 'Expected ' + stringify(actual) + ' to be a ' + type);
83
+ return assertion;
84
+ },
85
+ above: (n) => { check(actual > n, 'Expected ' + actual + ' to be above ' + n); return assertion; },
86
+ below: (n) => { check(actual < n, 'Expected ' + actual + ' to be below ' + n); return assertion; },
87
+ within: (min, max) => { check(actual >= min && actual <= max, 'Expected ' + actual + ' to be within ' + min + '..' + max); return assertion; },
88
+ oneOf: (arr) => { check(Array.isArray(arr) && arr.includes(actual), 'Expected ' + stringify(actual) + ' to be one of ' + stringify(arr)); return assertion; },
89
+ instanceOf: (cls) => { check(actual instanceof cls, 'Expected to be instance of ' + cls.name); return assertion; }
90
+ };
91
+ beObj.an = beObj.a;
92
+ Object.defineProperty(beObj, 'true', { get: () => { check(actual === true, 'Expected ' + stringify(actual) + ' to be true'); return assertion; } });
93
+ Object.defineProperty(beObj, 'false', { get: () => { check(actual === false, 'Expected ' + stringify(actual) + ' to be false'); return assertion; } });
94
+ Object.defineProperty(beObj, 'ok', { get: () => { check(!!actual, 'Expected ' + stringify(actual) + ' to be truthy'); return assertion; } });
95
+ Object.defineProperty(beObj, 'null', { get: () => { check(actual === null, 'Expected ' + stringify(actual) + ' to be null'); return assertion; } });
96
+ Object.defineProperty(beObj, 'undefined', { get: () => { check(actual === undefined, 'Expected ' + stringify(actual) + ' to be undefined'); return assertion; } });
97
+ Object.defineProperty(beObj, 'empty', { get: () => {
98
+ const isEmpty = actual === '' || (Array.isArray(actual) && actual.length === 0) || (actual && typeof actual === 'object' && Object.keys(actual).length === 0);
99
+ check(isEmpty, 'Expected ' + stringify(actual) + ' to be empty');
100
+ return assertion;
101
+ }});
102
+ return beObj;
103
+ }
104
+ });
105
+
106
+ // .have accessor with property/keys/lengthOf/at checks
107
+ Object.defineProperty(assertion, 'have', {
108
+ get: () => ({
109
+ property: (name, value) => {
110
+ const hasIt = actual != null && Object.prototype.hasOwnProperty.call(actual, name);
111
+ if (value !== undefined) {
112
+ check(hasIt && actual[name] === value, "Expected property '" + name + "' = " + stringify(value) + ", got " + stringify(actual?.[name]));
113
+ } else {
114
+ check(hasIt, "Expected to have property '" + name + "'");
115
+ }
116
+ if (hasIt) return __createShouldChain__(actual[name], negated);
117
+ return assertion;
118
+ },
119
+ keys: (...keys) => {
120
+ const actualKeys = Object.keys(actual || {});
121
+ check(keys.every(k => actualKeys.includes(k)), 'Expected to have keys ' + stringify(keys));
122
+ return assertion;
123
+ },
124
+ lengthOf: (n) => {
125
+ check(actual?.length === n, 'Expected length ' + n + ', got ' + actual?.length);
126
+ return assertion;
127
+ },
128
+ at: {
129
+ least: (n) => {
130
+ check(actual?.length >= n, 'Expected length at least ' + n + ', got ' + actual?.length);
131
+ return assertion;
132
+ },
133
+ most: (n) => {
134
+ check(actual?.length <= n, 'Expected length at most ' + n + ', got ' + actual?.length);
135
+ return assertion;
136
+ }
137
+ }
138
+ })
139
+ });
140
+
141
+ // .not negation
142
+ Object.defineProperty(assertion, 'not', {
143
+ get: () => __createShouldChain__(actual, !negated)
144
+ });
145
+
146
+ // .with passthrough for readability
147
+ Object.defineProperty(assertion, 'with', {
148
+ get: () => assertion
149
+ });
150
+
151
+ // .that passthrough for chaining (e.g. .have.property('x').that.matches(/.../) )
152
+ Object.defineProperty(assertion, 'that', {
153
+ get: () => assertion
154
+ });
155
+
156
+ // .and passthrough for chaining
157
+ Object.defineProperty(assertion, 'and', {
158
+ get: () => assertion
159
+ });
160
+
161
+ return assertion;
162
+ };
163
+
164
+ // Add .should to Object.prototype
165
+ Object.defineProperty(Object.prototype, 'should', {
166
+ get: function() { return __createShouldChain__(this); },
167
+ configurable: true,
168
+ enumerable: false
169
+ });
170
+
171
+
172
+ // Capture console output
173
+ const originalConsole = { ...console };
174
+ const captureConsole = (level) => (...args) => {
175
+ logs.push({
176
+ level,
177
+ message: args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '),
178
+ timestamp: Date.now()
179
+ });
180
+ originalConsole[level](...args);
181
+ };
182
+ console.log = captureConsole('log');
183
+ console.warn = captureConsole('warn');
184
+ console.error = captureConsole('error');
185
+ console.info = captureConsole('info');
186
+ console.debug = captureConsole('debug');
187
+
188
+
189
+ // Test framework (vitest-compatible API)
190
+ let currentDescribe = '';
191
+ let beforeEachFns = [];
192
+ let afterEachFns = [];
193
+
194
+ const describe = (name, fn) => {
195
+ const prev = currentDescribe;
196
+ const prevBeforeEach = [...beforeEachFns];
197
+ const prevAfterEach = [...afterEachFns];
198
+ currentDescribe = currentDescribe ? currentDescribe + ' > ' + name : name;
199
+ try { fn(); } finally {
200
+ currentDescribe = prev;
201
+ beforeEachFns = prevBeforeEach;
202
+ afterEachFns = prevAfterEach;
203
+ }
204
+ };
205
+
206
+ // Hooks
207
+ const beforeEach = (fn) => { beforeEachFns.push(fn); };
208
+ const afterEach = (fn) => { afterEachFns.push(fn); };
209
+
210
+ const it = (name, fn) => {
211
+ const fullName = currentDescribe ? currentDescribe + ' > ' + name : name;
212
+ const hooks = { before: [...beforeEachFns], after: [...afterEachFns] };
213
+ pendingTests.push({ name: fullName, fn, hooks });
214
+ };
215
+ const test = it;
216
+
217
+ it.skip = (name, fn) => {
218
+ const fullName = currentDescribe ? currentDescribe + ' > ' + name : name;
219
+ pendingTests.push({ name: fullName, fn: null, skip: true });
220
+ };
221
+ test.skip = it.skip;
222
+
223
+ it.only = (name, fn) => {
224
+ const fullName = currentDescribe ? currentDescribe + ' > ' + name : name;
225
+ const hooks = { before: [...beforeEachFns], after: [...afterEachFns] };
226
+ pendingTests.push({ name: fullName, fn, hooks, only: true });
227
+ };
228
+ test.only = it.only;
229
+
230
+ // Deep equality check
231
+ const deepEqual = (a, b) => {
232
+ if (a === b) return true;
233
+ if (a == null || b == null) return false;
234
+ if (typeof a !== typeof b) return false;
235
+ if (typeof a !== 'object') return false;
236
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
237
+ if (Array.isArray(a)) {
238
+ if (a.length !== b.length) return false;
239
+ return a.every((v, i) => deepEqual(v, b[i]));
240
+ }
241
+ const keysA = Object.keys(a);
242
+ const keysB = Object.keys(b);
243
+ if (keysA.length !== keysB.length) return false;
244
+ return keysA.every(k => deepEqual(a[k], b[k]));
245
+ };
246
+
247
+ // Expect implementation with vitest-compatible matchers
248
+ const expect = (actual) => {
249
+ const matchers = {
250
+ toBe: (expected) => {
251
+ if (actual !== expected) {
252
+ throw new Error(\
253
+
254
+ // Module exports object
255
+ const exports = {};
256
+ const pendingTests = [];
257
+ const testResults = { total: 0, passed: 0, failed: 0, skipped: 0, tests: [], duration: 0 };
258
+
259
+ // ============================================================
260
+ // USER CODE PLACEHOLDER
261
+ // ============================================================
262
+ // USER_MODULE_CODE
263
+ // USER_TEST_CODE
264
+
265
+ // ============================================================
266
+ // RPC SERVER - Expose exports via capnweb
267
+ // ============================================================
268
+ class ExportsRpcTarget extends RpcTarget {
269
+ constructor() {
270
+ super();
271
+ for (const [key, value] of Object.entries(exports)) {
272
+ if (typeof value === 'function') {
273
+ this[key] = value;
274
+ }
275
+ }
276
+ }
277
+
278
+ list() {
279
+ return Object.keys(exports);
280
+ }
281
+
282
+ get(name) {
283
+ return exports[name];
284
+ }
285
+ }
286
+
287
+ // ============================================================
288
+ // WORKER ENTRY POINT
289
+ // ============================================================
290
+ export default {
291
+ async fetch(request, env) {
292
+ const url = new URL(request.url);
293
+
294
+ // Route: GET / - Return info about exports
295
+ if (request.method === 'GET' && url.pathname === '/') {
296
+ return Response.json({
297
+ exports: Object.keys(exports),
298
+ rpc: '/rpc',
299
+ execute: '/execute'
300
+ });
301
+ }
302
+
303
+ // Route: /rpc - capnweb RPC to module exports
304
+ if (url.pathname === '/rpc') {
305
+ return newWorkersRpcResponse(request, new ExportsRpcTarget());
306
+ }
307
+
308
+ // Route: GET /:name - Simple JSON endpoint to access exports
309
+ if (request.method === 'GET' && url.pathname !== '/execute') {
310
+ const name = url.pathname.slice(1);
311
+ const value = exports[name];
312
+
313
+ if (!(name in exports)) {
314
+ return Response.json({ error: `Export "${name}" not found` }, { status: 404 });
315
+ }
316
+
317
+ if (typeof value !== 'function') {
318
+ return Response.json({ result: value });
319
+ }
320
+
321
+ try {
322
+ const args = [];
323
+ const argsParam = url.searchParams.get('args');
324
+ if (argsParam) {
325
+ try {
326
+ const parsed = JSON.parse(argsParam);
327
+ if (Array.isArray(parsed)) args.push(...parsed);
328
+ else args.push(parsed);
329
+ } catch {
330
+ args.push(argsParam);
331
+ }
332
+ } else {
333
+ const params = Object.fromEntries(url.searchParams.entries());
334
+ if (Object.keys(params).length > 0) {
335
+ for (const [key, val] of Object.entries(params)) {
336
+ const num = Number(val);
337
+ params[key] = !isNaN(num) && val !== '' ? num : val;
338
+ }
339
+ args.push(params);
340
+ }
341
+ }
342
+ const result = await value(...args);
343
+ return Response.json({ result });
344
+ } catch (e) {
345
+ return Response.json({ error: e.message }, { status: 500 });
346
+ }
347
+ }
348
+
349
+ // Route: /execute - Run tests and scripts
350
+ let scriptResult = undefined;
351
+ let scriptError = null;
352
+
353
+ // USER_SCRIPT_CODE
354
+
355
+
356
+ // Run all pending tests
357
+ const testStart = Date.now();
358
+ const hasOnly = pendingTests.some(t => t.only);
359
+ const testsToRun = hasOnly ? pendingTests.filter(t => t.only || t.skip) : pendingTests;
360
+
361
+ for (const { name, fn, hooks, skip } of testsToRun) {
362
+ testResults.total++;
363
+
364
+ if (skip) {
365
+ testResults.skipped++;
366
+ testResults.tests.push({ name, passed: true, skipped: true, duration: 0 });
367
+ continue;
368
+ }
369
+
370
+ const start = Date.now();
371
+ try {
372
+ // Run beforeEach hooks
373
+ if (hooks?.before) {
374
+ for (const hook of hooks.before) {
375
+ const hookResult = hook();
376
+ if (hookResult && typeof hookResult.then === 'function') {
377
+ await hookResult;
378
+ }
379
+ }
380
+ }
381
+
382
+ // Run the test
383
+ const result = fn();
384
+ if (result && typeof result.then === 'function') {
385
+ await result;
386
+ }
387
+
388
+ // Run afterEach hooks
389
+ if (hooks?.after) {
390
+ for (const hook of hooks.after) {
391
+ const hookResult = hook();
392
+ if (hookResult && typeof hookResult.then === 'function') {
393
+ await hookResult;
394
+ }
395
+ }
396
+ }
397
+
398
+ testResults.passed++;
399
+ testResults.tests.push({ name, passed: true, duration: Date.now() - start });
400
+ } catch (e) {
401
+ testResults.failed++;
402
+ testResults.tests.push({
403
+ name,
404
+ passed: false,
405
+ error: e.message || String(e),
406
+ duration: Date.now() - start
407
+ });
408
+ }
409
+ }
410
+
411
+ testResults.duration = Date.now() - testStart;
412
+
413
+
414
+ const hasTests = pendingTests.length > 0;
415
+ const success = scriptError === null && (!hasTests || testResults.failed === 0);
416
+
417
+ return Response.json({
418
+ success,
419
+ value: scriptResult,
420
+ logs,
421
+ testResults: hasTests ? testResults : undefined,
422
+ error: scriptError || undefined,
423
+ duration: 0
424
+ });
425
+ }
426
+ };
@@ -0,0 +1,198 @@
1
+ /**
2
+ * ai-evaluate v2.2.0
3
+ * Static worker template for evaluate.workers.do
4
+ * Generated: 2026-05-26T11:50:49.389Z
5
+ *
6
+ * @license MIT
7
+ */
8
+
9
+ // Base worker scaffold without capnweb dependency
10
+ // Use this for dev mode or when capnweb is not needed
11
+
12
+ const logs = [];
13
+
14
+ // Capture console output
15
+ const originalConsole = { ...console };
16
+ const captureConsole = (level) => (...args) => {
17
+ logs.push({
18
+ level,
19
+ message: args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '),
20
+ timestamp: Date.now()
21
+ });
22
+ originalConsole[level](...args);
23
+ };
24
+ console.log = captureConsole('log');
25
+ console.warn = captureConsole('warn');
26
+ console.error = captureConsole('error');
27
+ console.info = captureConsole('info');
28
+ console.debug = captureConsole('debug');
29
+
30
+
31
+ // Test framework (vitest-compatible API)
32
+ let currentDescribe = '';
33
+ let beforeEachFns = [];
34
+ let afterEachFns = [];
35
+
36
+ const describe = (name, fn) => {
37
+ const prev = currentDescribe;
38
+ const prevBeforeEach = [...beforeEachFns];
39
+ const prevAfterEach = [...afterEachFns];
40
+ currentDescribe = currentDescribe ? currentDescribe + ' > ' + name : name;
41
+ try { fn(); } finally {
42
+ currentDescribe = prev;
43
+ beforeEachFns = prevBeforeEach;
44
+ afterEachFns = prevAfterEach;
45
+ }
46
+ };
47
+
48
+ // Hooks
49
+ const beforeEach = (fn) => { beforeEachFns.push(fn); };
50
+ const afterEach = (fn) => { afterEachFns.push(fn); };
51
+
52
+ const it = (name, fn) => {
53
+ const fullName = currentDescribe ? currentDescribe + ' > ' + name : name;
54
+ const hooks = { before: [...beforeEachFns], after: [...afterEachFns] };
55
+ pendingTests.push({ name: fullName, fn, hooks });
56
+ };
57
+ const test = it;
58
+
59
+ it.skip = (name, fn) => {
60
+ const fullName = currentDescribe ? currentDescribe + ' > ' + name : name;
61
+ pendingTests.push({ name: fullName, fn: null, skip: true });
62
+ };
63
+ test.skip = it.skip;
64
+
65
+ it.only = (name, fn) => {
66
+ const fullName = currentDescribe ? currentDescribe + ' > ' + name : name;
67
+ const hooks = { before: [...beforeEachFns], after: [...afterEachFns] };
68
+ pendingTests.push({ name: fullName, fn, hooks, only: true });
69
+ };
70
+ test.only = it.only;
71
+
72
+ // Deep equality check
73
+ const deepEqual = (a, b) => {
74
+ if (a === b) return true;
75
+ if (a == null || b == null) return false;
76
+ if (typeof a !== typeof b) return false;
77
+ if (typeof a !== 'object') return false;
78
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
79
+ if (Array.isArray(a)) {
80
+ if (a.length !== b.length) return false;
81
+ return a.every((v, i) => deepEqual(v, b[i]));
82
+ }
83
+ const keysA = Object.keys(a);
84
+ const keysB = Object.keys(b);
85
+ if (keysA.length !== keysB.length) return false;
86
+ return keysA.every(k => deepEqual(a[k], b[k]));
87
+ };
88
+
89
+ // Expect implementation with vitest-compatible matchers
90
+ const expect = (actual) => {
91
+ const matchers = {
92
+ toBe: (expected) => {
93
+ if (actual !== expected) {
94
+ throw new Error(\
95
+
96
+ // Module exports object
97
+ const exports = {};
98
+ const pendingTests = [];
99
+ const testResults = { total: 0, passed: 0, failed: 0, skipped: 0, tests: [], duration: 0 };
100
+
101
+ // ============================================================
102
+ // USER CODE PLACEHOLDER
103
+ // ============================================================
104
+ // USER_MODULE_CODE
105
+ // USER_TEST_CODE
106
+ // USER_SCRIPT_CODE
107
+
108
+ // ============================================================
109
+ // WORKER ENTRY POINT
110
+ // ============================================================
111
+ export default {
112
+ async fetch(request, env) {
113
+ const url = new URL(request.url);
114
+
115
+ // Route: GET / - Return info
116
+ if (request.method === 'GET' && url.pathname === '/') {
117
+ return Response.json({
118
+ exports: Object.keys(exports),
119
+ execute: '/execute'
120
+ });
121
+ }
122
+
123
+ // Route: /execute - Run tests and scripts
124
+ let scriptResult = undefined;
125
+ let scriptError = null;
126
+
127
+
128
+ // Run all pending tests
129
+ const testStart = Date.now();
130
+ const hasOnly = pendingTests.some(t => t.only);
131
+ const testsToRun = hasOnly ? pendingTests.filter(t => t.only || t.skip) : pendingTests;
132
+
133
+ for (const { name, fn, hooks, skip } of testsToRun) {
134
+ testResults.total++;
135
+
136
+ if (skip) {
137
+ testResults.skipped++;
138
+ testResults.tests.push({ name, passed: true, skipped: true, duration: 0 });
139
+ continue;
140
+ }
141
+
142
+ const start = Date.now();
143
+ try {
144
+ // Run beforeEach hooks
145
+ if (hooks?.before) {
146
+ for (const hook of hooks.before) {
147
+ const hookResult = hook();
148
+ if (hookResult && typeof hookResult.then === 'function') {
149
+ await hookResult;
150
+ }
151
+ }
152
+ }
153
+
154
+ // Run the test
155
+ const result = fn();
156
+ if (result && typeof result.then === 'function') {
157
+ await result;
158
+ }
159
+
160
+ // Run afterEach hooks
161
+ if (hooks?.after) {
162
+ for (const hook of hooks.after) {
163
+ const hookResult = hook();
164
+ if (hookResult && typeof hookResult.then === 'function') {
165
+ await hookResult;
166
+ }
167
+ }
168
+ }
169
+
170
+ testResults.passed++;
171
+ testResults.tests.push({ name, passed: true, duration: Date.now() - start });
172
+ } catch (e) {
173
+ testResults.failed++;
174
+ testResults.tests.push({
175
+ name,
176
+ passed: false,
177
+ error: e.message || String(e),
178
+ duration: Date.now() - start
179
+ });
180
+ }
181
+ }
182
+
183
+ testResults.duration = Date.now() - testStart;
184
+
185
+
186
+ const hasTests = pendingTests.length > 0;
187
+ const success = scriptError === null && (!hasTests || testResults.failed === 0);
188
+
189
+ return Response.json({
190
+ success,
191
+ value: scriptResult,
192
+ logs,
193
+ testResults: hasTests ? testResults : undefined,
194
+ error: scriptError || undefined,
195
+ duration: 0
196
+ });
197
+ }
198
+ };
@@ -1,4 +0,0 @@
1
-
2
- > ai-evaluate@2.1.4 build /Users/nathanclevenger/projects/primitives.org.ai/packages/ai-evaluate
3
- > tsc -p tsconfig.json
4
-
@@ -1,54 +0,0 @@
1
-
2
- > ai-evaluate@2.1.3 test /Users/nathanclevenger/projects/primitives.org.ai/packages/ai-evaluate
3
- > vitest
4
-
5
-
6
- DEV v2.1.9 /Users/nathanclevenger/projects/primitives.org.ai/packages/ai-evaluate
7
-
8
- ✓ test/worker-template.test.ts (65 tests) 7ms
9
- stdout | test/evaluate.test.ts > evaluate > script execution > captures console output
10
- hello
11
-
12
- stderr | test/evaluate.test.ts > evaluate > script execution > captures console output
13
- warning
14
- error
15
-
16
- stdout | test/index.test.ts > types > LogEntry has correct shape
17
- test
18
-
19
- stderr | test/evaluate.test.ts > evaluate > script execution > handles script errors
20
- Script error: test error
21
-
22
- ✓ test/index.test.ts (8 tests) 1959ms
23
- ✓ types > EvaluateOptions interface is usable 1765ms
24
- stderr | test/evaluate-extended.test.ts > evaluate - extended tests > module errors > captures module runtime errors
25
- Module error: module error
26
-
27
- stdout | test/evaluate-extended.test.ts > evaluate - extended tests > console methods > captures console.info
28
- info message
29
-
30
- stdout | test/evaluate-extended.test.ts > evaluate - extended tests > console methods > captures console.debug
31
- debug message
32
-
33
- stdout | test/evaluate-extended.test.ts > evaluate - extended tests > console methods > stringifies objects in console output
34
- { a: 1 }
35
-
36
- stdout | test/evaluate-extended.test.ts > evaluate - extended tests > console methods > joins multiple console arguments
37
- a b c
38
-
39
- stderr | test/evaluate-extended.test.ts > evaluate - extended tests > async scripts > handles Promise rejection in script
40
- Script error: async error
41
-
42
- ✓ test/evaluate.test.ts (18 tests) 2319ms
43
- ✓ evaluate > script execution > executes simple expressions 1762ms
44
- ✓ test/evaluate-extended.test.ts (40 tests) 2896ms
45
- ✓ evaluate - extended tests > edge cases > handles empty options 1762ms
46
-
47
- Test Files 4 passed (4)
48
- Tests 131 passed (131)
49
- Start at 16:04:47
50
- Duration 3.30s (transform 119ms, setup 0ms, collect 216ms, tests 7.18s, environment 0ms, prepare 174ms)
51
-
52
- PASS Waiting for file changes...
53
- press h to show help, press q to quit
54
-  ELIFECYCLE  Test failed. See above for more details.
@@ -1,4 +0,0 @@
1
-
2
- > ai-evaluate@2.1.3 typecheck /Users/nathanclevenger/projects/primitives.org.ai/packages/ai-evaluate
3
- > tsc --noEmit
4
-