mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
polyfills: rework test runner
This commit is contained in:
@@ -3,17 +3,27 @@
|
||||
/// <reference types="bun-types" />
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
import path from 'node:path';
|
||||
import util from 'node:util';
|
||||
import fs from 'node:fs';
|
||||
import $ from 'chalk';
|
||||
import bunwasm from 'bun-wasm';
|
||||
import { TransformResponseStatus } from 'bun-wasm/schema';
|
||||
|
||||
const testRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '..', 'test');
|
||||
const tsconfigPath = path.resolve(testRoot, 'tsconfig.json');
|
||||
/** @type {Record<string, string[]>} */
|
||||
let tsconfigPaths = {};
|
||||
if (fs.existsSync(tsconfigPath)) {
|
||||
const tsconfig = JSON.parse(fs.readFileSync(tsconfigPath, 'utf-8'));
|
||||
tsconfigPaths = tsconfig.compilerOptions.paths;
|
||||
} else {
|
||||
throw new Error('No tsconfig.json found at: ' + tsconfigPath);
|
||||
}
|
||||
|
||||
await bunwasm.init();
|
||||
const NO_STACK = () => void 0;
|
||||
const decoder = new TextDecoder('utf-8');
|
||||
const libRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'dist', 'src');
|
||||
const knownBunModules = ['sqlite', 'ffi', 'jsc', 'test'];
|
||||
const knownBunModules = ['sqlite', 'ffi', 'jsc', 'test', 'wrap'];
|
||||
/** @type {string} */
|
||||
let mainURL;
|
||||
|
||||
@@ -24,13 +34,19 @@ export async function resolve(specifier, context, nextResolve) {
|
||||
if (specifier.startsWith('bun:')) {
|
||||
const module = specifier.slice(4);
|
||||
if (!knownBunModules.includes(module)) {
|
||||
const err = new Error(`[bun-polyfills] Unknown or unimplemented bun module "${specifier}"`);
|
||||
const err = new Error(`[bun-polyfills] Unknown or unimplemented bun module "${specifier}" imported from "${context.parentURL}"`);
|
||||
Error.captureStackTrace(err, NO_STACK);
|
||||
throw err;
|
||||
}
|
||||
if (module === 'sqlite') throw new Error('bun:sqlite polyfill is not implemented yet');
|
||||
if (module === 'wrap') return { url: 'bun:wrap@' + context.parentURL, format: 'module', shortCircuit: true };
|
||||
return { url: pathToFileURL(path.resolve(libRoot, 'modules', module + '.js')).href, format: 'module', shortCircuit: true };
|
||||
}
|
||||
// Not the really an accurate way to do this, but it works for the test suite usages
|
||||
if (Object.keys(tsconfigPaths).includes(specifier)) {
|
||||
const paths = tsconfigPaths[specifier];
|
||||
const resolved = paths.map(p => pathToFileURL(path.resolve(testRoot, p)).href);
|
||||
specifier = resolved[0];
|
||||
}
|
||||
//console.debug('trying to resolve', specifier, 'from', context.parentURL);
|
||||
/** @type {Resolve.Return | Error} */
|
||||
let next;
|
||||
@@ -68,9 +84,27 @@ export async function resolve(specifier, context, nextResolve) {
|
||||
else return next;
|
||||
}
|
||||
|
||||
const APPLY_IMPORT_META_POLYFILL = /*js*/`
|
||||
;(await import("${pathToFileURL(path.resolve(libRoot, 'global', 'importmeta.js')).href}")).default(import.meta);
|
||||
`;
|
||||
/** @type {load} */
|
||||
export async function load(url, context, nextLoad) {
|
||||
//console.debug('Loading', url, 'with context', context);
|
||||
if (url.startsWith('bun:wrap@')) {
|
||||
return {
|
||||
shortCircuit: true, format: 'module', source: /*js*/`
|
||||
import { createRequire } from 'node:module';
|
||||
const require = createRequire(import.meta.url.slice(9));
|
||||
export const __require = require;
|
||||
export default new Proxy({
|
||||
__require: require,
|
||||
}, {
|
||||
get(target, prop) {
|
||||
return target[prop];
|
||||
},
|
||||
});`
|
||||
};
|
||||
}
|
||||
if (context.format === 'tsmodule' || context.format === 'tscommonjs') {
|
||||
const filepath = fileURLToPath(url);
|
||||
const src = fs.readFileSync(filepath, 'utf-8');
|
||||
@@ -87,29 +121,41 @@ export async function load(url, context, nextLoad) {
|
||||
return {
|
||||
shortCircuit: true,
|
||||
format: /** @type {ModuleFormat} */(context.format.slice(2)),
|
||||
source: decoder.decode(transform.files[0].data),
|
||||
source: (context.format === 'tsmodule'
|
||||
? (url.includes('/bun-polyfills/') ? '' : APPLY_IMPORT_META_POLYFILL)
|
||||
: '') + decoder.decode(transform.files[0].data),
|
||||
};
|
||||
}
|
||||
if (context.format === 'json') context.importAssertions.type = 'json';
|
||||
|
||||
const loaded = await nextLoad(url, context);
|
||||
if (url.startsWith('file://') && loaded.format === 'module') {
|
||||
const src = typeof loaded.source === 'string' ? loaded.source : decoder.decode(loaded.source);
|
||||
return { shortCircuit: true, format: 'module', source: src };
|
||||
return {
|
||||
shortCircuit: true,
|
||||
format: 'module',
|
||||
source: (url.includes('/bun-polyfills/') ? '' : APPLY_IMPORT_META_POLYFILL) + src
|
||||
};
|
||||
}
|
||||
else return loaded;
|
||||
}
|
||||
|
||||
/** @type {globalPreload} */
|
||||
export function globalPreload(ctx) {
|
||||
return /*js*/`process.env.BUN_POLYFILLS_TEST_RUNNER = 1;`;
|
||||
}
|
||||
|
||||
/** @param {import('bun-wasm/schema').Message[]} buildErrors */
|
||||
function formatBuildErrors(buildErrors) {
|
||||
const formatted = buildErrors.map(err => {
|
||||
const loc = err.data.location;
|
||||
const str = `${$.redBright('error')}${$.gray(':')} ${$.bold(err.data.text)}\n` +
|
||||
(loc
|
||||
? `${highlightErrorChar(loc.line_text, loc.column)}\n` +
|
||||
(loc
|
||||
? `${highlightErrorChar(loc.line_text, loc.column)}\n` +
|
||||
$.redBright.bold('^'.padStart(loc.column)) + '\n' +
|
||||
`${$.bold(loc.file)}${$.gray(':')}${$.yellowBright(loc.line)}${$.gray(':')}${$.yellowBright(loc.column)} ${$.gray(loc.offset)}`
|
||||
: ''
|
||||
);
|
||||
: ''
|
||||
);
|
||||
const newerr = new Error(str);
|
||||
newerr.name = 'BuildError';
|
||||
newerr.stack = str;
|
||||
|
||||
Reference in New Issue
Block a user