@jsenv/core 29.4.1 → 29.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -15,9 +15,11 @@ import { performance as performance$1 } from "node:perf_hooks";
15
15
  import { Readable, Stream, Writable } from "node:stream";
16
16
  import { Http2ServerResponse } from "node:http2";
17
17
  import { lookup } from "node:dns";
18
- import { SOURCEMAP, generateSourcemapFileUrl, composeTwoSourcemaps, generateSourcemapDataUrl, createMagicSource, sourcemapConverter, getOriginalPosition } from "@jsenv/sourcemap";
19
- import { parseHtmlString, stringifyHtmlAst, getHtmlNodeAttribute, visitHtmlNodes, analyzeScriptNode, setHtmlNodeAttributes, parseSrcSet, getHtmlNodePosition, getHtmlNodeAttributePosition, applyPostCss, postCssPluginUrlVisitor, parseJsUrls, getHtmlNodeText, setHtmlNodeText, applyBabelPlugins, injectScriptNodeAsEarlyAsPossible, createHtmlNode, findHtmlNode, removeHtmlNode, removeHtmlNodeText, transpileWithParcel, injectJsImport, minifyWithParcel, analyzeLinkNode, injectHtmlNode } from "@jsenv/ast";
18
+ import MagicString from "magic-string";
20
19
  import { createRequire } from "node:module";
20
+ import { parse, serialize, parseFragment } from "parse5";
21
+ import { ancestor } from "acorn-walk";
22
+ import { p as parseSrcSet } from "./js/html_src_set.js";
21
23
  import babelParser from "@babel/parser";
22
24
  import v8, { takeCoverage } from "node:v8";
23
25
  import wrapAnsi from "wrap-ansi";
@@ -6964,6 +6966,1962 @@ const createServerEventsDispatcher = () => {
6964
6966
  };
6965
6967
  };
6966
6968
 
6969
+ const createMagicSource = content => {
6970
+ if (content === undefined) {
6971
+ throw new Error("content missing");
6972
+ }
6973
+ const mutations = [];
6974
+ return {
6975
+ prepend: string => {
6976
+ mutations.push(magicString => {
6977
+ magicString.prepend(string);
6978
+ });
6979
+ },
6980
+ append: string => {
6981
+ mutations.push(magicString => {
6982
+ magicString.append(string);
6983
+ });
6984
+ },
6985
+ replace: ({
6986
+ start,
6987
+ end,
6988
+ replacement
6989
+ }) => {
6990
+ mutations.push(magicString => {
6991
+ magicString.overwrite(start, end, replacement);
6992
+ });
6993
+ },
6994
+ remove: ({
6995
+ start,
6996
+ end
6997
+ }) => {
6998
+ mutations.push(magicString => {
6999
+ magicString.remove(start, end);
7000
+ });
7001
+ },
7002
+ toContentAndSourcemap: ({
7003
+ source
7004
+ } = {}) => {
7005
+ if (mutations.length === 0) {
7006
+ return {
7007
+ content,
7008
+ sourcemap: null
7009
+ };
7010
+ }
7011
+ const magicString = new MagicString(content);
7012
+ mutations.forEach(mutation => {
7013
+ mutation(magicString);
7014
+ });
7015
+ const code = magicString.toString();
7016
+ const map = magicString.generateMap({
7017
+ hires: true,
7018
+ includeContent: true,
7019
+ source
7020
+ });
7021
+ return {
7022
+ content: code,
7023
+ sourcemap: map
7024
+ };
7025
+ }
7026
+ };
7027
+ };
7028
+
7029
+ const require$3 = createRequire(import.meta.url);
7030
+ // consider using https://github.com/7rulnik/source-map-js
7031
+
7032
+ const requireSourcemap = () => {
7033
+ const namespace = require$3("source-map-js");
7034
+ return namespace;
7035
+ };
7036
+
7037
+ /*
7038
+ * https://github.com/mozilla/source-map#sourcemapgenerator
7039
+ */
7040
+ const {
7041
+ SourceMapConsumer,
7042
+ SourceMapGenerator
7043
+ } = requireSourcemap();
7044
+ const composeTwoSourcemaps = (firstSourcemap, secondSourcemap) => {
7045
+ if (!firstSourcemap && !secondSourcemap) {
7046
+ return null;
7047
+ }
7048
+ if (!firstSourcemap) {
7049
+ return secondSourcemap;
7050
+ }
7051
+ if (!secondSourcemap) {
7052
+ return firstSourcemap;
7053
+ }
7054
+ const sourcemapGenerator = new SourceMapGenerator();
7055
+ const firstSourcemapConsumer = new SourceMapConsumer(firstSourcemap);
7056
+ const secondSourcemapConsumer = new SourceMapConsumer(secondSourcemap);
7057
+ const firstMappings = readMappings(firstSourcemapConsumer);
7058
+ firstMappings.forEach(mapping => {
7059
+ sourcemapGenerator.addMapping(mapping);
7060
+ });
7061
+ const secondMappings = readMappings(secondSourcemapConsumer);
7062
+ secondMappings.forEach(mapping => {
7063
+ sourcemapGenerator.addMapping(mapping);
7064
+ });
7065
+ const sourcemap = sourcemapGenerator.toJSON();
7066
+ const sources = [];
7067
+ const sourcesContent = [];
7068
+ const firstSourcesContent = firstSourcemap.sourcesContent;
7069
+ const secondSourcesContent = secondSourcemap.sourcesContent;
7070
+ sourcemap.sources.forEach(source => {
7071
+ sources.push(source);
7072
+ if (secondSourcesContent) {
7073
+ const secondSourceIndex = secondSourcemap.sources.indexOf(source);
7074
+ if (secondSourceIndex > -1) {
7075
+ sourcesContent.push(secondSourcesContent[secondSourceIndex]);
7076
+ return;
7077
+ }
7078
+ }
7079
+ if (firstSourcesContent) {
7080
+ const firstSourceIndex = firstSourcemap.sources.indexOf(source);
7081
+ if (firstSourceIndex > -1) {
7082
+ sourcesContent.push(firstSourcesContent[firstSourceIndex]);
7083
+ return;
7084
+ }
7085
+ }
7086
+ sourcesContent.push(null);
7087
+ });
7088
+ sourcemap.sources = sources;
7089
+ sourcemap.sourcesContent = sourcesContent;
7090
+ return sourcemap;
7091
+ };
7092
+ const readMappings = consumer => {
7093
+ const mappings = [];
7094
+ consumer.eachMapping(({
7095
+ originalColumn,
7096
+ originalLine,
7097
+ generatedColumn,
7098
+ generatedLine,
7099
+ source,
7100
+ name
7101
+ }) => {
7102
+ mappings.push({
7103
+ original: typeof originalColumn === "number" ? {
7104
+ column: originalColumn,
7105
+ line: originalLine
7106
+ } : undefined,
7107
+ generated: {
7108
+ column: generatedColumn,
7109
+ line: generatedLine
7110
+ },
7111
+ source: typeof originalColumn === "number" ? source : undefined,
7112
+ name
7113
+ });
7114
+ });
7115
+ return mappings;
7116
+ };
7117
+
7118
+ // https://github.com/mozilla/source-map#sourcemapconsumerprototypeoriginalpositionforgeneratedposition
7119
+ const getOriginalPosition = ({
7120
+ sourcemap,
7121
+ line,
7122
+ column,
7123
+ bias
7124
+ }) => {
7125
+ const {
7126
+ SourceMapConsumer
7127
+ } = requireSourcemap();
7128
+ const sourceMapConsumer = new SourceMapConsumer(sourcemap);
7129
+ const originalPosition = sourceMapConsumer.originalPositionFor({
7130
+ line,
7131
+ column,
7132
+ bias
7133
+ });
7134
+ return originalPosition;
7135
+ };
7136
+
7137
+ const sourcemapConverter = {
7138
+ toFileUrls: sourcemap => {
7139
+ return {
7140
+ ...sourcemap,
7141
+ sources: sourcemap.sources.map(source => {
7142
+ return isFileSystemPath$1(source) ? fileSystemPathToUrl$1(source) : source;
7143
+ })
7144
+ };
7145
+ },
7146
+ toFilePaths: sourcemap => {
7147
+ return {
7148
+ ...sourcemap,
7149
+ sources: sourcemap.sources.map(source => {
7150
+ return urlToFileSystemPath(source);
7151
+ })
7152
+ };
7153
+ }
7154
+ };
7155
+
7156
+ const generateSourcemapFileUrl = url => {
7157
+ const urlObject = new URL(url);
7158
+ let {
7159
+ origin,
7160
+ pathname,
7161
+ search,
7162
+ hash
7163
+ } = urlObject;
7164
+ // origin is "null" for "file://" urls with Node.js
7165
+ if (origin === "null" && urlObject.href.startsWith("file:")) {
7166
+ origin = "file://";
7167
+ }
7168
+ const sourcemapUrl = `${origin}${pathname}.map${search}${hash}`;
7169
+ return sourcemapUrl;
7170
+ };
7171
+ const generateSourcemapDataUrl = sourcemap => {
7172
+ const asBase64 = Buffer.from(JSON.stringify(sourcemap)).toString("base64");
7173
+ return `data:application/json;charset=utf-8;base64,${asBase64}`;
7174
+ };
7175
+
7176
+ const SOURCEMAP = {
7177
+ enabledOnContentType: contentType => {
7178
+ return ["text/javascript", "text/css"].includes(contentType);
7179
+ },
7180
+ readComment: ({
7181
+ contentType,
7182
+ content
7183
+ }) => {
7184
+ const read = {
7185
+ "text/javascript": parseJavaScriptSourcemapComment,
7186
+ "text/css": parseCssSourcemapComment
7187
+ }[contentType];
7188
+ return read ? read(content) : null;
7189
+ },
7190
+ writeComment: ({
7191
+ contentType,
7192
+ content,
7193
+ specifier
7194
+ }) => {
7195
+ const write = {
7196
+ "text/javascript": setJavaScriptSourceMappingUrl,
7197
+ "text/css": setCssSourceMappingUrl
7198
+ }[contentType];
7199
+ return write ? write(content, specifier) : content;
7200
+ }
7201
+ };
7202
+ const parseJavaScriptSourcemapComment = javaScriptSource => {
7203
+ let sourceMappingUrl;
7204
+ replaceSourceMappingUrl(javaScriptSource, javascriptSourceMappingUrlCommentRegexp, value => {
7205
+ sourceMappingUrl = value;
7206
+ });
7207
+ if (!sourceMappingUrl) {
7208
+ return null;
7209
+ }
7210
+ return {
7211
+ type: "sourcemap_comment",
7212
+ subtype: "js",
7213
+ // we assume it's on last line
7214
+ line: javaScriptSource.split(/\r?\n/).length,
7215
+ // ${"//#"} is to avoid static analysis to think there is a sourceMappingUrl for this file
7216
+ column: `${"//#"} sourceMappingURL=`.length + 1,
7217
+ specifier: sourceMappingUrl
7218
+ };
7219
+ };
7220
+ const setJavaScriptSourceMappingUrl = (javaScriptSource, sourceMappingFileUrl) => {
7221
+ let replaced;
7222
+ const sourceAfterReplace = replaceSourceMappingUrl(javaScriptSource, javascriptSourceMappingUrlCommentRegexp, () => {
7223
+ replaced = true;
7224
+ return sourceMappingFileUrl ? writeJavaScriptSourceMappingURL(sourceMappingFileUrl) : "";
7225
+ });
7226
+ if (replaced) {
7227
+ return sourceAfterReplace;
7228
+ }
7229
+ return sourceMappingFileUrl ? `${javaScriptSource}
7230
+ ${writeJavaScriptSourceMappingURL(sourceMappingFileUrl)}
7231
+ ` : javaScriptSource;
7232
+ };
7233
+ const parseCssSourcemapComment = cssSource => {
7234
+ let sourceMappingUrl;
7235
+ replaceSourceMappingUrl(cssSource, cssSourceMappingUrlCommentRegExp, value => {
7236
+ sourceMappingUrl = value;
7237
+ });
7238
+ if (!sourceMappingUrl) {
7239
+ return null;
7240
+ }
7241
+ return {
7242
+ type: "sourcemap_comment",
7243
+ subtype: "css",
7244
+ // we assume it's on last line
7245
+ line: cssSource.split(/\r?\n/).length - 1,
7246
+ // ${"//*#"} is to avoid static analysis to think there is a sourceMappingUrl for this file
7247
+ column: `${"//*#"} sourceMappingURL=`.length + 1,
7248
+ specifier: sourceMappingUrl
7249
+ };
7250
+ };
7251
+ const setCssSourceMappingUrl = (cssSource, sourceMappingFileUrl) => {
7252
+ let replaced;
7253
+ const sourceAfterReplace = replaceSourceMappingUrl(cssSource, cssSourceMappingUrlCommentRegExp, () => {
7254
+ replaced = true;
7255
+ return sourceMappingFileUrl ? writeCssSourceMappingUrl(sourceMappingFileUrl) : "";
7256
+ });
7257
+ if (replaced) {
7258
+ return sourceAfterReplace;
7259
+ }
7260
+ return sourceMappingFileUrl ? `${cssSource}
7261
+ ${writeCssSourceMappingUrl(sourceMappingFileUrl)}
7262
+ ` : cssSource;
7263
+ };
7264
+ const javascriptSourceMappingUrlCommentRegexp = /\/\/ ?# ?sourceMappingURL=([^\s'"]+)/g;
7265
+ const cssSourceMappingUrlCommentRegExp = /\/\*# ?sourceMappingURL=([^\s'"]+) \*\//g;
7266
+
7267
+ // ${"//#"} is to avoid a parser thinking there is a sourceMappingUrl for this file
7268
+ const writeJavaScriptSourceMappingURL = value => `${"//#"} sourceMappingURL=${value}`;
7269
+ const writeCssSourceMappingUrl = value => `/*# sourceMappingURL=${value} */`;
7270
+ const replaceSourceMappingUrl = (source, regexp, callback) => {
7271
+ let lastSourceMappingUrl;
7272
+ let matchSourceMappingUrl;
7273
+ while (matchSourceMappingUrl = regexp.exec(source)) {
7274
+ lastSourceMappingUrl = matchSourceMappingUrl;
7275
+ }
7276
+ if (lastSourceMappingUrl) {
7277
+ const index = lastSourceMappingUrl.index;
7278
+ const before = source.slice(0, index);
7279
+ const after = source.slice(index);
7280
+ const mappedAfter = after.replace(regexp, (match, firstGroup) => {
7281
+ return callback(firstGroup);
7282
+ });
7283
+ return `${before}${mappedAfter}`;
7284
+ }
7285
+ return source;
7286
+ };
7287
+
7288
+ const getHtmlNodeAttribute = (htmlNode, attributeName) => {
7289
+ const attribute = getHtmlAttributeByName(htmlNode, attributeName);
7290
+ return attribute ? attribute.value || "" : undefined;
7291
+ };
7292
+ const setHtmlNodeAttributes = (htmlNode, attributesToAssign) => {
7293
+ if (typeof attributesToAssign !== "object") {
7294
+ throw new TypeError(`attributesToAssign must be an object`);
7295
+ }
7296
+ const {
7297
+ attrs
7298
+ } = htmlNode;
7299
+ if (!attrs) return;
7300
+ Object.keys(attributesToAssign).forEach(key => {
7301
+ const existingAttributeIndex = attrs.findIndex(({
7302
+ name
7303
+ }) => name === key);
7304
+ const value = attributesToAssign[key];
7305
+ // remove no-op
7306
+ if (existingAttributeIndex === -1 && value === undefined) {
7307
+ return;
7308
+ }
7309
+ // add
7310
+ if (existingAttributeIndex === -1 && value !== undefined) {
7311
+ attrs.push({
7312
+ name: key,
7313
+ value
7314
+ });
7315
+ return;
7316
+ }
7317
+ // remove
7318
+ if (value === undefined) {
7319
+ attrs.splice(existingAttributeIndex, 1);
7320
+ return;
7321
+ }
7322
+ // update
7323
+ attrs[existingAttributeIndex].value = value;
7324
+ });
7325
+ };
7326
+ const getHtmlAttributeByName = (htmlNode, attributeName) => {
7327
+ const attrs = htmlNode.attrs;
7328
+ const attribute = attrs ? attrs.find(attr => attr.name === attributeName) : null;
7329
+ return attribute;
7330
+ };
7331
+
7332
+ const storeHtmlNodePosition = node => {
7333
+ const originalPositionAttributeName = `original-position`;
7334
+ const originalPosition = getHtmlNodeAttribute(node, originalPositionAttributeName);
7335
+ if (originalPosition !== undefined) {
7336
+ return true;
7337
+ }
7338
+ const {
7339
+ sourceCodeLocation
7340
+ } = node;
7341
+ if (!sourceCodeLocation) {
7342
+ return false;
7343
+ }
7344
+ const {
7345
+ startLine,
7346
+ startCol,
7347
+ endLine,
7348
+ endCol
7349
+ } = sourceCodeLocation;
7350
+ setHtmlNodeAttributes(node, {
7351
+ [originalPositionAttributeName]: `${startLine}:${startCol};${endLine}:${endCol}`
7352
+ });
7353
+ return true;
7354
+ };
7355
+ const storeHtmlNodeAttributePosition = (node, attributeName) => {
7356
+ const {
7357
+ sourceCodeLocation
7358
+ } = node;
7359
+ if (!sourceCodeLocation) {
7360
+ return false;
7361
+ }
7362
+ const attributeValue = getHtmlNodeAttribute(node, attributeName);
7363
+ if (attributeValue === undefined) {
7364
+ return false;
7365
+ }
7366
+ const attributeLocation = sourceCodeLocation.attrs[attributeName];
7367
+ if (!attributeLocation) {
7368
+ return false;
7369
+ }
7370
+ const originalPositionAttributeName = `original-${attributeName}-position`;
7371
+ const originalPosition = getHtmlNodeAttribute(node, originalPositionAttributeName);
7372
+ if (originalPosition !== undefined) {
7373
+ return true;
7374
+ }
7375
+ const {
7376
+ startLine,
7377
+ startCol,
7378
+ endLine,
7379
+ endCol
7380
+ } = attributeLocation;
7381
+ setHtmlNodeAttributes(node, {
7382
+ [originalPositionAttributeName]: `${startLine}:${startCol};${endLine}:${endCol}`
7383
+ });
7384
+ return true;
7385
+ };
7386
+ const getHtmlNodePosition = (node, {
7387
+ preferOriginal = false
7388
+ } = {}) => {
7389
+ const position = {};
7390
+ const {
7391
+ sourceCodeLocation
7392
+ } = node;
7393
+ if (sourceCodeLocation) {
7394
+ const {
7395
+ startLine,
7396
+ startCol,
7397
+ endLine,
7398
+ endCol
7399
+ } = sourceCodeLocation;
7400
+ Object.assign(position, {
7401
+ line: startLine,
7402
+ lineEnd: endLine,
7403
+ column: startCol,
7404
+ columnEnd: endCol
7405
+ });
7406
+ }
7407
+ const originalPosition = getHtmlNodeAttribute(node, "original-position");
7408
+ if (originalPosition === undefined) {
7409
+ return position;
7410
+ }
7411
+ const [start, end] = originalPosition.split(";");
7412
+ const [originalLine, originalColumn] = start.split(":");
7413
+ const [originalLineEnd, originalColumnEnd] = end.split(":");
7414
+ Object.assign(position, {
7415
+ originalLine: parseInt(originalLine),
7416
+ originalColumn: parseInt(originalColumn),
7417
+ originalLineEnd: parseInt(originalLineEnd),
7418
+ originalColumnEnd: parseInt(originalColumnEnd)
7419
+ });
7420
+ if (preferOriginal) {
7421
+ position.line = position.originalLine;
7422
+ position.column = position.originalColumn;
7423
+ position.lineEnd = position.originalLineEnd;
7424
+ position.columnEnd = position.originalColumnEnd;
7425
+ position.isOriginal = true;
7426
+ }
7427
+ return position;
7428
+ };
7429
+ const getHtmlNodeAttributePosition = (node, attributeName) => {
7430
+ const position = {};
7431
+ const {
7432
+ sourceCodeLocation
7433
+ } = node;
7434
+ if (sourceCodeLocation) {
7435
+ const attributeLocation = sourceCodeLocation.attrs[attributeName];
7436
+ if (attributeLocation) {
7437
+ Object.assign(position, {
7438
+ line: attributeLocation.startLine,
7439
+ column: attributeLocation.startCol
7440
+ });
7441
+ }
7442
+ }
7443
+ const originalPositionAttributeName = attributeName === "inlined-from-src" ? "original-src-position" : attributeName === "inlined-from-href" ? "original-href-position" : `original-${attributeName}-position`;
7444
+ const originalPosition = getHtmlNodeAttribute(node, originalPositionAttributeName);
7445
+ if (originalPosition === undefined) {
7446
+ return position;
7447
+ }
7448
+ const [start, end] = originalPosition.split(";");
7449
+ const [originalLine, originalColumn] = start.split(":");
7450
+ const [originalLineEnd, originalColumnEnd] = end.split(":");
7451
+ Object.assign(position, {
7452
+ originalLine: parseInt(originalLine),
7453
+ originalColumn: parseInt(originalColumn),
7454
+ originalLineEnd: parseInt(originalLineEnd),
7455
+ originalColumnEnd: parseInt(originalColumnEnd)
7456
+ });
7457
+ return position;
7458
+ };
7459
+
7460
+ const visitHtmlNodes = (htmlAst, visitors) => {
7461
+ const visitNode = node => {
7462
+ const visitor = visitors[node.nodeName] || visitors["*"];
7463
+ if (visitor) {
7464
+ const callbackReturnValue = visitor(node);
7465
+ if (callbackReturnValue === "stop") {
7466
+ return;
7467
+ }
7468
+ }
7469
+ const {
7470
+ childNodes
7471
+ } = node;
7472
+ if (childNodes) {
7473
+ let i = 0;
7474
+ while (i < childNodes.length) {
7475
+ visitNode(childNodes[i++]);
7476
+ }
7477
+ }
7478
+ };
7479
+ visitNode(htmlAst);
7480
+ };
7481
+ const findHtmlNode = (htmlAst, predicate) => {
7482
+ let nodeMatching = null;
7483
+ visitHtmlNodes(htmlAst, {
7484
+ "*": node => {
7485
+ if (predicate(node)) {
7486
+ nodeMatching = node;
7487
+ return "stop";
7488
+ }
7489
+ return null;
7490
+ }
7491
+ });
7492
+ return nodeMatching;
7493
+ };
7494
+ const findHtmlChildNode = (htmlNode, predicate) => {
7495
+ const {
7496
+ childNodes = []
7497
+ } = htmlNode;
7498
+ return childNodes.find(predicate);
7499
+ };
7500
+
7501
+ const getHtmlNodeText = htmlNode => {
7502
+ const textNode = getTextNode(htmlNode);
7503
+ return textNode ? textNode.value : undefined;
7504
+ };
7505
+ const getTextNode = htmlNode => {
7506
+ const firstChild = htmlNode.childNodes[0];
7507
+ const textNode = firstChild && firstChild.nodeName === "#text" ? firstChild : null;
7508
+ return textNode;
7509
+ };
7510
+ const removeHtmlNodeText = htmlNode => {
7511
+ const textNode = getTextNode(htmlNode);
7512
+ if (textNode) {
7513
+ htmlNode.childNodes = [];
7514
+ }
7515
+ };
7516
+ const setHtmlNodeText = (htmlNode, textContent) => {
7517
+ const textNode = getTextNode(htmlNode);
7518
+ if (textNode) {
7519
+ textNode.value = textContent;
7520
+ } else {
7521
+ const newTextNode = {
7522
+ nodeName: "#text",
7523
+ value: textContent,
7524
+ parentNode: htmlNode
7525
+ };
7526
+ htmlNode.childNodes.splice(0, 0, newTextNode);
7527
+ }
7528
+ };
7529
+
7530
+ const parseHtmlString = (htmlString, {
7531
+ storeOriginalPositions = true
7532
+ } = {}) => {
7533
+ const htmlAst = parse(htmlString, {
7534
+ sourceCodeLocationInfo: true
7535
+ });
7536
+ if (storeOriginalPositions) {
7537
+ const htmlNode = findHtmlChildNode(htmlAst, node => node.nodeName === "html");
7538
+ const stored = getHtmlNodeAttribute(htmlNode, "original-position-stored");
7539
+ if (stored === undefined) {
7540
+ visitHtmlNodes(htmlAst, {
7541
+ "*": node => {
7542
+ if (node.nodeName === "script" || node.nodeName === "style") {
7543
+ const htmlNodeText = getHtmlNodeText(node);
7544
+ if (htmlNodeText !== undefined) {
7545
+ storeHtmlNodePosition(node);
7546
+ }
7547
+ }
7548
+ storeHtmlNodeAttributePosition(node, "src");
7549
+ storeHtmlNodeAttributePosition(node, "href");
7550
+ }
7551
+ });
7552
+ setHtmlNodeAttributes(htmlNode, {
7553
+ "original-position-stored": ""
7554
+ });
7555
+ }
7556
+ }
7557
+ return htmlAst;
7558
+ };
7559
+ const stringifyHtmlAst = (htmlAst, {
7560
+ cleanupJsenvAttributes = false
7561
+ } = {}) => {
7562
+ if (cleanupJsenvAttributes) {
7563
+ const htmlNode = findHtmlChildNode(htmlAst, node => node.nodeName === "html");
7564
+ const storedAttribute = getHtmlNodeAttribute(htmlNode, "original-position-stored");
7565
+ if (storedAttribute !== undefined) {
7566
+ setHtmlNodeAttributes(htmlNode, {
7567
+ "original-position-stored": undefined
7568
+ });
7569
+ visitHtmlNodes(htmlAst, {
7570
+ "*": node => {
7571
+ setHtmlNodeAttributes(node, {
7572
+ "original-position": undefined,
7573
+ "original-src-position": undefined,
7574
+ "original-href-position": undefined,
7575
+ "inlined-from-src": undefined,
7576
+ "inlined-from-href": undefined,
7577
+ "jsenv-plugin-owner": undefined,
7578
+ "jsenv-plugin-action": undefined,
7579
+ "jsenv-debug": undefined
7580
+ });
7581
+ }
7582
+ });
7583
+ }
7584
+ }
7585
+ const htmlString = serialize(htmlAst);
7586
+ return htmlString;
7587
+ };
7588
+
7589
+ const analyzeScriptNode = scriptNode => {
7590
+ const typeAttribute = getHtmlNodeAttribute(scriptNode, "type");
7591
+ if (typeAttribute === undefined || typeAttribute === "text/javascript") {
7592
+ return {
7593
+ type: "js_classic",
7594
+ contentType: "text/javascript"
7595
+ };
7596
+ }
7597
+ if (typeAttribute === "module") {
7598
+ return {
7599
+ type: "js_module",
7600
+ contentType: "text/javascript"
7601
+ };
7602
+ }
7603
+ if (typeAttribute === "importmap") {
7604
+ return {
7605
+ type: "importmap",
7606
+ contentType: "application/importmap+json"
7607
+ };
7608
+ }
7609
+ // jsx
7610
+ if (typeAttribute === "text/jsx") {
7611
+ return {
7612
+ type: "js_classic",
7613
+ contentType: "text/javascript",
7614
+ extension: ".jsx"
7615
+ };
7616
+ }
7617
+ if (typeAttribute === "module/jsx") {
7618
+ return {
7619
+ type: "js_module",
7620
+ contentType: "text/javascript",
7621
+ extension: ".jsx"
7622
+ };
7623
+ }
7624
+ // typescript
7625
+ if (typeAttribute === "text/ts") {
7626
+ return {
7627
+ type: "js_classic",
7628
+ contentType: "text/javascript",
7629
+ extension: ".ts"
7630
+ };
7631
+ }
7632
+ if (typeAttribute === "module/ts") {
7633
+ return {
7634
+ type: "js_module",
7635
+ contentType: "text/javascript",
7636
+ extension: ".ts"
7637
+ };
7638
+ }
7639
+ // typescript and jsx
7640
+ if (typeAttribute === "text/tsx") {
7641
+ return {
7642
+ type: "js_classic",
7643
+ contentType: "text/javascript",
7644
+ extension: ".tsx"
7645
+ };
7646
+ }
7647
+ if (typeAttribute === "module/tsx") {
7648
+ return {
7649
+ type: "js_module",
7650
+ contentType: "text/javascript",
7651
+ extension: ".tsx"
7652
+ };
7653
+ }
7654
+ // from MDN about [type] attribute:
7655
+ // "Any other value: The embedded content is treated as a data block
7656
+ // which won't be processed by the browser. Developers must use a valid MIME type
7657
+ // that is not a JavaScript MIME type to denote data blocks.
7658
+ // The src attribute will be ignored."
7659
+ // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-type
7660
+ return {
7661
+ type: "text",
7662
+ contentType: "text/plain"
7663
+ };
7664
+ };
7665
+ const analyzeLinkNode = linkNode => {
7666
+ const rel = getHtmlNodeAttribute(linkNode, "rel");
7667
+ if (rel === "stylesheet") {
7668
+ return {
7669
+ isStylesheet: true
7670
+ };
7671
+ }
7672
+ const isResourceHint = ["preconnect", "dns-prefetch", "prefetch", "preload", "modulepreload"].includes(rel);
7673
+ return {
7674
+ isResourceHint,
7675
+ rel
7676
+ };
7677
+ };
7678
+
7679
+ const removeHtmlNode = htmlNode => {
7680
+ const {
7681
+ childNodes
7682
+ } = htmlNode.parentNode;
7683
+ childNodes.splice(childNodes.indexOf(htmlNode), 1);
7684
+ };
7685
+ const createHtmlNode = ({
7686
+ tagName,
7687
+ textContent = "",
7688
+ ...rest
7689
+ }) => {
7690
+ const html = `<${tagName} ${stringifyAttributes(rest)}>${textContent}</${tagName}>`;
7691
+ const fragment = parseFragment(html);
7692
+ return fragment.childNodes[0];
7693
+ };
7694
+ const injectHtmlNode = (htmlAst, node, jsenvPluginName = "jsenv") => {
7695
+ setHtmlNodeAttributes(node, {
7696
+ "jsenv-plugin-owner": jsenvPluginName,
7697
+ "jsenv-plugin-action": "injected"
7698
+ });
7699
+ const htmlHtmlNode = findChild(htmlAst, node => node.nodeName === "html");
7700
+ const bodyNode = findChild(htmlHtmlNode, node => node.nodeName === "body");
7701
+ return insertAfter(node, bodyNode);
7702
+ };
7703
+ const injectScriptNodeAsEarlyAsPossible = (htmlAst, scriptNode, jsenvPluginName = "jsenv") => {
7704
+ setHtmlNodeAttributes(scriptNode, {
7705
+ "jsenv-plugin-owner": jsenvPluginName,
7706
+ "jsenv-plugin-action": "injected"
7707
+ });
7708
+ const isJsModule = analyzeScriptNode(scriptNode).type === "js_module";
7709
+ if (isJsModule) {
7710
+ const firstImportmapScript = findHtmlNode(htmlAst, node => {
7711
+ return node.nodeName === "script" && analyzeScriptNode(node).type === "importmap";
7712
+ });
7713
+ if (firstImportmapScript) {
7714
+ const importmapParent = firstImportmapScript.parentNode;
7715
+ const importmapSiblings = importmapParent.childNodes;
7716
+ const nextSiblings = importmapSiblings.slice(importmapSiblings.indexOf(firstImportmapScript) + 1);
7717
+ let after = firstImportmapScript;
7718
+ for (const nextSibling of nextSiblings) {
7719
+ if (nextSibling.nodeName === "script") {
7720
+ return insertBefore(scriptNode, importmapParent, nextSibling);
7721
+ }
7722
+ if (nextSibling.nodeName === "link") {
7723
+ after = nextSibling;
7724
+ }
7725
+ }
7726
+ return insertAfter(scriptNode, importmapParent, after);
7727
+ }
7728
+ }
7729
+ const headNode = findChild(htmlAst, node => node.nodeName === "html").childNodes[0];
7730
+ let after = headNode.childNodes[0];
7731
+ for (const child of headNode.childNodes) {
7732
+ if (child.nodeName === "script") {
7733
+ return insertBefore(scriptNode, headNode, child);
7734
+ }
7735
+ if (child.nodeName === "link") {
7736
+ after = child;
7737
+ }
7738
+ }
7739
+ return insertAfter(scriptNode, headNode, after);
7740
+ };
7741
+ const insertBefore = (nodeToInsert, futureParentNode, futureNextSibling) => {
7742
+ const {
7743
+ childNodes = []
7744
+ } = futureParentNode;
7745
+ const futureIndex = futureNextSibling ? childNodes.indexOf(futureNextSibling) : 0;
7746
+ injectWithWhitespaces(nodeToInsert, futureParentNode, futureIndex);
7747
+ };
7748
+ const insertAfter = (nodeToInsert, futureParentNode, futurePrevSibling) => {
7749
+ const {
7750
+ childNodes = []
7751
+ } = futureParentNode;
7752
+ const futureIndex = futurePrevSibling ? childNodes.indexOf(futurePrevSibling) + 1 : childNodes.length;
7753
+ injectWithWhitespaces(nodeToInsert, futureParentNode, futureIndex);
7754
+ };
7755
+ const injectWithWhitespaces = (nodeToInsert, futureParentNode, futureIndex) => {
7756
+ const {
7757
+ childNodes = []
7758
+ } = futureParentNode;
7759
+ const previousSiblings = childNodes.slice(0, futureIndex);
7760
+ const nextSiblings = childNodes.slice(futureIndex);
7761
+ const futureChildNodes = [];
7762
+ const previousSibling = previousSiblings[0];
7763
+ if (previousSibling) {
7764
+ futureChildNodes.push(...previousSiblings);
7765
+ }
7766
+ if (!previousSibling || previousSibling.nodeName !== "#text") {
7767
+ futureChildNodes.push({
7768
+ nodeName: "#text",
7769
+ value: "\n ",
7770
+ parentNode: futureParentNode
7771
+ });
7772
+ }
7773
+ futureChildNodes.push(nodeToInsert);
7774
+ const nextSibling = nextSiblings[0];
7775
+ if (!nextSibling || nextSibling.nodeName !== "#text") {
7776
+ futureChildNodes.push({
7777
+ nodeName: "#text",
7778
+ value: "\n ",
7779
+ parentNode: futureParentNode
7780
+ });
7781
+ }
7782
+ if (nextSibling) {
7783
+ futureChildNodes.push(...nextSiblings);
7784
+ }
7785
+ futureParentNode.childNodes = futureChildNodes;
7786
+ };
7787
+ const findChild = ({
7788
+ childNodes = []
7789
+ }, predicate) => childNodes.find(predicate);
7790
+ const stringifyAttributes = object => {
7791
+ return Object.keys(object).map(key => `${key}=${valueToHtmlAttributeValue(object[key])}`).join(" ");
7792
+ };
7793
+ const valueToHtmlAttributeValue = value => {
7794
+ if (typeof value === "string") {
7795
+ return JSON.stringify(value);
7796
+ }
7797
+ return `"${JSON.stringify(value)}"`;
7798
+ };
7799
+
7800
+ const applyPostCss = async ({
7801
+ sourcemaps = "comment",
7802
+ plugins,
7803
+ // https://github.com/postcss/postcss#options
7804
+ options = {},
7805
+ url,
7806
+ map,
7807
+ content
7808
+ }) => {
7809
+ const {
7810
+ default: postcss
7811
+ } = await import("postcss");
7812
+ try {
7813
+ const cssFileUrl = urlToFileUrl(url);
7814
+ const result = await postcss(plugins).process(content, {
7815
+ collectUrls: true,
7816
+ from: fileURLToPath(cssFileUrl),
7817
+ to: fileURLToPath(cssFileUrl),
7818
+ map: {
7819
+ annotation: sourcemaps === "file",
7820
+ inline: sourcemaps === "inline",
7821
+ // https://postcss.org/api/#sourcemapoptions
7822
+ ...(map ? {
7823
+ prev: JSON.stringify(map)
7824
+ } : {})
7825
+ },
7826
+ ...options
7827
+ });
7828
+ return {
7829
+ postCssMessages: result.messages,
7830
+ map: result.map.toJSON(),
7831
+ content: result.css
7832
+ };
7833
+ } catch (error) {
7834
+ if (error.name === "CssSyntaxError") {
7835
+ console.error(String(error));
7836
+ throw error;
7837
+ }
7838
+ throw error;
7839
+ }
7840
+ };
7841
+
7842
+ // the goal of this function is to take an url that is likely an http url
7843
+ // info a file:// url
7844
+ // for instance http://example.com/dir/file.js
7845
+ // must becomes file:///dir/file.js
7846
+ // but in windows it must be file://C:/dir/file.js
7847
+ const filesystemRootUrl = process.platform === "win32" ? `file:///${process.cwd()[0]}:/` : "file:///";
7848
+ const urlToFileUrl = url => {
7849
+ const urlString = String(url);
7850
+ if (urlString.startsWith("file:")) {
7851
+ return urlString;
7852
+ }
7853
+ const origin = new URL(url).origin;
7854
+ const afterOrigin = urlString.slice(origin.length);
7855
+ return new URL(afterOrigin, filesystemRootUrl).href;
7856
+ };
7857
+
7858
+ const require$2 = createRequire(import.meta.url);
7859
+ const transpileWithParcel = (urlInfo, context) => {
7860
+ const css = require$2("@parcel/css");
7861
+ const targets = runtimeCompatToTargets(context.runtimeCompat);
7862
+ const {
7863
+ code,
7864
+ map
7865
+ } = css.transform({
7866
+ filename: fileURLToPath(urlInfo.originalUrl),
7867
+ code: Buffer.from(urlInfo.content),
7868
+ targets,
7869
+ minify: false
7870
+ });
7871
+ return {
7872
+ code,
7873
+ map
7874
+ };
7875
+ };
7876
+ const minifyWithParcel = (urlInfo, context) => {
7877
+ const css = require$2("@parcel/css");
7878
+ const targets = runtimeCompatToTargets(context.runtimeCompat);
7879
+ const {
7880
+ code,
7881
+ map
7882
+ } = css.transform({
7883
+ filename: fileURLToPath(urlInfo.originalUrl),
7884
+ code: Buffer.from(urlInfo.content),
7885
+ targets,
7886
+ minify: true
7887
+ });
7888
+ return {
7889
+ code,
7890
+ map
7891
+ };
7892
+ };
7893
+ const runtimeCompatToTargets = runtimeCompat => {
7894
+ const targets = {};
7895
+ ["chrome", "firefox", "ie", "opera", "safari"].forEach(runtimeName => {
7896
+ const version = runtimeCompat[runtimeName];
7897
+ if (version) {
7898
+ targets[runtimeName] = versionToBits(version);
7899
+ }
7900
+ });
7901
+ return targets;
7902
+ };
7903
+ const versionToBits = version => {
7904
+ const [major, minor = 0, patch = 0] = version.split("-")[0].split(".").map(v => parseInt(v, 10));
7905
+ return major << 16 | minor << 8 | patch;
7906
+ };
7907
+
7908
+ const require$1 = createRequire(import.meta.url);
7909
+
7910
+ /**
7911
+
7912
+ https://github.com/postcss/postcss/blob/master/docs/writing-a-plugin.md
7913
+ https://github.com/postcss/postcss/blob/master/docs/guidelines/plugin.md
7914
+ https://github.com/postcss/postcss/blob/master/docs/guidelines/runner.md#31-dont-show-js-stack-for-csssyntaxerror
7915
+
7916
+ In case css sourcemap contains no%20source
7917
+ This is because of https://github.com/postcss/postcss/blob/fd30d3df5abc0954a0ec642a3cdc644ab2aacf9c/lib/map-generator.js#L231
7918
+ and it indicates a node has been replaced without passing source
7919
+ hence sourcemap cannot point the original source location
7920
+
7921
+ */
7922
+ const postCssPluginUrlVisitor = ({
7923
+ urlVisitor = () => null
7924
+ }) => {
7925
+ const parseCssValue = require$1("postcss-value-parser");
7926
+ const stringifyCssNodes = parseCssValue.stringify;
7927
+ return {
7928
+ postcssPlugin: "url_visitor",
7929
+ prepare: result => {
7930
+ const {
7931
+ from
7932
+ } = result.opts;
7933
+ const fromUrl = String(pathToFileURL(from));
7934
+ const mutations = [];
7935
+ return {
7936
+ AtRule: {
7937
+ import: (atImportNode, {
7938
+ AtRule
7939
+ }) => {
7940
+ if (atImportNode.parent.type !== "root") {
7941
+ atImportNode.warn(result, "`@import` should be top level");
7942
+ return;
7943
+ }
7944
+ if (atImportNode.nodes) {
7945
+ atImportNode.warn(result, "`@import` was not terminated correctly");
7946
+ return;
7947
+ }
7948
+ const parsed = parseCssValue(atImportNode.params);
7949
+ let [urlNode] = parsed.nodes;
7950
+ if (!urlNode || urlNode.type !== "string" && urlNode.type !== "function") {
7951
+ atImportNode.warn(result, `No URL in \`${atImportNode.toString()}\``);
7952
+ return;
7953
+ }
7954
+ let url = "";
7955
+ if (urlNode.type === "string") {
7956
+ url = urlNode.value;
7957
+ } else if (urlNode.type === "function") {
7958
+ // Invalid function
7959
+ if (!/^url$/i.test(urlNode.value)) {
7960
+ atImportNode.warn(result, `Invalid \`url\` function in \`${atImportNode.toString()}\``);
7961
+ return;
7962
+ }
7963
+ const firstNode = urlNode.nodes[0];
7964
+ if (firstNode && firstNode.type === "string") {
7965
+ urlNode = firstNode;
7966
+ url = urlNode.value;
7967
+ } else {
7968
+ urlNode = urlNode.nodes;
7969
+ url = stringifyCssNodes(urlNode.nodes);
7970
+ }
7971
+ }
7972
+ url = url.trim();
7973
+ if (url.length === 0) {
7974
+ atImportNode.warn(result, `Empty URL in \`${atImportNode.toString()}\``);
7975
+ return;
7976
+ }
7977
+ const specifier = url;
7978
+ url = new URL(specifier, fromUrl).href;
7979
+ if (url === fromUrl) {
7980
+ atImportNode.warn(result, `\`@import\` loop in \`${atImportNode.toString()}\``);
7981
+ return;
7982
+ }
7983
+ const atRuleStart = atImportNode.source.start.offset;
7984
+ const atRuleEnd = atImportNode.source.end.offset + 1; // for the ";"
7985
+ const atRuleRaw = atImportNode.source.input.css.slice(atRuleStart, atRuleEnd);
7986
+ const specifierIndex = atRuleRaw.indexOf(atImportNode.params);
7987
+ const specifierStart = atRuleStart + specifierIndex;
7988
+ const specifierEnd = specifierStart + atImportNode.params.length;
7989
+ const specifierLine = atImportNode.source.start.line;
7990
+ const specifierColumn = atImportNode.source.start.column + specifierIndex;
7991
+ urlVisitor({
7992
+ declarationNode: atImportNode,
7993
+ type: "@import",
7994
+ atRuleStart,
7995
+ atRuleEnd,
7996
+ specifier,
7997
+ specifierLine,
7998
+ specifierColumn,
7999
+ specifierStart,
8000
+ specifierEnd,
8001
+ replace: newUrlSpecifier => {
8002
+ if (newUrlSpecifier === urlNode.value) {
8003
+ return;
8004
+ }
8005
+ urlNode.value = newUrlSpecifier;
8006
+ const newParams = parsed.toString();
8007
+ const newAtImportRule = new AtRule({
8008
+ name: "import",
8009
+ params: newParams,
8010
+ source: atImportNode.source
8011
+ });
8012
+ atImportNode.replaceWith(newAtImportRule);
8013
+ }
8014
+ });
8015
+ }
8016
+ },
8017
+ Declaration: declarationNode => {
8018
+ const parsed = parseCssValue(declarationNode.value);
8019
+ const urlMutations = [];
8020
+ walkUrls(parsed, {
8021
+ stringifyCssNodes,
8022
+ visitor: ({
8023
+ url,
8024
+ urlNode
8025
+ }) => {
8026
+ // Empty URL
8027
+ if (!urlNode || url.length === 0) {
8028
+ declarationNode.warn(result, `Empty URL in \`${declarationNode.toString()}\``);
8029
+ return;
8030
+ }
8031
+ // Skip Data URI
8032
+ if (isDataUrl(url)) {
8033
+ return;
8034
+ }
8035
+ const specifier = url;
8036
+ url = new URL(specifier, pathToFileURL(from));
8037
+ const declarationNodeStart = declarationNode.source.start.offset;
8038
+ const afterDeclarationNode = declarationNode.source.input.css.slice(declarationNodeStart);
8039
+ const valueIndex = afterDeclarationNode.indexOf(declarationNode.value);
8040
+ const valueStart = declarationNodeStart + valueIndex;
8041
+ const specifierStart = valueStart + urlNode.sourceIndex;
8042
+ const specifierEnd = specifierStart + (urlNode.type === "word" ? urlNode.value.length : urlNode.value.length + 2); // the quotes
8043
+ // value raw
8044
+ // declarationNode.source.input.css.slice(valueStart)
8045
+ // specifier raw
8046
+ // declarationNode.source.input.css.slice(specifierStart, specifierEnd)
8047
+ const specifierLine = declarationNode.source.start.line;
8048
+ const specifierColumn = declarationNode.source.start.column + (specifierStart - declarationNodeStart);
8049
+ urlVisitor({
8050
+ declarationNode,
8051
+ type: "url",
8052
+ specifier,
8053
+ specifierLine,
8054
+ specifierColumn,
8055
+ specifierStart,
8056
+ specifierEnd,
8057
+ replace: newUrlSpecifier => {
8058
+ urlMutations.push(() => {
8059
+ // the specifier desires to be inside double quotes
8060
+ if (newUrlSpecifier[0] === `"`) {
8061
+ urlNode.type = "word";
8062
+ urlNode.value = newUrlSpecifier;
8063
+ return;
8064
+ }
8065
+ // the specifier desires to be inside simple quotes
8066
+ if (newUrlSpecifier[0] === `'`) {
8067
+ urlNode.type = "word";
8068
+ urlNode.value = newUrlSpecifier;
8069
+ return;
8070
+ }
8071
+ // the specifier desired to be just a word
8072
+ // for the "word" type so that newUrlSpecifier can opt-out of being between quotes
8073
+ // useful to inject __v__ calls for css inside js
8074
+ urlNode.type = "word";
8075
+ urlNode.value = newUrlSpecifier;
8076
+ });
8077
+ }
8078
+ });
8079
+ }
8080
+ });
8081
+ if (urlMutations.length) {
8082
+ mutations.push(() => {
8083
+ urlMutations.forEach(urlMutation => {
8084
+ urlMutation();
8085
+ });
8086
+ declarationNode.value = parsed.toString();
8087
+ });
8088
+ }
8089
+ },
8090
+ OnceExit: () => {
8091
+ mutations.forEach(mutation => {
8092
+ mutation();
8093
+ });
8094
+ }
8095
+ };
8096
+ }
8097
+ };
8098
+ };
8099
+ postCssPluginUrlVisitor.postcss = true;
8100
+ const walkUrls = (parsed, {
8101
+ stringifyCssNodes,
8102
+ visitor
8103
+ }) => {
8104
+ parsed.walk(node => {
8105
+ // https://github.com/andyjansson/postcss-functions
8106
+ if (isUrlFunctionNode(node)) {
8107
+ const {
8108
+ nodes
8109
+ } = node;
8110
+ const [urlNode] = nodes;
8111
+ const url = urlNode && urlNode.type === "string" ? urlNode.value : stringifyCssNodes(nodes);
8112
+ visitor({
8113
+ url: url.trim(),
8114
+ urlNode
8115
+ });
8116
+ return;
8117
+ }
8118
+ if (isImageSetFunctionNode(node)) {
8119
+ Array.from(node.nodes).forEach(childNode => {
8120
+ if (childNode.type === "string") {
8121
+ visitor({
8122
+ url: childNode.value.trim(),
8123
+ urlNode: childNode
8124
+ });
8125
+ return;
8126
+ }
8127
+ if (isUrlFunctionNode(node)) {
8128
+ const {
8129
+ nodes
8130
+ } = childNode;
8131
+ const [urlNode] = nodes;
8132
+ const url = urlNode && urlNode.type === "string" ? urlNode.value : stringifyCssNodes(nodes);
8133
+ visitor({
8134
+ url: url.trim(),
8135
+ urlNode
8136
+ });
8137
+ return;
8138
+ }
8139
+ });
8140
+ }
8141
+ });
8142
+ };
8143
+ const isUrlFunctionNode = node => {
8144
+ return node.type === "function" && /^url$/i.test(node.value);
8145
+ };
8146
+ const isImageSetFunctionNode = node => {
8147
+ return node.type === "function" && /^(?:-webkit-)?image-set$/i.test(node.value);
8148
+ };
8149
+ const isDataUrl = url => {
8150
+ return /data:[^\n\r;]+?(?:;charset=[^\n\r;]+?)?;base64,([\d+/A-Za-z]+={0,2})/.test(url);
8151
+ };
8152
+
8153
+ const createJsParseError = ({
8154
+ message,
8155
+ reasonCode,
8156
+ url,
8157
+ line,
8158
+ column
8159
+ }) => {
8160
+ const parseError = new Error(message);
8161
+ parseError.reasonCode = reasonCode;
8162
+ parseError.code = "PARSE_ERROR";
8163
+ parseError.url = url;
8164
+ parseError.line = line;
8165
+ parseError.column = column;
8166
+ return parseError;
8167
+ };
8168
+
8169
+ /*
8170
+ * Useful when writin a babel plugin:
8171
+ * - https://astexplorer.net/
8172
+ * - https://bvaughn.github.io/babel-repl
8173
+ */
8174
+ const applyBabelPlugins = async ({
8175
+ babelPlugins,
8176
+ urlInfo,
8177
+ ast,
8178
+ options = {}
8179
+ }) => {
8180
+ const sourceType = {
8181
+ js_module: "module",
8182
+ js_classic: "classic",
8183
+ [urlInfo.type]: undefined
8184
+ }[urlInfo.type];
8185
+ const url = urlInfo.originalUrl;
8186
+ const generatedUrl = urlInfo.generatedUrl;
8187
+ const content = urlInfo.content;
8188
+ if (babelPlugins.length === 0) {
8189
+ return {
8190
+ code: content
8191
+ };
8192
+ }
8193
+ const {
8194
+ transformAsync,
8195
+ transformFromAstAsync
8196
+ } = await import("@babel/core");
8197
+ const sourceFileName = url.startsWith("file:") ? fileURLToPath(url) : undefined;
8198
+ options = {
8199
+ ast: false,
8200
+ // https://babeljs.io/docs/en/options#source-map-options
8201
+ sourceMaps: true,
8202
+ sourceFileName,
8203
+ filename: generatedUrl ? generatedUrl.startsWith("file:") ? fileURLToPath(url) : undefined : sourceFileName,
8204
+ configFile: false,
8205
+ babelrc: false,
8206
+ highlightCode: false,
8207
+ // consider using startColumn and startLine for inline scripts?
8208
+ // see https://github.com/babel/babel/blob/3ee9db7afe741f4d2f7933c519d8e7672fccb08d/packages/babel-parser/src/options.js#L36-L39
8209
+ parserOpts: {
8210
+ sourceType,
8211
+ // allowAwaitOutsideFunction: true,
8212
+ plugins: [
8213
+ // "importMeta",
8214
+ // "topLevelAwait",
8215
+ "dynamicImport", "importAssertions", "jsx", "classProperties", "classPrivateProperties", "classPrivateMethods", ...(useTypeScriptExtension(url) ? ["typescript"] : []), ...(options.parserPlugins || [])].filter(Boolean)
8216
+ },
8217
+ generatorOpts: {
8218
+ compact: false
8219
+ },
8220
+ plugins: babelPlugins,
8221
+ ...options
8222
+ };
8223
+ try {
8224
+ if (ast) {
8225
+ const result = await transformFromAstAsync(ast, content, options);
8226
+ return result;
8227
+ }
8228
+ const result = await transformAsync(content, options);
8229
+ return result;
8230
+ } catch (error) {
8231
+ if (error && error.code === "BABEL_PARSE_ERROR") {
8232
+ throw createJsParseError({
8233
+ message: error.message,
8234
+ reasonCode: error.reasonCode,
8235
+ content,
8236
+ url,
8237
+ line: error.loc.line,
8238
+ column: error.loc.column
8239
+ });
8240
+ }
8241
+ throw error;
8242
+ }
8243
+ };
8244
+ const useTypeScriptExtension = url => {
8245
+ const {
8246
+ pathname
8247
+ } = new URL(url);
8248
+ return pathname.endsWith(".ts") || pathname.endsWith(".tsx");
8249
+ };
8250
+
8251
+ // const pattern = [
8252
+ // "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
8253
+ // "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))",
8254
+ // ].join("|")
8255
+ // const ansiRegex = new RegExp(pattern, "g")
8256
+
8257
+ // https://github.com/babel/babel/tree/master/packages/babel-helper-module-imports
8258
+ const injectJsImport = ({
8259
+ programPath,
8260
+ namespace,
8261
+ name,
8262
+ from,
8263
+ nameHint,
8264
+ sideEffect
8265
+ }) => {
8266
+ const {
8267
+ addNamespace,
8268
+ addDefault,
8269
+ addNamed,
8270
+ addSideEffect
8271
+ } = require$1("@babel/helper-module-imports");
8272
+ if (namespace) {
8273
+ return addNamespace(programPath, from, {
8274
+ nameHint
8275
+ });
8276
+ }
8277
+ if (name) {
8278
+ return addNamed(programPath, name, from);
8279
+ }
8280
+ if (sideEffect) {
8281
+ return addSideEffect(programPath, from);
8282
+ }
8283
+ return addDefault(programPath, from, {
8284
+ nameHint
8285
+ });
8286
+ };
8287
+
8288
+ let AcornParser;
8289
+ let _getLineInfo;
8290
+ const parseJsWithAcorn = async ({
8291
+ js,
8292
+ url,
8293
+ isJsModule
8294
+ }) => {
8295
+ await initAcornParser();
8296
+ try {
8297
+ // https://github.com/acornjs/acorn/tree/master/acorn#interface
8298
+ const jsAst = AcornParser.parse(js, {
8299
+ locations: true,
8300
+ allowAwaitOutsideFunction: true,
8301
+ sourceType: isJsModule ? "module" : "script",
8302
+ ecmaVersion: 2022
8303
+ });
8304
+ return jsAst;
8305
+ } catch (e) {
8306
+ if (e && e.name === "SyntaxError") {
8307
+ const {
8308
+ line,
8309
+ column
8310
+ } = _getLineInfo(js, e.raisedAt);
8311
+ throw createJsParseError({
8312
+ message: e.message,
8313
+ url,
8314
+ line,
8315
+ column
8316
+ });
8317
+ }
8318
+ throw e;
8319
+ }
8320
+ };
8321
+ const initAcornParser = async () => {
8322
+ if (AcornParser) {
8323
+ return;
8324
+ }
8325
+ const {
8326
+ Parser,
8327
+ getLineInfo
8328
+ } = await import("acorn");
8329
+ const {
8330
+ importAssertions
8331
+ } = await import("acorn-import-assertions");
8332
+ AcornParser = Parser.extend(importAssertions);
8333
+ _getLineInfo = getLineInfo;
8334
+ };
8335
+
8336
+ const getTypePropertyNode$1 = node => {
8337
+ if (node.type !== "ObjectExpression") {
8338
+ return null;
8339
+ }
8340
+ const {
8341
+ properties
8342
+ } = node;
8343
+ return properties.find(property => {
8344
+ return property.type === "Property" && property.key.type === "Identifier" && property.key.name === "type";
8345
+ });
8346
+ };
8347
+ const isStringLiteralNode = node => {
8348
+ return node.type === "Literal" && typeof node.value === "string";
8349
+ };
8350
+
8351
+ const analyzeImportDeclaration = (node, {
8352
+ onUrl
8353
+ }) => {
8354
+ const specifierNode = node.source;
8355
+ const assertionInfo = extractImportAssertionsInfo(node);
8356
+ onUrl({
8357
+ type: "js_import_export",
8358
+ subtype: "import_static",
8359
+ specifier: specifierNode.value,
8360
+ specifierStart: specifierNode.start,
8361
+ specifierEnd: specifierNode.end,
8362
+ specifierLine: specifierNode.loc.start.line,
8363
+ specifierColumn: specifierNode.loc.start.column,
8364
+ expectedType: assertionInfo ? assertionInfo.assert.type : "js_module",
8365
+ ...assertionInfo
8366
+ });
8367
+ };
8368
+ const analyzeImportExpression = (node, {
8369
+ onUrl
8370
+ }) => {
8371
+ const specifierNode = node.source;
8372
+ if (!isStringLiteralNode(specifierNode)) {
8373
+ return;
8374
+ }
8375
+ const assertionInfo = extractImportAssertionsInfo(node);
8376
+ onUrl({
8377
+ type: "js_import_export",
8378
+ subtype: "import_dynamic",
8379
+ specifier: specifierNode.value,
8380
+ specifierStart: specifierNode.start,
8381
+ specifierEnd: specifierNode.end,
8382
+ specifierLine: specifierNode.loc.start.line,
8383
+ specifierColumn: specifierNode.loc.start.column,
8384
+ expectedType: assertionInfo ? assertionInfo.assert.type : "js_module",
8385
+ ...assertionInfo
8386
+ });
8387
+ };
8388
+ const analyzeExportNamedDeclaration = (node, {
8389
+ onUrl
8390
+ }) => {
8391
+ const specifierNode = node.source;
8392
+ if (!specifierNode) {
8393
+ // This export has no "source", so it's probably
8394
+ // a local variable or function, e.g.
8395
+ // export { varName }
8396
+ // export const constName = ...
8397
+ // export function funcName() {}
8398
+ return;
8399
+ }
8400
+ onUrl({
8401
+ type: "js_import_export",
8402
+ subtype: "export_named",
8403
+ specifier: specifierNode.value,
8404
+ specifierStart: specifierNode.start,
8405
+ specifierEnd: specifierNode.end,
8406
+ specifierLine: specifierNode.loc.start.line,
8407
+ specifierColumn: specifierNode.loc.start.column
8408
+ });
8409
+ };
8410
+ const analyzeExportAllDeclaration = (node, {
8411
+ onUrl
8412
+ }) => {
8413
+ const specifierNode = node.source;
8414
+ onUrl({
8415
+ type: "js_import_export",
8416
+ subtype: "export_all",
8417
+ specifier: specifierNode.value,
8418
+ specifierStart: specifierNode.start,
8419
+ specifierEnd: specifierNode.end,
8420
+ specifierLine: specifierNode.loc.start.line,
8421
+ specifierColumn: specifierNode.loc.start.column
8422
+ });
8423
+ };
8424
+ const extractImportAssertionsInfo = node => {
8425
+ if (node.type === "ImportDeclaration") {
8426
+ // static import
8427
+ const {
8428
+ assertions
8429
+ } = node;
8430
+ if (!assertions) {
8431
+ return null;
8432
+ }
8433
+ if (assertions.length === 0) {
8434
+ return null;
8435
+ }
8436
+ const typeAssertionNode = assertions.find(assertion => assertion.key.name === "type");
8437
+ if (!typeAssertionNode) {
8438
+ return null;
8439
+ }
8440
+ const typeNode = typeAssertionNode.value;
8441
+ if (!isStringLiteralNode(typeNode)) {
8442
+ return null;
8443
+ }
8444
+ return {
8445
+ assertNode: typeAssertionNode,
8446
+ assert: {
8447
+ type: typeNode.value
8448
+ }
8449
+ };
8450
+ }
8451
+ // dynamic import
8452
+ const args = node.arguments;
8453
+ if (!args) {
8454
+ // acorn keeps node.arguments undefined for dynamic import without a second argument
8455
+ return null;
8456
+ }
8457
+ const firstArgNode = args[0];
8458
+ if (!firstArgNode) {
8459
+ return null;
8460
+ }
8461
+ const {
8462
+ properties
8463
+ } = firstArgNode;
8464
+ const assertProperty = properties.find(property => {
8465
+ return property.key.name === "assert";
8466
+ });
8467
+ if (!assertProperty) {
8468
+ return null;
8469
+ }
8470
+ const assertValueNode = assertProperty.value;
8471
+ if (assertValueNode.type !== "ObjectExpression") {
8472
+ return null;
8473
+ }
8474
+ const assertValueProperties = assertValueNode.properties;
8475
+ const typePropertyNode = assertValueProperties.find(property => {
8476
+ return property.key.name === "type";
8477
+ });
8478
+ if (!typePropertyNode) {
8479
+ return null;
8480
+ }
8481
+ const typePropertyValue = typePropertyNode.value;
8482
+ if (!isStringLiteralNode(typePropertyValue)) {
8483
+ return null;
8484
+ }
8485
+ return {
8486
+ assertNode: firstArgNode,
8487
+ assert: {
8488
+ type: typePropertyValue.value
8489
+ }
8490
+ };
8491
+ };
8492
+
8493
+ const isNewUrlCall = node => {
8494
+ return node.type === "NewExpression" && node.callee.type === "Identifier" && node.callee.name === "URL";
8495
+ };
8496
+ const analyzeNewUrlCall = (node, {
8497
+ isJsModule,
8498
+ onUrl
8499
+ }) => {
8500
+ if (node.arguments.length === 1) {
8501
+ const firstArgNode = node.arguments[0];
8502
+ const urlType = analyzeUrlNodeType(firstArgNode, {
8503
+ isJsModule
8504
+ });
8505
+ if (urlType === "StringLiteral") {
8506
+ const specifierNode = firstArgNode;
8507
+ onUrl({
8508
+ type: "js_url_specifier",
8509
+ subtype: "new_url_first_arg",
8510
+ specifier: specifierNode.value,
8511
+ specifierStart: specifierNode.start,
8512
+ specifierEnd: specifierNode.end,
8513
+ specifierLine: specifierNode.loc.start.line,
8514
+ specifierColumn: specifierNode.loc.start.column
8515
+ });
8516
+ }
8517
+ return;
8518
+ }
8519
+ if (node.arguments.length === 2) {
8520
+ const firstArgNode = node.arguments[0];
8521
+ const secondArgNode = node.arguments[1];
8522
+ const baseUrlType = analyzeUrlNodeType(secondArgNode, {
8523
+ isJsModule
8524
+ });
8525
+ if (baseUrlType) {
8526
+ // we can understand the second argument
8527
+ if (baseUrlType === "StringLiteral" && secondArgNode.value === "file:///") {
8528
+ // ignore new URL(specifier, "file:///")
8529
+ return;
8530
+ }
8531
+ const urlType = analyzeUrlNodeType(firstArgNode, {
8532
+ isJsModule
8533
+ });
8534
+ if (urlType === "StringLiteral") {
8535
+ // we can understand the first argument
8536
+ const specifierNode = firstArgNode;
8537
+ onUrl({
8538
+ type: "js_url_specifier",
8539
+ subtype: "new_url_first_arg",
8540
+ specifier: specifierNode.value,
8541
+ specifierStart: specifierNode.start,
8542
+ specifierEnd: specifierNode.end,
8543
+ specifierLine: specifierNode.loc.start.line,
8544
+ specifierColumn: specifierNode.loc.start.column,
8545
+ baseUrlType,
8546
+ baseUrl: baseUrlType === "StringLiteral" ? secondArgNode.value : undefined
8547
+ });
8548
+ }
8549
+ if (baseUrlType === "StringLiteral") {
8550
+ const specifierNode = secondArgNode;
8551
+ onUrl({
8552
+ type: "js_url_specifier",
8553
+ subtype: "new_url_second_arg",
8554
+ specifier: specifierNode.value,
8555
+ specifierStart: specifierNode.start,
8556
+ specifierEnd: specifierNode.end,
8557
+ specifierLine: specifierNode.loc.start.line,
8558
+ specifierColumn: specifierNode.loc.start.column
8559
+ });
8560
+ }
8561
+ }
8562
+ }
8563
+ };
8564
+ const analyzeUrlNodeType = (secondArgNode, {
8565
+ isJsModule
8566
+ }) => {
8567
+ if (isStringLiteralNode(secondArgNode)) {
8568
+ return "StringLiteral";
8569
+ }
8570
+ if (isImportMetaUrl(secondArgNode)) {
8571
+ return "import.meta.url";
8572
+ }
8573
+ if (isWindowLocation(secondArgNode)) {
8574
+ return "window.location";
8575
+ }
8576
+ if (isWindowOrigin(secondArgNode)) {
8577
+ return "window.origin";
8578
+ }
8579
+ if (!isJsModule && isContextMetaUrlFromSystemJs(secondArgNode)) {
8580
+ return "context.meta.url";
8581
+ }
8582
+ if (!isJsModule && isDocumentCurrentScriptSrc(secondArgNode)) {
8583
+ return "document.currentScript.src";
8584
+ }
8585
+ return null;
8586
+ };
8587
+ const isImportMetaUrl = node => {
8588
+ return node.type === "MemberExpression" && node.object.type === "MetaProperty" && node.property.type === "Identifier" && node.property.name === "url";
8589
+ };
8590
+ const isWindowLocation = node => {
8591
+ return node.type === "MemberExpression" && node.object.type === "Identifier" && node.object.name === "window" && node.property.type === "Identifier" && node.property.name === "location";
8592
+ };
8593
+ const isWindowOrigin = node => {
8594
+ return node.type === "MemberExpression" && node.object.type === "Identifier" && node.object.name === "window" && node.property.type === "Identifier" && node.property.name === "origin";
8595
+ };
8596
+ const isContextMetaUrlFromSystemJs = node => {
8597
+ return node.type === "MemberExpression" && node.object.type === "MemberExpression" && node.object.object.type === "Identifier" &&
8598
+ // because of minification we can't assume _context.
8599
+ // so anything matching "*.meta.url" (in the context of new URL())
8600
+ // will be assumed to be the equivalent to "import.meta.url"
8601
+ // node.object.object.name === "_context" &&
8602
+ node.object.property.type === "Identifier" && node.object.property.name === "meta" && node.property.type === "Identifier" && node.property.name === "url";
8603
+ };
8604
+ const isDocumentCurrentScriptSrc = node => {
8605
+ return node.type === "MemberExpression" && node.object.type === "MemberExpression" && node.object.object.type === "Identifier" && node.object.object.name === "document" && node.object.property.type === "Identifier" && node.object.property.name === "currentScript" && node.property.type === "Identifier" && node.property.name === "src";
8606
+ };
8607
+
8608
+ const isNewWorkerCall = node => {
8609
+ return node.type === "NewExpression" && node.callee.type === "Identifier" && node.callee.name === "Worker";
8610
+ };
8611
+ const analyzeNewWorkerCall = (node, {
8612
+ isJsModule,
8613
+ onUrl
8614
+ }) => {
8615
+ analyzeWorkerCallArguments(node, {
8616
+ isJsModule,
8617
+ onUrl,
8618
+ referenceSubtype: "new_worker_first_arg",
8619
+ expectedSubtype: "worker"
8620
+ });
8621
+ };
8622
+ const isNewSharedWorkerCall = node => {
8623
+ return node.type === "NewExpression" && node.callee.type === "Identifier" && node.callee.name === "SharedWorker";
8624
+ };
8625
+ const analyzeNewSharedWorkerCall = (node, {
8626
+ isJsModule,
8627
+ onUrl
8628
+ }) => {
8629
+ analyzeWorkerCallArguments(node, {
8630
+ isJsModule,
8631
+ onUrl,
8632
+ referenceSubtype: "new_shared_worker_first_arg",
8633
+ expectedSubtype: "shared_worker"
8634
+ });
8635
+ };
8636
+ const isServiceWorkerRegisterCall = node => {
8637
+ if (node.type !== "CallExpression") {
8638
+ return false;
8639
+ }
8640
+ const callee = node.callee;
8641
+ if (callee.type === "MemberExpression" && callee.property.type === "Identifier" && callee.property.name === "register") {
8642
+ const parentObject = callee.object;
8643
+ if (parentObject.type === "MemberExpression") {
8644
+ const parentProperty = parentObject.property;
8645
+ if (parentProperty.type === "Identifier" && parentProperty.name === "serviceWorker") {
8646
+ const grandParentObject = parentObject.object;
8647
+ if (grandParentObject.type === "MemberExpression") {
8648
+ // window.navigator.serviceWorker.register
8649
+ const grandParentProperty = grandParentObject.property;
8650
+ if (grandParentProperty.type === "Identifier" && grandParentProperty.name === "navigator") {
8651
+ const ancestorObject = grandParentObject.object;
8652
+ if (ancestorObject.type === "Identifier" && ancestorObject.name === "window") {
8653
+ return true;
8654
+ }
8655
+ }
8656
+ }
8657
+ if (grandParentObject.type === "Identifier") {
8658
+ // navigator.serviceWorker.register
8659
+ if (grandParentObject.name === "navigator") {
8660
+ return true;
8661
+ }
8662
+ }
8663
+ }
8664
+ }
8665
+ }
8666
+ return false;
8667
+ };
8668
+ const analyzeServiceWorkerRegisterCall = (node, {
8669
+ isJsModule,
8670
+ onUrl
8671
+ }) => {
8672
+ analyzeWorkerCallArguments(node, {
8673
+ isJsModule,
8674
+ onUrl,
8675
+ referenceSubtype: "service_worker_register_first_arg",
8676
+ expectedSubtype: "service_worker"
8677
+ });
8678
+ };
8679
+ const analyzeWorkerCallArguments = (node, {
8680
+ isJsModule,
8681
+ onUrl,
8682
+ referenceSubtype,
8683
+ expectedSubtype
8684
+ }) => {
8685
+ let expectedType = "js_classic";
8686
+ let typePropertyNode;
8687
+ const secondArgNode = node.arguments[1];
8688
+ if (secondArgNode) {
8689
+ typePropertyNode = getTypePropertyNode$1(secondArgNode);
8690
+ if (typePropertyNode) {
8691
+ const typePropertyValueNode = typePropertyNode.value;
8692
+ if (isStringLiteralNode(typePropertyValueNode)) {
8693
+ const typePropertyValue = typePropertyValueNode.value;
8694
+ if (typePropertyValue === "module") {
8695
+ expectedType = "js_module";
8696
+ }
8697
+ }
8698
+ }
8699
+ }
8700
+ const firstArgNode = node.arguments[0];
8701
+ if (isStringLiteralNode(firstArgNode)) {
8702
+ const specifierNode = firstArgNode;
8703
+ onUrl({
8704
+ type: "js_url_specifier",
8705
+ subtype: referenceSubtype,
8706
+ expectedType,
8707
+ expectedSubtype,
8708
+ typePropertyNode,
8709
+ specifier: specifierNode.value,
8710
+ specifierStart: specifierNode.start,
8711
+ specifierEnd: specifierNode.end,
8712
+ specifierLine: specifierNode.loc.start.line,
8713
+ specifierColumn: specifierNode.loc.start.column
8714
+ });
8715
+ return;
8716
+ }
8717
+ if (isNewUrlCall(firstArgNode)) {
8718
+ analyzeNewUrlCall(firstArgNode, {
8719
+ isJsModule,
8720
+ onUrl: mention => {
8721
+ Object.assign(mention, {
8722
+ expectedType,
8723
+ expectedSubtype,
8724
+ typePropertyNode
8725
+ });
8726
+ onUrl(mention);
8727
+ }
8728
+ });
8729
+ }
8730
+ };
8731
+
8732
+ const isImportScriptsCall = node => {
8733
+ const callee = node.callee;
8734
+ if (callee.type === "Identifier" && callee.name === "importScripts") {
8735
+ return true;
8736
+ }
8737
+ return callee.type === "MemberExpression" && callee.object.type === "Identifier" && callee.object.name === "self" && callee.property.type === "Identifier" && callee.property.name === "importScripts";
8738
+ };
8739
+ const analyzeImportScriptCalls = (node, {
8740
+ onUrl
8741
+ }) => {
8742
+ node.arguments.forEach(arg => {
8743
+ if (isStringLiteralNode(arg)) {
8744
+ const specifierNode = arg;
8745
+ onUrl({
8746
+ type: "js_url_specifier",
8747
+ subtype: "self_import_scripts_arg",
8748
+ expectedType: "js_classic",
8749
+ specifier: specifierNode.value,
8750
+ specifierStart: specifierNode.start,
8751
+ specifierEnd: specifierNode.end,
8752
+ specifierLine: specifierNode.loc.start.line,
8753
+ specifierColumn: specifierNode.loc.start.column
8754
+ });
8755
+ }
8756
+ });
8757
+ };
8758
+
8759
+ const isSystemRegisterCall = node => {
8760
+ const callee = node.callee;
8761
+ return callee.type === "MemberExpression" && callee.object.type === "Identifier" && callee.object.name === "System" && callee.property.type === "Identifier" && callee.property.name === "register";
8762
+ };
8763
+ const analyzeSystemRegisterCall = (node, {
8764
+ onUrl
8765
+ }) => {
8766
+ const firstArgNode = node.arguments[0];
8767
+ if (firstArgNode.type === "ArrayExpression") {
8768
+ analyzeSystemRegisterDeps(firstArgNode, {
8769
+ onUrl
8770
+ });
8771
+ return;
8772
+ }
8773
+ if (isStringLiteralNode(firstArgNode)) {
8774
+ const secondArgNode = node.arguments[1];
8775
+ if (secondArgNode.type === "ArrayExpression") {
8776
+ analyzeSystemRegisterDeps(secondArgNode, {
8777
+ onUrl
8778
+ });
8779
+ return;
8780
+ }
8781
+ }
8782
+ };
8783
+ const analyzeSystemRegisterDeps = (node, {
8784
+ onUrl
8785
+ }) => {
8786
+ const elements = node.elements;
8787
+ elements.forEach(element => {
8788
+ if (isStringLiteralNode(element)) {
8789
+ const specifierNode = element;
8790
+ onUrl({
8791
+ type: "js_url_specifier",
8792
+ subtype: "system_register_arg",
8793
+ expectedType: "js_classic",
8794
+ specifier: specifierNode.value,
8795
+ specifierStart: specifierNode.start,
8796
+ specifierEnd: specifierNode.end,
8797
+ specifierLine: specifierNode.loc.start.line,
8798
+ specifierColumn: specifierNode.loc.start.column
8799
+ });
8800
+ }
8801
+ });
8802
+ };
8803
+ const isSystemImportCall = node => {
8804
+ const callee = node.callee;
8805
+ return callee.type === "MemberExpression" && callee.object.type === "Identifier" &&
8806
+ // because of minification we can't assume _context.
8807
+ // so anything matching "*.import()"
8808
+ // will be assumed to be the equivalent to "import()"
8809
+ // callee.object.name === "_context" &&
8810
+ callee.property.type === "Identifier" && callee.property.name === "import";
8811
+ };
8812
+ const analyzeSystemImportCall = (node, {
8813
+ onUrl
8814
+ }) => {
8815
+ const firstArgNode = node.arguments[0];
8816
+ if (isStringLiteralNode(firstArgNode)) {
8817
+ const specifierNode = firstArgNode;
8818
+ onUrl({
8819
+ type: "js_url_specifier",
8820
+ subtype: "system_import_arg",
8821
+ expectedType: "js_classic",
8822
+ specifier: specifierNode.value,
8823
+ specifierStart: specifierNode.start,
8824
+ specifierEnd: specifierNode.end,
8825
+ specifierLine: specifierNode.loc.start.line,
8826
+ specifierColumn: specifierNode.loc.start.column
8827
+ });
8828
+ }
8829
+ };
8830
+
8831
+ const parseJsUrls = async ({
8832
+ js,
8833
+ url,
8834
+ isJsModule = false,
8835
+ isWebWorker = false
8836
+ } = {}) => {
8837
+ const jsUrls = [];
8838
+ const jsAst = await parseJsWithAcorn({
8839
+ js,
8840
+ url,
8841
+ isJsModule
8842
+ });
8843
+ const onUrl = jsUrl => {
8844
+ jsUrls.push(jsUrl);
8845
+ };
8846
+ ancestor(jsAst, {
8847
+ ImportDeclaration: node => {
8848
+ analyzeImportDeclaration(node, {
8849
+ onUrl
8850
+ });
8851
+ },
8852
+ ImportExpression: node => {
8853
+ analyzeImportExpression(node, {
8854
+ onUrl
8855
+ });
8856
+ },
8857
+ ExportNamedDeclaration: node => {
8858
+ analyzeExportNamedDeclaration(node, {
8859
+ onUrl
8860
+ });
8861
+ },
8862
+ ExportAllDeclaration: node => {
8863
+ analyzeExportAllDeclaration(node, {
8864
+ onUrl
8865
+ });
8866
+ },
8867
+ CallExpression: node => {
8868
+ if (isServiceWorkerRegisterCall(node)) {
8869
+ analyzeServiceWorkerRegisterCall(node, {
8870
+ isJsModule,
8871
+ onUrl
8872
+ });
8873
+ return;
8874
+ }
8875
+ if (isWebWorker && isImportScriptsCall(node)) {
8876
+ analyzeImportScriptCalls(node, {
8877
+ onUrl
8878
+ });
8879
+ return;
8880
+ }
8881
+ if (!isJsModule && isSystemRegisterCall(node)) {
8882
+ analyzeSystemRegisterCall(node, {
8883
+ onUrl
8884
+ });
8885
+ return;
8886
+ }
8887
+ if (!isJsModule && isSystemImportCall(node)) {
8888
+ analyzeSystemImportCall(node, {
8889
+ onUrl
8890
+ });
8891
+ return;
8892
+ }
8893
+ },
8894
+ NewExpression: (node, ancestors) => {
8895
+ if (isNewWorkerCall(node)) {
8896
+ analyzeNewWorkerCall(node, {
8897
+ isJsModule,
8898
+ onUrl
8899
+ });
8900
+ return;
8901
+ }
8902
+ if (isNewSharedWorkerCall(node)) {
8903
+ analyzeNewSharedWorkerCall(node, {
8904
+ isJsModule,
8905
+ onUrl
8906
+ });
8907
+ return;
8908
+ }
8909
+ if (isNewUrlCall(node)) {
8910
+ const parent = ancestors[ancestors.length - 2];
8911
+ if (parent && (isNewWorkerCall(parent) || isNewSharedWorkerCall(parent) || isServiceWorkerRegisterCall(parent))) {
8912
+ return;
8913
+ }
8914
+ analyzeNewUrlCall(node, {
8915
+ isJsModule,
8916
+ onUrl
8917
+ });
8918
+ return;
8919
+ }
8920
+ }
8921
+ });
8922
+ return jsUrls;
8923
+ };
8924
+
6967
8925
  const sortByDependencies = nodes => {
6968
8926
  const visited = [];
6969
8927
  const sorted = [];
@@ -16266,62 +18224,55 @@ const defaultReadPackageJson = packageUrl => {
16266
18224
  };
16267
18225
 
16268
18226
  // https://github.com/nodejs/node/blob/0367b5c35ea0f98b323175a4aaa8e651af7a91e7/tools/node_modules/eslint/node_modules/%40babel/core/lib/vendor/import-meta-resolve.js#L2473
16269
- const createInvalidModuleSpecifierError = ({
16270
- specifier,
16271
- parentUrl,
16272
- reason
18227
+ const createInvalidModuleSpecifierError = (reason, specifier, {
18228
+ parentUrl
16273
18229
  }) => {
16274
18230
  const error = new Error(`Invalid module "${specifier}" ${reason} imported from ${fileURLToPath(parentUrl)}`);
16275
18231
  error.code = "INVALID_MODULE_SPECIFIER";
16276
18232
  return error;
16277
18233
  };
16278
- const createInvalidPackageTargetError = ({
18234
+ const createInvalidPackageTargetError = (reason, target, {
16279
18235
  parentUrl,
16280
- packageUrl,
16281
- target,
18236
+ packageDirectoryUrl,
16282
18237
  key,
16283
- isImport,
16284
- reason
18238
+ isImport
16285
18239
  }) => {
16286
18240
  let message;
16287
18241
  if (key === ".") {
16288
- message = `Invalid "exports" main target defined in ${fileURLToPath(packageUrl)}package.json imported from ${fileURLToPath(parentUrl)}; ${reason}`;
18242
+ message = `Invalid "exports" main target defined in ${fileURLToPath(packageDirectoryUrl)}package.json imported from ${fileURLToPath(parentUrl)}; ${reason}`;
16289
18243
  } else {
16290
- message = `Invalid "${isImport ? "imports" : "exports"}" target ${JSON.stringify(target)} defined for "${key}" in ${fileURLToPath(packageUrl)}package.json imported from ${fileURLToPath(parentUrl)}; ${reason}`;
18244
+ message = `Invalid "${isImport ? "imports" : "exports"}" target ${JSON.stringify(target)} defined for "${key}" in ${fileURLToPath(packageDirectoryUrl)}package.json imported from ${fileURLToPath(parentUrl)}; ${reason}`;
16291
18245
  }
16292
18246
  const error = new Error(message);
16293
18247
  error.code = "INVALID_PACKAGE_TARGET";
16294
18248
  return error;
16295
18249
  };
16296
- const createPackagePathNotExportedError = ({
16297
- subpath,
18250
+ const createPackagePathNotExportedError = (subpath, {
16298
18251
  parentUrl,
16299
- packageUrl
18252
+ packageDirectoryUrl
16300
18253
  }) => {
16301
18254
  let message;
16302
18255
  if (subpath === ".") {
16303
- message = `No "exports" main defined in ${fileURLToPath(packageUrl)}package.json imported from ${fileURLToPath(parentUrl)}`;
18256
+ message = `No "exports" main defined in ${fileURLToPath(packageDirectoryUrl)}package.json imported from ${fileURLToPath(parentUrl)}`;
16304
18257
  } else {
16305
- message = `Package subpath "${subpath}" is not defined by "exports" in ${fileURLToPath(packageUrl)}package.json imported from ${fileURLToPath(parentUrl)}`;
18258
+ message = `Package subpath "${subpath}" is not defined by "exports" in ${fileURLToPath(packageDirectoryUrl)}package.json imported from ${fileURLToPath(parentUrl)}`;
16306
18259
  }
16307
18260
  const error = new Error(message);
16308
18261
  error.code = "PACKAGE_PATH_NOT_EXPORTED";
16309
18262
  return error;
16310
18263
  };
16311
- const createModuleNotFoundError = ({
16312
- specifier,
18264
+ const createModuleNotFoundError = (specifier, {
16313
18265
  parentUrl
16314
18266
  }) => {
16315
18267
  const error = new Error(`Cannot find "${specifier}" imported from ${fileURLToPath(parentUrl)}`);
16316
18268
  error.code = "MODULE_NOT_FOUND";
16317
18269
  return error;
16318
18270
  };
16319
- const createPackageImportNotDefinedError = ({
16320
- specifier,
16321
- packageUrl,
16322
- parentUrl
18271
+ const createPackageImportNotDefinedError = (specifier, {
18272
+ parentUrl,
18273
+ packageDirectoryUrl
16323
18274
  }) => {
16324
- const error = new Error(`Package import specifier "${specifier}" is not defined in ${fileURLToPath(packageUrl)}package.json imported from ${fileURLToPath(parentUrl)}`);
18275
+ const error = new Error(`Package import specifier "${specifier}" is not defined in ${fileURLToPath(packageDirectoryUrl)}package.json imported from ${fileURLToPath(parentUrl)}`);
16325
18276
  error.code = "PACKAGE_IMPORT_NOT_DEFINED";
16326
18277
  return error;
16327
18278
  };
@@ -16354,51 +18305,41 @@ const readCustomConditionsFromProcessArgs = () => {
16354
18305
  * or use the real path when inside
16355
18306
  */
16356
18307
  const applyNodeEsmResolution = ({
16357
- conditions = [...readCustomConditionsFromProcessArgs(), "node", "import"],
16358
- parentUrl,
16359
18308
  specifier,
18309
+ parentUrl,
18310
+ conditions = [...readCustomConditionsFromProcessArgs(), "node", "import"],
16360
18311
  lookupPackageScope = defaultLookupPackageScope,
16361
- readPackageJson = defaultReadPackageJson
18312
+ readPackageJson = defaultReadPackageJson,
18313
+ preservesSymlink = false
16362
18314
  }) => {
16363
- const resolution = applyPackageSpecifierResolution({
16364
- conditions,
18315
+ const resolution = applyPackageSpecifierResolution(specifier, {
16365
18316
  parentUrl: String(parentUrl),
16366
- specifier,
18317
+ conditions,
16367
18318
  lookupPackageScope,
16368
- readPackageJson
18319
+ readPackageJson,
18320
+ preservesSymlink
16369
18321
  });
16370
18322
  const {
16371
18323
  url
16372
18324
  } = resolution;
16373
18325
  if (url.startsWith("file:")) {
16374
18326
  if (url.includes("%2F") || url.includes("%5C")) {
16375
- throw createInvalidModuleSpecifierError({
16376
- specifier,
16377
- parentUrl,
16378
- reason: `must not include encoded "/" or "\\" characters`
18327
+ throw createInvalidModuleSpecifierError(`must not include encoded "/" or "\\" characters`, specifier, {
18328
+ parentUrl
16379
18329
  });
16380
18330
  }
16381
18331
  return resolution;
16382
18332
  }
16383
18333
  return resolution;
16384
18334
  };
16385
- const applyPackageSpecifierResolution = ({
16386
- conditions,
16387
- parentUrl,
16388
- specifier,
16389
- lookupPackageScope,
16390
- readPackageJson
16391
- }) => {
18335
+ const applyPackageSpecifierResolution = (specifier, resolutionContext) => {
18336
+ const {
18337
+ parentUrl
18338
+ } = resolutionContext;
16392
18339
  // relative specifier
16393
18340
  if (specifier[0] === "/" || specifier.startsWith("./") || specifier.startsWith("../")) {
16394
18341
  if (specifier[0] !== "/") {
16395
- const browserFieldResolution = applyBrowserFieldResolution({
16396
- conditions,
16397
- parentUrl,
16398
- specifier,
16399
- lookupPackageScope,
16400
- readPackageJson
16401
- });
18342
+ const browserFieldResolution = applyBrowserFieldResolution(specifier, resolutionContext);
16402
18343
  if (browserFieldResolution) {
16403
18344
  return browserFieldResolution;
16404
18345
  }
@@ -16409,13 +18350,7 @@ const applyPackageSpecifierResolution = ({
16409
18350
  };
16410
18351
  }
16411
18352
  if (specifier[0] === "#") {
16412
- return applyPackageImportsResolution({
16413
- conditions,
16414
- parentUrl,
16415
- specifier,
16416
- lookupPackageScope,
16417
- readPackageJson
16418
- });
18353
+ return applyPackageImportsResolution(specifier, resolutionContext);
16419
18354
  }
16420
18355
  try {
16421
18356
  const urlObject = new URL(specifier);
@@ -16431,41 +18366,29 @@ const applyPackageSpecifierResolution = ({
16431
18366
  };
16432
18367
  } catch (e) {
16433
18368
  // bare specifier
16434
- const browserFieldResolution = applyBrowserFieldResolution({
16435
- conditions,
16436
- parentUrl,
16437
- packageSpecifier: specifier,
16438
- lookupPackageScope,
16439
- readPackageJson
16440
- });
18369
+ const browserFieldResolution = applyBrowserFieldResolution(specifier, resolutionContext);
16441
18370
  if (browserFieldResolution) {
16442
18371
  return browserFieldResolution;
16443
18372
  }
16444
- return applyPackageResolve({
16445
- conditions,
16446
- parentUrl,
16447
- packageSpecifier: specifier,
16448
- lookupPackageScope,
16449
- readPackageJson
16450
- });
18373
+ return applyPackageResolve(specifier, resolutionContext);
16451
18374
  }
16452
18375
  };
16453
- const applyBrowserFieldResolution = ({
16454
- conditions,
16455
- parentUrl,
16456
- packageSpecifier,
16457
- lookupPackageScope,
16458
- readPackageJson
16459
- }) => {
18376
+ const applyBrowserFieldResolution = (specifier, resolutionContext) => {
18377
+ const {
18378
+ parentUrl,
18379
+ conditions,
18380
+ lookupPackageScope,
18381
+ readPackageJson
18382
+ } = resolutionContext;
16460
18383
  const browserCondition = conditions.includes("browser");
16461
18384
  if (!browserCondition) {
16462
18385
  return null;
16463
18386
  }
16464
- const packageUrl = lookupPackageScope(parentUrl);
16465
- if (!packageUrl) {
18387
+ const packageDirectoryUrl = lookupPackageScope(parentUrl);
18388
+ if (!packageDirectoryUrl) {
16466
18389
  return null;
16467
18390
  }
16468
- const packageJson = readPackageJson(packageUrl);
18391
+ const packageJson = readPackageJson(packageDirectoryUrl);
16469
18392
  if (!packageJson) {
16470
18393
  return null;
16471
18394
  }
@@ -16479,91 +18402,73 @@ const applyBrowserFieldResolution = ({
16479
18402
  return null;
16480
18403
  }
16481
18404
  let url;
16482
- if (packageSpecifier.startsWith(".")) {
16483
- const packageSpecifierUrl = new URL(packageSpecifier, parentUrl).href;
16484
- const packageSpecifierRelativeUrl = packageSpecifierUrl.slice(packageUrl.length);
16485
- const packageSpecifierRelativeNotation = `./${packageSpecifierRelativeUrl}`;
16486
- const browserMapping = browser[packageSpecifierRelativeNotation];
18405
+ if (specifier.startsWith(".")) {
18406
+ const specifierUrl = new URL(specifier, parentUrl).href;
18407
+ const specifierRelativeUrl = specifierUrl.slice(packageDirectoryUrl.length);
18408
+ const secifierRelativeNotation = `./${specifierRelativeUrl}`;
18409
+ const browserMapping = browser[secifierRelativeNotation];
16487
18410
  if (typeof browserMapping === "string") {
16488
- url = new URL(browserMapping, packageUrl).href;
18411
+ url = new URL(browserMapping, packageDirectoryUrl).href;
16489
18412
  } else if (browserMapping === false) {
16490
- url = `file:///@ignore/${packageSpecifierUrl.slice("file:///")}`;
18413
+ url = `file:///@ignore/${specifierUrl.slice("file:///")}`;
16491
18414
  }
16492
18415
  } else {
16493
- const browserMapping = browser[packageSpecifier];
18416
+ const browserMapping = browser[specifier];
16494
18417
  if (typeof browserMapping === "string") {
16495
- url = new URL(browserMapping, packageUrl).href;
18418
+ url = new URL(browserMapping, packageDirectoryUrl).href;
16496
18419
  } else if (browserMapping === false) {
16497
- url = `file:///@ignore/${packageSpecifier}`;
18420
+ url = `file:///@ignore/${specifier}`;
16498
18421
  }
16499
18422
  }
16500
18423
  if (url) {
16501
18424
  return {
16502
18425
  type: "field:browser",
16503
- packageUrl,
18426
+ packageDirectoryUrl,
16504
18427
  packageJson,
16505
18428
  url
16506
18429
  };
16507
18430
  }
16508
18431
  return null;
16509
18432
  };
16510
- const applyPackageImportsResolution = ({
16511
- conditions,
16512
- parentUrl,
16513
- specifier,
16514
- lookupPackageScope,
16515
- readPackageJson
16516
- }) => {
16517
- if (!specifier.startsWith("#")) {
16518
- throw createInvalidModuleSpecifierError({
16519
- specifier,
16520
- parentUrl,
16521
- reason: "internal imports must start with #"
16522
- });
16523
- }
16524
- if (specifier === "#" || specifier.startsWith("#/")) {
16525
- throw createInvalidModuleSpecifierError({
16526
- specifier,
16527
- parentUrl,
16528
- reason: "not a valid internal imports specifier name"
16529
- });
18433
+ const applyPackageImportsResolution = (internalSpecifier, resolutionContext) => {
18434
+ const {
18435
+ parentUrl,
18436
+ lookupPackageScope,
18437
+ readPackageJson
18438
+ } = resolutionContext;
18439
+ if (internalSpecifier === "#" || internalSpecifier.startsWith("#/")) {
18440
+ throw createInvalidModuleSpecifierError("not a valid internal imports specifier name", internalSpecifier, resolutionContext);
16530
18441
  }
16531
- const packageUrl = lookupPackageScope(parentUrl);
16532
- if (packageUrl !== null) {
16533
- const packageJson = readPackageJson(packageUrl);
18442
+ const packageDirectoryUrl = lookupPackageScope(parentUrl);
18443
+ if (packageDirectoryUrl !== null) {
18444
+ const packageJson = readPackageJson(packageDirectoryUrl);
16534
18445
  const {
16535
18446
  imports
16536
18447
  } = packageJson;
16537
18448
  if (imports !== null && typeof imports === "object") {
16538
- const resolved = applyPackageImportsExportsResolution({
16539
- conditions,
16540
- parentUrl,
16541
- packageUrl,
18449
+ const resolved = applyPackageImportsExportsResolution(internalSpecifier, {
18450
+ ...resolutionContext,
18451
+ packageDirectoryUrl,
16542
18452
  packageJson,
16543
- matchObject: imports,
16544
- matchKey: specifier,
16545
- isImports: true,
16546
- lookupPackageScope,
16547
- readPackageJson
18453
+ isImport: true
16548
18454
  });
16549
18455
  if (resolved) {
16550
18456
  return resolved;
16551
18457
  }
16552
18458
  }
16553
18459
  }
16554
- throw createPackageImportNotDefinedError({
16555
- specifier,
16556
- packageUrl,
16557
- parentUrl
18460
+ throw createPackageImportNotDefinedError(internalSpecifier, {
18461
+ ...resolutionContext,
18462
+ packageDirectoryUrl
16558
18463
  });
16559
18464
  };
16560
- const applyPackageResolve = ({
16561
- conditions,
16562
- parentUrl,
16563
- packageSpecifier,
16564
- lookupPackageScope,
16565
- readPackageJson
16566
- }) => {
18465
+ const applyPackageResolve = (packageSpecifier, resolutionContext) => {
18466
+ const {
18467
+ parentUrl,
18468
+ conditions,
18469
+ readPackageJson,
18470
+ preservesSymlink
18471
+ } = resolutionContext;
16567
18472
  if (packageSpecifier === "") {
16568
18473
  throw new Error("invalid module specifier");
16569
18474
  }
@@ -16578,79 +18483,60 @@ const applyPackageResolve = ({
16578
18483
  packageSubpath
16579
18484
  } = parsePackageSpecifier(packageSpecifier);
16580
18485
  if (packageName[0] === "." || packageName.includes("\\") || packageName.includes("%")) {
16581
- throw createInvalidModuleSpecifierError({
16582
- specifier: packageName,
16583
- parentUrl,
16584
- reason: `is not a valid package name`
16585
- });
18486
+ throw createInvalidModuleSpecifierError(`is not a valid package name`, packageName, resolutionContext);
16586
18487
  }
16587
18488
  if (packageSubpath.endsWith("/")) {
16588
18489
  throw new Error("invalid module specifier");
16589
18490
  }
16590
- const selfResolution = applyPackageSelfResolution({
16591
- conditions,
16592
- parentUrl,
16593
- packageName,
16594
- packageSubpath,
16595
- lookupPackageScope,
16596
- readPackageJson
18491
+ const selfResolution = applyPackageSelfResolution(packageSubpath, {
18492
+ ...resolutionContext,
18493
+ packageName
16597
18494
  });
16598
18495
  if (selfResolution) {
16599
18496
  return selfResolution;
16600
18497
  }
16601
18498
  let currentUrl = parentUrl;
16602
18499
  while (currentUrl !== "file:///") {
16603
- const packageUrl = new URL(`node_modules/${packageName}/`, currentUrl).href;
16604
- if (!existsSync(new URL(packageUrl))) {
18500
+ const packageDirectoryFacadeUrl = new URL(`node_modules/${packageName}/`, currentUrl).href;
18501
+ if (!existsSync(new URL(packageDirectoryFacadeUrl))) {
16605
18502
  currentUrl = getParentUrl(currentUrl);
16606
18503
  continue;
16607
18504
  }
16608
- const packageJson = readPackageJson(packageUrl);
18505
+ const packageDirectoryUrl = preservesSymlink ? packageDirectoryFacadeUrl : resolvePackageSymlink(packageDirectoryFacadeUrl);
18506
+ const packageJson = readPackageJson(packageDirectoryUrl);
16609
18507
  if (packageJson !== null) {
16610
18508
  const {
16611
18509
  exports
16612
18510
  } = packageJson;
16613
18511
  if (exports !== null && exports !== undefined) {
16614
- return applyPackageExportsResolution({
16615
- conditions,
16616
- parentUrl,
16617
- packageUrl,
18512
+ return applyPackageExportsResolution(packageSubpath, {
18513
+ ...resolutionContext,
18514
+ packageDirectoryUrl,
16618
18515
  packageJson,
16619
- packageSubpath,
16620
- exports,
16621
- lookupPackageScope,
16622
- readPackageJson
18516
+ exports
16623
18517
  });
16624
18518
  }
16625
18519
  }
16626
- return applyLegacySubpathResolution({
16627
- conditions,
16628
- parentUrl,
16629
- packageUrl,
16630
- packageJson,
16631
- packageSubpath,
16632
- lookupPackageScope,
16633
- readPackageJson
18520
+ return applyLegacySubpathResolution(packageSubpath, {
18521
+ ...resolutionContext,
18522
+ packageDirectoryUrl,
18523
+ packageJson
16634
18524
  });
16635
18525
  }
16636
- throw createModuleNotFoundError({
16637
- specifier: packageName,
16638
- parentUrl
16639
- });
18526
+ throw createModuleNotFoundError(packageName, resolutionContext);
16640
18527
  };
16641
- const applyPackageSelfResolution = ({
16642
- conditions,
16643
- parentUrl,
16644
- packageName,
16645
- packageSubpath,
16646
- lookupPackageScope,
16647
- readPackageJson
16648
- }) => {
16649
- const packageUrl = lookupPackageScope(parentUrl);
16650
- if (!packageUrl) {
18528
+ const applyPackageSelfResolution = (packageSubpath, resolutionContext) => {
18529
+ const {
18530
+ parentUrl,
18531
+ packageName,
18532
+ lookupPackageScope,
18533
+ readPackageJson
18534
+ } = resolutionContext;
18535
+ const packageDirectoryUrl = lookupPackageScope(parentUrl);
18536
+ if (!packageDirectoryUrl) {
16651
18537
  return undefined;
16652
18538
  }
16653
- const packageJson = readPackageJson(packageUrl);
18539
+ const packageJson = readPackageJson(packageDirectoryUrl);
16654
18540
  if (!packageJson) {
16655
18541
  return undefined;
16656
18542
  }
@@ -16661,123 +18547,63 @@ const applyPackageSelfResolution = ({
16661
18547
  exports
16662
18548
  } = packageJson;
16663
18549
  if (!exports) {
16664
- const subpathResolution = applyLegacySubpathResolution({
16665
- conditions,
16666
- parentUrl,
16667
- packageUrl,
16668
- packageJson,
16669
- packageSubpath,
16670
- lookupPackageScope,
16671
- readPackageJson
18550
+ const subpathResolution = applyLegacySubpathResolution(packageSubpath, {
18551
+ ...resolutionContext,
18552
+ packageDirectoryUrl,
18553
+ packageJson
16672
18554
  });
16673
18555
  if (subpathResolution && subpathResolution.type !== "subpath") {
16674
18556
  return subpathResolution;
16675
18557
  }
16676
18558
  return undefined;
16677
18559
  }
16678
- return applyPackageExportsResolution({
16679
- conditions,
16680
- parentUrl,
16681
- packageUrl,
16682
- packageJson,
16683
- packageSubpath,
16684
- exports,
16685
- lookupPackageScope,
16686
- readPackageJson
18560
+ return applyPackageExportsResolution(packageSubpath, {
18561
+ ...resolutionContext,
18562
+ packageDirectoryUrl,
18563
+ packageJson
16687
18564
  });
16688
18565
  };
16689
18566
 
16690
18567
  // https://github.com/nodejs/node/blob/0367b5c35ea0f98b323175a4aaa8e651af7a91e7/lib/internal/modules/esm/resolve.js#L642
16691
- const applyPackageExportsResolution = ({
16692
- conditions,
16693
- parentUrl,
16694
- packageUrl,
16695
- packageJson,
16696
- packageSubpath,
16697
- exports,
16698
- lookupPackageScope,
16699
- readPackageJson
16700
- }) => {
16701
- const exportsInfo = readExports({
16702
- exports,
16703
- packageUrl
16704
- });
18568
+ const applyPackageExportsResolution = (packageSubpath, resolutionContext) => {
16705
18569
  if (packageSubpath === ".") {
16706
- const mainExport = applyMainExportResolution({
16707
- exports,
16708
- exportsInfo
16709
- });
18570
+ const mainExport = applyMainExportResolution(resolutionContext);
16710
18571
  if (!mainExport) {
16711
- throw createPackagePathNotExportedError({
16712
- subpath: packageSubpath,
16713
- parentUrl,
16714
- packageUrl
16715
- });
18572
+ throw createPackagePathNotExportedError(packageSubpath, resolutionContext);
16716
18573
  }
16717
- const resolved = applyPackageTargetResolution({
16718
- conditions,
16719
- parentUrl,
16720
- packageUrl,
16721
- packageJson,
16722
- key: ".",
16723
- target: mainExport,
16724
- lookupPackageScope,
16725
- readPackageJson
18574
+ const resolved = applyPackageTargetResolution(mainExport, {
18575
+ ...resolutionContext,
18576
+ key: "."
16726
18577
  });
16727
18578
  if (resolved) {
16728
18579
  return resolved;
16729
18580
  }
16730
- throw createPackagePathNotExportedError({
16731
- subpath: packageSubpath,
16732
- parentUrl,
16733
- packageUrl
16734
- });
18581
+ throw createPackagePathNotExportedError(packageSubpath, resolutionContext);
16735
18582
  }
16736
- if (exportsInfo.type === "object" && exportsInfo.allKeysAreRelative) {
16737
- const resolved = applyPackageImportsExportsResolution({
16738
- conditions,
16739
- parentUrl,
16740
- packageUrl,
16741
- packageJson,
16742
- matchObject: exports,
16743
- matchKey: packageSubpath,
16744
- isImports: false,
16745
- lookupPackageScope,
16746
- readPackageJson
18583
+ const packageExportsInfo = readExports(resolutionContext);
18584
+ if (packageExportsInfo.type === "object" && packageExportsInfo.allKeysAreRelative) {
18585
+ const resolved = applyPackageImportsExportsResolution(packageSubpath, {
18586
+ ...resolutionContext,
18587
+ isImport: false
16747
18588
  });
16748
18589
  if (resolved) {
16749
18590
  return resolved;
16750
18591
  }
16751
18592
  }
16752
- throw createPackagePathNotExportedError({
16753
- subpath: packageSubpath,
16754
- parentUrl,
16755
- packageUrl
16756
- });
18593
+ throw createPackagePathNotExportedError(packageSubpath, resolutionContext);
16757
18594
  };
16758
- const applyPackageImportsExportsResolution = ({
16759
- conditions,
16760
- parentUrl,
16761
- packageUrl,
16762
- packageJson,
16763
- matchObject,
16764
- matchKey,
16765
- isImports,
16766
- lookupPackageScope,
16767
- readPackageJson
16768
- }) => {
18595
+ const applyPackageImportsExportsResolution = (matchKey, resolutionContext) => {
18596
+ const {
18597
+ packageJson,
18598
+ isImport
18599
+ } = resolutionContext;
18600
+ const matchObject = isImport ? packageJson.imports : packageJson.exports;
16769
18601
  if (!matchKey.includes("*") && matchObject.hasOwnProperty(matchKey)) {
16770
18602
  const target = matchObject[matchKey];
16771
- return applyPackageTargetResolution({
16772
- conditions,
16773
- parentUrl,
16774
- packageUrl,
16775
- packageJson,
18603
+ return applyPackageTargetResolution(target, {
18604
+ ...resolutionContext,
16776
18605
  key: matchKey,
16777
- target,
16778
- internal: isImports,
16779
- lookupPackageScope,
16780
- readPackageJson
18606
+ isImport
16781
18607
  });
16782
18608
  }
16783
18609
  const expansionKeys = Object.keys(matchObject).filter(key => key.split("*").length === 2).sort(comparePatternKeys);
@@ -16791,74 +18617,48 @@ const applyPackageImportsExportsResolution = ({
16791
18617
  }
16792
18618
  const target = matchObject[expansionKey];
16793
18619
  const subpath = matchKey.slice(patternBase.length, matchKey.length - patternTrailer.length);
16794
- return applyPackageTargetResolution({
16795
- conditions,
16796
- parentUrl,
16797
- packageUrl,
16798
- packageJson,
18620
+ return applyPackageTargetResolution(target, {
18621
+ ...resolutionContext,
16799
18622
  key: matchKey,
16800
- target,
16801
18623
  subpath,
16802
18624
  pattern: true,
16803
- internal: isImports,
16804
- lookupPackageScope,
16805
- readPackageJson
18625
+ isImport
16806
18626
  });
16807
18627
  }
16808
18628
  return null;
16809
18629
  };
16810
- const applyPackageTargetResolution = ({
16811
- conditions,
16812
- parentUrl,
16813
- packageUrl,
16814
- packageJson,
16815
- key,
16816
- target,
16817
- subpath = "",
16818
- pattern = false,
16819
- internal = false,
16820
- lookupPackageScope,
16821
- readPackageJson
16822
- }) => {
18630
+ const applyPackageTargetResolution = (target, resolutionContext) => {
18631
+ const {
18632
+ conditions,
18633
+ packageDirectoryUrl,
18634
+ packageJson,
18635
+ key,
18636
+ subpath = "",
18637
+ pattern = false,
18638
+ isImport = false
18639
+ } = resolutionContext;
16823
18640
  if (typeof target === "string") {
16824
18641
  if (pattern === false && subpath !== "" && !target.endsWith("/")) {
16825
18642
  throw new Error("invalid module specifier");
16826
18643
  }
16827
18644
  if (target.startsWith("./")) {
16828
- const targetUrl = new URL(target, packageUrl).href;
16829
- if (!targetUrl.startsWith(packageUrl)) {
16830
- throw createInvalidPackageTargetError({
16831
- parentUrl,
16832
- packageUrl,
16833
- target,
16834
- key,
16835
- isImport: internal,
16836
- reason: `target must be inside package`
16837
- });
18645
+ const targetUrl = new URL(target, packageDirectoryUrl).href;
18646
+ if (!targetUrl.startsWith(packageDirectoryUrl)) {
18647
+ throw createInvalidPackageTargetError(`target must be inside package`, target, resolutionContext);
16838
18648
  }
16839
18649
  return {
16840
- type: internal ? "field:imports" : "field:exports",
16841
- packageUrl,
18650
+ type: isImport ? "field:imports" : "field:exports",
18651
+ packageDirectoryUrl,
16842
18652
  packageJson,
16843
18653
  url: pattern ? targetUrl.replaceAll("*", subpath) : new URL(subpath, targetUrl).href
16844
18654
  };
16845
18655
  }
16846
- if (!internal || target.startsWith("../") || isValidUrl(target)) {
16847
- throw createInvalidPackageTargetError({
16848
- parentUrl,
16849
- packageUrl,
16850
- target,
16851
- key,
16852
- isImport: internal,
16853
- reason: `target must starst with "./"`
16854
- });
18656
+ if (!isImport || target.startsWith("../") || isValidUrl(target)) {
18657
+ throw createInvalidPackageTargetError(`target must starst with "./"`, target, resolutionContext);
16855
18658
  }
16856
- return applyPackageResolve({
16857
- conditions,
16858
- parentUrl: packageUrl,
16859
- packageSpecifier: pattern ? target.replaceAll("*", subpath) : `${target}${subpath}`,
16860
- lookupPackageScope,
16861
- readPackageJson
18659
+ return applyPackageResolve(pattern ? target.replaceAll("*", subpath) : `${target}${subpath}`, {
18660
+ ...resolutionContext,
18661
+ parentUrl: packageDirectoryUrl
16862
18662
  });
16863
18663
  }
16864
18664
  if (Array.isArray(target)) {
@@ -16871,18 +18671,12 @@ const applyPackageTargetResolution = ({
16871
18671
  const targetValue = target[i];
16872
18672
  i++;
16873
18673
  try {
16874
- const resolved = applyPackageTargetResolution({
16875
- conditions,
16876
- parentUrl,
16877
- packageUrl,
16878
- packageJson,
18674
+ const resolved = applyPackageTargetResolution(targetValue, {
18675
+ ...resolutionContext,
16879
18676
  key: `${key}[${i}]`,
16880
- target: targetValue,
16881
18677
  subpath,
16882
18678
  pattern,
16883
- internal,
16884
- lookupPackageScope,
16885
- readPackageJson
18679
+ isImport
16886
18680
  });
16887
18681
  if (resolved) {
16888
18682
  return resolved;
@@ -16911,18 +18705,12 @@ const applyPackageTargetResolution = ({
16911
18705
  }
16912
18706
  if (key === "default" || conditions.includes(key)) {
16913
18707
  const targetValue = target[key];
16914
- const resolved = applyPackageTargetResolution({
16915
- conditions,
16916
- parentUrl,
16917
- packageUrl,
16918
- packageJson,
18708
+ const resolved = applyPackageTargetResolution(targetValue, {
18709
+ ...resolutionContext,
16919
18710
  key,
16920
- target: targetValue,
16921
18711
  subpath,
16922
18712
  pattern,
16923
- internal,
16924
- lookupPackageScope,
16925
- readPackageJson
18713
+ isImport
16926
18714
  });
16927
18715
  if (resolved) {
16928
18716
  return resolved;
@@ -16931,29 +18719,23 @@ const applyPackageTargetResolution = ({
16931
18719
  }
16932
18720
  return null;
16933
18721
  }
16934
- throw createInvalidPackageTargetError({
16935
- parentUrl,
16936
- packageUrl,
16937
- target,
16938
- key,
16939
- isImport: internal,
16940
- reason: `target must be a string, array, object or null`
16941
- });
18722
+ throw createInvalidPackageTargetError(`target must be a string, array, object or null`, target, resolutionContext);
16942
18723
  };
16943
18724
  const readExports = ({
16944
- exports,
16945
- packageUrl
18725
+ packageDirectoryUrl,
18726
+ packageJson
16946
18727
  }) => {
16947
- if (Array.isArray(exports)) {
18728
+ const packageExports = packageJson.exports;
18729
+ if (Array.isArray(packageExports)) {
16948
18730
  return {
16949
18731
  type: "array"
16950
18732
  };
16951
18733
  }
16952
- if (exports === null) {
18734
+ if (packageExports === null) {
16953
18735
  return {};
16954
18736
  }
16955
- if (typeof exports === "object") {
16956
- const keys = Object.keys(exports);
18737
+ if (typeof packageExports === "object") {
18738
+ const keys = Object.keys(packageExports);
16957
18739
  const relativeKeys = [];
16958
18740
  const conditionalKeys = [];
16959
18741
  keys.forEach(availableKey => {
@@ -16968,8 +18750,8 @@ const readExports = ({
16968
18750
  throw new Error(`Invalid package configuration: cannot mix relative and conditional keys in package.exports
16969
18751
  --- unexpected keys ---
16970
18752
  ${conditionalKeys.map(key => `"${key}"`).join("\n")}
16971
- --- package.json ---
16972
- ${packageUrl}`);
18753
+ --- package directory url ---
18754
+ ${packageDirectoryUrl}`);
16973
18755
  }
16974
18756
  return {
16975
18757
  type: "object",
@@ -16977,7 +18759,7 @@ ${packageUrl}`);
16977
18759
  allKeysAreRelative: relativeKeys.length === keys.length
16978
18760
  };
16979
18761
  }
16980
- if (typeof exports === "string") {
18762
+ if (typeof packageExports === "string") {
16981
18763
  return {
16982
18764
  type: "string"
16983
18765
  };
@@ -17022,84 +18804,74 @@ const parsePackageSpecifier = packageSpecifier => {
17022
18804
  packageSubpath
17023
18805
  };
17024
18806
  };
17025
- const applyMainExportResolution = ({
17026
- exports,
17027
- exportsInfo
17028
- }) => {
17029
- if (exportsInfo.type === "array" || exportsInfo.type === "string") {
17030
- return exports;
18807
+ const applyMainExportResolution = resolutionContext => {
18808
+ const {
18809
+ packageJson
18810
+ } = resolutionContext;
18811
+ const packageExportsInfo = readExports(resolutionContext);
18812
+ if (packageExportsInfo.type === "array" || packageExportsInfo.type === "string") {
18813
+ return packageJson.exports;
17031
18814
  }
17032
- if (exportsInfo.type === "object") {
17033
- if (exportsInfo.hasRelativeKey) {
17034
- return exports["."];
18815
+ if (packageExportsInfo.type === "object") {
18816
+ if (packageExportsInfo.hasRelativeKey) {
18817
+ return packageJson.exports["."];
17035
18818
  }
17036
- return exports;
18819
+ return packageJson.exports;
17037
18820
  }
17038
18821
  return undefined;
17039
18822
  };
17040
- const applyLegacySubpathResolution = ({
17041
- conditions,
17042
- parentUrl,
17043
- packageUrl,
17044
- packageJson,
17045
- packageSubpath,
17046
- lookupPackageScope,
17047
- readPackageJson
17048
- }) => {
18823
+ const applyLegacySubpathResolution = (packageSubpath, resolutionContext) => {
18824
+ const {
18825
+ packageDirectoryUrl,
18826
+ packageJson
18827
+ } = resolutionContext;
17049
18828
  if (packageSubpath === ".") {
17050
- return applyLegacyMainResolution({
17051
- conditions,
17052
- packageUrl,
17053
- packageJson
17054
- });
18829
+ return applyLegacyMainResolution(packageSubpath, resolutionContext);
17055
18830
  }
17056
- const browserFieldResolution = applyBrowserFieldResolution({
17057
- conditions,
17058
- parentUrl,
17059
- specifier: packageSubpath,
17060
- lookupPackageScope,
17061
- readPackageJson
17062
- });
18831
+ const browserFieldResolution = applyBrowserFieldResolution(packageSubpath, resolutionContext);
17063
18832
  if (browserFieldResolution) {
17064
18833
  return browserFieldResolution;
17065
18834
  }
17066
18835
  return {
17067
18836
  type: "subpath",
17068
- packageUrl,
18837
+ packageDirectoryUrl,
17069
18838
  packageJson,
17070
- url: new URL(packageSubpath, packageUrl).href
18839
+ url: new URL(packageSubpath, packageDirectoryUrl).href
17071
18840
  };
17072
18841
  };
17073
- const applyLegacyMainResolution = ({
17074
- conditions,
17075
- packageUrl,
17076
- packageJson
17077
- }) => {
18842
+ const applyLegacyMainResolution = (packageSubpath, resolutionContext) => {
18843
+ const {
18844
+ conditions,
18845
+ packageDirectoryUrl,
18846
+ packageJson
18847
+ } = resolutionContext;
17078
18848
  for (const condition of conditions) {
17079
18849
  const conditionResolver = mainLegacyResolvers[condition];
17080
18850
  if (!conditionResolver) {
17081
18851
  continue;
17082
18852
  }
17083
- const resolved = conditionResolver(packageJson, packageUrl);
18853
+ const resolved = conditionResolver(resolutionContext);
17084
18854
  if (resolved) {
17085
18855
  return {
17086
18856
  type: resolved.type,
17087
- packageUrl,
18857
+ packageDirectoryUrl,
17088
18858
  packageJson,
17089
- url: new URL(resolved.path, packageUrl).href
18859
+ url: new URL(resolved.path, packageDirectoryUrl).href
17090
18860
  };
17091
18861
  }
17092
18862
  }
17093
18863
  return {
17094
18864
  type: "field:main",
17095
18865
  // the absence of "main" field
17096
- packageUrl,
18866
+ packageDirectoryUrl,
17097
18867
  packageJson,
17098
- url: new URL("index.js", packageUrl).href
18868
+ url: new URL("index.js", packageDirectoryUrl).href
17099
18869
  };
17100
18870
  };
17101
18871
  const mainLegacyResolvers = {
17102
- import: packageJson => {
18872
+ import: ({
18873
+ packageJson
18874
+ }) => {
17103
18875
  if (typeof packageJson.module === "string") {
17104
18876
  return {
17105
18877
  type: "field:module",
@@ -17120,7 +18892,10 @@ const mainLegacyResolvers = {
17120
18892
  }
17121
18893
  return null;
17122
18894
  },
17123
- browser: (packageJson, packageUrl) => {
18895
+ browser: ({
18896
+ packageDirectoryUrl,
18897
+ packageJson
18898
+ }) => {
17124
18899
  const browserMain = (() => {
17125
18900
  if (typeof packageJson.browser === "string") {
17126
18901
  return packageJson.browser;
@@ -17145,7 +18920,7 @@ const mainLegacyResolvers = {
17145
18920
  path: browserMain
17146
18921
  };
17147
18922
  }
17148
- const browserMainUrlObject = new URL(browserMain, packageUrl);
18923
+ const browserMainUrlObject = new URL(browserMain, packageDirectoryUrl);
17149
18924
  const content = readFileSync$1(browserMainUrlObject, "utf-8");
17150
18925
  if (/typeof exports\s*==/.test(content) && /typeof module\s*==/.test(content) || /module\.exports\s*=/.test(content)) {
17151
18926
  return {
@@ -17158,7 +18933,9 @@ const mainLegacyResolvers = {
17158
18933
  path: browserMain
17159
18934
  };
17160
18935
  },
17161
- node: packageJson => {
18936
+ node: ({
18937
+ packageJson
18938
+ }) => {
17162
18939
  if (typeof packageJson.main === "string") {
17163
18940
  return {
17164
18941
  type: "field:main",
@@ -17199,6 +18976,11 @@ const comparePatternKeys = (keyA, keyB) => {
17199
18976
  }
17200
18977
  return 0;
17201
18978
  };
18979
+ const resolvePackageSymlink = packageDirectoryUrl => {
18980
+ const packageDirectoryPath = realpathSync(new URL(packageDirectoryUrl));
18981
+ const packageDirectoryResolvedUrl = pathToFileURL(packageDirectoryPath).href;
18982
+ return `${packageDirectoryResolvedUrl}/`;
18983
+ };
17202
18984
 
17203
18985
  const applyFileSystemMagicResolution = (fileUrl, {
17204
18986
  fileStat,
@@ -17309,7 +19091,7 @@ const createNodeEsmResolver = ({
17309
19091
  const {
17310
19092
  url,
17311
19093
  type,
17312
- packageUrl
19094
+ packageDirectoryUrl
17313
19095
  } = applyNodeEsmResolution({
17314
19096
  conditions: packageConditions,
17315
19097
  parentUrl,
@@ -17324,7 +19106,7 @@ const createNodeEsmResolver = ({
17324
19106
  addRelationshipWithPackageJson({
17325
19107
  reference,
17326
19108
  context,
17327
- packageJsonUrl: `${packageUrl}package.json`,
19109
+ packageJsonUrl: `${packageDirectoryUrl}package.json`,
17328
19110
  field: type.startsWith("field:") ? `#${type.slice("field:".length)}` : ""
17329
19111
  });
17330
19112
  }
@@ -22067,8 +23849,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
22067
23849
  const buildSpecifierBeforeRedirect = findKey(buildUrls, buildUrlFormatted);
22068
23850
  mutations.push(() => {
22069
23851
  setHtmlNodeAttributes(node, {
22070
- href: buildSpecifierBeforeRedirect,
22071
- crossorigin: undefined
23852
+ href: buildSpecifierBeforeRedirect
22072
23853
  });
22073
23854
  });
22074
23855
  };