mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 16:02:36 +00:00
* fix: keep version pins from imported scripts in bun lockfiles Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WCq4nkUjiZBnPPMuGYCo6w * fix: strip version pins from the bundle a bun modules run executes Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WCq4nkUjiZBnPPMuGYCo6w * fix: unpin only module specifiers, not matching text elsewhere in the script Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WCq4nkUjiZBnPPMuGYCo6w * docs: name the raw endpoint lock generation fetches imports through Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WCq4nkUjiZBnPPMuGYCo6w * fix: leave require calls alone and skip spans not on a quote pair when unpinning Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WCq4nkUjiZBnPPMuGYCo6w * test: create the bun bundle cache dir a dependency job saves into Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WCq4nkUjiZBnPPMuGYCo6w * test: drop the lock test #11082's module test already covers Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WCq4nkUjiZBnPPMuGYCo6w * fix: narrow the change to a fail-open strip of the modules-run bundle Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WCq4nkUjiZBnPPMuGYCo6w * fix: unpin only the specifiers in the modules-run bundle, and log a parse fallback Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WCq4nkUjiZBnPPMuGYCo6w --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
125 lines
4.3 KiB
JavaScript
125 lines
4.3 KiB
JavaScript
// Injected by backend: maps normalized paths to temp storage hashes (or null)
|
|
const TEMP_SCRIPT_REFS = TEMP_SCRIPT_REFS_PLACEHOLDER;
|
|
|
|
const p = {
|
|
name: "windmill-relative-resolver",
|
|
async setup(build) {
|
|
const { writeFileSync, readFileSync, mkdirSync } = await import("fs");
|
|
const { dirname, resolve, join } = await import("node:path");
|
|
|
|
const base_internal_url = "BASE_INTERNAL_URL".replace(
|
|
"localhost",
|
|
"127.0.0.1"
|
|
);
|
|
|
|
const w_id = "W_ID";
|
|
const current_path = "CURRENT_PATH";
|
|
const token = "TOKEN";
|
|
|
|
const cdir = resolve("./");
|
|
const cdirNoPrivate = cdir.replace(/^\/private/, ""); // for macos
|
|
// On Windows, normalize path to POSIX format to match args.path from Bun's resolver
|
|
const cdirPosix = cdir.replace(/\\/g, "/").replace(/^[a-zA-Z]:/, "");
|
|
const filterResolve = new RegExp(
|
|
`^(?!\\.\/main\\.ts)(?!\\.\/_wm_)(?!${cdir}\/main\\.ts)(?!${cdir}\/_wm_)(?!${cdirPosix}\/main\\.ts)(?!${cdirPosix}\/_wm_)(?!(?:/private)?${cdirNoPrivate}\/wrapper\\.mjs).*\\.ts$`
|
|
);
|
|
|
|
let cdirNodeModules = `${cdir}/node_modules/`;
|
|
|
|
const filterLoad = new RegExp(`^${cdir}\/main\\.ts$`);
|
|
const transpiler = new Bun.Transpiler({
|
|
loader: "ts",
|
|
});
|
|
|
|
function replaceRelativeImports(code) {
|
|
const imports = transpiler.scanImports(code);
|
|
for (const imp of imports) {
|
|
if (imp.kind == "import-statement") {
|
|
if (
|
|
(imp.path.startsWith(".") ||
|
|
imp.path.startsWith("/u/") ||
|
|
imp.path.startsWith("/f/")) &&
|
|
!imp.path.endsWith(".ts")
|
|
) {
|
|
code = code.replaceAll(imp.path, imp.path + ".ts");
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
contents: code,
|
|
};
|
|
}
|
|
|
|
build.onLoad({ filter: filterLoad }, async (args) => {
|
|
const code = readFileSync(args.path, "utf8");
|
|
return replaceRelativeImports(code);
|
|
});
|
|
|
|
build.onLoad({ filter: /.*\.url$/ }, async (args) => {
|
|
const url = readFileSync(args.path, "utf8");
|
|
const req = await fetch(url, {
|
|
method: "GET",
|
|
headers: {
|
|
Authorization: "Bearer " + token,
|
|
},
|
|
});
|
|
if (!req.ok) {
|
|
throw new Error(
|
|
`Failed to find relative import at ${url}`,
|
|
req.statusText
|
|
);
|
|
}
|
|
const contents = await req.text();
|
|
return {
|
|
contents: replaceRelativeImports(contents).contents,
|
|
loader: "tsx",
|
|
};
|
|
});
|
|
|
|
build.onResolve({ filter: filterResolve }, (args) => {
|
|
if (args.importer?.startsWith(cdirNodeModules)) {
|
|
return undefined;
|
|
}
|
|
|
|
// Check if the import resolves to a local module file (written by write_module_files).
|
|
// Only check relative paths — absolute/bare specifiers should fall through to the
|
|
// remote resolver, matching the Windows loader pattern.
|
|
if (args.path.startsWith(".")) {
|
|
const localPath = resolve(cdir, args.path);
|
|
try {
|
|
readFileSync(localPath);
|
|
return { path: localPath };
|
|
} catch {}
|
|
}
|
|
|
|
const file_path =
|
|
args.importer == "./main.ts" || args.importer == resolve("./main.ts")
|
|
? current_path
|
|
: args.importer.replace(cdir + "/", "");
|
|
|
|
const isRelative = !args.path.startsWith("/");
|
|
const endExt = args.path.endsWith(".ts") ? "" : ".ts";
|
|
const pathNoExt = args.path.replace(/\.ts$/, "");
|
|
|
|
// Lookup temp script hash
|
|
const normalized = (isRelative ? join(dirname(file_path), pathNoExt) : pathNoExt.slice(1)).replace(/\\/g, "/");
|
|
const hash = TEMP_SCRIPT_REFS?.[normalized];
|
|
|
|
// Lock generation substitutes `raw`: the dependency scan reads versions from the
|
|
// `pkg@version` specifiers in imported scripts, which `raw_unpinned` strips.
|
|
const url = (isRelative
|
|
? `${base_internal_url}/api/w/${w_id}/scripts/RAW_GET_ENDPOINT/p/${file_path}/../${args.path}${endExt}`
|
|
: `${base_internal_url}/api/w/${w_id}/scripts/RAW_GET_ENDPOINT/p/${args.path}${endExt}`
|
|
) + (hash ? `?temp_script_hash=${hash}` : "");
|
|
const file = isRelative
|
|
? resolve("./" + file_path + "/../" + args.path + ".url")
|
|
: resolve("./" + args.path + ".url");
|
|
mkdirSync(dirname(file), { recursive: true });
|
|
writeFileSync(file, url);
|
|
return {
|
|
path: file,
|
|
};
|
|
});
|
|
},
|
|
};
|