esbuild
Version:
An extremely fast JavaScript bundler and minifier.
1,355 lines (1,352 loc) • 68.5 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// lib/npm/node.ts
__markAsModule(exports);
__export(exports, {
build: () => build,
buildSync: () => buildSync,
formatMessages: () => formatMessages,
formatMessagesSync: () => formatMessagesSync,
initialize: () => initialize,
serve: () => serve,
transform: () => transform,
transformSync: () => transformSync,
version: () => version
});
// lib/shared/stdio_protocol.ts
function encodePacket(packet) {
let visit = (value) => {
if (value === null) {
bb.write8(0);
} else if (typeof value === "boolean") {
bb.write8(1);
bb.write8(+value);
} else if (typeof value === "number") {
bb.write8(2);
bb.write32(value | 0);
} else if (typeof value === "string") {
bb.write8(3);
bb.write(encodeUTF8(value));
} else if (value instanceof Uint8Array) {
bb.write8(4);
bb.write(value);
} else if (value instanceof Array) {
bb.write8(5);
bb.write32(value.length);
for (let item of value) {
visit(item);
}
} else {
let keys = Object.keys(value);
bb.write8(6);
bb.write32(keys.length);
for (let key of keys) {
bb.write(encodeUTF8(key));
visit(value[key]);
}
}
};
let bb = new ByteBuffer();
bb.write32(0);
bb.write32(packet.id << 1 | +!packet.isRequest);
visit(packet.value);
writeUInt32LE(bb.buf, bb.len - 4, 0);
return bb.buf.subarray(0, bb.len);
}
function decodePacket(bytes) {
let visit = () => {
switch (bb.read8()) {
case 0:
return null;
case 1:
return !!bb.read8();
case 2:
return bb.read32();
case 3:
return decodeUTF8(bb.read());
case 4:
return bb.read();
case 5: {
let count = bb.read32();
let value2 = [];
for (let i = 0; i < count; i++) {
value2.push(visit());
}
return value2;
}
case 6: {
let count = bb.read32();
let value2 = {};
for (let i = 0; i < count; i++) {
value2[decodeUTF8(bb.read())] = visit();
}
return value2;
}
default:
throw new Error("Invalid packet");
}
};
let bb = new ByteBuffer(bytes);
let id = bb.read32();
let isRequest = (id & 1) === 0;
id >>>= 1;
let value = visit();
if (bb.ptr !== bytes.length) {
throw new Error("Invalid packet");
}
return { id, isRequest, value };
}
var ByteBuffer = class {
constructor(buf = new Uint8Array(1024)) {
this.buf = buf;
this.len = 0;
this.ptr = 0;
}
_write(delta) {
if (this.len + delta > this.buf.length) {
let clone = new Uint8Array((this.len + delta) * 2);
clone.set(this.buf);
this.buf = clone;
}
this.len += delta;
return this.len - delta;
}
write8(value) {
let offset = this._write(1);
this.buf[offset] = value;
}
write32(value) {
let offset = this._write(4);
writeUInt32LE(this.buf, value, offset);
}
write(bytes) {
let offset = this._write(4 + bytes.length);
writeUInt32LE(this.buf, bytes.length, offset);
this.buf.set(bytes, offset + 4);
}
_read(delta) {
if (this.ptr + delta > this.buf.length) {
throw new Error("Invalid packet");
}
this.ptr += delta;
return this.ptr - delta;
}
read8() {
return this.buf[this._read(1)];
}
read32() {
return readUInt32LE(this.buf, this._read(4));
}
read() {
let length = this.read32();
let bytes = new Uint8Array(length);
let ptr = this._read(bytes.length);
bytes.set(this.buf.subarray(ptr, ptr + length));
return bytes;
}
};
var encodeUTF8;
var decodeUTF8;
if (typeof TextEncoder !== "undefined" && typeof TextDecoder !== "undefined") {
let encoder = new TextEncoder();
let decoder = new TextDecoder();
encodeUTF8 = (text) => encoder.encode(text);
decodeUTF8 = (bytes) => decoder.decode(bytes);
} else if (typeof Buffer !== "undefined") {
encodeUTF8 = (text) => {
let buffer = Buffer.from(text);
if (!(buffer instanceof Uint8Array)) {
buffer = new Uint8Array(buffer);
}
return buffer;
};
decodeUTF8 = (bytes) => {
let { buffer, byteOffset, byteLength } = bytes;
return Buffer.from(buffer, byteOffset, byteLength).toString();
};
} else {
throw new Error("No UTF-8 codec found");
}
function readUInt32LE(buffer, offset) {
return buffer[offset++] | buffer[offset++] << 8 | buffer[offset++] << 16 | buffer[offset++] << 24;
}
function writeUInt32LE(buffer, value, offset) {
buffer[offset++] = value;
buffer[offset++] = value >> 8;
buffer[offset++] = value >> 16;
buffer[offset++] = value >> 24;
}
// lib/shared/common.ts
function validateTarget(target) {
target += "";
if (target.indexOf(",") >= 0)
throw new Error(`Invalid target: ${target}`);
return target;
}
var canBeAnything = () => null;
var mustBeBoolean = (value) => typeof value === "boolean" ? null : "a boolean";
var mustBeBooleanOrObject = (value) => typeof value === "boolean" || typeof value === "object" && !Array.isArray(value) ? null : "a boolean or an object";
var mustBeString = (value) => typeof value === "string" ? null : "a string";
var mustBeRegExp = (value) => value instanceof RegExp ? null : "a RegExp object";
var mustBeInteger = (value) => typeof value === "number" && value === (value | 0) ? null : "an integer";
var mustBeFunction = (value) => typeof value === "function" ? null : "a function";
var mustBeArray = (value) => Array.isArray(value) ? null : "an array";
var mustBeObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? null : "an object";
var mustBeArrayOrRecord = (value) => typeof value === "object" && value !== null ? null : "an array or an object";
var mustBeObjectOrNull = (value) => typeof value === "object" && !Array.isArray(value) ? null : "an object or null";
var mustBeStringOrBoolean = (value) => typeof value === "string" || typeof value === "boolean" ? null : "a string or a boolean";
var mustBeStringOrObject = (value) => typeof value === "string" || typeof value === "object" && value !== null && !Array.isArray(value) ? null : "a string or an object";
var mustBeStringOrArray = (value) => typeof value === "string" || Array.isArray(value) ? null : "a string or an array";
var mustBeStringOrUint8Array = (value) => typeof value === "string" || value instanceof Uint8Array ? null : "a string or a Uint8Array";
function getFlag(object, keys, key, mustBeFn) {
let value = object[key];
keys[key + ""] = true;
if (value === void 0)
return void 0;
let mustBe = mustBeFn(value);
if (mustBe !== null)
throw new Error(`"${key}" must be ${mustBe}`);
return value;
}
function checkForInvalidFlags(object, keys, where) {
for (let key in object) {
if (!(key in keys)) {
throw new Error(`Invalid option ${where}: "${key}"`);
}
}
}
function validateInitializeOptions(options) {
let keys = Object.create(null);
let wasmURL = getFlag(options, keys, "wasmURL", mustBeString);
let worker = getFlag(options, keys, "worker", mustBeBoolean);
checkForInvalidFlags(options, keys, "in startService() call");
return {
wasmURL,
worker
};
}
function pushLogFlags(flags, options, keys, isTTY2, logLevelDefault) {
let color = getFlag(options, keys, "color", mustBeBoolean);
let logLevel = getFlag(options, keys, "logLevel", mustBeString);
let logLimit = getFlag(options, keys, "logLimit", mustBeInteger);
if (color !== void 0)
flags.push(`--color=${color}`);
else if (isTTY2)
flags.push(`--color=true`);
flags.push(`--log-level=${logLevel || logLevelDefault}`);
flags.push(`--log-limit=${logLimit || 0}`);
}
function pushCommonFlags(flags, options, keys) {
let legalComments = getFlag(options, keys, "legalComments", mustBeString);
let sourceRoot = getFlag(options, keys, "sourceRoot", mustBeString);
let sourcesContent = getFlag(options, keys, "sourcesContent", mustBeBoolean);
let target = getFlag(options, keys, "target", mustBeStringOrArray);
let format = getFlag(options, keys, "format", mustBeString);
let globalName = getFlag(options, keys, "globalName", mustBeString);
let minify = getFlag(options, keys, "minify", mustBeBoolean);
let minifySyntax = getFlag(options, keys, "minifySyntax", mustBeBoolean);
let minifyWhitespace = getFlag(options, keys, "minifyWhitespace", mustBeBoolean);
let minifyIdentifiers = getFlag(options, keys, "minifyIdentifiers", mustBeBoolean);
let charset = getFlag(options, keys, "charset", mustBeString);
let treeShaking = getFlag(options, keys, "treeShaking", mustBeStringOrBoolean);
let jsx = getFlag(options, keys, "jsx", mustBeString);
let jsxFactory = getFlag(options, keys, "jsxFactory", mustBeString);
let jsxFragment = getFlag(options, keys, "jsxFragment", mustBeString);
let define = getFlag(options, keys, "define", mustBeObject);
let pure = getFlag(options, keys, "pure", mustBeArray);
let keepNames = getFlag(options, keys, "keepNames", mustBeBoolean);
if (legalComments)
flags.push(`--legal-comments=${legalComments}`);
if (sourceRoot !== void 0)
flags.push(`--source-root=${sourceRoot}`);
if (sourcesContent !== void 0)
flags.push(`--sources-content=${sourcesContent}`);
if (target) {
if (Array.isArray(target))
flags.push(`--target=${Array.from(target).map(validateTarget).join(",")}`);
else
flags.push(`--target=${validateTarget(target)}`);
}
if (format)
flags.push(`--format=${format}`);
if (globalName)
flags.push(`--global-name=${globalName}`);
if (minify)
flags.push("--minify");
if (minifySyntax)
flags.push("--minify-syntax");
if (minifyWhitespace)
flags.push("--minify-whitespace");
if (minifyIdentifiers)
flags.push("--minify-identifiers");
if (charset)
flags.push(`--charset=${charset}`);
if (treeShaking !== void 0 && treeShaking !== true)
flags.push(`--tree-shaking=${treeShaking}`);
if (jsx)
flags.push(`--jsx=${jsx}`);
if (jsxFactory)
flags.push(`--jsx-factory=${jsxFactory}`);
if (jsxFragment)
flags.push(`--jsx-fragment=${jsxFragment}`);
if (define) {
for (let key in define) {
if (key.indexOf("=") >= 0)
throw new Error(`Invalid define: ${key}`);
flags.push(`--define:${key}=${define[key]}`);
}
}
if (pure)
for (let fn of pure)
flags.push(`--pure:${fn}`);
if (keepNames)
flags.push(`--keep-names`);
}
function flagsForBuildOptions(callName, options, isTTY2, logLevelDefault, writeDefault) {
var _a;
let flags = [];
let entries = [];
let keys = Object.create(null);
let stdinContents = null;
let stdinResolveDir = null;
let watchMode = null;
pushLogFlags(flags, options, keys, isTTY2, logLevelDefault);
pushCommonFlags(flags, options, keys);
let sourcemap = getFlag(options, keys, "sourcemap", mustBeStringOrBoolean);
let bundle = getFlag(options, keys, "bundle", mustBeBoolean);
let watch = getFlag(options, keys, "watch", mustBeBooleanOrObject);
let splitting = getFlag(options, keys, "splitting", mustBeBoolean);
let preserveSymlinks = getFlag(options, keys, "preserveSymlinks", mustBeBoolean);
let metafile = getFlag(options, keys, "metafile", mustBeBoolean);
let outfile = getFlag(options, keys, "outfile", mustBeString);
let outdir = getFlag(options, keys, "outdir", mustBeString);
let outbase = getFlag(options, keys, "outbase", mustBeString);
let platform = getFlag(options, keys, "platform", mustBeString);
let tsconfig = getFlag(options, keys, "tsconfig", mustBeString);
let resolveExtensions = getFlag(options, keys, "resolveExtensions", mustBeArray);
let nodePathsInput = getFlag(options, keys, "nodePaths", mustBeArray);
let mainFields = getFlag(options, keys, "mainFields", mustBeArray);
let conditions = getFlag(options, keys, "conditions", mustBeArray);
let external = getFlag(options, keys, "external", mustBeArray);
let loader = getFlag(options, keys, "loader", mustBeObject);
let outExtension = getFlag(options, keys, "outExtension", mustBeObject);
let publicPath = getFlag(options, keys, "publicPath", mustBeString);
let entryNames = getFlag(options, keys, "entryNames", mustBeString);
let chunkNames = getFlag(options, keys, "chunkNames", mustBeString);
let assetNames = getFlag(options, keys, "assetNames", mustBeString);
let inject = getFlag(options, keys, "inject", mustBeArray);
let banner = getFlag(options, keys, "banner", mustBeObject);
let footer = getFlag(options, keys, "footer", mustBeObject);
let entryPoints = getFlag(options, keys, "entryPoints", mustBeArrayOrRecord);
let absWorkingDir = getFlag(options, keys, "absWorkingDir", mustBeString);
let stdin = getFlag(options, keys, "stdin", mustBeObject);
let write = (_a = getFlag(options, keys, "write", mustBeBoolean)) != null ? _a : writeDefault;
let allowOverwrite = getFlag(options, keys, "allowOverwrite", mustBeBoolean);
let incremental = getFlag(options, keys, "incremental", mustBeBoolean) === true;
keys.plugins = true;
checkForInvalidFlags(options, keys, `in ${callName}() call`);
if (sourcemap)
flags.push(`--sourcemap${sourcemap === true ? "" : `=${sourcemap}`}`);
if (bundle)
flags.push("--bundle");
if (allowOverwrite)
flags.push("--allow-overwrite");
if (watch) {
flags.push("--watch");
if (typeof watch === "boolean") {
watchMode = {};
} else {
let watchKeys = Object.create(null);
let onRebuild = getFlag(watch, watchKeys, "onRebuild", mustBeFunction);
checkForInvalidFlags(watch, watchKeys, `on "watch" in ${callName}() call`);
watchMode = { onRebuild };
}
}
if (splitting)
flags.push("--splitting");
if (preserveSymlinks)
flags.push("--preserve-symlinks");
if (metafile)
flags.push(`--metafile`);
if (outfile)
flags.push(`--outfile=${outfile}`);
if (outdir)
flags.push(`--outdir=${outdir}`);
if (outbase)
flags.push(`--outbase=${outbase}`);
if (platform)
flags.push(`--platform=${platform}`);
if (tsconfig)
flags.push(`--tsconfig=${tsconfig}`);
if (resolveExtensions) {
let values = [];
for (let value of resolveExtensions) {
value += "";
if (value.indexOf(",") >= 0)
throw new Error(`Invalid resolve extension: ${value}`);
values.push(value);
}
flags.push(`--resolve-extensions=${values.join(",")}`);
}
if (publicPath)
flags.push(`--public-path=${publicPath}`);
if (entryNames)
flags.push(`--entry-names=${entryNames}`);
if (chunkNames)
flags.push(`--chunk-names=${chunkNames}`);
if (assetNames)
flags.push(`--asset-names=${assetNames}`);
if (mainFields) {
let values = [];
for (let value of mainFields) {
value += "";
if (value.indexOf(",") >= 0)
throw new Error(`Invalid main field: ${value}`);
values.push(value);
}
flags.push(`--main-fields=${values.join(",")}`);
}
if (conditions) {
let values = [];
for (let value of conditions) {
value += "";
if (value.indexOf(",") >= 0)
throw new Error(`Invalid condition: ${value}`);
values.push(value);
}
flags.push(`--conditions=${values.join(",")}`);
}
if (external)
for (let name of external)
flags.push(`--external:${name}`);
if (banner) {
for (let type in banner) {
if (type.indexOf("=") >= 0)
throw new Error(`Invalid banner file type: ${type}`);
flags.push(`--banner:${type}=${banner[type]}`);
}
}
if (footer) {
for (let type in footer) {
if (type.indexOf("=") >= 0)
throw new Error(`Invalid footer file type: ${type}`);
flags.push(`--footer:${type}=${footer[type]}`);
}
}
if (inject)
for (let path2 of inject)
flags.push(`--inject:${path2}`);
if (loader) {
for (let ext in loader) {
if (ext.indexOf("=") >= 0)
throw new Error(`Invalid loader extension: ${ext}`);
flags.push(`--loader:${ext}=${loader[ext]}`);
}
}
if (outExtension) {
for (let ext in outExtension) {
if (ext.indexOf("=") >= 0)
throw new Error(`Invalid out extension: ${ext}`);
flags.push(`--out-extension:${ext}=${outExtension[ext]}`);
}
}
if (entryPoints) {
if (Array.isArray(entryPoints)) {
for (let entryPoint of entryPoints) {
entries.push(["", entryPoint + ""]);
}
} else {
for (let [key, value] of Object.entries(entryPoints)) {
entries.push([key + "", value + ""]);
}
}
}
if (stdin) {
let stdinKeys = Object.create(null);
let contents = getFlag(stdin, stdinKeys, "contents", mustBeString);
let resolveDir = getFlag(stdin, stdinKeys, "resolveDir", mustBeString);
let sourcefile = getFlag(stdin, stdinKeys, "sourcefile", mustBeString);
let loader2 = getFlag(stdin, stdinKeys, "loader", mustBeString);
checkForInvalidFlags(stdin, stdinKeys, 'in "stdin" object');
if (sourcefile)
flags.push(`--sourcefile=${sourcefile}`);
if (loader2)
flags.push(`--loader=${loader2}`);
if (resolveDir)
stdinResolveDir = resolveDir + "";
stdinContents = contents ? contents + "" : "";
}
let nodePaths = [];
if (nodePathsInput) {
for (let value of nodePathsInput) {
value += "";
nodePaths.push(value);
}
}
return {
entries,
flags,
write,
stdinContents,
stdinResolveDir,
absWorkingDir,
incremental,
nodePaths,
watch: watchMode
};
}
function flagsForTransformOptions(callName, options, isTTY2, logLevelDefault) {
let flags = [];
let keys = Object.create(null);
pushLogFlags(flags, options, keys, isTTY2, logLevelDefault);
pushCommonFlags(flags, options, keys);
let sourcemap = getFlag(options, keys, "sourcemap", mustBeStringOrBoolean);
let tsconfigRaw = getFlag(options, keys, "tsconfigRaw", mustBeStringOrObject);
let sourcefile = getFlag(options, keys, "sourcefile", mustBeString);
let loader = getFlag(options, keys, "loader", mustBeString);
let banner = getFlag(options, keys, "banner", mustBeString);
let footer = getFlag(options, keys, "footer", mustBeString);
checkForInvalidFlags(options, keys, `in ${callName}() call`);
if (sourcemap)
flags.push(`--sourcemap=${sourcemap === true ? "external" : sourcemap}`);
if (tsconfigRaw)
flags.push(`--tsconfig-raw=${typeof tsconfigRaw === "string" ? tsconfigRaw : JSON.stringify(tsconfigRaw)}`);
if (sourcefile)
flags.push(`--sourcefile=${sourcefile}`);
if (loader)
flags.push(`--loader=${loader}`);
if (banner)
flags.push(`--banner=${banner}`);
if (footer)
flags.push(`--footer=${footer}`);
return flags;
}
function createChannel(streamIn) {
let responseCallbacks = new Map();
let pluginCallbacks = new Map();
let watchCallbacks = new Map();
let serveCallbacks = new Map();
let nextServeID = 0;
let isClosed = false;
let nextRequestID = 0;
let nextBuildKey = 0;
let stdout = new Uint8Array(16 * 1024);
let stdoutUsed = 0;
let readFromStdout = (chunk) => {
let limit = stdoutUsed + chunk.length;
if (limit > stdout.length) {
let swap = new Uint8Array(limit * 2);
swap.set(stdout);
stdout = swap;
}
stdout.set(chunk, stdoutUsed);
stdoutUsed += chunk.length;
let offset = 0;
while (offset + 4 <= stdoutUsed) {
let length = readUInt32LE(stdout, offset);
if (offset + 4 + length > stdoutUsed) {
break;
}
offset += 4;
handleIncomingPacket(stdout.subarray(offset, offset + length));
offset += length;
}
if (offset > 0) {
stdout.copyWithin(0, offset, stdoutUsed);
stdoutUsed -= offset;
}
};
let afterClose = () => {
isClosed = true;
for (let callback of responseCallbacks.values()) {
callback("The service was stopped", null);
}
responseCallbacks.clear();
for (let callbacks of serveCallbacks.values()) {
callbacks.onWait("The service was stopped");
}
serveCallbacks.clear();
for (let callback of watchCallbacks.values()) {
try {
callback(new Error("The service was stopped"), null);
} catch (e) {
console.error(e);
}
}
watchCallbacks.clear();
};
let sendRequest = (refs, value, callback) => {
if (isClosed)
return callback("The service is no longer running", null);
let id = nextRequestID++;
responseCallbacks.set(id, (error, response) => {
try {
callback(error, response);
} finally {
if (refs)
refs.unref();
}
});
if (refs)
refs.ref();
streamIn.writeToStdin(encodePacket({ id, isRequest: true, value }));
};
let sendResponse = (id, value) => {
if (isClosed)
throw new Error("The service is no longer running");
streamIn.writeToStdin(encodePacket({ id, isRequest: false, value }));
};
let handleRequest = (id, request) => __async(this, null, function* () {
try {
switch (request.command) {
case "ping": {
sendResponse(id, {});
break;
}
case "start": {
let callback = pluginCallbacks.get(request.key);
if (!callback)
sendResponse(id, {});
else
sendResponse(id, yield callback(request));
break;
}
case "resolve": {
let callback = pluginCallbacks.get(request.key);
if (!callback)
sendResponse(id, {});
else
sendResponse(id, yield callback(request));
break;
}
case "load": {
let callback = pluginCallbacks.get(request.key);
if (!callback)
sendResponse(id, {});
else
sendResponse(id, yield callback(request));
break;
}
case "serve-request": {
let callbacks = serveCallbacks.get(request.serveID);
if (callbacks && callbacks.onRequest)
callbacks.onRequest(request.args);
sendResponse(id, {});
break;
}
case "serve-wait": {
let callbacks = serveCallbacks.get(request.serveID);
if (callbacks)
callbacks.onWait(request.error);
sendResponse(id, {});
break;
}
case "watch-rebuild": {
let callback = watchCallbacks.get(request.watchID);
try {
if (callback)
callback(null, request.args);
} catch (err) {
console.error(err);
}
sendResponse(id, {});
break;
}
default:
throw new Error(`Invalid command: ` + request.command);
}
} catch (e) {
sendResponse(id, { errors: [extractErrorMessageV8(e, streamIn, null, void 0, "")] });
}
});
let isFirstPacket = true;
let handleIncomingPacket = (bytes) => {
if (isFirstPacket) {
isFirstPacket = false;
let binaryVersion = String.fromCharCode(...bytes);
if (binaryVersion !== "0.12.4") {
throw new Error(`Cannot start service: Host version "${"0.12.4"}" does not match binary version ${JSON.stringify(binaryVersion)}`);
}
return;
}
let packet = decodePacket(bytes);
if (packet.isRequest) {
handleRequest(packet.id, packet.value);
} else {
let callback = responseCallbacks.get(packet.id);
responseCallbacks.delete(packet.id);
if (packet.value.error)
callback(packet.value.error, {});
else
callback(null, packet.value);
}
};
let handlePlugins = (initialOptions, plugins, buildKey, stash) => __async(this, null, function* () {
let onStartCallbacks = [];
let onEndCallbacks = [];
let onResolveCallbacks = {};
let onLoadCallbacks = {};
let nextCallbackID = 0;
let i = 0;
let requestPlugins = [];
plugins = [...plugins];
for (let item of plugins) {
let keys = {};
if (typeof item !== "object")
throw new Error(`Plugin at index ${i} must be an object`);
let name = getFlag(item, keys, "name", mustBeString);
if (typeof name !== "string" || name === "")
throw new Error(`Plugin at index ${i} is missing a name`);
try {
let setup = getFlag(item, keys, "setup", mustBeFunction);
if (typeof setup !== "function")
throw new Error(`Plugin is missing a setup function`);
checkForInvalidFlags(item, keys, `on plugin ${JSON.stringify(name)}`);
let plugin = {
name,
onResolve: [],
onLoad: []
};
i++;
let promise = setup({
initialOptions,
onStart(callback2) {
let registeredText = `This error came from the "onStart" callback registered here`;
let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onStart");
onStartCallbacks.push({ name, callback: callback2, note: registeredNote });
},
onEnd(callback2) {
let registeredText = `This error came from the "onEnd" callback registered here`;
let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onEnd");
onEndCallbacks.push({ name, callback: callback2, note: registeredNote });
},
onResolve(options, callback2) {
let registeredText = `This error came from the "onResolve" callback registered here`;
let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onResolve");
let keys2 = {};
let filter = getFlag(options, keys2, "filter", mustBeRegExp);
let namespace = getFlag(options, keys2, "namespace", mustBeString);
checkForInvalidFlags(options, keys2, `in onResolve() call for plugin ${JSON.stringify(name)}`);
if (filter == null)
throw new Error(`onResolve() call is missing a filter`);
let id = nextCallbackID++;
onResolveCallbacks[id] = { name, callback: callback2, note: registeredNote };
plugin.onResolve.push({ id, filter: filter.source, namespace: namespace || "" });
},
onLoad(options, callback2) {
let registeredText = `This error came from the "onLoad" callback registered here`;
let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onLoad");
let keys2 = {};
let filter = getFlag(options, keys2, "filter", mustBeRegExp);
let namespace = getFlag(options, keys2, "namespace", mustBeString);
checkForInvalidFlags(options, keys2, `in onLoad() call for plugin ${JSON.stringify(name)}`);
if (filter == null)
throw new Error(`onLoad() call is missing a filter`);
let id = nextCallbackID++;
onLoadCallbacks[id] = { name, callback: callback2, note: registeredNote };
plugin.onLoad.push({ id, filter: filter.source, namespace: namespace || "" });
}
});
if (promise)
yield promise;
requestPlugins.push(plugin);
} catch (e) {
return { ok: false, error: e, pluginName: name };
}
}
const callback = (request) => __async(this, null, function* () {
switch (request.command) {
case "start": {
let response = { errors: [], warnings: [] };
yield Promise.all(onStartCallbacks.map((_0) => __async(this, [_0], function* ({ name, callback: callback2, note }) {
try {
let result = yield callback2();
if (result != null) {
if (typeof result !== "object")
throw new Error(`Expected onStart() callback in plugin ${JSON.stringify(name)} to return an object`);
let keys = {};
let errors = getFlag(result, keys, "errors", mustBeArray);
let warnings = getFlag(result, keys, "warnings", mustBeArray);
checkForInvalidFlags(result, keys, `from onStart() callback in plugin ${JSON.stringify(name)}`);
if (errors != null)
response.errors.push(...sanitizeMessages(errors, "errors", stash, name));
if (warnings != null)
response.warnings.push(...sanitizeMessages(warnings, "warnings", stash, name));
}
} catch (e) {
response.errors.push(extractErrorMessageV8(e, streamIn, stash, note && note(), name));
}
})));
return response;
}
case "resolve": {
let response = {}, name = "", callback2, note;
for (let id of request.ids) {
try {
({ name, callback: callback2, note } = onResolveCallbacks[id]);
let result = yield callback2({
path: request.path,
importer: request.importer,
namespace: request.namespace,
resolveDir: request.resolveDir,
kind: request.kind,
pluginData: stash.load(request.pluginData)
});
if (result != null) {
if (typeof result !== "object")
throw new Error(`Expected onResolve() callback in plugin ${JSON.stringify(name)} to return an object`);
let keys = {};
let pluginName = getFlag(result, keys, "pluginName", mustBeString);
let path2 = getFlag(result, keys, "path", mustBeString);
let namespace = getFlag(result, keys, "namespace", mustBeString);
let external = getFlag(result, keys, "external", mustBeBoolean);
let pluginData = getFlag(result, keys, "pluginData", canBeAnything);
let errors = getFlag(result, keys, "errors", mustBeArray);
let warnings = getFlag(result, keys, "warnings", mustBeArray);
let watchFiles = getFlag(result, keys, "watchFiles", mustBeArray);
let watchDirs = getFlag(result, keys, "watchDirs", mustBeArray);
checkForInvalidFlags(result, keys, `from onResolve() callback in plugin ${JSON.stringify(name)}`);
response.id = id;
if (pluginName != null)
response.pluginName = pluginName;
if (path2 != null)
response.path = path2;
if (namespace != null)
response.namespace = namespace;
if (external != null)
response.external = external;
if (pluginData != null)
response.pluginData = stash.store(pluginData);
if (errors != null)
response.errors = sanitizeMessages(errors, "errors", stash, name);
if (warnings != null)
response.warnings = sanitizeMessages(warnings, "warnings", stash, name);
if (watchFiles != null)
response.watchFiles = sanitizeStringArray(watchFiles, "watchFiles");
if (watchDirs != null)
response.watchDirs = sanitizeStringArray(watchDirs, "watchDirs");
break;
}
} catch (e) {
return { id, errors: [extractErrorMessageV8(e, streamIn, stash, note && note(), name)] };
}
}
return response;
}
case "load": {
let response = {}, name = "", callback2, note;
for (let id of request.ids) {
try {
({ name, callback: callback2, note } = onLoadCallbacks[id]);
let result = yield callback2({
path: request.path,
namespace: request.namespace,
pluginData: stash.load(request.pluginData)
});
if (result != null) {
if (typeof result !== "object")
throw new Error(`Expected onLoad() callback in plugin ${JSON.stringify(name)} to return an object`);
let keys = {};
let pluginName = getFlag(result, keys, "pluginName", mustBeString);
let contents = getFlag(result, keys, "contents", mustBeStringOrUint8Array);
let resolveDir = getFlag(result, keys, "resolveDir", mustBeString);
let pluginData = getFlag(result, keys, "pluginData", canBeAnything);
let loader = getFlag(result, keys, "loader", mustBeString);
let errors = getFlag(result, keys, "errors", mustBeArray);
let warnings = getFlag(result, keys, "warnings", mustBeArray);
let watchFiles = getFlag(result, keys, "watchFiles", mustBeArray);
let watchDirs = getFlag(result, keys, "watchDirs", mustBeArray);
checkForInvalidFlags(result, keys, `from onLoad() callback in plugin ${JSON.stringify(name)}`);
response.id = id;
if (pluginName != null)
response.pluginName = pluginName;
if (contents instanceof Uint8Array)
response.contents = contents;
else if (contents != null)
response.contents = encodeUTF8(contents);
if (resolveDir != null)
response.resolveDir = resolveDir;
if (pluginData != null)
response.pluginData = stash.store(pluginData);
if (loader != null)
response.loader = loader;
if (errors != null)
response.errors = sanitizeMessages(errors, "errors", stash, name);
if (warnings != null)
response.warnings = sanitizeMessages(warnings, "warnings", stash, name);
if (watchFiles != null)
response.watchFiles = sanitizeStringArray(watchFiles, "watchFiles");
if (watchDirs != null)
response.watchDirs = sanitizeStringArray(watchDirs, "watchDirs");
break;
}
} catch (e) {
return { id, errors: [extractErrorMessageV8(e, streamIn, stash, note && note(), name)] };
}
}
return response;
}
default:
throw new Error(`Invalid command: ` + request.command);
}
});
let runOnEndCallbacks = (result, logPluginError, done) => done();
if (onEndCallbacks.length > 0) {
runOnEndCallbacks = (result, logPluginError, done) => {
(() => __async(this, null, function* () {
for (const { name, callback: callback2, note } of onEndCallbacks) {
try {
yield callback2(result);
} catch (e) {
result.errors.push(yield new Promise((resolve) => logPluginError(e, name, note && note(), resolve)));
}
}
}))().then(done);
};
}
let refCount = 0;
return {
ok: true,
requestPlugins,
runOnEndCallbacks,
pluginRefs: {
ref() {
if (++refCount === 1)
pluginCallbacks.set(buildKey, callback);
},
unref() {
if (--refCount === 0)
pluginCallbacks.delete(buildKey);
}
}
};
});
let buildServeData = (refs, options, request) => {
let keys = {};
let port = getFlag(options, keys, "port", mustBeInteger);
let host = getFlag(options, keys, "host", mustBeString);
let servedir = getFlag(options, keys, "servedir", mustBeString);
let onRequest = getFlag(options, keys, "onRequest", mustBeFunction);
let serveID = nextServeID++;
let onWait;
let wait = new Promise((resolve, reject) => {
onWait = (error) => {
serveCallbacks.delete(serveID);
if (error !== null)
reject(new Error(error));
else
resolve();
};
});
request.serve = { serveID };
checkForInvalidFlags(options, keys, `in serve() call`);
if (port !== void 0)
request.serve.port = port;
if (host !== void 0)
request.serve.host = host;
if (servedir !== void 0)
request.serve.servedir = servedir;
serveCallbacks.set(serveID, {
onRequest,
onWait
});
return {
wait,
stop() {
sendRequest(refs, { command: "serve-stop", serveID }, () => {
});
}
};
};
const buildLogLevelDefault = "warning";
const transformLogLevelDefault = "silent";
let buildOrServe = (args) => {
let key = nextBuildKey++;
const details = createObjectStash();
let plugins;
let { refs, options, isTTY: isTTY2, callback } = args;
if (typeof options === "object") {
let value = options.plugins;
if (value !== void 0) {
if (!Array.isArray(value))
throw new Error(`"plugins" must be an array`);
plugins = value;
}
}
let logPluginError = (e, pluginName, note, done) => {
let flags = [];
try {
pushLogFlags(flags, options, {}, isTTY2, buildLogLevelDefault);
} catch (e2) {
}
const message = extractErrorMessageV8(e, streamIn, details, note, pluginName);
sendRequest(refs, { command: "error", flags, error: message }, () => {
message.detail = details.load(message.detail);
done(message);
});
};
let handleError = (e, pluginName) => {
logPluginError(e, pluginName, void 0, (error) => {
callback(failureErrorWithLog("Build failed", [error], []), null);
});
};
if (plugins && plugins.length > 0) {
if (streamIn.isSync)
return handleError(new Error("Cannot use plugins in synchronous API calls"), "");
handlePlugins(options, plugins, key, details).then((result) => {
if (!result.ok) {
handleError(result.error, result.pluginName);
} else {
try {
buildOrServeContinue(__spreadProps(__spreadValues({}, args), {
key,
details,
logPluginError,
requestPlugins: result.requestPlugins,
runOnEndCallbacks: result.runOnEndCallbacks,
pluginRefs: result.pluginRefs
}));
} catch (e) {
handleError(e, "");
}
}
}, (e) => handleError(e, ""));
} else {
try {
buildOrServeContinue(__spreadProps(__spreadValues({}, args), {
key,
details,
logPluginError,
requestPlugins: null,
runOnEndCallbacks: (result, logPluginError2, done) => done(),
pluginRefs: null
}));
} catch (e) {
handleError(e, "");
}
}
};
let buildOrServeContinue = ({
callName,
refs: callerRefs,
serveOptions,
options,
isTTY: isTTY2,
defaultWD: defaultWD2,
callback,
key,
details,
logPluginError,
requestPlugins,
runOnEndCallbacks,
pluginRefs
}) => {
const refs = {
ref() {
if (pluginRefs)
pluginRefs.ref();
if (callerRefs)
callerRefs.ref();
},
unref() {
if (pluginRefs)
pluginRefs.unref();
if (callerRefs)
callerRefs.unref();
}
};
let writeDefault = !streamIn.isBrowser;
let {
entries,
flags,
write,
stdinContents,
stdinResolveDir,
absWorkingDir,
incremental,
nodePaths,
watch
} = flagsForBuildOptions(callName, options, isTTY2, buildLogLevelDefault, writeDefault);
let request = {
command: "build",
key,
entries,
flags,
write,
stdinContents,
stdinResolveDir,
absWorkingDir: absWorkingDir || defaultWD2,
incremental,
nodePaths
};
if (requestPlugins)
request.plugins = requestPlugins;
let serve2 = serveOptions && buildServeData(refs, serveOptions, request);
let rebuild;
let stop;
let copyResponseToResult = (response, result) => {
if (response.outputFiles)
result.outputFiles = response.outputFiles.map(convertOutputFiles);
if (response.metafile)
result.metafile = JSON.parse(response.metafile);
if (response.writeToStdout !== void 0)
console.log(decodeUTF8(response.writeToStdout).replace(/\n$/, ""));
};
let buildResponseToResult = (response, callback2) => {
let result = {
errors: replaceDetailsInMessages(response.errors, details),
warnings: replaceDetailsInMessages(response.warnings, details)
};
copyResponseToResult(response, result);
runOnEndCallbacks(result, logPluginError, () => {
if (result.errors.length > 0) {
return callback2(failureErrorWithLog("Build failed", result.errors, result.warnings), null);
}
if (response.rebuildID !== void 0) {
if (!rebuild) {
let isDisposed = false;
rebuild = () => new Promise((resolve, reject) => {
if (isDisposed || isClosed)
throw new Error("Cannot rebuild");
sendRequest(refs, { command: "rebuild", rebuildID: response.rebuildID }, (error2, response2) => {
if (error2) {
const message = { pluginName: "", text: error2, location: null, notes: [], detail: void 0 };
return callback2(failureErrorWithLog("Build failed", [message], []), null);
}
buildResponseToResult(response2, (error3, result3) => {
if (error3)
reject(error3);
else
resolve(result3);
});
});
});
refs.ref();
rebuild.dispose = () => {
if (isDisposed)
return;
isDisposed = true;
sendRequest(refs, { command: "rebuild-dispose", rebuildID: response.rebuildID }, () => {
});
refs.unref();
};
}
result.rebuild = rebuild;
}
if (response.watchID !== void 0) {
if (!stop) {
let isStopped = false;
refs.ref();
stop = () => {
if (isStopped)
return;
isStopped = true;
watchCallbacks.delete(response.watchID);
sendRequest(refs, { command: "watch-stop", watchID: response.watchID }, () => {
});
refs.unref();
};
if (watch) {
watchCallbacks.set(response.watchID, (serviceStopError, watchResponse) => {
if (serviceStopError) {
if (watch.onRebuild)
watch.onRebuild(serviceStopError, null);
return;
}
let result2 = {
errors: replaceDetailsInMessages(watchResponse.errors, details),
warnings: replaceDetailsInMessages(watchResponse.warnings, details)
};
copyResponseToResult(watchResponse, result2);
runOnEndCallbacks(result2, logPluginError, () => {
if (result2.errors.length > 0) {
if (watch.onRebuild)
watch.onRebuild(failureErrorWithLog("Build failed", result2.errors, result2.warnings), null);
return;
}
if (watchResponse.rebuildID !== void 0)
result2.rebuild = rebuild;
result2.stop = stop;
if (watch.onRebuild)
watch.onRebuild(null, result2);
});
});
}
}
result.stop = stop;
}
callback2(null, result);
});
};
if (write && streamIn.isBrowser)
throw new Error(`Cannot enable "write" in the browser`);
if (incremental && streamIn.isSync)
throw new Error(`Cannot use "incremental" with a synchronous build`);
sendRequest(refs, request, (error, response) => {
if (error)
return callback(new Error(error), null);
if (serve2) {
let serveResponse = response;
let isStopped = false;
refs.ref();
let result = {
port: serveResponse.port,
host: serveResponse.host,
wait: serve2.wait,
stop() {
if (isStopped)
return;
isStopped = true;
serve2.stop();
refs.unref();
}
};
refs.ref();
serve2.wait.then(refs.unref, refs.unref);
return callback(null, result);
}
return buildResponseToResult(response, callback);
});
};
let transform2 = ({ callName, refs, input, options, isTTY: isTTY2, fs: fs2, callback }) => {
const details = createObjectStash();
let start = (inputPath) => {
try {
if (typeof input !== "string")
throw new Error('The input to "transform" must be a string');
let flags = flagsForTransformOptions(callName, options, isTTY2, transformLogLevelDefault);
let request = {
command: "transform",
flags,
inputFS: inputPath !== null,
input: inputPath !== null ? inputPath : input
};
sendRequest(refs, request, (error, response) => {
if (error)
return callback(new Error(error), null);
let errors = replaceDetailsInMessages(response.errors, details);
let warnings = replaceDetailsInMessages(response.warnings, details);
let outstanding = 1;
let next = () => --outstanding === 0 && callback(null, { warnings, code: response.code, map: response.map });
if (errors.length > 0)
return callback(failureErrorWithLog("Transform failed", errors, warnings), null);
if (response.codeFS) {
outstanding++;
fs2.readFile(response.code, (err, contents) => {
if (err !== null) {
callback(err, null);
} else {
response.code = contents;
next();
}
});
}
if (response.mapFS) {
outstanding++;
fs2.readFile(response.map, (err, contents) => {
if (err !== null) {
callback(err, null);
} else {
response.map = contents;
next();
}
});
}
next();
});
} catch (e) {
let flags = [];
try {
pushLogFlags(flags, options, {}, isTTY2, transformLogLevelDefault);
} catch (e2) {
}
const error = extractErrorMessageV8(e, streamIn, details, void 0, "");
sendRequest(refs, { command: "error", flags, error }, () => {
error.detail = details.load(error.detail);
callback(failureErrorWithLog("Transform failed", [error], []), null);
});
}
};
if (typeof input === "string" && input.length > 1024 * 1024) {
let next = start;
start = () => fs2.writeFile(input, next);
}
start(null);
};
let formatMessages2 = ({ callName, refs, messages, options, callback }) => {
let result = sanitizeMessages(messages, "messages", null, "");
if (!options)
throw new Error(`Missing second argument in ${callName}() call`);
let keys = {};
let kind = getFlag(options, keys, "kind", mustBeString);
let color = getFlag(options, keys, "color", mustBeBoolean);
let terminalWidth = getFlag(options, keys, "terminalWidth", mustBeInteger);
checkForInvalidFlags(options, keys, `in ${callName}() call`);
if (kind === void 0)
throw new Error(`Missing "kind" in ${callName}() call`);
if (kind !== "error" && kind !== "warning")
throw new Error(`Expected "kind" to be "error" or "warning" in ${callName}() call`);
let request = {
command: "format-msgs",
messages: result,
isWarning: kind === "warning"
};
if (color !== void 0)
request.color = color;
if (terminalWidth !== void 0)
request.terminalWidth = terminalWidth;
sendRequest(refs, request, (error, response) => {
if (error)
return callback(new Error(error), null);
callback(null, response.messages);
});
};
return {
readFromStdout,
afterClose,
service: {
buildOrServe,
transform: transform2,
formatMessages: formatM