donobu
Version:
Create browser automations with an LLM agent and replay them as Playwright scripts.
85 lines • 2.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.captureCallSite = captureCallSite;
const fs_1 = require("fs");
/**
* Segments of Donobu-internal file paths. Any stack frame whose file
* name contains one of these is considered internal and skipped.
*/
const INTERNAL_PATH_SEGMENTS = [
'/lib/page/',
'/lib/test/',
'/lib/ai/',
'/managers/',
'/controlPanel/',
'node_modules/',
];
/**
* Walks the V8 stack to find the first frame that belongs to user code
* (i.e., not inside the Donobu library or node_modules).
*
* This is robust regardless of how many internal wrappers sit between
* the user's `await page.tbd()` call and this function.
*/
function captureCallSite() {
const orig = Error.prepareStackTrace;
try {
Error.prepareStackTrace = (_err, stack) => stack;
const err = new Error();
const stack = err.stack;
if (!stack || stack.length === 0) {
return null;
}
// Walk from the top of the stack (closest to us) outward, looking
// for the first frame that is NOT inside Donobu internals.
for (let i = 1; i < stack.length; i++) {
const frame = stack[i];
const file = frame.getFileName();
if (!file) {
continue;
}
const isInternal = INTERNAL_PATH_SEGMENTS.some((seg) => file.includes(seg));
if (!isInternal) {
const line = frame.getLineNumber();
const column = frame.getColumnNumber();
if (!line) {
continue;
}
// Playwright compiles .ts files and may give us the .ts path
// (with source maps) or the compiled .js path. If the path
// ends in .js, check if a .ts sibling exists and prefer that
// since the user's source is what we want to rewrite.
const resolvedFile = resolveToTypeScript(file);
return { file: resolvedFile, line, column: column ?? 0 };
}
}
return null;
}
finally {
Error.prepareStackTrace = orig;
}
}
/**
* If `filePath` is a `.js` file and a corresponding `.ts` file exists
* on disk, return the `.ts` path. Otherwise return the original path.
*/
function resolveToTypeScript(filePath) {
if (filePath.endsWith('.js')) {
const tsPath = filePath.replace(/\.js$/, '.ts');
if ((0, fs_1.existsSync)(tsPath)) {
return tsPath;
}
}
if (filePath.endsWith('.mjs')) {
const tsPath = filePath.replace(/\.mjs$/, '.mts');
if ((0, fs_1.existsSync)(tsPath)) {
return tsPath;
}
const ts2 = filePath.replace(/\.mjs$/, '.ts');
if ((0, fs_1.existsSync)(ts2)) {
return ts2;
}
}
return filePath;
}
//# sourceMappingURL=callSiteCapture.js.map