@jsenv/core 37.1.5 → 38.0.1
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 +2 -2
- package/dist/jsenv_core.js +3231 -2483
- package/package.json +14 -13
- package/src/build/build.js +250 -1028
- package/src/build/build_specifier_manager.js +1200 -0
- package/src/build/build_urls_generator.js +40 -18
- package/src/build/version_mappings_injection.js +14 -16
- package/src/dev/file_service.js +0 -10
- package/src/dev/start_dev_server.js +0 -2
- package/src/kitchen/kitchen.js +54 -37
- package/src/kitchen/url_graph/references.js +84 -93
- package/src/kitchen/url_graph/url_graph.js +16 -6
- package/src/kitchen/url_graph/url_info_transformations.js +124 -55
- package/src/plugins/autoreload/client/autoreload.js +6 -2
- package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +20 -16
- package/src/plugins/autoreload/jsenv_plugin_hot_search_param.js +1 -1
- package/src/plugins/cache_control/jsenv_plugin_cache_control.js +2 -2
- package/src/plugins/clean_html/jsenv_plugin_clean_html.js +16 -0
- package/src/plugins/importmap/jsenv_plugin_importmap.js +11 -23
- package/src/plugins/inlining/jsenv_plugin_inlining_as_data_url.js +16 -1
- package/src/plugins/inlining/jsenv_plugin_inlining_into_html.js +14 -24
- package/src/plugins/plugin_controller.js +37 -25
- package/src/plugins/plugins.js +2 -0
- package/src/plugins/protocol_file/jsenv_plugin_protocol_file.js +31 -16
- package/src/plugins/reference_analysis/directory/jsenv_plugin_directory_reference_analysis.js +12 -6
- package/src/plugins/reference_analysis/html/jsenv_plugin_html_reference_analysis.js +33 -54
- package/src/plugins/reference_analysis/js/jsenv_plugin_js_reference_analysis.js +2 -9
- package/src/plugins/reference_analysis/jsenv_plugin_reference_analysis.js +15 -8
- package/src/build/build_versions_manager.js +0 -492
|
@@ -1,492 +0,0 @@
|
|
|
1
|
-
// see https://github.com/rollup/rollup/blob/ce453507ab8457dd1ea3909d8dd7b117b2d14fab/src/utils/hashPlaceholders.ts#L1
|
|
2
|
-
|
|
3
|
-
import { createHash } from "node:crypto";
|
|
4
|
-
import {
|
|
5
|
-
injectQueryParamIntoSpecifierWithoutEncoding,
|
|
6
|
-
renderUrlOrRelativeUrlFilename,
|
|
7
|
-
} from "@jsenv/urls";
|
|
8
|
-
import { parseHtmlString, stringifyHtmlAst } from "@jsenv/ast";
|
|
9
|
-
import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js";
|
|
10
|
-
import { escapeRegexpSpecialChars } from "@jsenv/utils/src/string/escape_regexp_special_chars.js";
|
|
11
|
-
import { GRAPH_VISITOR } from "../kitchen/url_graph/url_graph_visitor.js";
|
|
12
|
-
import { isWebWorkerUrlInfo } from "../kitchen/web_workers.js";
|
|
13
|
-
import {
|
|
14
|
-
injectVersionMappingsAsGlobal,
|
|
15
|
-
injectVersionMappingsAsImportmap,
|
|
16
|
-
} from "./version_mappings_injection.js";
|
|
17
|
-
|
|
18
|
-
const placeholderLeft = "!~{";
|
|
19
|
-
const placeholderRight = "}~";
|
|
20
|
-
const placeholderOverhead = placeholderLeft.length + placeholderRight.length;
|
|
21
|
-
|
|
22
|
-
export const createBuildVersionsManager = ({
|
|
23
|
-
finalKitchen,
|
|
24
|
-
versioningMethod,
|
|
25
|
-
versionLength = 8,
|
|
26
|
-
canUseImportmap,
|
|
27
|
-
getBuildUrlFromBuildSpecifier,
|
|
28
|
-
}) => {
|
|
29
|
-
const workerReferenceSet = new Set();
|
|
30
|
-
const isReferencedByWorker = (reference) => {
|
|
31
|
-
if (workerReferenceSet.has(reference)) {
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
const referencedUrlInfo = reference.urlInfo;
|
|
35
|
-
const dependentWorker = GRAPH_VISITOR.findDependent(
|
|
36
|
-
referencedUrlInfo,
|
|
37
|
-
(dependentUrlInfo) => {
|
|
38
|
-
return isWebWorkerUrlInfo(dependentUrlInfo);
|
|
39
|
-
},
|
|
40
|
-
);
|
|
41
|
-
if (dependentWorker) {
|
|
42
|
-
workerReferenceSet.add(reference);
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
return Boolean(dependentWorker);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const chars =
|
|
49
|
-
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$";
|
|
50
|
-
const base = 64;
|
|
51
|
-
const toBase64 = (value) => {
|
|
52
|
-
let outString = "";
|
|
53
|
-
do {
|
|
54
|
-
const currentDigit = value % base;
|
|
55
|
-
value = (value / base) | 0;
|
|
56
|
-
outString = chars[currentDigit] + outString;
|
|
57
|
-
} while (value !== 0);
|
|
58
|
-
return outString;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
let nextIndex = 0;
|
|
62
|
-
const generatePlaceholder = () => {
|
|
63
|
-
nextIndex++;
|
|
64
|
-
const id = toBase64(nextIndex);
|
|
65
|
-
let placeholder = placeholderLeft;
|
|
66
|
-
placeholder += id.padStart(versionLength - placeholderOverhead, "0");
|
|
67
|
-
placeholder += placeholderRight;
|
|
68
|
-
return placeholder;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const replaceFirstPlaceholder = (code, value) => {
|
|
72
|
-
let replaced = false;
|
|
73
|
-
return code.replace(REPLACER_REGEX, (match) => {
|
|
74
|
-
if (replaced) return match;
|
|
75
|
-
replaced = true;
|
|
76
|
-
return value;
|
|
77
|
-
});
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const defaultPlaceholder = `${placeholderLeft}${"0".repeat(
|
|
81
|
-
versionLength - placeholderOverhead,
|
|
82
|
-
)}${placeholderRight}`;
|
|
83
|
-
const replaceWithDefaultAndPopulateContainedPlaceholders = (
|
|
84
|
-
code,
|
|
85
|
-
containedPlaceholders,
|
|
86
|
-
) => {
|
|
87
|
-
const transformedCode = code.replace(REPLACER_REGEX, (placeholder) => {
|
|
88
|
-
containedPlaceholders.add(placeholder);
|
|
89
|
-
return defaultPlaceholder;
|
|
90
|
-
});
|
|
91
|
-
return transformedCode;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const REPLACER_REGEX = new RegExp(
|
|
95
|
-
`${escapeRegexpSpecialChars(placeholderLeft)}[0-9a-zA-Z_$]{1,${
|
|
96
|
-
versionLength - placeholderOverhead
|
|
97
|
-
}}${escapeRegexpSpecialChars(placeholderRight)}`,
|
|
98
|
-
"g",
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
const placeholderToReferenceMap = new Map();
|
|
102
|
-
const buildSpecifierToPlaceholderMap = new Map();
|
|
103
|
-
|
|
104
|
-
const referenceVersionedByCodeMap = new Map();
|
|
105
|
-
const referenceVersionedByImportmapMap = new Map();
|
|
106
|
-
const specifierVersionedInlineSet = new Set();
|
|
107
|
-
const specifierVersionedByCodeSet = new Set();
|
|
108
|
-
const specifierVersionedByImportmapSet = new Set();
|
|
109
|
-
const versionMap = new Map();
|
|
110
|
-
|
|
111
|
-
const buildSpecifierToBuildSpecifierVersionedMap = new Map();
|
|
112
|
-
// - will be used by global and importmap registry
|
|
113
|
-
// - will be used by build during "inject_urls_in_service_workers" and
|
|
114
|
-
// "resync_resource_hints"
|
|
115
|
-
const getBuildSpecifierVersioned = (buildSpecifier) => {
|
|
116
|
-
const fromCache =
|
|
117
|
-
buildSpecifierToBuildSpecifierVersionedMap.get(buildSpecifier);
|
|
118
|
-
if (fromCache) {
|
|
119
|
-
return fromCache;
|
|
120
|
-
}
|
|
121
|
-
const buildSpecifierPlaceholder =
|
|
122
|
-
buildSpecifierToPlaceholderMap.get(buildSpecifier);
|
|
123
|
-
if (!buildSpecifierPlaceholder) {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
const buildUrl = getBuildUrlFromBuildSpecifier(buildSpecifier);
|
|
127
|
-
const urlInfo = finalKitchen.graph.getUrlInfo(buildUrl);
|
|
128
|
-
const version = versionMap.get(urlInfo);
|
|
129
|
-
const buildSpecifierVersioned = replaceFirstPlaceholder(
|
|
130
|
-
buildSpecifierPlaceholder,
|
|
131
|
-
version,
|
|
132
|
-
);
|
|
133
|
-
buildSpecifierToBuildSpecifierVersionedMap.set(
|
|
134
|
-
buildSpecifier,
|
|
135
|
-
buildSpecifierVersioned,
|
|
136
|
-
);
|
|
137
|
-
return buildSpecifierVersioned;
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
generateBuildSpecifierPlaceholder: (reference, buildSpecifier) => {
|
|
142
|
-
const placeholder = generatePlaceholder();
|
|
143
|
-
const buildSpecifierWithVersionPlaceholder =
|
|
144
|
-
injectVersionPlaceholderIntoBuildSpecifier({
|
|
145
|
-
buildSpecifier,
|
|
146
|
-
versionPlaceholder: placeholder,
|
|
147
|
-
versioningMethod,
|
|
148
|
-
});
|
|
149
|
-
buildSpecifierToPlaceholderMap.set(
|
|
150
|
-
buildSpecifier,
|
|
151
|
-
buildSpecifierWithVersionPlaceholder,
|
|
152
|
-
);
|
|
153
|
-
placeholderToReferenceMap.set(placeholder, reference);
|
|
154
|
-
|
|
155
|
-
const asPlaceholderForVersionedSpecifier = () => {
|
|
156
|
-
specifierVersionedInlineSet.add(buildSpecifier);
|
|
157
|
-
return buildSpecifierWithVersionPlaceholder;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const asPlaceholderForCodeVersionedByGlobalRegistry = (codeToInject) => {
|
|
161
|
-
// here we use placeholder as specifier, so something like
|
|
162
|
-
// "/other/file.png" becomes "!~{0001}~" and finally "__v__("/other/file.png")"
|
|
163
|
-
// this is to support cases like CSS inlined in JS
|
|
164
|
-
// CSS minifier must see valid CSS specifiers like background-image: url("!~{0001}~");
|
|
165
|
-
// that is finally replaced by invalid css background-image: url("__v__("/other/file.png")")
|
|
166
|
-
specifierVersionedByCodeSet.add(buildSpecifier);
|
|
167
|
-
referenceVersionedByCodeMap.set(reference, codeToInject);
|
|
168
|
-
return placeholder;
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
const asPlaceholderForSpecifierVersionedByImportmap = (
|
|
172
|
-
specifierToUse,
|
|
173
|
-
) => {
|
|
174
|
-
specifierVersionedByImportmapSet.add(buildSpecifier);
|
|
175
|
-
referenceVersionedByImportmapMap.set(reference, specifierToUse);
|
|
176
|
-
return buildSpecifier;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
const ownerUrlInfo = reference.ownerUrlInfo;
|
|
180
|
-
if (ownerUrlInfo.jsQuote) {
|
|
181
|
-
return asPlaceholderForCodeVersionedByGlobalRegistry(
|
|
182
|
-
`${ownerUrlInfo.jsQuote}+__v__(${JSON.stringify(buildSpecifier)})+${
|
|
183
|
-
ownerUrlInfo.jsQuote
|
|
184
|
-
}`,
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
if (reference.type === "js_url") {
|
|
188
|
-
return asPlaceholderForCodeVersionedByGlobalRegistry(
|
|
189
|
-
`__v__(${JSON.stringify(buildSpecifier)})`,
|
|
190
|
-
);
|
|
191
|
-
}
|
|
192
|
-
if (reference.type === "js_import") {
|
|
193
|
-
if (reference.subtype === "import_dynamic") {
|
|
194
|
-
return asPlaceholderForCodeVersionedByGlobalRegistry(
|
|
195
|
-
`__v__(${JSON.stringify(buildSpecifier)})`,
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
if (reference.subtype === "import_meta_resolve") {
|
|
199
|
-
return asPlaceholderForCodeVersionedByGlobalRegistry(
|
|
200
|
-
`__v__(${JSON.stringify(buildSpecifier)})`,
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
if (canUseImportmap && !isReferencedByWorker(reference)) {
|
|
204
|
-
return asPlaceholderForSpecifierVersionedByImportmap(
|
|
205
|
-
JSON.stringify(buildSpecifier),
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
return asPlaceholderForVersionedSpecifier();
|
|
210
|
-
},
|
|
211
|
-
applyVersioning: async (finalKitchen) => {
|
|
212
|
-
workerReferenceSet.clear();
|
|
213
|
-
|
|
214
|
-
const contentOnlyVersionMap = new Map();
|
|
215
|
-
generate_content_only_versions: {
|
|
216
|
-
GRAPH_VISITOR.forEachUrlInfoStronglyReferenced(
|
|
217
|
-
finalKitchen.graph.rootUrlInfo,
|
|
218
|
-
(urlInfo) => {
|
|
219
|
-
// ignore:
|
|
220
|
-
// - inline files and data files:
|
|
221
|
-
// they are already taken into account in the file where they appear
|
|
222
|
-
// - ignored files:
|
|
223
|
-
// we don't know their content
|
|
224
|
-
// - unused files without reference
|
|
225
|
-
// File updated such as style.css -> style.css.js or file.js->file.nomodule.js
|
|
226
|
-
// Are used at some point just to be discarded later because they need to be converted
|
|
227
|
-
// There is no need to version them and we could not because the file have been ignored
|
|
228
|
-
// so their content is unknown
|
|
229
|
-
if (urlInfo.type === "sourcemap") {
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
if (urlInfo.isInline) {
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
if (urlInfo.url.startsWith("data:")) {
|
|
236
|
-
// urlInfo became inline and is not referenced by something else
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
if (urlInfo.url.startsWith("ignore:")) {
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
let content = urlInfo.content;
|
|
243
|
-
if (urlInfo.type === "html") {
|
|
244
|
-
content = stringifyHtmlAst(
|
|
245
|
-
parseHtmlString(urlInfo.content, {
|
|
246
|
-
storeOriginalPositions: false,
|
|
247
|
-
}),
|
|
248
|
-
{
|
|
249
|
-
cleanupJsenvAttributes: true,
|
|
250
|
-
cleanupPositionAttributes: true,
|
|
251
|
-
},
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
-
if (
|
|
255
|
-
CONTENT_TYPE.isTextual(urlInfo.contentType) &&
|
|
256
|
-
urlInfo.referenceToOthersSet.size > 0
|
|
257
|
-
) {
|
|
258
|
-
const containedPlaceholders = new Set();
|
|
259
|
-
const contentWithPredictibleVersionPlaceholders =
|
|
260
|
-
replaceWithDefaultAndPopulateContainedPlaceholders(
|
|
261
|
-
content,
|
|
262
|
-
containedPlaceholders,
|
|
263
|
-
);
|
|
264
|
-
content = contentWithPredictibleVersionPlaceholders;
|
|
265
|
-
}
|
|
266
|
-
const contentVersion = generateVersion([content], versionLength);
|
|
267
|
-
contentOnlyVersionMap.set(urlInfo, contentVersion);
|
|
268
|
-
},
|
|
269
|
-
);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
generate_versions: {
|
|
273
|
-
const getSetOfUrlInfoInfluencingVersion = (urlInfo) => {
|
|
274
|
-
// there is no need to take into account dependencies
|
|
275
|
-
// when the reference can reference them without version
|
|
276
|
-
// (importmap or window.__v__)
|
|
277
|
-
const setOfUrlInfluencingVersion = new Set();
|
|
278
|
-
const visitDependencies = (urlInfo) => {
|
|
279
|
-
urlInfo.referenceToOthersSet.forEach((referenceToOther) => {
|
|
280
|
-
if (
|
|
281
|
-
referenceVersionedByCodeMap.has(referenceToOther) ||
|
|
282
|
-
referenceVersionedByImportmapMap.has(referenceToOther)
|
|
283
|
-
) {
|
|
284
|
-
// when versioning is dynamic no need to take into account
|
|
285
|
-
// happens for:
|
|
286
|
-
// - specifier mapped by window.__v__()
|
|
287
|
-
// - specifier mapped by importmap
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
const referencedUrlInfo = referenceToOther.urlInfo;
|
|
291
|
-
const referencedContentVersion =
|
|
292
|
-
contentOnlyVersionMap.get(referencedUrlInfo);
|
|
293
|
-
if (!referencedContentVersion) {
|
|
294
|
-
// ignored while traversing graph (not used anymore, inline, ...)
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
if (setOfUrlInfluencingVersion.has(referencedUrlInfo)) {
|
|
298
|
-
// handle circular deps
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
setOfUrlInfluencingVersion.add(referencedUrlInfo);
|
|
302
|
-
visitDependencies(referencedUrlInfo);
|
|
303
|
-
});
|
|
304
|
-
};
|
|
305
|
-
visitDependencies(urlInfo);
|
|
306
|
-
return setOfUrlInfluencingVersion;
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
contentOnlyVersionMap.forEach((contentOnlyVersion, urlInfo) => {
|
|
310
|
-
const setOfUrlInfoInfluencingVersion =
|
|
311
|
-
getSetOfUrlInfoInfluencingVersion(urlInfo);
|
|
312
|
-
const versionPartSet = new Set();
|
|
313
|
-
versionPartSet.add(contentOnlyVersion);
|
|
314
|
-
setOfUrlInfoInfluencingVersion.forEach(
|
|
315
|
-
(urlInfoInfluencingVersion) => {
|
|
316
|
-
const otherUrlInfoContentVersion = contentOnlyVersionMap.get(
|
|
317
|
-
urlInfoInfluencingVersion,
|
|
318
|
-
);
|
|
319
|
-
if (!otherUrlInfoContentVersion) {
|
|
320
|
-
throw new Error(
|
|
321
|
-
`cannot find content version for ${urlInfoInfluencingVersion.url} (used by ${urlInfo.url})`,
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
|
-
versionPartSet.add(otherUrlInfoContentVersion);
|
|
325
|
-
},
|
|
326
|
-
);
|
|
327
|
-
const version = generateVersion(versionPartSet, versionLength);
|
|
328
|
-
versionMap.set(urlInfo, version);
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
replace_version_placeholders: {
|
|
333
|
-
// now replace all placeholders in urlInfos with the real versions
|
|
334
|
-
versionMap.forEach((version, urlInfo) => {
|
|
335
|
-
if (!CONTENT_TYPE.isTextual(urlInfo.contentType)) return;
|
|
336
|
-
if (urlInfo.referenceToOthersSet.size === 0) return;
|
|
337
|
-
|
|
338
|
-
let replacements = [];
|
|
339
|
-
let content = urlInfo.content;
|
|
340
|
-
content.replace(REPLACER_REGEX, (placeholder, index) => {
|
|
341
|
-
const replacement = {
|
|
342
|
-
start: index,
|
|
343
|
-
placeholder,
|
|
344
|
-
value: null,
|
|
345
|
-
valueType: "",
|
|
346
|
-
};
|
|
347
|
-
replacements.push(replacement);
|
|
348
|
-
const reference = placeholderToReferenceMap.get(placeholder);
|
|
349
|
-
|
|
350
|
-
const codeToInject = referenceVersionedByCodeMap.get(reference);
|
|
351
|
-
if (codeToInject) {
|
|
352
|
-
replacement.value = codeToInject;
|
|
353
|
-
replacement.valueType = "code";
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
const specifierToUse =
|
|
357
|
-
referenceVersionedByImportmapMap.get(reference);
|
|
358
|
-
if (specifierToUse) {
|
|
359
|
-
replacement.value = specifierToUse;
|
|
360
|
-
replacement.valueType = "specifier";
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
const version = versionMap.get(reference.urlInfo);
|
|
364
|
-
replacement.value = version;
|
|
365
|
-
replacement.valueType = "specifier";
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
let diff = 0;
|
|
369
|
-
replacements.forEach((replacement) => {
|
|
370
|
-
const placeholder = replacement.placeholder;
|
|
371
|
-
const value = replacement.value;
|
|
372
|
-
let start = replacement.start + diff;
|
|
373
|
-
let end = start + placeholder.length;
|
|
374
|
-
if (
|
|
375
|
-
replacement.valueType === "code" &&
|
|
376
|
-
// when specifier is wrapper by quotes
|
|
377
|
-
// we remove the quotes to transform the string
|
|
378
|
-
// into code that will be executed
|
|
379
|
-
isWrappedByQuote(content, start, end)
|
|
380
|
-
) {
|
|
381
|
-
start = start - 1;
|
|
382
|
-
end = end + 1;
|
|
383
|
-
diff = diff - 2;
|
|
384
|
-
}
|
|
385
|
-
const before = content.slice(0, start);
|
|
386
|
-
const after = content.slice(end);
|
|
387
|
-
content = before + value + after;
|
|
388
|
-
const charAdded = value.length - placeholder.length;
|
|
389
|
-
diff += charAdded;
|
|
390
|
-
});
|
|
391
|
-
urlInfo.content = content;
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
inject_global_registry_and_importmap: {
|
|
396
|
-
const actions = [];
|
|
397
|
-
const visitors = [];
|
|
398
|
-
if (specifierVersionedByCodeSet.size) {
|
|
399
|
-
const versionMappingsNeeded = {};
|
|
400
|
-
specifierVersionedByCodeSet.forEach((buildSpecifier) => {
|
|
401
|
-
versionMappingsNeeded[buildSpecifier] =
|
|
402
|
-
getBuildSpecifierVersioned(buildSpecifier);
|
|
403
|
-
});
|
|
404
|
-
visitors.push((urlInfo) => {
|
|
405
|
-
if (urlInfo.isEntryPoint) {
|
|
406
|
-
actions.push(async () => {
|
|
407
|
-
await injectVersionMappingsAsGlobal(
|
|
408
|
-
urlInfo,
|
|
409
|
-
versionMappingsNeeded,
|
|
410
|
-
);
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
if (specifierVersionedByImportmapSet.size) {
|
|
416
|
-
const versionMappingsNeeded = {};
|
|
417
|
-
specifierVersionedByImportmapSet.forEach((buildSpecifier) => {
|
|
418
|
-
versionMappingsNeeded[buildSpecifier] =
|
|
419
|
-
getBuildSpecifierVersioned(buildSpecifier);
|
|
420
|
-
});
|
|
421
|
-
visitors.push((urlInfo) => {
|
|
422
|
-
if (urlInfo.type === "html" && urlInfo.isEntryPoint) {
|
|
423
|
-
actions.push(async () => {
|
|
424
|
-
await injectVersionMappingsAsImportmap(
|
|
425
|
-
urlInfo,
|
|
426
|
-
versionMappingsNeeded,
|
|
427
|
-
);
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
if (visitors.length) {
|
|
434
|
-
GRAPH_VISITOR.forEach(finalKitchen.graph, (urlInfo) => {
|
|
435
|
-
if (urlInfo.isRoot) return;
|
|
436
|
-
visitors.forEach((visitor) => visitor(urlInfo));
|
|
437
|
-
});
|
|
438
|
-
if (actions.length) {
|
|
439
|
-
await Promise.all(actions.map((action) => action()));
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
},
|
|
444
|
-
getVersion: (urlInfo) => versionMap.get(urlInfo),
|
|
445
|
-
getBuildSpecifierVersioned,
|
|
446
|
-
};
|
|
447
|
-
};
|
|
448
|
-
|
|
449
|
-
const isWrappedByQuote = (content, start, end) => {
|
|
450
|
-
const previousChar = content[start - 1];
|
|
451
|
-
const nextChar = content[end];
|
|
452
|
-
if (previousChar === `'` && nextChar === `'`) {
|
|
453
|
-
return true;
|
|
454
|
-
}
|
|
455
|
-
if (previousChar === `"` && nextChar === `"`) {
|
|
456
|
-
return true;
|
|
457
|
-
}
|
|
458
|
-
if (previousChar === "`" && nextChar === "`") {
|
|
459
|
-
return true;
|
|
460
|
-
}
|
|
461
|
-
return false;
|
|
462
|
-
};
|
|
463
|
-
|
|
464
|
-
// https://github.com/rollup/rollup/blob/19e50af3099c2f627451a45a84e2fa90d20246d5/src/utils/FileEmitter.ts#L47
|
|
465
|
-
// https://github.com/rollup/rollup/blob/5a5391971d695c808eed0c5d7d2c6ccb594fc689/src/Chunk.ts#L870
|
|
466
|
-
export const generateVersion = (parts, length) => {
|
|
467
|
-
const hash = createHash("sha256");
|
|
468
|
-
parts.forEach((part) => {
|
|
469
|
-
hash.update(part);
|
|
470
|
-
});
|
|
471
|
-
return hash.digest("hex").slice(0, length);
|
|
472
|
-
};
|
|
473
|
-
|
|
474
|
-
const injectVersionPlaceholderIntoBuildSpecifier = ({
|
|
475
|
-
buildSpecifier,
|
|
476
|
-
versionPlaceholder,
|
|
477
|
-
versioningMethod,
|
|
478
|
-
}) => {
|
|
479
|
-
if (versioningMethod === "search_param") {
|
|
480
|
-
return injectQueryParamIntoSpecifierWithoutEncoding(
|
|
481
|
-
buildSpecifier,
|
|
482
|
-
"v",
|
|
483
|
-
versionPlaceholder,
|
|
484
|
-
);
|
|
485
|
-
}
|
|
486
|
-
return renderUrlOrRelativeUrlFilename(
|
|
487
|
-
buildSpecifier,
|
|
488
|
-
({ basename, extension }) => {
|
|
489
|
-
return `${basename}-${versionPlaceholder}${extension}`;
|
|
490
|
-
},
|
|
491
|
-
);
|
|
492
|
-
};
|