@jsenv/core 24.6.5 → 25.0.0-alpha.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 (49) hide show
  1. package/dist/browser_runtime/asset-manifest.json +2 -1
  2. package/dist/browser_runtime/{browser_runtime-bb0e3aa4.js → browser_runtime_a8097085.js} +1 -1
  3. package/dist/browser_runtime/{browser_runtime-bb0e3aa4.js.map → browser_runtime_a8097085.js.map} +1 -1
  4. package/dist/build_manifest.js +6 -6
  5. package/dist/compile_proxy/asset-manifest.json +2 -1
  6. package/dist/compile_proxy/{compile_proxy-6eb67db4.html → compile_proxy_e16d7de8.html} +2 -2
  7. package/dist/compile_proxy/{compile_proxy.html__inline__20-9e168143.js.map → compile_proxy_e3b0c442_9e168143.js.map} +0 -0
  8. package/dist/event_source_client/asset-manifest.json +2 -1
  9. package/dist/event_source_client/{event_source_client-9f14c8b9.js → event_source_client_620fbc2c.js} +1 -1
  10. package/dist/event_source_client/{event_source_client-9f14c8b9.js.map → event_source_client_620fbc2c.js.map} +1 -1
  11. package/dist/redirector/asset-manifest.json +2 -1
  12. package/dist/redirector/{redirector-b6ad84bf.html → redirector_2e0c8abe.html} +2 -2
  13. package/dist/redirector/{redirector.html__inline__15-3a34a156.js.map → redirector_e3b0c442_3a34a156.js.map} +0 -0
  14. package/dist/toolbar/asset-manifest.json +11 -10
  15. package/dist/toolbar/assets/{compilation.css-209d68b4.map → compilation.css_e37c747b.map} +1 -1
  16. package/dist/toolbar/assets/{eventsource.css-38cd0a36.map → eventsource.css_c0c71e7b.map} +1 -1
  17. package/dist/toolbar/assets/{execution.css-0ebe522f.map → execution.css_f3377c10.map} +1 -1
  18. package/dist/toolbar/assets/{focus.css-3f9c156d.map → focus.css_896f3e45.map} +1 -1
  19. package/dist/toolbar/assets/{light-theme.css-78b19a80.map → light-theme.css_72a60fa3.map} +1 -1
  20. package/dist/toolbar/assets/{overflow-menu.css-d9688a1c.map → overflow-menu.css_2859d519.map} +1 -1
  21. package/dist/toolbar/assets/{settings.css-2b81b245.map → settings.css_61548139.map} +1 -1
  22. package/dist/toolbar/assets/{toolbar.main.css-846920e9.map → toolbar.main.css_269d7ce2.map} +9 -9
  23. package/dist/toolbar/assets/{tooltip.css-03395ee6.map → tooltip.css_a94a8bdd.map} +1 -1
  24. package/dist/toolbar/{toolbar.main-a5ef2c60.js.map → toolbar.main_a5ef2c60.js.map} +0 -0
  25. package/dist/toolbar/{toolbar-1fbf8dcb.html → toolbar_412abb83.html} +3 -5
  26. package/dist/toolbar_injector/asset-manifest.json +3 -2
  27. package/dist/toolbar_injector/assets/{jsenv-logo-188b9ca6.svg → jsenv-logo_188b9ca6.svg} +0 -0
  28. package/dist/toolbar_injector/{toolbar_injector-997dbaa0.js → toolbar_injector_4f9c19e5.js} +3 -3
  29. package/dist/toolbar_injector/{toolbar_injector-997dbaa0.js.map → toolbar_injector_4f9c19e5.js.map} +2 -2
  30. package/package.json +1 -1
  31. package/readme.md +2 -2
  32. package/src/buildProject.js +18 -16
  33. package/src/internal/building/buildUsingRollup.js +9 -7
  34. package/src/internal/building/build_logs.js +2 -2
  35. package/src/internal/building/build_stats.js +11 -1
  36. package/src/internal/building/html/parseHtmlRessource.js +2 -26
  37. package/src/internal/building/js/parseJsRessource.js +3 -2
  38. package/src/internal/building/json_module.js +11 -0
  39. package/src/internal/building/parseRessource.js +1 -1
  40. package/src/internal/building/ressource_builder.js +216 -215
  41. package/src/internal/building/rollup_plugin_jsenv.js +462 -306
  42. package/src/internal/building/url_loader.js +8 -145
  43. package/src/internal/building/url_versioning.js +226 -0
  44. package/src/internal/compiling/compileHtml.js +8 -1
  45. package/src/jsenvServiceWorkerFinalizer.js +7 -8
  46. package/src/internal/building/asset_url_versioning.js +0 -50
  47. package/src/internal/building/rollup_build_sourcemap.js +0 -54
  48. package/src/internal/building/url-versioning.js +0 -96
  49. package/src/internal/renderNamePattern.js +0 -6
@@ -1,17 +1,12 @@
1
- import { resolveUrl, urlToFilename } from "@jsenv/filesystem"
2
-
3
- import { transformJs } from "@jsenv/core/src/internal/compiling/js-compilation-service/transformJs.js"
4
- import { convertCssTextToJavascriptModule } from "@jsenv/core/src/internal/building/css_module.js"
1
+ import { convertJsonTextToJavascriptModule } from "@jsenv/core/src/internal/building/json_module.js"
5
2
  import { getJavaScriptSourceMappingUrl } from "@jsenv/core/src/internal/sourceMappingURLUtils.js"
3
+
6
4
  import { loadSourcemap } from "./sourcemap_loader.js"
7
5
 
8
6
  export const createUrlLoader = ({
9
- projectDirectoryUrl,
10
- buildDirectoryUrl,
11
- babelPluginMap,
7
+ urlCustomLoaders,
12
8
  allowJson,
13
9
  urlImporterMap,
14
- inlineModuleScripts,
15
10
 
16
11
  asServerUrl,
17
12
  asProjectUrl,
@@ -21,115 +16,13 @@ export const createUrlLoader = ({
21
16
  }) => {
22
17
  const urlResponseBodyMap = {}
23
18
 
24
- const loadUrl = async (rollupUrl, { signal, logger, ressourceBuilder }) => {
19
+ const loadUrl = async (rollupUrl, { signal, logger }) => {
25
20
  let url = asServerUrl(rollupUrl)
26
- const { importType, urlWithoutImportType } = extractImportTypeFromUrl(url)
27
- // importing CSS from JS with import assertions
28
- if (importType === "css") {
29
- const importer = urlImporterMap[url]
30
- const cssReference =
31
- await ressourceBuilder.createReferenceFoundInJsModule({
32
- referenceLabel: "css import assertion",
33
- // If all references to a ressource are only import assertions
34
- // the file referenced do not need to be written on filesystem
35
- // as it was converted to a js file
36
- // We pass "isImportAssertion: true" for this purpose
37
- isImportAssertion: true,
38
- jsUrl: importer.url,
39
- jsLine: importer.line,
40
- jsColumn: importer.column,
41
- ressourceSpecifier: urlWithoutImportType,
42
- contentTypeExpected: "text/css",
43
- })
44
- await cssReference.ressource.getReadyPromise()
45
- const cssBuildUrl = resolveUrl(
46
- cssReference.ressource.buildRelativeUrl,
47
- buildDirectoryUrl,
48
- )
49
- const jsBuildUrl = resolveUrl(
50
- urlToFilename(importer.url),
51
- buildDirectoryUrl,
52
- )
53
- let code = String(cssReference.ressource.bufferAfterBuild)
54
- let map
55
- const sourcemapReference = cssReference.ressource.dependencies.find(
56
- (dependency) => {
57
- return dependency.ressource.isSourcemap
58
- },
59
- )
60
- if (sourcemapReference) {
61
- // because css is ready, it's sourcemap is also ready
62
- // we can read directly sourcemapReference.ressource.bufferAfterBuild
63
- map = JSON.parse(sourcemapReference.ressource.bufferAfterBuild)
64
- }
65
-
66
- const jsModuleConversionResult = await convertCssTextToJavascriptModule({
67
- cssUrl: cssBuildUrl,
68
- jsUrl: jsBuildUrl,
69
- code,
70
- map,
71
- })
72
- code = jsModuleConversionResult.code
73
- map = jsModuleConversionResult.map
74
-
75
- return {
76
- url,
77
- code,
78
- map,
79
- }
80
- }
81
- // importing json from JS with import assertion
82
- if (importType === "json") {
83
- const importer = urlImporterMap[url]
84
- const jsonReference =
85
- await ressourceBuilder.createReferenceFoundInJsModule({
86
- referenceLabel: "json import assertion",
87
- // If all references to a ressource are only import assertions
88
- // the file referenced do not need to be written on filesystem
89
- // as it was converted to a js file
90
- // We pass "isImportAssertion: true" for this purpose
91
- isImportAssertion: true,
92
- jsUrl: importer.url,
93
- jsLine: importer.line,
94
- jsColumn: importer.column,
95
- ressourceSpecifier: asServerUrl(urlWithoutImportType),
96
- contentTypeExpected: "application/json",
97
- })
98
- await jsonReference.ressource.getReadyPromise()
99
- let code = String(jsonReference.ressource.bufferAfterBuild)
100
- let map
101
-
102
- const jsModuleConversionResult = await convertJsonTextToJavascriptModule({
103
- code,
104
- map,
105
- })
106
- code = jsModuleConversionResult.code
107
- map = jsModuleConversionResult.map
108
21
 
109
- return {
110
- url,
111
- code,
112
- }
113
- }
114
-
115
- if (url in inlineModuleScripts) {
116
- const transformResult = await transformJs({
117
- code: String(inlineModuleScripts[url].bufferBeforeBuild),
118
- url: asOriginalUrl(url), // transformJs expect a file:// url
119
- projectDirectoryUrl,
120
- babelPluginMap,
121
- // moduleOutFormat: format // we are compiling for rollup output must be "esmodule"
122
- // we compile for rollup, let top level await untouched
123
- // it will be converted, if needed, during "renderChunk" hook
124
- topLevelAwait: "ignore",
125
- })
126
- let code = transformResult.code
127
- let map = transformResult.map
128
- return {
129
- url,
130
- code,
131
- map,
132
- }
22
+ const customLoader = urlCustomLoaders[url]
23
+ if (customLoader) {
24
+ const result = await customLoader()
25
+ return result
133
26
  }
134
27
 
135
28
  const response = await urlFetcher.fetchUrl(url, {
@@ -236,33 +129,3 @@ export const createUrlLoader = ({
236
129
  getUrlResponseBodyMap: () => urlResponseBodyMap,
237
130
  }
238
131
  }
239
-
240
- const extractImportTypeFromUrl = (url) => {
241
- const urlObject = new URL(url)
242
- const { search } = urlObject
243
- const searchParams = new URLSearchParams(search)
244
-
245
- const importType = searchParams.get("import_type")
246
- if (!importType) {
247
- return {}
248
- }
249
-
250
- searchParams.delete("import_type")
251
- urlObject.search = String(searchParams)
252
- return {
253
- importType,
254
- urlWithoutImportType: urlObject.href,
255
- }
256
- }
257
-
258
- const convertJsonTextToJavascriptModule = ({ code }) => {
259
- // here we could do the following
260
- // return export default jsonText
261
- // This would return valid js, that would be minified later
262
- // however we will prefer using JSON.parse because it's faster
263
- // for js engine to parse JSON than JS
264
-
265
- return {
266
- code: `export default JSON.parse(${JSON.stringify(code.trim())})`,
267
- }
268
- }
@@ -0,0 +1,226 @@
1
+ import { createHash } from "crypto"
2
+ import {
3
+ urlToParentUrl,
4
+ urlToBasename,
5
+ urlToExtension,
6
+ } from "@jsenv/filesystem"
7
+
8
+ export const createUrlVersioner = ({
9
+ entryPointUrls,
10
+ workerUrls,
11
+ classicWorkerUrls,
12
+ serviceWorkerUrls,
13
+ classicServiceWorkerUrls,
14
+ asOriginalUrl,
15
+ lineBreakNormalization,
16
+ }) => {
17
+ const computeBuildRelativeUrl = (ressource) => {
18
+ const pattern = getFilenamePattern({
19
+ ressource,
20
+ entryPointUrls,
21
+ workerUrls,
22
+ classicWorkerUrls,
23
+ serviceWorkerUrls,
24
+ classicServiceWorkerUrls,
25
+ asOriginalUrl,
26
+ precomputeBuildRelativeUrl,
27
+ })
28
+ const buildRelativeUrl = generateBuildRelativeUrl(
29
+ ressource.url,
30
+ ressource.bufferAfterBuild,
31
+ {
32
+ pattern,
33
+ contentType: ressource.contentType,
34
+ lineBreakNormalization,
35
+ },
36
+ )
37
+ return buildRelativeUrl
38
+ }
39
+
40
+ const precomputeBuildRelativeUrl = (ressource, bufferAfterBuild = "") => {
41
+ if (ressource.buildRelativeUrl) {
42
+ return ressource.buildRelativeUrl
43
+ }
44
+ if (ressource.precomputedBuildRelativeUrl) {
45
+ return ressource.precomputedBuildRelativeUrl
46
+ }
47
+
48
+ ressource.bufferAfterBuild = bufferAfterBuild
49
+ const precomputedBuildRelativeUrl = computeBuildRelativeUrl(ressource)
50
+ ressource.bufferAfterBuild = undefined
51
+ ressource.precomputedBuildRelativeUrl = precomputedBuildRelativeUrl
52
+ return precomputedBuildRelativeUrl
53
+ }
54
+
55
+ return {
56
+ computeBuildRelativeUrl,
57
+ precomputeBuildRelativeUrl,
58
+ }
59
+ }
60
+
61
+ const getFilenamePattern = ({
62
+ ressource,
63
+ entryPointUrls,
64
+ workerUrls,
65
+ classicWorkerUrls,
66
+ serviceWorkerUrls,
67
+ classicServiceWorkerUrls,
68
+ asOriginalUrl,
69
+ precomputeBuildRelativeUrl,
70
+ }) => {
71
+ if (ressource.isEntryPoint) {
72
+ const originalUrl = asOriginalUrl(ressource.url)
73
+ const entryPointBuildRelativeUrl = entryPointUrls[originalUrl]
74
+ return entryPointBuildRelativeUrl
75
+ }
76
+
77
+ // service worker:
78
+ // - MUST be at the root (same level than the HTML file)
79
+ // otherwise it might be registered for the scope "/assets/" instead of "/"
80
+ // - MUST not be versioned
81
+ if (ressource.isServiceWorker) {
82
+ const originalUrl = asOriginalUrl(ressource.url)
83
+ const serviceWorkerBuildRelativeUrl = ressource.isJsModule
84
+ ? serviceWorkerUrls[originalUrl]
85
+ : classicServiceWorkerUrls[originalUrl]
86
+ // we could/should log a warning when service worker is not at the root
87
+ // we should also disable versioning for this file
88
+ // of the build directory
89
+ return serviceWorkerBuildRelativeUrl
90
+ }
91
+
92
+ // it's a module worker
93
+ if (ressource.isWorker) {
94
+ const originalUrl = asOriginalUrl(ressource.url)
95
+ const workerBuildRelativeUrl = ressource.isJsModule
96
+ ? workerUrls[originalUrl]
97
+ : classicWorkerUrls[originalUrl]
98
+ return workerBuildRelativeUrl
99
+ }
100
+
101
+ // inline ressource inherits location
102
+ if (ressource.isInline) {
103
+ // inherit parent directory location because it's an inline file
104
+ const importerBuildRelativeUrl = precomputeBuildRelativeUrl(
105
+ ressource.importer,
106
+ )
107
+ const name = urlToBasename(`file://${importerBuildRelativeUrl}`)
108
+ return `${name}_[hash][extname]`
109
+ }
110
+
111
+ // importmap.
112
+ // we want to force the fileName for the importmap
113
+ // so that we don't have to rewrite its content
114
+ // the goal is to put the importmap at the same relative path
115
+ // than in the project
116
+ if (ressource.contentType === "application/importmap+json") {
117
+ const importmapRessourceUrl = ressource.url
118
+ const name = urlToBasename(importmapRessourceUrl)
119
+ return `${name}_[hash][extname]`
120
+ }
121
+
122
+ if (ressource.isJsModule) {
123
+ // it's a js module
124
+ return "[name]_[hash][extname]"
125
+ }
126
+
127
+ return ressource.urlVersioningDisabled
128
+ ? "assets/[name][extname]"
129
+ : "assets/[name]_[hash][extname]"
130
+ }
131
+
132
+ const generateBuildRelativeUrl = (
133
+ fileUrl,
134
+ fileContent,
135
+ {
136
+ name = urlToBasename(fileUrl),
137
+ pattern = "[name]-[hash][extname]",
138
+ contentType = "application/octet-stream",
139
+ lineBreakNormalization = false,
140
+ } = {},
141
+ ) => {
142
+ pattern = typeof pattern === "function" ? pattern() : pattern
143
+ if (pattern.startsWith("./")) pattern = pattern.slice(2)
144
+ const buildRelativeUrl = renderFileNamePattern(pattern, {
145
+ dirname: () => urlToParentUrl(fileUrl),
146
+ name: () => name,
147
+ hash: () =>
148
+ generateContentHash(fileContent, {
149
+ contentType,
150
+ lineBreakNormalization,
151
+ }),
152
+ extname: () => urlToExtension(fileUrl),
153
+ })
154
+ return buildRelativeUrl
155
+ }
156
+
157
+ const renderFileNamePattern = (pattern, replacements) => {
158
+ return pattern.replace(/\[(\w+)\]/g, (_match, type) => {
159
+ const replacement = replacements[type]()
160
+ return replacement
161
+ })
162
+ }
163
+
164
+ // https://github.com/rollup/rollup/blob/19e50af3099c2f627451a45a84e2fa90d20246d5/src/utils/FileEmitter.ts#L47
165
+ export const generateContentHash = (
166
+ stringOrBuffer,
167
+ {
168
+ contentType = "application/octet-stream",
169
+ lineBreakNormalization = false,
170
+ } = {},
171
+ ) => {
172
+ const hash = createHash("sha256")
173
+ hash.update(
174
+ lineBreakNormalization && contentTypeIsTextual(contentType)
175
+ ? normalizeLineBreaks(stringOrBuffer)
176
+ : stringOrBuffer,
177
+ )
178
+ return hash.digest("hex").slice(0, 8)
179
+ }
180
+
181
+ const contentTypeIsTextual = (contentType) => {
182
+ if (contentType.startsWith("text/")) {
183
+ return true
184
+ }
185
+ // catch things like application/manifest+json, application/importmap+json
186
+ if (/^application\/\w+\+json$/.test(contentType)) {
187
+ return true
188
+ }
189
+ if (CONTENT_TYPE_AS_TEXT.includes(contentType)) {
190
+ return true
191
+ }
192
+ return false
193
+ }
194
+
195
+ const CONTENT_TYPE_AS_TEXT = [
196
+ "application/javascript",
197
+ "application/json",
198
+ "image/svg+xml",
199
+ ]
200
+
201
+ const normalizeLineBreaks = (stringOrBuffer) => {
202
+ if (typeof stringOrBuffer === "string") {
203
+ const stringWithLinuxBreaks = stringOrBuffer.replace(/\r\n/g, "\n")
204
+ return stringWithLinuxBreaks
205
+ }
206
+ return normalizeLineBreaksForBuffer(stringOrBuffer)
207
+ }
208
+
209
+ // https://github.com/nodejs/help/issues/1738#issuecomment-458460503
210
+ const normalizeLineBreaksForBuffer = (buffer) => {
211
+ const int32Array = new Int32Array(buffer, 0, buffer.length)
212
+ const int32ArrayWithLineBreaksNormalized = int32Array.filter(
213
+ (element, index, typedArray) => {
214
+ if (element === 0x0d) {
215
+ if (typedArray[index + 1] === 0x0a) {
216
+ // Windows -> Unix
217
+ return false
218
+ }
219
+ // Mac OS -> Unix
220
+ typedArray[index] = 0x0a
221
+ }
222
+ return true
223
+ },
224
+ )
225
+ return Buffer.from(int32ArrayWithLineBreaksNormalized)
226
+ }
@@ -9,8 +9,8 @@ which one is being done first
9
9
  */
10
10
 
11
11
  import { createHash } from "crypto"
12
+
12
13
  import { require } from "../require.js"
13
- import { renderNamePattern } from "../renderNamePattern.js"
14
14
 
15
15
  // https://github.com/inikulin/parse5/blob/master/packages/parse5/lib/tree-adapters/default.js
16
16
  // eslint-disable-next-line import/no-unresolved
@@ -519,6 +519,13 @@ export const getUniqueNameForInlineHtmlNode = (node, nodes, pattern) => {
519
519
  })
520
520
  }
521
521
 
522
+ const renderNamePattern = (pattern, replacements) => {
523
+ return pattern.replace(/\[(\w+)\]/g, (_match, type) => {
524
+ const replacement = replacements[type]()
525
+ return replacement
526
+ })
527
+ }
528
+
522
529
  const parseHtmlAsSingleElement = (html) => {
523
530
  const parse5 = require("parse5")
524
531
  const fragment = parse5.parseFragment(html)
@@ -1,13 +1,13 @@
1
1
  import { resolveUrl, urlToRelativeUrl } from "@jsenv/filesystem"
2
2
 
3
- import { generateContentHash } from "./internal/building/url-versioning.js"
3
+ import { generateContentHash } from "./internal/building/url_versioning.js"
4
4
 
5
5
  export const jsenvServiceWorkerFinalizer = (
6
6
  code,
7
7
  {
8
8
  serviceWorkerBuildRelativeUrl,
9
9
  buildManifest,
10
- rollupBuild,
10
+ buildFileContents,
11
11
  lineBreakNormalization,
12
12
  },
13
13
  ) => {
@@ -32,7 +32,7 @@ export const jsenvServiceWorkerFinalizer = (
32
32
  return
33
33
  }
34
34
  const versioned = fileNameContainsHash(buildRelativeUrl)
35
- const rollupFile = rollupBuild[buildRelativeUrl]
35
+ const buildFileContent = buildFileContents[buildRelativeUrl]
36
36
 
37
37
  generatedUrlsConfig[urlRelativeToServiceWorker] = {
38
38
  versioned,
@@ -42,10 +42,9 @@ export const jsenvServiceWorkerFinalizer = (
42
42
  // when url is not versioned we compute a "version" for that url anyway
43
43
  // so that service worker source still changes and navigator
44
44
  // detect there is a change
45
- version: generateContentHash(
46
- rollupFile.type === "chunk" ? rollupFile.code : rollupFile.source,
47
- { lineBreakNormalization },
48
- ),
45
+ version: generateContentHash(buildFileContent, {
46
+ lineBreakNormalization,
47
+ }),
49
48
  }),
50
49
  }
51
50
  })
@@ -57,4 +56,4 @@ ${code}
57
56
  }
58
57
 
59
58
  const fileNameContainsHash = (fileName) =>
60
- /-[a-z0-9]{8,}(\..*?)?$/.test(fileName)
59
+ /_[a-z0-9]{8,}(\..*?)?$/.test(fileName)
@@ -1,50 +0,0 @@
1
- import { computeBuildRelativeUrl } from "./url-versioning.js"
2
-
3
- export const computeBuildRelativeUrlForRessource = (
4
- ressource,
5
- { lineBreakNormalization },
6
- ) => {
7
- return computeBuildRelativeUrl(ressource.url, ressource.bufferAfterBuild, {
8
- pattern: fileNamePatternFromRessource(ressource),
9
- contentType: ressource.contentType,
10
- lineBreakNormalization,
11
- })
12
- }
13
-
14
- const assetFileNamePattern = "assets/[name]-[hash][extname]"
15
- const assetFileNamePatternWithoutHash = "assets/[name][extname]"
16
-
17
- const fileNamePatternFromRessource = (ressource) => {
18
- if (ressource.fileNamePattern) {
19
- return ressource.fileNamePattern
20
- }
21
-
22
- if (ressource.urlVersioningDisabled) {
23
- if (canMoveToAssetsDirectory(ressource)) {
24
- return assetFileNamePatternWithoutHash
25
- }
26
- return `[name][extname]`
27
- }
28
-
29
- if (canMoveToAssetsDirectory(ressource)) {
30
- return assetFileNamePattern
31
- }
32
- return `[name]-[hash][extname]`
33
- }
34
-
35
- const canMoveToAssetsDirectory = (ressource) => {
36
- if (ressource.isEntryPoint) {
37
- return false
38
- }
39
- // in theory js module can be moved to assets directory
40
- // but that needs to be tested
41
- if (ressource.isJsModule) {
42
- return false
43
- }
44
- // service worker MUST be at the root (same level than the HTML file)
45
- // otherwise it might be registered for the scope "/assets/" instead of "/"
46
- if (ressource.isServiceWorker) {
47
- return false
48
- }
49
- return true
50
- }
@@ -1,54 +0,0 @@
1
- import { resolveUrl, urlToRelativeUrl } from "@jsenv/filesystem"
2
-
3
- import { setJavaScriptSourceMappingUrl } from "@jsenv/core/src/internal/sourceMappingURLUtils.js"
4
-
5
- export const injectSourcemapInRollupBuild = (
6
- rollupBuild,
7
- { buildDirectoryUrl },
8
- ) => {
9
- const rollupBuildWithSourcemap = {}
10
-
11
- Object.keys(rollupBuild).forEach((buildRelativeUrl) => {
12
- const rollupFileInfo = rollupBuild[buildRelativeUrl]
13
- const { type, code, map } = rollupFileInfo
14
-
15
- if (type === "asset" || !map) {
16
- rollupBuildWithSourcemap[buildRelativeUrl] = rollupFileInfo
17
- return
18
- }
19
-
20
- const sourcemapBuildRelativeUrl = `${buildRelativeUrl}.map`
21
- const sourcemapRollupFileInfo = rollupBuild[sourcemapBuildRelativeUrl]
22
- if (sourcemapRollupFileInfo) {
23
- rollupBuildWithSourcemap[buildRelativeUrl] = rollupFileInfo
24
- return
25
- }
26
-
27
- const fileBuildUrl = resolveUrl(buildRelativeUrl, buildDirectoryUrl)
28
- const sourcemapBuildUrl = resolveUrl(
29
- sourcemapBuildRelativeUrl,
30
- buildDirectoryUrl,
31
- )
32
- const fileSourcemapString = JSON.stringify(map, null, " ")
33
- const sourcemapBuildUrlRelativeToFileBuildUrl = urlToRelativeUrl(
34
- sourcemapBuildUrl,
35
- fileBuildUrl,
36
- )
37
- const codeWithSourcemapComment = setJavaScriptSourceMappingUrl(
38
- code,
39
- sourcemapBuildUrlRelativeToFileBuildUrl,
40
- )
41
-
42
- rollupBuildWithSourcemap[sourcemapBuildRelativeUrl] = {
43
- type: "asset",
44
- fileName: sourcemapBuildRelativeUrl,
45
- source: fileSourcemapString,
46
- }
47
- rollupBuildWithSourcemap[buildRelativeUrl] = {
48
- ...rollupFileInfo,
49
- code: codeWithSourcemapComment,
50
- }
51
- })
52
-
53
- return rollupBuildWithSourcemap
54
- }
@@ -1,96 +0,0 @@
1
- import { createHash } from "crypto"
2
- import {
3
- urlToParentUrl,
4
- urlToBasename,
5
- urlToExtension,
6
- } from "@jsenv/filesystem"
7
- import { renderNamePattern } from "../renderNamePattern.js"
8
-
9
- export const computeBuildRelativeUrl = (
10
- fileUrl,
11
- fileContent,
12
- {
13
- pattern = "[name]-[hash][extname]",
14
- contentType = "application/octet-stream",
15
- lineBreakNormalization = false,
16
- } = {},
17
- ) => {
18
- const buildRelativeUrl = renderNamePattern(
19
- typeof pattern === "function" ? pattern() : pattern,
20
- {
21
- dirname: () => urlToParentUrl(fileUrl),
22
- name: () => urlToBasename(fileUrl),
23
- hash: () =>
24
- generateContentHash(fileContent, {
25
- contentType,
26
- lineBreakNormalization,
27
- }),
28
- extname: () => urlToExtension(fileUrl),
29
- },
30
- )
31
- return buildRelativeUrl
32
- }
33
-
34
- // https://github.com/rollup/rollup/blob/19e50af3099c2f627451a45a84e2fa90d20246d5/src/utils/FileEmitter.ts#L47
35
- export const generateContentHash = (
36
- stringOrBuffer,
37
- {
38
- contentType = "application/octet-stream",
39
- lineBreakNormalization = false,
40
- } = {},
41
- ) => {
42
- const hash = createHash("sha256")
43
- hash.update(
44
- lineBreakNormalization && contentTypeIsTextual(contentType)
45
- ? normalizeLineBreaks(stringOrBuffer)
46
- : stringOrBuffer,
47
- )
48
- return hash.digest("hex").slice(0, 8)
49
- }
50
-
51
- const contentTypeIsTextual = (contentType) => {
52
- if (contentType.startsWith("text/")) {
53
- return true
54
- }
55
- // catch things like application/manifest+json, application/importmap+json
56
- if (/^application\/\w+\+json$/.test(contentType)) {
57
- return true
58
- }
59
- if (CONTENT_TYPE_AS_TEXT.includes(contentType)) {
60
- return true
61
- }
62
- return false
63
- }
64
-
65
- const CONTENT_TYPE_AS_TEXT = [
66
- "application/javascript",
67
- "application/json",
68
- "image/svg+xml",
69
- ]
70
-
71
- const normalizeLineBreaks = (stringOrBuffer) => {
72
- if (typeof stringOrBuffer === "string") {
73
- const stringWithLinuxBreaks = stringOrBuffer.replace(/\r\n/g, "\n")
74
- return stringWithLinuxBreaks
75
- }
76
- return normalizeLineBreaksForBuffer(stringOrBuffer)
77
- }
78
-
79
- // https://github.com/nodejs/help/issues/1738#issuecomment-458460503
80
- const normalizeLineBreaksForBuffer = (buffer) => {
81
- const int32Array = new Int32Array(buffer, 0, buffer.length)
82
- const int32ArrayWithLineBreaksNormalized = int32Array.filter(
83
- (element, index, typedArray) => {
84
- if (element === 0x0d) {
85
- if (typedArray[index + 1] === 0x0a) {
86
- // Windows -> Unix
87
- return false
88
- }
89
- // Mac OS -> Unix
90
- typedArray[index] = 0x0a
91
- }
92
- return true
93
- },
94
- )
95
- return Buffer.from(int32ArrayWithLineBreaksNormalized)
96
- }
@@ -1,6 +0,0 @@
1
- export const renderNamePattern = (pattern, replacements) => {
2
- return pattern.replace(/\[(\w+)\]/g, (_match, type) => {
3
- const replacement = replacements[type]()
4
- return replacement
5
- })
6
- }