ai-evaluate 2.1.6 → 2.1.8

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 (100) hide show
  1. package/README.md +90 -3
  2. package/dist/capnweb-bundle.d.ts +10 -0
  3. package/dist/capnweb-bundle.d.ts.map +1 -0
  4. package/dist/capnweb-bundle.js +2596 -0
  5. package/dist/capnweb-bundle.js.map +1 -0
  6. package/dist/evaluate.d.ts +1 -1
  7. package/dist/evaluate.d.ts.map +1 -1
  8. package/dist/evaluate.js +186 -7
  9. package/dist/evaluate.js.map +1 -1
  10. package/dist/index.d.ts +2 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +1 -0
  13. package/dist/index.js.map +1 -1
  14. package/dist/miniflare-pool.d.ts +109 -0
  15. package/dist/miniflare-pool.d.ts.map +1 -0
  16. package/dist/miniflare-pool.js +308 -0
  17. package/dist/miniflare-pool.js.map +1 -0
  18. package/dist/node.d.ts.map +1 -1
  19. package/dist/node.js +42 -10
  20. package/dist/node.js.map +1 -1
  21. package/dist/shared.d.ts +66 -0
  22. package/dist/shared.d.ts.map +1 -0
  23. package/dist/shared.js +169 -0
  24. package/dist/shared.js.map +1 -0
  25. package/dist/type-guards.d.ts +21 -0
  26. package/dist/type-guards.d.ts.map +1 -0
  27. package/dist/type-guards.js +216 -0
  28. package/dist/type-guards.js.map +1 -0
  29. package/dist/types.d.ts +17 -2
  30. package/dist/types.d.ts.map +1 -1
  31. package/dist/validation.d.ts +26 -0
  32. package/dist/validation.d.ts.map +1 -0
  33. package/dist/validation.js +104 -0
  34. package/dist/validation.js.map +1 -0
  35. package/dist/worker-template/code-transforms.d.ts +9 -0
  36. package/dist/worker-template/code-transforms.d.ts.map +1 -0
  37. package/dist/worker-template/code-transforms.js +28 -0
  38. package/dist/worker-template/code-transforms.js.map +1 -0
  39. package/{src/worker-template.d.ts → dist/worker-template/core.d.ts} +7 -15
  40. package/dist/worker-template/core.d.ts.map +1 -0
  41. package/dist/worker-template/core.js +502 -0
  42. package/dist/worker-template/core.js.map +1 -0
  43. package/dist/worker-template/helpers.d.ts +14 -0
  44. package/dist/worker-template/helpers.d.ts.map +1 -0
  45. package/dist/worker-template/helpers.js +79 -0
  46. package/dist/worker-template/helpers.js.map +1 -0
  47. package/dist/worker-template/index.d.ts +14 -0
  48. package/dist/worker-template/index.d.ts.map +1 -0
  49. package/dist/worker-template/index.js +19 -0
  50. package/dist/worker-template/index.js.map +1 -0
  51. package/dist/worker-template/sdk-generator.d.ts +17 -0
  52. package/dist/worker-template/sdk-generator.d.ts.map +1 -0
  53. package/{src/worker-template.js → dist/worker-template/sdk-generator.js} +377 -1506
  54. package/dist/worker-template/sdk-generator.js.map +1 -0
  55. package/dist/worker-template/test-generator.d.ts +16 -0
  56. package/dist/worker-template/test-generator.d.ts.map +1 -0
  57. package/dist/worker-template/test-generator.js +357 -0
  58. package/dist/worker-template/test-generator.js.map +1 -0
  59. package/dist/worker-template.d.ts +2 -2
  60. package/dist/worker-template.d.ts.map +1 -1
  61. package/dist/worker-template.js +64 -31
  62. package/dist/worker-template.js.map +1 -1
  63. package/example/package.json +7 -3
  64. package/example/src/index.ts +194 -40
  65. package/example/wrangler.jsonc +18 -2
  66. package/package.json +1 -3
  67. package/src/capnweb-bundle.ts +2596 -0
  68. package/src/evaluate.ts +216 -7
  69. package/src/index.ts +3 -1
  70. package/src/miniflare-pool.ts +395 -0
  71. package/src/node.ts +56 -11
  72. package/src/shared.ts +186 -0
  73. package/src/type-guards.ts +323 -0
  74. package/src/types.ts +18 -2
  75. package/src/validation.ts +120 -0
  76. package/src/worker-template/code-transforms.ts +32 -0
  77. package/src/worker-template/core.ts +557 -0
  78. package/src/worker-template/helpers.ts +90 -0
  79. package/src/worker-template/index.ts +23 -0
  80. package/src/{worker-template.ts → worker-template/sdk-generator.ts} +322 -1566
  81. package/src/worker-template/test-generator.ts +358 -0
  82. package/test/miniflare-pool.test.ts +246 -0
  83. package/test/node.test.ts +467 -0
  84. package/test/security.test.ts +1009 -0
  85. package/test/shared.test.ts +105 -0
  86. package/test/type-guards.test.ts +303 -0
  87. package/test/validation.test.ts +240 -0
  88. package/test/worker-template.test.ts +21 -19
  89. package/src/evaluate.js +0 -187
  90. package/src/index.js +0 -10
  91. package/src/node.d.ts +0 -17
  92. package/src/node.d.ts.map +0 -1
  93. package/src/node.js +0 -168
  94. package/src/node.js.map +0 -1
  95. package/src/types.d.ts +0 -172
  96. package/src/types.d.ts.map +0 -1
  97. package/src/types.js +0 -4
  98. package/src/types.js.map +0 -1
  99. package/src/worker-template.d.ts.map +0 -1
  100. package/src/worker-template.js.map +0 -1
@@ -0,0 +1,502 @@
1
+ /**
2
+ * Worker scaffold and main template generation
3
+ *
4
+ * This module contains the main generateWorkerCode and generateDevWorkerCode functions
5
+ * that produce the complete worker code for sandbox execution.
6
+ */
7
+ import { getExportNames, wrapScriptForReturn } from './helpers.js';
8
+ import { transformModuleCode } from './code-transforms.js';
9
+ import { generateSDKCode, generateShouldCode } from './sdk-generator.js';
10
+ import { generateTestFrameworkCode, generateTestRunnerCode } from './test-generator.js';
11
+ import { generateDomainCheckCode } from '../shared.js';
12
+ /**
13
+ * Generate worker code for production (uses RPC to ai-tests)
14
+ */
15
+ export function generateWorkerCode(options) {
16
+ const { module: rawModule = '', tests = '', script: rawScript = '', sdk, imports = [], fetch: fetchOption } = options;
17
+ const sdkConfig = sdk === true ? {} : sdk || null;
18
+ const module = rawModule ? transformModuleCode(rawModule) : '';
19
+ const script = rawScript ? wrapScriptForReturn(rawScript) : '';
20
+ const exportNames = getExportNames(rawModule);
21
+ // Hoisted imports (from MDX test files) - placed at true module top level
22
+ const hoistedImports = imports.length > 0 ? imports.join('\n') + '\n' : '';
23
+ // Generate fetch control code for allowlist (block is handled by globalOutbound)
24
+ const allowlistDomains = Array.isArray(fetchOption) ? fetchOption : null;
25
+ const fetchControlCode = allowlistDomains ? generateDomainCheckCode(allowlistDomains) : '';
26
+ return `
27
+ // Sandbox Worker Entry Point
28
+ import { RpcTarget, newWorkersRpcResponse } from 'capnweb.js';
29
+ ${hoistedImports}
30
+ const logs = [];
31
+
32
+ ${fetchControlCode}
33
+
34
+ ${sdkConfig ? generateShouldCode() : ''}
35
+
36
+ ${sdkConfig ? generateSDKCode(sdkConfig) : '// SDK not enabled'}
37
+
38
+ // Capture console output
39
+ const originalConsole = { ...console };
40
+ const captureConsole = (level) => (...args) => {
41
+ logs.push({
42
+ level,
43
+ message: args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '),
44
+ timestamp: Date.now()
45
+ });
46
+ originalConsole[level](...args);
47
+ };
48
+ console.log = captureConsole('log');
49
+ console.warn = captureConsole('warn');
50
+ console.error = captureConsole('error');
51
+ console.info = captureConsole('info');
52
+ console.debug = captureConsole('debug');
53
+
54
+ // ============================================================
55
+ // USER MODULE CODE (embedded at generation time)
56
+ // ============================================================
57
+ // Module exports object - exports become top-level variables
58
+ const exports = {};
59
+
60
+ ${module
61
+ ? `
62
+ // Execute module code
63
+ try {
64
+ ${module}
65
+ } catch (e) {
66
+ console.error('Module error:', e.message);
67
+ }
68
+ `
69
+ : '// No module code provided'}
70
+
71
+ // Expose all exports as top-level variables for tests and scripts
72
+ // This allows: export const add = (a, b) => a + b; then later: add(1, 2)
73
+ ${rawModule
74
+ ? `
75
+ const { ${exportNames} } = exports;
76
+ `.trim()
77
+ : ''}
78
+
79
+ // ============================================================
80
+ // RPC SERVER - Expose exports via capnweb
81
+ // ============================================================
82
+ class ExportsRpcTarget extends RpcTarget {
83
+ // Dynamically expose all exports as RPC methods
84
+ constructor() {
85
+ super();
86
+ for (const [key, value] of Object.entries(exports)) {
87
+ if (typeof value === 'function') {
88
+ this[key] = value;
89
+ }
90
+ }
91
+ }
92
+
93
+ // List available exports
94
+ list() {
95
+ return Object.keys(exports);
96
+ }
97
+
98
+ // Get an export by name
99
+ get(name) {
100
+ return exports[name];
101
+ }
102
+ }
103
+
104
+ // ============================================================
105
+ // WORKER ENTRY POINT
106
+ // ============================================================
107
+ export default {
108
+ async fetch(request, env) {
109
+ const url = new URL(request.url);
110
+
111
+ // Route: GET / - Return info about exports
112
+ if (request.method === 'GET' && url.pathname === '/') {
113
+ return Response.json({
114
+ exports: Object.keys(exports),
115
+ rpc: '/rpc',
116
+ execute: '/execute'
117
+ });
118
+ }
119
+
120
+ // Route: /rpc - capnweb RPC to module exports
121
+ if (url.pathname === '/rpc') {
122
+ return newWorkersRpcResponse(request, new ExportsRpcTarget());
123
+ }
124
+
125
+ // Route: GET /:name - Simple JSON endpoint to access exports
126
+ if (request.method === 'GET' && url.pathname !== '/execute') {
127
+ const name = url.pathname.slice(1); // Remove leading /
128
+ const value = exports[name];
129
+
130
+ // Check if export exists
131
+ if (!(name in exports)) {
132
+ return Response.json({ error: \`Export "\${name}" not found\` }, { status: 404 });
133
+ }
134
+
135
+ // If it's not a function, just return the value
136
+ if (typeof value !== 'function') {
137
+ return Response.json({ result: value });
138
+ }
139
+
140
+ // It's a function - parse args and call it
141
+ try {
142
+ const args = [];
143
+ const argsParam = url.searchParams.get('args');
144
+ if (argsParam) {
145
+ // Support JSON array: ?args=[1,2,3]
146
+ try {
147
+ const parsed = JSON.parse(argsParam);
148
+ if (Array.isArray(parsed)) {
149
+ args.push(...parsed);
150
+ } else {
151
+ args.push(parsed);
152
+ }
153
+ } catch {
154
+ // Not JSON, use as single string arg
155
+ args.push(argsParam);
156
+ }
157
+ } else {
158
+ // Support named params: ?a=1&b=2 -> passed as object
159
+ const params = Object.fromEntries(url.searchParams.entries());
160
+ if (Object.keys(params).length > 0) {
161
+ // Try to parse numeric values
162
+ for (const [key, val] of Object.entries(params)) {
163
+ const num = Number(val);
164
+ params[key] = !isNaN(num) && val !== '' ? num : val;
165
+ }
166
+ args.push(params);
167
+ }
168
+ }
169
+
170
+ const result = await value(...args);
171
+ return Response.json({ result });
172
+ } catch (e) {
173
+ return Response.json({ error: e.message }, { status: 500 });
174
+ }
175
+ }
176
+
177
+ // Route: /execute - Run tests and scripts
178
+ // Check for TEST service binding
179
+ if (!env.TEST) {
180
+ return Response.json({
181
+ success: false,
182
+ error: 'TEST service binding not available. Ensure ai-tests worker is bound.',
183
+ logs,
184
+ duration: 0
185
+ });
186
+ }
187
+
188
+ // Connect to get the TestServiceCore via RPC
189
+ const testService = await env.TEST.connect();
190
+
191
+ // Create global test functions that proxy to the RPC service
192
+ const describe = (name, fn) => testService.describe(name, fn);
193
+ const it = (name, fn) => testService.it(name, fn);
194
+ const test = (name, fn) => testService.test(name, fn);
195
+ const expect = (value, message) => testService.expect(value, message);
196
+ const should = (value) => testService.should(value);
197
+ const assert = testService.assert;
198
+ const beforeEach = (fn) => testService.beforeEach(fn);
199
+ const afterEach = (fn) => testService.afterEach(fn);
200
+ const beforeAll = (fn) => testService.beforeAll(fn);
201
+ const afterAll = (fn) => testService.afterAll(fn);
202
+
203
+ // Add skip/only modifiers
204
+ it.skip = (name, fn) => testService.skip(name, fn);
205
+ it.only = (name, fn) => testService.only(name, fn);
206
+ test.skip = it.skip;
207
+ test.only = it.only;
208
+
209
+ let scriptResult = undefined;
210
+ let scriptError = null;
211
+ let testResults = undefined;
212
+
213
+ // ============================================================
214
+ // USER TEST CODE (embedded at generation time)
215
+ // ============================================================
216
+
217
+ ${tests
218
+ ? `
219
+ // Register tests
220
+ try {
221
+ ${tests}
222
+ } catch (e) {
223
+ console.error('Test registration error:', e.message);
224
+ }
225
+ `
226
+ : '// No test code provided'}
227
+
228
+ // Execute user script
229
+ ${script
230
+ ? `
231
+ try {
232
+ scriptResult = await (async () => {
233
+ ${script}
234
+ })();
235
+ } catch (e) {
236
+ console.error('Script error:', e.message);
237
+ scriptError = e.message;
238
+ }
239
+ `
240
+ : '// No script code provided'}
241
+
242
+ // Run tests if any were registered
243
+ ${tests
244
+ ? `
245
+ try {
246
+ testResults = await testService.run();
247
+ } catch (e) {
248
+ console.error('Test run error:', e.message);
249
+ testResults = { total: 0, passed: 0, failed: 1, skipped: 0, tests: [], duration: 0, error: e.message };
250
+ }
251
+ `
252
+ : ''}
253
+
254
+ const hasTests = ${tests ? 'true' : 'false'};
255
+ const success = scriptError === null && (!hasTests || (testResults && testResults.failed === 0));
256
+
257
+ return Response.json({
258
+ success,
259
+ value: scriptResult,
260
+ logs,
261
+ testResults: hasTests ? testResults : undefined,
262
+ error: scriptError || undefined,
263
+ duration: 0
264
+ });
265
+ }
266
+ };
267
+ `;
268
+ }
269
+ /**
270
+ * Generate worker code for development (embedded test framework)
271
+ *
272
+ * This version bundles the test framework directly into the worker,
273
+ * avoiding the need for RPC service bindings in local development.
274
+ */
275
+ export function generateDevWorkerCode(options) {
276
+ const { module: rawModule = '', tests = '', script: rawScript = '', sdk, imports = [], fetch: fetchOption, } = options;
277
+ const sdkConfig = sdk === true ? {} : sdk || null;
278
+ const module = rawModule ? transformModuleCode(rawModule) : '';
279
+ const script = rawScript ? wrapScriptForReturn(rawScript) : '';
280
+ const exportNames = getExportNames(rawModule);
281
+ // Determine fetch handling mode
282
+ // - false or null -> block all network
283
+ // - string[] -> domain allowlist
284
+ // - true or undefined -> allow all (no wrapper needed)
285
+ const blockFetch = fetchOption === false || fetchOption === null;
286
+ const allowlistDomains = Array.isArray(fetchOption) ? fetchOption : null;
287
+ // Hoisted imports (from MDX test files) - placed at true module top level
288
+ const hoistedImports = imports.length > 0 ? imports.join('\n') + '\n' : '';
289
+ // Generate fetch control code based on mode
290
+ let fetchControlCode = '';
291
+ if (blockFetch) {
292
+ fetchControlCode = `
293
+ // Block fetch when fetch: false or null is specified
294
+ const __originalFetch__ = globalThis.fetch;
295
+ globalThis.fetch = async (...args) => {
296
+ throw new Error('Network access blocked: fetch is disabled in this sandbox');
297
+ };
298
+ `;
299
+ }
300
+ else if (allowlistDomains) {
301
+ fetchControlCode = generateDomainCheckCode(allowlistDomains);
302
+ }
303
+ return `
304
+ // Sandbox Worker Entry Point (Dev Mode - embedded test framework)
305
+ ${hoistedImports}
306
+ const logs = [];
307
+ const testResults = { total: 0, passed: 0, failed: 0, skipped: 0, tests: [], duration: 0 };
308
+ const pendingTests = [];
309
+
310
+ ${fetchControlCode}
311
+
312
+ ${sdkConfig ? generateShouldCode() : ''}
313
+
314
+ ${sdkConfig ? generateSDKCode(sdkConfig) : '// SDK not enabled'}
315
+
316
+ // Capture console output
317
+ const originalConsole = { ...console };
318
+ const captureConsole = (level) => (...args) => {
319
+ logs.push({
320
+ level,
321
+ message: args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '),
322
+ timestamp: Date.now()
323
+ });
324
+ originalConsole[level](...args);
325
+ };
326
+ console.log = captureConsole('log');
327
+ console.warn = captureConsole('warn');
328
+ console.error = captureConsole('error');
329
+ console.info = captureConsole('info');
330
+ console.debug = captureConsole('debug');
331
+
332
+ ${generateTestFrameworkCode()}
333
+
334
+ // ============================================================
335
+ // USER MODULE CODE (embedded at generation time)
336
+ // ============================================================
337
+ // Module exports object - exports become top-level variables
338
+ const exports = {};
339
+
340
+ ${module
341
+ ? `
342
+ // Execute module code
343
+ try {
344
+ ${module}
345
+ } catch (e) {
346
+ console.error('Module error:', e.message);
347
+ }
348
+ `
349
+ : '// No module code provided'}
350
+
351
+ // Expose all exports as top-level variables for tests and scripts
352
+ // This allows: export const add = (a, b) => a + b; then later: add(1, 2)
353
+ ${rawModule
354
+ ? `
355
+ const { ${exportNames} } = exports;
356
+ `.trim()
357
+ : ''}
358
+
359
+ // ============================================================
360
+ // USER TEST CODE (embedded at generation time)
361
+ // ============================================================
362
+ ${tests
363
+ ? `
364
+ // Register tests
365
+ try {
366
+ ${tests}
367
+ } catch (e) {
368
+ console.error('Test registration error:', e.message);
369
+ }
370
+ `
371
+ : '// No test code provided'}
372
+
373
+ // ============================================================
374
+ // SIMPLE RPC HANDLER (dev mode - no capnweb dependency)
375
+ // ============================================================
376
+ async function handleRpc(request) {
377
+ try {
378
+ const { method, args = [] } = await request.json();
379
+ if (method === 'list') {
380
+ return Response.json({ result: Object.keys(exports) });
381
+ }
382
+ if (method === 'get') {
383
+ const [name] = args;
384
+ const value = exports[name];
385
+ if (typeof value === 'function') {
386
+ return Response.json({ result: { type: 'function', name } });
387
+ }
388
+ return Response.json({ result: value });
389
+ }
390
+ // Call an exported function
391
+ const fn = exports[method];
392
+ if (typeof fn !== 'function') {
393
+ return Response.json({ error: \`Export "\${method}" is not a function\` }, { status: 400 });
394
+ }
395
+ const result = await fn(...args);
396
+ return Response.json({ result });
397
+ } catch (e) {
398
+ return Response.json({ error: e.message }, { status: 500 });
399
+ }
400
+ }
401
+
402
+ // ============================================================
403
+ // WORKER ENTRY POINT
404
+ // ============================================================
405
+ export default {
406
+ async fetch(request, env) {
407
+ const url = new URL(request.url);
408
+
409
+ // Route: GET / - Return info about exports
410
+ if (request.method === 'GET' && url.pathname === '/') {
411
+ return Response.json({
412
+ exports: Object.keys(exports),
413
+ rpc: '/rpc',
414
+ execute: '/execute'
415
+ });
416
+ }
417
+
418
+ // Route: POST /rpc - Simple RPC to module exports
419
+ if (url.pathname === '/rpc' && request.method === 'POST') {
420
+ return handleRpc(request);
421
+ }
422
+
423
+ // Route: GET /:name - Simple JSON endpoint to access exports
424
+ if (request.method === 'GET' && url.pathname !== '/execute') {
425
+ const name = url.pathname.slice(1);
426
+ const value = exports[name];
427
+
428
+ // Check if export exists
429
+ if (!(name in exports)) {
430
+ return Response.json({ error: \`Export "\${name}" not found\` }, { status: 404 });
431
+ }
432
+
433
+ // If it's not a function, just return the value
434
+ if (typeof value !== 'function') {
435
+ return Response.json({ result: value });
436
+ }
437
+
438
+ // It's a function - parse args and call it
439
+ try {
440
+ const args = [];
441
+ const argsParam = url.searchParams.get('args');
442
+ if (argsParam) {
443
+ try {
444
+ const parsed = JSON.parse(argsParam);
445
+ if (Array.isArray(parsed)) args.push(...parsed);
446
+ else args.push(parsed);
447
+ } catch {
448
+ args.push(argsParam);
449
+ }
450
+ } else {
451
+ const params = Object.fromEntries(url.searchParams.entries());
452
+ if (Object.keys(params).length > 0) {
453
+ for (const [key, val] of Object.entries(params)) {
454
+ const num = Number(val);
455
+ params[key] = !isNaN(num) && val !== '' ? num : val;
456
+ }
457
+ args.push(params);
458
+ }
459
+ }
460
+ const result = await value(...args);
461
+ return Response.json({ result });
462
+ } catch (e) {
463
+ return Response.json({ error: e.message }, { status: 500 });
464
+ }
465
+ }
466
+
467
+ // Route: /execute - Run tests and scripts
468
+ let scriptResult = undefined;
469
+ let scriptError = null;
470
+
471
+ // Execute user script
472
+ ${script
473
+ ? `
474
+ try {
475
+ scriptResult = await (async () => {
476
+ ${script}
477
+ })();
478
+ } catch (e) {
479
+ console.error('Script error:', e.message);
480
+ scriptError = e.message;
481
+ }
482
+ `
483
+ : '// No script code provided'}
484
+
485
+ ${generateTestRunnerCode()}
486
+
487
+ const hasTests = ${tests ? 'true' : 'false'};
488
+ const success = scriptError === null && (!hasTests || testResults.failed === 0);
489
+
490
+ return Response.json({
491
+ success,
492
+ value: scriptResult,
493
+ logs,
494
+ testResults: hasTests ? testResults : undefined,
495
+ error: scriptError || undefined,
496
+ duration: 0
497
+ });
498
+ }
499
+ };
500
+ `;
501
+ }
502
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/worker-template/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared utility functions for worker template generation
3
+ */
4
+ /**
5
+ * Extract export names from module code
6
+ * Supports both CommonJS (exports.foo) and ES module (export const foo) syntax
7
+ */
8
+ export declare function getExportNames(moduleCode: string): string;
9
+ /**
10
+ * Wrap script to auto-return the last expression
11
+ * Converts: `add(1, 2)` -> `return add(1, 2)`
12
+ */
13
+ export declare function wrapScriptForReturn(script: string): string;
14
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/worker-template/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAmCzD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAwC1D"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Shared utility functions for worker template generation
3
+ */
4
+ /**
5
+ * Extract export names from module code
6
+ * Supports both CommonJS (exports.foo) and ES module (export const foo) syntax
7
+ */
8
+ export function getExportNames(moduleCode) {
9
+ const names = new Set();
10
+ // Match exports.name = ...
11
+ const dotPattern = /exports\.(\w+)\s*=/g;
12
+ let match;
13
+ while ((match = dotPattern.exec(moduleCode)) !== null) {
14
+ if (match[1])
15
+ names.add(match[1]);
16
+ }
17
+ // Match exports['name'] = ... or exports["name"] = ...
18
+ const bracketPattern = /exports\[['"](\w+)['"]\]\s*=/g;
19
+ while ((match = bracketPattern.exec(moduleCode)) !== null) {
20
+ if (match[1])
21
+ names.add(match[1]);
22
+ }
23
+ // Match export const name = ... or export let name = ... or export var name = ...
24
+ const esConstPattern = /export\s+(?:const|let|var)\s+(\w+)\s*=/g;
25
+ while ((match = esConstPattern.exec(moduleCode)) !== null) {
26
+ if (match[1])
27
+ names.add(match[1]);
28
+ }
29
+ // Match export function name(...) or export async function name(...) or export async function* name(...)
30
+ const esFunctionPattern = /export\s+(?:async\s+)?function\*?\s+(\w+)\s*\(/g;
31
+ while ((match = esFunctionPattern.exec(moduleCode)) !== null) {
32
+ if (match[1])
33
+ names.add(match[1]);
34
+ }
35
+ // Match export class name
36
+ const esClassPattern = /export\s+class\s+(\w+)/g;
37
+ while ((match = esClassPattern.exec(moduleCode)) !== null) {
38
+ if (match[1])
39
+ names.add(match[1]);
40
+ }
41
+ return Array.from(names).join(', ') || '_unused';
42
+ }
43
+ /**
44
+ * Wrap script to auto-return the last expression
45
+ * Converts: `add(1, 2)` -> `return add(1, 2)`
46
+ */
47
+ export function wrapScriptForReturn(script) {
48
+ const trimmed = script.trim();
49
+ if (!trimmed)
50
+ return script;
51
+ // If script already contains a return statement anywhere, don't modify
52
+ if (/\breturn\b/.test(trimmed))
53
+ return script;
54
+ // If script starts with throw, don't modify
55
+ if (/^\s*throw\b/.test(trimmed))
56
+ return script;
57
+ // If it's a single expression (no newlines, no semicolons except at end), wrap it
58
+ const withoutTrailingSemi = trimmed.replace(/;?\s*$/, '');
59
+ const isSingleLine = !withoutTrailingSemi.includes('\n');
60
+ // Check if it looks like a single expression (no control flow, no declarations)
61
+ const startsWithKeyword = /^\s*(const|let|var|if|for|while|switch|try|class|function|async\s+function)\b/.test(withoutTrailingSemi);
62
+ if (isSingleLine && !startsWithKeyword) {
63
+ return `return ${withoutTrailingSemi}`;
64
+ }
65
+ // For multi-statement scripts, try to return the last expression
66
+ const lines = trimmed.split('\n');
67
+ const lastLineRaw = lines[lines.length - 1];
68
+ if (!lastLineRaw)
69
+ return script;
70
+ const lastLine = lastLineRaw.trim();
71
+ // If last line is an expression (not a declaration, control flow, or throw)
72
+ if (lastLine &&
73
+ !/^\s*(const|let|var|if|for|while|switch|try|class|function|return|throw)\b/.test(lastLine)) {
74
+ lines[lines.length - 1] = `return ${lastLine.replace(/;?\s*$/, '')}`;
75
+ return lines.join('\n');
76
+ }
77
+ return script;
78
+ }
79
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/worker-template/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Worker template module for sandbox execution
3
+ *
4
+ * This module provides functions to generate worker code for sandboxed execution.
5
+ * The generated code is stringified and sent to the worker loader.
6
+ *
7
+ * @module worker-template
8
+ */
9
+ export { generateWorkerCode, generateDevWorkerCode } from './core.js';
10
+ export { generateSDKCode, generateShouldCode } from './sdk-generator.js';
11
+ export { generateTestFrameworkCode, generateTestRunnerCode } from './test-generator.js';
12
+ export { transformModuleCode } from './code-transforms.js';
13
+ export { getExportNames, wrapScriptForReturn } from './helpers.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/worker-template/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AAGrE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAGxE,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAGvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAG1D,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Worker template module for sandbox execution
3
+ *
4
+ * This module provides functions to generate worker code for sandboxed execution.
5
+ * The generated code is stringified and sent to the worker loader.
6
+ *
7
+ * @module worker-template
8
+ */
9
+ // Main public API - worker code generators
10
+ export { generateWorkerCode, generateDevWorkerCode } from './core.js';
11
+ // SDK code generation (local and remote modes)
12
+ export { generateSDKCode, generateShouldCode } from './sdk-generator.js';
13
+ // Test framework embedding
14
+ export { generateTestFrameworkCode, generateTestRunnerCode } from './test-generator.js';
15
+ // Module transformation and export detection
16
+ export { transformModuleCode } from './code-transforms.js';
17
+ // Shared utility functions
18
+ export { getExportNames, wrapScriptForReturn } from './helpers.js';
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/worker-template/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,2CAA2C;AAC3C,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AAErE,+CAA+C;AAC/C,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAExE,2BAA2B;AAC3B,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAEvF,6CAA6C;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAE1D,2BAA2B;AAC3B,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * SDK code generation for worker templates
3
+ *
4
+ * Supports two modes:
5
+ * - local: In-memory implementations (for testing without network)
6
+ * - remote: RPC-based implementations (for production/integration tests)
7
+ */
8
+ import type { SDKConfig } from '../types.js';
9
+ /**
10
+ * Generate SDK code for injection into sandbox
11
+ */
12
+ export declare function generateSDKCode(config?: SDKConfig): string;
13
+ /**
14
+ * Generate .should chainable assertions code
15
+ */
16
+ export declare function generateShouldCode(): string;
17
+ //# sourceMappingURL=sdk-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-generator.d.ts","sourceRoot":"","sources":["../../src/worker-template/sdk-generator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,GAAE,SAAc,GAAG,MAAM,CAK9D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CA4J3C"}