@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/js/autoreload.js +1 -1
- package/dist/js/html_src_set.js +20 -0
- package/dist/main.js +2187 -406
- package/package.json +3 -2
- package/src/build/build.js +0 -1
- package/src/plugins/url_resolution/node_esm_resolver.js +2 -2
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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
18252
|
+
packageDirectoryUrl
|
|
16300
18253
|
}) => {
|
|
16301
18254
|
let message;
|
|
16302
18255
|
if (subpath === ".") {
|
|
16303
|
-
message = `No "exports" main defined in ${fileURLToPath(
|
|
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(
|
|
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
|
-
|
|
16321
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16387
|
-
|
|
16388
|
-
|
|
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
|
-
|
|
16455
|
-
|
|
16456
|
-
|
|
16457
|
-
|
|
16458
|
-
|
|
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
|
|
16465
|
-
if (!
|
|
18387
|
+
const packageDirectoryUrl = lookupPackageScope(parentUrl);
|
|
18388
|
+
if (!packageDirectoryUrl) {
|
|
16466
18389
|
return null;
|
|
16467
18390
|
}
|
|
16468
|
-
const packageJson = readPackageJson(
|
|
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 (
|
|
16483
|
-
const
|
|
16484
|
-
const
|
|
16485
|
-
const
|
|
16486
|
-
const browserMapping = browser[
|
|
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,
|
|
18411
|
+
url = new URL(browserMapping, packageDirectoryUrl).href;
|
|
16489
18412
|
} else if (browserMapping === false) {
|
|
16490
|
-
url = `file:///@ignore/${
|
|
18413
|
+
url = `file:///@ignore/${specifierUrl.slice("file:///")}`;
|
|
16491
18414
|
}
|
|
16492
18415
|
} else {
|
|
16493
|
-
const browserMapping = browser[
|
|
18416
|
+
const browserMapping = browser[specifier];
|
|
16494
18417
|
if (typeof browserMapping === "string") {
|
|
16495
|
-
url = new URL(browserMapping,
|
|
18418
|
+
url = new URL(browserMapping, packageDirectoryUrl).href;
|
|
16496
18419
|
} else if (browserMapping === false) {
|
|
16497
|
-
url = `file:///@ignore/${
|
|
18420
|
+
url = `file:///@ignore/${specifier}`;
|
|
16498
18421
|
}
|
|
16499
18422
|
}
|
|
16500
18423
|
if (url) {
|
|
16501
18424
|
return {
|
|
16502
18425
|
type: "field:browser",
|
|
16503
|
-
|
|
18426
|
+
packageDirectoryUrl,
|
|
16504
18427
|
packageJson,
|
|
16505
18428
|
url
|
|
16506
18429
|
};
|
|
16507
18430
|
}
|
|
16508
18431
|
return null;
|
|
16509
18432
|
};
|
|
16510
|
-
const applyPackageImportsResolution = ({
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16514
|
-
|
|
16515
|
-
|
|
16516
|
-
|
|
16517
|
-
|
|
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
|
|
16532
|
-
if (
|
|
16533
|
-
const packageJson = readPackageJson(
|
|
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
|
-
|
|
16540
|
-
|
|
16541
|
-
packageUrl,
|
|
18449
|
+
const resolved = applyPackageImportsExportsResolution(internalSpecifier, {
|
|
18450
|
+
...resolutionContext,
|
|
18451
|
+
packageDirectoryUrl,
|
|
16542
18452
|
packageJson,
|
|
16543
|
-
|
|
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
|
-
|
|
16556
|
-
|
|
16557
|
-
parentUrl
|
|
18460
|
+
throw createPackageImportNotDefinedError(internalSpecifier, {
|
|
18461
|
+
...resolutionContext,
|
|
18462
|
+
packageDirectoryUrl
|
|
16558
18463
|
});
|
|
16559
18464
|
};
|
|
16560
|
-
const applyPackageResolve = ({
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
|
|
16565
|
-
|
|
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
|
-
|
|
16592
|
-
|
|
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
|
|
16604
|
-
if (!existsSync(new URL(
|
|
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
|
|
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
|
-
|
|
16616
|
-
|
|
16617
|
-
packageUrl,
|
|
18512
|
+
return applyPackageExportsResolution(packageSubpath, {
|
|
18513
|
+
...resolutionContext,
|
|
18514
|
+
packageDirectoryUrl,
|
|
16618
18515
|
packageJson,
|
|
16619
|
-
|
|
16620
|
-
exports,
|
|
16621
|
-
lookupPackageScope,
|
|
16622
|
-
readPackageJson
|
|
18516
|
+
exports
|
|
16623
18517
|
});
|
|
16624
18518
|
}
|
|
16625
18519
|
}
|
|
16626
|
-
return applyLegacySubpathResolution({
|
|
16627
|
-
|
|
16628
|
-
|
|
16629
|
-
|
|
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
|
-
|
|
16643
|
-
|
|
16644
|
-
|
|
16645
|
-
|
|
16646
|
-
|
|
16647
|
-
|
|
16648
|
-
|
|
16649
|
-
|
|
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(
|
|
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
|
-
|
|
16666
|
-
|
|
16667
|
-
|
|
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
|
-
|
|
16680
|
-
|
|
16681
|
-
|
|
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
|
-
|
|
16719
|
-
|
|
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
|
-
|
|
16737
|
-
|
|
16738
|
-
|
|
16739
|
-
|
|
16740
|
-
|
|
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
|
-
|
|
16760
|
-
|
|
16761
|
-
|
|
16762
|
-
|
|
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
|
-
|
|
16773
|
-
parentUrl,
|
|
16774
|
-
packageUrl,
|
|
16775
|
-
packageJson,
|
|
18603
|
+
return applyPackageTargetResolution(target, {
|
|
18604
|
+
...resolutionContext,
|
|
16776
18605
|
key: matchKey,
|
|
16777
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16804
|
-
lookupPackageScope,
|
|
16805
|
-
readPackageJson
|
|
18625
|
+
isImport
|
|
16806
18626
|
});
|
|
16807
18627
|
}
|
|
16808
18628
|
return null;
|
|
16809
18629
|
};
|
|
16810
|
-
const applyPackageTargetResolution = ({
|
|
16811
|
-
|
|
16812
|
-
|
|
16813
|
-
|
|
16814
|
-
|
|
16815
|
-
|
|
16816
|
-
|
|
16817
|
-
|
|
16818
|
-
|
|
16819
|
-
|
|
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,
|
|
16829
|
-
if (!targetUrl.startsWith(
|
|
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:
|
|
16841
|
-
|
|
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 (!
|
|
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
|
-
|
|
16858
|
-
parentUrl:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16945
|
-
|
|
18725
|
+
packageDirectoryUrl,
|
|
18726
|
+
packageJson
|
|
16946
18727
|
}) => {
|
|
16947
|
-
|
|
18728
|
+
const packageExports = packageJson.exports;
|
|
18729
|
+
if (Array.isArray(packageExports)) {
|
|
16948
18730
|
return {
|
|
16949
18731
|
type: "array"
|
|
16950
18732
|
};
|
|
16951
18733
|
}
|
|
16952
|
-
if (
|
|
18734
|
+
if (packageExports === null) {
|
|
16953
18735
|
return {};
|
|
16954
18736
|
}
|
|
16955
|
-
if (typeof
|
|
16956
|
-
const keys = Object.keys(
|
|
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
|
|
16972
|
-
${
|
|
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
|
|
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
|
-
|
|
17027
|
-
|
|
17028
|
-
}
|
|
17029
|
-
|
|
17030
|
-
|
|
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 (
|
|
17033
|
-
if (
|
|
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
|
-
|
|
17042
|
-
|
|
17043
|
-
|
|
17044
|
-
|
|
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
|
-
|
|
18837
|
+
packageDirectoryUrl,
|
|
17069
18838
|
packageJson,
|
|
17070
|
-
url: new URL(packageSubpath,
|
|
18839
|
+
url: new URL(packageSubpath, packageDirectoryUrl).href
|
|
17071
18840
|
};
|
|
17072
18841
|
};
|
|
17073
|
-
const applyLegacyMainResolution = ({
|
|
17074
|
-
|
|
17075
|
-
|
|
17076
|
-
|
|
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(
|
|
18853
|
+
const resolved = conditionResolver(resolutionContext);
|
|
17084
18854
|
if (resolved) {
|
|
17085
18855
|
return {
|
|
17086
18856
|
type: resolved.type,
|
|
17087
|
-
|
|
18857
|
+
packageDirectoryUrl,
|
|
17088
18858
|
packageJson,
|
|
17089
|
-
url: new URL(resolved.path,
|
|
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
|
-
|
|
18866
|
+
packageDirectoryUrl,
|
|
17097
18867
|
packageJson,
|
|
17098
|
-
url: new URL("index.js",
|
|
18868
|
+
url: new URL("index.js", packageDirectoryUrl).href
|
|
17099
18869
|
};
|
|
17100
18870
|
};
|
|
17101
18871
|
const mainLegacyResolvers = {
|
|
17102
|
-
import:
|
|
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: (
|
|
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,
|
|
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:
|
|
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
|
-
|
|
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: `${
|
|
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
|
};
|