@jsenv/core 25.0.0 → 25.2.0
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/browser_runtime/browser_runtime_91c5a3b8.js.map +2 -2
- package/dist/build_manifest.js +4 -4
- package/dist/compile_proxy/asset-manifest.json +2 -2
- package/dist/compile_proxy/{compile_proxy_e3b0c442_809f35f7.js.map → compile_proxy.html__inline__20_809f35f7.js.map} +0 -0
- package/dist/compile_proxy/{compile_proxy_7ad5faa6.html → compile_proxy_8dfaee51.html} +3 -4
- package/dist/redirector/asset-manifest.json +2 -2
- package/dist/redirector/{redirector_e3b0c442_e391410e.js.map → redirector.html__inline__15_e391410e.js.map} +0 -0
- package/dist/redirector/{redirector_eb92e8a7.html → redirector_3e9a97b9.html} +3 -4
- package/dist/toolbar/asset-manifest.json +1 -1
- package/dist/toolbar/{toolbar_f7b8a263.html → toolbar_361afb84.html} +2 -3
- package/dist/toolbar_injector/asset-manifest.json +2 -2
- package/dist/toolbar_injector/{toolbar_injector_49e4756e.js → toolbar_injector_fac1e995.js} +2 -2
- package/dist/toolbar_injector/{toolbar_injector_49e4756e.js.map → toolbar_injector_fac1e995.js.map} +2 -2
- package/package.json +8 -8
- package/readme.md +61 -52
- package/src/buildProject.js +21 -13
- package/src/commonJsToJavaScriptModule.js +8 -7
- package/src/execute.js +2 -0
- package/src/executeTestPlan.js +14 -0
- package/src/internal/building/buildUsingRollup.js +4 -2
- package/src/internal/building/build_stats.js +3 -0
- package/src/internal/building/build_url_generator.js +153 -0
- package/src/internal/building/css/parseCssRessource.js +32 -26
- package/src/internal/building/html/parseHtmlRessource.js +109 -91
- package/src/internal/building/js/parseJsRessource.js +5 -13
- package/src/internal/building/parseRessource.js +3 -0
- package/src/internal/building/ressource_builder.js +72 -64
- package/src/internal/building/ressource_builder_util.js +17 -5
- package/src/internal/building/rollup_plugin_jsenv.js +262 -189
- package/src/internal/building/url_fetcher.js +16 -7
- package/src/internal/building/url_loader.js +1 -5
- package/src/internal/building/url_versioning.js +0 -173
- package/src/internal/compiling/babel_plugin_import_metadata.js +7 -11
- package/src/internal/compiling/babel_plugin_proxy_external_imports.js +31 -0
- package/src/internal/compiling/compile-directory/compile-asset.js +8 -4
- package/src/internal/compiling/compile-directory/getOrGenerateCompiledFile.js +43 -8
- package/src/internal/compiling/compile-directory/updateMeta.js +2 -8
- package/src/internal/compiling/compile-directory/validateCache.js +1 -2
- package/src/internal/compiling/compileFile.js +22 -10
- package/src/internal/compiling/compileHtml.js +15 -28
- package/src/internal/compiling/createCompiledFileService.js +22 -24
- package/src/internal/compiling/html_source_file_service.js +18 -19
- package/src/internal/compiling/js-compilation-service/jsenvTransform.js +14 -4
- package/src/internal/compiling/js-compilation-service/transformJs.js +9 -5
- package/src/internal/compiling/jsenvCompilerForHtml.js +534 -263
- package/src/internal/compiling/jsenvCompilerForJavaScript.js +15 -11
- package/src/internal/compiling/startCompileServer.js +83 -20
- package/src/internal/compiling/transformResultToCompilationResult.js +47 -25
- package/src/internal/executing/executePlan.js +2 -0
- package/src/internal/fetchUrl.js +3 -2
- package/src/internal/integrity/integrity_algorithms.js +26 -0
- package/src/internal/integrity/integrity_parsing.js +50 -0
- package/src/internal/integrity/integrity_update.js +23 -0
- package/src/internal/integrity/integrity_validation.js +49 -0
- package/src/internal/jsenvCoreDirectoryUrl.js +2 -0
- package/src/internal/jsenv_remote_directory.js +156 -0
- package/src/internal/origin_directory_converter.js +62 -0
- package/src/internal/response_validation.js +11 -24
- package/src/internal/sourceMappingURLUtils.js +10 -0
- package/src/internal/url_conversion.js +1 -0
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
replaceHtmlNode,
|
|
25
25
|
getHtmlNodeAttributeByName,
|
|
26
26
|
stringifyHtmlAst,
|
|
27
|
-
|
|
27
|
+
getIdForInlineHtmlNode,
|
|
28
28
|
removeHtmlNodeAttribute,
|
|
29
29
|
setHtmlNodeText,
|
|
30
30
|
getHtmlNodeTextNode,
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
stringifySrcset,
|
|
33
33
|
getHtmlNodeLocation,
|
|
34
34
|
removeHtmlNode,
|
|
35
|
+
addHtmlNodeAttribute,
|
|
35
36
|
} from "@jsenv/core/src/internal/compiling/compileHtml.js"
|
|
36
37
|
import {
|
|
37
38
|
getJavaScriptSourceMappingUrl,
|
|
@@ -47,6 +48,7 @@ import { collectNodesMutations } from "../parsing.utils.js"
|
|
|
47
48
|
|
|
48
49
|
import { collectSvgMutations } from "../svg/parseSvgRessource.js"
|
|
49
50
|
import { moveCssUrls } from "../css/moveCssUrls.js"
|
|
51
|
+
import { applyAlgoToRepresentationData } from "../../integrity/integrity_algorithms.js"
|
|
50
52
|
|
|
51
53
|
export const parseHtmlRessource = async (
|
|
52
54
|
htmlRessource,
|
|
@@ -172,20 +174,21 @@ const regularScriptSrcVisitor = (
|
|
|
172
174
|
if (!srcAttribute) {
|
|
173
175
|
return null
|
|
174
176
|
}
|
|
175
|
-
|
|
177
|
+
const integrityAttribute = getHtmlNodeAttributeByName(script, "integrity")
|
|
178
|
+
const integrity = integrityAttribute ? integrityAttribute.value : ""
|
|
176
179
|
const remoteScriptReference = notifyReferenceFound({
|
|
177
180
|
referenceLabel: "html script",
|
|
178
181
|
contentTypeExpected: "application/javascript",
|
|
179
182
|
ressourceSpecifier: srcAttribute.value,
|
|
183
|
+
integrity,
|
|
184
|
+
...crossoriginFromHtmlNode(script),
|
|
180
185
|
...referenceLocationFromHtmlNode(script, "src"),
|
|
181
186
|
})
|
|
182
187
|
return ({ getUrlRelativeToImporter }) => {
|
|
183
188
|
const ressource = remoteScriptReference.ressource
|
|
184
|
-
|
|
185
189
|
if (ressource.isExternal) {
|
|
186
190
|
return
|
|
187
191
|
}
|
|
188
|
-
|
|
189
192
|
if (shouldInline({ ressource, htmlNode: script })) {
|
|
190
193
|
removeHtmlNodeAttribute(script, srcAttribute)
|
|
191
194
|
const { bufferAfterBuild } = ressource
|
|
@@ -200,14 +203,19 @@ const regularScriptSrcVisitor = (
|
|
|
200
203
|
const sourcemapInlineUrl = urlToRelativeUrl(sourcemapBuildUrl, htmlUrl)
|
|
201
204
|
jsString = setJavaScriptSourceMappingUrl(jsString, sourcemapInlineUrl)
|
|
202
205
|
}
|
|
203
|
-
|
|
204
206
|
setHtmlNodeText(script, jsString)
|
|
205
207
|
remoteScriptReference.inlinedCallback()
|
|
206
208
|
return
|
|
207
209
|
}
|
|
208
|
-
|
|
209
210
|
const urlRelativeToImporter = getUrlRelativeToImporter(ressource)
|
|
210
211
|
srcAttribute.value = urlRelativeToImporter
|
|
212
|
+
if (integrityAttribute) {
|
|
213
|
+
const base64Value = applyAlgoToRepresentationData(
|
|
214
|
+
"sha256",
|
|
215
|
+
ressource.bufferAfterBuild,
|
|
216
|
+
)
|
|
217
|
+
integrityAttribute.value = `sha256-${base64Value}`
|
|
218
|
+
}
|
|
211
219
|
}
|
|
212
220
|
}
|
|
213
221
|
|
|
@@ -233,12 +241,10 @@ const regularScriptTextNodeVisitor = (
|
|
|
233
241
|
if (!textNode) {
|
|
234
242
|
return null
|
|
235
243
|
}
|
|
236
|
-
|
|
237
|
-
const ressourceSpecifier =
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
`${urlToFilename(htmlRessource.url)}__inline__[id].js`,
|
|
241
|
-
)
|
|
244
|
+
const scriptId = getIdForInlineHtmlNode(script, scripts)
|
|
245
|
+
const ressourceSpecifier = `${urlToFilename(
|
|
246
|
+
htmlRessource.url,
|
|
247
|
+
)}__inline__${scriptId}.js`
|
|
242
248
|
const jsReference = notifyReferenceFound({
|
|
243
249
|
referenceLabel: "html inline script",
|
|
244
250
|
contentTypeExpected: "application/javascript",
|
|
@@ -266,25 +272,25 @@ const moduleScriptSrcVisitor = (script, { format, notifyReferenceFound }) => {
|
|
|
266
272
|
if (!srcAttribute) {
|
|
267
273
|
return null
|
|
268
274
|
}
|
|
269
|
-
|
|
275
|
+
const integrityAttribute = getHtmlNodeAttributeByName(script, "integrity")
|
|
276
|
+
const integrity = integrityAttribute ? integrityAttribute.value : ""
|
|
270
277
|
const remoteScriptReference = notifyReferenceFound({
|
|
271
278
|
referenceLabel: "html module script",
|
|
272
279
|
contentTypeExpected: "application/javascript",
|
|
273
280
|
ressourceSpecifier: srcAttribute.value,
|
|
281
|
+
integrity,
|
|
282
|
+
...crossoriginFromHtmlNode(script),
|
|
274
283
|
...referenceLocationFromHtmlNode(script, "src"),
|
|
275
284
|
isJsModule: true,
|
|
276
285
|
})
|
|
277
286
|
return ({ getUrlRelativeToImporter }) => {
|
|
278
287
|
const { ressource } = remoteScriptReference
|
|
279
|
-
|
|
280
288
|
if (format === "systemjs") {
|
|
281
289
|
removeHtmlNodeAttribute(script, typeAttribute)
|
|
282
290
|
}
|
|
283
|
-
|
|
284
291
|
if (ressource.isExternal) {
|
|
285
292
|
return
|
|
286
293
|
}
|
|
287
|
-
|
|
288
294
|
if (shouldInline({ ressource, htmlNode: script })) {
|
|
289
295
|
// here put a warning if we cannot inline importmap because it would mess
|
|
290
296
|
// the remapping (note that it's feasible) but not yet supported
|
|
@@ -299,15 +305,20 @@ const moduleScriptSrcVisitor = (script, { format, notifyReferenceFound }) => {
|
|
|
299
305
|
// with these assumptions we can force the sourcemap url
|
|
300
306
|
const sourcemapUrl = `${ressource.buildRelativeUrl}.map`
|
|
301
307
|
jsString = setJavaScriptSourceMappingUrl(jsString, sourcemapUrl)
|
|
302
|
-
|
|
303
308
|
setHtmlNodeText(script, jsString)
|
|
304
309
|
remoteScriptReference.inlinedCallback()
|
|
305
310
|
return
|
|
306
311
|
}
|
|
307
|
-
|
|
308
312
|
const urlRelativeToImporter = getUrlRelativeToImporter(ressource)
|
|
309
313
|
const relativeUrlNotation = ensureRelativeUrlNotation(urlRelativeToImporter)
|
|
310
314
|
srcAttribute.value = relativeUrlNotation
|
|
315
|
+
if (integrityAttribute) {
|
|
316
|
+
const base64Value = applyAlgoToRepresentationData(
|
|
317
|
+
"sha256",
|
|
318
|
+
ressource.bufferAfterBuild,
|
|
319
|
+
)
|
|
320
|
+
integrityAttribute.value = `sha256-${base64Value}`
|
|
321
|
+
}
|
|
311
322
|
}
|
|
312
323
|
}
|
|
313
324
|
|
|
@@ -332,12 +343,10 @@ const moduleScriptTextNodeVisitor = (
|
|
|
332
343
|
if (!textNode) {
|
|
333
344
|
return null
|
|
334
345
|
}
|
|
335
|
-
|
|
336
|
-
const ressourceSpecifier =
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
`${urlToFilename(htmlRessource.url)}__inline__[id].js`,
|
|
340
|
-
)
|
|
346
|
+
const scriptId = getIdForInlineHtmlNode(script, scripts)
|
|
347
|
+
const ressourceSpecifier = `${urlToFilename(
|
|
348
|
+
htmlRessource.url,
|
|
349
|
+
)}__inline__${scriptId}.js`
|
|
341
350
|
const jsReference = notifyReferenceFound({
|
|
342
351
|
referenceLabel: "html inline module script",
|
|
343
352
|
contentTypeExpected: "application/javascript",
|
|
@@ -373,24 +382,24 @@ const importmapScriptSrcVisitor = (
|
|
|
373
382
|
if (!srcAttribute) {
|
|
374
383
|
return null
|
|
375
384
|
}
|
|
376
|
-
|
|
385
|
+
const integrityAttribute = getHtmlNodeAttributeByName(script, "integrity")
|
|
386
|
+
const integrity = integrityAttribute ? integrityAttribute.value : ""
|
|
377
387
|
const importmapReference = notifyReferenceFound({
|
|
378
388
|
referenceLabel: "html importmap",
|
|
379
389
|
contentTypeExpected: "application/importmap+json",
|
|
380
390
|
ressourceSpecifier: srcAttribute.value,
|
|
391
|
+
integrity,
|
|
392
|
+
...crossoriginFromHtmlNode(script),
|
|
381
393
|
...referenceLocationFromHtmlNode(script, "src"),
|
|
382
394
|
})
|
|
383
395
|
return ({ getUrlRelativeToImporter }) => {
|
|
384
396
|
const { ressource } = importmapReference
|
|
385
|
-
|
|
386
397
|
if (format === "systemjs") {
|
|
387
398
|
typeAttribute.value = "systemjs-importmap"
|
|
388
399
|
}
|
|
389
|
-
|
|
390
400
|
if (ressource.isExternal) {
|
|
391
401
|
return
|
|
392
402
|
}
|
|
393
|
-
|
|
394
403
|
if (
|
|
395
404
|
// for esmodule we always inline the importmap
|
|
396
405
|
// as it's the only thing supported by Chrome
|
|
@@ -404,22 +413,22 @@ const importmapScriptSrcVisitor = (
|
|
|
404
413
|
// here put a warning if we cannot inline importmap because it would mess
|
|
405
414
|
// the remapping (note that it's feasible) but not yet supported
|
|
406
415
|
const { bufferAfterBuild } = ressource
|
|
407
|
-
|
|
408
416
|
const importmapString = String(bufferAfterBuild)
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
${importmapString}</script>`,
|
|
413
|
-
{
|
|
414
|
-
attributesToIgnore: ["src"],
|
|
415
|
-
},
|
|
416
|
-
)
|
|
417
|
+
removeHtmlNodeAttribute(script, srcAttribute)
|
|
418
|
+
setHtmlNodeText(script, importmapString)
|
|
419
|
+
removeHtmlNodeAttribute(script, integrityAttribute)
|
|
417
420
|
importmapReference.inlinedCallback()
|
|
418
421
|
return
|
|
419
422
|
}
|
|
420
|
-
|
|
421
423
|
const urlRelativeToImporter = getUrlRelativeToImporter(ressource)
|
|
422
424
|
srcAttribute.value = urlRelativeToImporter
|
|
425
|
+
if (integrityAttribute) {
|
|
426
|
+
const base64Value = applyAlgoToRepresentationData(
|
|
427
|
+
"sha256",
|
|
428
|
+
ressource.bufferAfterBuild,
|
|
429
|
+
)
|
|
430
|
+
integrityAttribute.value = `sha256-${base64Value}`
|
|
431
|
+
}
|
|
423
432
|
}
|
|
424
433
|
}
|
|
425
434
|
|
|
@@ -444,17 +453,14 @@ const importmapScriptTextNodeVisitor = (
|
|
|
444
453
|
if (!textNode) {
|
|
445
454
|
return null
|
|
446
455
|
}
|
|
447
|
-
|
|
456
|
+
const importmapScriptId = getIdForInlineHtmlNode(script, scripts)
|
|
448
457
|
const importmapReference = notifyReferenceFound({
|
|
449
458
|
referenceLabel: "html inline importmap",
|
|
450
459
|
contentTypeExpected: "application/importmap+json",
|
|
451
|
-
ressourceSpecifier:
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
`${urlToFilename(htmlRessource.url)}__inline__[id].importmap`,
|
|
455
|
-
),
|
|
460
|
+
ressourceSpecifier: `${urlToFilename(
|
|
461
|
+
htmlRessource.url,
|
|
462
|
+
)}__inline__${importmapScriptId}.importmap`,
|
|
456
463
|
...referenceLocationFromHtmlNode(script),
|
|
457
|
-
|
|
458
464
|
contentType: "application/importmap+json",
|
|
459
465
|
bufferBeforeBuild: Buffer.from(textNode.value),
|
|
460
466
|
isInline: true,
|
|
@@ -463,7 +469,6 @@ const importmapScriptTextNodeVisitor = (
|
|
|
463
469
|
if (format === "systemjs") {
|
|
464
470
|
typeAttribute.value = "systemjs-importmap"
|
|
465
471
|
}
|
|
466
|
-
|
|
467
472
|
const { bufferAfterBuild } = importmapReference.ressource
|
|
468
473
|
textNode.value = bufferAfterBuild
|
|
469
474
|
}
|
|
@@ -485,38 +490,34 @@ const linkStylesheetHrefVisitor = (
|
|
|
485
490
|
if (relAttribute.value !== "stylesheet") {
|
|
486
491
|
return null
|
|
487
492
|
}
|
|
488
|
-
|
|
493
|
+
const integrityAttribute = getHtmlNodeAttributeByName(link, "integrity")
|
|
494
|
+
const integrity = integrityAttribute ? integrityAttribute.value : ""
|
|
489
495
|
const cssReference = notifyReferenceFound({
|
|
490
496
|
referenceLabel: "html stylesheet link",
|
|
491
497
|
contentTypeExpected: "text/css",
|
|
492
498
|
ressourceSpecifier: hrefAttribute.value,
|
|
499
|
+
integrity,
|
|
500
|
+
...crossoriginFromHtmlNode(link),
|
|
493
501
|
...referenceLocationFromHtmlNode(link, "href"),
|
|
494
502
|
})
|
|
495
|
-
return async ({
|
|
496
|
-
getUrlRelativeToImporter,
|
|
497
|
-
precomputeBuildRelativeUrl,
|
|
498
|
-
buildDirectoryUrl,
|
|
499
|
-
}) => {
|
|
503
|
+
return async ({ getUrlRelativeToImporter, buildDirectoryUrl }) => {
|
|
500
504
|
const { ressource } = cssReference
|
|
501
|
-
|
|
502
505
|
if (ressource.isExternal) {
|
|
503
506
|
return
|
|
504
507
|
}
|
|
505
|
-
|
|
506
508
|
if (shouldInline({ ressource, htmlNode: link })) {
|
|
507
509
|
const { bufferAfterBuild } = ressource
|
|
508
510
|
let code = String(bufferAfterBuild)
|
|
509
511
|
const { buildRelativeUrl } = ressource
|
|
510
512
|
const cssBuildUrl = resolveUrl(buildRelativeUrl, buildDirectoryUrl)
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
+
const htmlBuildUrl = resolveUrl(
|
|
514
|
+
htmlRessource.buildRelativeUrlWithoutHash,
|
|
513
515
|
buildDirectoryUrl,
|
|
514
516
|
)
|
|
515
|
-
|
|
516
517
|
const moveResult = await moveCssUrls({
|
|
517
518
|
code,
|
|
518
519
|
from: cssBuildUrl,
|
|
519
|
-
to:
|
|
520
|
+
to: htmlBuildUrl,
|
|
520
521
|
// moveCssUrls will change the css source code
|
|
521
522
|
// Ideally we should update the sourcemap referenced by css
|
|
522
523
|
// to target the one after css urls are moved.
|
|
@@ -527,24 +528,38 @@ const linkStylesheetHrefVisitor = (
|
|
|
527
528
|
sourcemapMethod: null,
|
|
528
529
|
})
|
|
529
530
|
code = moveResult.code
|
|
530
|
-
|
|
531
531
|
const sourcemapRelativeUrl = getCssSourceMappingUrl(code)
|
|
532
532
|
if (sourcemapRelativeUrl) {
|
|
533
533
|
const cssBuildUrl = resolveUrl(buildRelativeUrl, buildDirectoryUrl)
|
|
534
534
|
const sourcemapBuildUrl = resolveUrl(sourcemapRelativeUrl, cssBuildUrl)
|
|
535
|
-
const sourcemapInlineUrl = urlToRelativeUrl(
|
|
535
|
+
const sourcemapInlineUrl = urlToRelativeUrl(
|
|
536
|
+
sourcemapBuildUrl,
|
|
537
|
+
htmlBuildUrl,
|
|
538
|
+
)
|
|
536
539
|
code = setCssSourceMappingUrl(code, sourcemapInlineUrl)
|
|
537
540
|
}
|
|
538
|
-
|
|
539
541
|
replaceHtmlNode(link, `<style>${code}</style>`, {
|
|
540
|
-
attributesToIgnore: [
|
|
542
|
+
attributesToIgnore: [
|
|
543
|
+
"href",
|
|
544
|
+
"rel",
|
|
545
|
+
"as",
|
|
546
|
+
"crossorigin",
|
|
547
|
+
"type",
|
|
548
|
+
"integrity",
|
|
549
|
+
],
|
|
541
550
|
})
|
|
542
551
|
cssReference.inlinedCallback()
|
|
543
552
|
return
|
|
544
553
|
}
|
|
545
|
-
|
|
546
554
|
const urlRelativeToImporter = getUrlRelativeToImporter(ressource)
|
|
547
555
|
hrefAttribute.value = urlRelativeToImporter
|
|
556
|
+
if (integrityAttribute) {
|
|
557
|
+
const base64Value = applyAlgoToRepresentationData(
|
|
558
|
+
"sha256",
|
|
559
|
+
ressource.bufferAfterBuild,
|
|
560
|
+
)
|
|
561
|
+
integrityAttribute.value = `sha256-${base64Value}`
|
|
562
|
+
}
|
|
548
563
|
}
|
|
549
564
|
}
|
|
550
565
|
|
|
@@ -556,7 +571,6 @@ const linkHrefVisitor = (
|
|
|
556
571
|
if (!hrefAttribute) {
|
|
557
572
|
return null
|
|
558
573
|
}
|
|
559
|
-
|
|
560
574
|
const href = hrefAttribute.value
|
|
561
575
|
const relAttribute = getHtmlNodeAttributeByName(link, "rel")
|
|
562
576
|
const rel = relAttribute ? relAttribute.value : undefined
|
|
@@ -567,7 +581,6 @@ const linkHrefVisitor = (
|
|
|
567
581
|
"preload",
|
|
568
582
|
"modulepreload",
|
|
569
583
|
].includes(rel)
|
|
570
|
-
|
|
571
584
|
let contentTypeExpected
|
|
572
585
|
const typeAttribute = getHtmlNodeAttributeByName(link, "type")
|
|
573
586
|
const type = typeAttribute ? typeAttribute.value : ""
|
|
@@ -580,19 +593,21 @@ const linkHrefVisitor = (
|
|
|
580
593
|
contentTypeExpected = "application/javascript"
|
|
581
594
|
isJsModule = true
|
|
582
595
|
}
|
|
583
|
-
|
|
596
|
+
const integrityAttribute = getHtmlNodeAttributeByName(link, "integrity")
|
|
597
|
+
const integrity = integrityAttribute ? integrityAttribute.value : ""
|
|
584
598
|
const linkReference = notifyReferenceFound({
|
|
585
599
|
referenceLabel: rel ? `html ${rel} link href` : `html link href`,
|
|
586
600
|
isRessourceHint,
|
|
587
601
|
contentTypeExpected,
|
|
588
602
|
ressourceSpecifier: href,
|
|
603
|
+
integrity,
|
|
604
|
+
...crossoriginFromHtmlNode(link),
|
|
589
605
|
...referenceLocationFromHtmlNode(link, "href"),
|
|
590
606
|
urlVersioningDisabled: contentTypeExpected === "application/manifest+json",
|
|
591
607
|
isJsModule,
|
|
592
608
|
})
|
|
593
609
|
return ({ getUrlRelativeToImporter }) => {
|
|
594
610
|
const { ressource } = linkReference
|
|
595
|
-
|
|
596
611
|
if (isRessourceHint) {
|
|
597
612
|
if (isReferencedOnlyByRessourceHint(ressource)) {
|
|
598
613
|
ressourceHintNeverUsedCallback({
|
|
@@ -604,36 +619,34 @@ const linkHrefVisitor = (
|
|
|
604
619
|
// we could remove the HTML node but better keep it untouched and let user decide what to do
|
|
605
620
|
return
|
|
606
621
|
}
|
|
607
|
-
|
|
608
622
|
ressource.inlinedCallbacks.push(() => {
|
|
609
623
|
removeHtmlNode(link)
|
|
610
624
|
})
|
|
611
625
|
}
|
|
612
|
-
|
|
613
626
|
if (ressource.isExternal) {
|
|
614
627
|
return
|
|
615
628
|
}
|
|
616
|
-
|
|
617
629
|
if (format === "systemjs" && rel === "modulepreload") {
|
|
618
630
|
const urlRelativeToImporter = getUrlRelativeToImporter(ressource)
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
)
|
|
631
|
+
relAttribute.value = "preload"
|
|
632
|
+
hrefAttribute.value = urlRelativeToImporter
|
|
633
|
+
addHtmlNodeAttribute(link, { name: "as", value: "script" })
|
|
623
634
|
return
|
|
624
635
|
}
|
|
625
|
-
|
|
626
636
|
if (shouldInline({ ressource, htmlNode: link })) {
|
|
627
|
-
|
|
628
|
-
link,
|
|
629
|
-
`<link href="${getRessourceAsBase64Url(ressource)}" />`,
|
|
630
|
-
)
|
|
637
|
+
removeHtmlNode(link)
|
|
631
638
|
linkReference.inlinedCallback()
|
|
632
639
|
return
|
|
633
640
|
}
|
|
634
|
-
|
|
635
641
|
const urlRelativeToImporter = getUrlRelativeToImporter(ressource)
|
|
636
642
|
hrefAttribute.value = urlRelativeToImporter
|
|
643
|
+
if (integrityAttribute) {
|
|
644
|
+
const base64Value = applyAlgoToRepresentationData(
|
|
645
|
+
"sha256",
|
|
646
|
+
ressource.bufferAfterBuild,
|
|
647
|
+
)
|
|
648
|
+
integrityAttribute.value = `sha256-${base64Value}`
|
|
649
|
+
}
|
|
637
650
|
}
|
|
638
651
|
}
|
|
639
652
|
|
|
@@ -647,17 +660,14 @@ const styleTextNodeVisitor = (
|
|
|
647
660
|
if (!textNode) {
|
|
648
661
|
return null
|
|
649
662
|
}
|
|
650
|
-
|
|
663
|
+
const styleId = getIdForInlineHtmlNode(style, styles)
|
|
651
664
|
const inlineStyleReference = notifyReferenceFound({
|
|
652
665
|
referenceLabel: "html style",
|
|
653
666
|
contentTypeExpected: "text/css",
|
|
654
|
-
ressourceSpecifier:
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
`${urlToFilename(htmlRessource.url)}__inline__[id].css`,
|
|
658
|
-
),
|
|
667
|
+
ressourceSpecifier: `${urlToFilename(
|
|
668
|
+
htmlRessource.url,
|
|
669
|
+
)}__inline__${styleId}.css`,
|
|
659
670
|
...referenceLocationFromHtmlNode(style),
|
|
660
|
-
|
|
661
671
|
contentType: "text/css",
|
|
662
672
|
bufferBeforeBuild: Buffer.from(textNode.value),
|
|
663
673
|
isInline: true,
|
|
@@ -673,10 +683,10 @@ const imgSrcVisitor = (img, { notifyReferenceFound }) => {
|
|
|
673
683
|
if (!srcAttribute) {
|
|
674
684
|
return null
|
|
675
685
|
}
|
|
676
|
-
|
|
677
686
|
const srcReference = notifyReferenceFound({
|
|
678
687
|
referenceLabel: "html img src",
|
|
679
688
|
ressourceSpecifier: srcAttribute.value,
|
|
689
|
+
...crossoriginFromHtmlNode(img),
|
|
680
690
|
...referenceLocationFromHtmlNode(img, "src"),
|
|
681
691
|
})
|
|
682
692
|
return ({ getUrlRelativeToImporter }) => {
|
|
@@ -694,19 +704,18 @@ const srcsetVisitor = (htmlNode, { notifyReferenceFound }) => {
|
|
|
694
704
|
if (!srcsetAttribute) {
|
|
695
705
|
return null
|
|
696
706
|
}
|
|
697
|
-
|
|
698
707
|
const srcsetParts = parseSrcset(srcsetAttribute.value)
|
|
699
708
|
const srcsetPartsReferences = srcsetParts.map(({ specifier }, index) =>
|
|
700
709
|
notifyReferenceFound({
|
|
701
710
|
referenceLabel: `html srcset ${index}`,
|
|
702
711
|
ressourceSpecifier: specifier,
|
|
712
|
+
...crossoriginFromHtmlNode(htmlNode),
|
|
703
713
|
...referenceLocationFromHtmlNode(htmlNode, "srcset"),
|
|
704
714
|
}),
|
|
705
715
|
)
|
|
706
716
|
if (srcsetParts.length === 0) {
|
|
707
717
|
return null
|
|
708
718
|
}
|
|
709
|
-
|
|
710
719
|
return ({ getUrlRelativeToImporter }) => {
|
|
711
720
|
srcsetParts.forEach((srcsetPart, index) => {
|
|
712
721
|
const reference = srcsetPartsReferences[index]
|
|
@@ -727,12 +736,12 @@ const sourceSrcVisitor = (source, { notifyReferenceFound }) => {
|
|
|
727
736
|
if (!srcAttribute) {
|
|
728
737
|
return null
|
|
729
738
|
}
|
|
730
|
-
|
|
731
739
|
const typeAttribute = getHtmlNodeAttributeByName(source, "type")
|
|
732
740
|
const srcReference = notifyReferenceFound({
|
|
733
741
|
referenceLabel: "html source",
|
|
734
742
|
contentTypeExpected: typeAttribute ? typeAttribute.value : undefined,
|
|
735
743
|
ressourceSpecifier: srcAttribute.value,
|
|
744
|
+
...crossoriginFromHtmlNode(source),
|
|
736
745
|
...referenceLocationFromHtmlNode(source, "src"),
|
|
737
746
|
})
|
|
738
747
|
return ({ getUrlRelativeToImporter }) => {
|
|
@@ -757,6 +766,15 @@ const referenceToUrl = ({ reference, htmlNode, getUrlRelativeToImporter }) => {
|
|
|
757
766
|
return getUrlRelativeToImporter(ressource)
|
|
758
767
|
}
|
|
759
768
|
|
|
769
|
+
const crossoriginFromHtmlNode = (htmlNode) => {
|
|
770
|
+
const crossOriginAttribute = getHtmlNodeAttributeByName(
|
|
771
|
+
htmlNode,
|
|
772
|
+
"crossorigin",
|
|
773
|
+
)
|
|
774
|
+
const crossorigin = crossOriginAttribute ? crossOriginAttribute.value : ""
|
|
775
|
+
return { crossorigin }
|
|
776
|
+
}
|
|
777
|
+
|
|
760
778
|
const referenceLocationFromHtmlNode = (htmlNode, htmlAttributeName) => {
|
|
761
779
|
const locInfo = getHtmlNodeLocation(htmlNode, htmlAttributeName)
|
|
762
780
|
return locInfo
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { urlToFilename, resolveUrl, urlToRelativeUrl } from "@jsenv/filesystem"
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
generateSourcemapUrl,
|
|
4
5
|
getJavaScriptSourceMappingUrl,
|
|
5
6
|
setJavaScriptSourceMappingUrl,
|
|
6
7
|
} from "@jsenv/core/src/internal/sourceMappingURLUtils.js"
|
|
@@ -14,8 +15,8 @@ export const parseJsRessource = async (
|
|
|
14
15
|
const jsUrl = jsRessource.url
|
|
15
16
|
const jsString = String(jsRessource.bufferBeforeBuild)
|
|
16
17
|
const jsSourcemapUrl = getJavaScriptSourceMappingUrl(jsString)
|
|
17
|
-
let sourcemapReference
|
|
18
18
|
|
|
19
|
+
let sourcemapReference
|
|
19
20
|
if (jsSourcemapUrl) {
|
|
20
21
|
sourcemapReference = notifyReferenceFound({
|
|
21
22
|
referenceLabel: "js sourcemapping comment",
|
|
@@ -32,7 +33,7 @@ export const parseJsRessource = async (
|
|
|
32
33
|
sourcemapReference = notifyReferenceFound({
|
|
33
34
|
referenceLabel: "js sourcemapping comment",
|
|
34
35
|
contentType: "application/octet-stream",
|
|
35
|
-
ressourceSpecifier:
|
|
36
|
+
ressourceSpecifier: urlToRelativeUrl(generateSourcemapUrl(jsUrl), jsUrl),
|
|
36
37
|
isPlaceholder: true,
|
|
37
38
|
isSourcemap: true,
|
|
38
39
|
})
|
|
@@ -40,7 +41,6 @@ export const parseJsRessource = async (
|
|
|
40
41
|
|
|
41
42
|
return async ({ buildDirectoryUrl }) => {
|
|
42
43
|
const sourcemapRessource = sourcemapReference.ressource
|
|
43
|
-
|
|
44
44
|
let code
|
|
45
45
|
let map
|
|
46
46
|
if (!sourcemapRessource.isPlaceholder) {
|
|
@@ -76,13 +76,10 @@ export const parseJsRessource = async (
|
|
|
76
76
|
code = result.code
|
|
77
77
|
map = result.map
|
|
78
78
|
}
|
|
79
|
-
|
|
80
79
|
jsRessource.buildEnd(code)
|
|
81
|
-
|
|
82
80
|
if (!map) {
|
|
83
81
|
return
|
|
84
82
|
}
|
|
85
|
-
|
|
86
83
|
// In theory code should never be modified once buildEnd() is called
|
|
87
84
|
// because buildRelativeUrl might be versioned based on file content
|
|
88
85
|
// There is an exception for sourcemap because we want to update sourcemap.file
|
|
@@ -95,16 +92,12 @@ export const parseJsRessource = async (
|
|
|
95
92
|
jsRessource.buildRelativeUrl,
|
|
96
93
|
buildDirectoryUrl,
|
|
97
94
|
)
|
|
98
|
-
const sourcemapPrecomputedBuildUrl =
|
|
99
|
-
`${urlToFilename(jsBuildUrl)}.map`,
|
|
100
|
-
jsBuildUrl,
|
|
101
|
-
)
|
|
102
|
-
|
|
95
|
+
const sourcemapPrecomputedBuildUrl = generateSourcemapUrl(jsBuildUrl)
|
|
103
96
|
map.file = urlToFilename(jsBuildUrl)
|
|
104
97
|
if (map.sources) {
|
|
105
98
|
map.sources = map.sources.map((source) => {
|
|
106
99
|
const sourceUrl = resolveUrl(source, jsUrl)
|
|
107
|
-
const sourceOriginalUrl = asOriginalUrl(sourceUrl)
|
|
100
|
+
const sourceOriginalUrl = asOriginalUrl(sourceUrl) || sourceUrl
|
|
108
101
|
const sourceUrlRelativeToSourceMap = urlToRelativeUrl(
|
|
109
102
|
sourceOriginalUrl,
|
|
110
103
|
sourcemapPrecomputedBuildUrl,
|
|
@@ -114,7 +107,6 @@ export const parseJsRessource = async (
|
|
|
114
107
|
}
|
|
115
108
|
const mapAsText = JSON.stringify(map, null, " ")
|
|
116
109
|
sourcemapRessource.buildEnd(mapAsText)
|
|
117
|
-
|
|
118
110
|
const sourcemapBuildUrl = resolveUrl(
|
|
119
111
|
sourcemapRessource.buildRelativeUrl,
|
|
120
112
|
buildDirectoryUrl,
|
|
@@ -27,6 +27,7 @@ export const parseRessource = async (
|
|
|
27
27
|
notifiers,
|
|
28
28
|
{
|
|
29
29
|
projectDirectoryUrl,
|
|
30
|
+
jsenvRemoteDirectory,
|
|
30
31
|
format,
|
|
31
32
|
systemJsUrl,
|
|
32
33
|
asProjectUrl,
|
|
@@ -125,6 +126,7 @@ export const parseRessource = async (
|
|
|
125
126
|
|
|
126
127
|
if (contentType === "text/css") {
|
|
127
128
|
return parseCssRessource(ressource, notifiers, {
|
|
129
|
+
jsenvRemoteDirectory,
|
|
128
130
|
asProjectUrl,
|
|
129
131
|
asOriginalUrl,
|
|
130
132
|
asOriginalServerUrl,
|
|
@@ -156,6 +158,7 @@ export const parseRessource = async (
|
|
|
156
158
|
) {
|
|
157
159
|
return parseJsRessource(ressource, notifiers, {
|
|
158
160
|
projectDirectoryUrl,
|
|
161
|
+
jsenvRemoteDirectory,
|
|
159
162
|
asProjectUrl,
|
|
160
163
|
asOriginalUrl,
|
|
161
164
|
asOriginalServerUrl,
|