diff --git a/.babelrc b/.babelrc index 9ffb370b..5f434168 100644 --- a/.babelrc +++ b/.babelrc @@ -3,6 +3,7 @@ [ "@babel/preset-env", { + "modules": "commonjs", "targets": { "node": 12 } diff --git a/.changeset/support-babel-8.md b/.changeset/support-babel-8.md new file mode 100644 index 00000000..2dd15251 --- /dev/null +++ b/.changeset/support-babel-8.md @@ -0,0 +1,5 @@ +--- +'babel-plugin-styled-components': minor +--- + +Support Babel 8. The plugin now installs alongside `@babel/core@8` without peer dependency warnings or errors, and the `css` prop transform no longer crashes with `t.jSXIdentifier is not a function` on Babel 8. The plugin also no longer depends on `@babel/plugin-syntax-jsx`, which only accepted Babel 7 as a peer. Babel 7 output is unchanged. diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c507f5e1..2360da22 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,3 +33,6 @@ jobs: - name: Run tests run: pnpm test + + - name: Run fixtures on Babel 8 + run: pnpm build && pnpm test:babel8 diff --git a/AGENTS.md b/AGENTS.md index 32319c8f..57deca20 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,6 +11,7 @@ Commands - `pnpm exec jest -u`: regenerate fixture outputs, only after the snapshot-drift rule below is satisfied - `pnpm exec jest --coverage`: prints live coverage - `pnpm build`: compile `src/` to `lib/`; run it to verify every set of changes. Don't start a dev server unless asked +- `pnpm test:babel8`: the built `lib/` over the fixtures on Babel 8, outside Jest because Babel 8 is ESM-only; run `pnpm build` first - `pnpm bench [--base ] [--config default|all|bare] [--rounds N] [--normalize-aliases]`: interleaved A/B of the plugin at `` (default `origin/main`) against the working tree over generated inputs; fails when outputs differ - `pnpm bench:profile [--input small|medium|large|large-cjs]`: CPU profile with the plugin frames that drive Babel's work - `node scripts/compat.js [--base ]`: styled-components v5, v6, and v7 prerelease smoke against the working tree and `` (default `origin/main`) diff --git a/README.md b/README.md index 9ddd3693..a8d1a07e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This plugin is a highly recommended supplement to the base styled-components lib This plugin is tested against: -- `@babel/core` `^7` +- `@babel/core` `^7` and `^8` - `styled-components` `>= 6` (earlier majors may still work but aren't exercised in CI) ## Quick start diff --git a/package.json b/package.json index 99eb35a6..a22298c1 100644 --- a/package.json +++ b/package.json @@ -23,11 +23,14 @@ "devDependencies": { "@babel/cli": "^7.26.4", "@babel/core": "^7.26.0", + "@babel/plugin-syntax-jsx": "^7.28.6", "@babel/plugin-transform-class-properties": "^7.25.9", "@babel/plugin-transform-modules-commonjs": "^7.26.3", "@babel/preset-env": "^7.26.0", "@changesets/cli": "2.31.0", "babel-test": "^0.2.4", + "babel8": "npm:@babel/core@^8.0.9", + "babel8-preset-typescript": "npm:@babel/preset-typescript@^8", "jest": "^29.7.0", "jest-file-snapshot": "^0.5.0", "prettier": "^3.4.2", @@ -37,11 +40,10 @@ "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-module-imports": "^7.25.9", - "@babel/plugin-syntax-jsx": "^7.25.9", "picomatch": "^4.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0", + "@babel/core": "^7.0.0 || ^8.0.0", "styled-components": ">= 2" }, "scripts": { @@ -49,6 +51,7 @@ "style": "prettier --write src/**/*.js", "build": "babel src -d lib", "test": "jest", + "test:babel8": "node scripts/babel8.js", "test:watch": "pnpm test -- --watch", "bench": "node scripts/bench/index.js", "bench:profile": "node scripts/bench/profile.js", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9d21c5ac..5cd42a37 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -175,9 +175,6 @@ importers: '@babel/helper-module-imports': specifier: ^7.25.9 version: 7.28.6(supports-color@8.1.1) - '@babel/plugin-syntax-jsx': - specifier: ^7.25.9 - version: 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) picomatch: specifier: ^4.0.2 version: 4.0.4 @@ -188,6 +185,9 @@ importers: '@babel/core': specifier: ^7.26.0 version: 7.29.0(supports-color@8.1.1) + '@babel/plugin-syntax-jsx': + specifier: ^7.28.6 + version: 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) '@babel/plugin-transform-class-properties': specifier: ^7.25.9 version: 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) @@ -203,6 +203,12 @@ importers: babel-test: specifier: ^0.2.4 version: 0.2.4(patch_hash=6b3cf0bcf4b9110049af53f6978b3834388ea424736399f5321452cba461e47e) + babel8: + specifier: npm:@babel/core@^8.0.9 + version: '@babel/core@8.0.9' + babel8-preset-typescript: + specifier: npm:@babel/preset-typescript@^8 + version: '@babel/preset-typescript@8.0.7(@babel/core@7.29.0(supports-color@8.1.1))' jest: specifier: ^29.7.0 version: 29.7.0(@types/node@25.8.0)(supports-color@8.1.1) @@ -232,32 +238,62 @@ packages: resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} + '@babel/code-frame@8.0.6': + resolution: {integrity: sha512-uMHhvmDmwFiLuiozaoRYTZHqMFuu3fem/X9JY78lohAuLoh8LSGGC8JqUzo2cVuBsBxkjMZNk56CE7ock8Xxkw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/compat-data@7.29.3': resolution: {integrity: sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==} engines: {node: '>=6.9.0'} + '@babel/compat-data@8.0.5': + resolution: {integrity: sha512-YLsYoQMvL8l8WrGpN3Zj7O1wK5LEBN+cQtux7BcuHyxIXve724XG+zuJ1n3U1cUweRtTzQOA4IHbuQw3N34SZw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/core@7.29.0': resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} engines: {node: '>=6.9.0'} + '@babel/core@8.0.9': + resolution: {integrity: sha512-wXtyKlpR/pXf/u0vmib+OBakQaIzLglLcRoKpWxCHW/whqq7YfQYPD0IAAl9H/evi40MyLIjYYdvb6N+9DI2yA==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/generator@7.29.1': resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} + '@babel/generator@8.0.6': + resolution: {integrity: sha512-/pcanjdRsonCexCuxgGD8fKnBLLzk2i9uM4kmcmGyyev2R5YDs+rafMYZ89RvaGY1mW8T7C5au0TyYaEeHBGng==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@8.0.0': + resolution: {integrity: sha512-NSpMkMsvvZqzThJ0p1B02cbtA2ObEyfBvq950bmNkyxsxvcxwhvvCB036rKhlEnuBBo30bOrk13u3FzlKSoRrw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-compilation-targets@7.28.6': resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@8.0.7': + resolution: {integrity: sha512-ilAZCdOOlOVA7dQbaFNw2f/59p6GW33NxTopc3DvEE3efp3ZXTrGX/yZScaKw8/vd9bq31Ag0EcXiLw32bAgJg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-create-class-features-plugin@7.29.3': resolution: {integrity: sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-create-class-features-plugin@8.0.7': + resolution: {integrity: sha512-7ug3KrOhNVPPxFFLTel0/pMzimKzU/vTlNJKVL/dKguCpmNJZjjibyFbWg+Qs8QHmiIZPNuZ2UNnDGdHWGEpOg==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/helper-create-regexp-features-plugin@7.28.5': resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} engines: {node: '>=6.9.0'} @@ -273,28 +309,56 @@ packages: resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} + '@babel/helper-globals@8.0.6': + resolution: {integrity: sha512-OdnA/N52LhzFpeUuVz5YGuSWjc7TPHiFmVYZbPlSgExocO2GwbxVpSni9MVs5wwW+wZ4kPuwBEBN9pIPDYz1mA==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-member-expression-to-functions@7.28.5': resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} engines: {node: '>=6.9.0'} + '@babel/helper-member-expression-to-functions@8.0.5': + resolution: {integrity: sha512-GLe05QD98BkNFTkjaqeqF9QSRoHLKrrB4tpoplyQuuPrQJ72rtmkM4wvqJLX/sjZPqkbK5MUYSsuUTqdJoOVjA==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-module-imports@7.28.6': resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@8.0.0': + resolution: {integrity: sha512-NZ7mSS93o4ndX4KrbD7W8Sf3QT8Qe24PrnFyUcuOPDzK6faqDFKjY9RG7he7+I7FdiQ4llpnosFqzrXa+Vy3Ew==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-module-transforms@7.28.6': resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@8.0.6': + resolution: {integrity: sha512-YUi+3X0cb0v97xKhuqkLdrwQtP6XXv1eVbhLRCFyMwG481UskbMQk4mjH7K/Jg3oJ1KLskvFwwq4kF/QnABkWQ==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/helper-optimise-call-expression@7.27.1': resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} + '@babel/helper-optimise-call-expression@8.0.0': + resolution: {integrity: sha512-3W6satvtPuCUkUx63S2jMoW9EQNYkADgs1HTfufmL7gCmAulHMKupA/12WNz4A0GMMFn/YnWWwqOT9IZrJHQjg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-plugin-utils@7.28.6': resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@8.0.1': + resolution: {integrity: sha512-3PKFgjTyPlhFhorfP+SjKQxLViIL++zWjFOO4hGriYU+Bsm983DxEM1JmDRJVWXV0O9npu+xXRqz7Pbd3mh70g==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/helper-remap-async-to-generator@7.27.1': resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} engines: {node: '>=6.9.0'} @@ -307,22 +371,44 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-replace-supers@8.0.1': + resolution: {integrity: sha512-B1SZADIcy3tmH8CmWvj4SHi/oAPom4UL3uknTc2QRNsPVLFk/sPnZvQL/8kj7Y5omvjMqie0vklvs6XM4OLW5Q==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} engines: {node: '>=6.9.0'} + '@babel/helper-skip-transparent-expression-wrappers@8.0.0': + resolution: {integrity: sha512-xmCA9kP3IhySsqhzwIdWGlDN/1A4cCKNBO/uwZx/3YzmDoMePwno2Q5/Bq0q+tYaKbeF940YiKV/kaW8Mzvpjw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@8.0.8': + resolution: {integrity: sha512-fVM+gSuKbdv9cpmyRNh5EvsDHUZCdxQH3FdnFKSkNYHpbsn95bbrxm+ES3MVeQjcqwi2O5ur/DjLfmTQaO60ng==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-validator-identifier@7.28.5': resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@8.0.6': + resolution: {integrity: sha512-HYx0YmuchRxRSpnjvcNffnPS8DCauKNmnumIuHG3jnQAVewRA7kfJGwF13ayEpSZs7s4R/oBH4eppuXcAQd5JQ==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-validator-option@7.27.1': resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@8.0.0': + resolution: {integrity: sha512-U4Dybxh4WESWHt5XhBeExi4DrY0/DNK1aHpQbsrQXCUbFHuMweT0TpLEWKvaraV2Y6fS+ZXunsZ8zIuZIgvF2Q==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-wrap-function@7.28.6': resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} engines: {node: '>=6.9.0'} @@ -331,11 +417,20 @@ packages: resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} + '@babel/helpers@8.0.8': + resolution: {integrity: sha512-FBmhiDWs625wHg03OKiLQDeT6LOc2lWBbW97Yqs2iI1tZcucjpmYnO29NHsQ83XxKvredcvUymW/AAn2UtnakA==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/parser@7.29.3': resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@8.0.8': + resolution: {integrity: sha512-Gq65JogAr0S2p0BzvfSJboyuiRnxDQApyOqHkKmkrvm+VlLK4gC3pKsiOKEdnhFBemrFbSnOu90mZZWDpiJnmQ==} + engines: {node: ^22.18.0 || >=24.11.0} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} engines: {node: '>=6.9.0'} @@ -475,6 +570,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-typescript@8.0.3': + resolution: {integrity: sha512-jmTPwps7oSQSZaV1SxkQ3C12UWyufGysGc5OzDpZzvPAIX4mO7dJT3hoqkWVrSImvkcMiknir1iLN1SNV/CZzg==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} engines: {node: '>=6.9.0'} @@ -631,6 +732,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-modules-commonjs@8.0.1': + resolution: {integrity: sha512-PMuzulWrrzFNmY3lXSk/tV9NRb7y0eZZLJY4UEo2TKszroxvUZHAPPi+T9FDyrQhod+TQA+t+8/QYaaMpiEuhA==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/plugin-transform-modules-systemjs@7.29.4': resolution: {integrity: sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==} engines: {node: '>=6.9.0'} @@ -763,6 +870,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-typescript@8.0.6': + resolution: {integrity: sha512-WF3yRlQtClzScvQbWct00ix63+w3DPiyU0WmCBU4YqK539n3VvJFElElpevoD8wfu6953CbiNoUZBi2B7/5jXw==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/plugin-transform-unicode-escapes@7.27.1': resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} engines: {node: '>=6.9.0'} @@ -798,6 +911,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + '@babel/preset-typescript@8.0.7': + resolution: {integrity: sha512-sUFLFphAG6YNjCnJpSKpyoNxkfyeM2KNuUjJJN0R6dZusMcK2V3Fg11MVHPFvb37AZeDNocc+xM748vdh9z82Q==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/runtime@7.29.2': resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} @@ -806,14 +925,26 @@ packages: resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} + '@babel/template@8.0.0': + resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/traverse@7.29.0': resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} + '@babel/traverse@8.0.7': + resolution: {integrity: sha512-bVV0brinsTWgc6ptSIoQo3GbITtl0VZAqEUJbHHcyfDPEu+q/fEvlYEa+6H85HoK8IdksKBFtKJbJFZ6Kff+zg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/types@7.29.0': resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} + '@babel/types@8.0.8': + resolution: {integrity: sha512-iXSSZAKQWmaeAwGtFw10v9fg5hUiUs0L+w+Z2K11kym3pDNK+SF0VcAQPsEFvWcTSZ7LMgClMXDBvTbH0IlICg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -968,6 +1099,9 @@ packages: '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/gen-mapping@0.4.0-beta.0': + resolution: {integrity: sha512-JdGNkbE4GlNPYQhM0L95fBQr7ctLZJ276QXQLTad4t1oSdnnCI3fDq9DW3BqYAWv8Wc3+HS+4Gsii1oPMCfz1w==} + '@jridgewell/remapping@2.3.5': resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} @@ -978,6 +1112,9 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} @@ -1023,6 +1160,9 @@ packages: '@types/babel__traverse@7.28.0': resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/gensync@1.0.5': + resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} + '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -1035,6 +1175,9 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + '@types/jsesc@2.5.1': + resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} @@ -1303,6 +1446,10 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + empathic@2.1.0: + resolution: {integrity: sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==} + engines: {node: '>=14'} + enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} @@ -1386,6 +1533,10 @@ packages: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} + flru@1.0.2: + resolution: {integrity: sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog==} + engines: {node: '>=6'} + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -1475,6 +1626,9 @@ packages: engines: {node: '>=8'} hasBin: true + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -1696,6 +1850,9 @@ packages: node-notifier: optional: true + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1817,6 +1974,10 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + obug@3.0.0: + resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} + engines: {node: '>=12.20.0'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2192,6 +2353,10 @@ packages: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} + verkit@0.5.0: + resolution: {integrity: sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==} + engines: {node: '>=18.12.0'} + walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} @@ -2252,8 +2417,15 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@8.0.6': + dependencies: + '@babel/helper-validator-identifier': 8.0.6 + js-tokens: 10.0.0 + '@babel/compat-data@7.29.3': {} + '@babel/compat-data@8.0.5': {} + '@babel/core@7.29.0(supports-color@8.1.1)': dependencies: '@babel/code-frame': 7.29.0 @@ -2274,6 +2446,25 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/core@8.0.9': + dependencies: + '@babel/code-frame': 8.0.6 + '@babel/generator': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 + '@babel/helpers': 8.0.8 + '@babel/parser': 8.0.8 + '@babel/template': 8.0.0 + '@babel/traverse': 8.0.7 + '@babel/types': 8.0.8 + '@types/gensync': 1.0.5 + convert-source-map: 2.0.0 + empathic: 2.1.0 + gensync: 1.0.0-beta.2 + import-meta-resolve: 4.2.0 + json5: 2.2.3 + obug: 3.0.0 + verkit: 0.5.0 + '@babel/generator@7.29.1': dependencies: '@babel/parser': 7.29.3 @@ -2282,10 +2473,23 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 + '@babel/generator@8.0.6': + dependencies: + '@babel/parser': 8.0.8 + '@babel/types': 8.0.8 + '@jridgewell/gen-mapping': 0.4.0-beta.0 + '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.27.3': dependencies: '@babel/types': 7.29.0 + '@babel/helper-annotate-as-pure@8.0.0': + dependencies: + '@babel/types': 8.0.8 + '@babel/helper-compilation-targets@7.28.6': dependencies: '@babel/compat-data': 7.29.3 @@ -2294,6 +2498,14 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-compilation-targets@8.0.7': + dependencies: + '@babel/compat-data': 8.0.5 + '@babel/helper-validator-option': 8.0.0 + browserslist: 4.28.2 + flru: 1.0.2 + verkit: 0.5.0 + '@babel/helper-create-class-features-plugin@7.29.3(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) @@ -2307,6 +2519,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-create-class-features-plugin@8.0.7(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-annotate-as-pure': 8.0.0 + '@babel/helper-member-expression-to-functions': 8.0.5 + '@babel/helper-optimise-call-expression': 8.0.0 + '@babel/helper-replace-supers': 8.0.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 + '@babel/traverse': 8.0.7 + verkit: 0.5.0 + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) @@ -2327,6 +2550,8 @@ snapshots: '@babel/helper-globals@7.28.0': {} + '@babel/helper-globals@8.0.6': {} + '@babel/helper-member-expression-to-functions@7.28.5(supports-color@8.1.1)': dependencies: '@babel/traverse': 7.29.0(supports-color@8.1.1) @@ -2334,6 +2559,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-member-expression-to-functions@8.0.5': + dependencies: + '@babel/traverse': 8.0.7 + '@babel/types': 8.0.8 + '@babel/helper-module-imports@7.28.6(supports-color@8.1.1)': dependencies: '@babel/traverse': 7.29.0(supports-color@8.1.1) @@ -2341,6 +2571,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-imports@8.0.0': + dependencies: + '@babel/traverse': 8.0.7 + '@babel/types': 8.0.8 + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) @@ -2350,12 +2585,27 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@8.0.6(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-module-imports': 8.0.0 + '@babel/helper-validator-identifier': 8.0.6 + '@babel/traverse': 8.0.7 + '@babel/helper-optimise-call-expression@7.27.1': dependencies: '@babel/types': 7.29.0 + '@babel/helper-optimise-call-expression@8.0.0': + dependencies: + '@babel/types': 8.0.8 + '@babel/helper-plugin-utils@7.28.6': {} + '@babel/helper-plugin-utils@8.0.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) @@ -2374,6 +2624,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-replace-supers@8.0.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-member-expression-to-functions': 8.0.5 + '@babel/helper-optimise-call-expression': 8.0.0 + '@babel/traverse': 8.0.7 + '@babel/helper-skip-transparent-expression-wrappers@7.27.1(supports-color@8.1.1)': dependencies: '@babel/traverse': 7.29.0(supports-color@8.1.1) @@ -2381,12 +2638,23 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-skip-transparent-expression-wrappers@8.0.0': + dependencies: + '@babel/traverse': 8.0.7 + '@babel/types': 8.0.8 + '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-string-parser@8.0.8': {} + '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-identifier@8.0.6': {} + '@babel/helper-validator-option@7.27.1': {} + '@babel/helper-validator-option@8.0.0': {} + '@babel/helper-wrap-function@7.28.6(supports-color@8.1.1)': dependencies: '@babel/template': 7.28.6 @@ -2400,10 +2668,19 @@ snapshots: '@babel/template': 7.28.6 '@babel/types': 7.29.0 + '@babel/helpers@8.0.8': + dependencies: + '@babel/template': 8.0.0 + '@babel/types': 8.0.8 + '@babel/parser@7.29.3': dependencies: '@babel/types': 7.29.0 + '@babel/parser@8.0.8': + dependencies: + '@babel/types': 8.0.8 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) @@ -2541,6 +2818,11 @@ snapshots: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-typescript@8.0.3(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 8.0.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) @@ -2715,6 +2997,12 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-modules-commonjs@8.0.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-module-transforms': 8.0.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/helper-plugin-utils': 8.0.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-modules-systemjs@7.29.4(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) @@ -2857,6 +3145,15 @@ snapshots: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-typescript@8.0.6(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-annotate-as-pure': 8.0.0 + '@babel/helper-create-class-features-plugin': 8.0.7(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/helper-plugin-utils': 8.0.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 + '@babel/plugin-syntax-typescript': 8.0.3(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) @@ -2964,6 +3261,14 @@ snapshots: '@babel/types': 7.29.0 esutils: 2.0.3 + '@babel/preset-typescript@8.0.7(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 8.0.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/helper-validator-option': 8.0.0 + '@babel/plugin-transform-modules-commonjs': 8.0.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-typescript': 8.0.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/runtime@7.29.2': {} '@babel/template@7.28.6': @@ -2972,6 +3277,12 @@ snapshots: '@babel/parser': 7.29.3 '@babel/types': 7.29.0 + '@babel/template@8.0.0': + dependencies: + '@babel/code-frame': 8.0.6 + '@babel/parser': 8.0.8 + '@babel/types': 8.0.8 + '@babel/traverse@7.29.0(supports-color@8.1.1)': dependencies: '@babel/code-frame': 7.29.0 @@ -2984,11 +3295,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@8.0.7': + dependencies: + '@babel/code-frame': 8.0.6 + '@babel/generator': 8.0.6 + '@babel/helper-globals': 8.0.6 + '@babel/parser': 8.0.8 + '@babel/template': 8.0.0 + '@babel/types': 8.0.8 + obug: 3.0.0 + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@babel/types@8.0.8': + dependencies: + '@babel/helper-string-parser': 8.0.8 + '@babel/helper-validator-identifier': 8.0.6 + '@bcoe/v8-coverage@0.2.3': {} '@changesets/apply-release-plan@7.1.1': @@ -3332,6 +3658,11 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/gen-mapping@0.4.0-beta.0': + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/remapping@2.3.5': dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -3341,6 +3672,8 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/sourcemap-codec@1.6.0': {} + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -3408,6 +3741,8 @@ snapshots: dependencies: '@babel/types': 7.29.0 + '@types/gensync@1.0.5': {} + '@types/graceful-fs@4.1.9': dependencies: '@types/node': 25.8.0 @@ -3422,6 +3757,8 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 + '@types/jsesc@2.5.1': {} + '@types/node@12.20.55': {} '@types/node@25.8.0': @@ -3704,6 +4041,8 @@ snapshots: emoji-regex@8.0.0: {} + empathic@2.1.0: {} + enquirer@2.4.1: dependencies: ansi-colors: 4.1.3 @@ -3790,6 +4129,8 @@ snapshots: locate-path: 5.0.0 path-exists: 4.0.0 + flru@1.0.2: {} + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -3872,6 +4213,8 @@ snapshots: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 + import-meta-resolve@4.2.0: {} + imurmurhash@0.1.4: {} inflight@1.0.6: @@ -4279,6 +4622,8 @@ snapshots: - supports-color - ts-node + js-tokens@10.0.0: {} + js-tokens@4.0.0: {} js-yaml@3.14.2: @@ -4372,6 +4717,8 @@ snapshots: dependencies: path-key: 3.1.1 + obug@3.0.0: {} + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -4678,6 +5025,8 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 + verkit@0.5.0: {} + walker@1.0.8: dependencies: makeerror: 1.0.12 diff --git a/scripts/babel8.js b/scripts/babel8.js new file mode 100644 index 00000000..0b94f868 --- /dev/null +++ b/scripts/babel8.js @@ -0,0 +1,140 @@ +// Runs the built plugin (`lib/`) through Babel 8 over the fixture suite and +// compares against the same output.js / error.js files Jest uses on Babel 7. +// A fixture that also runs Babel's own presets or plugins has a snapshot that +// differs between majors by design, so it runs with this plugin alone and +// must match Babel 7's output instead. Babel 8 ships as ESM only, which +// Jest's module sandbox cannot require, so this runs as plain Node. Run with +// `pnpm build && pnpm test:babel8`. +const fs = require('fs') +const path = require('path') +const babel7 = require('@babel/core') +const babel = require('babel8') +const presetTypescript = require('babel8-preset-typescript').default + +const ROOT = path.resolve(__dirname, '..') +const FIXTURES = path.join(ROOT, 'test', 'fixtures') +const PLUGIN = '../../../src' + +const usesOtherBabelPlugins = config => + [...(config.presets || []), ...(config.plugins || [])].some( + entry => (Array.isArray(entry) ? entry[0] : entry) !== PLUGIN + ) + +const SKIP = { + 'imports-inside-exported-ambient-namespace': + 'Babel 8 rejects an import inside `declare namespace` while parsing, as TypeScript does', +} + +// Fixtures always parse as code.js, so the extension rules run here +const TYPESCRIPT_CASES = [ + { + file: 'a.ts', + code: 'export const C = B', + expected: 'export const C = B;\n', + }, + { + file: 'a.tsx', + code: 'const A =
', + expected: 'const A =
;\n', + }, +] + +// Mirrors the babel-test patch in patches/ so error.js matches across machines +const normalizeError = e => + String(e) + .replace(/\u001b\[[0-9;]*m/g, '') + .replace( + new RegExp( + ROOT.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace( + /\\\\|\//g, + '[\\\\/]' + ), + 'gi' + ), + '' + ) + .replace(/[^\s:]*/g, p => p.replace(/\\/g, '/')) + '\n' + +const read = file => + fs.existsSync(file) ? fs.readFileSync(file, 'utf8') : null + +// Babel reads .babelrc as JSON5; the fixtures only lean on trailing commas +const readConfig = dir => + JSON.parse(read(path.join(dir, '.babelrc')).replace(/,(\s*[\]}])/g, '$1')) + +const transform = async (instance, code, options) => { + try { + const result = await instance.transformAsync(code, { + ...options, + babelrc: false, + configFile: false, + cwd: ROOT, + }) + return result.code + '\n' + } catch (e) { + return normalizeError(e) + } +} + +const main = async () => { + const lib = path.join(ROOT, 'lib', 'index.js') + if (!fs.existsSync(lib)) { + console.error('lib/ is missing. Run `pnpm build` first.') + process.exit(1) + } + + let passed = 0 + const skipped = [] + const failed = [] + + for (const name of fs.readdirSync(FIXTURES).sort()) { + const dir = path.join(FIXTURES, name) + const config = readConfig(dir) + + if (SKIP[name]) { + skipped.push(`${name}: ${SKIP[name]}`) + continue + } + + const filename = path.join(dir, 'code.js') + const code = read(filename) + const pluginOnly = usesOtherBabelPlugins(config) + const options = { + ...config, + presets: [], + plugins: config.plugins + .filter(entry => (Array.isArray(entry) ? entry[0] : entry) === PLUGIN) + .map(entry => (Array.isArray(entry) ? [lib, ...entry.slice(1)] : lib)), + filename, + } + + const actual = await transform(babel, code, options) + const expected = pluginOnly + ? await transform(babel7, code, options) + : (read(path.join(dir, 'output.js')) ?? read(path.join(dir, 'error.js'))) + if (actual === expected) passed++ + else failed.push({ name, expected, actual }) + } + + for (const { file, code, expected } of TYPESCRIPT_CASES) { + const actual = await transform(babel, code, { + filename: path.join(ROOT, file), + plugins: [lib], + presets: [presetTypescript], + }) + if (actual === expected) passed++ + else failed.push({ name: file, expected, actual }) + } + + for (const { name, expected, actual } of failed) { + console.log(`\n✗ ${name}\n--- expected\n${expected}--- actual\n${actual}`) + } + console.log(`\nSkipped on Babel ${babel.version}:`) + for (const line of skipped) console.log(` ${line}`) + console.log( + `\nBabel ${babel.version}: ${passed} passed, ${failed.length} failed, ${skipped.length} skipped` + ) + if (failed.length) process.exit(1) +} + +main() diff --git a/src/index.js b/src/index.js index 78e77f18..d8384c93 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,3 @@ -import syntax from '@babel/plugin-syntax-jsx' import assignStyledRequired from './visitors/assignStyledRequired' import transpileCssProp from './visitors/transpileCssProp' import { @@ -13,7 +12,21 @@ export default function ({ types: t }) { const processTaggedTemplateVisit = processTaggedTemplate(t) return { - inherits: syntax, + // Same as @babel/plugin-syntax-jsx, whose peer range is pinned to one + // Babel major. Presets run after this, and Babel 8's TypeScript preset + // neither removes `jsx` from .ts files nor adds it to .tsx files, so the + // extension decides: `jsx` breaks `value` assertions in .ts + manipulateOptions(opts, parserOpts) { + if ( + /\.[cm]?ts$/.test(opts.filename) || + parserOpts.plugins.some( + p => (Array.isArray(p) ? p[0] : p) === 'typescript' + ) + ) { + return + } + parserOpts.plugins.push('jsx') + }, visitor: { Program(path, state) { path.traverse( diff --git a/src/visitors/transpileCssProp.js b/src/visitors/transpileCssProp.js index c34ac531..b378fa32 100644 --- a/src/visitors/transpileCssProp.js +++ b/src/visitors/transpileCssProp.js @@ -95,7 +95,6 @@ export default t => { const elem = path.parentPath const name = getName(elem.node.name, t, path) - const nameExpression = getNameExpression(elem.node.name, t, path) const id = path.scope.generateUidIdentifier( 'Styled' + name.replace(/^([a-z])/, (match, p1) => p1.toUpperCase()) ) @@ -106,7 +105,9 @@ export default t => { if (TAG_NAME_REGEXP.test(name)) { styled = t.callExpression(importName, [t.stringLiteral(name)]) } else { - styled = t.callExpression(importName, [nameExpression]) + styled = t.callExpression(importName, [ + getNameExpression(elem.node.name, t, path), + ]) if ( bindings[name] && @@ -162,10 +163,10 @@ export default t => { (t.isJSXAttribute(x) ? x.name.name !== 'css' : false) ) - elem.node.name = t.jSXIdentifier(id.name) + elem.node.name = t.jsxIdentifier(id.name) if (elem.parentPath.node.closingElement) { - elem.parentPath.node.closingElement.name = t.jSXIdentifier(id.name) + elem.parentPath.node.closingElement.name = t.jsxIdentifier(id.name) } // object syntax @@ -209,9 +210,9 @@ export default t => { const identifier = getLocalIdentifier(path) elem.node.attributes.push( - t.jSXAttribute( - t.jSXIdentifier(identifier.name), - t.jSXExpressionContainer(property.key) + t.jsxAttribute( + t.jsxIdentifier(identifier.name), + t.jsxExpressionContainer(property.key) ) ) @@ -240,9 +241,9 @@ export default t => { const identifier = getLocalIdentifier(path) elem.node.attributes.push( - t.jSXAttribute( - t.jSXIdentifier(identifier.name), - t.jSXExpressionContainer(property.argument) + t.jsxAttribute( + t.jsxIdentifier(identifier.name), + t.jsxExpressionContainer(property.argument) ) ) @@ -267,9 +268,9 @@ export default t => { const identifier = getLocalIdentifier(path) elem.node.attributes.push( - t.jSXAttribute( - t.jSXIdentifier(identifier.name), - t.jSXExpressionContainer(property.value) + t.jsxAttribute( + t.jsxIdentifier(identifier.name), + t.jsxExpressionContainer(property.value) ) ) @@ -311,9 +312,9 @@ export default t => { const p = t.identifier('p') elem.node.attributes.push( - t.jSXAttribute( - t.jSXIdentifier(identifier.name), - t.jSXExpressionContainer(ex) + t.jsxAttribute( + t.jsxIdentifier(identifier.name), + t.jsxExpressionContainer(ex) ) ) diff --git a/test/fixtures/css-prop-on-hyphenated-element/.babelrc b/test/fixtures/css-prop-on-hyphenated-element/.babelrc new file mode 100644 index 00000000..21885a8b --- /dev/null +++ b/test/fixtures/css-prop-on-hyphenated-element/.babelrc @@ -0,0 +1,13 @@ +{ + "plugins": [ + [ + "../../../src", + { + "ssr": false, + "displayName": false, + "transpileTemplateLiterals": false, + "minify": false + } + ] + ] +} diff --git a/test/fixtures/css-prop-on-hyphenated-element/code.js b/test/fixtures/css-prop-on-hyphenated-element/code.js new file mode 100644 index 00000000..8b77a294 --- /dev/null +++ b/test/fixtures/css-prop-on-hyphenated-element/code.js @@ -0,0 +1,3 @@ +import styled from 'styled-components' + +const Element = () => H diff --git a/test/fixtures/css-prop-on-hyphenated-element/output.js b/test/fixtures/css-prop-on-hyphenated-element/output.js new file mode 100644 index 00000000..fbee308b --- /dev/null +++ b/test/fixtures/css-prop-on-hyphenated-element/output.js @@ -0,0 +1,3 @@ +import styled from 'styled-components'; +const Element = () => <_StyledButtonGhost>H; +var _StyledButtonGhost = styled("button-ghost")`flex: 1`; diff --git a/test/fixtures/typescript-parser-plugin-with-options-keeps-angle-bracket-assertions/.babelrc b/test/fixtures/typescript-parser-plugin-with-options-keeps-angle-bracket-assertions/.babelrc new file mode 100644 index 00000000..e10817d7 --- /dev/null +++ b/test/fixtures/typescript-parser-plugin-with-options-keeps-angle-bracket-assertions/.babelrc @@ -0,0 +1,17 @@ +{ + "parserOpts": { + "plugins": [["typescript", { "dts": false }]] + }, + "plugins": [ + [ + "../../../src", + { + "displayName": true, + "fileName": false, + "ssr": false, + "transpileTemplateLiterals": false, + "minify": false + } + ] + ] +} diff --git a/test/fixtures/typescript-parser-plugin-with-options-keeps-angle-bracket-assertions/code.js b/test/fixtures/typescript-parser-plugin-with-options-keeps-angle-bracket-assertions/code.js new file mode 100644 index 00000000..5f5dff74 --- /dev/null +++ b/test/fixtures/typescript-parser-plugin-with-options-keeps-angle-bracket-assertions/code.js @@ -0,0 +1,4 @@ +import styled from 'styled-components' + +const Foo = styled.div`color: red;` +const wrapped = Foo diff --git a/test/fixtures/typescript-parser-plugin-with-options-keeps-angle-bracket-assertions/output.js b/test/fixtures/typescript-parser-plugin-with-options-keeps-angle-bracket-assertions/output.js new file mode 100644 index 00000000..4edf2e3c --- /dev/null +++ b/test/fixtures/typescript-parser-plugin-with-options-keeps-angle-bracket-assertions/output.js @@ -0,0 +1,5 @@ +import styled from 'styled-components'; +const Foo = styled.div.withConfig({ + displayName: "Foo" +})`color: red;`; +const wrapped = Foo; diff --git a/test/index.test.js b/test/index.test.js index 6e749c65..7dc493c0 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -2,6 +2,8 @@ import fs from 'fs' import path from 'path' import { create } from 'babel-test' import { toMatchFile } from 'jest-file-snapshot' +import { transformSync } from '@babel/core' +import plugin from '../src' expect.extend({ toMatchFile }) @@ -29,3 +31,50 @@ describe('fixture snapshots', () => { expect(leaks).toEqual([]) }) }) + +describe('runtime dependencies', () => { + const majors = range => + new Set((range.match(/\^\d+/g) || []).map(m => m.slice(1))) + const pkg = require('../package.json') + const supported = majors(pkg.peerDependencies['@babel/core']) + + it('accept every @babel/core major the plugin supports', () => { + const narrower = Object.keys(pkg.dependencies) + .map(name => [name, require(`${name}/package.json`).peerDependencies]) + .filter(([, peers]) => peers && peers['@babel/core']) + .filter(([, peers]) => + [...supported].some(major => !majors(peers['@babel/core']).has(major)) + ) + .map(([name, peers]) => `${name} ${peers['@babel/core']}`) + + expect(narrower).toEqual([]) + }) +}) + +describe('jsx parser option', () => { + // Stands in for Babel 8's TypeScript preset, which runs after this plugin + // and leaves any `jsx` parser plugin in place + const lateTypescript = () => ({ + manipulateOptions(opts, parserOpts) { + parserOpts.plugins.push('typescript') + }, + }) + + const transform = (code, filename) => + transformSync(code, { + babelrc: false, + configFile: false, + filename, + plugins: [plugin, lateTypescript], + }).code + + it.each(['a.ts', 'a.mts', 'a.cts'])('stays off for %s', filename => { + expect(transform('export const C = B', filename)).toBe( + 'export const C = B;' + ) + }) + + it.each(['a.tsx', 'a.js'])('turns on for %s', filename => { + expect(transform('const A =
', filename)).toBe('const A =
;') + }) +})