Split files
This commit is contained in:
parent
f741ba41c2
commit
5a3b03b69b
@ -4,5 +4,6 @@ const { extendConfig } = require("@aet/eslint-rules");
|
|||||||
module.exports = extendConfig({
|
module.exports = extendConfig({
|
||||||
rules: {
|
rules: {
|
||||||
"class-methods-use-this": "error",
|
"class-methods-use-this": "error",
|
||||||
|
"import-x/no-unresolved": ["error", { ignore: ["react"] }],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
14
package.json
14
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@aet/tailwind",
|
"name": "@aet/tailwind",
|
||||||
"version": "1.0.9",
|
"version": "1.0.10",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "./scripts/index.ts",
|
"build": "./scripts/index.ts",
|
||||||
@ -33,7 +33,7 @@
|
|||||||
"@types/bun": "^1.1.6",
|
"@types/bun": "^1.1.6",
|
||||||
"@types/dedent": "^0.7.2",
|
"@types/dedent": "^0.7.2",
|
||||||
"@types/lodash": "^4.17.7",
|
"@types/lodash": "^4.17.7",
|
||||||
"@types/node": "^22.2.0",
|
"@types/node": "^22.4.0",
|
||||||
"@types/postcss-safe-parser": "^5.0.4",
|
"@types/postcss-safe-parser": "^5.0.4",
|
||||||
"@types/react": "^18.3.3",
|
"@types/react": "^18.3.3",
|
||||||
"@types/stylis": "^4.2.6",
|
"@types/stylis": "^4.2.6",
|
||||||
@ -47,11 +47,11 @@
|
|||||||
"nolyfill": "^1.0.39",
|
"nolyfill": "^1.0.39",
|
||||||
"postcss-nested": "^6.2.0",
|
"postcss-nested": "^6.2.0",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"tailwindcss": "^3.4.9",
|
"tailwindcss": "^3.4.10",
|
||||||
"tslib": "^2.6.3",
|
"tslib": "^2.6.3",
|
||||||
"tsup": "^8.2.4",
|
"tsup": "^8.2.4",
|
||||||
"typescript": "^5.5.4",
|
"typescript": "^5.5.4",
|
||||||
"vite": "^5.4.0",
|
"vite": "^5.4.1",
|
||||||
"vitest": "^2.0.5"
|
"vitest": "^2.0.5"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
@ -60,14 +60,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.25.2",
|
"@babel/core": "^7.25.2",
|
||||||
"@emotion/hash": "^0.9.2",
|
"@emotion/hash": "^0.9.2",
|
||||||
"esbuild": "^0.23.0",
|
"esbuild": "^0.23.1",
|
||||||
"json5": "^2.2.3",
|
"json5": "^2.2.3",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"postcss": "^8.4.41",
|
"postcss": "^8.4.41",
|
||||||
"postcss-selector-parser": "^6.1.1",
|
"postcss-selector-parser": "^6.1.2",
|
||||||
"stylis": "^4.3.2",
|
"stylis": "^4.3.2",
|
||||||
"tiny-invariant": "^1.3.3",
|
"tiny-invariant": "^1.3.3",
|
||||||
"type-fest": "^4.24.0"
|
"type-fest": "^4.25.0"
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"arrowParens": "avoid",
|
"arrowParens": "avoid",
|
||||||
|
298
pnpm-lock.yaml
generated
298
pnpm-lock.yaml
generated
@ -18,8 +18,8 @@ importers:
|
|||||||
specifier: ^0.9.2
|
specifier: ^0.9.2
|
||||||
version: 0.9.2
|
version: 0.9.2
|
||||||
esbuild:
|
esbuild:
|
||||||
specifier: ^0.23.0
|
specifier: ^0.23.1
|
||||||
version: 0.23.0
|
version: 0.23.1
|
||||||
json5:
|
json5:
|
||||||
specifier: ^2.2.3
|
specifier: ^2.2.3
|
||||||
version: 2.2.3
|
version: 2.2.3
|
||||||
@ -30,8 +30,8 @@ importers:
|
|||||||
specifier: ^8.4.41
|
specifier: ^8.4.41
|
||||||
version: 8.4.41
|
version: 8.4.41
|
||||||
postcss-selector-parser:
|
postcss-selector-parser:
|
||||||
specifier: ^6.1.1
|
specifier: ^6.1.2
|
||||||
version: 6.1.1
|
version: 6.1.2
|
||||||
stylis:
|
stylis:
|
||||||
specifier: ^4.3.2
|
specifier: ^4.3.2
|
||||||
version: 4.3.2
|
version: 4.3.2
|
||||||
@ -39,8 +39,8 @@ importers:
|
|||||||
specifier: ^1.3.3
|
specifier: ^1.3.3
|
||||||
version: 1.3.3
|
version: 1.3.3
|
||||||
type-fest:
|
type-fest:
|
||||||
specifier: ^4.24.0
|
specifier: ^4.25.0
|
||||||
version: 4.24.0
|
version: 4.25.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@aet/eslint-rules':
|
'@aet/eslint-rules':
|
||||||
specifier: 1.0.1-beta.24
|
specifier: 1.0.1-beta.24
|
||||||
@ -58,8 +58,8 @@ importers:
|
|||||||
specifier: ^4.17.7
|
specifier: ^4.17.7
|
||||||
version: 4.17.7
|
version: 4.17.7
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.2.0
|
specifier: ^22.4.0
|
||||||
version: 22.2.0
|
version: 22.4.0
|
||||||
'@types/postcss-safe-parser':
|
'@types/postcss-safe-parser':
|
||||||
specifier: ^5.0.4
|
specifier: ^5.0.4
|
||||||
version: 5.0.4
|
version: 5.0.4
|
||||||
@ -86,7 +86,7 @@ importers:
|
|||||||
version: 1.5.3
|
version: 1.5.3
|
||||||
esbuild-register:
|
esbuild-register:
|
||||||
specifier: ^3.6.0
|
specifier: ^3.6.0
|
||||||
version: 3.6.0(esbuild@0.23.0)
|
version: 3.6.0(esbuild@0.23.1)
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^8.57.0
|
specifier: ^8.57.0
|
||||||
version: 8.57.0
|
version: 8.57.0
|
||||||
@ -100,8 +100,8 @@ importers:
|
|||||||
specifier: ^3.3.3
|
specifier: ^3.3.3
|
||||||
version: 3.3.3
|
version: 3.3.3
|
||||||
tailwindcss:
|
tailwindcss:
|
||||||
specifier: ^3.4.9
|
specifier: ^3.4.10
|
||||||
version: 3.4.9
|
version: 3.4.10
|
||||||
tslib:
|
tslib:
|
||||||
specifier: ^2.6.3
|
specifier: ^2.6.3
|
||||||
version: 2.6.3
|
version: 2.6.3
|
||||||
@ -112,11 +112,11 @@ importers:
|
|||||||
specifier: ^5.5.4
|
specifier: ^5.5.4
|
||||||
version: 5.5.4
|
version: 5.5.4
|
||||||
vite:
|
vite:
|
||||||
specifier: ^5.4.0
|
specifier: ^5.4.1
|
||||||
version: 5.4.0(@types/node@22.2.0)
|
version: 5.4.1(@types/node@22.4.0)
|
||||||
vitest:
|
vitest:
|
||||||
specifier: ^2.0.5
|
specifier: ^2.0.5
|
||||||
version: 2.0.5(@types/node@22.2.0)
|
version: 2.0.5(@types/node@22.4.0)
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
@ -226,8 +226,8 @@ packages:
|
|||||||
cpu: [ppc64]
|
cpu: [ppc64]
|
||||||
os: [aix]
|
os: [aix]
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.23.0':
|
'@esbuild/aix-ppc64@0.23.1':
|
||||||
resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==}
|
resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [ppc64]
|
cpu: [ppc64]
|
||||||
os: [aix]
|
os: [aix]
|
||||||
@ -238,8 +238,8 @@ packages:
|
|||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [android]
|
os: [android]
|
||||||
|
|
||||||
'@esbuild/android-arm64@0.23.0':
|
'@esbuild/android-arm64@0.23.1':
|
||||||
resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==}
|
resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [android]
|
os: [android]
|
||||||
@ -250,8 +250,8 @@ packages:
|
|||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [android]
|
os: [android]
|
||||||
|
|
||||||
'@esbuild/android-arm@0.23.0':
|
'@esbuild/android-arm@0.23.1':
|
||||||
resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==}
|
resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [android]
|
os: [android]
|
||||||
@ -262,8 +262,8 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [android]
|
os: [android]
|
||||||
|
|
||||||
'@esbuild/android-x64@0.23.0':
|
'@esbuild/android-x64@0.23.1':
|
||||||
resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==}
|
resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [android]
|
os: [android]
|
||||||
@ -274,8 +274,8 @@ packages:
|
|||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@esbuild/darwin-arm64@0.23.0':
|
'@esbuild/darwin-arm64@0.23.1':
|
||||||
resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==}
|
resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
@ -286,8 +286,8 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@esbuild/darwin-x64@0.23.0':
|
'@esbuild/darwin-x64@0.23.1':
|
||||||
resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==}
|
resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
@ -298,8 +298,8 @@ packages:
|
|||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [freebsd]
|
os: [freebsd]
|
||||||
|
|
||||||
'@esbuild/freebsd-arm64@0.23.0':
|
'@esbuild/freebsd-arm64@0.23.1':
|
||||||
resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==}
|
resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [freebsd]
|
os: [freebsd]
|
||||||
@ -310,8 +310,8 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [freebsd]
|
os: [freebsd]
|
||||||
|
|
||||||
'@esbuild/freebsd-x64@0.23.0':
|
'@esbuild/freebsd-x64@0.23.1':
|
||||||
resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==}
|
resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [freebsd]
|
os: [freebsd]
|
||||||
@ -322,8 +322,8 @@ packages:
|
|||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@esbuild/linux-arm64@0.23.0':
|
'@esbuild/linux-arm64@0.23.1':
|
||||||
resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==}
|
resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -334,8 +334,8 @@ packages:
|
|||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@esbuild/linux-arm@0.23.0':
|
'@esbuild/linux-arm@0.23.1':
|
||||||
resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==}
|
resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -346,8 +346,8 @@ packages:
|
|||||||
cpu: [ia32]
|
cpu: [ia32]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@esbuild/linux-ia32@0.23.0':
|
'@esbuild/linux-ia32@0.23.1':
|
||||||
resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==}
|
resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [ia32]
|
cpu: [ia32]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -358,8 +358,8 @@ packages:
|
|||||||
cpu: [loong64]
|
cpu: [loong64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@esbuild/linux-loong64@0.23.0':
|
'@esbuild/linux-loong64@0.23.1':
|
||||||
resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==}
|
resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [loong64]
|
cpu: [loong64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -370,8 +370,8 @@ packages:
|
|||||||
cpu: [mips64el]
|
cpu: [mips64el]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@esbuild/linux-mips64el@0.23.0':
|
'@esbuild/linux-mips64el@0.23.1':
|
||||||
resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==}
|
resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [mips64el]
|
cpu: [mips64el]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -382,8 +382,8 @@ packages:
|
|||||||
cpu: [ppc64]
|
cpu: [ppc64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@esbuild/linux-ppc64@0.23.0':
|
'@esbuild/linux-ppc64@0.23.1':
|
||||||
resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==}
|
resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [ppc64]
|
cpu: [ppc64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -394,8 +394,8 @@ packages:
|
|||||||
cpu: [riscv64]
|
cpu: [riscv64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@esbuild/linux-riscv64@0.23.0':
|
'@esbuild/linux-riscv64@0.23.1':
|
||||||
resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==}
|
resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [riscv64]
|
cpu: [riscv64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -406,8 +406,8 @@ packages:
|
|||||||
cpu: [s390x]
|
cpu: [s390x]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@esbuild/linux-s390x@0.23.0':
|
'@esbuild/linux-s390x@0.23.1':
|
||||||
resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==}
|
resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [s390x]
|
cpu: [s390x]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -418,8 +418,8 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@esbuild/linux-x64@0.23.0':
|
'@esbuild/linux-x64@0.23.1':
|
||||||
resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==}
|
resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -430,14 +430,14 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [netbsd]
|
os: [netbsd]
|
||||||
|
|
||||||
'@esbuild/netbsd-x64@0.23.0':
|
'@esbuild/netbsd-x64@0.23.1':
|
||||||
resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==}
|
resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [netbsd]
|
os: [netbsd]
|
||||||
|
|
||||||
'@esbuild/openbsd-arm64@0.23.0':
|
'@esbuild/openbsd-arm64@0.23.1':
|
||||||
resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==}
|
resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [openbsd]
|
os: [openbsd]
|
||||||
@ -448,8 +448,8 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [openbsd]
|
os: [openbsd]
|
||||||
|
|
||||||
'@esbuild/openbsd-x64@0.23.0':
|
'@esbuild/openbsd-x64@0.23.1':
|
||||||
resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==}
|
resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [openbsd]
|
os: [openbsd]
|
||||||
@ -460,8 +460,8 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [sunos]
|
os: [sunos]
|
||||||
|
|
||||||
'@esbuild/sunos-x64@0.23.0':
|
'@esbuild/sunos-x64@0.23.1':
|
||||||
resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==}
|
resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [sunos]
|
os: [sunos]
|
||||||
@ -472,8 +472,8 @@ packages:
|
|||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@esbuild/win32-arm64@0.23.0':
|
'@esbuild/win32-arm64@0.23.1':
|
||||||
resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==}
|
resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@ -484,8 +484,8 @@ packages:
|
|||||||
cpu: [ia32]
|
cpu: [ia32]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@esbuild/win32-ia32@0.23.0':
|
'@esbuild/win32-ia32@0.23.1':
|
||||||
resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==}
|
resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [ia32]
|
cpu: [ia32]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@ -496,8 +496,8 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@esbuild/win32-x64@0.23.0':
|
'@esbuild/win32-x64@0.23.1':
|
||||||
resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==}
|
resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@ -732,8 +732,8 @@ packages:
|
|||||||
'@types/node@20.12.14':
|
'@types/node@20.12.14':
|
||||||
resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==}
|
resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==}
|
||||||
|
|
||||||
'@types/node@22.2.0':
|
'@types/node@22.4.0':
|
||||||
resolution: {integrity: sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==}
|
resolution: {integrity: sha512-49AbMDwYUz7EXxKU/r7mXOsxwFr4BYbvB7tWYxVuLdb2ibd30ijjXINSMAHiEEZk5PCRBmW1gUeisn2VMKt3cQ==}
|
||||||
|
|
||||||
'@types/normalize-package-data@2.4.4':
|
'@types/normalize-package-data@2.4.4':
|
||||||
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
|
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
|
||||||
@ -1198,8 +1198,8 @@ packages:
|
|||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
esbuild@0.23.0:
|
esbuild@0.23.1:
|
||||||
resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==}
|
resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@ -1955,8 +1955,8 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.2.14
|
postcss: ^8.2.14
|
||||||
|
|
||||||
postcss-selector-parser@6.1.1:
|
postcss-selector-parser@6.1.2:
|
||||||
resolution: {integrity: sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==}
|
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
postcss-value-parser@4.2.0:
|
postcss-value-parser@4.2.0:
|
||||||
@ -2181,8 +2181,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==}
|
resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==}
|
||||||
engines: {node: ^14.18.0 || >=16.0.0}
|
engines: {node: ^14.18.0 || >=16.0.0}
|
||||||
|
|
||||||
tailwindcss@3.4.9:
|
tailwindcss@3.4.10:
|
||||||
resolution: {integrity: sha512-1SEOvRr6sSdV5IDf9iC+NU4dhwdqzF4zKKq3sAbasUWHEM6lsMhX+eNN5gkPx1BvLFEnZQEUFbXnGj8Qlp83Pg==}
|
resolution: {integrity: sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
@ -2292,8 +2292,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
|
resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
type-fest@4.24.0:
|
type-fest@4.25.0:
|
||||||
resolution: {integrity: sha512-spAaHzc6qre0TlZQQ2aA/nGMe+2Z/wyGk5Z+Ru2VUfdNwT6kWO6TjevOlpebsATEG1EIQ2sOiDszud3lO5mt/Q==}
|
resolution: {integrity: sha512-bRkIGlXsnGBRBQRAY56UXBm//9qH4bmJfFvq83gSz41N282df+fjy8ofcEgc1sM8geNt5cl6mC2g9Fht1cs8Aw==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
typescript@5.5.4:
|
typescript@5.5.4:
|
||||||
@ -2304,8 +2304,8 @@ packages:
|
|||||||
undici-types@5.26.5:
|
undici-types@5.26.5:
|
||||||
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
|
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
|
||||||
|
|
||||||
undici-types@6.13.0:
|
undici-types@6.19.6:
|
||||||
resolution: {integrity: sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==}
|
resolution: {integrity: sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==}
|
||||||
|
|
||||||
update-browserslist-db@1.1.0:
|
update-browserslist-db@1.1.0:
|
||||||
resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==}
|
resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==}
|
||||||
@ -2327,8 +2327,8 @@ packages:
|
|||||||
engines: {node: ^18.0.0 || >=20.0.0}
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
vite@5.4.0:
|
vite@5.4.1:
|
||||||
resolution: {integrity: sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==}
|
resolution: {integrity: sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==}
|
||||||
engines: {node: ^18.0.0 || >=20.0.0}
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2624,142 +2624,142 @@ snapshots:
|
|||||||
'@esbuild/aix-ppc64@0.21.5':
|
'@esbuild/aix-ppc64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.23.0':
|
'@esbuild/aix-ppc64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/android-arm64@0.21.5':
|
'@esbuild/android-arm64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/android-arm64@0.23.0':
|
'@esbuild/android-arm64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/android-arm@0.21.5':
|
'@esbuild/android-arm@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/android-arm@0.23.0':
|
'@esbuild/android-arm@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/android-x64@0.21.5':
|
'@esbuild/android-x64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/android-x64@0.23.0':
|
'@esbuild/android-x64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/darwin-arm64@0.21.5':
|
'@esbuild/darwin-arm64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/darwin-arm64@0.23.0':
|
'@esbuild/darwin-arm64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/darwin-x64@0.21.5':
|
'@esbuild/darwin-x64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/darwin-x64@0.23.0':
|
'@esbuild/darwin-x64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/freebsd-arm64@0.21.5':
|
'@esbuild/freebsd-arm64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/freebsd-arm64@0.23.0':
|
'@esbuild/freebsd-arm64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/freebsd-x64@0.21.5':
|
'@esbuild/freebsd-x64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/freebsd-x64@0.23.0':
|
'@esbuild/freebsd-x64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-arm64@0.21.5':
|
'@esbuild/linux-arm64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-arm64@0.23.0':
|
'@esbuild/linux-arm64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-arm@0.21.5':
|
'@esbuild/linux-arm@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-arm@0.23.0':
|
'@esbuild/linux-arm@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-ia32@0.21.5':
|
'@esbuild/linux-ia32@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-ia32@0.23.0':
|
'@esbuild/linux-ia32@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-loong64@0.21.5':
|
'@esbuild/linux-loong64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-loong64@0.23.0':
|
'@esbuild/linux-loong64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-mips64el@0.21.5':
|
'@esbuild/linux-mips64el@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-mips64el@0.23.0':
|
'@esbuild/linux-mips64el@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-ppc64@0.21.5':
|
'@esbuild/linux-ppc64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-ppc64@0.23.0':
|
'@esbuild/linux-ppc64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-riscv64@0.21.5':
|
'@esbuild/linux-riscv64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-riscv64@0.23.0':
|
'@esbuild/linux-riscv64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-s390x@0.21.5':
|
'@esbuild/linux-s390x@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-s390x@0.23.0':
|
'@esbuild/linux-s390x@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-x64@0.21.5':
|
'@esbuild/linux-x64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/linux-x64@0.23.0':
|
'@esbuild/linux-x64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/netbsd-x64@0.21.5':
|
'@esbuild/netbsd-x64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/netbsd-x64@0.23.0':
|
'@esbuild/netbsd-x64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/openbsd-arm64@0.23.0':
|
'@esbuild/openbsd-arm64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/openbsd-x64@0.21.5':
|
'@esbuild/openbsd-x64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/openbsd-x64@0.23.0':
|
'@esbuild/openbsd-x64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/sunos-x64@0.21.5':
|
'@esbuild/sunos-x64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/sunos-x64@0.23.0':
|
'@esbuild/sunos-x64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/win32-arm64@0.21.5':
|
'@esbuild/win32-arm64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/win32-arm64@0.23.0':
|
'@esbuild/win32-arm64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/win32-ia32@0.21.5':
|
'@esbuild/win32-ia32@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/win32-ia32@0.23.0':
|
'@esbuild/win32-ia32@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/win32-x64@0.21.5':
|
'@esbuild/win32-x64@0.21.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@esbuild/win32-x64@0.23.0':
|
'@esbuild/win32-x64@0.23.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)':
|
'@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)':
|
||||||
@ -3055,9 +3055,9 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 5.26.5
|
undici-types: 5.26.5
|
||||||
|
|
||||||
'@types/node@22.2.0':
|
'@types/node@22.4.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.13.0
|
undici-types: 6.19.6
|
||||||
|
|
||||||
'@types/normalize-package-data@2.4.4': {}
|
'@types/normalize-package-data@2.4.4': {}
|
||||||
|
|
||||||
@ -3076,7 +3076,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/ws@8.5.12':
|
'@types/ws@8.5.12':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 22.2.0
|
'@types/node': 22.4.0
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.0.1(@typescript-eslint/parser@8.0.1(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)':
|
'@typescript-eslint/eslint-plugin@8.0.1(@typescript-eslint/parser@8.0.1(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)':
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -3365,9 +3365,9 @@ snapshots:
|
|||||||
'@types/node': 20.12.14
|
'@types/node': 20.12.14
|
||||||
'@types/ws': 8.5.12
|
'@types/ws': 8.5.12
|
||||||
|
|
||||||
bundle-require@5.0.0(esbuild@0.23.0):
|
bundle-require@5.0.0(esbuild@0.23.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.23.0
|
esbuild: 0.23.1
|
||||||
load-tsconfig: 0.2.5
|
load-tsconfig: 0.2.5
|
||||||
|
|
||||||
cac@6.7.14: {}
|
cac@6.7.14: {}
|
||||||
@ -3527,10 +3527,10 @@ snapshots:
|
|||||||
|
|
||||||
es-module-lexer@1.5.4: {}
|
es-module-lexer@1.5.4: {}
|
||||||
|
|
||||||
esbuild-register@3.6.0(esbuild@0.23.0):
|
esbuild-register@3.6.0(esbuild@0.23.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.3.6
|
debug: 4.3.6
|
||||||
esbuild: 0.23.0
|
esbuild: 0.23.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@ -3560,32 +3560,32 @@ snapshots:
|
|||||||
'@esbuild/win32-ia32': 0.21.5
|
'@esbuild/win32-ia32': 0.21.5
|
||||||
'@esbuild/win32-x64': 0.21.5
|
'@esbuild/win32-x64': 0.21.5
|
||||||
|
|
||||||
esbuild@0.23.0:
|
esbuild@0.23.1:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@esbuild/aix-ppc64': 0.23.0
|
'@esbuild/aix-ppc64': 0.23.1
|
||||||
'@esbuild/android-arm': 0.23.0
|
'@esbuild/android-arm': 0.23.1
|
||||||
'@esbuild/android-arm64': 0.23.0
|
'@esbuild/android-arm64': 0.23.1
|
||||||
'@esbuild/android-x64': 0.23.0
|
'@esbuild/android-x64': 0.23.1
|
||||||
'@esbuild/darwin-arm64': 0.23.0
|
'@esbuild/darwin-arm64': 0.23.1
|
||||||
'@esbuild/darwin-x64': 0.23.0
|
'@esbuild/darwin-x64': 0.23.1
|
||||||
'@esbuild/freebsd-arm64': 0.23.0
|
'@esbuild/freebsd-arm64': 0.23.1
|
||||||
'@esbuild/freebsd-x64': 0.23.0
|
'@esbuild/freebsd-x64': 0.23.1
|
||||||
'@esbuild/linux-arm': 0.23.0
|
'@esbuild/linux-arm': 0.23.1
|
||||||
'@esbuild/linux-arm64': 0.23.0
|
'@esbuild/linux-arm64': 0.23.1
|
||||||
'@esbuild/linux-ia32': 0.23.0
|
'@esbuild/linux-ia32': 0.23.1
|
||||||
'@esbuild/linux-loong64': 0.23.0
|
'@esbuild/linux-loong64': 0.23.1
|
||||||
'@esbuild/linux-mips64el': 0.23.0
|
'@esbuild/linux-mips64el': 0.23.1
|
||||||
'@esbuild/linux-ppc64': 0.23.0
|
'@esbuild/linux-ppc64': 0.23.1
|
||||||
'@esbuild/linux-riscv64': 0.23.0
|
'@esbuild/linux-riscv64': 0.23.1
|
||||||
'@esbuild/linux-s390x': 0.23.0
|
'@esbuild/linux-s390x': 0.23.1
|
||||||
'@esbuild/linux-x64': 0.23.0
|
'@esbuild/linux-x64': 0.23.1
|
||||||
'@esbuild/netbsd-x64': 0.23.0
|
'@esbuild/netbsd-x64': 0.23.1
|
||||||
'@esbuild/openbsd-arm64': 0.23.0
|
'@esbuild/openbsd-arm64': 0.23.1
|
||||||
'@esbuild/openbsd-x64': 0.23.0
|
'@esbuild/openbsd-x64': 0.23.1
|
||||||
'@esbuild/sunos-x64': 0.23.0
|
'@esbuild/sunos-x64': 0.23.1
|
||||||
'@esbuild/win32-arm64': 0.23.0
|
'@esbuild/win32-arm64': 0.23.1
|
||||||
'@esbuild/win32-ia32': 0.23.0
|
'@esbuild/win32-ia32': 0.23.1
|
||||||
'@esbuild/win32-x64': 0.23.0
|
'@esbuild/win32-x64': 0.23.1
|
||||||
|
|
||||||
escalade@3.1.2: {}
|
escalade@3.1.2: {}
|
||||||
|
|
||||||
@ -4358,9 +4358,9 @@ snapshots:
|
|||||||
postcss-nested@6.2.0(postcss@8.4.41):
|
postcss-nested@6.2.0(postcss@8.4.41):
|
||||||
dependencies:
|
dependencies:
|
||||||
postcss: 8.4.41
|
postcss: 8.4.41
|
||||||
postcss-selector-parser: 6.1.1
|
postcss-selector-parser: 6.1.2
|
||||||
|
|
||||||
postcss-selector-parser@6.1.1:
|
postcss-selector-parser@6.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
cssesc: 3.0.0
|
cssesc: 3.0.0
|
||||||
util-deprecate: 1.0.2
|
util-deprecate: 1.0.2
|
||||||
@ -4410,7 +4410,7 @@ snapshots:
|
|||||||
|
|
||||||
remeda@2.10.1:
|
remeda@2.10.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
type-fest: 4.24.0
|
type-fest: 4.25.0
|
||||||
|
|
||||||
require-directory@2.1.1: {}
|
require-directory@2.1.1: {}
|
||||||
|
|
||||||
@ -4574,7 +4574,7 @@ snapshots:
|
|||||||
'@pkgr/core': 0.1.1
|
'@pkgr/core': 0.1.1
|
||||||
tslib: 2.6.3
|
tslib: 2.6.3
|
||||||
|
|
||||||
tailwindcss@3.4.9:
|
tailwindcss@3.4.10:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@alloc/quick-lru': 5.2.0
|
'@alloc/quick-lru': 5.2.0
|
||||||
arg: 5.0.2
|
arg: 5.0.2
|
||||||
@ -4595,7 +4595,7 @@ snapshots:
|
|||||||
postcss-js: 4.0.1(postcss@8.4.41)
|
postcss-js: 4.0.1(postcss@8.4.41)
|
||||||
postcss-load-config: 4.0.2(postcss@8.4.41)
|
postcss-load-config: 4.0.2(postcss@8.4.41)
|
||||||
postcss-nested: 6.2.0(postcss@8.4.41)
|
postcss-nested: 6.2.0(postcss@8.4.41)
|
||||||
postcss-selector-parser: 6.1.1
|
postcss-selector-parser: 6.1.2
|
||||||
resolve: 1.22.8
|
resolve: 1.22.8
|
||||||
sucrase: 3.35.0
|
sucrase: 3.35.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -4652,12 +4652,12 @@ snapshots:
|
|||||||
|
|
||||||
tsup@8.2.4(jiti@1.21.6)(postcss@8.4.41)(typescript@5.5.4)(yaml@2.5.0):
|
tsup@8.2.4(jiti@1.21.6)(postcss@8.4.41)(typescript@5.5.4)(yaml@2.5.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
bundle-require: 5.0.0(esbuild@0.23.0)
|
bundle-require: 5.0.0(esbuild@0.23.1)
|
||||||
cac: 6.7.14
|
cac: 6.7.14
|
||||||
chokidar: 3.6.0
|
chokidar: 3.6.0
|
||||||
consola: 3.2.3
|
consola: 3.2.3
|
||||||
debug: 4.3.6
|
debug: 4.3.6
|
||||||
esbuild: 0.23.0
|
esbuild: 0.23.1
|
||||||
execa: 5.1.1
|
execa: 5.1.1
|
||||||
globby: 11.1.0
|
globby: 11.1.0
|
||||||
joycon: 3.1.1
|
joycon: 3.1.1
|
||||||
@ -4689,13 +4689,13 @@ snapshots:
|
|||||||
|
|
||||||
type-fest@0.8.1: {}
|
type-fest@0.8.1: {}
|
||||||
|
|
||||||
type-fest@4.24.0: {}
|
type-fest@4.25.0: {}
|
||||||
|
|
||||||
typescript@5.5.4: {}
|
typescript@5.5.4: {}
|
||||||
|
|
||||||
undici-types@5.26.5: {}
|
undici-types@5.26.5: {}
|
||||||
|
|
||||||
undici-types@6.13.0: {}
|
undici-types@6.19.6: {}
|
||||||
|
|
||||||
update-browserslist-db@1.1.0(browserslist@4.23.3):
|
update-browserslist-db@1.1.0(browserslist@4.23.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -4714,13 +4714,13 @@ snapshots:
|
|||||||
spdx-correct: 3.2.0
|
spdx-correct: 3.2.0
|
||||||
spdx-expression-parse: 3.0.1
|
spdx-expression-parse: 3.0.1
|
||||||
|
|
||||||
vite-node@2.0.5(@types/node@22.2.0):
|
vite-node@2.0.5(@types/node@22.4.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
cac: 6.7.14
|
cac: 6.7.14
|
||||||
debug: 4.3.6
|
debug: 4.3.6
|
||||||
pathe: 1.1.2
|
pathe: 1.1.2
|
||||||
tinyrainbow: 1.2.0
|
tinyrainbow: 1.2.0
|
||||||
vite: 5.4.0(@types/node@22.2.0)
|
vite: 5.4.1(@types/node@22.4.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/node'
|
- '@types/node'
|
||||||
- less
|
- less
|
||||||
@ -4732,16 +4732,16 @@ snapshots:
|
|||||||
- supports-color
|
- supports-color
|
||||||
- terser
|
- terser
|
||||||
|
|
||||||
vite@5.4.0(@types/node@22.2.0):
|
vite@5.4.1(@types/node@22.4.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.21.5
|
esbuild: 0.21.5
|
||||||
postcss: 8.4.41
|
postcss: 8.4.41
|
||||||
rollup: 4.20.0
|
rollup: 4.20.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 22.2.0
|
'@types/node': 22.4.0
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
|
||||||
vitest@2.0.5(@types/node@22.2.0):
|
vitest@2.0.5(@types/node@22.4.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@ampproject/remapping': 2.3.0
|
'@ampproject/remapping': 2.3.0
|
||||||
'@vitest/expect': 2.0.5
|
'@vitest/expect': 2.0.5
|
||||||
@ -4759,11 +4759,11 @@ snapshots:
|
|||||||
tinybench: 2.9.0
|
tinybench: 2.9.0
|
||||||
tinypool: 1.0.0
|
tinypool: 1.0.0
|
||||||
tinyrainbow: 1.2.0
|
tinyrainbow: 1.2.0
|
||||||
vite: 5.4.0(@types/node@22.2.0)
|
vite: 5.4.1(@types/node@22.4.0)
|
||||||
vite-node: 2.0.5(@types/node@22.2.0)
|
vite-node: 2.0.5(@types/node@22.4.0)
|
||||||
why-is-node-running: 2.3.0
|
why-is-node-running: 2.3.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 22.2.0
|
'@types/node': 22.4.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- less
|
- less
|
||||||
- lightningcss
|
- lightningcss
|
||||||
|
@ -1,536 +0,0 @@
|
|||||||
import { basename, dirname, extname, join } from "node:path";
|
|
||||||
import type b from "@babel/core";
|
|
||||||
import hash from "@emotion/hash";
|
|
||||||
import { isPlainObject } from "lodash";
|
|
||||||
import invariant from "tiny-invariant";
|
|
||||||
import { type NodePath, type types as t } from "@babel/core";
|
|
||||||
import { type SourceLocation, type StyleMapEntry, macroNames } from "./shared";
|
|
||||||
import { type ResolveTailwindOptions, getClassName } from "./index";
|
|
||||||
|
|
||||||
export type ClassNameCollector = (path: string, entries: StyleMapEntry[]) => void;
|
|
||||||
type BabelTypes = typeof b.types;
|
|
||||||
type Type = "css" | "js";
|
|
||||||
|
|
||||||
export function babelTailwind(
|
|
||||||
options: ResolveTailwindOptions,
|
|
||||||
onCollect: ClassNameCollector | undefined
|
|
||||||
) {
|
|
||||||
const {
|
|
||||||
styleMap,
|
|
||||||
clsx,
|
|
||||||
getClassName: getClass = getClassName,
|
|
||||||
jsxAttributeAction = "delete",
|
|
||||||
jsxAttributeName = "css",
|
|
||||||
vite: bustCache,
|
|
||||||
} = options;
|
|
||||||
|
|
||||||
type BabelPluginUtils = ReturnType<typeof getUtils>;
|
|
||||||
|
|
||||||
function getUtils(path: NodePath<t.Program>, state: b.PluginPass, t: BabelTypes) {
|
|
||||||
let cx: t.Identifier;
|
|
||||||
let tslibImport: t.Identifier;
|
|
||||||
let styleImport: t.Identifier;
|
|
||||||
|
|
||||||
const cssMap = new Map<string, StyleMapEntry>();
|
|
||||||
const jsMap = new Map<string, StyleMapEntry>();
|
|
||||||
|
|
||||||
function getStyleImport() {
|
|
||||||
styleImport ??= path.scope.generateUidIdentifier("styles");
|
|
||||||
return t.cloneNode(styleImport);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
getClass(type: Type, value: string) {
|
|
||||||
return type === "css" ? getClass(value) : "tw_" + hash(value);
|
|
||||||
},
|
|
||||||
|
|
||||||
sliceText: (node: t.Node): SourceLocation => ({
|
|
||||||
filename: state.filename!,
|
|
||||||
start: node.loc!.start,
|
|
||||||
end: node.loc!.end,
|
|
||||||
text: state.file.code
|
|
||||||
.split("\n")
|
|
||||||
.slice(node.loc!.start.line - 1, node.loc!.end.line)
|
|
||||||
.join("\n"),
|
|
||||||
}),
|
|
||||||
|
|
||||||
recordIfAbsent(type: Type, entry: StyleMapEntry) {
|
|
||||||
const map = type === "css" ? cssMap : jsMap;
|
|
||||||
if (!map.has(entry.key)) {
|
|
||||||
map.set(entry.key, entry);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
replaceWithImport({
|
|
||||||
type,
|
|
||||||
path,
|
|
||||||
className,
|
|
||||||
}: {
|
|
||||||
type: Type;
|
|
||||||
path: NodePath;
|
|
||||||
className: string;
|
|
||||||
}) {
|
|
||||||
if (type === "css") {
|
|
||||||
path.replaceWith(t.stringLiteral(className));
|
|
||||||
} else {
|
|
||||||
const styleImportId = getStyleImport();
|
|
||||||
path.replaceWith(
|
|
||||||
t.memberExpression(styleImportId, t.stringLiteral(className), true)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getCx: () => {
|
|
||||||
if (cx == null) {
|
|
||||||
cx = path.scope.generateUidIdentifier("cx");
|
|
||||||
path.node.body.unshift(getClsxImport(t, cx, clsx));
|
|
||||||
}
|
|
||||||
return t.cloneNode(cx);
|
|
||||||
},
|
|
||||||
|
|
||||||
getTSlibImport: () => {
|
|
||||||
if (tslibImport == null) {
|
|
||||||
tslibImport = path.scope.generateUidIdentifier("tslib");
|
|
||||||
path.node.body.unshift(
|
|
||||||
t.importDeclaration(
|
|
||||||
[t.importNamespaceSpecifier(tslibImport)],
|
|
||||||
t.stringLiteral("tslib")
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return t.cloneNode(tslibImport);
|
|
||||||
},
|
|
||||||
|
|
||||||
finish(node: t.Program) {
|
|
||||||
const { filename } = state;
|
|
||||||
if (!cssMap.size && !jsMap.size) return;
|
|
||||||
invariant(filename, "babel: missing state.filename");
|
|
||||||
|
|
||||||
if (cssMap.size) {
|
|
||||||
const cssName = basename(filename, extname(filename)) + ".css";
|
|
||||||
const path = join(dirname(filename), cssName);
|
|
||||||
const value = Array.from(cssMap.values());
|
|
||||||
const importee = `tailwind:./${cssName}` + getSuffix(bustCache, value);
|
|
||||||
|
|
||||||
node.body.unshift(t.importDeclaration([], t.stringLiteral(importee)));
|
|
||||||
|
|
||||||
styleMap.set(path, value);
|
|
||||||
onCollect?.(path, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jsMap.size) {
|
|
||||||
const jsName = basename(filename, extname(filename)) + ".tailwindStyle.js";
|
|
||||||
const path = join(dirname(filename), jsName);
|
|
||||||
const value = Array.from(jsMap.values());
|
|
||||||
const importee = `tailwind:./${jsName}` + getSuffix(bustCache, value);
|
|
||||||
|
|
||||||
node.body.unshift(
|
|
||||||
t.importDeclaration(
|
|
||||||
[t.importNamespaceSpecifier(getStyleImport())],
|
|
||||||
t.stringLiteral(importee)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
styleMap.set(path, value);
|
|
||||||
onCollect?.(path, value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return definePlugin<BabelPluginUtils>(({ types: t }) => ({
|
|
||||||
Program: {
|
|
||||||
enter(path, state) {
|
|
||||||
const _ = getUtils(path, state, t);
|
|
||||||
Object.assign(state, _);
|
|
||||||
|
|
||||||
for (const { callee, imported, prefix } of getMacros(t, path, macroNames).map(
|
|
||||||
macro => mapMacro(t, macro)
|
|
||||||
)) {
|
|
||||||
const type = imported === "tw" ? "css" : imported === "tws" ? "js" : undefined;
|
|
||||||
if (!type) continue;
|
|
||||||
|
|
||||||
if (isNodePath(callee, t.isTaggedTemplateExpression)) {
|
|
||||||
const { node } = callee;
|
|
||||||
const { quasi } = node;
|
|
||||||
|
|
||||||
invariant(
|
|
||||||
!quasi.expressions.length,
|
|
||||||
`Macro call should not contain expressions`
|
|
||||||
);
|
|
||||||
|
|
||||||
const value = quasi.quasis[0].value.cooked;
|
|
||||||
if (value) {
|
|
||||||
const list = trimPrefix(value, prefix ? prefix + ":" : undefined);
|
|
||||||
const className = _.getClass(type, list.join(" "));
|
|
||||||
_.recordIfAbsent(type, {
|
|
||||||
key: className,
|
|
||||||
classNames: list,
|
|
||||||
location: _.sliceText(node),
|
|
||||||
});
|
|
||||||
_.replaceWithImport({
|
|
||||||
type,
|
|
||||||
path: callee,
|
|
||||||
className: addIf(className, list.includes("group") && " group"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (isNodePath(callee, t.isCallExpression)) {
|
|
||||||
const { node } = callee;
|
|
||||||
if (!t.isIdentifier(node.callee)) continue;
|
|
||||||
|
|
||||||
const list = callee.get("arguments").flatMap(evaluateArgs);
|
|
||||||
const className = getClass(list.join(" "));
|
|
||||||
_.recordIfAbsent(type, {
|
|
||||||
key: className,
|
|
||||||
classNames: list,
|
|
||||||
location: _.sliceText(node),
|
|
||||||
});
|
|
||||||
_.replaceWithImport({
|
|
||||||
type,
|
|
||||||
path: callee,
|
|
||||||
className: addIf(className, list.includes("group") && " group"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
exit({ node }, _) {
|
|
||||||
_.finish(node);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
JSXAttribute(path, _) {
|
|
||||||
const { name } = path.node;
|
|
||||||
if (name.name !== jsxAttributeName) return;
|
|
||||||
|
|
||||||
const valuePath = path.get("value");
|
|
||||||
if (!valuePath.node) return;
|
|
||||||
|
|
||||||
const copy =
|
|
||||||
jsxAttributeAction === "delete" ? undefined : t.cloneNode(valuePath.node, true);
|
|
||||||
|
|
||||||
const parent = path.parent as t.JSXOpeningElement;
|
|
||||||
const classNameAttribute = parent.attributes.find(
|
|
||||||
(attr): attr is t.JSXAttribute =>
|
|
||||||
t.isJSXAttribute(attr) && attr.name.name === "className"
|
|
||||||
);
|
|
||||||
|
|
||||||
matchPath(valuePath, go => ({
|
|
||||||
StringLiteral(path) {
|
|
||||||
const { node } = path;
|
|
||||||
const { value } = node;
|
|
||||||
const trimmed = trim(value);
|
|
||||||
if (trimmed.length) {
|
|
||||||
const className = getClass(trimmed.join(" "));
|
|
||||||
_.recordIfAbsent("css", {
|
|
||||||
key: className,
|
|
||||||
classNames: trimmed,
|
|
||||||
location: _.sliceText(node),
|
|
||||||
});
|
|
||||||
path.replaceWith(t.stringLiteral(className));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ArrayExpression(path) {
|
|
||||||
for (const element of path.get("elements")) {
|
|
||||||
go(element);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ObjectExpression(path) {
|
|
||||||
const trimmed = evaluateArgs(path);
|
|
||||||
const className = getClass(trimmed.join(" "));
|
|
||||||
_.recordIfAbsent("css", {
|
|
||||||
key: className,
|
|
||||||
classNames: trimmed,
|
|
||||||
location: _.sliceText(path.node),
|
|
||||||
});
|
|
||||||
path.replaceWith(t.stringLiteral(className));
|
|
||||||
},
|
|
||||||
JSXExpressionContainer(path) {
|
|
||||||
go(path.get("expression"));
|
|
||||||
},
|
|
||||||
ConditionalExpression(path) {
|
|
||||||
go(path.get("consequent"));
|
|
||||||
go(path.get("alternate"));
|
|
||||||
},
|
|
||||||
LogicalExpression(path) {
|
|
||||||
go(path.get("right"));
|
|
||||||
},
|
|
||||||
CallExpression(path) {
|
|
||||||
for (const arg of path.get("arguments")) {
|
|
||||||
go(arg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
let valuePathNode = extractJSXContainer(valuePath.node);
|
|
||||||
if (
|
|
||||||
t.isArrayExpression(valuePathNode) &&
|
|
||||||
valuePathNode.elements.every(node => t.isStringLiteral(node))
|
|
||||||
) {
|
|
||||||
valuePathNode = t.stringLiteral(
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
||||||
(valuePathNode.elements as t.StringLiteral[]).map(node => node.value).join(" ")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (classNameAttribute) {
|
|
||||||
const attrValue = classNameAttribute.value!;
|
|
||||||
const wrap = (originalValue: b.types.Expression) =>
|
|
||||||
t.callExpression(_.getCx(), [originalValue, valuePathNode]);
|
|
||||||
|
|
||||||
// If both are string literals, we can merge them directly here
|
|
||||||
if (t.isStringLiteral(attrValue) && t.isStringLiteral(valuePathNode)) {
|
|
||||||
attrValue.value +=
|
|
||||||
(attrValue.value.at(-1) === " " ? "" : " ") + valuePathNode.value;
|
|
||||||
} else {
|
|
||||||
const internalAttrValue = extractJSXContainer(attrValue);
|
|
||||||
if (
|
|
||||||
t.isArrowFunctionExpression(internalAttrValue) &&
|
|
||||||
!t.isBlockStatement(internalAttrValue.body)
|
|
||||||
) {
|
|
||||||
internalAttrValue.body = wrap(internalAttrValue.body);
|
|
||||||
} else {
|
|
||||||
classNameAttribute.value = t.jsxExpressionContainer(wrap(internalAttrValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const wrap = (originalValue: b.types.Expression) =>
|
|
||||||
t.callExpression(_.getCx(), [valuePathNode, originalValue]);
|
|
||||||
|
|
||||||
const rest = parent.attributes.filter(attr => t.isJSXSpreadAttribute(attr));
|
|
||||||
let arg;
|
|
||||||
if (rest.length === 1 && (arg = rest[0].argument) && t.isIdentifier(arg)) {
|
|
||||||
// props from argument and not modified anywhere
|
|
||||||
const scope = path.scope.getBinding(arg.name);
|
|
||||||
let index: number;
|
|
||||||
const node = scope?.path.node;
|
|
||||||
if (
|
|
||||||
scope &&
|
|
||||||
!scope.constantViolations.length &&
|
|
||||||
t.isFunctionDeclaration(scope.path.parent) &&
|
|
||||||
(index = (scope.path.parent.params as t.Node[]).indexOf(node!)) !== -1 &&
|
|
||||||
(t.isIdentifier(node) || t.isObjectPattern(node))
|
|
||||||
) {
|
|
||||||
const clsVar = path.scope.generateUidIdentifier("className");
|
|
||||||
if (t.isIdentifier(node)) {
|
|
||||||
scope.path.parent.params[index] = t.objectPattern([
|
|
||||||
t.objectProperty(t.identifier("className"), clsVar),
|
|
||||||
t.restElement(node),
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
node.properties.unshift(
|
|
||||||
t.objectProperty(t.identifier("className"), clsVar)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
parent.attributes.push(
|
|
||||||
t.jsxAttribute(
|
|
||||||
t.jsxIdentifier("className"),
|
|
||||||
t.jsxExpressionContainer(wrap(clsVar))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const tslibImport = _.getTSlibImport();
|
|
||||||
rest[0].argument = t.callExpression(
|
|
||||||
t.memberExpression(tslibImport, t.identifier("__rest")),
|
|
||||||
[arg, t.arrayExpression([t.stringLiteral("className")])]
|
|
||||||
);
|
|
||||||
|
|
||||||
parent.attributes.push(
|
|
||||||
t.jsxAttribute(
|
|
||||||
t.jsxIdentifier("className"),
|
|
||||||
t.jsxExpressionContainer(
|
|
||||||
wrap(t.memberExpression(arg, t.identifier("className")))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const containerValue = t.isStringLiteral(valuePathNode)
|
|
||||||
? valuePathNode
|
|
||||||
: t.callExpression(_.getCx(), [valuePathNode]);
|
|
||||||
|
|
||||||
parent.attributes.push(
|
|
||||||
t.jsxAttribute(
|
|
||||||
t.jsxIdentifier("className"),
|
|
||||||
t.jsxExpressionContainer(containerValue)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jsxAttributeAction === "delete") {
|
|
||||||
path.remove();
|
|
||||||
} else {
|
|
||||||
path.node.value = copy!;
|
|
||||||
if (Array.isArray(jsxAttributeAction) && jsxAttributeAction[0] === "rename") {
|
|
||||||
path.node.name.name = jsxAttributeAction[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function getClsxImport(t: BabelTypes, cx: t.Identifier, clsx: string) {
|
|
||||||
switch (clsx) {
|
|
||||||
case "emotion":
|
|
||||||
return t.importDeclaration(
|
|
||||||
[t.importSpecifier(cx, t.identifier("cx"))],
|
|
||||||
t.stringLiteral("@emotion/css")
|
|
||||||
);
|
|
||||||
case "clsx":
|
|
||||||
return t.importDeclaration([t.importDefaultSpecifier(cx)], t.stringLiteral("clsx"));
|
|
||||||
case "classnames":
|
|
||||||
return t.importDeclaration(
|
|
||||||
[t.importDefaultSpecifier(cx)],
|
|
||||||
t.stringLiteral("classnames")
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
throw new Error("Unknown clsx library");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function evaluateArgs(path: NodePath) {
|
|
||||||
const { confident, value } = path.evaluate();
|
|
||||||
invariant(confident, "Argument cannot be statically evaluated");
|
|
||||||
|
|
||||||
if (typeof value === "string") {
|
|
||||||
return trim(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPlainObject(value)) {
|
|
||||||
return flatMapEntries(value, (classes, modifier) => {
|
|
||||||
if (modifier === "data" && isPlainObject(classes)) {
|
|
||||||
return flatMapEntries(classes as Record<string, string | object>, (cls, key) =>
|
|
||||||
typeof cls === "string"
|
|
||||||
? trimPrefix(cls, `${modifier}-[${key}]:`)
|
|
||||||
: flatMapEntries(cls as Record<string, string>, (cls, attrValue) =>
|
|
||||||
trimPrefix(cls, `${modifier}-[${key}=${attrValue}]:`)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
invariant(
|
|
||||||
typeof classes === "string",
|
|
||||||
`Value for "${modifier}" should be a string`
|
|
||||||
);
|
|
||||||
return trimPrefix(classes, modifier + ":");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error("Invalid argument type");
|
|
||||||
}
|
|
||||||
|
|
||||||
function getName(t: BabelTypes, exp: t.Node) {
|
|
||||||
if (t.isIdentifier(exp)) {
|
|
||||||
return exp.name;
|
|
||||||
} else if (t.isStringLiteral(exp)) {
|
|
||||||
return exp.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMacros(
|
|
||||||
t: BabelTypes,
|
|
||||||
programPath: NodePath<t.Program>,
|
|
||||||
importSources: string[]
|
|
||||||
) {
|
|
||||||
const importDecs = programPath
|
|
||||||
.get("body")
|
|
||||||
.filter(x => isNodePath(x, t.isImportDeclaration))
|
|
||||||
.filter(x => importSources.includes(x.node.source.value));
|
|
||||||
|
|
||||||
const macros = importDecs
|
|
||||||
.flatMap(x => x.get("specifiers"))
|
|
||||||
.map(x => {
|
|
||||||
const local = x.get("local");
|
|
||||||
if (isNodePath(x, t.isImportNamespaceSpecifier)) {
|
|
||||||
return local.scope
|
|
||||||
.getOwnBinding(local.node.name)!
|
|
||||||
.referencePaths.map(p => p.parentPath)
|
|
||||||
.filter(p => isNodePath(p, t.isMemberExpression))
|
|
||||||
.map(p => ({
|
|
||||||
local: p,
|
|
||||||
imported: getName(t, p.node.property)!,
|
|
||||||
}))
|
|
||||||
.filter(p => p.imported);
|
|
||||||
} else if (t.isImportSpecifier(x.node)) {
|
|
||||||
const imported = x.node.imported;
|
|
||||||
return local.scope.getOwnBinding(local.node.name)!.referencePaths.map(p => ({
|
|
||||||
local: p as NodePath<t.Identifier>,
|
|
||||||
imported: getName(t, imported)!,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(Boolean)
|
|
||||||
.flat(1);
|
|
||||||
|
|
||||||
for (const x of importDecs) {
|
|
||||||
x.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
return macros;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapMacro(t: BabelTypes, macro: ReturnType<typeof getMacros>[number]) {
|
|
||||||
let callee = macro.local.parentPath;
|
|
||||||
const prefix: string[] = [];
|
|
||||||
|
|
||||||
while (isNodePath(callee, t.isMemberExpression)) {
|
|
||||||
invariant(t.isIdentifier(callee.node.property), "Invalid member expression");
|
|
||||||
prefix.unshift(
|
|
||||||
callee.node.property.name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()
|
|
||||||
);
|
|
||||||
callee = callee.parentPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
callee,
|
|
||||||
imported: macro.imported,
|
|
||||||
prefix: prefix.length ? prefix.join(":") : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const definePlugin =
|
|
||||||
<T>(fn: (runtime: typeof b) => b.Visitor<b.PluginPass & T>) =>
|
|
||||||
(runtime: typeof b) => {
|
|
||||||
const plugin: b.PluginObj<b.PluginPass & T> = {
|
|
||||||
visitor: fn(runtime),
|
|
||||||
};
|
|
||||||
return plugin as b.PluginObj;
|
|
||||||
};
|
|
||||||
|
|
||||||
const extractJSXContainer = (attr: NonNullable<t.JSXAttribute["value"]>): t.Expression =>
|
|
||||||
attr.type === "JSXExpressionContainer" ? (attr.expression as t.Expression) : attr;
|
|
||||||
|
|
||||||
function matchPath(
|
|
||||||
nodePath: NodePath<t.Node | null | undefined>,
|
|
||||||
fns: (dig: (nodePath: NodePath<t.Node | null | undefined>) => void) => b.Visitor
|
|
||||||
) {
|
|
||||||
if (!nodePath.node) return;
|
|
||||||
const fn = fns(path => matchPath(path, fns))[nodePath.node.type] as any;
|
|
||||||
fn?.(nodePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addIf(text: string, suffix: string | false) {
|
|
||||||
return suffix ? text + suffix : text;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isNodePath = <T extends t.Node>(
|
|
||||||
nodePath: NodePath<t.Node | null | undefined> | null,
|
|
||||||
predicate: (node: t.Node) => node is T
|
|
||||||
): nodePath is NodePath<T> => Boolean(nodePath?.node && predicate(nodePath.node));
|
|
||||||
|
|
||||||
function getSuffix(add: boolean | undefined, entries: StyleMapEntry[]) {
|
|
||||||
if (!add) return "";
|
|
||||||
|
|
||||||
const cacheKey = hash(entries.map(x => x.classNames).join(","));
|
|
||||||
return `?${cacheKey}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const trim = (value: string) =>
|
|
||||||
value.replace(/\s+/g, " ").trim().split(" ").filter(Boolean);
|
|
||||||
const trimPrefix = (cls: string, prefix = "") => trim(cls).map(value => prefix + value);
|
|
||||||
|
|
||||||
const flatMapEntries = <K extends string | number, V, R>(
|
|
||||||
map: Record<K, V>,
|
|
||||||
fn: (value: V, key: K) => R[]
|
|
||||||
): R[] => Object.entries(map).flatMap(([key, value]) => fn(value as V, key as K));
|
|
389
src/babel/index.ts
Normal file
389
src/babel/index.ts
Normal file
@ -0,0 +1,389 @@
|
|||||||
|
import { basename, dirname, extname, join } from "node:path";
|
||||||
|
import type b from "@babel/core";
|
||||||
|
import hash from "@emotion/hash";
|
||||||
|
import invariant from "tiny-invariant";
|
||||||
|
import { type NodePath, type types as t } from "@babel/core";
|
||||||
|
import { type SourceLocation, type StyleMapEntry } from "../shared";
|
||||||
|
import { type ResolveTailwindOptions, getClassName } from "../index";
|
||||||
|
import { handleMacro } from "./macro";
|
||||||
|
import { evaluateArgs, trim } from "./utils";
|
||||||
|
|
||||||
|
export type ClassNameCollector = (path: string, entries: StyleMapEntry[]) => void;
|
||||||
|
type BabelTypes = typeof b.types;
|
||||||
|
type Type = "css" | "js";
|
||||||
|
|
||||||
|
export type BabelPluginUtils = ReturnType<typeof getUtils>;
|
||||||
|
|
||||||
|
function getUtils({
|
||||||
|
path,
|
||||||
|
state,
|
||||||
|
t,
|
||||||
|
options,
|
||||||
|
onCollect,
|
||||||
|
}: {
|
||||||
|
path: NodePath<t.Program>;
|
||||||
|
state: b.PluginPass;
|
||||||
|
t: BabelTypes;
|
||||||
|
options: ResolveTailwindOptions;
|
||||||
|
onCollect: ClassNameCollector | undefined;
|
||||||
|
}) {
|
||||||
|
const {
|
||||||
|
styleMap,
|
||||||
|
clsx,
|
||||||
|
getClassName: getClass = getClassName,
|
||||||
|
vite: bustCache,
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
let cx: t.Identifier;
|
||||||
|
let tslibImport: t.Identifier;
|
||||||
|
let styleImport: t.Identifier;
|
||||||
|
|
||||||
|
const cssMap = new Map<string, StyleMapEntry>();
|
||||||
|
const jsMap = new Map<string, StyleMapEntry>();
|
||||||
|
|
||||||
|
function getStyleImport() {
|
||||||
|
styleImport ??= path.scope.generateUidIdentifier("styles");
|
||||||
|
return t.cloneNode(styleImport);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
getClass(type: Type, value: string) {
|
||||||
|
return type === "css" ? getClass(value) : "tw_" + hash(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
sliceText: (node: t.Node): SourceLocation => ({
|
||||||
|
filename: state.filename!,
|
||||||
|
start: node.loc!.start,
|
||||||
|
end: node.loc!.end,
|
||||||
|
text: state.file.code
|
||||||
|
.split("\n")
|
||||||
|
.slice(node.loc!.start.line - 1, node.loc!.end.line)
|
||||||
|
.join("\n"),
|
||||||
|
}),
|
||||||
|
|
||||||
|
recordIfAbsent(type: Type, entry: StyleMapEntry) {
|
||||||
|
const map = type === "css" ? cssMap : jsMap;
|
||||||
|
if (!map.has(entry.key)) {
|
||||||
|
map.set(entry.key, entry);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
replaceWithImport({
|
||||||
|
type,
|
||||||
|
path,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
type: Type;
|
||||||
|
path: NodePath;
|
||||||
|
className: string;
|
||||||
|
}) {
|
||||||
|
if (type === "css") {
|
||||||
|
path.replaceWith(t.stringLiteral(className));
|
||||||
|
} else {
|
||||||
|
const styleImportId = getStyleImport();
|
||||||
|
path.replaceWith(
|
||||||
|
t.memberExpression(styleImportId, t.stringLiteral(className), true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getCx: () => {
|
||||||
|
if (cx == null) {
|
||||||
|
cx = path.scope.generateUidIdentifier("cx");
|
||||||
|
path.node.body.unshift(getClsxImport(t, cx, clsx));
|
||||||
|
}
|
||||||
|
return t.cloneNode(cx);
|
||||||
|
},
|
||||||
|
|
||||||
|
getTSlibImport: () => {
|
||||||
|
if (tslibImport == null) {
|
||||||
|
tslibImport = path.scope.generateUidIdentifier("tslib");
|
||||||
|
path.node.body.unshift(
|
||||||
|
t.importDeclaration(
|
||||||
|
[t.importNamespaceSpecifier(tslibImport)],
|
||||||
|
t.stringLiteral("tslib")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return t.cloneNode(tslibImport);
|
||||||
|
},
|
||||||
|
|
||||||
|
finish(node: t.Program) {
|
||||||
|
const { filename } = state;
|
||||||
|
if (!cssMap.size && !jsMap.size) return;
|
||||||
|
invariant(filename, "babel: missing state.filename");
|
||||||
|
|
||||||
|
if (cssMap.size) {
|
||||||
|
const cssName = basename(filename, extname(filename)) + ".css";
|
||||||
|
const path = join(dirname(filename), cssName);
|
||||||
|
const value = Array.from(cssMap.values());
|
||||||
|
const importee = `tailwind:./${cssName}` + getSuffix(bustCache, value);
|
||||||
|
|
||||||
|
node.body.unshift(t.importDeclaration([], t.stringLiteral(importee)));
|
||||||
|
|
||||||
|
styleMap.set(path, value);
|
||||||
|
onCollect?.(path, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsMap.size) {
|
||||||
|
const jsName = basename(filename, extname(filename)) + ".tailwindStyle.js";
|
||||||
|
const path = join(dirname(filename), jsName);
|
||||||
|
const value = Array.from(jsMap.values());
|
||||||
|
const importee = `tailwind:./${jsName}` + getSuffix(bustCache, value);
|
||||||
|
|
||||||
|
node.body.unshift(
|
||||||
|
t.importDeclaration(
|
||||||
|
[t.importNamespaceSpecifier(getStyleImport())],
|
||||||
|
t.stringLiteral(importee)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
styleMap.set(path, value);
|
||||||
|
onCollect?.(path, value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function babelTailwind(
|
||||||
|
options: ResolveTailwindOptions,
|
||||||
|
onCollect: ClassNameCollector | undefined
|
||||||
|
) {
|
||||||
|
const {
|
||||||
|
getClassName: getClass = getClassName,
|
||||||
|
jsxAttributeAction = "delete",
|
||||||
|
jsxAttributeName = "css",
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
return definePlugin<BabelPluginUtils>(({ types: t }) => ({
|
||||||
|
Program: {
|
||||||
|
enter(path, state) {
|
||||||
|
const _ = getUtils({ path, state, t, options, onCollect });
|
||||||
|
Object.assign(state, _);
|
||||||
|
|
||||||
|
handleMacro({ t, path, _ });
|
||||||
|
},
|
||||||
|
|
||||||
|
exit({ node }, _) {
|
||||||
|
_.finish(node);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
JSXAttribute(path, _) {
|
||||||
|
const { name } = path.node;
|
||||||
|
if (name.name !== jsxAttributeName) return;
|
||||||
|
|
||||||
|
const valuePath = path.get("value");
|
||||||
|
if (!valuePath.node) return;
|
||||||
|
|
||||||
|
const copy =
|
||||||
|
jsxAttributeAction === "delete" ? undefined : t.cloneNode(valuePath.node, true);
|
||||||
|
|
||||||
|
const parent = path.parent as t.JSXOpeningElement;
|
||||||
|
const classNameAttribute = parent.attributes.find(
|
||||||
|
(attr): attr is t.JSXAttribute =>
|
||||||
|
t.isJSXAttribute(attr) && attr.name.name === "className"
|
||||||
|
);
|
||||||
|
|
||||||
|
matchPath(valuePath, go => ({
|
||||||
|
StringLiteral(path) {
|
||||||
|
const { node } = path;
|
||||||
|
const { value } = node;
|
||||||
|
const trimmed = trim(value);
|
||||||
|
if (trimmed.length) {
|
||||||
|
const className = getClass(trimmed.join(" "));
|
||||||
|
_.recordIfAbsent("css", {
|
||||||
|
key: className,
|
||||||
|
classNames: trimmed,
|
||||||
|
location: _.sliceText(node),
|
||||||
|
});
|
||||||
|
path.replaceWith(t.stringLiteral(className));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ArrayExpression(path) {
|
||||||
|
for (const element of path.get("elements")) {
|
||||||
|
go(element);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ObjectExpression(path) {
|
||||||
|
const trimmed = evaluateArgs(path);
|
||||||
|
const className = getClass(trimmed.join(" "));
|
||||||
|
_.recordIfAbsent("css", {
|
||||||
|
key: className,
|
||||||
|
classNames: trimmed,
|
||||||
|
location: _.sliceText(path.node),
|
||||||
|
});
|
||||||
|
path.replaceWith(t.stringLiteral(className));
|
||||||
|
},
|
||||||
|
JSXExpressionContainer(path) {
|
||||||
|
go(path.get("expression"));
|
||||||
|
},
|
||||||
|
ConditionalExpression(path) {
|
||||||
|
go(path.get("consequent"));
|
||||||
|
go(path.get("alternate"));
|
||||||
|
},
|
||||||
|
LogicalExpression(path) {
|
||||||
|
go(path.get("right"));
|
||||||
|
},
|
||||||
|
CallExpression(path) {
|
||||||
|
for (const arg of path.get("arguments")) {
|
||||||
|
go(arg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
let valuePathNode = extractJSXContainer(valuePath.node);
|
||||||
|
if (
|
||||||
|
t.isArrayExpression(valuePathNode) &&
|
||||||
|
valuePathNode.elements.every(node => t.isStringLiteral(node))
|
||||||
|
) {
|
||||||
|
valuePathNode = t.stringLiteral(
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
|
(valuePathNode.elements as t.StringLiteral[]).map(node => node.value).join(" ")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classNameAttribute) {
|
||||||
|
const attrValue = classNameAttribute.value!;
|
||||||
|
const wrap = (originalValue: b.types.Expression) =>
|
||||||
|
t.callExpression(_.getCx(), [originalValue, valuePathNode]);
|
||||||
|
|
||||||
|
// If both are string literals, we can merge them directly here
|
||||||
|
if (t.isStringLiteral(attrValue) && t.isStringLiteral(valuePathNode)) {
|
||||||
|
attrValue.value +=
|
||||||
|
(attrValue.value.at(-1) === " " ? "" : " ") + valuePathNode.value;
|
||||||
|
} else {
|
||||||
|
const internalAttrValue = extractJSXContainer(attrValue);
|
||||||
|
if (
|
||||||
|
t.isArrowFunctionExpression(internalAttrValue) &&
|
||||||
|
!t.isBlockStatement(internalAttrValue.body)
|
||||||
|
) {
|
||||||
|
internalAttrValue.body = wrap(internalAttrValue.body);
|
||||||
|
} else {
|
||||||
|
classNameAttribute.value = t.jsxExpressionContainer(wrap(internalAttrValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const wrap = (originalValue: b.types.Expression) =>
|
||||||
|
t.callExpression(_.getCx(), [valuePathNode, originalValue]);
|
||||||
|
|
||||||
|
const rest = parent.attributes.filter(attr => t.isJSXSpreadAttribute(attr));
|
||||||
|
let arg;
|
||||||
|
if (rest.length === 1 && (arg = rest[0].argument) && t.isIdentifier(arg)) {
|
||||||
|
// props from argument and not modified anywhere
|
||||||
|
const scope = path.scope.getBinding(arg.name);
|
||||||
|
let index: number;
|
||||||
|
const node = scope?.path.node;
|
||||||
|
if (
|
||||||
|
scope &&
|
||||||
|
!scope.constantViolations.length &&
|
||||||
|
t.isFunctionDeclaration(scope.path.parent) &&
|
||||||
|
(index = (scope.path.parent.params as t.Node[]).indexOf(node!)) !== -1 &&
|
||||||
|
(t.isIdentifier(node) || t.isObjectPattern(node))
|
||||||
|
) {
|
||||||
|
const clsVar = path.scope.generateUidIdentifier("className");
|
||||||
|
if (t.isIdentifier(node)) {
|
||||||
|
scope.path.parent.params[index] = t.objectPattern([
|
||||||
|
t.objectProperty(t.identifier("className"), clsVar),
|
||||||
|
t.restElement(node),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
node.properties.unshift(
|
||||||
|
t.objectProperty(t.identifier("className"), clsVar)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.attributes.push(
|
||||||
|
t.jsxAttribute(
|
||||||
|
t.jsxIdentifier("className"),
|
||||||
|
t.jsxExpressionContainer(wrap(clsVar))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const tslibImport = _.getTSlibImport();
|
||||||
|
rest[0].argument = t.callExpression(
|
||||||
|
t.memberExpression(tslibImport, t.identifier("__rest")),
|
||||||
|
[arg, t.arrayExpression([t.stringLiteral("className")])]
|
||||||
|
);
|
||||||
|
|
||||||
|
parent.attributes.push(
|
||||||
|
t.jsxAttribute(
|
||||||
|
t.jsxIdentifier("className"),
|
||||||
|
t.jsxExpressionContainer(
|
||||||
|
wrap(t.memberExpression(arg, t.identifier("className")))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const containerValue = t.isStringLiteral(valuePathNode)
|
||||||
|
? valuePathNode
|
||||||
|
: t.callExpression(_.getCx(), [valuePathNode]);
|
||||||
|
|
||||||
|
parent.attributes.push(
|
||||||
|
t.jsxAttribute(
|
||||||
|
t.jsxIdentifier("className"),
|
||||||
|
t.jsxExpressionContainer(containerValue)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsxAttributeAction === "delete") {
|
||||||
|
path.remove();
|
||||||
|
} else {
|
||||||
|
path.node.value = copy!;
|
||||||
|
if (Array.isArray(jsxAttributeAction) && jsxAttributeAction[0] === "rename") {
|
||||||
|
// eslint-disable-next-line unicorn/consistent-destructuring
|
||||||
|
path.node.name.name = jsxAttributeAction[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getClsxImport(t: BabelTypes, cx: t.Identifier, clsx: string) {
|
||||||
|
switch (clsx) {
|
||||||
|
case "emotion":
|
||||||
|
return t.importDeclaration(
|
||||||
|
[t.importSpecifier(cx, t.identifier("cx"))],
|
||||||
|
t.stringLiteral("@emotion/css")
|
||||||
|
);
|
||||||
|
case "clsx":
|
||||||
|
return t.importDeclaration([t.importDefaultSpecifier(cx)], t.stringLiteral("clsx"));
|
||||||
|
case "classnames":
|
||||||
|
return t.importDeclaration(
|
||||||
|
[t.importDefaultSpecifier(cx)],
|
||||||
|
t.stringLiteral("classnames")
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
throw new Error("Unknown clsx library");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const definePlugin =
|
||||||
|
<T>(fn: (runtime: typeof b) => b.Visitor<b.PluginPass & T>) =>
|
||||||
|
(runtime: typeof b) => {
|
||||||
|
const plugin: b.PluginObj<b.PluginPass & T> = {
|
||||||
|
visitor: fn(runtime),
|
||||||
|
};
|
||||||
|
return plugin as b.PluginObj;
|
||||||
|
};
|
||||||
|
|
||||||
|
const extractJSXContainer = (attr: NonNullable<t.JSXAttribute["value"]>): t.Expression =>
|
||||||
|
attr.type === "JSXExpressionContainer" ? (attr.expression as t.Expression) : attr;
|
||||||
|
|
||||||
|
function matchPath(
|
||||||
|
nodePath: NodePath<t.Node | null | undefined>,
|
||||||
|
fns: (dig: (nodePath: NodePath<t.Node | null | undefined>) => void) => b.Visitor
|
||||||
|
) {
|
||||||
|
if (!nodePath.node) return;
|
||||||
|
const fn = fns(path => matchPath(path, fns))[nodePath.node.type] as any;
|
||||||
|
fn?.(nodePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSuffix(add: boolean | undefined, entries: StyleMapEntry[]) {
|
||||||
|
if (!add) return "";
|
||||||
|
|
||||||
|
const cacheKey = hash(entries.map(x => x.classNames).join(","));
|
||||||
|
return `?${cacheKey}`;
|
||||||
|
}
|
142
src/babel/macro.ts
Normal file
142
src/babel/macro.ts
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import type b from "@babel/core";
|
||||||
|
import invariant from "tiny-invariant";
|
||||||
|
import { type NodePath, type types as t } from "@babel/core";
|
||||||
|
import { macroNames } from "../shared";
|
||||||
|
import type { BabelPluginUtils } from "./index";
|
||||||
|
import { evaluateArgs, trimPrefix } from "./utils";
|
||||||
|
|
||||||
|
type BabelTypes = typeof b.types;
|
||||||
|
|
||||||
|
export function handleMacro({
|
||||||
|
t,
|
||||||
|
path,
|
||||||
|
_,
|
||||||
|
}: {
|
||||||
|
t: BabelTypes;
|
||||||
|
path: NodePath<t.Program>;
|
||||||
|
_: BabelPluginUtils;
|
||||||
|
}) {
|
||||||
|
for (const { callee, imported, prefix } of getMacros(t, path, macroNames).map(macro =>
|
||||||
|
mapMacro(t, macro)
|
||||||
|
)) {
|
||||||
|
const type = imported === "tw" ? "css" : imported === "tws" ? "js" : undefined;
|
||||||
|
if (!type) continue;
|
||||||
|
|
||||||
|
if (isNodePath(callee, t.isTaggedTemplateExpression)) {
|
||||||
|
const { node } = callee;
|
||||||
|
const { quasi } = node;
|
||||||
|
|
||||||
|
invariant(!quasi.expressions.length, `Macro call should not contain expressions`);
|
||||||
|
|
||||||
|
const value = quasi.quasis[0].value.cooked;
|
||||||
|
if (value) {
|
||||||
|
const list = trimPrefix(value, prefix ? prefix + ":" : undefined);
|
||||||
|
const className = _.getClass(type, list.join(" "));
|
||||||
|
_.recordIfAbsent(type, {
|
||||||
|
key: className,
|
||||||
|
classNames: list,
|
||||||
|
location: _.sliceText(node),
|
||||||
|
});
|
||||||
|
_.replaceWithImport({
|
||||||
|
type,
|
||||||
|
path: callee,
|
||||||
|
className: addIf(className, list.includes("group") && " group"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (isNodePath(callee, t.isCallExpression)) {
|
||||||
|
const { node } = callee;
|
||||||
|
if (!t.isIdentifier(node.callee)) continue;
|
||||||
|
|
||||||
|
const list = callee.get("arguments").flatMap(evaluateArgs);
|
||||||
|
const className = _.getClass("css", list.join(" "));
|
||||||
|
_.recordIfAbsent(type, {
|
||||||
|
key: className,
|
||||||
|
classNames: list,
|
||||||
|
location: _.sliceText(node),
|
||||||
|
});
|
||||||
|
_.replaceWithImport({
|
||||||
|
type,
|
||||||
|
path: callee,
|
||||||
|
className: addIf(className, list.includes("group") && " group"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addIf(text: string, suffix: string | false) {
|
||||||
|
return suffix ? text + suffix : text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapMacro(t: BabelTypes, macro: ReturnType<typeof getMacros>[number]) {
|
||||||
|
let callee = macro.local.parentPath;
|
||||||
|
const prefix: string[] = [];
|
||||||
|
|
||||||
|
while (isNodePath(callee, t.isMemberExpression)) {
|
||||||
|
invariant(t.isIdentifier(callee.node.property), "Invalid member expression");
|
||||||
|
prefix.unshift(
|
||||||
|
callee.node.property.name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()
|
||||||
|
);
|
||||||
|
callee = callee.parentPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
callee,
|
||||||
|
imported: macro.imported,
|
||||||
|
prefix: prefix.length ? prefix.join(":") : undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getName(t: BabelTypes, exp: t.Node) {
|
||||||
|
if (t.isIdentifier(exp)) {
|
||||||
|
return exp.name;
|
||||||
|
} else if (t.isStringLiteral(exp)) {
|
||||||
|
return exp.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMacros(
|
||||||
|
t: BabelTypes,
|
||||||
|
programPath: NodePath<t.Program>,
|
||||||
|
importSources: string[]
|
||||||
|
) {
|
||||||
|
const importDecs = programPath
|
||||||
|
.get("body")
|
||||||
|
.filter(x => isNodePath(x, t.isImportDeclaration))
|
||||||
|
.filter(x => importSources.includes(x.node.source.value));
|
||||||
|
|
||||||
|
const macros = importDecs
|
||||||
|
.flatMap(x => x.get("specifiers"))
|
||||||
|
.map(x => {
|
||||||
|
const local = x.get("local");
|
||||||
|
if (isNodePath(x, t.isImportNamespaceSpecifier)) {
|
||||||
|
return local.scope
|
||||||
|
.getOwnBinding(local.node.name)!
|
||||||
|
.referencePaths.map(p => p.parentPath)
|
||||||
|
.filter(p => isNodePath(p, t.isMemberExpression))
|
||||||
|
.map(p => ({
|
||||||
|
local: p,
|
||||||
|
imported: getName(t, p.node.property)!,
|
||||||
|
}))
|
||||||
|
.filter(p => p.imported);
|
||||||
|
} else if (t.isImportSpecifier(x.node)) {
|
||||||
|
const imported = x.node.imported;
|
||||||
|
return local.scope.getOwnBinding(local.node.name)!.referencePaths.map(p => ({
|
||||||
|
local: p as NodePath<t.Identifier>,
|
||||||
|
imported: getName(t, imported)!,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Boolean)
|
||||||
|
.flat(1);
|
||||||
|
|
||||||
|
for (const x of importDecs) {
|
||||||
|
x.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
return macros;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isNodePath = <T extends t.Node>(
|
||||||
|
nodePath: NodePath<t.Node | null | undefined> | null,
|
||||||
|
predicate: (node: t.Node) => node is T
|
||||||
|
): nodePath is NodePath<T> => Boolean(nodePath?.node && predicate(nodePath.node));
|
51
src/babel/utils.ts
Normal file
51
src/babel/utils.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { basename, dirname, extname, join } from "node:path";
|
||||||
|
import type b from "@babel/core";
|
||||||
|
import hash from "@emotion/hash";
|
||||||
|
import { isPlainObject } from "lodash";
|
||||||
|
import invariant from "tiny-invariant";
|
||||||
|
import { type NodePath, type types as t } from "@babel/core";
|
||||||
|
import { type SourceLocation, type StyleMapEntry } from "../shared";
|
||||||
|
import { type ResolveTailwindOptions, getClassName } from "../index";
|
||||||
|
import { handleMacro } from "./macro";
|
||||||
|
|
||||||
|
export function evaluateArgs(path: NodePath) {
|
||||||
|
const { confident, value } = path.evaluate();
|
||||||
|
invariant(confident, "Argument cannot be statically evaluated");
|
||||||
|
|
||||||
|
if (typeof value === "string") {
|
||||||
|
return trim(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPlainObject(value)) {
|
||||||
|
return flatMapEntries(value, (classes, modifier) => {
|
||||||
|
if (modifier === "data" && isPlainObject(classes)) {
|
||||||
|
return flatMapEntries(classes as Record<string, string | object>, (cls, key) =>
|
||||||
|
typeof cls === "string"
|
||||||
|
? trimPrefix(cls, `${modifier}-[${key}]:`)
|
||||||
|
: flatMapEntries(cls as Record<string, string>, (cls, attrValue) =>
|
||||||
|
trimPrefix(cls, `${modifier}-[${key}=${attrValue}]:`)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
invariant(
|
||||||
|
typeof classes === "string",
|
||||||
|
`Value for "${modifier}" should be a string`
|
||||||
|
);
|
||||||
|
return trimPrefix(classes, modifier + ":");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("Invalid argument type");
|
||||||
|
}
|
||||||
|
|
||||||
|
export const trim = (value: string) =>
|
||||||
|
value.replace(/\s+/g, " ").trim().split(" ").filter(Boolean);
|
||||||
|
|
||||||
|
export const trimPrefix = (cls: string, prefix = "") =>
|
||||||
|
trim(cls).map(value => prefix + value);
|
||||||
|
|
||||||
|
const flatMapEntries = <K extends string | number, V, R>(
|
||||||
|
map: Record<K, V>,
|
||||||
|
fn: (value: V, key: K) => R[]
|
||||||
|
): R[] => Object.entries(map).flatMap(([key, value]) => fn(value as V, key as K));
|
@ -4,7 +4,7 @@ import type { SetRequired } from "type-fest";
|
|||||||
import { transformSync } from "esbuild";
|
import { transformSync } from "esbuild";
|
||||||
import type postcss from "postcss";
|
import type postcss from "postcss";
|
||||||
import { memoize, without } from "lodash";
|
import { memoize, without } from "lodash";
|
||||||
import { type ClassNameCollector, babelTailwind } from "./babel-tailwind";
|
import { type ClassNameCollector, babelTailwind } from "./babel/index";
|
||||||
import { esbuildPlugin } from "./esbuild-postcss";
|
import { esbuildPlugin } from "./esbuild-postcss";
|
||||||
import { vitePlugin } from "./vite-plugin";
|
import { vitePlugin } from "./vite-plugin";
|
||||||
import { type StyleMap, createPostCSS } from "./shared";
|
import { type StyleMap, createPostCSS } from "./shared";
|
||||||
|
2
src/macro.d.ts
vendored
2
src/macro.d.ts
vendored
@ -99,5 +99,5 @@ type TailwindStyleFunctionReturn = Config extends { tws: infer T } ? T : never;
|
|||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface, @typescript-eslint/no-empty-object-type
|
||||||
export interface Config {}
|
export interface Config {}
|
||||||
|
@ -17,7 +17,7 @@ export const vitePlugin = ({
|
|||||||
name: "tailwind",
|
name: "tailwind",
|
||||||
|
|
||||||
config(config) {
|
config(config) {
|
||||||
((config.optimizeDeps ?? {}).exclude ?? []).push(...macroNames, `${pkgName}/base`);
|
((config.optimizeDeps ??= {}).exclude ??= []).push(...macroNames, `${pkgName}/base`);
|
||||||
},
|
},
|
||||||
|
|
||||||
resolveId(id, importer) {
|
resolveId(id, importer) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user