@jsenv/core 25.1.1 → 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.
Files changed (58) hide show
  1. package/dist/browser_runtime/browser_runtime_91c5a3b8.js.map +2 -2
  2. package/dist/build_manifest.js +4 -4
  3. package/dist/compile_proxy/asset-manifest.json +2 -2
  4. package/dist/compile_proxy/{compile_proxy_e3b0c442_809f35f7.js.map → compile_proxy.html__inline__20_809f35f7.js.map} +0 -0
  5. package/dist/compile_proxy/{compile_proxy_7ad5faa6.html → compile_proxy_8dfaee51.html} +3 -4
  6. package/dist/redirector/asset-manifest.json +2 -2
  7. package/dist/redirector/{redirector_e3b0c442_e391410e.js.map → redirector.html__inline__15_e391410e.js.map} +0 -0
  8. package/dist/redirector/{redirector_eb92e8a7.html → redirector_3e9a97b9.html} +3 -4
  9. package/dist/toolbar/asset-manifest.json +1 -1
  10. package/dist/toolbar/{toolbar_f7b8a263.html → toolbar_361afb84.html} +2 -3
  11. package/dist/toolbar_injector/asset-manifest.json +2 -2
  12. package/dist/toolbar_injector/{toolbar_injector_49e4756e.js → toolbar_injector_fac1e995.js} +2 -2
  13. package/dist/toolbar_injector/{toolbar_injector_49e4756e.js.map → toolbar_injector_fac1e995.js.map} +2 -2
  14. package/package.json +7 -7
  15. package/readme.md +43 -49
  16. package/src/buildProject.js +21 -13
  17. package/src/commonJsToJavaScriptModule.js +8 -7
  18. package/src/execute.js +2 -0
  19. package/src/executeTestPlan.js +4 -1
  20. package/src/internal/building/buildUsingRollup.js +4 -2
  21. package/src/internal/building/build_stats.js +3 -0
  22. package/src/internal/building/build_url_generator.js +153 -0
  23. package/src/internal/building/css/parseCssRessource.js +32 -26
  24. package/src/internal/building/html/parseHtmlRessource.js +92 -68
  25. package/src/internal/building/js/parseJsRessource.js +4 -7
  26. package/src/internal/building/parseRessource.js +3 -0
  27. package/src/internal/building/ressource_builder.js +64 -62
  28. package/src/internal/building/ressource_builder_util.js +17 -5
  29. package/src/internal/building/rollup_plugin_jsenv.js +259 -189
  30. package/src/internal/building/url_fetcher.js +16 -7
  31. package/src/internal/building/url_loader.js +1 -5
  32. package/src/internal/building/url_versioning.js +0 -173
  33. package/src/internal/compiling/babel_plugin_import_metadata.js +7 -11
  34. package/src/internal/compiling/babel_plugin_proxy_external_imports.js +31 -0
  35. package/src/internal/compiling/compile-directory/compile-asset.js +8 -4
  36. package/src/internal/compiling/compile-directory/getOrGenerateCompiledFile.js +43 -8
  37. package/src/internal/compiling/compile-directory/updateMeta.js +2 -8
  38. package/src/internal/compiling/compile-directory/validateCache.js +1 -2
  39. package/src/internal/compiling/compileFile.js +22 -10
  40. package/src/internal/compiling/createCompiledFileService.js +22 -24
  41. package/src/internal/compiling/html_source_file_service.js +9 -9
  42. package/src/internal/compiling/js-compilation-service/jsenvTransform.js +14 -4
  43. package/src/internal/compiling/js-compilation-service/transformJs.js +9 -5
  44. package/src/internal/compiling/jsenvCompilerForHtml.js +221 -182
  45. package/src/internal/compiling/jsenvCompilerForJavaScript.js +15 -11
  46. package/src/internal/compiling/startCompileServer.js +79 -19
  47. package/src/internal/compiling/transformResultToCompilationResult.js +47 -25
  48. package/src/internal/executing/executePlan.js +2 -0
  49. package/src/internal/fetchUrl.js +3 -2
  50. package/src/internal/integrity/integrity_algorithms.js +26 -0
  51. package/src/internal/integrity/integrity_parsing.js +50 -0
  52. package/src/internal/integrity/integrity_update.js +23 -0
  53. package/src/internal/integrity/integrity_validation.js +49 -0
  54. package/src/internal/jsenv_remote_directory.js +156 -0
  55. package/src/internal/origin_directory_converter.js +62 -0
  56. package/src/internal/response_validation.js +11 -24
  57. package/src/internal/sourceMappingURLUtils.js +10 -0
  58. package/src/internal/url_conversion.js +1 -0
@@ -0,0 +1,153 @@
1
+ import { urlToBasename, urlToExtension } from "@jsenv/filesystem"
2
+
3
+ import { generateContentHash } from "./url_versioning.js"
4
+
5
+ export const createBuildUrlGenerator = ({
6
+ entryPointUrls,
7
+ asOriginalUrl,
8
+ lineBreakNormalization,
9
+ }) => {
10
+ const availableNameGenerator = createAvailableNameGenerator()
11
+
12
+ const prepareBuildUrlForRessource = (ressource) => {
13
+ const buildRelativeUrlPattern = getBuildRelativeUrlPattern({
14
+ entryPointUrls,
15
+ asOriginalUrl,
16
+ availableNameGenerator,
17
+ ressource,
18
+ })
19
+ const buildRelativeUrlWithoutHash = buildRelativeUrlPattern.replace(
20
+ "_[hash]",
21
+ "",
22
+ )
23
+ return {
24
+ buildRelativeUrlPattern,
25
+ buildRelativeUrlWithoutHash,
26
+ }
27
+ }
28
+
29
+ const computeBuildRelativeUrl = (ressource) => {
30
+ const buildRelativeUrl = renderFileNamePattern(
31
+ ressource.buildRelativeUrlPattern,
32
+ {
33
+ hash: () =>
34
+ generateContentHash(ressource.bufferAfterBuild, {
35
+ contentType: ressource.contentType,
36
+ lineBreakNormalization,
37
+ }),
38
+ },
39
+ )
40
+ return buildRelativeUrl
41
+ }
42
+
43
+ return { prepareBuildUrlForRessource, computeBuildRelativeUrl }
44
+ }
45
+
46
+ const getBuildRelativeUrlPattern = ({
47
+ entryPointUrls,
48
+ asOriginalUrl,
49
+ availableNameGenerator,
50
+ ressource,
51
+ }) => {
52
+ if (ressource.isEntryPoint) {
53
+ const originalUrl = asOriginalUrl(ressource.url)
54
+ const entryPointBuildRelativeUrlPattern = entryPointUrls[originalUrl]
55
+ return entryPointBuildRelativeUrlPattern
56
+ }
57
+
58
+ // inline ressource
59
+ // TODO: should inherit importer directory location because inline
60
+ if (ressource.isInline) {
61
+ // const importerBuildRelativeUrlWithoutHash =
62
+ // ressource.importer.buildRelativeUrlWithoutHash
63
+ const name = urlToBasename(ressource.url)
64
+ const extension = urlToExtension(ressource.url)
65
+ // no need to ensure name is unique because it's already done
66
+ return `${name}_[hash]${extension}`
67
+ }
68
+
69
+ // importmap.
70
+ // the goal is to put the importmap at the same relative path
71
+ // than in the project to avoid having to re-resolve mappings
72
+ if (ressource.contentType === "application/importmap+json") {
73
+ const name = availableNameGenerator.getAvailableNameInDirectory(
74
+ urlToBasename(ressource.url),
75
+ "/",
76
+ )
77
+ const extension = urlToExtension(ressource.url)
78
+ return `${name}_[hash]${extension}`
79
+ }
80
+
81
+ // service worker:
82
+ // - MUST be at the root (same level than the HTML file)
83
+ // otherwise it might be registered for the scope "/assets/" instead of "/"
84
+ // - MUST not be versioned
85
+ if (ressource.isServiceWorker) {
86
+ const name = availableNameGenerator.getAvailableNameInDirectory(
87
+ urlToBasename(ressource.url),
88
+ "/",
89
+ )
90
+ const extension = urlToExtension(ressource.url)
91
+ return `${name}${extension}`
92
+ }
93
+
94
+ if (ressource.isWorker) {
95
+ const name = availableNameGenerator.getAvailableNameInDirectory(
96
+ urlToBasename(ressource.url),
97
+ "/",
98
+ )
99
+ const extension = urlToExtension(ressource.url)
100
+ return `${name}_[hash]${extension}`
101
+ }
102
+
103
+ if (ressource.isJsModule) {
104
+ const name = availableNameGenerator.getAvailableNameInDirectory(
105
+ urlToBasename(ressource.url),
106
+ "/",
107
+ )
108
+ return `${name}_[hash].js`
109
+ }
110
+
111
+ const name = availableNameGenerator.getAvailableNameInDirectory(
112
+ urlToBasename(ressource.url),
113
+ "assets/",
114
+ )
115
+ const extension = urlToExtension(ressource.url)
116
+ return ressource.urlVersioningDisabled
117
+ ? `assets/${name}${extension}`
118
+ : `assets/${name}_[hash]${extension}`
119
+ }
120
+
121
+ const createAvailableNameGenerator = () => {
122
+ const cache = {}
123
+ const getAvailableNameInDirectory = (name, directory) => {
124
+ let names = cache[directory]
125
+ if (!names) {
126
+ names = []
127
+ cache[directory] = names
128
+ }
129
+
130
+ let nameCandidate = name
131
+ let integer = 1
132
+ // eslint-disable-next-line no-constant-condition
133
+ while (true) {
134
+ if (!names.includes(nameCandidate)) {
135
+ names.push(nameCandidate)
136
+ return nameCandidate
137
+ }
138
+ integer++
139
+ nameCandidate = `${name}${integer}`
140
+ }
141
+ }
142
+
143
+ return {
144
+ getAvailableNameInDirectory,
145
+ }
146
+ }
147
+
148
+ const renderFileNamePattern = (pattern, replacements) => {
149
+ return pattern.replace(/\[(\w+)\]/g, (_match, type) => {
150
+ const replacement = replacements[type](_match)
151
+ return replacement
152
+ })
153
+ }
@@ -6,6 +6,7 @@ import {
6
6
  } from "@jsenv/filesystem"
7
7
 
8
8
  import {
9
+ generateSourcemapUrl,
9
10
  getCssSourceMappingUrl,
10
11
  setCssSourceMappingUrl,
11
12
  } from "@jsenv/core/src/internal/sourceMappingURLUtils.js"
@@ -17,11 +18,18 @@ import { moveCssUrls } from "./moveCssUrls.js"
17
18
  export const parseCssRessource = async (
18
19
  cssRessource,
19
20
  { notifyReferenceFound },
20
- { asProjectUrl, asOriginalUrl, minify, minifyCssOptions, cssConcatenation },
21
+ {
22
+ jsenvRemoteDirectory,
23
+ asProjectUrl,
24
+ asOriginalUrl,
25
+ minify,
26
+ minifyCssOptions,
27
+ cssConcatenation,
28
+ },
21
29
  ) => {
22
30
  const cssString = String(cssRessource.bufferBeforeBuild)
23
31
  const cssSourcemapUrl = getCssSourceMappingUrl(cssString)
24
- const url = cssRessource.url
32
+ const cssUrl = cssRessource.url
25
33
  let code = cssString
26
34
  let map
27
35
  let sourcemapReference
@@ -42,7 +50,10 @@ export const parseCssRessource = async (
42
50
  sourcemapReference = notifyReferenceFound({
43
51
  referenceLabel: "css sourcemaping comment",
44
52
  contentType: "application/octet-stream",
45
- ressourceSpecifier: `${urlToFilename(cssRessource.url)}.map`,
53
+ ressourceSpecifier: urlToRelativeUrl(
54
+ generateSourcemapUrl(cssUrl),
55
+ cssUrl,
56
+ ),
46
57
  isPlaceholder: true,
47
58
  isSourcemap: true,
48
59
  })
@@ -50,7 +61,7 @@ export const parseCssRessource = async (
50
61
 
51
62
  const { atImports, urlDeclarations } = await parseCssUrls({
52
63
  code,
53
- url,
64
+ url: cssUrl,
54
65
  })
55
66
  const urlNodeReferenceMapping = new Map()
56
67
  const atImportReferences = []
@@ -75,11 +86,7 @@ export const parseCssRessource = async (
75
86
  urlNodeReferenceMapping.set(urlDeclaration.urlNode, urlReference)
76
87
  })
77
88
 
78
- return async ({
79
- getUrlRelativeToImporter,
80
- precomputeBuildRelativeUrl,
81
- buildDirectoryUrl,
82
- }) => {
89
+ return async ({ getUrlRelativeToImporter, buildDirectoryUrl }) => {
83
90
  const sourcemapRessource = sourcemapReference.ressource
84
91
  const cssCompiledUrl = cssRessource.url
85
92
  const cssOriginalUrl = asOriginalUrl(cssCompiledUrl)
@@ -96,16 +103,13 @@ export const parseCssRessource = async (
96
103
  if (!urlNodeFound) {
97
104
  return urlNode.value
98
105
  }
99
-
100
106
  // url node nous dit quel référence y correspond
101
107
  const urlNodeReference = urlNodeReferenceMapping.get(urlNodeFound)
102
108
  const cssUrlRessource = urlNodeReference.ressource
103
-
104
109
  const { isExternal } = cssUrlRessource
105
110
  if (isExternal) {
106
111
  return urlNode.value
107
112
  }
108
-
109
113
  const { isInline } = cssUrlRessource
110
114
  if (isInline) {
111
115
  return getRessourceAsBase64Url(cssUrlRessource)
@@ -126,16 +130,18 @@ export const parseCssRessource = async (
126
130
  )
127
131
  atImportReference.inlinedCallback()
128
132
  let code = String(atImportReference.ressource.bufferAfterBuild)
133
+ const from = resolveUrl(
134
+ atImportReference.ressource.buildRelativeUrl,
135
+ buildDirectoryUrl,
136
+ )
137
+ const to = resolveUrl(
138
+ cssRessource.buildRelativeUrlWithoutHash,
139
+ buildDirectoryUrl,
140
+ )
129
141
  const moveResult = await moveCssUrls({
130
142
  code,
131
- from: resolveUrl(
132
- atImportReference.ressource.buildRelativeUrl,
133
- buildDirectoryUrl,
134
- ),
135
- to: resolveUrl(
136
- precomputeBuildRelativeUrl(cssRessource),
137
- buildDirectoryUrl,
138
- ),
143
+ from,
144
+ to,
139
145
  // moveCssUrls will change the css source code
140
146
  // Ideally we should update the sourcemap referenced by css
141
147
  // to target the one after css urls are moved.
@@ -153,7 +159,6 @@ export const parseCssRessource = async (
153
159
  })
154
160
  code = replaceCssResult.code
155
161
  map = replaceCssResult.map
156
-
157
162
  cssRessource.buildEnd(code)
158
163
 
159
164
  // In theory code should never be modified once buildEnd() is called
@@ -168,15 +173,16 @@ export const parseCssRessource = async (
168
173
  cssRessource.buildRelativeUrl,
169
174
  buildDirectoryUrl,
170
175
  )
171
- const sourcemapPrecomputedBuildUrl = resolveUrl(
172
- `${urlToFilename(cssBuildUrl)}.map`,
173
- cssBuildUrl,
174
- )
175
-
176
+ const sourcemapPrecomputedBuildUrl = generateSourcemapUrl(cssBuildUrl)
176
177
  map.file = urlToFilename(cssBuildUrl)
177
178
  if (map.sources) {
178
179
  map.sources = map.sources.map((source) => {
179
180
  const sourceUrl = resolveUrl(source, cssOriginalUrl)
181
+ if (jsenvRemoteDirectory.isFileUrlForRemoteUrl(sourceUrl)) {
182
+ const sourceRemoteUrl =
183
+ jsenvRemoteDirectory.remoteUrlFromFileUrl(sourceUrl)
184
+ return sourceRemoteUrl
185
+ }
180
186
  const sourceUrlRelativeToSourceMap = urlToRelativeUrl(
181
187
  sourceUrl,
182
188
  sourcemapPrecomputedBuildUrl,