aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/builtins/js/BundlerPlugin.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/builtins/js/BundlerPlugin.js')
-rw-r--r--src/bun.js/builtins/js/BundlerPlugin.js467
1 files changed, 0 insertions, 467 deletions
diff --git a/src/bun.js/builtins/js/BundlerPlugin.js b/src/bun.js/builtins/js/BundlerPlugin.js
deleted file mode 100644
index 344f570d0..000000000
--- a/src/bun.js/builtins/js/BundlerPlugin.js
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (C) 2023 Codeblog Corp. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This API expects 4 functions:
-// - onLoadAsync
-// - onResolveAsync
-// - addError
-// - addFilter
-//
-// It should be generic enough to reuse for Bun.plugin() eventually, too.
-
-function runOnResolvePlugins(
- specifier,
- inputNamespace,
- importer,
- internalID,
- kindId
-) {
- "use strict";
-
- // Must be kept in sync with ImportRecord.label
- const kind = [
- "entry-point",
- "import-statement",
- "require-call",
- "dynamic-import",
- "require-resolve",
- "import-rule",
- "url-token",
- "internal",
- ][kindId];
-
- var promiseResult = (async (inputPath, inputNamespace, importer, kind) => {
- var {onResolve, onLoad} = this;
- var results = onResolve.@get(inputNamespace);
- if (!results) {
- this.onResolveAsync(internalID, null, null, null);
- return null;
- }
-
- for (let [filter, callback] of results) {
- if (filter.test(inputPath)) {
- var result = callback({
- path: inputPath,
- importer,
- namespace: inputNamespace,
- // resolveDir
- kind,
- // pluginData
- });
-
- while (
- result &&
- @isPromise(result) &&
- (@getPromiseInternalField(result, @promiseFieldFlags) &
- @promiseStateMask) ===
- @promiseStateFulfilled
- ) {
- result = @getPromiseInternalField(
- result,
- @promiseFieldReactionsOrResult
- );
- }
-
- if (result && @isPromise(result)) {
- result = await result;
- }
-
- if (!result || !@isObject(result)) {
- continue;
- }
-
-
- var {
- path,
- namespace: userNamespace = inputNamespace,
- external,
- } = result;
- if (
- !(typeof path === "string") ||
- !(typeof userNamespace === "string")
- ) {
- @throwTypeError(
- "onResolve plugins must return an object with a string 'path' and string 'loader' field"
- );
- }
-
- if (!path) {
- continue;
- }
-
- if (!userNamespace) {
- userNamespace = inputNamespace;
- }
- if (typeof external !== "boolean" && !@isUndefinedOrNull(external)) {
- @throwTypeError(
- 'onResolve plugins "external" field must be boolean or unspecified'
- );
- }
-
-
- if (!external) {
- if (userNamespace === "file") {
- // TODO: Windows
-
- if (path[0] !== "/" || path.includes("..")) {
- @throwTypeError(
- 'onResolve plugin "path" must be absolute when the namespace is "file"'
- );
- }
- }
- if (userNamespace === "dataurl") {
- if (!path.startsWith("data:")) {
- @throwTypeError(
- 'onResolve plugin "path" must start with "data:" when the namespace is "dataurl"'
- );
- }
- }
-
- if (userNamespace && userNamespace !== "file" && (!onLoad || !onLoad.@has(userNamespace))) {
- @throwTypeError(
- `Expected onLoad plugin for namespace ${@jsonStringify(userNamespace, " ")} to exist`
- );
- }
-
- }
- this.onResolveAsync(internalID, path, userNamespace, external);
- return null;
- }
- }
-
- this.onResolveAsync(internalID, null, null, null);
- return null;
- })(specifier, inputNamespace, importer, kind);
-
- while (
- promiseResult &&
- @isPromise(promiseResult) &&
- (@getPromiseInternalField(promiseResult, @promiseFieldFlags) &
- @promiseStateMask) ===
- @promiseStateFulfilled
- ) {
- promiseResult = @getPromiseInternalField(
- promiseResult,
- @promiseFieldReactionsOrResult
- );
- }
-
- if (promiseResult && @isPromise(promiseResult)) {
- promiseResult.then(
- () => {},
- (e) => {
- this.addError(internalID, e, 0);
- }
- );
- }
-}
-
-function runSetupFunction(setup, config) {
- "use strict";
- var onLoadPlugins = new Map(),
- onResolvePlugins = new Map();
-
- function validate(filterObject, callback, map) {
- if (!filterObject || !@isObject(filterObject)) {
- @throwTypeError('Expected an object with "filter" RegExp');
- }
-
- if (!callback || !@isCallable(callback)) {
- @throwTypeError("callback must be a function");
- }
-
- var { filter, namespace = "file" } = filterObject;
-
- if (!filter) {
- @throwTypeError('Expected an object with "filter" RegExp');
- }
-
- if (!@isRegExpObject(filter)) {
- @throwTypeError("filter must be a RegExp");
- }
-
- if (namespace && !(typeof namespace === "string")) {
- @throwTypeError("namespace must be a string");
- }
-
- if ((namespace?.length ?? 0) === 0) {
- namespace = "file";
- }
-
- if (!/^([/@a-zA-Z0-9_\\-]+)$/.test(namespace)) {
- @throwTypeError("namespace can only contain @a-zA-Z0-9_\\-");
- }
-
- var callbacks = map.@get(namespace);
-
- if (!callbacks) {
- map.@set(namespace, [[filter, callback]]);
- } else {
- @arrayPush(callbacks, [filter, callback]);
- }
- }
-
- function onLoad(filterObject, callback) {
- validate(filterObject, callback, onLoadPlugins);
- }
-
- function onResolve(filterObject, callback) {
- validate(filterObject, callback, onResolvePlugins);
- }
-
- function onStart(callback) {
- // builtin generator thinks the // in the link is a comment and removes it
- @throwTypeError("On-start callbacks are not implemented yet. See https:/\/github.com/oven-sh/bun/issues/2771");
- }
-
- function onEnd(callback) {
- @throwTypeError("On-end callbacks are not implemented yet. See https:/\/github.com/oven-sh/bun/issues/2771");
- }
-
- function onDispose(callback) {
- @throwTypeError("On-dispose callbacks are not implemented yet. See https:/\/github.com/oven-sh/bun/issues/2771");
- }
-
- function resolve(callback) {
- @throwTypeError("build.resolve() is not implemented yet. See https:/\/github.com/oven-sh/bun/issues/2771");
- }
-
- const processSetupResult = () => {
- var anyOnLoad = false,
- anyOnResolve = false;
-
- for (var [namespace, callbacks] of onLoadPlugins.entries()) {
- for (var [filter] of callbacks) {
- this.addFilter(filter, namespace, 1);
- anyOnLoad = true;
- }
- }
-
- for (var [namespace, callbacks] of onResolvePlugins.entries()) {
- for (var [filter] of callbacks) {
- this.addFilter(filter, namespace, 0);
- anyOnResolve = true;
- }
- }
-
- if (anyOnResolve) {
- var onResolveObject = this.onResolve;
- if (!onResolveObject) {
- this.onResolve = onResolvePlugins;
- } else {
- for (var [namespace, callbacks] of onResolvePlugins.entries()) {
- var existing = onResolveObject.@get(namespace);
-
- if (!existing) {
- onResolveObject.@set(namespace, callbacks);
- } else {
- onResolveObject.@set(namespace, existing.concat(callbacks));
- }
- }
- }
- }
-
- if (anyOnLoad) {
- var onLoadObject = this.onLoad;
- if (!onLoadObject) {
- this.onLoad = onLoadPlugins;
- } else {
- for (var [namespace, callbacks] of onLoadPlugins.entries()) {
- var existing = onLoadObject.@get(namespace);
-
- if (!existing) {
- onLoadObject.@set(namespace, callbacks);
- } else {
- onLoadObject.@set(namespace, existing.concat(callbacks));
- }
- }
- }
- }
-
- return anyOnLoad || anyOnResolve;
- };
-
- var setupResult = setup({
- config,
- onDispose,
- onEnd,
- onLoad,
- onResolve,
- onStart,
- resolve,
- // esbuild's options argument is different, we provide some interop
- initialOptions: {
- ...config,
- bundle: true,
- entryPoints: config.entrypoints ?? config.entryPoints ?? [],
- minify: typeof config.minify === 'boolean' ? config.minify : false,
- minifyIdentifiers: config.minify === true || config.minify?.identifiers,
- minifyWhitespace: config.minify === true || config.minify?.whitespace,
- minifySyntax: config.minify === true || config.minify?.syntax,
- outbase: config.root,
- platform: config.target === 'bun' ? 'node' : config.target,
- root: undefined,
- },
- esbuild: {},
- });
-
- if (setupResult && @isPromise(setupResult)) {
- if (
- @getPromiseInternalField(setupResult, @promiseFieldFlags) &
- @promiseStateFulfilled
- ) {
- setupResult = @getPromiseInternalField(
- setupResult,
- @promiseFieldReactionsOrResult
- );
- } else {
- return setupResult.@then(processSetupResult);
- }
- }
-
- return processSetupResult();
-}
-
-function runOnLoadPlugins(internalID, path, namespace, defaultLoaderId) {
- "use strict";
-
- const LOADERS_MAP = {
- 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,
- };
- const loaderName = [
- "jsx",
- "js",
- "ts",
- "tsx",
- "css",
- "file",
- "json",
- "toml",
- "wasm",
- "napi",
- "base64",
- "dataurl",
- "text",
- ][defaultLoaderId];
-
- var promiseResult = (async (internalID, path, namespace, defaultLoader) => {
- var results = this.onLoad.@get(namespace);
- if (!results) {
- this.onLoadAsync(internalID, null, null, null);
- return null;
- }
-
- for (let [filter, callback] of results) {
- if (filter.test(path)) {
- var result = callback({
- path,
- namespace,
- // suffix
- // pluginData
- loader: defaultLoader,
- });
-
- while (
- result &&
- @isPromise(result) &&
- (@getPromiseInternalField(result, @promiseFieldFlags) &
- @promiseStateMask) ===
- @promiseStateFulfilled
- ) {
- result = @getPromiseInternalField(
- result,
- @promiseFieldReactionsOrResult
- );
- }
-
- if (result && @isPromise(result)) {
- result = await result;
- }
-
- if (!result || !@isObject(result)) {
- continue;
- }
-
- var { contents, loader = defaultLoader } = result;
- if (!(typeof contents === "string") && !@isTypedArrayView(contents)) {
- @throwTypeError(
- 'onLoad plugins must return an object with "contents" as a string or Uint8Array'
- );
- }
-
- if (!(typeof loader === "string")) {
- @throwTypeError(
- 'onLoad plugins must return an object with "loader" as a string'
- );
- }
-
- const chosenLoader = LOADERS_MAP[loader];
- if (chosenLoader === @undefined) {
- @throwTypeError(`Loader ${@jsonStringify(loader, " ")} is not supported.`);
- }
-
- this.onLoadAsync(internalID, contents, chosenLoader);
- return null;
- }
- }
-
- this.onLoadAsync(internalID, null, null);
- return null;
- })(internalID, path, namespace, loaderName);
-
- while (
- promiseResult &&
- @isPromise(promiseResult) &&
- (@getPromiseInternalField(promiseResult, @promiseFieldFlags) &
- @promiseStateMask) ===
- @promiseStateFulfilled
- ) {
- promiseResult = @getPromiseInternalField(
- promiseResult,
- @promiseFieldReactionsOrResult
- );
- }
-
- if (promiseResult && @isPromise(promiseResult)) {
- promiseResult.then(
- () => {},
- (e) => {
- this.addError(internalID, e, 1);
- }
- );
- }
-}