mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 23:18:47 +00:00
Compare commits
5 Commits
jarred/han
...
plugin/plu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a443f72b5 | ||
|
|
4f2095d1c6 | ||
|
|
cfd68a4e9b | ||
|
|
dba07b8675 | ||
|
|
599162ce73 |
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -2,7 +2,7 @@
|
||||
"git.autoRepositoryDetection": "openEditors",
|
||||
"search.quickOpen.includeSymbols": false,
|
||||
"search.seedWithNearestWord": true,
|
||||
"search.smartCase": true,
|
||||
"search.smartCase": false,
|
||||
"search.exclude": {},
|
||||
"search.followSymlinks": false,
|
||||
"search.useIgnoreFiles": true,
|
||||
|
||||
13
packages/bun-types/bun.d.ts
vendored
13
packages/bun-types/bun.d.ts
vendored
@@ -2913,6 +2913,10 @@ declare module "bun" {
|
||||
* The default loader for this file extension
|
||||
*/
|
||||
loader: Loader;
|
||||
/**
|
||||
* Contextual data passed down from the `onResolve` callback that resolved this module
|
||||
*/
|
||||
pluginData: any;
|
||||
}
|
||||
|
||||
type OnLoadResult = OnLoadResultSourceCode | OnLoadResultObject;
|
||||
@@ -2937,7 +2941,10 @@ declare module "bun" {
|
||||
* The kind of import this resolve is for.
|
||||
*/
|
||||
kind: ImportKind;
|
||||
// resolveDir: string;
|
||||
/**
|
||||
* The= directory of the importing module. Commonly used to resolve `args.path` to an absolute path.
|
||||
*/
|
||||
resolveDir: string;
|
||||
// pluginData: any;
|
||||
}
|
||||
|
||||
@@ -2956,6 +2963,10 @@ declare module "bun" {
|
||||
*/
|
||||
namespace?: string;
|
||||
external?: boolean;
|
||||
/**
|
||||
* Data to pass to the `onLoad` callback
|
||||
*/
|
||||
pluginData?: any;
|
||||
}
|
||||
|
||||
type OnResolveCallback = (
|
||||
|
||||
@@ -598,10 +598,12 @@ pub const JSBundler = struct {
|
||||
path: []const u8 = "",
|
||||
namespace: []const u8 = "",
|
||||
external: bool = false,
|
||||
plugin_data: JSValue = JSC.JSValue.jsUndefined(),
|
||||
|
||||
pub fn deinit(this: *@This()) void {
|
||||
bun.default_allocator.destroy(this.path);
|
||||
bun.default_allocator.destroy(this.namespace);
|
||||
// bun.default_allocator.destroy(this.plugin_data);
|
||||
}
|
||||
},
|
||||
no_match: void,
|
||||
@@ -679,6 +681,7 @@ pub const JSBundler = struct {
|
||||
path_value: JSValue,
|
||||
namespace_value: JSValue,
|
||||
external_value: JSValue,
|
||||
plugin_data_value: JSValue,
|
||||
) void {
|
||||
var completion = this.completion orelse {
|
||||
this.deinit();
|
||||
@@ -689,11 +692,14 @@ pub const JSBundler = struct {
|
||||
} else {
|
||||
const path = path_value.toSliceCloneWithAllocator(completion.globalThis, bun.default_allocator) orelse @panic("Unexpected: path is not a string");
|
||||
const namespace = namespace_value.toSliceCloneWithAllocator(completion.globalThis, bun.default_allocator) orelse @panic("Unexpected: namespace is not a string");
|
||||
std.debug.print("got plugin data", .{});
|
||||
const plugin_data = plugin_data_value; //.toObject(completion.globalThis).*; // orelse @panic("Unexpected: plugin_data is not an object");
|
||||
this.value = .{
|
||||
.success = .{
|
||||
.path = path.slice(),
|
||||
.namespace = namespace.slice(),
|
||||
.external = external_value.to(bool),
|
||||
.plugin_data = plugin_data,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -711,6 +717,7 @@ pub const JSBundler = struct {
|
||||
default_loader: options.Loader,
|
||||
path: []const u8 = "",
|
||||
namespace: []const u8 = "",
|
||||
plugin_data: JSValue = JSC.JSValue.jsUndefined(),
|
||||
|
||||
/// Null means the task was aborted.
|
||||
completion: ?*bun.BundleV2.JSBundleCompletionTask = null,
|
||||
@@ -723,12 +730,7 @@ pub const JSBundler = struct {
|
||||
/// Faster path: skip the extra threadpool dispatch when the file is not found
|
||||
was_file: bool = false,
|
||||
|
||||
pub fn create(
|
||||
completion: *bun.BundleV2.JSBundleCompletionTask,
|
||||
source_index: Index,
|
||||
default_loader: options.Loader,
|
||||
path: Fs.Path,
|
||||
) Load {
|
||||
pub fn create(completion: *bun.BundleV2.JSBundleCompletionTask, source_index: Index, default_loader: options.Loader, path: Fs.Path, plugin_data: ?JSValue) Load {
|
||||
completion.ref();
|
||||
return Load{
|
||||
.source_index = source_index,
|
||||
@@ -737,6 +739,7 @@ pub const JSBundler = struct {
|
||||
.value = .{ .pending = {} },
|
||||
.path = path.text,
|
||||
.namespace = path.namespace,
|
||||
.plugin_data = plugin_data orelse JSValue.undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -772,6 +775,11 @@ pub const JSBundler = struct {
|
||||
|
||||
pub fn deinit(this: *Load) void {
|
||||
this.value.deinit();
|
||||
// seems like a reasonable place to free idk
|
||||
// if (this.plugin_data != JSValue.undefined) {
|
||||
// bun.default_allocator.free(this.plugin_data);
|
||||
// }
|
||||
|
||||
if (this.completion) |completion|
|
||||
completion.deref();
|
||||
}
|
||||
@@ -790,6 +798,7 @@ pub const JSBundler = struct {
|
||||
this.namespace,
|
||||
this,
|
||||
this.default_loader,
|
||||
this.plugin_data,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -876,14 +885,7 @@ pub const JSBundler = struct {
|
||||
bool,
|
||||
) bool;
|
||||
|
||||
extern fn JSBundlerPlugin__matchOnLoad(
|
||||
*JSC.JSGlobalObject,
|
||||
*Plugin,
|
||||
namespaceString: *const ZigString,
|
||||
path: *const ZigString,
|
||||
context: *anyopaque,
|
||||
u8,
|
||||
) void;
|
||||
extern fn JSBundlerPlugin__matchOnLoad(*JSC.JSGlobalObject, *Plugin, namespaceString: *const ZigString, path: *const ZigString, context: *anyopaque, u8, pluginData: *const JSValue) void;
|
||||
|
||||
extern fn JSBundlerPlugin__matchOnResolve(
|
||||
*JSC.JSGlobalObject,
|
||||
@@ -893,6 +895,7 @@ pub const JSBundler = struct {
|
||||
importer: *const ZigString,
|
||||
context: *anyopaque,
|
||||
u8,
|
||||
resolve_dir: *const ZigString,
|
||||
) void;
|
||||
|
||||
pub fn hasAnyMatches(
|
||||
@@ -919,6 +922,7 @@ pub const JSBundler = struct {
|
||||
namespace: []const u8,
|
||||
context: *anyopaque,
|
||||
default_loader: options.Loader,
|
||||
plugin_data: JSValue,
|
||||
) void {
|
||||
JSC.markBinding(@src());
|
||||
const tracer = bun.tracy.traceNamed(@src(), "JSBundler.matchOnLoad");
|
||||
@@ -928,7 +932,8 @@ pub const JSBundler = struct {
|
||||
else
|
||||
ZigString.fromUTF8(namespace);
|
||||
const path_string = ZigString.fromUTF8(path);
|
||||
JSBundlerPlugin__matchOnLoad(globalThis, this, &namespace_string, &path_string, context, @enumToInt(default_loader));
|
||||
std.debug.print("matchonload\n", .{});
|
||||
JSBundlerPlugin__matchOnLoad(globalThis, this, &namespace_string, &path_string, context, @enumToInt(default_loader), &plugin_data);
|
||||
}
|
||||
|
||||
pub fn matchOnResolve(
|
||||
@@ -949,7 +954,10 @@ pub const JSBundler = struct {
|
||||
ZigString.fromUTF8(namespace);
|
||||
const path_string = ZigString.fromUTF8(path);
|
||||
const importer_string = ZigString.fromUTF8(importer);
|
||||
JSBundlerPlugin__matchOnResolve(globalThis, this, &namespace_string, &path_string, &importer_string, context, @enumToInt(import_record_kind));
|
||||
// TODO: improve this for virtual modules
|
||||
const resolve_dir = std.fs.path.dirname(importer) orelse "/";
|
||||
const resolve_dir_string = ZigString.fromUTF8(resolve_dir);
|
||||
JSBundlerPlugin__matchOnResolve(globalThis, this, &namespace_string, &path_string, &importer_string, context, @enumToInt(import_record_kind), &resolve_dir_string);
|
||||
}
|
||||
|
||||
pub fn addPlugin(
|
||||
|
||||
@@ -5224,6 +5224,7 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type {
|
||||
}
|
||||
|
||||
pub fn listen(this: *ThisServer) void {
|
||||
JSC.markBinding(@src());
|
||||
httplog("listen", .{});
|
||||
if (ssl_enabled) {
|
||||
BoringSSL.load();
|
||||
|
||||
@@ -279,10 +279,12 @@ extern "C" bool JSBundlerPlugin__anyMatches(Bun::JSBundlerPlugin* pluginObject,
|
||||
return pluginObject->plugin.anyMatchesCrossThread(pluginObject->vm(), namespaceString, path, isOnLoad);
|
||||
}
|
||||
|
||||
extern "C" void JSBundlerPlugin__matchOnLoad(JSC::JSGlobalObject* globalObject, Bun::JSBundlerPlugin* plugin, const ZigString* namespaceString, const ZigString* path, void* context, uint8_t defaultLoaderId)
|
||||
extern "C" void JSBundlerPlugin__matchOnLoad(JSC::JSGlobalObject* globalObject, Bun::JSBundlerPlugin* plugin, const ZigString* namespaceString, const ZigString* path, void* context, uint8_t defaultLoaderId, JSValue* pluginData)
|
||||
{
|
||||
WTF::String namespaceStringStr = namespaceString ? Zig::toStringCopy(*namespaceString) : WTF::String();
|
||||
WTF::String pathStr = path ? Zig::toStringCopy(*path) : WTF::String();
|
||||
// get value from pointer
|
||||
JSValue pluginDataValue = *pluginData;
|
||||
|
||||
JSFunction* function = plugin->onLoadFunction.get(plugin);
|
||||
if (UNLIKELY(!function))
|
||||
@@ -299,6 +301,7 @@ extern "C" void JSBundlerPlugin__matchOnLoad(JSC::JSGlobalObject* globalObject,
|
||||
arguments.append(JSC::jsString(plugin->vm(), pathStr));
|
||||
arguments.append(JSC::jsString(plugin->vm(), namespaceStringStr));
|
||||
arguments.append(JSC::jsNumber(defaultLoaderId));
|
||||
arguments.append(pluginDataValue);
|
||||
|
||||
auto result = call(globalObject, function, callData, plugin, arguments);
|
||||
|
||||
@@ -315,7 +318,7 @@ extern "C" void JSBundlerPlugin__matchOnLoad(JSC::JSGlobalObject* globalObject,
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void JSBundlerPlugin__matchOnResolve(JSC::JSGlobalObject* globalObject, Bun::JSBundlerPlugin* plugin, const ZigString* namespaceString, const ZigString* path, const ZigString* importer, void* context, uint8_t kindId)
|
||||
extern "C" void JSBundlerPlugin__matchOnResolve(JSC::JSGlobalObject* globalObject, Bun::JSBundlerPlugin* plugin, const ZigString* namespaceString, const ZigString* path, const ZigString* importer, void* context, uint8_t kindId, const ZigString* resolveDir)
|
||||
{
|
||||
WTF::String namespaceStringStr = namespaceString ? Zig::toStringCopy(*namespaceString) : WTF::String("file"_s);
|
||||
if (namespaceStringStr.length() == 0) {
|
||||
@@ -323,6 +326,7 @@ extern "C" void JSBundlerPlugin__matchOnResolve(JSC::JSGlobalObject* globalObjec
|
||||
}
|
||||
WTF::String pathStr = path ? Zig::toStringCopy(*path) : WTF::String();
|
||||
WTF::String importerStr = importer ? Zig::toStringCopy(*importer) : WTF::String();
|
||||
WTF::String resolveDirStr = resolveDir ? Zig::toStringCopy(*resolveDir) : WTF::String();
|
||||
auto& vm = globalObject->vm();
|
||||
|
||||
JSFunction* function = plugin->onResolveFunction.get(plugin);
|
||||
@@ -341,6 +345,7 @@ extern "C" void JSBundlerPlugin__matchOnResolve(JSC::JSGlobalObject* globalObjec
|
||||
arguments.append(JSC::jsString(vm, importerStr));
|
||||
arguments.append(WRAP_BUNDLER_PLUGIN(context));
|
||||
arguments.append(JSC::jsNumber(kindId));
|
||||
arguments.append(JSC::jsString(vm, resolveDirStr));
|
||||
|
||||
auto result = call(globalObject, function, callData, plugin, arguments);
|
||||
|
||||
|
||||
@@ -603,7 +603,7 @@ pub const BundleV2 = struct {
|
||||
_ = @atomicRmw(usize, &this.graph.parse_pending, .Add, 1, .Monotonic);
|
||||
|
||||
// Handle onLoad plugins
|
||||
if (!this.enqueueOnLoadPluginIfNeeded(task)) {
|
||||
if (!this.enqueueOnLoadPluginIfNeeded(task, bun.JSC.JSValue.jsUndefined())) {
|
||||
if (loader.shouldCopyForBundling()) {
|
||||
var additional_files: *BabyList(AdditionalFile) = &this.graph.input_files.items(.additional_files)[source_index.get()];
|
||||
additional_files.push(this.graph.allocator, .{ .source_index = task.source_index.get() }) catch unreachable;
|
||||
@@ -670,7 +670,7 @@ pub const BundleV2 = struct {
|
||||
task.tree_shaking = this.linker.options.tree_shaking;
|
||||
|
||||
// Handle onLoad plugins as entry points
|
||||
if (!this.enqueueOnLoadPluginIfNeeded(task)) {
|
||||
if (!this.enqueueOnLoadPluginIfNeeded(task, bun.JSC.JSValue.jsUndefined())) {
|
||||
if (loader.shouldCopyForBundling()) {
|
||||
var additional_files: *BabyList(AdditionalFile) = &this.graph.input_files.items(.additional_files)[source_index.get()];
|
||||
additional_files.push(this.graph.allocator, .{ .source_index = task.source_index.get() }) catch unreachable;
|
||||
@@ -1476,7 +1476,8 @@ pub const BundleV2 = struct {
|
||||
_ = @atomicRmw(usize, &this.graph.parse_pending, .Add, 1, .Monotonic);
|
||||
|
||||
// Handle onLoad plugins
|
||||
if (!this.enqueueOnLoadPluginIfNeeded(task)) {
|
||||
std.debug.print("enqueueOnLoadPluginIfNeeded", .{});
|
||||
if (!this.enqueueOnLoadPluginIfNeeded(task, result.plugin_data)) {
|
||||
if (loader.shouldCopyForBundling()) {
|
||||
var additional_files: *BabyList(AdditionalFile) = &this.graph.input_files.items(.additional_files)[source_index.get()];
|
||||
additional_files.push(this.graph.allocator, .{ .source_index = task.source_index.get() }) catch unreachable;
|
||||
@@ -1774,7 +1775,11 @@ pub const BundleV2 = struct {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn enqueueOnLoadPluginIfNeeded(this: *BundleV2, parse: *ParseTask) bool {
|
||||
pub fn enqueueOnLoadPluginIfNeeded(
|
||||
this: *BundleV2,
|
||||
parse: *ParseTask,
|
||||
plugin_data: JSC.JSValue,
|
||||
) bool {
|
||||
if (this.plugins) |plugins| {
|
||||
if (plugins.hasAnyMatches(&parse.path, true)) {
|
||||
// This is where onLoad plugins are enqueued
|
||||
@@ -1783,12 +1788,8 @@ pub const BundleV2 = struct {
|
||||
parse.path.text,
|
||||
});
|
||||
var load = bun.default_allocator.create(JSC.API.JSBundler.Load) catch unreachable;
|
||||
load.* = JSC.API.JSBundler.Load.create(
|
||||
this.completion.?,
|
||||
parse.source_index,
|
||||
parse.path.loader(&this.bundler.options.loaders) orelse options.Loader.js,
|
||||
parse.path,
|
||||
);
|
||||
std.debug.print("Load.create", .{});
|
||||
load.* = JSC.API.JSBundler.Load.create(this.completion.?, parse.source_index, parse.path.loader(&this.bundler.options.loaders) orelse options.Loader.js, parse.path, plugin_data);
|
||||
load.parse_task = parse;
|
||||
load.dispatch();
|
||||
return true;
|
||||
@@ -2164,7 +2165,7 @@ pub const BundleV2 = struct {
|
||||
graph.ast.append(bun.default_allocator, JSAst.empty) catch unreachable;
|
||||
diff += 1;
|
||||
|
||||
if (this.enqueueOnLoadPluginIfNeeded(new_task)) {
|
||||
if (this.enqueueOnLoadPluginIfNeeded(new_task, bun.JSC.JSValue.jsUndefined())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ interface BundlerPlugin {
|
||||
sourceCode: string | Uint8Array | ArrayBuffer | DataView | null,
|
||||
loaderKey: number | null,
|
||||
): void;
|
||||
onResolveAsync(internalID, a, b, c): void;
|
||||
onResolveAsync(internalID, a, b, c, d): void;
|
||||
addError(internalID, error, number): void;
|
||||
addFilter(filter, namespace, number): void;
|
||||
}
|
||||
@@ -189,15 +189,23 @@ export function runSetupFunction(this: BundlerPlugin, setup: Setup, config: Buil
|
||||
return processSetupResult();
|
||||
}
|
||||
|
||||
export function runOnResolvePlugins(this: BundlerPlugin, specifier, inputNamespace, importer, internalID, kindId) {
|
||||
export function runOnResolvePlugins(
|
||||
this: BundlerPlugin,
|
||||
specifier,
|
||||
inputNamespace,
|
||||
importer,
|
||||
internalID,
|
||||
kindId,
|
||||
resolveDir,
|
||||
) {
|
||||
// Must be kept in sync with ImportRecord.label
|
||||
const kind = $ImportKindIdToLabel[kindId];
|
||||
|
||||
var promiseResult: any = (async (inputPath, inputNamespace, importer, kind) => {
|
||||
var promiseResult: any = (async (inputPath, inputNamespace, importer, kind, resolveDir) => {
|
||||
var { onResolve, onLoad } = this;
|
||||
var results = onResolve.$get(inputNamespace);
|
||||
if (!results) {
|
||||
this.onResolveAsync(internalID, null, null, null);
|
||||
this.onResolveAsync(internalID, null, null, null, null);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -207,7 +215,7 @@ export function runOnResolvePlugins(this: BundlerPlugin, specifier, inputNamespa
|
||||
path: inputPath,
|
||||
importer,
|
||||
namespace: inputNamespace,
|
||||
// resolveDir
|
||||
resolveDir,
|
||||
kind,
|
||||
// pluginData
|
||||
});
|
||||
@@ -228,9 +236,13 @@ export function runOnResolvePlugins(this: BundlerPlugin, specifier, inputNamespa
|
||||
continue;
|
||||
}
|
||||
|
||||
var { path, namespace: userNamespace = inputNamespace, external } = result;
|
||||
if (!(typeof path === "string") || !(typeof userNamespace === "string")) {
|
||||
throw new TypeError("onResolve plugins must return an object with a string 'path' and string 'loader' field");
|
||||
var { path, namespace: userNamespace = inputNamespace, external, pluginData } = result;
|
||||
if (!(typeof path === "string")) {
|
||||
throw new TypeError("onResolve: expected 'path' to be a string");
|
||||
}
|
||||
|
||||
if (!(typeof userNamespace === "string")) {
|
||||
throw new TypeError("onResolve: expected 'namespace' to be a string");
|
||||
}
|
||||
|
||||
if (!path) {
|
||||
@@ -241,7 +253,7 @@ export function runOnResolvePlugins(this: BundlerPlugin, specifier, inputNamespa
|
||||
userNamespace = inputNamespace;
|
||||
}
|
||||
if (typeof external !== "boolean" && !$isUndefinedOrNull(external)) {
|
||||
throw new TypeError('onResolve plugins "external" field must be boolean or unspecified');
|
||||
throw new TypeError("onResolve: expected 'external' to be boolean");
|
||||
}
|
||||
|
||||
if (!external) {
|
||||
@@ -264,14 +276,14 @@ export function runOnResolvePlugins(this: BundlerPlugin, specifier, inputNamespa
|
||||
throw new TypeError(`Expected onLoad plugin for namespace ${userNamespace} to exist`);
|
||||
}
|
||||
}
|
||||
this.onResolveAsync(internalID, path, userNamespace, external);
|
||||
this.onResolveAsync(internalID, path, userNamespace, external, pluginData);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
this.onResolveAsync(internalID, null, null, null);
|
||||
this.onResolveAsync(internalID, null, null, null, null);
|
||||
return null;
|
||||
})(specifier, inputNamespace, importer, kind);
|
||||
})(specifier, inputNamespace, importer, kind, resolveDir);
|
||||
|
||||
while (
|
||||
promiseResult &&
|
||||
@@ -291,11 +303,11 @@ export function runOnResolvePlugins(this: BundlerPlugin, specifier, inputNamespa
|
||||
}
|
||||
}
|
||||
|
||||
export function runOnLoadPlugins(this: BundlerPlugin, internalID, path, namespace, defaultLoaderId) {
|
||||
export function runOnLoadPlugins(this: BundlerPlugin, internalID, path, namespace, defaultLoaderId, pluginData) {
|
||||
const LOADERS_MAP = $LoaderLabelToId;
|
||||
const loaderName = $LoaderIdToLabel[defaultLoaderId];
|
||||
|
||||
var promiseResult = (async (internalID, path, namespace, defaultLoader) => {
|
||||
var promiseResult = (async (internalID, path, namespace, defaultLoader, pluginData) => {
|
||||
var results = this.onLoad.$get(namespace);
|
||||
if (!results) {
|
||||
this.onLoadAsync(internalID, null, null);
|
||||
@@ -308,7 +320,7 @@ export function runOnLoadPlugins(this: BundlerPlugin, internalID, path, namespac
|
||||
path,
|
||||
namespace,
|
||||
// suffix
|
||||
// pluginData
|
||||
pluginData,
|
||||
loader: defaultLoader,
|
||||
});
|
||||
|
||||
@@ -329,6 +341,9 @@ export function runOnLoadPlugins(this: BundlerPlugin, internalID, path, namespac
|
||||
}
|
||||
|
||||
var { contents, loader = defaultLoader } = result as OnLoadResultSourceCode & OnLoadResultObject;
|
||||
|
||||
// TODO: Support "object" loader
|
||||
|
||||
if (!(typeof contents === "string") && !$isTypedArrayView(contents)) {
|
||||
throw new TypeError('onLoad plugins must return an object with "contents" as a string or Uint8Array');
|
||||
}
|
||||
@@ -349,7 +364,7 @@ export function runOnLoadPlugins(this: BundlerPlugin, internalID, path, namespac
|
||||
|
||||
this.onLoadAsync(internalID, null, null);
|
||||
return null;
|
||||
})(internalID, path, namespace, loaderName);
|
||||
})(internalID, path, namespace, loaderName, pluginData);
|
||||
|
||||
while (
|
||||
promiseResult &&
|
||||
|
||||
8
src/js/out/WebCoreJSBuiltins.cpp
generated
8
src/js/out/WebCoreJSBuiltins.cpp
generated
@@ -22,17 +22,17 @@ const char* const s_bundlerPluginRunSetupFunctionCode = "(function (_,E){\"use s
|
||||
const JSC::ConstructAbility s_bundlerPluginRunOnResolvePluginsCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
|
||||
const JSC::ConstructorKind s_bundlerPluginRunOnResolvePluginsCodeConstructorKind = JSC::ConstructorKind::None;
|
||||
const JSC::ImplementationVisibility s_bundlerPluginRunOnResolvePluginsCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
|
||||
const int s_bundlerPluginRunOnResolvePluginsCodeLength = 1711;
|
||||
const int s_bundlerPluginRunOnResolvePluginsCodeLength = 1757;
|
||||
static const JSC::Intrinsic s_bundlerPluginRunOnResolvePluginsCodeIntrinsic = JSC::NoIntrinsic;
|
||||
const char* const s_bundlerPluginRunOnResolvePluginsCode = "(function (_,w,g,y,b){\"use strict\";const j=[\"entry-point\",\"import-statement\",\"require-call\",\"dynamic-import\",\"require-resolve\",\"import-rule\",\"url-token\",\"internal\"][b];var q=(async(z,A,B,C)=>{var{onResolve:E,onLoad:F}=this,G=E.@get(A);if(!G)return this.onResolveAsync(y,null,null,null),null;for(let[O,Q]of G)if(O.test(z)){var H=Q({path:z,importer:B,namespace:A,kind:C});while(H&&@isPromise(H)&&(@getPromiseInternalField(H,@promiseFieldFlags)&@promiseStateMask)===@promiseStateFulfilled)H=@getPromiseInternalField(H,@promiseFieldReactionsOrResult);if(H&&@isPromise(H))H=await H;if(!H||!@isObject(H))continue;var{path:J,namespace:K=A,external:M}=H;if(typeof J!==\"string\"||typeof K!==\"string\")@throwTypeError(\"onResolve plugins must return an object with a string 'path' and string 'loader' field\");if(!J)continue;if(!K)K=A;if(typeof M!==\"boolean\"&&!@isUndefinedOrNull(M))@throwTypeError('onResolve plugins \"external\" field must be boolean or unspecified');if(!M){if(K===\"file\"){if(darwin!==\"win32\"){if(J[0]!==\"/\"||J.includes(\"..\"))@throwTypeError('onResolve plugin \"path\" must be absolute when the namespace is \"file\"')}}if(K===\"dataurl\"){if(!J.startsWith(\"data:\"))@throwTypeError('onResolve plugin \"path\" must start with \"data:\" when the namespace is \"dataurl\"')}if(K&&K!==\"file\"&&(!F||!F.@has(K)))@throwTypeError(`Expected onLoad plugin for namespace ${K} to exist`)}return this.onResolveAsync(y,J,K,M),null}return this.onResolveAsync(y,null,null,null),null})(_,w,g,j);while(q&&@isPromise(q)&&(@getPromiseInternalField(q,@promiseFieldFlags)&@promiseStateMask)===@promiseStateFulfilled)q=@getPromiseInternalField(q,@promiseFieldReactionsOrResult);if(q&&@isPromise(q))q.then(()=>{},(z)=>{this.addError(y,z,0)})})\n";
|
||||
const char* const s_bundlerPluginRunOnResolvePluginsCode = "(function (_,y,w,j,q,z){\"use strict\";const A=[\"entry-point\",\"import-statement\",\"require-call\",\"dynamic-import\",\"require-resolve\",\"import-rule\",\"url-token\",\"internal\"][q];var B=(async(C,E,F,G,H)=>{var{onResolve:J,onLoad:K}=this,M=J.@get(E);if(!M)return this.onResolveAsync(j,null,null,null,null),null;for(let[V,W]of M)if(V.test(C)){var O=W({path:C,importer:F,namespace:E,resolveDir:H,kind:G});while(O&&@isPromise(O)&&(@getPromiseInternalField(O,@promiseFieldFlags)&@promiseStateMask)===@promiseStateFulfilled)O=@getPromiseInternalField(O,@promiseFieldReactionsOrResult);if(O&&@isPromise(O))O=await O;if(!O||!@isObject(O))continue;var{path:Q,namespace:S=E,external:T,pluginData:U}=O;if(typeof Q!==\"string\")@throwTypeError(\"onResolve: expected 'path' to be a string\");if(typeof S!==\"string\")@throwTypeError(\"onResolve: expected 'namespace' to be a string\");if(!Q)continue;if(!S)S=E;if(typeof T!==\"boolean\"&&!@isUndefinedOrNull(T))@throwTypeError(\"onResolve: expected 'external' to be boolean\");if(!T){if(S===\"file\"){if(darwin!==\"win32\"){if(Q[0]!==\"/\"||Q.includes(\"..\"))@throwTypeError('onResolve plugin \"path\" must be absolute when the namespace is \"file\"')}}if(S===\"dataurl\"){if(!Q.startsWith(\"data:\"))@throwTypeError('onResolve plugin \"path\" must start with \"data:\" when the namespace is \"dataurl\"')}if(S&&S!==\"file\"&&(!K||!K.@has(S)))@throwTypeError(`Expected onLoad plugin for namespace ${S} to exist`)}return this.onResolveAsync(j,Q,S,T,U),null}return this.onResolveAsync(j,null,null,null,null),null})(_,y,w,A,z);while(B&&@isPromise(B)&&(@getPromiseInternalField(B,@promiseFieldFlags)&@promiseStateMask)===@promiseStateFulfilled)B=@getPromiseInternalField(B,@promiseFieldReactionsOrResult);if(B&&@isPromise(B))B.then(()=>{},(C)=>{this.addError(j,C,0)})})\n";
|
||||
|
||||
// runOnLoadPlugins
|
||||
const JSC::ConstructAbility s_bundlerPluginRunOnLoadPluginsCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
|
||||
const JSC::ConstructorKind s_bundlerPluginRunOnLoadPluginsCodeConstructorKind = JSC::ConstructorKind::None;
|
||||
const JSC::ImplementationVisibility s_bundlerPluginRunOnLoadPluginsCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
|
||||
const int s_bundlerPluginRunOnLoadPluginsCodeLength = 1325;
|
||||
const int s_bundlerPluginRunOnLoadPluginsCodeLength = 1344;
|
||||
static const JSC::Intrinsic s_bundlerPluginRunOnLoadPluginsCodeIntrinsic = JSC::NoIntrinsic;
|
||||
const char* const s_bundlerPluginRunOnLoadPluginsCode = "(function (b,g,j,q){\"use strict\";const v={jsx:0,js:1,ts:2,tsx:3,css:4,file:5,json:6,toml:7,wasm:8,napi:9,base64:10,dataurl:11,text:12},w=[\"jsx\",\"js\",\"ts\",\"tsx\",\"css\",\"file\",\"json\",\"toml\",\"wasm\",\"napi\",\"base64\",\"dataurl\",\"text\"][q];var x=(async(y,z,B,C)=>{var F=this.onLoad.@get(B);if(!F)return this.onLoadAsync(y,null,null),null;for(let[K,Q]of F)if(K.test(z)){var G=Q({path:z,namespace:B,loader:C});while(G&&@isPromise(G)&&(@getPromiseInternalField(G,@promiseFieldFlags)&@promiseStateMask)===@promiseStateFulfilled)G=@getPromiseInternalField(G,@promiseFieldReactionsOrResult);if(G&&@isPromise(G))G=await G;if(!G||!@isObject(G))continue;var{contents:H,loader:J=C}=G;if(typeof H!==\"string\"&&!@isTypedArrayView(H))@throwTypeError('onLoad plugins must return an object with \"contents\" as a string or Uint8Array');if(typeof J!==\"string\")@throwTypeError('onLoad plugins must return an object with \"loader\" as a string');const T=v[J];if(T===@undefined)@throwTypeError(`Loader ${J} is not supported.`);return this.onLoadAsync(y,H,T),null}return this.onLoadAsync(y,null,null),null})(b,g,j,w);while(x&&@isPromise(x)&&(@getPromiseInternalField(x,@promiseFieldFlags)&@promiseStateMask)===@promiseStateFulfilled)x=@getPromiseInternalField(x,@promiseFieldReactionsOrResult);if(x&&@isPromise(x))x.then(()=>{},(y)=>{this.addError(b,y,1)})})\n";
|
||||
const char* const s_bundlerPluginRunOnLoadPluginsCode = "(function (j,T,_,b,q){\"use strict\";const v={jsx:0,js:1,ts:2,tsx:3,css:4,file:5,json:6,toml:7,wasm:8,napi:9,base64:10,dataurl:11,text:12},w=[\"jsx\",\"js\",\"ts\",\"tsx\",\"css\",\"file\",\"json\",\"toml\",\"wasm\",\"napi\",\"base64\",\"dataurl\",\"text\"][b];var x=(async(y,z,B,C,F)=>{var G=this.onLoad.@get(B);if(!G)return this.onLoadAsync(y,null,null),null;for(let[P,Q]of G)if(P.test(z)){var H=Q({path:z,namespace:B,pluginData:F,loader:C});while(H&&@isPromise(H)&&(@getPromiseInternalField(H,@promiseFieldFlags)&@promiseStateMask)===@promiseStateFulfilled)H=@getPromiseInternalField(H,@promiseFieldReactionsOrResult);if(H&&@isPromise(H))H=await H;if(!H||!@isObject(H))continue;var{contents:J,loader:K=C}=H;if(typeof J!==\"string\"&&!@isTypedArrayView(J))@throwTypeError('onLoad plugins must return an object with \"contents\" as a string or Uint8Array');if(typeof K!==\"string\")@throwTypeError('onLoad plugins must return an object with \"loader\" as a string');const S=v[K];if(S===@undefined)@throwTypeError(`Loader ${K} is not supported.`);return this.onLoadAsync(y,J,S),null}return this.onLoadAsync(y,null,null),null})(j,T,_,w,q);while(x&&@isPromise(x)&&(@getPromiseInternalField(x,@promiseFieldFlags)&@promiseStateMask)===@promiseStateFulfilled)x=@getPromiseInternalField(x,@promiseFieldReactionsOrResult);if(x&&@isPromise(x))x.then(()=>{},(y)=>{this.addError(j,y,1)})})\n";
|
||||
|
||||
#define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \
|
||||
JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
|
||||
|
||||
4
src/js/out/WebCoreJSBuiltins.h
generated
4
src/js/out/WebCoreJSBuiltins.h
generated
@@ -42,8 +42,8 @@ extern const JSC::ImplementationVisibility s_bundlerPluginRunOnLoadPluginsCodeIm
|
||||
|
||||
#define WEBCORE_FOREACH_BUNDLERPLUGIN_BUILTIN_DATA(macro) \
|
||||
macro(runSetupFunction, bundlerPluginRunSetupFunction, 2) \
|
||||
macro(runOnResolvePlugins, bundlerPluginRunOnResolvePlugins, 5) \
|
||||
macro(runOnLoadPlugins, bundlerPluginRunOnLoadPlugins, 4) \
|
||||
macro(runOnResolvePlugins, bundlerPluginRunOnResolvePlugins, 7) \
|
||||
macro(runOnLoadPlugins, bundlerPluginRunOnLoadPlugins, 5) \
|
||||
|
||||
#define WEBCORE_FOREACH_BUNDLERPLUGIN_BUILTIN_CODE(macro) \
|
||||
macro(bundlerPluginRunSetupFunctionCode, runSetupFunction, ASCIILiteral(), s_bundlerPluginRunSetupFunctionCodeLength) \
|
||||
|
||||
BIN
test/bun.lockb
BIN
test/bun.lockb
Binary file not shown.
@@ -830,4 +830,32 @@ describe("bundler", () => {
|
||||
},
|
||||
};
|
||||
});
|
||||
itBundled("plugin/resolveDir", ({ getConfigRef, root }) => {
|
||||
return {
|
||||
run: true,
|
||||
files: {
|
||||
"index.ts": /* ts */ `
|
||||
import "./foo.magic";
|
||||
`,
|
||||
},
|
||||
entryPoints: ["./index.ts"],
|
||||
plugins(build) {
|
||||
build.onResolve({ "filter": /.magic$/ }, args => {
|
||||
console.log({ root, resolveDir: args.resolveDir });
|
||||
expect(args.resolveDir).toBeDefined();
|
||||
expect(args.resolveDir).toEqual(root);
|
||||
return {
|
||||
path: "magic",
|
||||
"namespace": "magic",
|
||||
};
|
||||
});
|
||||
build.onLoad({ namespace: "magic", "filter": /.*/ }, _args => {
|
||||
return {
|
||||
contents: "",
|
||||
loader: "ts",
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "fs";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import dedent from "dedent";
|
||||
import { bunEnv, bunExe } from "harness";
|
||||
import { tmpdir } from "os";
|
||||
@@ -42,7 +43,7 @@ export const RUN_UNCHECKED_TESTS = false;
|
||||
|
||||
const outBaseTemplate = path.join(tmpdir(), "bun-build-tests", `${ESBUILD ? "esbuild" : "bun"}-`);
|
||||
if (!existsSync(path.dirname(outBaseTemplate))) mkdirSync(path.dirname(outBaseTemplate), { recursive: true });
|
||||
const outBase = mkdtempSync(outBaseTemplate);
|
||||
const outBase = fs.realpathSync(mkdtempSync(outBaseTemplate));
|
||||
const testsRan = new Set();
|
||||
|
||||
if (ESBUILD) {
|
||||
@@ -410,7 +411,7 @@ function expectBundled(
|
||||
backend = plugins !== undefined ? "api" : "cli";
|
||||
}
|
||||
|
||||
const root = path.join(outBase, id.replaceAll("/", path.sep));
|
||||
const root = await path.join(outBase, id.replaceAll("/", path.sep));
|
||||
if (DEBUG) console.log("root:", root);
|
||||
|
||||
const entryPaths = entryPoints.map(file => path.join(root, file));
|
||||
@@ -1186,6 +1187,9 @@ for (const [key, blob] of build.outputs) {
|
||||
},
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
});
|
||||
if (DEBUG) {
|
||||
console.log({ stdout: stdout!.toString("utf-8"), stderr: stderr!.toString("utf-8") });
|
||||
}
|
||||
|
||||
if (run.error) {
|
||||
if (success) {
|
||||
@@ -1287,6 +1291,7 @@ export function itBundled(
|
||||
): BundlerTestRef {
|
||||
if (typeof opts === "function") {
|
||||
const fn = opts;
|
||||
// console.log("outbase", outBase);
|
||||
opts = opts({ root: path.join(outBase, id.replaceAll("/", path.sep)), getConfigRef });
|
||||
// @ts-expect-error
|
||||
opts._referenceFn = fn;
|
||||
|
||||
Reference in New Issue
Block a user