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,308 @@
1
+ /**
2
+ * Miniflare instance pool for improved performance
3
+ *
4
+ * Reuses Miniflare instances between evaluations instead of creating/disposing
5
+ * for each evaluation, providing 4-5x performance improvement.
6
+ *
7
+ * Uses Miniflare's setOptions() to update the worker script between uses,
8
+ * avoiding the expensive instance creation/teardown cycle.
9
+ */
10
+ /**
11
+ * Global pool state (singleton per process)
12
+ */
13
+ let pool = [];
14
+ let poolConfig = {
15
+ size: 3,
16
+ maxIdleTime: 30000,
17
+ };
18
+ let idleCleanupInterval = null;
19
+ let MiniflareClass = null;
20
+ let isShuttingDown = false;
21
+ // Default worker script for warm instances
22
+ const WARM_WORKER_SCRIPT = `
23
+ export default {
24
+ async fetch(request, env) {
25
+ return new Response('ready', { status: 200 });
26
+ }
27
+ };
28
+ `;
29
+ /**
30
+ * Configure the Miniflare pool
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * import { configurePool } from 'ai-evaluate/node'
35
+ *
36
+ * configurePool({
37
+ * size: 5, // Keep 5 warm instances
38
+ * maxIdleTime: 60000 // Dispose after 60s idle
39
+ * })
40
+ * ```
41
+ */
42
+ export function configurePool(config) {
43
+ poolConfig = {
44
+ size: config.size ?? poolConfig.size,
45
+ maxIdleTime: config.maxIdleTime ?? poolConfig.maxIdleTime,
46
+ };
47
+ startIdleCleanup();
48
+ }
49
+ /**
50
+ * Get the current pool configuration
51
+ */
52
+ export function getPoolConfig() {
53
+ return { ...poolConfig };
54
+ }
55
+ /**
56
+ * Get pool statistics for monitoring
57
+ */
58
+ export function getPoolStats() {
59
+ const available = pool.filter((p) => !p.inUse).length;
60
+ return {
61
+ size: pool.length,
62
+ available,
63
+ inUse: pool.length - available,
64
+ config: { ...poolConfig },
65
+ };
66
+ }
67
+ /**
68
+ * Initialize the Miniflare class (lazy load)
69
+ */
70
+ async function getMiniflareClass() {
71
+ if (!MiniflareClass) {
72
+ const { Miniflare } = await import('miniflare');
73
+ MiniflareClass = Miniflare;
74
+ }
75
+ return MiniflareClass;
76
+ }
77
+ /**
78
+ * Create a new Miniflare instance with a warm worker
79
+ */
80
+ async function createInstance() {
81
+ const Miniflare = await getMiniflareClass();
82
+ return new Miniflare({
83
+ modules: true,
84
+ script: WARM_WORKER_SCRIPT,
85
+ compatibilityDate: '2026-01-01',
86
+ });
87
+ }
88
+ /**
89
+ * Start the idle cleanup interval
90
+ */
91
+ function startIdleCleanup() {
92
+ if (idleCleanupInterval) {
93
+ clearInterval(idleCleanupInterval);
94
+ }
95
+ idleCleanupInterval = setInterval(async () => {
96
+ if (isShuttingDown)
97
+ return;
98
+ const now = Date.now();
99
+ const toDispose = [];
100
+ // Find idle instances beyond the idle timeout
101
+ for (let i = pool.length - 1; i >= 0; i--) {
102
+ const item = pool[i];
103
+ if (!item.inUse && now - item.lastUsed > poolConfig.maxIdleTime) {
104
+ // Keep at least one warm instance
105
+ if (pool.filter((p) => !p.inUse && !toDispose.includes(p)).length > 1) {
106
+ toDispose.push(item);
107
+ pool.splice(i, 1);
108
+ }
109
+ }
110
+ }
111
+ // Dispose old instances
112
+ for (const item of toDispose) {
113
+ try {
114
+ await item.instance.dispose();
115
+ }
116
+ catch {
117
+ // Ignore disposal errors
118
+ }
119
+ }
120
+ }, 5000); // Check every 5 seconds
121
+ // Don't keep the process alive just for cleanup
122
+ if (idleCleanupInterval.unref) {
123
+ idleCleanupInterval.unref();
124
+ }
125
+ }
126
+ /**
127
+ * Acquire a Miniflare instance from the pool and configure it with a worker
128
+ *
129
+ * If a free instance is available, it will be reconfigured and returned.
130
+ * Otherwise, a new instance will be created (up to pool size limit).
131
+ * If pool is exhausted, creates a temporary instance.
132
+ *
133
+ * @param workerOptions - Configuration for the worker to run
134
+ * @returns Object with the configured instance and a release function
135
+ */
136
+ export async function acquireInstance(workerOptions) {
137
+ if (isShuttingDown) {
138
+ throw new Error('Pool is shutting down');
139
+ }
140
+ // Start idle cleanup if not started
141
+ if (!idleCleanupInterval) {
142
+ startIdleCleanup();
143
+ }
144
+ const { script, compatibilityDate = '2026-01-01', outboundService } = workerOptions;
145
+ // Build the options for setOptions
146
+ const updateOptions = {
147
+ modules: true,
148
+ script,
149
+ compatibilityDate,
150
+ };
151
+ // Only add outboundService if it's defined (for blocking network)
152
+ if (outboundService !== undefined) {
153
+ updateOptions.outboundService = outboundService;
154
+ }
155
+ // Try to find an available instance
156
+ const available = pool.find((p) => !p.inUse);
157
+ if (available) {
158
+ available.inUse = true;
159
+ // Reconfigure the instance with the new worker script
160
+ await available.instance.setOptions(updateOptions);
161
+ return {
162
+ instance: available.instance,
163
+ release: async () => {
164
+ available.inUse = false;
165
+ available.lastUsed = Date.now();
166
+ },
167
+ isPooled: true,
168
+ };
169
+ }
170
+ // Create new instance if pool not full
171
+ if (pool.length < poolConfig.size) {
172
+ const Miniflare = await getMiniflareClass();
173
+ const instance = new Miniflare(updateOptions);
174
+ const pooled = {
175
+ instance,
176
+ inUse: true,
177
+ lastUsed: Date.now(),
178
+ createdAt: Date.now(),
179
+ };
180
+ pool.push(pooled);
181
+ return {
182
+ instance,
183
+ release: async () => {
184
+ pooled.inUse = false;
185
+ pooled.lastUsed = Date.now();
186
+ },
187
+ isPooled: true,
188
+ };
189
+ }
190
+ // Pool exhausted - create temporary instance
191
+ const Miniflare = await getMiniflareClass();
192
+ const tempInstance = new Miniflare(updateOptions);
193
+ return {
194
+ instance: tempInstance,
195
+ release: async () => {
196
+ // Dispose temporary instance immediately
197
+ await tempInstance.dispose();
198
+ },
199
+ isPooled: false,
200
+ };
201
+ }
202
+ /**
203
+ * Pre-warm the pool with instances
204
+ *
205
+ * Call this at application startup to avoid cold start latency.
206
+ *
207
+ * @example
208
+ * ```ts
209
+ * import { warmPool } from 'ai-evaluate/node'
210
+ *
211
+ * // Pre-warm 3 instances at startup
212
+ * await warmPool(3)
213
+ * ```
214
+ */
215
+ export async function warmPool(count) {
216
+ const targetCount = count ?? poolConfig.size;
217
+ const toCreate = Math.max(0, targetCount - pool.length);
218
+ const promises = [];
219
+ for (let i = 0; i < toCreate; i++) {
220
+ promises.push((async () => {
221
+ const instance = await createInstance();
222
+ pool.push({
223
+ instance,
224
+ inUse: false,
225
+ lastUsed: Date.now(),
226
+ createdAt: Date.now(),
227
+ });
228
+ })());
229
+ }
230
+ await Promise.all(promises);
231
+ // Start idle cleanup if not already started
232
+ if (!idleCleanupInterval) {
233
+ startIdleCleanup();
234
+ }
235
+ }
236
+ /**
237
+ * Dispose all instances and clean up the pool
238
+ *
239
+ * Call this before process exit to ensure clean shutdown.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * import { disposePool } from 'ai-evaluate/node'
244
+ *
245
+ * process.on('beforeExit', async () => {
246
+ * await disposePool()
247
+ * })
248
+ * ```
249
+ */
250
+ export async function disposePool() {
251
+ isShuttingDown = true;
252
+ if (idleCleanupInterval) {
253
+ clearInterval(idleCleanupInterval);
254
+ idleCleanupInterval = null;
255
+ }
256
+ const instances = [...pool];
257
+ pool = [];
258
+ await Promise.all(instances.map(async (item) => {
259
+ try {
260
+ await item.instance.dispose();
261
+ }
262
+ catch {
263
+ // Ignore disposal errors
264
+ }
265
+ }));
266
+ isShuttingDown = false;
267
+ }
268
+ /**
269
+ * Reset the pool (for testing purposes)
270
+ */
271
+ export async function resetPool() {
272
+ await disposePool();
273
+ poolConfig = {
274
+ size: 3,
275
+ maxIdleTime: 30000,
276
+ };
277
+ MiniflareClass = null;
278
+ }
279
+ // Register cleanup on process exit
280
+ if (typeof process !== 'undefined') {
281
+ const cleanup = () => {
282
+ isShuttingDown = true;
283
+ if (idleCleanupInterval) {
284
+ clearInterval(idleCleanupInterval);
285
+ }
286
+ // Synchronous disposal attempt - best effort
287
+ for (const item of pool) {
288
+ try {
289
+ // Fire and forget - we're exiting anyway
290
+ item.instance.dispose().catch(() => { });
291
+ }
292
+ catch {
293
+ // Ignore errors during shutdown
294
+ }
295
+ }
296
+ pool = [];
297
+ };
298
+ process.on('exit', cleanup);
299
+ process.on('SIGINT', () => {
300
+ cleanup();
301
+ process.exit(0);
302
+ });
303
+ process.on('SIGTERM', () => {
304
+ cleanup();
305
+ process.exit(0);
306
+ });
307
+ }
308
+ //# sourceMappingURL=miniflare-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"miniflare-pool.js","sourceRoot":"","sources":["../src/miniflare-pool.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAgB,UAAU,EAAE,MAAM,YAAY,CAAA;AAmC3F;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,eAAe,EACxB,GAAG,CAAC,EAAE,UAAU,GACf,OAAO,CAAC,cAAc,CAAC,CAkCzB;AA6GD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,CAAC,EAAE,UAAU,IACtC,SAAS,eAAe,6BACjC;AAGD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAgB,UAAU,EAAe,MAAM,YAAY,CAAA;AAoCxG;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,eAAe,EACxB,GAAG,CAAC,EAAE,UAAU,GACf,OAAO,CAAC,cAAc,CAAC,CAmCzB;AAkJD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,CAAC,EAAE,UAAU,IACtC,SAAS,eAAe,6BACjC;AAGD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA"}
package/dist/node.js CHANGED
@@ -4,7 +4,8 @@
4
4
  * Uses Cloudflare worker_loaders when available, falls back to Miniflare for local dev.
5
5
  * For Workers-only builds, import from 'ai-evaluate' instead.
6
6
  */
7
- import { generateWorkerCode, generateDevWorkerCode } from './worker-template.js';
7
+ import { generateWorkerCode, generateDevWorkerCode } from './worker-template/index.js';
8
+ import { isDomainAllowed, normalizeImports } from './shared.js';
8
9
  /**
9
10
  * Check if code contains JSX syntax that needs transformation
10
11
  */
@@ -52,6 +53,7 @@ export async function evaluate(options, env) {
52
53
  module: transformedModule,
53
54
  tests: transformedTests,
54
55
  script: transformedScript,
56
+ imports: normalizeImports(options.imports),
55
57
  };
56
58
  // Use worker_loaders if available (Cloudflare Workers)
57
59
  // Check lowercase first (preferred), then legacy uppercase
@@ -103,6 +105,23 @@ async function evaluateWithWorkerLoader(options, loader, testService, start) {
103
105
  duration: Date.now() - start,
104
106
  };
105
107
  }
108
+ /**
109
+ * Determine if network access should be blocked based on fetch options
110
+ * fetch: false | null -> block
111
+ */
112
+ function shouldBlockNetwork(options) {
113
+ return options.fetch === false || options.fetch === null;
114
+ }
115
+ /**
116
+ * Get allowlist domains if fetch is an array
117
+ * fetch: string[] -> allowlist
118
+ */
119
+ function getAllowlistDomains(options) {
120
+ if (Array.isArray(options.fetch)) {
121
+ return options.fetch;
122
+ }
123
+ return null;
124
+ }
106
125
  /**
107
126
  * Evaluate using Miniflare (for Node.js/development)
108
127
  */
@@ -116,19 +135,32 @@ async function evaluateWithMiniflare(options, start) {
116
135
  imports: options.imports,
117
136
  fetch: options.fetch, // Pass fetch option to worker template
118
137
  });
119
- // Block outbound network requests at Miniflare level when fetch: null
120
- // This complements the globalThis.fetch override in the worker template
121
- const blockNetwork = options.fetch === null;
138
+ // Determine outbound service configuration based on fetch option
139
+ const blockNetwork = shouldBlockNetwork(options);
140
+ const allowlistDomains = getAllowlistDomains(options);
141
+ let outboundService;
142
+ if (blockNetwork) {
143
+ outboundService = () => {
144
+ throw new Error('Network access blocked: fetch is disabled in this sandbox');
145
+ };
146
+ }
147
+ else if (allowlistDomains) {
148
+ outboundService = (request) => {
149
+ const url = request.url;
150
+ if (!isDomainAllowed(url, allowlistDomains)) {
151
+ const hostname = new URL(url).hostname;
152
+ throw new Error(`Network access blocked: domain not in allowlist. Attempted: ${hostname}`);
153
+ }
154
+ // Allow the request by returning a fetched response
155
+ return fetch(request);
156
+ };
157
+ }
122
158
  const mf = new Miniflare({
123
159
  modules: true,
124
160
  script: workerCode,
125
161
  compatibilityDate: '2026-01-01',
126
- // Block all outbound fetch/connect when network is disabled
127
- ...(blockNetwork && {
128
- outboundService: () => {
129
- throw new Error('Network access blocked: fetch is disabled in this sandbox');
130
- },
131
- }),
162
+ // Configure outbound service based on fetch mode
163
+ ...(outboundService && { outboundService }),
132
164
  });
133
165
  try {
134
166
  const timeout = options.timeout || 5000;
package/dist/node.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Shared utilities for ai-evaluate
3
+ *
4
+ * Contains constants and helper functions used by both
5
+ * evaluate.ts (Workers) and node.ts (Node.js/Miniflare)
6
+ */
7
+ import type { EvaluateResult } from './types.js';
8
+ /**
9
+ * Compatibility date for dynamic workers (2026)
10
+ */
11
+ export declare const COMPATIBILITY_DATE = "2026-01-01";
12
+ /**
13
+ * Normalize an import specifier to a full URL
14
+ *
15
+ * Supports:
16
+ * - Full URLs: https://esm.sh/lodash@4.17.21 (unchanged)
17
+ * - Bare package names: lodash -> https://esm.sh/lodash
18
+ * - Package with version: lodash@4.17.21 -> https://esm.sh/lodash@4.17.21
19
+ * - Scoped packages: @scope/pkg -> https://esm.sh/@scope/pkg
20
+ */
21
+ export declare function normalizeImport(specifier: string): string;
22
+ /**
23
+ * Normalize an array of import specifiers
24
+ */
25
+ export declare function normalizeImports(imports: string[] | undefined): string[] | undefined;
26
+ /**
27
+ * Extract package name from import specifier for variable naming
28
+ * Supports: lodash, lodash@4.17.21, @scope/pkg, https://esm.sh/lodash
29
+ */
30
+ export declare function extractPackageName(specifier: string, index: number): string;
31
+ /**
32
+ * Default sandbox URL for worker fetch requests
33
+ */
34
+ export declare const SANDBOX_URL = "http://sandbox/execute";
35
+ /**
36
+ * Generate a unique sandbox worker ID
37
+ */
38
+ export declare const generateSandboxId: () => string;
39
+ /**
40
+ * Create an error result with consistent structure
41
+ */
42
+ export declare function createErrorResult(error: unknown, start: number): EvaluateResult;
43
+ /**
44
+ * Process a result from worker execution, adding duration
45
+ */
46
+ export declare function processResult(result: EvaluateResult, start: number): EvaluateResult;
47
+ /**
48
+ * Check if a domain matches a pattern (supports wildcards)
49
+ * @param domain - The domain to check (e.g., 'api.example.com')
50
+ * @param pattern - The pattern to match against (e.g., '*.example.com' or 'api.example.com')
51
+ * @returns true if the domain matches the pattern
52
+ */
53
+ export declare function matchesDomainPattern(domain: string, pattern: string): boolean;
54
+ /**
55
+ * Check if a URL's domain is in the allowed list
56
+ * @param url - The URL to check
57
+ * @param allowedDomains - List of allowed domains (supports wildcards like '*.example.com')
58
+ * @returns true if the URL's domain is allowed
59
+ */
60
+ export declare function isDomainAllowed(url: string, allowedDomains: string[]): boolean;
61
+ /**
62
+ * Generate JavaScript code for domain checking in workers
63
+ * This is embedded into the worker source code
64
+ */
65
+ export declare function generateDomainCheckCode(allowedDomains: string[]): string;
66
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD;;GAEG;AACH,eAAO,MAAM,kBAAkB,eAAe,CAAA;AAE9C;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,EAAE,GAAG,SAAS,CAGpF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAW3E;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,2BAA2B,CAAA;AAEnD;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAO,MAC2B,CAAA;AAEhE;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAO/E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAKnF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAoB7E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAgB9E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,CAsCxE"}
package/dist/shared.js ADDED
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Shared utilities for ai-evaluate
3
+ *
4
+ * Contains constants and helper functions used by both
5
+ * evaluate.ts (Workers) and node.ts (Node.js/Miniflare)
6
+ */
7
+ /**
8
+ * Compatibility date for dynamic workers (2026)
9
+ */
10
+ export const COMPATIBILITY_DATE = '2026-01-01';
11
+ /**
12
+ * Normalize an import specifier to a full URL
13
+ *
14
+ * Supports:
15
+ * - Full URLs: https://esm.sh/lodash@4.17.21 (unchanged)
16
+ * - Bare package names: lodash -> https://esm.sh/lodash
17
+ * - Package with version: lodash@4.17.21 -> https://esm.sh/lodash@4.17.21
18
+ * - Scoped packages: @scope/pkg -> https://esm.sh/@scope/pkg
19
+ */
20
+ export function normalizeImport(specifier) {
21
+ // Already a URL - return as-is
22
+ if (specifier.includes('://')) {
23
+ return specifier;
24
+ }
25
+ // Bare package name or scoped package - prepend esm.sh
26
+ return `https://esm.sh/${specifier}`;
27
+ }
28
+ /**
29
+ * Normalize an array of import specifiers
30
+ */
31
+ export function normalizeImports(imports) {
32
+ if (!imports || imports.length === 0)
33
+ return imports;
34
+ return imports.map(normalizeImport);
35
+ }
36
+ /**
37
+ * Extract package name from import specifier for variable naming
38
+ * Supports: lodash, lodash@4.17.21, @scope/pkg, https://esm.sh/lodash
39
+ */
40
+ export function extractPackageName(specifier, index) {
41
+ let pkgName;
42
+ if (specifier.includes('://')) {
43
+ // Full URL - extract from path
44
+ const match = specifier.match(/esm\.sh\/(@?[^@/]+)/);
45
+ pkgName = match ? match[1].replace(/^@/, '').replace(/-/g, '_') : `pkg${index}`;
46
+ }
47
+ else {
48
+ // Bare package name - extract before @ version
49
+ pkgName = specifier.split('@')[0].replace(/^@/, '').replace(/-/g, '_').replace(/\//g, '_');
50
+ }
51
+ return pkgName;
52
+ }
53
+ /**
54
+ * Default sandbox URL for worker fetch requests
55
+ */
56
+ export const SANDBOX_URL = 'http://sandbox/execute';
57
+ /**
58
+ * Generate a unique sandbox worker ID
59
+ */
60
+ export const generateSandboxId = () => `sandbox-${Date.now()}-${Math.random().toString(36).slice(2)}`;
61
+ /**
62
+ * Create an error result with consistent structure
63
+ */
64
+ export function createErrorResult(error, start) {
65
+ return {
66
+ success: false,
67
+ logs: [],
68
+ error: error instanceof Error ? error.message : String(error),
69
+ duration: Date.now() - start,
70
+ };
71
+ }
72
+ /**
73
+ * Process a result from worker execution, adding duration
74
+ */
75
+ export function processResult(result, start) {
76
+ return {
77
+ ...result,
78
+ duration: Date.now() - start,
79
+ };
80
+ }
81
+ /**
82
+ * Check if a domain matches a pattern (supports wildcards)
83
+ * @param domain - The domain to check (e.g., 'api.example.com')
84
+ * @param pattern - The pattern to match against (e.g., '*.example.com' or 'api.example.com')
85
+ * @returns true if the domain matches the pattern
86
+ */
87
+ export function matchesDomainPattern(domain, pattern) {
88
+ // Normalize both to lowercase
89
+ const normalizedDomain = domain.toLowerCase();
90
+ const normalizedPattern = pattern.toLowerCase();
91
+ // Exact match
92
+ if (normalizedDomain === normalizedPattern) {
93
+ return true;
94
+ }
95
+ // Wildcard pattern: *.example.com
96
+ if (normalizedPattern.startsWith('*.')) {
97
+ const suffix = normalizedPattern.slice(2); // Remove '*.'
98
+ // Domain must end with the suffix and have at least one character before it
99
+ // e.g., 'api.example.com' matches '*.example.com'
100
+ // but 'example.com' does not match '*.example.com'
101
+ return normalizedDomain.endsWith('.' + suffix) || normalizedDomain === suffix;
102
+ }
103
+ return false;
104
+ }
105
+ /**
106
+ * Check if a URL's domain is in the allowed list
107
+ * @param url - The URL to check
108
+ * @param allowedDomains - List of allowed domains (supports wildcards like '*.example.com')
109
+ * @returns true if the URL's domain is allowed
110
+ */
111
+ export function isDomainAllowed(url, allowedDomains) {
112
+ try {
113
+ const parsedUrl = new URL(url);
114
+ const hostname = parsedUrl.hostname;
115
+ for (const pattern of allowedDomains) {
116
+ if (matchesDomainPattern(hostname, pattern)) {
117
+ return true;
118
+ }
119
+ }
120
+ return false;
121
+ }
122
+ catch {
123
+ // Invalid URL - not allowed
124
+ return false;
125
+ }
126
+ }
127
+ /**
128
+ * Generate JavaScript code for domain checking in workers
129
+ * This is embedded into the worker source code
130
+ */
131
+ export function generateDomainCheckCode(allowedDomains) {
132
+ const domainsJson = JSON.stringify(allowedDomains);
133
+ return `
134
+ // Domain allowlist checking
135
+ const __allowedDomains__ = ${domainsJson};
136
+
137
+ const __matchesDomainPattern__ = (domain, pattern) => {
138
+ const normalizedDomain = domain.toLowerCase();
139
+ const normalizedPattern = pattern.toLowerCase();
140
+ if (normalizedDomain === normalizedPattern) return true;
141
+ if (normalizedPattern.startsWith('*.')) {
142
+ const suffix = normalizedPattern.slice(2);
143
+ return normalizedDomain.endsWith('.' + suffix) || normalizedDomain === suffix;
144
+ }
145
+ return false;
146
+ };
147
+
148
+ const __isDomainAllowed__ = (url) => {
149
+ try {
150
+ const parsedUrl = new URL(url);
151
+ const hostname = parsedUrl.hostname;
152
+ for (const pattern of __allowedDomains__) {
153
+ if (__matchesDomainPattern__(hostname, pattern)) return true;
154
+ }
155
+ return false;
156
+ } catch { return false; }
157
+ };
158
+
159
+ const __originalFetch__ = globalThis.fetch;
160
+ globalThis.fetch = async (input, init) => {
161
+ const url = typeof input === 'string' ? input : input instanceof Request ? input.url : String(input);
162
+ if (!__isDomainAllowed__(url)) {
163
+ throw new Error(\`Network access blocked: domain not in allowlist. Attempted: \${new URL(url).hostname}\`);
164
+ }
165
+ return __originalFetch__(input, init);
166
+ };
167
+ `;
168
+ }
169
+ //# sourceMappingURL=shared.js.map