@jsenv/core 30.0.7 → 30.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/main.js CHANGED
@@ -16,7 +16,7 @@ import { Readable, Stream, Writable } from "node:stream";
16
16
  import { Http2ServerResponse } from "node:http2";
17
17
  import { lookup } from "node:dns";
18
18
  import { SOURCEMAP, generateSourcemapFileUrl, composeTwoSourcemaps, generateSourcemapDataUrl, createMagicSource, getOriginalPosition } from "@jsenv/sourcemap";
19
- import { parseHtmlString, stringifyHtmlAst, getHtmlNodeAttribute, visitHtmlNodes, analyzeScriptNode, setHtmlNodeAttributes, parseSrcSet, getHtmlNodePosition, getHtmlNodeAttributePosition, applyPostCss, postCssPluginUrlVisitor, parseJsUrls, getHtmlNodeText, setHtmlNodeText, applyBabelPlugins, injectScriptNodeAsEarlyAsPossible, createHtmlNode, findHtmlNode, removeHtmlNode, removeHtmlNodeText, transpileWithParcel, injectJsImport, analyzeLinkNode, injectHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
19
+ import { parseHtmlString, stringifyHtmlAst, getHtmlNodeAttribute, visitHtmlNodes, analyzeScriptNode, setHtmlNodeAttributes, parseSrcSet, getHtmlNodePosition, getHtmlNodeAttributePosition, applyPostCss, postCssPluginUrlVisitor, parseJsUrls, getHtmlNodeText, setHtmlNodeText, applyBabelPlugins, injectScriptNodeAsEarlyAsPossible, createHtmlNode, findHtmlNode, removeHtmlNode, removeHtmlNodeText, injectJsImport, analyzeLinkNode, injectHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
20
20
  import { createRequire } from "node:module";
21
21
  import babelParser from "@babel/parser";
22
22
  import { bundleJsModules } from "@jsenv/plugin-bundling";
@@ -17750,17 +17750,16 @@ const babelPluginMetadataImportMetaScenarios = () => {
17750
17750
  };
17751
17751
  };
17752
17752
 
17753
- // https://github.com/parcel-bundler/parcel-css
17754
- const jsenvPluginCssParcel = () => {
17753
+ const jsenvPluginCssTranspilation = () => {
17755
17754
  return {
17756
- name: "jsenv:css_parcel",
17755
+ name: "jsenv:css_transpilation",
17757
17756
  appliesDuring: "*",
17758
17757
  transformUrlContent: {
17759
- css: (urlInfo, context) => {
17758
+ css: async (urlInfo, context) => {
17760
17759
  const {
17761
17760
  code,
17762
17761
  map
17763
- } = transpileWithParcel(urlInfo, context);
17762
+ } = await transpileCss(urlInfo, context);
17764
17763
  return {
17765
17764
  content: String(code),
17766
17765
  sourcemap: map
@@ -17769,6 +17768,44 @@ const jsenvPluginCssParcel = () => {
17769
17768
  }
17770
17769
  };
17771
17770
  };
17771
+ const transpileCss = async (urlInfo, context) => {
17772
+ // https://lightningcss.dev/docs.html
17773
+ const {
17774
+ transform
17775
+ } = await import("lightningcss");
17776
+ const targets = runtimeCompatToTargets(context.runtimeCompat);
17777
+ const {
17778
+ code,
17779
+ map
17780
+ } = transform({
17781
+ filename: fileURLToPath(urlInfo.originalUrl),
17782
+ code: Buffer.from(urlInfo.content),
17783
+ targets,
17784
+ minify: false,
17785
+ drafts: {
17786
+ nesting: true,
17787
+ customMedia: true
17788
+ }
17789
+ });
17790
+ return {
17791
+ code,
17792
+ map
17793
+ };
17794
+ };
17795
+ const runtimeCompatToTargets = runtimeCompat => {
17796
+ const targets = {};
17797
+ ["chrome", "firefox", "ie", "opera", "safari"].forEach(runtimeName => {
17798
+ const version = runtimeCompat[runtimeName];
17799
+ if (version) {
17800
+ targets[runtimeName] = versionToBits(version);
17801
+ }
17802
+ });
17803
+ return targets;
17804
+ };
17805
+ const versionToBits = version => {
17806
+ const [major, minor = 0, patch = 0] = version.split("-")[0].split(".").map(v => parseInt(v, 10));
17807
+ return major << 16 | minor << 8 | patch;
17808
+ };
17772
17809
 
17773
17810
  /*
17774
17811
  * Jsenv wont touch code where "specifier" or "type" is dynamic (see code below)
@@ -19206,7 +19243,7 @@ const jsenvPluginTranspilation = ({
19206
19243
  }), jsenvPluginAsJsModule(),
19207
19244
  // topLevelAwait must come after jsenvPluginAsJsClassic because it's related to the module format
19208
19245
  // so we want to wait to know the module format before transforming things related to top level await
19209
- ...(topLevelAwait ? [jsenvPluginTopLevelAwait()] : []), ...(css ? [jsenvPluginCssParcel()] : [])];
19246
+ ...(topLevelAwait ? [jsenvPluginTopLevelAwait()] : []), ...(css ? [jsenvPluginCssTranspilation()] : [])];
19210
19247
  };
19211
19248
 
19212
19249
  const jsenvPluginNodeRuntime = ({
@@ -20324,36 +20361,16 @@ ${globalName}.__v__ = function (specifier) {
20324
20361
  `;
20325
20362
  };
20326
20363
 
20327
- // https://github.com/rollup/rollup/blob/19e50af3099c2f627451a45a84e2fa90d20246d5/src/utils/FileEmitter.ts#L47
20328
- // https://github.com/rollup/rollup/blob/5a5391971d695c808eed0c5d7d2c6ccb594fc689/src/Chunk.ts#L870
20329
- const createVersionGenerator = () => {
20330
- const hash = createHash("sha256");
20331
- return {
20332
- augmentWithContent: ({
20333
- content,
20334
- contentType = "application/octet-stream",
20335
- lineBreakNormalization = false
20336
- }) => {
20337
- hash.update(lineBreakNormalization && CONTENT_TYPE.isTextual(contentType) ? normalizeLineBreaks(content) : content);
20338
- },
20339
- augment: value => {
20340
- hash.update(value);
20341
- },
20342
- generate: () => {
20343
- return hash.digest("hex").slice(0, 8);
20344
- }
20345
- };
20346
- };
20347
- const normalizeLineBreaks = stringOrBuffer => {
20364
+ const ensureUnixLineBreaks = stringOrBuffer => {
20348
20365
  if (typeof stringOrBuffer === "string") {
20349
20366
  const stringWithLinuxBreaks = stringOrBuffer.replace(/\r\n/g, "\n");
20350
20367
  return stringWithLinuxBreaks;
20351
20368
  }
20352
- return normalizeLineBreaksForBuffer(stringOrBuffer);
20369
+ return ensureUnixLineBreaksOnBuffer(stringOrBuffer);
20353
20370
  };
20354
20371
 
20355
20372
  // https://github.com/nodejs/help/issues/1738#issuecomment-458460503
20356
- const normalizeLineBreaksForBuffer = buffer => {
20373
+ const ensureUnixLineBreaksOnBuffer = buffer => {
20357
20374
  const int32Array = new Int32Array(buffer, 0, buffer.length);
20358
20375
  const int32ArrayWithLineBreaksNormalized = int32Array.filter((element, index, typedArray) => {
20359
20376
  if (element === 0x0d) {
@@ -20369,6 +20386,27 @@ const normalizeLineBreaksForBuffer = buffer => {
20369
20386
  return Buffer.from(int32ArrayWithLineBreaksNormalized);
20370
20387
  };
20371
20388
 
20389
+ // https://github.com/rollup/rollup/blob/19e50af3099c2f627451a45a84e2fa90d20246d5/src/utils/FileEmitter.ts#L47
20390
+ // https://github.com/rollup/rollup/blob/5a5391971d695c808eed0c5d7d2c6ccb594fc689/src/Chunk.ts#L870
20391
+ const createVersionGenerator = () => {
20392
+ const hash = createHash("sha256");
20393
+ return {
20394
+ augmentWithContent: ({
20395
+ content,
20396
+ contentType = "application/octet-stream",
20397
+ lineBreakNormalization = false
20398
+ }) => {
20399
+ hash.update(lineBreakNormalization && CONTENT_TYPE.isTextual(contentType) ? ensureUnixLineBreaks(content) : content);
20400
+ },
20401
+ augment: value => {
20402
+ hash.update(value);
20403
+ },
20404
+ generate: () => {
20405
+ return hash.digest("hex").slice(0, 8);
20406
+ }
20407
+ };
20408
+ };
20409
+
20372
20410
  /*
20373
20411
  * Build is split in 3 steps:
20374
20412
  * 1. craft
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "30.0.7",
3
+ "version": "30.2.0",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -67,9 +67,9 @@
67
67
  "@c88/v8-coverage": "0.1.1",
68
68
  "@financial-times/polyfill-useragent-normaliser": "1.10.2",
69
69
  "@jsenv/abort": "4.2.4",
70
- "@jsenv/ast": "1.4.10",
70
+ "@jsenv/ast": "2.0.0",
71
71
  "@jsenv/babel-plugins": "1.1.2",
72
- "@jsenv/plugin-bundling": "1.0.4",
72
+ "@jsenv/plugin-bundling": "1.1.0",
73
73
  "@jsenv/filesystem": "4.1.9",
74
74
  "@jsenv/importmap": "1.2.1",
75
75
  "@jsenv/integrity": "0.0.1",
@@ -88,6 +88,7 @@
88
88
  "istanbul-lib-report": "3.0.0",
89
89
  "istanbul-reports": "3.1.5",
90
90
  "launch-editor": "2.6.0",
91
+ "lightningcss": "1.18.0",
91
92
  "pidtree": "0.6.0",
92
93
  "string-width": "5.1.2",
93
94
  "strip-ansi": "7.0.1",
@@ -0,0 +1,26 @@
1
+ export const ensureUnixLineBreaks = (stringOrBuffer) => {
2
+ if (typeof stringOrBuffer === "string") {
3
+ const stringWithLinuxBreaks = stringOrBuffer.replace(/\r\n/g, "\n")
4
+ return stringWithLinuxBreaks
5
+ }
6
+ return ensureUnixLineBreaksOnBuffer(stringOrBuffer)
7
+ }
8
+
9
+ // https://github.com/nodejs/help/issues/1738#issuecomment-458460503
10
+ const ensureUnixLineBreaksOnBuffer = (buffer) => {
11
+ const int32Array = new Int32Array(buffer, 0, buffer.length)
12
+ const int32ArrayWithLineBreaksNormalized = int32Array.filter(
13
+ (element, index, typedArray) => {
14
+ if (element === 0x0d) {
15
+ if (typedArray[index + 1] === 0x0a) {
16
+ // Windows -> Unix
17
+ return false
18
+ }
19
+ // Mac OS -> Unix
20
+ typedArray[index] = 0x0a
21
+ }
22
+ return true
23
+ },
24
+ )
25
+ return Buffer.from(int32ArrayWithLineBreaksNormalized)
26
+ }
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto"
2
2
 
3
3
  import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
4
+ import { ensureUnixLineBreaks } from "./line_break_unix.js"
4
5
 
5
6
  // https://github.com/rollup/rollup/blob/19e50af3099c2f627451a45a84e2fa90d20246d5/src/utils/FileEmitter.ts#L47
6
7
  // https://github.com/rollup/rollup/blob/5a5391971d695c808eed0c5d7d2c6ccb594fc689/src/Chunk.ts#L870
@@ -15,7 +16,7 @@ export const createVersionGenerator = () => {
15
16
  }) => {
16
17
  hash.update(
17
18
  lineBreakNormalization && CONTENT_TYPE.isTextual(contentType)
18
- ? normalizeLineBreaks(content)
19
+ ? ensureUnixLineBreaks(content)
19
20
  : content,
20
21
  )
21
22
  },
@@ -27,30 +28,3 @@ export const createVersionGenerator = () => {
27
28
  },
28
29
  }
29
30
  }
30
-
31
- const normalizeLineBreaks = (stringOrBuffer) => {
32
- if (typeof stringOrBuffer === "string") {
33
- const stringWithLinuxBreaks = stringOrBuffer.replace(/\r\n/g, "\n")
34
- return stringWithLinuxBreaks
35
- }
36
- return normalizeLineBreaksForBuffer(stringOrBuffer)
37
- }
38
-
39
- // https://github.com/nodejs/help/issues/1738#issuecomment-458460503
40
- const normalizeLineBreaksForBuffer = (buffer) => {
41
- const int32Array = new Int32Array(buffer, 0, buffer.length)
42
- const int32ArrayWithLineBreaksNormalized = int32Array.filter(
43
- (element, index, typedArray) => {
44
- if (element === 0x0d) {
45
- if (typedArray[index + 1] === 0x0a) {
46
- // Windows -> Unix
47
- return false
48
- }
49
- // Mac OS -> Unix
50
- typedArray[index] = 0x0a
51
- }
52
- return true
53
- },
54
- )
55
- return Buffer.from(int32ArrayWithLineBreaksNormalized)
56
- }
@@ -0,0 +1,54 @@
1
+ import { fileURLToPath } from "node:url"
2
+
3
+ export const jsenvPluginCssTranspilation = () => {
4
+ return {
5
+ name: "jsenv:css_transpilation",
6
+ appliesDuring: "*",
7
+ transformUrlContent: {
8
+ css: async (urlInfo, context) => {
9
+ const { code, map } = await transpileCss(urlInfo, context)
10
+ return {
11
+ content: String(code),
12
+ sourcemap: map,
13
+ }
14
+ },
15
+ },
16
+ }
17
+ }
18
+
19
+ const transpileCss = async (urlInfo, context) => {
20
+ // https://lightningcss.dev/docs.html
21
+ const { transform } = await import("lightningcss")
22
+
23
+ const targets = runtimeCompatToTargets(context.runtimeCompat)
24
+ const { code, map } = transform({
25
+ filename: fileURLToPath(urlInfo.originalUrl),
26
+ code: Buffer.from(urlInfo.content),
27
+ targets,
28
+ minify: false,
29
+ drafts: {
30
+ nesting: true,
31
+ customMedia: true,
32
+ },
33
+ })
34
+ return { code, map }
35
+ }
36
+
37
+ const runtimeCompatToTargets = (runtimeCompat) => {
38
+ const targets = {}
39
+ ;["chrome", "firefox", "ie", "opera", "safari"].forEach((runtimeName) => {
40
+ const version = runtimeCompat[runtimeName]
41
+ if (version) {
42
+ targets[runtimeName] = versionToBits(version)
43
+ }
44
+ })
45
+ return targets
46
+ }
47
+
48
+ const versionToBits = (version) => {
49
+ const [major, minor = 0, patch = 0] = version
50
+ .split("-")[0]
51
+ .split(".")
52
+ .map((v) => parseInt(v, 10))
53
+ return (major << 16) | (minor << 8) | patch
54
+ }
@@ -7,7 +7,7 @@
7
7
  * of this plugin
8
8
  */
9
9
 
10
- import { jsenvPluginCssParcel } from "./css_parcel/jsenv_plugin_css_parcel.js"
10
+ import { jsenvPluginCssTranspilation } from "./css/jsenv_plugin_css_transpilation.js"
11
11
  import { jsenvPluginImportAssertions } from "./import_assertions/jsenv_plugin_import_assertions.js"
12
12
  import { jsenvPluginAsJsClassic } from "./as_js_classic/jsenv_plugin_as_js_classic.js"
13
13
  import { jsenvPluginAsJsModule } from "./as_js_module/jsenv_plugin_as_js_module.js"
@@ -52,6 +52,6 @@ export const jsenvPluginTranspilation = ({
52
52
  // topLevelAwait must come after jsenvPluginAsJsClassic because it's related to the module format
53
53
  // so we want to wait to know the module format before transforming things related to top level await
54
54
  ...(topLevelAwait ? [jsenvPluginTopLevelAwait(topLevelAwait)] : []),
55
- ...(css ? [jsenvPluginCssParcel()] : []),
55
+ ...(css ? [jsenvPluginCssTranspilation()] : []),
56
56
  ]
57
57
  }
@@ -1,18 +0,0 @@
1
- import { transpileWithParcel } from "@jsenv/ast"
2
-
3
- // https://github.com/parcel-bundler/parcel-css
4
- export const jsenvPluginCssParcel = () => {
5
- return {
6
- name: "jsenv:css_parcel",
7
- appliesDuring: "*",
8
- transformUrlContent: {
9
- css: (urlInfo, context) => {
10
- const { code, map } = transpileWithParcel(urlInfo, context)
11
- return {
12
- content: String(code),
13
- sourcemap: map,
14
- }
15
- },
16
- },
17
- }
18
- }