ai-evaluate 2.1.7 → 2.2.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 +61 -4
- package/dist/evaluate.d.ts.map +1 -1
- package/dist/evaluate.js +18 -16
- package/dist/evaluate.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/miniflare-pool.d.ts +109 -0
- package/dist/miniflare-pool.d.ts.map +1 -0
- package/dist/miniflare-pool.js +308 -0
- package/dist/miniflare-pool.js.map +1 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +42 -10
- package/dist/node.js.map +1 -1
- package/dist/shared.d.ts +66 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +169 -0
- package/dist/shared.js.map +1 -0
- package/dist/static/index.d.ts +111 -0
- package/dist/static/index.d.ts.map +1 -0
- package/dist/static/index.js +347 -0
- package/dist/static/index.js.map +1 -0
- package/dist/type-guards.d.ts +21 -0
- package/dist/type-guards.d.ts.map +1 -0
- package/dist/type-guards.js +216 -0
- package/dist/type-guards.js.map +1 -0
- package/dist/types.d.ts +17 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/validation.d.ts +26 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +104 -0
- package/dist/validation.js.map +1 -0
- package/dist/worker-template/code-transforms.d.ts +9 -0
- package/dist/worker-template/code-transforms.d.ts.map +1 -0
- package/dist/worker-template/code-transforms.js +28 -0
- package/dist/worker-template/code-transforms.js.map +1 -0
- package/{src/worker-template.d.ts → dist/worker-template/core.d.ts} +7 -15
- package/dist/worker-template/core.d.ts.map +1 -0
- package/dist/worker-template/core.js +502 -0
- package/dist/worker-template/core.js.map +1 -0
- package/dist/worker-template/helpers.d.ts +14 -0
- package/dist/worker-template/helpers.d.ts.map +1 -0
- package/dist/worker-template/helpers.js +79 -0
- package/dist/worker-template/helpers.js.map +1 -0
- package/dist/worker-template/index.d.ts +14 -0
- package/dist/worker-template/index.d.ts.map +1 -0
- package/dist/worker-template/index.js +19 -0
- package/dist/worker-template/index.js.map +1 -0
- package/dist/worker-template/sdk-generator.d.ts +17 -0
- package/dist/worker-template/sdk-generator.d.ts.map +1 -0
- package/{src/worker-template.js → dist/worker-template/sdk-generator.js} +377 -1506
- package/dist/worker-template/sdk-generator.js.map +1 -0
- package/dist/worker-template/test-generator.d.ts +16 -0
- package/dist/worker-template/test-generator.d.ts.map +1 -0
- package/dist/worker-template/test-generator.js +357 -0
- package/dist/worker-template/test-generator.js.map +1 -0
- package/dist/worker-template.d.ts +2 -2
- package/dist/worker-template.d.ts.map +1 -1
- package/dist/worker-template.js +22 -10
- package/dist/worker-template.js.map +1 -1
- package/package.json +17 -6
- package/public/capnweb.mjs +220 -0
- package/public/index.mjs +426 -0
- package/public/scaffold.mjs +198 -0
- package/.turbo/turbo-build.log +0 -4
- package/.turbo/turbo-test.log +0 -54
- package/.turbo/turbo-typecheck.log +0 -4
- package/CHANGELOG.md +0 -48
- package/example/package.json +0 -20
- package/example/src/index.ts +0 -214
- package/example/wrangler.jsonc +0 -25
- package/src/capnweb-bundle.ts +0 -2596
- package/src/evaluate.js +0 -187
- package/src/evaluate.ts +0 -325
- package/src/index.js +0 -10
- package/src/index.ts +0 -21
- package/src/node.d.ts +0 -17
- package/src/node.d.ts.map +0 -1
- package/src/node.js +0 -168
- package/src/node.js.map +0 -1
- package/src/node.ts +0 -200
- package/src/repl.ts +0 -228
- package/src/types.d.ts +0 -172
- package/src/types.d.ts.map +0 -1
- package/src/types.js +0 -4
- package/src/types.js.map +0 -1
- package/src/types.ts +0 -180
- package/src/worker-template.d.ts.map +0 -1
- package/src/worker-template.js.map +0 -1
- package/src/worker-template.ts +0 -3806
- package/test/evaluate-extended.test.js +0 -429
- package/test/evaluate-extended.test.ts +0 -469
- package/test/evaluate.test.js +0 -235
- package/test/evaluate.test.ts +0 -253
- package/test/index.test.js +0 -77
- package/test/index.test.ts +0 -95
- package/test/worker-template.test.js +0 -365
- package/test/worker-template.test.ts +0 -430
- package/tsconfig.json +0 -22
- package/vitest.config.js +0 -21
- package/vitest.config.ts +0 -28
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ai-evaluate v2.1.8
|
|
3
|
+
* Static worker template for evaluate.workers.do
|
|
4
|
+
* Generated: 2026-01-26T01:42:47.000Z
|
|
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
|
+
};
|
package/.turbo/turbo-build.log
DELETED
package/.turbo/turbo-test.log
DELETED
|
@@ -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.
|
package/CHANGELOG.md
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# ai-evaluate
|
|
2
|
-
|
|
3
|
-
## 2.1.3
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- Documentation and testing improvements
|
|
8
|
-
- Add deterministic AI testing suite with self-validating patterns
|
|
9
|
-
- Apply StoryBrand narrative to all package READMEs
|
|
10
|
-
- Update TESTING.md with four principles of deterministic AI testing
|
|
11
|
-
- Fix duplicate examples package name conflict
|
|
12
|
-
|
|
13
|
-
- Updated dependencies
|
|
14
|
-
- ai-functions@2.1.3
|
|
15
|
-
- ai-tests@2.1.3
|
|
16
|
-
|
|
17
|
-
## 2.1.1
|
|
18
|
-
|
|
19
|
-
### Patch Changes
|
|
20
|
-
|
|
21
|
-
- Updated dependencies [6beb531]
|
|
22
|
-
- ai-functions@2.1.1
|
|
23
|
-
- ai-tests@2.1.1
|
|
24
|
-
|
|
25
|
-
## 2.0.3
|
|
26
|
-
|
|
27
|
-
### Patch Changes
|
|
28
|
-
|
|
29
|
-
- Updated dependencies
|
|
30
|
-
- rpc.do@0.2.0
|
|
31
|
-
- ai-functions@2.0.3
|
|
32
|
-
- ai-tests@2.0.3
|
|
33
|
-
|
|
34
|
-
## 2.0.2
|
|
35
|
-
|
|
36
|
-
### Patch Changes
|
|
37
|
-
|
|
38
|
-
- Updated dependencies
|
|
39
|
-
- ai-functions@2.0.2
|
|
40
|
-
- ai-tests@2.0.2
|
|
41
|
-
|
|
42
|
-
## 2.0.1
|
|
43
|
-
|
|
44
|
-
### Patch Changes
|
|
45
|
-
|
|
46
|
-
- Updated dependencies
|
|
47
|
-
- ai-functions@2.0.1
|
|
48
|
-
- ai-tests@2.0.1
|
package/example/package.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "eval-workers-do",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"private": true,
|
|
5
|
-
"description": "ai-evaluate REST API Worker for eval.workers.do",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"dev": "wrangler dev",
|
|
9
|
-
"deploy": "wrangler deploy",
|
|
10
|
-
"typecheck": "tsc --noEmit"
|
|
11
|
-
},
|
|
12
|
-
"dependencies": {
|
|
13
|
-
"ai-evaluate": "workspace:*"
|
|
14
|
-
},
|
|
15
|
-
"devDependencies": {
|
|
16
|
-
"@cloudflare/workers-types": "^4.20251011.0",
|
|
17
|
-
"typescript": "^5.7.0",
|
|
18
|
-
"wrangler": "^4.60.0"
|
|
19
|
-
}
|
|
20
|
-
}
|
package/example/src/index.ts
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ai-evaluate REST API Worker
|
|
3
|
-
*
|
|
4
|
-
* Deploy: wrangler deploy
|
|
5
|
-
* Domain: eval.workers.do
|
|
6
|
-
*
|
|
7
|
-
* Endpoints:
|
|
8
|
-
* - POST / - Execute code (accepts { script?, module?, tests?, imports? })
|
|
9
|
-
* - GET /health - Health check
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { evaluate, type SandboxEnv, type EvaluateOptions, type EvaluateResult } from 'ai-evaluate'
|
|
13
|
-
|
|
14
|
-
interface Env extends SandboxEnv {
|
|
15
|
-
loader: unknown
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// CORS headers for cross-origin requests
|
|
19
|
-
const corsHeaders = {
|
|
20
|
-
'Access-Control-Allow-Origin': '*',
|
|
21
|
-
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
22
|
-
'Access-Control-Allow-Headers': 'Content-Type',
|
|
23
|
-
'Content-Type': 'application/json',
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export default {
|
|
27
|
-
async fetch(request: Request, env: Env): Promise<Response> {
|
|
28
|
-
const url = new URL(request.url)
|
|
29
|
-
|
|
30
|
-
// Handle CORS preflight
|
|
31
|
-
if (request.method === 'OPTIONS') {
|
|
32
|
-
return new Response(null, { headers: corsHeaders })
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Health check endpoint
|
|
36
|
-
if (url.pathname === '/health' || url.pathname === '/healthz') {
|
|
37
|
-
return Response.json(
|
|
38
|
-
{
|
|
39
|
-
status: 'ok',
|
|
40
|
-
service: 'ai-evaluate',
|
|
41
|
-
version: '2.1.6',
|
|
42
|
-
timestamp: new Date().toISOString(),
|
|
43
|
-
},
|
|
44
|
-
{ headers: corsHeaders }
|
|
45
|
-
)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// GET with query params - execute code
|
|
49
|
-
// e.g., GET /?script=return+1+%2B+1
|
|
50
|
-
// e.g., GET /?script=return+_.chunk([1,2,3],2)&imports=https://esm.sh/lodash
|
|
51
|
-
if (request.method === 'GET' && url.pathname === '/') {
|
|
52
|
-
const script = url.searchParams.get('script') || url.searchParams.get('code')
|
|
53
|
-
const module = url.searchParams.get('module')
|
|
54
|
-
const importsParam = url.searchParams.get('imports')
|
|
55
|
-
|
|
56
|
-
// If script or module provided, execute code
|
|
57
|
-
if (script || module) {
|
|
58
|
-
try {
|
|
59
|
-
// Parse imports - can be comma-separated or multiple params
|
|
60
|
-
let imports: string[] | undefined
|
|
61
|
-
if (importsParam) {
|
|
62
|
-
imports = importsParam.includes(',')
|
|
63
|
-
? importsParam.split(',').map((s) => s.trim())
|
|
64
|
-
: [importsParam]
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const options: EvaluateOptions = {
|
|
68
|
-
script: script || undefined,
|
|
69
|
-
module: module || undefined,
|
|
70
|
-
imports,
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const result = await evaluate(options, env)
|
|
74
|
-
return Response.json(
|
|
75
|
-
{
|
|
76
|
-
$id: request.url,
|
|
77
|
-
$context: url.origin,
|
|
78
|
-
input: {
|
|
79
|
-
script: script || undefined,
|
|
80
|
-
module: module || undefined,
|
|
81
|
-
imports: imports || undefined,
|
|
82
|
-
},
|
|
83
|
-
...result,
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
status: result.success ? 200 : 400,
|
|
87
|
-
headers: corsHeaders,
|
|
88
|
-
}
|
|
89
|
-
)
|
|
90
|
-
} catch (error) {
|
|
91
|
-
return Response.json(
|
|
92
|
-
{
|
|
93
|
-
$id: request.url,
|
|
94
|
-
$context: url.origin,
|
|
95
|
-
success: false,
|
|
96
|
-
error: error instanceof Error ? error.message : 'Invalid request',
|
|
97
|
-
logs: [],
|
|
98
|
-
duration: 0,
|
|
99
|
-
},
|
|
100
|
-
{ status: 400, headers: corsHeaders }
|
|
101
|
-
)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// No script - return API info with clickable examples
|
|
106
|
-
const baseUrl = url.origin
|
|
107
|
-
return Response.json(
|
|
108
|
-
{
|
|
109
|
-
name: 'ai-evaluate',
|
|
110
|
-
version: '2.1.6',
|
|
111
|
-
description: 'Secure code execution in sandboxed Cloudflare Workers',
|
|
112
|
-
endpoints: {
|
|
113
|
-
'GET /?script=...': 'Execute code via query params',
|
|
114
|
-
'POST /': 'Execute code via JSON body',
|
|
115
|
-
'GET /health': 'Health check',
|
|
116
|
-
},
|
|
117
|
-
tryIt: {
|
|
118
|
-
math: `${baseUrl}/?script=return+1+%2B+1`,
|
|
119
|
-
variables: `${baseUrl}/?script=const+x+%3D+10%3B+const+y+%3D+20%3B+return+x+*+y`,
|
|
120
|
-
arrays: `${baseUrl}/?script=return+[1,2,3,4,5].map(n+%3D%3E+n+*+2)`,
|
|
121
|
-
objects: `${baseUrl}/?script=return+%7B+name%3A+'eval'%2C+version%3A+'2.1.6'+%7D`,
|
|
122
|
-
functions: `${baseUrl}/?script=const+add+%3D+(a%2Cb)+%3D%3E+a%2Bb%3B+return+add(5%2C3)`,
|
|
123
|
-
async: `${baseUrl}/?script=return+await+Promise.resolve(42)`,
|
|
124
|
-
console: `${baseUrl}/?script=console.log('Hello')%3B+return+'check+logs'`,
|
|
125
|
-
json: `${baseUrl}/?script=return+JSON.parse('%7B%22a%22%3A1%7D')`,
|
|
126
|
-
date: `${baseUrl}/?script=return+new+Date().toISOString()`,
|
|
127
|
-
lodash: `${baseUrl}/?script=return+_.chunk([1,2,3,4,5,6],2)&imports=https://esm.sh/lodash@4.17.21`,
|
|
128
|
-
lodashMap: `${baseUrl}/?script=return+_.map([1,2,3],n%3D%3En*10)&imports=https://esm.sh/lodash@4.17.21`,
|
|
129
|
-
dayjs: `${baseUrl}/?script=return+dayjs().format('YYYY-MM-DD')&imports=https://esm.sh/dayjs@1.11.10`,
|
|
130
|
-
uuid: `${baseUrl}/?script=return+uuid.v4()&imports=https://esm.sh/uuid@9.0.0`,
|
|
131
|
-
},
|
|
132
|
-
curl: {
|
|
133
|
-
get: `curl '${baseUrl}/?script=return+1+%2B+1'`,
|
|
134
|
-
post: `curl -X POST ${baseUrl} -H 'Content-Type: application/json' -d '{"script":"return 1 + 1"}'`,
|
|
135
|
-
withImports: `curl -X POST ${baseUrl} -H 'Content-Type: application/json' -d '{"script":"return _.chunk([1,2,3,4,5,6],2)","imports":["https://esm.sh/lodash@4.17.21"]}'`,
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
{ headers: corsHeaders }
|
|
139
|
-
)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Execute code endpoint (POST)
|
|
143
|
-
if (request.method === 'POST') {
|
|
144
|
-
try {
|
|
145
|
-
const body = (await request.json()) as Partial<EvaluateOptions> & { code?: string }
|
|
146
|
-
|
|
147
|
-
// Support both simple { code } and full { module, tests, script }
|
|
148
|
-
const options: EvaluateOptions = {
|
|
149
|
-
module: body.module,
|
|
150
|
-
tests: body.tests,
|
|
151
|
-
script: body.script || body.code,
|
|
152
|
-
timeout: body.timeout,
|
|
153
|
-
imports: body.imports,
|
|
154
|
-
sdk: body.sdk,
|
|
155
|
-
fetch: body.fetch,
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Validate that at least one of script/module/tests is provided
|
|
159
|
-
if (!options.script && !options.module && !options.tests) {
|
|
160
|
-
return Response.json(
|
|
161
|
-
{
|
|
162
|
-
$id: request.url,
|
|
163
|
-
$context: url.origin,
|
|
164
|
-
success: false,
|
|
165
|
-
error: 'At least one of script, module, or tests is required',
|
|
166
|
-
logs: [],
|
|
167
|
-
duration: 0,
|
|
168
|
-
},
|
|
169
|
-
{ status: 400, headers: corsHeaders }
|
|
170
|
-
)
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const result = await evaluate(options, env)
|
|
174
|
-
return Response.json(
|
|
175
|
-
{
|
|
176
|
-
$id: request.url,
|
|
177
|
-
$context: url.origin,
|
|
178
|
-
input: {
|
|
179
|
-
script: options.script || undefined,
|
|
180
|
-
module: options.module || undefined,
|
|
181
|
-
tests: options.tests || undefined,
|
|
182
|
-
imports: options.imports || undefined,
|
|
183
|
-
timeout: options.timeout || undefined,
|
|
184
|
-
sdk: options.sdk || undefined,
|
|
185
|
-
},
|
|
186
|
-
...result,
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
status: result.success ? 200 : 400,
|
|
190
|
-
headers: corsHeaders,
|
|
191
|
-
}
|
|
192
|
-
)
|
|
193
|
-
} catch (error) {
|
|
194
|
-
return Response.json(
|
|
195
|
-
{
|
|
196
|
-
$id: request.url,
|
|
197
|
-
$context: url.origin,
|
|
198
|
-
success: false,
|
|
199
|
-
error: error instanceof Error ? error.message : 'Invalid request',
|
|
200
|
-
logs: [],
|
|
201
|
-
duration: 0,
|
|
202
|
-
},
|
|
203
|
-
{ status: 400, headers: corsHeaders }
|
|
204
|
-
)
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// 404 for unknown routes
|
|
209
|
-
return Response.json(
|
|
210
|
-
{ error: 'Not found', path: url.pathname },
|
|
211
|
-
{ status: 404, headers: corsHeaders }
|
|
212
|
-
)
|
|
213
|
-
},
|
|
214
|
-
}
|
package/example/wrangler.jsonc
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "node_modules/wrangler/config-schema.json",
|
|
3
|
-
"name": "eval-workers-do",
|
|
4
|
-
"main": "src/index.ts",
|
|
5
|
-
"compatibility_date": "2026-01-01",
|
|
6
|
-
"account_id": "b6641681fe423910342b9ffa1364c76d",
|
|
7
|
-
|
|
8
|
-
// Routes - zone route for workers.do domain
|
|
9
|
-
"routes": [
|
|
10
|
-
{ "pattern": "eval.workers.do/*", "zone_name": "workers.do" }
|
|
11
|
-
],
|
|
12
|
-
|
|
13
|
-
// Keep workers.dev enabled for testing
|
|
14
|
-
"workers_dev": true,
|
|
15
|
-
|
|
16
|
-
// Worker loader for dynamic sandbox execution
|
|
17
|
-
"worker_loaders": [
|
|
18
|
-
{ "binding": "loader" }
|
|
19
|
-
],
|
|
20
|
-
|
|
21
|
-
// Bundle configuration to resolve workspace package
|
|
22
|
-
"alias": {
|
|
23
|
-
"ai-evaluate": "../dist/index.js"
|
|
24
|
-
}
|
|
25
|
-
}
|