tidewave 0.1.0 → 0.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.
@@ -0,0 +1,12 @@
1
+ import type { TidewaveConfig } from '../core';
2
+ import type { Request, Response } from './index';
3
+ export declare function checkRemoteIp(req: Request, res: Response, config: TidewaveConfig): boolean;
4
+ export declare function isLocalIp(ip?: string): boolean;
5
+ export declare function checkOrigin(req: Request, res: Response, config: TidewaveConfig): boolean;
6
+ export declare function getDefaultAllowedOrigins(config: TidewaveConfig): string[];
7
+ export declare function parseUrl(url: string): {
8
+ scheme?: string;
9
+ host: string;
10
+ port?: number;
11
+ } | null;
12
+ export declare function isOriginAllowed(origin: ReturnType<typeof parseUrl>, allowed: ReturnType<typeof parseUrl>): boolean;
@@ -0,0 +1,132 @@
1
+ import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
29
+
30
+ // src/http/security.ts
31
+ function fetchRemoteIp(req) {
32
+ const remote = req.socket.remoteAddress;
33
+ if (remote)
34
+ return remote;
35
+ const ip = req.headers["x-real-ip"] && req.headers["x-forwarded-for"] || null;
36
+ if (Array.isArray(ip)) {
37
+ return ip.join();
38
+ }
39
+ return ip;
40
+ }
41
+ function checkRemoteIp(req, res, config) {
42
+ const ip = fetchRemoteIp(req);
43
+ if (!ip)
44
+ return false;
45
+ if (isLocalIp(ip))
46
+ return true;
47
+ if (config.allowRemoteAccess)
48
+ return true;
49
+ const message = "For security reasons, Tidewave does not accept remote connections by default.\n\nIf you really want to allow remote connections, configure the Tidewave with the `allowRemoteAccess: true` option.";
50
+ console.warn(message);
51
+ res.statusCode = 403;
52
+ res.end(message);
53
+ return false;
54
+ }
55
+ function isLocalIp(ip) {
56
+ if (!ip)
57
+ return false;
58
+ if (ip.startsWith("127.0.0."))
59
+ return true;
60
+ if (ip === "::1")
61
+ return true;
62
+ if (ip === "::ffff:127.0.0.1")
63
+ return true;
64
+ return false;
65
+ }
66
+ function checkOrigin(req, res, config) {
67
+ const { origin } = req.headers;
68
+ if (!origin)
69
+ return true;
70
+ const allowedOrigins = config.allowedOrigins || getDefaultAllowedOrigins(config);
71
+ const originUrl = parseUrl(origin);
72
+ if (!originUrl) {
73
+ const message = `For security reasons, Tidewave only accepts requests from allowed origins.
74
+
75
+ Invalid origin: ${origin}`;
76
+ console.warn(message);
77
+ res.statusCode = 403;
78
+ res.end(message);
79
+ return false;
80
+ }
81
+ const isAllowed = allowedOrigins.some((allowed) => isOriginAllowed(originUrl, parseUrl(allowed)));
82
+ if (!isAllowed) {
83
+ const message = `For security reasons, Tidewave only accepts requests from the same origin your web app is running on.
84
+
85
+ If you really want to allow remote connections, configure the Tidewave with the \`allowedOrigins: [${JSON.stringify(origin)}]\` option.`;
86
+ console.warn(message);
87
+ res.statusCode = 403;
88
+ res.end(message);
89
+ return false;
90
+ }
91
+ return true;
92
+ }
93
+ function getDefaultAllowedOrigins(config) {
94
+ const { host, port } = config;
95
+ if (!(host || port))
96
+ return [];
97
+ return [`http://${host}:${port}`, `https://${host}:${port}`];
98
+ }
99
+ function parseUrl(url) {
100
+ try {
101
+ const isProtocolRelative = url.startsWith("//");
102
+ const parsed = new URL(isProtocolRelative ? "http:" + url : url);
103
+ return {
104
+ scheme: isProtocolRelative ? undefined : parsed.protocol?.slice(0, -1),
105
+ host: parsed.hostname,
106
+ port: parsed.port ? parseInt(parsed.port) : undefined
107
+ };
108
+ } catch {
109
+ return null;
110
+ }
111
+ }
112
+ function isOriginAllowed(origin, allowed) {
113
+ if (!origin || !allowed)
114
+ return false;
115
+ if (allowed.scheme && origin.scheme !== allowed.scheme)
116
+ return false;
117
+ if (allowed.port && origin.port !== allowed.port)
118
+ return false;
119
+ if (allowed.host.startsWith("*.")) {
120
+ const allowedDomain = allowed.host.slice(2);
121
+ return origin.host === allowedDomain || origin.host.endsWith("." + allowedDomain);
122
+ }
123
+ return origin.host === allowed.host;
124
+ }
125
+ export {
126
+ parseUrl,
127
+ isOriginAllowed,
128
+ isLocalIp,
129
+ getDefaultAllowedOrigins,
130
+ checkRemoteIp,
131
+ checkOrigin
132
+ };
@@ -0,0 +1,8 @@
1
+ import { extractDocs, getSourceLocation, formatOutput } from './resolution';
2
+ import { executeIsolated } from './evaluation/code_executor';
3
+ export declare const Tidewave: {
4
+ extractDocs: typeof extractDocs;
5
+ getSourceLocation: typeof getSourceLocation;
6
+ formatOutput: typeof formatOutput;
7
+ executeIsolated: typeof executeIsolated;
8
+ };
package/dist/index.js CHANGED
@@ -1,212 +1,31 @@
1
- // src/resolution/index.ts
2
- import ts5 from "typescript";
3
-
4
- // node:path
5
- var L = Object.create;
6
- var h = Object.defineProperty;
7
- var D = Object.getOwnPropertyDescriptor;
8
- var T = Object.getOwnPropertyNames;
9
- var _ = Object.getPrototypeOf;
10
- var E = Object.prototype.hasOwnProperty;
11
- var R = (s, e) => () => (e || s((e = { exports: {} }).exports, e), e.exports);
12
- var N = (s, e, r, t) => {
13
- if (e && typeof e == "object" || typeof e == "function")
14
- for (let i of T(e))
15
- !E.call(s, i) && i !== r && h(s, i, { get: () => e[i], enumerable: !(t = D(e, i)) || t.enumerable });
16
- return s;
17
- };
18
- var j = (s, e, r) => (r = s != null ? L(_(s)) : {}, N(e || !s || !s.__esModule ? h(r, "default", { value: s, enumerable: true }) : r, s));
19
- var k = R((W, w) => {
20
- function v(s) {
21
- if (typeof s != "string")
22
- throw new TypeError("Path must be a string. Received " + JSON.stringify(s));
23
- }
24
- function C(s, e) {
25
- for (var r = "", t = 0, i = -1, a = 0, n, l = 0;l <= s.length; ++l) {
26
- if (l < s.length)
27
- n = s.charCodeAt(l);
28
- else {
29
- if (n === 47)
30
- break;
31
- n = 47;
32
- }
33
- if (n === 47) {
34
- if (!(i === l - 1 || a === 1))
35
- if (i !== l - 1 && a === 2) {
36
- if (r.length < 2 || t !== 2 || r.charCodeAt(r.length - 1) !== 46 || r.charCodeAt(r.length - 2) !== 46) {
37
- if (r.length > 2) {
38
- var f = r.lastIndexOf("/");
39
- if (f !== r.length - 1) {
40
- f === -1 ? (r = "", t = 0) : (r = r.slice(0, f), t = r.length - 1 - r.lastIndexOf("/")), i = l, a = 0;
41
- continue;
42
- }
43
- } else if (r.length === 2 || r.length === 1) {
44
- r = "", t = 0, i = l, a = 0;
45
- continue;
46
- }
47
- }
48
- e && (r.length > 0 ? r += "/.." : r = "..", t = 2);
49
- } else
50
- r.length > 0 ? r += "/" + s.slice(i + 1, l) : r = s.slice(i + 1, l), t = l - i - 1;
51
- i = l, a = 0;
52
- } else
53
- n === 46 && a !== -1 ? ++a : a = -1;
54
- }
55
- return r;
56
- }
57
- function F(s, e) {
58
- var r = e.dir || e.root, t = e.base || (e.name || "") + (e.ext || "");
59
- return r ? r === e.root ? r + t : r + s + t : t;
60
- }
61
- var m = { resolve: function() {
62
- for (var e = "", r = false, t, i = arguments.length - 1;i >= -1 && !r; i--) {
63
- var a;
64
- i >= 0 ? a = arguments[i] : (t === undefined && (t = process.cwd()), a = t), v(a), a.length !== 0 && (e = a + "/" + e, r = a.charCodeAt(0) === 47);
65
- }
66
- return e = C(e, !r), r ? e.length > 0 ? "/" + e : "/" : e.length > 0 ? e : ".";
67
- }, normalize: function(e) {
68
- if (v(e), e.length === 0)
69
- return ".";
70
- var r = e.charCodeAt(0) === 47, t = e.charCodeAt(e.length - 1) === 47;
71
- return e = C(e, !r), e.length === 0 && !r && (e = "."), e.length > 0 && t && (e += "/"), r ? "/" + e : e;
72
- }, isAbsolute: function(e) {
73
- return v(e), e.length > 0 && e.charCodeAt(0) === 47;
74
- }, join: function() {
75
- if (arguments.length === 0)
76
- return ".";
77
- for (var e, r = 0;r < arguments.length; ++r) {
78
- var t = arguments[r];
79
- v(t), t.length > 0 && (e === undefined ? e = t : e += "/" + t);
80
- }
81
- return e === undefined ? "." : m.normalize(e);
82
- }, relative: function(e, r) {
83
- if (v(e), v(r), e === r || (e = m.resolve(e), r = m.resolve(r), e === r))
84
- return "";
85
- for (var t = 1;t < e.length && e.charCodeAt(t) === 47; ++t)
86
- ;
87
- for (var i = e.length, a = i - t, n = 1;n < r.length && r.charCodeAt(n) === 47; ++n)
88
- ;
89
- for (var l = r.length, f = l - n, c = a < f ? a : f, d = -1, o = 0;o <= c; ++o) {
90
- if (o === c) {
91
- if (f > c) {
92
- if (r.charCodeAt(n + o) === 47)
93
- return r.slice(n + o + 1);
94
- if (o === 0)
95
- return r.slice(n + o);
96
- } else
97
- a > c && (e.charCodeAt(t + o) === 47 ? d = o : o === 0 && (d = 0));
98
- break;
99
- }
100
- var A = e.charCodeAt(t + o), z = r.charCodeAt(n + o);
101
- if (A !== z)
102
- break;
103
- A === 47 && (d = o);
104
- }
105
- var b = "";
106
- for (o = t + d + 1;o <= i; ++o)
107
- (o === i || e.charCodeAt(o) === 47) && (b.length === 0 ? b += ".." : b += "/..");
108
- return b.length > 0 ? b + r.slice(n + d) : (n += d, r.charCodeAt(n) === 47 && ++n, r.slice(n));
109
- }, _makeLong: function(e) {
110
- return e;
111
- }, dirname: function(e) {
112
- if (v(e), e.length === 0)
113
- return ".";
114
- for (var r = e.charCodeAt(0), t = r === 47, i = -1, a = true, n = e.length - 1;n >= 1; --n)
115
- if (r = e.charCodeAt(n), r === 47) {
116
- if (!a) {
117
- i = n;
118
- break;
119
- }
120
- } else
121
- a = false;
122
- return i === -1 ? t ? "/" : "." : t && i === 1 ? "//" : e.slice(0, i);
123
- }, basename: function(e, r) {
124
- if (r !== undefined && typeof r != "string")
125
- throw new TypeError('"ext" argument must be a string');
126
- v(e);
127
- var t = 0, i = -1, a = true, n;
128
- if (r !== undefined && r.length > 0 && r.length <= e.length) {
129
- if (r.length === e.length && r === e)
130
- return "";
131
- var l = r.length - 1, f = -1;
132
- for (n = e.length - 1;n >= 0; --n) {
133
- var c = e.charCodeAt(n);
134
- if (c === 47) {
135
- if (!a) {
136
- t = n + 1;
137
- break;
138
- }
139
- } else
140
- f === -1 && (a = false, f = n + 1), l >= 0 && (c === r.charCodeAt(l) ? --l === -1 && (i = n) : (l = -1, i = f));
141
- }
142
- return t === i ? i = f : i === -1 && (i = e.length), e.slice(t, i);
143
- } else {
144
- for (n = e.length - 1;n >= 0; --n)
145
- if (e.charCodeAt(n) === 47) {
146
- if (!a) {
147
- t = n + 1;
148
- break;
149
- }
150
- } else
151
- i === -1 && (a = false, i = n + 1);
152
- return i === -1 ? "" : e.slice(t, i);
153
- }
154
- }, extname: function(e) {
155
- v(e);
156
- for (var r = -1, t = 0, i = -1, a = true, n = 0, l = e.length - 1;l >= 0; --l) {
157
- var f = e.charCodeAt(l);
158
- if (f === 47) {
159
- if (!a) {
160
- t = l + 1;
161
- break;
162
- }
163
- continue;
164
- }
165
- i === -1 && (a = false, i = l + 1), f === 46 ? r === -1 ? r = l : n !== 1 && (n = 1) : r !== -1 && (n = -1);
166
- }
167
- return r === -1 || i === -1 || n === 0 || n === 1 && r === i - 1 && r === t + 1 ? "" : e.slice(r, i);
168
- }, format: function(e) {
169
- if (e === null || typeof e != "object")
170
- throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof e);
171
- return F("/", e);
172
- }, parse: function(e) {
173
- v(e);
174
- var r = { root: "", dir: "", base: "", ext: "", name: "" };
175
- if (e.length === 0)
176
- return r;
177
- var t = e.charCodeAt(0), i = t === 47, a;
178
- i ? (r.root = "/", a = 1) : a = 0;
179
- for (var n = -1, l = 0, f = -1, c = true, d = e.length - 1, o = 0;d >= a; --d) {
180
- if (t = e.charCodeAt(d), t === 47) {
181
- if (!c) {
182
- l = d + 1;
183
- break;
184
- }
185
- continue;
186
- }
187
- f === -1 && (c = false, f = d + 1), t === 46 ? n === -1 ? n = d : o !== 1 && (o = 1) : n !== -1 && (o = -1);
188
- }
189
- return n === -1 || f === -1 || o === 0 || o === 1 && n === f - 1 && n === l + 1 ? f !== -1 && (l === 0 && i ? r.base = r.name = e.slice(1, f) : r.base = r.name = e.slice(l, f)) : (l === 0 && i ? (r.name = e.slice(1, n), r.base = e.slice(1, f)) : (r.name = e.slice(l, n), r.base = e.slice(l, f)), r.ext = e.slice(n, f)), l > 0 ? r.dir = e.slice(0, l - 1) : i && (r.dir = "/"), r;
190
- }, sep: "/", delimiter: ":", win32: null, posix: null };
191
- m.posix = m;
192
- w.exports = m;
193
- });
194
- var x = j(k());
195
- var u = x;
196
- var J = x;
197
- var P = function(s) {
198
- return s;
1
+ import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
199
17
  };
200
- var S = function() {
201
- throw new Error("Not implemented");
18
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
202
27
  };
203
- u.parse ??= S;
204
- J.parse ??= S;
205
- var g = { resolve: u.resolve.bind(u), normalize: u.normalize.bind(u), isAbsolute: u.isAbsolute.bind(u), join: u.join.bind(u), relative: u.relative.bind(u), toNamespacedPath: P, dirname: u.dirname.bind(u), basename: u.basename.bind(u), extname: u.extname.bind(u), format: u.format.bind(u), parse: u.parse.bind(u), sep: "/", delimiter: ":", win32: undefined, posix: undefined, _makeLong: P };
206
- var y = { sep: "\\", delimiter: ";", win32: undefined, ...g, posix: g };
207
- g.win32 = y.win32 = y;
208
- g.posix = g;
209
- var q = g;
28
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
210
29
 
211
30
  // src/core.ts
212
31
  function isError(result) {
@@ -239,6 +58,7 @@ function createExtractError(code, message, details) {
239
58
 
240
59
  // src/resolution/module-resolver.ts
241
60
  import ts from "typescript";
61
+ import path from "node:path";
242
62
  function loadTsConfig(prefix) {
243
63
  const projectPath = prefix || process.cwd();
244
64
  const configPath = ts.findConfigFile(projectPath, ts.sys.fileExists, "tsconfig.json");
@@ -258,7 +78,7 @@ function loadTsConfig(prefix) {
258
78
  if (configPath) {
259
79
  const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
260
80
  if (configFile.config) {
261
- const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, q.dirname(configPath));
81
+ const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
262
82
  compilerOptions = { ...compilerOptions, ...parsedConfig.options };
263
83
  rootNames = parsedConfig.fileNames;
264
84
  }
@@ -270,7 +90,7 @@ function loadTsConfig(prefix) {
270
90
  }
271
91
  function resolveModule(moduleName, compilerOptions) {
272
92
  if (moduleName.startsWith("./") || moduleName.startsWith("../") || moduleName.includes(".") && !moduleName.includes("/")) {
273
- const absolutePath = q.resolve(moduleName);
93
+ const absolutePath = path.resolve(moduleName);
274
94
  if (ts.sys.fileExists(absolutePath)) {
275
95
  const dedicatedProgram = ts.createProgram([absolutePath], compilerOptions);
276
96
  const sourceFile = dedicatedProgram.getSourceFile(absolutePath);
@@ -279,7 +99,7 @@ function resolveModule(moduleName, compilerOptions) {
279
99
  }
280
100
  }
281
101
  }
282
- const moduleResolver = ts.resolveModuleName(moduleName, q.resolve("./index.ts"), compilerOptions, ts.sys);
102
+ const moduleResolver = ts.resolveModuleName(moduleName, path.resolve("./index.ts"), compilerOptions, ts.sys);
283
103
  if (moduleResolver.resolvedModule) {
284
104
  const { resolvedFileName } = moduleResolver.resolvedModule;
285
105
  const dedicatedProgram = ts.createProgram([resolvedFileName], compilerOptions);
@@ -340,11 +160,9 @@ function resolveNodeBuiltin(moduleName, compilerOptions) {
340
160
  return resolveError(moduleName, process.cwd());
341
161
  }
342
162
 
343
- // src/resolution/symbol-finder.ts
344
- import ts4 from "typescript";
345
-
346
163
  // src/resolution/utils.ts
347
164
  import ts2 from "typescript";
165
+ import path2 from "node:path";
348
166
  function getLocation(symbol) {
349
167
  if (symbol.valueDeclaration) {
350
168
  const sourceFile = symbol.valueDeclaration.getSourceFile();
@@ -352,7 +170,7 @@ function getLocation(symbol) {
352
170
  let { fileName } = sourceFile;
353
171
  const cwd = process.cwd();
354
172
  if (fileName.startsWith(cwd)) {
355
- fileName = q.relative(cwd, fileName);
173
+ fileName = path2.relative(cwd, fileName);
356
174
  }
357
175
  return `${fileName}:${line + 1}:${character + 1}`;
358
176
  }
@@ -365,7 +183,7 @@ function getLocation(symbol) {
365
183
  let fileName = sourceFile?.fileName;
366
184
  const cwd = process.cwd();
367
185
  if (fileName?.startsWith(cwd)) {
368
- fileName = q.relative(cwd, fileName);
186
+ fileName = path2.relative(cwd, fileName);
369
187
  }
370
188
  return `${fileName}:${line + 1}:${character + 1}`;
371
189
  }
@@ -543,6 +361,7 @@ ${info.name}`);
543
361
  }
544
362
 
545
363
  // src/resolution/symbol-finder.ts
364
+ import ts4 from "typescript";
546
365
  function findSymbolInJavaScriptFile(sourceFile, checker, symbolName) {
547
366
  for (const statement of sourceFile.statements) {
548
367
  if (ts4.isFunctionDeclaration(statement) && statement.name?.text === symbolName) {
@@ -710,6 +529,8 @@ function getSymbolInfo(checker, symbol, member, isStatic) {
710
529
  }
711
530
 
712
531
  // src/resolution/index.ts
532
+ import ts5 from "typescript";
533
+ import path3 from "node:path";
713
534
  function parseModulePath(modulePath) {
714
535
  let module;
715
536
  let symbolPath;
@@ -914,12 +735,12 @@ async function getSourceLocation(reference) {
914
735
  }
915
736
  const moduleName = reference;
916
737
  if (moduleName.startsWith("./") || moduleName.startsWith("../")) {
917
- const absolutePath = q.resolve(moduleName);
738
+ const absolutePath = path3.resolve(moduleName);
918
739
  if (ts5.sys.fileExists(absolutePath)) {
919
740
  const cwd = process.cwd();
920
741
  let finalPath;
921
742
  if (absolutePath.startsWith(cwd)) {
922
- const relativePath = q.relative(cwd, absolutePath);
743
+ const relativePath = path3.relative(cwd, absolutePath);
923
744
  finalPath = relativePath.startsWith("..") ? absolutePath : relativePath;
924
745
  } else {
925
746
  finalPath = absolutePath;
@@ -928,13 +749,13 @@ async function getSourceLocation(reference) {
928
749
  }
929
750
  }
930
751
  const config = loadTsConfig(options.prefix);
931
- const moduleResolver = ts5.resolveModuleName(moduleName, q.resolve("./index.ts"), config.options, ts5.sys);
752
+ const moduleResolver = ts5.resolveModuleName(moduleName, path3.resolve("./index.ts"), config.options, ts5.sys);
932
753
  if (moduleResolver.resolvedModule) {
933
754
  const { resolvedFileName } = moduleResolver.resolvedModule;
934
755
  const cwd = process.cwd();
935
756
  let finalPath;
936
757
  if (resolvedFileName.startsWith(cwd)) {
937
- const relativePath = q.relative(cwd, resolvedFileName);
758
+ const relativePath = path3.relative(cwd, resolvedFileName);
938
759
  finalPath = relativePath.startsWith("..") ? resolvedFileName : relativePath;
939
760
  } else {
940
761
  finalPath = resolvedFileName;
@@ -1000,21 +821,86 @@ async function extractSymbol(request, options = {}) {
1000
821
  };
1001
822
  }
1002
823
  }
824
+ // src/evaluation/eval_worker.ts
825
+ process.on("message", async ({ code, args }) => {
826
+ if (!process.send) {
827
+ console.error("[Tidewave] Unable to establish communication channel with code-executor.");
828
+ process.exit(1);
829
+ }
830
+ try {
831
+ const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor;
832
+ const fn = new AsyncFunction(code);
833
+ const result = await fn(...args);
834
+ process.send({
835
+ type: "result",
836
+ success: true,
837
+ data: (result || null) && result
838
+ });
839
+ } catch (error) {
840
+ process.send({
841
+ type: "result",
842
+ success: false,
843
+ data: new String(error)
844
+ });
845
+ }
846
+ process.exit(0);
847
+ });
848
+
849
+ // src/evaluation/code_executor.ts
850
+ import { fork } from "child_process";
851
+ async function executeIsolated(request) {
852
+ return new Promise((resolve) => {
853
+ const workerPath = __require.resolve("./eval_worker");
854
+ const child = fork(workerPath, { silent: true });
855
+ const evaluation = {
856
+ success: false,
857
+ result: null,
858
+ stdout: "",
859
+ stderr: ""
860
+ };
861
+ child.stdout?.on("data", (data) => {
862
+ evaluation.stdout += data.toString();
863
+ });
864
+ child.stderr?.on("data", (data) => {
865
+ evaluation.stderr += data.toString();
866
+ });
867
+ child.on("message", (msg) => {
868
+ if (msg.type === "result") {
869
+ const { data, success } = msg;
870
+ evaluation.result = data;
871
+ evaluation.success = success;
872
+ }
873
+ });
874
+ child.on("exit", (code) => {
875
+ resolve({
876
+ success: evaluation.success && code === 0,
877
+ result: evaluation.result,
878
+ stdout: evaluation.stdout.trim(),
879
+ stderr: evaluation.stderr.trim()
880
+ });
881
+ });
882
+ const { timeout } = request;
883
+ const timeoutId = setTimeout(() => {
884
+ child.kill("SIGKILL");
885
+ resolve({
886
+ success: false,
887
+ result: `Evaluation timed out after ${timeout} milliseconds`,
888
+ stdout: evaluation.stdout,
889
+ stderr: evaluation.stderr
890
+ });
891
+ }, timeout);
892
+ child.on("exit", () => clearTimeout(timeoutId));
893
+ child.send(request);
894
+ });
895
+ }
896
+
1003
897
  // src/index.ts
1004
- var TidewaveExtractor = {
898
+ var Tidewave = {
1005
899
  extractDocs,
1006
900
  getSourceLocation,
1007
- formatOutput
901
+ formatOutput,
902
+ executeIsolated
1008
903
  };
1009
904
  export {
1010
- resolveError,
1011
- isResolveError,
1012
- isExtractError,
1013
- isError,
1014
- getSourceLocation,
1015
- formatOutput,
1016
- extractSymbol,
1017
- extractDocs,
1018
- createExtractError,
1019
- TidewaveExtractor
905
+ Tidewave
1020
906
  };
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
2
+ export declare function serveMcp(transport: Transport): Promise<void>;