tidewave 0.3.0 → 0.4.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 +131 -94
- package/dist/cli/index.js +12024 -11669
- package/dist/core.d.ts +5 -0
- package/dist/evaluation/eval_worker.js +1 -30
- package/dist/index.d.ts +2 -2
- package/dist/logger/circular-buffer.d.ts +54 -0
- package/dist/logger/instrumentation.d.ts +2 -0
- package/dist/logger/tidewave-log-record-processor.d.ts +17 -0
- package/dist/logger/tidewave-span-processor.d.ts +26 -0
- package/dist/{next-js.d.ts → next-js/handler.d.ts} +2 -6
- package/dist/{http/index.js → next-js/handler.js} +33003 -32394
- package/dist/next-js/instrumentation.d.ts +7 -0
- package/dist/next-js/instrumentation.js +255 -0
- package/dist/tools.d.ts +18 -0
- package/dist/vite-plugin.d.ts +1 -0
- package/dist/vite-plugin.js +32255 -31741
- package/package.json +22 -7
- package/dist/core.js +0 -64
- package/dist/evaluation/code_executor.js +0 -104
- package/dist/http/security.js +0 -132
- package/dist/index.js +0 -906
- package/dist/mcp.js +0 -14174
- package/dist/next-js.js +0 -40304
- package/dist/resolution/formatters.js +0 -155
- package/dist/resolution/index.js +0 -829
- package/dist/resolution/module-resolver.js +0 -166
- package/dist/resolution/symbol-finder.js +0 -429
- package/dist/resolution/utils.js +0 -112
- package/dist/tools.js +0 -4099
package/dist/index.js
DELETED
|
@@ -1,906 +0,0 @@
|
|
|
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/core.ts
|
|
31
|
-
function isError(result) {
|
|
32
|
-
return result != null && "success" in result && result.success === false;
|
|
33
|
-
}
|
|
34
|
-
function isResolveError(result) {
|
|
35
|
-
return result != null && "success" in result && result.success === false;
|
|
36
|
-
}
|
|
37
|
-
function isExtractError(result) {
|
|
38
|
-
return result != null && "error" in result;
|
|
39
|
-
}
|
|
40
|
-
function resolveError(specifier, source) {
|
|
41
|
-
return {
|
|
42
|
-
success: false,
|
|
43
|
-
error: {
|
|
44
|
-
code: "MODULE_NOT_FOUND",
|
|
45
|
-
message: `Cannot resolve module '${specifier}' from '${source}'`
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
function createExtractError(code, message, details) {
|
|
50
|
-
return {
|
|
51
|
-
error: {
|
|
52
|
-
code,
|
|
53
|
-
message,
|
|
54
|
-
details
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// src/resolution/module-resolver.ts
|
|
60
|
-
import ts from "typescript";
|
|
61
|
-
import path from "node:path";
|
|
62
|
-
function loadTsConfig(prefix) {
|
|
63
|
-
const projectPath = prefix || process.cwd();
|
|
64
|
-
const configPath = ts.findConfigFile(projectPath, ts.sys.fileExists, "tsconfig.json");
|
|
65
|
-
let compilerOptions = {
|
|
66
|
-
target: ts.ScriptTarget.ES2020,
|
|
67
|
-
module: ts.ModuleKind.CommonJS,
|
|
68
|
-
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
69
|
-
esModuleInterop: true,
|
|
70
|
-
allowSyntheticDefaultImports: true,
|
|
71
|
-
skipLibCheck: true,
|
|
72
|
-
allowJs: true,
|
|
73
|
-
declaration: true,
|
|
74
|
-
typeRoots: ["./node_modules/@types"],
|
|
75
|
-
baseUrl: "."
|
|
76
|
-
};
|
|
77
|
-
let rootNames = [];
|
|
78
|
-
if (configPath) {
|
|
79
|
-
const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
80
|
-
if (configFile.config) {
|
|
81
|
-
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
|
|
82
|
-
compilerOptions = { ...compilerOptions, ...parsedConfig.options };
|
|
83
|
-
rootNames = parsedConfig.fileNames;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return {
|
|
87
|
-
fileNames: rootNames,
|
|
88
|
-
options: compilerOptions
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
function resolveModule(moduleName, compilerOptions) {
|
|
92
|
-
if (moduleName.startsWith("./") || moduleName.startsWith("../") || moduleName.includes(".") && !moduleName.includes("/")) {
|
|
93
|
-
const absolutePath = path.resolve(moduleName);
|
|
94
|
-
if (ts.sys.fileExists(absolutePath)) {
|
|
95
|
-
const dedicatedProgram = ts.createProgram([absolutePath], compilerOptions);
|
|
96
|
-
const sourceFile = dedicatedProgram.getSourceFile(absolutePath);
|
|
97
|
-
if (sourceFile) {
|
|
98
|
-
return { sourceFile, program: dedicatedProgram };
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
const moduleResolver = ts.resolveModuleName(moduleName, path.resolve("./index.ts"), compilerOptions, ts.sys);
|
|
103
|
-
if (moduleResolver.resolvedModule) {
|
|
104
|
-
const { resolvedFileName } = moduleResolver.resolvedModule;
|
|
105
|
-
const dedicatedProgram = ts.createProgram([resolvedFileName], compilerOptions);
|
|
106
|
-
const sourceFile = dedicatedProgram.getSourceFile(resolvedFileName);
|
|
107
|
-
if (sourceFile) {
|
|
108
|
-
return { sourceFile, program: dedicatedProgram };
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return resolveError(moduleName, process.cwd());
|
|
112
|
-
}
|
|
113
|
-
function resolveNodeBuiltin(moduleName, compilerOptions) {
|
|
114
|
-
if (!moduleName.startsWith("node:")) {
|
|
115
|
-
return resolveError(moduleName, process.cwd());
|
|
116
|
-
}
|
|
117
|
-
const symbolName = moduleName.slice(5);
|
|
118
|
-
const globalBuiltins = [
|
|
119
|
-
"Math",
|
|
120
|
-
"Date",
|
|
121
|
-
"JSON",
|
|
122
|
-
"Object",
|
|
123
|
-
"Array",
|
|
124
|
-
"String",
|
|
125
|
-
"Number",
|
|
126
|
-
"Boolean",
|
|
127
|
-
"RegExp",
|
|
128
|
-
"Function",
|
|
129
|
-
"Promise",
|
|
130
|
-
"Map",
|
|
131
|
-
"Set",
|
|
132
|
-
"WeakMap",
|
|
133
|
-
"WeakSet",
|
|
134
|
-
"Symbol",
|
|
135
|
-
"Error",
|
|
136
|
-
"console",
|
|
137
|
-
"process",
|
|
138
|
-
"Buffer",
|
|
139
|
-
"global",
|
|
140
|
-
"__dirname",
|
|
141
|
-
"__filename"
|
|
142
|
-
];
|
|
143
|
-
if (globalBuiltins.includes(symbolName)) {
|
|
144
|
-
const syntheticContent = `declare const ${symbolName}: typeof globalThis.${symbolName};`;
|
|
145
|
-
const syntheticFileName = `synthetic-global-${symbolName}.d.ts`;
|
|
146
|
-
const host = ts.createCompilerHost(compilerOptions);
|
|
147
|
-
const originalGetSourceFile = host.getSourceFile;
|
|
148
|
-
host.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
|
|
149
|
-
if (fileName === syntheticFileName) {
|
|
150
|
-
return ts.createSourceFile(fileName, syntheticContent, ts.ScriptTarget.Latest, true);
|
|
151
|
-
}
|
|
152
|
-
return originalGetSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
|
|
153
|
-
};
|
|
154
|
-
const dedicatedProgram = ts.createProgram([syntheticFileName], compilerOptions, host);
|
|
155
|
-
const sourceFile = dedicatedProgram.getSourceFile(syntheticFileName);
|
|
156
|
-
if (sourceFile) {
|
|
157
|
-
return { sourceFile, program: dedicatedProgram };
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return resolveError(moduleName, process.cwd());
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// src/resolution/utils.ts
|
|
164
|
-
import ts2 from "typescript";
|
|
165
|
-
import path2 from "node:path";
|
|
166
|
-
function getLocation(symbol) {
|
|
167
|
-
if (symbol.valueDeclaration) {
|
|
168
|
-
const sourceFile = symbol.valueDeclaration.getSourceFile();
|
|
169
|
-
const { line, character } = sourceFile.getLineAndCharacterOfPosition(symbol.valueDeclaration.getStart());
|
|
170
|
-
let { fileName } = sourceFile;
|
|
171
|
-
const cwd = process.cwd();
|
|
172
|
-
if (fileName.startsWith(cwd)) {
|
|
173
|
-
fileName = path2.relative(cwd, fileName);
|
|
174
|
-
}
|
|
175
|
-
return `${fileName}:${line + 1}:${character + 1}`;
|
|
176
|
-
}
|
|
177
|
-
if (symbol.declarations && symbol.declarations.length > 0) {
|
|
178
|
-
const [firstDeclaration] = symbol.declarations;
|
|
179
|
-
const sourceFile = firstDeclaration?.getSourceFile();
|
|
180
|
-
if (sourceFile === undefined || firstDeclaration === undefined)
|
|
181
|
-
return "unknown";
|
|
182
|
-
const { line, character } = sourceFile.getLineAndCharacterOfPosition(firstDeclaration.getStart());
|
|
183
|
-
let fileName = sourceFile?.fileName;
|
|
184
|
-
const cwd = process.cwd();
|
|
185
|
-
if (fileName?.startsWith(cwd)) {
|
|
186
|
-
fileName = path2.relative(cwd, fileName);
|
|
187
|
-
}
|
|
188
|
-
return `${fileName}:${line + 1}:${character + 1}`;
|
|
189
|
-
}
|
|
190
|
-
return "unknown";
|
|
191
|
-
}
|
|
192
|
-
function getDocumentation(checker, symbol) {
|
|
193
|
-
return ts2.displayPartsToString(symbol.getDocumentationComment(checker));
|
|
194
|
-
}
|
|
195
|
-
function getJSDoc(checker, symbol) {
|
|
196
|
-
const jsDocTags = symbol.getJsDocTags(checker);
|
|
197
|
-
return jsDocTags.map((tag) => {
|
|
198
|
-
const tagName = tag.name;
|
|
199
|
-
const tagText = tag.text ? ts2.displayPartsToString(tag.text) : "";
|
|
200
|
-
return `@${tagName}${tagText ? " " + tagText : ""}`;
|
|
201
|
-
}).join(`
|
|
202
|
-
`);
|
|
203
|
-
}
|
|
204
|
-
function getSymbolKind(symbol) {
|
|
205
|
-
const flags = symbol.getFlags();
|
|
206
|
-
if (flags & ts2.SymbolFlags.Function)
|
|
207
|
-
return "function";
|
|
208
|
-
if (flags & ts2.SymbolFlags.Class)
|
|
209
|
-
return "class";
|
|
210
|
-
if (flags & ts2.SymbolFlags.Interface)
|
|
211
|
-
return "interface";
|
|
212
|
-
if (flags & ts2.SymbolFlags.TypeAlias)
|
|
213
|
-
return "type";
|
|
214
|
-
if (flags & ts2.SymbolFlags.Variable)
|
|
215
|
-
return "variable";
|
|
216
|
-
if (flags & ts2.SymbolFlags.Property)
|
|
217
|
-
return "property";
|
|
218
|
-
if (flags & ts2.SymbolFlags.Method)
|
|
219
|
-
return "method";
|
|
220
|
-
if (flags & ts2.SymbolFlags.Enum)
|
|
221
|
-
return "enum";
|
|
222
|
-
if (flags & ts2.SymbolFlags.Module)
|
|
223
|
-
return "module";
|
|
224
|
-
if (symbol.valueDeclaration) {
|
|
225
|
-
if (ts2.isFunctionDeclaration(symbol.valueDeclaration)) {
|
|
226
|
-
return "function";
|
|
227
|
-
}
|
|
228
|
-
if (ts2.isClassDeclaration(symbol.valueDeclaration)) {
|
|
229
|
-
return "class";
|
|
230
|
-
}
|
|
231
|
-
if (ts2.isVariableDeclaration(symbol.valueDeclaration)) {
|
|
232
|
-
return "variable";
|
|
233
|
-
}
|
|
234
|
-
if (ts2.isMethodDeclaration(symbol.valueDeclaration)) {
|
|
235
|
-
return "method";
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
return "unknown";
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// src/resolution/formatters.ts
|
|
242
|
-
import ts3 from "typescript";
|
|
243
|
-
function getSignature(checker, symbol, type) {
|
|
244
|
-
const signatures = checker.getSignaturesOfType(type, ts3.SignatureKind.Call);
|
|
245
|
-
if (signatures.length > 0) {
|
|
246
|
-
return signatures.map((sig) => {
|
|
247
|
-
const sigString = checker.signatureToString(sig);
|
|
248
|
-
return `${symbol.getName()}${sigString}`;
|
|
249
|
-
}).join(`
|
|
250
|
-
`);
|
|
251
|
-
}
|
|
252
|
-
const constructSignatures = checker.getSignaturesOfType(type, ts3.SignatureKind.Construct);
|
|
253
|
-
if (constructSignatures.length > 0) {
|
|
254
|
-
return constructSignatures.map((sig) => "new " + checker.signatureToString(sig)).join(`
|
|
255
|
-
`);
|
|
256
|
-
}
|
|
257
|
-
if (symbol.valueDeclaration || symbol.declarations && symbol.declarations.length > 0) {
|
|
258
|
-
const declaration = symbol.valueDeclaration || symbol.declarations[0];
|
|
259
|
-
if (!declaration)
|
|
260
|
-
return checker.typeToString(type);
|
|
261
|
-
const sourceFile = declaration.getSourceFile();
|
|
262
|
-
if (ts3.isFunctionDeclaration(declaration) && declaration.name) {
|
|
263
|
-
const functionType = checker.getTypeOfSymbolAtLocation(symbol, declaration);
|
|
264
|
-
const functionSignatures = checker.getSignaturesOfType(functionType, ts3.SignatureKind.Call);
|
|
265
|
-
if (functionSignatures.length > 0) {
|
|
266
|
-
return functionSignatures.map((sig) => checker.signatureToString(sig)).join(`
|
|
267
|
-
`);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
if (ts3.isInterfaceDeclaration(declaration) || ts3.isTypeAliasDeclaration(declaration)) {
|
|
271
|
-
const start2 = declaration.getStart();
|
|
272
|
-
const end2 = declaration.getEnd();
|
|
273
|
-
const text2 = sourceFile.text.substring(start2, end2);
|
|
274
|
-
const lines = text2.split(`
|
|
275
|
-
`).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
276
|
-
if (ts3.isInterfaceDeclaration(declaration)) {
|
|
277
|
-
const bodyStart = text2.indexOf("{");
|
|
278
|
-
const bodyEnd = text2.lastIndexOf("}");
|
|
279
|
-
if (bodyStart !== -1 && bodyEnd !== -1) {
|
|
280
|
-
const body = text2.substring(bodyStart, bodyEnd + 1);
|
|
281
|
-
const interfaceName = `interface ${declaration.name.text}`;
|
|
282
|
-
const compactBody = body.replace(/\s*\n\s*/g, " ").replace(/\s+/g, " ");
|
|
283
|
-
return `${interfaceName} ${compactBody}`;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
return lines.join(" ").replace(/\s+/g, " ");
|
|
287
|
-
}
|
|
288
|
-
if (ts3.isClassDeclaration(declaration)) {
|
|
289
|
-
const classType = checker.getTypeOfSymbolAtLocation(symbol, declaration);
|
|
290
|
-
const classConstructSignatures = checker.getSignaturesOfType(classType, ts3.SignatureKind.Construct);
|
|
291
|
-
if (classConstructSignatures.length > 0) {
|
|
292
|
-
return classConstructSignatures.map((sig) => "new " + checker.signatureToString(sig)).join(`
|
|
293
|
-
`);
|
|
294
|
-
} else {
|
|
295
|
-
const start2 = declaration.getStart();
|
|
296
|
-
const end2 = Math.min(declaration.getStart() + 100, declaration.getEnd());
|
|
297
|
-
const text2 = sourceFile.text.substring(start2, end2);
|
|
298
|
-
return text2.split(`
|
|
299
|
-
`)[0]?.trim() + (text2.includes(`
|
|
300
|
-
`) ? "..." : "") || "";
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
const start = declaration.getStart();
|
|
304
|
-
const end = Math.min(declaration.getStart() + 100, declaration.getEnd());
|
|
305
|
-
const text = sourceFile.text.substring(start, end);
|
|
306
|
-
return text.split(`
|
|
307
|
-
`)[0]?.trim() + (text.includes(`
|
|
308
|
-
`) ? "..." : "") || "";
|
|
309
|
-
}
|
|
310
|
-
return checker.typeToString(type);
|
|
311
|
-
}
|
|
312
|
-
function getTypeString(checker, symbol, type) {
|
|
313
|
-
if (symbol.flags & (ts3.SymbolFlags.Interface | ts3.SymbolFlags.TypeAlias)) {
|
|
314
|
-
const declaration = symbol.valueDeclaration || symbol.declarations && symbol.declarations[0];
|
|
315
|
-
if (declaration && ts3.isInterfaceDeclaration(declaration)) {
|
|
316
|
-
const properties = type.getProperties();
|
|
317
|
-
if (properties.length > 0) {
|
|
318
|
-
const propertyStrings = properties.map((prop) => {
|
|
319
|
-
const propDeclaration = prop.valueDeclaration || prop.declarations && prop.declarations[0];
|
|
320
|
-
const propType = propDeclaration ? checker.getTypeOfSymbolAtLocation(prop, propDeclaration) : checker.getTypeAtLocation(prop.declarations[0]);
|
|
321
|
-
const propTypeString = checker.typeToString(propType);
|
|
322
|
-
const isOptional = prop.flags & ts3.SymbolFlags.Optional;
|
|
323
|
-
return `${prop.getName()}${isOptional ? "?" : ""}: ${propTypeString}`;
|
|
324
|
-
});
|
|
325
|
-
return `{ ${propertyStrings.join("; ")} }`;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
const defaultTypeString = checker.typeToString(type);
|
|
330
|
-
if (defaultTypeString === "any" && symbol.flags & ts3.SymbolFlags.Interface) {
|
|
331
|
-
return `interface ${symbol.getName()}`;
|
|
332
|
-
}
|
|
333
|
-
return defaultTypeString;
|
|
334
|
-
}
|
|
335
|
-
function formatOutput(info) {
|
|
336
|
-
const output = [];
|
|
337
|
-
output.push(`
|
|
338
|
-
${info.name}`);
|
|
339
|
-
output.push(`Kind: ${info.kind}`);
|
|
340
|
-
output.push(`Location: ${info.location}`);
|
|
341
|
-
output.push("");
|
|
342
|
-
if (info.signature) {
|
|
343
|
-
output.push("Signature:");
|
|
344
|
-
output.push(info.signature);
|
|
345
|
-
output.push("");
|
|
346
|
-
}
|
|
347
|
-
if (info.documentation) {
|
|
348
|
-
output.push("Documentation:");
|
|
349
|
-
output.push(info.documentation);
|
|
350
|
-
output.push("");
|
|
351
|
-
}
|
|
352
|
-
if (info.jsDoc) {
|
|
353
|
-
output.push("JSDoc Tags:");
|
|
354
|
-
output.push(info.jsDoc);
|
|
355
|
-
output.push("");
|
|
356
|
-
}
|
|
357
|
-
output.push("Type:");
|
|
358
|
-
output.push(info.type);
|
|
359
|
-
return output.join(`
|
|
360
|
-
`);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// src/resolution/symbol-finder.ts
|
|
364
|
-
import ts4 from "typescript";
|
|
365
|
-
function findSymbolInJavaScriptFile(sourceFile, checker, symbolName) {
|
|
366
|
-
for (const statement of sourceFile.statements) {
|
|
367
|
-
if (ts4.isFunctionDeclaration(statement) && statement.name?.text === symbolName) {
|
|
368
|
-
return checker.getSymbolAtLocation(statement.name);
|
|
369
|
-
}
|
|
370
|
-
if (ts4.isClassDeclaration(statement) && statement.name?.text === symbolName) {
|
|
371
|
-
return checker.getSymbolAtLocation(statement.name);
|
|
372
|
-
}
|
|
373
|
-
if (ts4.isVariableStatement(statement)) {
|
|
374
|
-
for (const declaration of statement.declarationList.declarations) {
|
|
375
|
-
if (ts4.isIdentifier(declaration.name) && declaration.name.text === symbolName) {
|
|
376
|
-
return checker.getSymbolAtLocation(declaration.name);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
if (ts4.isExpressionStatement(statement)) {
|
|
381
|
-
const { expression } = statement;
|
|
382
|
-
if (ts4.isBinaryExpression(expression) && expression.operatorToken.kind === ts4.SyntaxKind.EqualsToken) {
|
|
383
|
-
const { left, right } = expression;
|
|
384
|
-
if (ts4.isPropertyAccessExpression(left) && ts4.isIdentifier(left.expression) && left.expression.text === "module" && ts4.isIdentifier(left.name) && left.name.text === "exports" && ts4.isObjectLiteralExpression(right)) {
|
|
385
|
-
for (const prop of right.properties) {
|
|
386
|
-
if (ts4.isPropertyAssignment(prop) || ts4.isShorthandPropertyAssignment(prop)) {
|
|
387
|
-
const propName = ts4.isIdentifier(prop.name) ? prop.name.text : undefined;
|
|
388
|
-
if (propName === symbolName) {
|
|
389
|
-
let targetIdentifier;
|
|
390
|
-
if (ts4.isShorthandPropertyAssignment(prop)) {
|
|
391
|
-
targetIdentifier = prop.name;
|
|
392
|
-
} else if (ts4.isPropertyAssignment(prop) && ts4.isIdentifier(prop.initializer)) {
|
|
393
|
-
targetIdentifier = prop.initializer;
|
|
394
|
-
}
|
|
395
|
-
if (targetIdentifier) {
|
|
396
|
-
for (const statement2 of sourceFile.statements) {
|
|
397
|
-
if (ts4.isFunctionDeclaration(statement2) && statement2.name?.text === targetIdentifier.text) {
|
|
398
|
-
const originalSymbol = checker.getSymbolAtLocation(statement2.name);
|
|
399
|
-
if (originalSymbol) {
|
|
400
|
-
return originalSymbol;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
if (ts4.isClassDeclaration(statement2) && statement2.name?.text === targetIdentifier.text) {
|
|
404
|
-
const originalSymbol = checker.getSymbolAtLocation(statement2.name);
|
|
405
|
-
if (originalSymbol) {
|
|
406
|
-
return originalSymbol;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
if (ts4.isVariableStatement(statement2)) {
|
|
410
|
-
for (const declaration of statement2.declarationList.declarations) {
|
|
411
|
-
if (ts4.isIdentifier(declaration.name) && declaration.name.text === targetIdentifier.text) {
|
|
412
|
-
const originalSymbol = checker.getSymbolAtLocation(declaration.name);
|
|
413
|
-
if (originalSymbol) {
|
|
414
|
-
return originalSymbol;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
const exportSymbol = checker.getSymbolAtLocation(targetIdentifier);
|
|
421
|
-
return exportSymbol;
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
return;
|
|
431
|
-
}
|
|
432
|
-
function getSymbolInfo(checker, symbol, member, isStatic) {
|
|
433
|
-
const declaration = symbol.valueDeclaration || symbol.declarations && symbol.declarations[0];
|
|
434
|
-
if (!declaration && (!symbol.declarations || symbol.declarations.length === 0)) {
|
|
435
|
-
return createExtractError("TYPE_ERROR", `Symbol '${symbol.getName()}' has no declarations`);
|
|
436
|
-
}
|
|
437
|
-
const targetDeclaration = declaration || symbol.declarations[0];
|
|
438
|
-
const type = checker.getTypeOfSymbolAtLocation(symbol, targetDeclaration);
|
|
439
|
-
const symbolName = symbol.getName();
|
|
440
|
-
let targetSymbol = symbol;
|
|
441
|
-
let targetType = type;
|
|
442
|
-
let name = symbolName;
|
|
443
|
-
if (member) {
|
|
444
|
-
if (isStatic) {
|
|
445
|
-
const staticMembers = checker.getPropertiesOfType(type);
|
|
446
|
-
const staticMember = staticMembers.find((s) => s.getName() === member);
|
|
447
|
-
if (staticMember) {
|
|
448
|
-
targetSymbol = staticMember;
|
|
449
|
-
targetType = checker.getTypeOfSymbolAtLocation(staticMember, staticMember.valueDeclaration);
|
|
450
|
-
name = `${symbolName}.${member}`;
|
|
451
|
-
} else {
|
|
452
|
-
return createExtractError("MEMBER_NOT_FOUND", `Static member '${member}' not found on '${symbolName}'`);
|
|
453
|
-
}
|
|
454
|
-
} else {
|
|
455
|
-
let instanceType;
|
|
456
|
-
if (symbol.flags & ts4.SymbolFlags.Class) {
|
|
457
|
-
instanceType = checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration);
|
|
458
|
-
const constructSignatures = instanceType.getConstructSignatures();
|
|
459
|
-
if (constructSignatures.length > 0) {
|
|
460
|
-
const [constructSignature] = constructSignatures;
|
|
461
|
-
if (constructSignature) {
|
|
462
|
-
const instanceTypeFromConstruct = checker.getReturnTypeOfSignature(constructSignature);
|
|
463
|
-
const instanceMembers = checker.getPropertiesOfType(instanceTypeFromConstruct);
|
|
464
|
-
const instanceMember = instanceMembers.find((s) => s.getName() === member);
|
|
465
|
-
if (instanceMember) {
|
|
466
|
-
targetSymbol = instanceMember;
|
|
467
|
-
targetType = checker.getTypeOfSymbolAtLocation(instanceMember, instanceMember.valueDeclaration);
|
|
468
|
-
name = `${symbolName}#${member}`;
|
|
469
|
-
} else {
|
|
470
|
-
return createExtractError("MEMBER_NOT_FOUND", `Instance member '${member}' not found on '${symbolName}'. Available: ${instanceMembers.map((m) => m.getName()).join(", ")}`);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
} else {
|
|
474
|
-
const instanceMembers = checker.getPropertiesOfType(instanceType);
|
|
475
|
-
const instanceMember = instanceMembers.find((s) => s.getName() === member);
|
|
476
|
-
if (instanceMember) {
|
|
477
|
-
targetSymbol = instanceMember;
|
|
478
|
-
targetType = checker.getTypeOfSymbolAtLocation(instanceMember, instanceMember.valueDeclaration);
|
|
479
|
-
name = `${symbolName}#${member}`;
|
|
480
|
-
} else {
|
|
481
|
-
return createExtractError("MEMBER_NOT_FOUND", `Instance member '${member}' not found on '${symbolName}'. Available: ${instanceMembers.map((m) => m.getName()).join(", ")}`);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
} else {
|
|
485
|
-
const callSignatures = type.getCallSignatures();
|
|
486
|
-
const constructSignatures = type.getConstructSignatures();
|
|
487
|
-
if (constructSignatures.length > 0) {
|
|
488
|
-
const [constructSignature] = constructSignatures;
|
|
489
|
-
if (constructSignature) {
|
|
490
|
-
instanceType = checker.getReturnTypeOfSignature(constructSignature);
|
|
491
|
-
}
|
|
492
|
-
} else if (callSignatures.length > 0) {
|
|
493
|
-
const [callSignature] = callSignatures;
|
|
494
|
-
if (callSignature) {
|
|
495
|
-
instanceType = checker.getReturnTypeOfSignature(callSignature);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
if (instanceType) {
|
|
499
|
-
const instanceMembers = checker.getPropertiesOfType(instanceType);
|
|
500
|
-
const instanceMember = instanceMembers.find((s) => s.getName() === member);
|
|
501
|
-
if (instanceMember) {
|
|
502
|
-
targetSymbol = instanceMember;
|
|
503
|
-
targetType = checker.getTypeOfSymbolAtLocation(instanceMember, instanceMember.valueDeclaration);
|
|
504
|
-
name = `${symbolName}#${member}`;
|
|
505
|
-
} else {
|
|
506
|
-
return createExtractError("MEMBER_NOT_FOUND", `Instance member '${member}' not found on '${symbolName}'`);
|
|
507
|
-
}
|
|
508
|
-
} else {
|
|
509
|
-
return createExtractError("TYPE_ERROR", `'${symbolName}' is not a constructor or class`);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
const typeString = getTypeString(checker, targetSymbol, targetType);
|
|
515
|
-
const signature = getSignature(checker, targetSymbol, targetType);
|
|
516
|
-
const documentation = getDocumentation(checker, targetSymbol);
|
|
517
|
-
const jsDoc = getJSDoc(checker, targetSymbol);
|
|
518
|
-
const kind = getSymbolKind(targetSymbol);
|
|
519
|
-
const location = getLocation(targetSymbol);
|
|
520
|
-
return {
|
|
521
|
-
name,
|
|
522
|
-
kind,
|
|
523
|
-
type: typeString,
|
|
524
|
-
documentation,
|
|
525
|
-
jsDoc,
|
|
526
|
-
signature,
|
|
527
|
-
location
|
|
528
|
-
};
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
// src/resolution/index.ts
|
|
532
|
-
import ts5 from "typescript";
|
|
533
|
-
import path3 from "node:path";
|
|
534
|
-
function parseModulePath(modulePath) {
|
|
535
|
-
let module;
|
|
536
|
-
let symbolPath;
|
|
537
|
-
if (modulePath.startsWith("node:")) {
|
|
538
|
-
const nodeSymbol = modulePath.slice(5);
|
|
539
|
-
const [baseSymbol] = nodeSymbol.split(".");
|
|
540
|
-
module = `node:${baseSymbol}`;
|
|
541
|
-
symbolPath = nodeSymbol;
|
|
542
|
-
} else {
|
|
543
|
-
const [mod, symPath] = modulePath.split(":");
|
|
544
|
-
if (!mod || !symPath) {
|
|
545
|
-
return createExtractError("INVALID_REQUEST", `Invalid format. Expected 'module:symbol', got '${modulePath}'`);
|
|
546
|
-
}
|
|
547
|
-
module = mod;
|
|
548
|
-
symbolPath = symPath;
|
|
549
|
-
}
|
|
550
|
-
if (symbolPath.includes("#")) {
|
|
551
|
-
const [symbol, member] = symbolPath.split("#");
|
|
552
|
-
if (!symbol || !member) {
|
|
553
|
-
return createExtractError("INVALID_REQUEST", `Invalid format. Expected 'symbol#instance-member', got '${symbolPath}'`);
|
|
554
|
-
}
|
|
555
|
-
return { module, symbol, member, isStatic: false };
|
|
556
|
-
}
|
|
557
|
-
if (symbolPath.includes(".")) {
|
|
558
|
-
const [symbol, member] = symbolPath.split(".");
|
|
559
|
-
if (!symbol || !member) {
|
|
560
|
-
return createExtractError("INVALID_REQUEST", `Invalid format. Expected 'symbol.static-member', got '${symbolPath}'`);
|
|
561
|
-
}
|
|
562
|
-
return { module, symbol, member, isStatic: true };
|
|
563
|
-
}
|
|
564
|
-
return { module, symbol: symbolPath, member: undefined, isStatic: false };
|
|
565
|
-
}
|
|
566
|
-
async function extractDocs(modulePath) {
|
|
567
|
-
const options = { prefix: process.cwd() };
|
|
568
|
-
const parseResult = parseModulePath(modulePath);
|
|
569
|
-
if ("error" in parseResult) {
|
|
570
|
-
return parseResult;
|
|
571
|
-
}
|
|
572
|
-
const { module, symbol, member, isStatic } = parseResult;
|
|
573
|
-
const config = loadTsConfig(options.prefix);
|
|
574
|
-
let resolvedModule = resolveModule(module, config.options);
|
|
575
|
-
let isGlobalModule = false;
|
|
576
|
-
if (isResolveError(resolvedModule)) {
|
|
577
|
-
const nodeBuiltinResolution = resolveNodeBuiltin(module, config.options);
|
|
578
|
-
if (!isResolveError(nodeBuiltinResolution)) {
|
|
579
|
-
resolvedModule = nodeBuiltinResolution;
|
|
580
|
-
isGlobalModule = true;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
if (isResolveError(resolvedModule)) {
|
|
584
|
-
return createExtractError("MODULE_NOT_FOUND", `Module '${module}' not found`);
|
|
585
|
-
}
|
|
586
|
-
const { sourceFile, program } = resolvedModule;
|
|
587
|
-
const checker = program.getTypeChecker();
|
|
588
|
-
let targetSymbol;
|
|
589
|
-
if (isGlobalModule) {
|
|
590
|
-
const actualSymbolName = module.startsWith("node:") ? module.slice(5) : module;
|
|
591
|
-
const globalSymbols = checker.getSymbolsInScope(sourceFile, ts5.SymbolFlags.Value);
|
|
592
|
-
targetSymbol = globalSymbols.find((s) => s.getName() === actualSymbolName);
|
|
593
|
-
if (!targetSymbol) {
|
|
594
|
-
const [identifierNode] = sourceFile.statements;
|
|
595
|
-
if (identifierNode && ts5.isVariableStatement(identifierNode)) {
|
|
596
|
-
const [declaration] = identifierNode.declarationList.declarations;
|
|
597
|
-
if (declaration && ts5.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
598
|
-
targetSymbol = checker.getSymbolAtLocation(declaration.initializer);
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
} else {
|
|
603
|
-
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
604
|
-
if (moduleSymbol) {
|
|
605
|
-
const exports = checker.getExportsOfModule(moduleSymbol);
|
|
606
|
-
const exportSymbol = exports.find((exp) => exp.getName() === symbol);
|
|
607
|
-
if (exportSymbol) {
|
|
608
|
-
if (exportSymbol.valueDeclaration && (ts5.isFunctionDeclaration(exportSymbol.valueDeclaration) || ts5.isClassDeclaration(exportSymbol.valueDeclaration) || ts5.isVariableDeclaration(exportSymbol.valueDeclaration))) {
|
|
609
|
-
targetSymbol = exportSymbol;
|
|
610
|
-
} else if (exportSymbol.flags & (ts5.SymbolFlags.Interface | ts5.SymbolFlags.TypeAlias)) {
|
|
611
|
-
targetSymbol = exportSymbol;
|
|
612
|
-
} else {
|
|
613
|
-
targetSymbol = findSymbolInJavaScriptFile(sourceFile, checker, symbol);
|
|
614
|
-
}
|
|
615
|
-
} else {
|
|
616
|
-
return createExtractError("SYMBOL_NOT_FOUND", `Symbol '${symbol}' not found in module '${module}'. Available exports: ${exports.map((e) => e.getName()).join(", ")}`);
|
|
617
|
-
}
|
|
618
|
-
} else {
|
|
619
|
-
targetSymbol = findSymbolInJavaScriptFile(sourceFile, checker, symbol);
|
|
620
|
-
if (!targetSymbol) {
|
|
621
|
-
return createExtractError("SYMBOL_NOT_FOUND", `Symbol '${symbol}' not found in JavaScript module '${module}'`);
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
if (!targetSymbol) {
|
|
626
|
-
let symbolToShow;
|
|
627
|
-
if (isGlobalModule) {
|
|
628
|
-
symbolToShow = module.startsWith("node:") ? module.slice(5) : module;
|
|
629
|
-
} else {
|
|
630
|
-
symbolToShow = symbol;
|
|
631
|
-
}
|
|
632
|
-
return createExtractError("SYMBOL_NOT_FOUND", `Symbol '${symbolToShow}' not found`);
|
|
633
|
-
}
|
|
634
|
-
const result = getSymbolInfo(checker, targetSymbol, member, isStatic);
|
|
635
|
-
return result;
|
|
636
|
-
}
|
|
637
|
-
async function getSourceLocation(reference) {
|
|
638
|
-
const options = { prefix: process.cwd() };
|
|
639
|
-
if (reference.includes(":")) {
|
|
640
|
-
const parseResult = parseModulePath(reference);
|
|
641
|
-
if ("error" in parseResult) {
|
|
642
|
-
return {
|
|
643
|
-
success: false,
|
|
644
|
-
error: {
|
|
645
|
-
code: "MODULE_NOT_FOUND",
|
|
646
|
-
message: parseResult.error.message
|
|
647
|
-
}
|
|
648
|
-
};
|
|
649
|
-
}
|
|
650
|
-
const { module, symbol, member, isStatic } = parseResult;
|
|
651
|
-
const config2 = loadTsConfig(options.prefix);
|
|
652
|
-
let resolvedModule = resolveModule(module, config2.options);
|
|
653
|
-
let isGlobalModule = false;
|
|
654
|
-
if (isResolveError(resolvedModule)) {
|
|
655
|
-
const nodeBuiltinResolution = resolveNodeBuiltin(module, config2.options);
|
|
656
|
-
if (!isResolveError(nodeBuiltinResolution)) {
|
|
657
|
-
resolvedModule = nodeBuiltinResolution;
|
|
658
|
-
isGlobalModule = true;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
if (isResolveError(resolvedModule)) {
|
|
662
|
-
return {
|
|
663
|
-
success: false,
|
|
664
|
-
error: {
|
|
665
|
-
code: "MODULE_NOT_FOUND",
|
|
666
|
-
message: `Module '${module}' not found`
|
|
667
|
-
}
|
|
668
|
-
};
|
|
669
|
-
}
|
|
670
|
-
const { sourceFile, program } = resolvedModule;
|
|
671
|
-
const checker = program.getTypeChecker();
|
|
672
|
-
let targetSymbol;
|
|
673
|
-
if (isGlobalModule) {
|
|
674
|
-
const actualSymbolName = module.startsWith("node:") ? module.slice(5) : module;
|
|
675
|
-
const globalSymbols = checker.getSymbolsInScope(sourceFile, ts5.SymbolFlags.Value);
|
|
676
|
-
targetSymbol = globalSymbols.find((s) => s.getName() === actualSymbolName);
|
|
677
|
-
if (!targetSymbol) {
|
|
678
|
-
const [identifierNode] = sourceFile.statements;
|
|
679
|
-
if (identifierNode && ts5.isVariableStatement(identifierNode)) {
|
|
680
|
-
const [declaration] = identifierNode.declarationList.declarations;
|
|
681
|
-
if (declaration && ts5.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
682
|
-
targetSymbol = checker.getSymbolAtLocation(declaration.initializer);
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
} else {
|
|
687
|
-
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
688
|
-
if (moduleSymbol) {
|
|
689
|
-
const exports = checker.getExportsOfModule(moduleSymbol);
|
|
690
|
-
const exportSymbol = exports.find((exp) => exp.getName() === symbol);
|
|
691
|
-
if (exportSymbol) {
|
|
692
|
-
targetSymbol = exportSymbol;
|
|
693
|
-
} else {
|
|
694
|
-
return {
|
|
695
|
-
success: false,
|
|
696
|
-
error: {
|
|
697
|
-
code: "MODULE_NOT_FOUND",
|
|
698
|
-
message: `Symbol '${symbol}' not found in module '${module}'`
|
|
699
|
-
}
|
|
700
|
-
};
|
|
701
|
-
}
|
|
702
|
-
} else {
|
|
703
|
-
targetSymbol = findSymbolInJavaScriptFile(sourceFile, checker, symbol);
|
|
704
|
-
if (!targetSymbol) {
|
|
705
|
-
return {
|
|
706
|
-
success: false,
|
|
707
|
-
error: {
|
|
708
|
-
code: "MODULE_NOT_FOUND",
|
|
709
|
-
message: `Symbol '${symbol}' not found in JavaScript module '${module}'`
|
|
710
|
-
}
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
if (!targetSymbol) {
|
|
716
|
-
return {
|
|
717
|
-
success: false,
|
|
718
|
-
error: {
|
|
719
|
-
code: "MODULE_NOT_FOUND",
|
|
720
|
-
message: `Symbol '${symbol}' not found`
|
|
721
|
-
}
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
const symbolInfo = getSymbolInfo(checker, targetSymbol, member, isStatic);
|
|
725
|
-
if (isExtractError(symbolInfo)) {
|
|
726
|
-
return {
|
|
727
|
-
success: false,
|
|
728
|
-
error: {
|
|
729
|
-
code: "MODULE_NOT_FOUND",
|
|
730
|
-
message: symbolInfo.error.message
|
|
731
|
-
}
|
|
732
|
-
};
|
|
733
|
-
}
|
|
734
|
-
return { path: symbolInfo.location, format: "typescript" };
|
|
735
|
-
}
|
|
736
|
-
const moduleName = reference;
|
|
737
|
-
if (moduleName.startsWith("./") || moduleName.startsWith("../")) {
|
|
738
|
-
const absolutePath = path3.resolve(moduleName);
|
|
739
|
-
if (ts5.sys.fileExists(absolutePath)) {
|
|
740
|
-
const cwd = process.cwd();
|
|
741
|
-
let finalPath;
|
|
742
|
-
if (absolutePath.startsWith(cwd)) {
|
|
743
|
-
const relativePath = path3.relative(cwd, absolutePath);
|
|
744
|
-
finalPath = relativePath.startsWith("..") ? absolutePath : relativePath;
|
|
745
|
-
} else {
|
|
746
|
-
finalPath = absolutePath;
|
|
747
|
-
}
|
|
748
|
-
return { path: finalPath, format: "typescript" };
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
const config = loadTsConfig(options.prefix);
|
|
752
|
-
const moduleResolver = ts5.resolveModuleName(moduleName, path3.resolve("./index.ts"), config.options, ts5.sys);
|
|
753
|
-
if (moduleResolver.resolvedModule) {
|
|
754
|
-
const { resolvedFileName } = moduleResolver.resolvedModule;
|
|
755
|
-
const cwd = process.cwd();
|
|
756
|
-
let finalPath;
|
|
757
|
-
if (resolvedFileName.startsWith(cwd)) {
|
|
758
|
-
const relativePath = path3.relative(cwd, resolvedFileName);
|
|
759
|
-
finalPath = relativePath.startsWith("..") ? resolvedFileName : relativePath;
|
|
760
|
-
} else {
|
|
761
|
-
finalPath = resolvedFileName;
|
|
762
|
-
}
|
|
763
|
-
return { path: finalPath, format: "typescript" };
|
|
764
|
-
}
|
|
765
|
-
return resolveError(moduleName, process.cwd());
|
|
766
|
-
}
|
|
767
|
-
async function extractSymbol(request, options = {}) {
|
|
768
|
-
try {
|
|
769
|
-
if (!request.symbol) {
|
|
770
|
-
return {
|
|
771
|
-
error: {
|
|
772
|
-
code: "INVALID_REQUEST",
|
|
773
|
-
message: "Symbol name is required"
|
|
774
|
-
}
|
|
775
|
-
};
|
|
776
|
-
}
|
|
777
|
-
const config = loadTsConfig(options.prefix);
|
|
778
|
-
const resolvedModule = resolveModule(request.module, config.options);
|
|
779
|
-
if (isResolveError(resolvedModule)) {
|
|
780
|
-
return {
|
|
781
|
-
error: {
|
|
782
|
-
code: "MODULE_NOT_FOUND",
|
|
783
|
-
message: `Module '${request.module}' not found`
|
|
784
|
-
}
|
|
785
|
-
};
|
|
786
|
-
}
|
|
787
|
-
const { sourceFile, program } = resolvedModule;
|
|
788
|
-
const checker = program.getTypeChecker();
|
|
789
|
-
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
790
|
-
let targetSymbol;
|
|
791
|
-
if (moduleSymbol) {
|
|
792
|
-
const exports = checker.getExportsOfModule(moduleSymbol);
|
|
793
|
-
targetSymbol = exports.find((exp) => exp.getName() === request.symbol);
|
|
794
|
-
if (!targetSymbol) {
|
|
795
|
-
return {
|
|
796
|
-
error: {
|
|
797
|
-
code: "SYMBOL_NOT_FOUND",
|
|
798
|
-
message: `Symbol '${request.symbol}' not found in module '${request.module}'. Available exports: ${exports.map((e) => e.getName()).join(", ")}`
|
|
799
|
-
}
|
|
800
|
-
};
|
|
801
|
-
}
|
|
802
|
-
} else {
|
|
803
|
-
targetSymbol = findSymbolInJavaScriptFile(sourceFile, checker, request.symbol);
|
|
804
|
-
if (!targetSymbol) {
|
|
805
|
-
return {
|
|
806
|
-
error: {
|
|
807
|
-
code: "SYMBOL_NOT_FOUND",
|
|
808
|
-
message: `Symbol '${request.symbol}' not found in JavaScript module '${request.module}'`
|
|
809
|
-
}
|
|
810
|
-
};
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
const result = getSymbolInfo(checker, targetSymbol, request.member, request.isStatic);
|
|
814
|
-
return result;
|
|
815
|
-
} catch (error) {
|
|
816
|
-
return {
|
|
817
|
-
error: {
|
|
818
|
-
code: "PARSE_ERROR",
|
|
819
|
-
message: `Extraction failed: ${error instanceof Error ? error.message : String(error)}`
|
|
820
|
-
}
|
|
821
|
-
};
|
|
822
|
-
}
|
|
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
|
-
|
|
897
|
-
// src/index.ts
|
|
898
|
-
var Tidewave = {
|
|
899
|
-
extractDocs,
|
|
900
|
-
getSourceLocation,
|
|
901
|
-
formatOutput,
|
|
902
|
-
executeIsolated
|
|
903
|
-
};
|
|
904
|
-
export {
|
|
905
|
-
Tidewave
|
|
906
|
-
};
|