From 3083b0a059e7ad3ae811785a1c3bd5ed0b379392 Mon Sep 17 00:00:00 2001 From: SonOfMagic Date: Wed, 7 Jun 2023 10:30:27 +0800 Subject: [PATCH 1/9] chore: add mangleClassFilter options --- apps/vite-vue/src/App.vue | 33 +++++++++++++++++++++++++++++++++ apps/vite-vue/vite.config.ts | 8 +++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/apps/vite-vue/src/App.vue b/apps/vite-vue/src/App.vue index e93b75f4..987ca090 100644 --- a/apps/vite-vue/src/App.vue +++ b/apps/vite-vue/src/App.vue @@ -75,6 +75,39 @@ + + .logo { height: 6em; diff --git a/apps/vite-vue/vite.config.ts b/apps/vite-vue/vite.config.ts index c99bd368..3bc44b18 100644 --- a/apps/vite-vue/vite.config.ts +++ b/apps/vite-vue/vite.config.ts @@ -1,11 +1,17 @@ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' -import { vitePlugin as utwm } from 'unplugin-tailwindcss-mangle' +import { vitePlugin as utwm, defaultMangleClassFilter } from 'unplugin-tailwindcss-mangle' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), utwm({ + mangleClassFilter(className) { + if (['ease-out', 'ease-linear', 'ease-in', 'ease-in-out'].includes(className)) { + return false + } + return defaultMangleClassFilter(className) + }, classSetOutput: true, classMapOutput: true }) From 00dc3d49ce067dca978b7a8516a22efdd83ed353 Mon Sep 17 00:00:00 2001 From: SonOfMagic Date: Wed, 7 Jun 2023 10:45:46 +0800 Subject: [PATCH 2/9] fix: #22 tsd type error --- apps/vite-vue/vite.config.ts | 5 ++++- .../unplugin-tailwindcss-mangle/src/types.ts | 16 +++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/vite-vue/vite.config.ts b/apps/vite-vue/vite.config.ts index 3bc44b18..f41b1ed6 100644 --- a/apps/vite-vue/vite.config.ts +++ b/apps/vite-vue/vite.config.ts @@ -13,7 +13,10 @@ export default defineConfig({ return defaultMangleClassFilter(className) }, classSetOutput: true, - classMapOutput: true + classMapOutput: true, + jsHandlerOptions: { + minified: true + } }) ] }) diff --git a/packages/unplugin-tailwindcss-mangle/src/types.ts b/packages/unplugin-tailwindcss-mangle/src/types.ts index 3f867854..6110d71c 100644 --- a/packages/unplugin-tailwindcss-mangle/src/types.ts +++ b/packages/unplugin-tailwindcss-mangle/src/types.ts @@ -1,5 +1,5 @@ import type { - ClassGenerator, + IHandlerOptions, IHtmlHandlerOptions, // as InternalHtmlHandlerOptions, IJsHandlerOptions, // as InternalJsHandlerOptions, ICssHandlerOptions // as InternalCssHandlerOptions @@ -15,11 +15,6 @@ export interface IClassGeneratorOptions { classPrefix?: string } -export interface IHandlerOptions { - runtimeSet: Set - classGenerator: ClassGenerator -} - export interface ClassSetOutputOptions { filename: string dir?: string @@ -30,6 +25,9 @@ export interface ClassMapOutputOptions { filename: string dir?: string } + +export type PartialHandlerOptions = Partial> + export interface Options { mangleClassFilter?: (className: string) => boolean classGenerator?: IClassGeneratorOptions @@ -37,7 +35,7 @@ export interface Options { include?: string[] classSetOutput?: boolean | ClassSetOutputOptions classMapOutput?: boolean | ClassMapOutputOptions - htmlHandlerOptions?: IHtmlHandlerOptions - jsHandlerOptions?: IJsHandlerOptions - cssHandlerOptions?: ICssHandlerOptions + htmlHandlerOptions?: PartialHandlerOptions + jsHandlerOptions?: PartialHandlerOptions + cssHandlerOptions?: PartialHandlerOptions } From 29e96df43f0733efdfc123686d7852c1d86472fa Mon Sep 17 00:00:00 2001 From: SonOfMagic Date: Wed, 7 Jun 2023 10:47:09 +0800 Subject: [PATCH 3/9] chore: release v1.2.3 --- package.json | 2 +- packages/core/package.json | 2 +- packages/shared/package.json | 2 +- packages/tailwindcss-patch/package.json | 2 +- packages/unplugin-tailwindcss-mangle/package.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 92b261b6..a86ebf89 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tailwindcss-mangle", - "version": "1.2.2", + "version": "1.2.3", "private": true, "workspaces": [ "apps/*", diff --git a/packages/core/package.json b/packages/core/package.json index 3a3d4675..6844e32d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "tailwindcss-mangle-core", - "version": "1.2.2", + "version": "1.2.3", "description": "The core of tailwindcss-mangle", "main": "dist/index.js", "module": "./dist/index.mjs", diff --git a/packages/shared/package.json b/packages/shared/package.json index 451b26a0..37e426fc 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "tailwindcss-mangle-shared", - "version": "1.2.2", + "version": "1.2.3", "description": "The shared utils of tailwindcss-mangle", "main": "dist/index.js", "module": "./dist/index.mjs", diff --git a/packages/tailwindcss-patch/package.json b/packages/tailwindcss-patch/package.json index 4afbfb41..f3251ce2 100644 --- a/packages/tailwindcss-patch/package.json +++ b/packages/tailwindcss-patch/package.json @@ -1,6 +1,6 @@ { "name": "tailwindcss-patch", - "version": "1.2.2", + "version": "1.2.3", "description": "patch tailwindcss for exposing context", "main": "dist/index.js", "module": "./dist/index.mjs", diff --git a/packages/unplugin-tailwindcss-mangle/package.json b/packages/unplugin-tailwindcss-mangle/package.json index 1d94a015..724b9b3f 100644 --- a/packages/unplugin-tailwindcss-mangle/package.json +++ b/packages/unplugin-tailwindcss-mangle/package.json @@ -1,6 +1,6 @@ { "name": "unplugin-tailwindcss-mangle", - "version": "1.2.2", + "version": "1.2.3", "description": "mangle tailwindcss utilities class plugin. support vite and webpack!", "main": "./dist/index.js", "module": "./dist/index.mjs", From 9d5308f249a3cacf308e5bc04fca0ad0940d54f5 Mon Sep 17 00:00:00 2001 From: ice breaker <1324318532@qq.com> Date: Wed, 7 Jun 2023 23:15:55 +0800 Subject: [PATCH 4/9] fix: Bug with utility class which contains trailing slash #24 regex should exact match class str --- package.json | 5 +- packages/core/jest.config.ts | 3 +- packages/core/package.json | 8 +- .../core/test/__snapshots__/html.test.ts.snap | 39 +++ .../core/test/__snapshots__/js.test.ts.snap | 2 + .../core/test/fixtures/trailing-slash-0.js | 1 + .../core/test/fixtures/trailing-slash.html | 22 ++ packages/core/test/html.test.ts | 35 ++ packages/core/test/js.test.ts | 12 + packages/core/vitest.config.ts | 8 + packages/shared/src/regex.ts | 11 +- .../test/__snapshots__/reg.test.ts.snap | 19 ++ packages/shared/test/reg.test.ts | 18 + .../tailwindcss-patch/test/context.test.ts | 11 + .../test/fixtures/trailing-slash.vue | 16 + pnpm-lock.yaml | 317 +++++++++++++++--- 16 files changed, 477 insertions(+), 50 deletions(-) create mode 100644 packages/core/test/__snapshots__/html.test.ts.snap create mode 100644 packages/core/test/fixtures/trailing-slash-0.js create mode 100644 packages/core/test/fixtures/trailing-slash.html create mode 100644 packages/core/test/html.test.ts create mode 100644 packages/core/vitest.config.ts create mode 100644 packages/tailwindcss-patch/test/fixtures/trailing-slash.vue diff --git a/package.json b/package.json index a86ebf89..a750697f 100644 --- a/package.json +++ b/package.json @@ -44,5 +44,8 @@ "engines": { "node": ">=14.0.0" }, - "packageManager": "pnpm@8.5.1" + "packageManager": "pnpm@8.5.1", + "dependencies": { + "vitest": "^0.32.0" + } } diff --git a/packages/core/jest.config.ts b/packages/core/jest.config.ts index d5846f50..be4ffc77 100644 --- a/packages/core/jest.config.ts +++ b/packages/core/jest.config.ts @@ -3,7 +3,8 @@ import baseConfig from '../../jest.config' const config: Config = { projects: [ { - ...baseConfig + ...baseConfig, + modulePathIgnorePatterns: ['test/html.test.ts'] // transformIgnorePatterns: ['/node_modules/(?!(@parse5/)/tools)'] } ] diff --git a/packages/core/package.json b/packages/core/package.json index 6844e32d..a8ef5e04 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -13,7 +13,11 @@ "build": "cross-env NODE_ENV=production rollup -c", "dev:tsc": "tsc -p tsconfig.json --sourceMap", "build:tsc": "tsc -p tsconfig.json", - "test": "yarn build && jest" + "_test": "yarn build && jest", + "jest:u": "jest -u", + "test:dev": "yarn build && vitest", + "test": "yarn build && jest && vitest run", + "coverage": "vitest run --coverage" }, "keywords": [ "tailwindcss", @@ -45,4 +49,4 @@ "type": "git", "url": "git+https://github.com/sonofmagic/tailwindcss-mangle.git" } -} +} \ No newline at end of file diff --git a/packages/core/test/__snapshots__/html.test.ts.snap b/packages/core/test/__snapshots__/html.test.ts.snap new file mode 100644 index 00000000..5e3d5d40 --- /dev/null +++ b/packages/core/test/__snapshots__/html.test.ts.snap @@ -0,0 +1,39 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`html handler > common usage 1`] = ` +" + + + + + + +

+ Hello world! +

+ + +" +`; + +exports[`html handler > trailing slash case 1`] = ` +" + + + + Document + + + +
+
+ Block with bg-red-500 class +
+
+ Block with bg-red-500/50 class +
+
+ + +" +`; diff --git a/packages/core/test/__snapshots__/js.test.ts.snap b/packages/core/test/__snapshots__/js.test.ts.snap index b4a10947..eaae2b76 100644 --- a/packages/core/test/__snapshots__/js.test.ts.snap +++ b/packages/core/test/__snapshots__/js.test.ts.snap @@ -252,6 +252,8 @@ exports[`js handler nextjs server side mangle 1`] = ` })();" `; +exports[`js handler trailing slash case 0 1`] = `"document.getElementById("#app").classList.add("tw-a tw-b");"`; + exports[`js handler z-10 not transform 1`] = ` "{ className: "tw-a tw-b tw-c tw-d tw-e tw-f tw-g tw-h"; diff --git a/packages/core/test/fixtures/trailing-slash-0.js b/packages/core/test/fixtures/trailing-slash-0.js new file mode 100644 index 00000000..6f942b7b --- /dev/null +++ b/packages/core/test/fixtures/trailing-slash-0.js @@ -0,0 +1 @@ +document.getElementById('#app').classList.add('bg-red-500 bg-red-500/50') diff --git a/packages/core/test/fixtures/trailing-slash.html b/packages/core/test/fixtures/trailing-slash.html new file mode 100644 index 00000000..5107940b --- /dev/null +++ b/packages/core/test/fixtures/trailing-slash.html @@ -0,0 +1,22 @@ + + + + + + + + Document + + + +
+
+ Block with bg-red-500 class +
+
+ Block with bg-red-500/50 class +
+
+ + + \ No newline at end of file diff --git a/packages/core/test/html.test.ts b/packages/core/test/html.test.ts new file mode 100644 index 00000000..f8a09549 --- /dev/null +++ b/packages/core/test/html.test.ts @@ -0,0 +1,35 @@ +import { getTestCase } from './utils' +import { htmlHandler } from '../src/html' +import { ClassGenerator, splitCode } from 'tailwindcss-mangle-shared' +import { describe, it, beforeEach, expect } from 'vitest' +describe('html handler', () => { + let classGenerator: ClassGenerator + beforeEach(() => { + classGenerator = new ClassGenerator() + }) + it('common usage', () => { + const runtimeSet = new Set() + + splitCode('text-3xl font-bold underline').forEach((x) => { + runtimeSet.add(x) + }) + const res = htmlHandler(getTestCase('hello-world.html'), { + classGenerator, + runtimeSet + }) + expect(res).toMatchSnapshot() + }) + + it('trailing slash case', () => { + const runtimeSet = new Set() + + splitCode('bg-red-500 bg-red-500/50').forEach((x) => { + runtimeSet.add(x) + }) + const res = htmlHandler(getTestCase('trailing-slash.html'), { + classGenerator, + runtimeSet + }) + expect(res).toMatchSnapshot() + }) +}) diff --git a/packages/core/test/js.test.ts b/packages/core/test/js.test.ts index 6853987e..05f68b7d 100644 --- a/packages/core/test/js.test.ts +++ b/packages/core/test/js.test.ts @@ -149,4 +149,16 @@ describe('js handler', () => { }).code expect(code).toMatchSnapshot() }) + // https://github.com/sonofmagic/tailwindcss-mangle/issues/24 + it('trailing slash case 0', () => { + const testCase = getTestCase('trailing-slash-0.js') + const runtimeSet = new Set() + runtimeSet.add('bg-red-500') + runtimeSet.add('bg-red-500/50') + const code = jsHandler(testCase, { + classGenerator, + runtimeSet + }).code + expect(code).toMatchSnapshot() + }) }) diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts new file mode 100644 index 00000000..a0e465aa --- /dev/null +++ b/packages/core/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + include: ['test/html.test.ts'] + // ... + } +}) diff --git a/packages/shared/src/regex.ts b/packages/shared/src/regex.ts index d8f27504..da516e62 100644 --- a/packages/shared/src/regex.ts +++ b/packages/shared/src/regex.ts @@ -5,6 +5,13 @@ export function escapeStringRegexp(str: string) { return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d') } -export function makeRegex(str: string) { - return new RegExp('(?<=^|[\\s"])' + escapeStringRegexp(str), 'g') +export function makeRegex( + str: string, + options: { + exact: boolean + } = { + exact: true + } +) { + return new RegExp('(?<=^|[\\s"])' + escapeStringRegexp(str) + (options.exact ? '(?=$|[\\s"])' : ''), 'g') } diff --git a/packages/shared/test/__snapshots__/reg.test.ts.snap b/packages/shared/test/__snapshots__/reg.test.ts.snap index 5a5f1071..d5d7cebc 100644 --- a/packages/shared/test/__snapshots__/reg.test.ts.snap +++ b/packages/shared/test/__snapshots__/reg.test.ts.snap @@ -1,5 +1,24 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`regex trailing slash should exact match case 0 1`] = ` +[ + [ + "bg-red-500", + ], + [ + "bg-red-500", + ], +] +`; + +exports[`regex trailing slash should exact match case 1 1`] = ` +[ + [ + "bg-red-500", + ], +] +`; + exports[`regex z-10 regex 1`] = ` [ [ diff --git a/packages/shared/test/reg.test.ts b/packages/shared/test/reg.test.ts index 936650aa..a3d4fb5b 100644 --- a/packages/shared/test/reg.test.ts +++ b/packages/shared/test/reg.test.ts @@ -8,4 +8,22 @@ describe('regex', () => { expect(arr.length).toBe(1) expect(arr).toMatchSnapshot() }) + + it('trailing slash should exact match case 0', () => { + const testCase = 'bg-red-500 bg-red-500/50' + const regex = makeRegex('bg-red-500', { + exact: false + }) + const arr = Array.from(testCase.matchAll(regex)) + expect(arr.length).toBe(2) + expect(arr).toMatchSnapshot() + }) + + it('trailing slash should exact match case 1', () => { + const testCase = 'bg-red-500 bg-red-500/50' + const regex = makeRegex('bg-red-500') + const arr = Array.from(testCase.matchAll(regex)) + expect(arr.length).toBe(1) + expect(arr).toMatchSnapshot() + }) }) diff --git a/packages/tailwindcss-patch/test/context.test.ts b/packages/tailwindcss-patch/test/context.test.ts index 11a4c44b..aefc11e6 100644 --- a/packages/tailwindcss-patch/test/context.test.ts +++ b/packages/tailwindcss-patch/test/context.test.ts @@ -32,4 +32,15 @@ describe('common usage', () => { expect(Array.from(set.values())[1]).toBe("bg-[url('https://xxx.webp')]") // }) + + it('trailing slash', () => { + getCss([getTestCase('trailing-slash.vue')]) + const ctxs = getContexts() + expect(ctxs).toBeTruthy() + const set = getClassCacheSet() + expect(set.size).toBeGreaterThan(0) + expect(set.size).toBe(4) + expect(set.has('bg-red-500')).toBe(true) + expect(set.has('bg-red-500/50')).toBe(true) + }) }) diff --git a/packages/tailwindcss-patch/test/fixtures/trailing-slash.vue b/packages/tailwindcss-patch/test/fixtures/trailing-slash.vue new file mode 100644 index 00000000..5f6b8b10 --- /dev/null +++ b/packages/tailwindcss-patch/test/fixtures/trailing-slash.vue @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3b54a6be..d237daa6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,6 +3,10 @@ lockfileVersion: '6.0' importers: .: + dependencies: + vitest: + specifier: ^0.32.0 + version: 0.32.0 devDependencies: '@icebreakers/eslint-config-ts': specifier: ^1.1.0 @@ -2966,7 +2970,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.21.5 '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.21.4) '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.21.4) '@babel/types': 7.22.4 @@ -3127,7 +3131,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-arm64@0.17.6: @@ -3145,7 +3148,6 @@ packages: cpu: [arm] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-arm@0.17.6: @@ -3163,7 +3165,6 @@ packages: cpu: [x64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-x64@0.17.6: @@ -3181,7 +3182,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/darwin-arm64@0.17.6: @@ -3199,7 +3199,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/darwin-x64@0.17.6: @@ -3217,7 +3216,6 @@ packages: cpu: [arm64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-arm64@0.17.6: @@ -3235,7 +3233,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-x64@0.17.6: @@ -3253,7 +3250,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm64@0.17.6: @@ -3271,7 +3267,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm@0.17.6: @@ -3289,7 +3284,6 @@ packages: cpu: [ia32] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ia32@0.17.6: @@ -3307,7 +3301,6 @@ packages: cpu: [loong64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-loong64@0.17.6: @@ -3325,7 +3318,6 @@ packages: cpu: [mips64el] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-mips64el@0.17.6: @@ -3343,7 +3335,6 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ppc64@0.17.6: @@ -3361,7 +3352,6 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-riscv64@0.17.6: @@ -3379,7 +3369,6 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-s390x@0.17.6: @@ -3397,7 +3386,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-x64@0.17.6: @@ -3415,7 +3403,6 @@ packages: cpu: [x64] os: [netbsd] requiresBuild: true - dev: true optional: true /@esbuild/netbsd-x64@0.17.6: @@ -3433,7 +3420,6 @@ packages: cpu: [x64] os: [openbsd] requiresBuild: true - dev: true optional: true /@esbuild/openbsd-x64@0.17.6: @@ -3451,7 +3437,6 @@ packages: cpu: [x64] os: [sunos] requiresBuild: true - dev: true optional: true /@esbuild/sunos-x64@0.17.6: @@ -3469,7 +3454,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-arm64@0.17.6: @@ -3487,7 +3471,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-ia32@0.17.6: @@ -3505,7 +3488,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-x64@0.17.6: @@ -4914,6 +4896,16 @@ packages: '@types/responselike': 1.0.0 dev: true + /@types/chai-subset@1.3.3: + resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} + dependencies: + '@types/chai': 4.3.5 + dev: false + + /@types/chai@4.3.5: + resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} + dev: false + /@types/connect-history-api-fallback@1.3.5: resolution: {integrity: sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==} dependencies: @@ -5493,6 +5485,45 @@ packages: vue: 3.3.4 dev: true + /@vitest/expect@0.32.0: + resolution: {integrity: sha512-VxVHhIxKw9Lux+O9bwLEEk2gzOUe93xuFHy9SzYWnnoYZFYg1NfBtnfnYWiJN7yooJ7KNElCK5YtA7DTZvtXtg==} + dependencies: + '@vitest/spy': 0.32.0 + '@vitest/utils': 0.32.0 + chai: 4.3.7 + dev: false + + /@vitest/runner@0.32.0: + resolution: {integrity: sha512-QpCmRxftHkr72xt5A08xTEs9I4iWEXIOCHWhQQguWOKE4QH7DXSKZSOFibuwEIMAD7G0ERvtUyQn7iPWIqSwmw==} + dependencies: + '@vitest/utils': 0.32.0 + concordance: 5.0.4 + p-limit: 4.0.0 + pathe: 1.1.1 + dev: false + + /@vitest/snapshot@0.32.0: + resolution: {integrity: sha512-yCKorPWjEnzpUxQpGlxulujTcSPgkblwGzAUEL+z01FTUg/YuCDZ8dxr9sHA08oO2EwxzHXNLjQKWJ2zc2a19Q==} + dependencies: + magic-string: 0.30.0 + pathe: 1.1.1 + pretty-format: 27.5.1 + dev: false + + /@vitest/spy@0.32.0: + resolution: {integrity: sha512-MruAPlM0uyiq3d53BkwTeShXY0rYEfhNGQzVO5GHBmmX3clsxcWp79mMnkOVcV244sNTeDcHbcPFWIjOI4tZvw==} + dependencies: + tinyspy: 2.1.1 + dev: false + + /@vitest/utils@0.32.0: + resolution: {integrity: sha512-53yXunzx47MmbuvcOPpLaVljHaeSu1G2dHdmy7+9ngMnQIkBQcvwOcoclWFnxDMxFbnq8exAfh3aKSZaK71J5A==} + dependencies: + concordance: 5.0.4 + loupe: 2.3.6 + pretty-format: 27.5.1 + dev: false + /@volar/language-core@1.4.1: resolution: {integrity: sha512-EIY+Swv+TjsWpxOxujjMf1ZXqOjg9MT2VMXZ+1dKva0wD8W0L6EtptFFcCJdBbcKmGMFkr57Qzz9VNMWhs3jXQ==} dependencies: @@ -6599,7 +6630,6 @@ packages: /ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - dev: true /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -6730,6 +6760,10 @@ packages: es-shim-unscopables: 1.0.0 get-intrinsic: 1.2.1 + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: false + /ast-types-flow@0.0.7: resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} @@ -7045,6 +7079,10 @@ packages: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} dev: true + /blueimp-md5@2.19.0: + resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} + dev: false + /body-parser@1.20.1: resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -7235,7 +7273,6 @@ packages: /cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - dev: true /cacache@15.3.0: resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} @@ -7336,6 +7373,19 @@ packages: engines: {node: '>=4'} dev: true + /chai@4.3.7: + resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.2 + deep-eql: 4.1.3 + get-func-name: 2.0.0 + loupe: 2.3.6 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: false + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -7389,6 +7439,10 @@ packages: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true + /check-error@1.0.2: + resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} + dev: false + /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -7659,6 +7713,20 @@ packages: /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + /concordance@5.0.4: + resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==} + engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'} + dependencies: + date-time: 3.1.0 + esutils: 2.0.3 + fast-diff: 1.3.0 + js-string-escape: 1.0.1 + lodash: 4.17.21 + md5-hex: 3.0.1 + semver: 7.5.1 + well-known-symbols: 2.0.0 + dev: false + /connect-history-api-fallback@2.0.0: resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} engines: {node: '>=0.8'} @@ -8243,6 +8311,13 @@ packages: engines: {node: '>= 12'} dev: true + /date-time@3.1.0: + resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} + engines: {node: '>=6'} + dependencies: + time-zone: 1.0.0 + dev: false + /de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} dev: true @@ -8305,6 +8380,13 @@ packages: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} dev: true + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: false + /deep-equal@2.2.1: resolution: {integrity: sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ==} dependencies: @@ -8837,7 +8919,6 @@ packages: '@esbuild/win32-arm64': 0.17.19 '@esbuild/win32-ia32': 0.17.19 '@esbuild/win32-x64': 0.17.19 - dev: true /esbuild@0.17.6: resolution: {integrity: sha512-TKFRp9TxrJDdRWfSsSERKEovm6v30iHnrjlcGhLBOtReE28Yp1VSBRfO3GTaOFMoxsNerx4TjrhzSuma9ha83Q==} @@ -9685,7 +9766,6 @@ packages: /fast-diff@1.3.0: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - dev: true /fast-glob@3.2.11: resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} @@ -10029,6 +10109,10 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true + /get-func-name@2.0.0: + resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} + dev: false + /get-intrinsic@1.2.0: resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} dependencies: @@ -11607,6 +11691,11 @@ packages: engines: {node: '>=0.6.0'} dev: true + /js-string-escape@1.0.1: + resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} + engines: {node: '>= 0.8'} + dev: false + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -11675,7 +11764,6 @@ packages: /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - dev: true /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -11849,7 +11937,6 @@ packages: /local-pkg@0.4.3: resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} engines: {node: '>=14'} - dev: true /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} @@ -11925,7 +12012,6 @@ packages: /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} @@ -11954,6 +12040,12 @@ packages: dependencies: js-tokens: 4.0.0 + /loupe@2.3.6: + resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} + dependencies: + get-func-name: 2.0.0 + dev: false + /lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} dependencies: @@ -12039,6 +12131,13 @@ packages: engines: {node: '>=0.10.0'} dev: true + /md5-hex@3.0.1: + resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==} + engines: {node: '>=8'} + dependencies: + blueimp-md5: 2.19.0 + dev: false + /mdast-util-definitions@5.1.2: resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==} dependencies: @@ -12666,10 +12765,9 @@ packages: resolution: {integrity: sha512-1aMEByaWgBPEbWV2BOPEMySRrzl7rIHXmQxam4DM8jVjalTQDjpN2ZKOLUrwyhfZQO7IXHml2StcHMhooDeEEQ==} dependencies: acorn: 8.8.2 - pathe: 1.1.0 + pathe: 1.1.1 pkg-types: 1.0.3 ufo: 1.1.2 - dev: true /mlly@1.3.0: resolution: {integrity: sha512-HT5mcgIQKkOrZecOjOX3DJorTikWXwsBfpcr/MGBkhfWcjiqvnaL/9ppxvIUXfjT6xt4DVIAsN9fMUz1ev4bIw==} @@ -12678,7 +12776,6 @@ packages: pathe: 1.1.1 pkg-types: 1.0.3 ufo: 1.1.2 - dev: true /module-alias@2.2.2: resolution: {integrity: sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==} @@ -13379,6 +13476,13 @@ packages: dependencies: yocto-queue: 0.1.0 + /p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: false + /p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -13566,11 +13670,13 @@ packages: /pathe@1.1.0: resolution: {integrity: sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==} - dev: true /pathe@1.1.1: resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} - dev: true + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: false /peek-stream@1.1.3: resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} @@ -13628,7 +13734,6 @@ packages: jsonc-parser: 3.2.0 mlly: 1.2.1 pathe: 1.1.0 - dev: true /portfinder@1.0.32: resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==} @@ -14436,7 +14541,6 @@ packages: ansi-regex: 5.0.1 ansi-styles: 5.2.0 react-is: 17.0.2 - dev: true /pretty-format@29.5.0: resolution: {integrity: sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==} @@ -14637,7 +14741,6 @@ packages: /react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - dev: true /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} @@ -15004,7 +15107,6 @@ packages: hasBin: true optionalDependencies: fsevents: 2.3.2 - dev: true /run-applescript@5.0.0: resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} @@ -15290,6 +15392,10 @@ packages: get-intrinsic: 1.2.0 object-inspect: 1.12.3 + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + dev: false + /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -15503,6 +15609,10 @@ packages: escape-string-regexp: 2.0.0 dev: true + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + dev: false + /stackframe@1.3.4: resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} dev: true @@ -15522,7 +15632,6 @@ packages: /std-env@3.3.3: resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==} - dev: true /stop-iteration-iterator@1.0.0: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} @@ -15687,7 +15796,6 @@ packages: resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} dependencies: acorn: 8.8.2 - dev: true /style-to-object@0.4.1: resolution: {integrity: sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==} @@ -16103,10 +16211,29 @@ packages: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} dev: true + /time-zone@1.0.0: + resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==} + engines: {node: '>=4'} + dev: false + /tiny-invariant@1.3.1: resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} dev: true + /tinybench@2.5.0: + resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==} + dev: false + + /tinypool@0.5.0: + resolution: {integrity: sha512-paHQtnrlS1QZYKF/GnLoOM/DN9fqaGOFbCbxzAhwniySnzl9Ebk8w73/dd34DAhe/obUbPAOldTyYXQZxnPBPQ==} + engines: {node: '>=14.0.0'} + dev: false + + /tinyspy@2.1.1: + resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==} + engines: {node: '>=14.0.0'} + dev: false + /titleize@3.0.0: resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} engines: {node: '>=12'} @@ -16283,7 +16410,6 @@ packages: /type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} - dev: true /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} @@ -16330,7 +16456,6 @@ packages: /ufo@1.1.2: resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==} - dev: true /ultrahtml@1.2.0: resolution: {integrity: sha512-vxZM2yNvajRmCj/SknRYGNXk2tqiy6kRNvZjJLaleG3zJbSh/aNkOqD1/CVzypw8tyHyhpzYuwQgMMhUB4ZVNQ==} @@ -16767,6 +16892,27 @@ packages: - terser dev: true + /vite-node@0.32.0(@types/node@20.2.5): + resolution: {integrity: sha512-220P/y8YacYAU+daOAqiGEFXx2A8AwjadDzQqos6wSukjvvTWNqleJSwoUn0ckyNdjHIKoxn93Nh1vWBqEKr3Q==} + engines: {node: '>=v14.18.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + mlly: 1.3.0 + pathe: 1.1.1 + picocolors: 1.0.0 + vite: 4.3.9(@types/node@20.2.5) + transitivePeerDependencies: + - '@types/node' + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: false + /vite-plugin-checker@0.6.0(eslint@8.42.0)(typescript@5.1.3)(vite@4.3.9): resolution: {integrity: sha512-DWZ9Hv2TkpjviPxAelNUt4Q3IhSGrx7xrwdM64NI+Q4dt8PaMWJJh4qGNtSrfEuiuIzWWo00Ksvh5It4Y3L9xQ==} engines: {node: '>=14.16'} @@ -16870,7 +17016,6 @@ packages: rollup: 3.23.1 optionalDependencies: fsevents: 2.3.2 - dev: true /vitefu@0.2.4(vite@4.3.9): resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} @@ -16883,6 +17028,71 @@ packages: vite: 4.3.9(@types/node@20.2.5) dev: true + /vitest@0.32.0: + resolution: {integrity: sha512-SW83o629gCqnV3BqBnTxhB10DAwzwEx3z+rqYZESehUB+eWsJxwcBQx7CKy0otuGMJTYh7qCVuUX23HkftGl/Q==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.5 + '@types/chai-subset': 1.3.3 + '@types/node': 20.2.5 + '@vitest/expect': 0.32.0 + '@vitest/runner': 0.32.0 + '@vitest/snapshot': 0.32.0 + '@vitest/spy': 0.32.0 + '@vitest/utils': 0.32.0 + acorn: 8.8.2 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + concordance: 5.0.4 + debug: 4.3.4 + local-pkg: 0.4.3 + magic-string: 0.30.0 + pathe: 1.1.1 + picocolors: 1.0.0 + std-env: 3.3.3 + strip-literal: 1.0.1 + tinybench: 2.5.0 + tinypool: 0.5.0 + vite: 4.3.9(@types/node@20.2.5) + vite-node: 0.32.0(@types/node@20.2.5) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: false + /vm2@3.9.19: resolution: {integrity: sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==} engines: {node: '>=6.0'} @@ -17374,6 +17584,11 @@ packages: engines: {node: '>=0.8.0'} dev: true + /well-known-symbols@2.0.0: + resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==} + engines: {node: '>=6'} + dev: false + /whatwg-fetch@3.6.2: resolution: {integrity: sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==} dev: true @@ -17432,6 +17647,15 @@ packages: dependencies: isexe: 2.0.0 + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: false + /wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} dependencies: @@ -17652,6 +17876,11 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: false + /yorkie@2.0.0: resolution: {integrity: sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==} engines: {node: '>=4'} From f475c58873ff1699aa30cfb38ae50f9c92fc8a9a Mon Sep 17 00:00:00 2001 From: ice breaker <1324318532@qq.com> Date: Wed, 7 Jun 2023 23:42:37 +0800 Subject: [PATCH 5/9] refact: use unicorn rule --- .eslintrc.js | 9 +- package.json | 1 + packages/core/src/css/plugins.ts | 20 +-- packages/core/src/html/index.ts | 11 +- packages/core/src/js/index.ts | 27 ++-- packages/core/test/html.test.ts | 8 +- packages/core/test/js.test.ts | 8 +- packages/shared/src/classGenerator.ts | 12 +- packages/shared/src/regex.ts | 2 +- packages/shared/src/split.ts | 6 +- packages/shared/src/utils.ts | 26 ++-- packages/shared/test/reg.test.ts | 6 +- packages/shared/test/split.test.ts | 4 +- packages/tailwindcss-patch/src/babel.ts | 8 +- packages/tailwindcss-patch/src/cache.ts | 14 +- packages/tailwindcss-patch/src/class.ts | 2 +- .../tailwindcss-patch/src/exposeContext.ts | 7 +- packages/tailwindcss-patch/src/inspector.ts | 140 +++++++++--------- packages/tailwindcss-patch/src/patcher.ts | 8 +- packages/tailwindcss-patch/src/utils.ts | 7 +- .../unplugin-tailwindcss-mangle/src/index.ts | 60 ++++---- .../src/options.ts | 6 +- .../unplugin-tailwindcss-mangle/src/utils.ts | 14 +- pnpm-lock.yaml | 58 ++++++++ 24 files changed, 252 insertions(+), 212 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 92360a36..8bb4a778 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,4 +1,11 @@ module.exports = { root: true, - extends: ['@icebreakers/eslint-config-ts'] + extends: ['@icebreakers/eslint-config-ts', 'plugin:unicorn/recommended'], + rules: { + 'unicorn/prefer-module': 0, + 'unicorn/prevent-abbreviations': 0, + 'unicorn/filename-case': 0, + 'unicorn/no-object-as-default-parameter': 0, + 'unicorn/no-null': 0 + } } diff --git a/package.json b/package.json index a750697f..732f9c04 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "bumpp": "^9.1.1", "cross-env": "^7.0.3", "eslint": "^8.42.0", + "eslint-plugin-unicorn": "^47.0.0", "jest": "^29.5.0", "only-allow": "^1.1.1", "prettier": "^2.8.8", diff --git a/packages/core/src/css/plugins.ts b/packages/core/src/css/plugins.ts index b86c060e..2952f455 100644 --- a/packages/core/src/css/plugins.ts +++ b/packages/core/src/css/plugins.ts @@ -8,10 +8,10 @@ const postcssPlugin = 'postcss-mangle-tailwindcss-plugin' export function isVueScoped(s: parser.ClassName): boolean { if (s.parent) { - const idx = s.parent.nodes.indexOf(s) - if (idx > -1) { - const nextNode = s.parent.nodes[idx + 1] - if (nextNode && nextNode.type === 'attribute' && nextNode.attribute.indexOf('data-v-') > -1) { + const index = s.parent.nodes.indexOf(s) + if (index > -1) { + const nextNode = s.parent.nodes[index + 1] + if (nextNode && nextNode.type === 'attribute' && nextNode.attribute.includes('data-v-')) { return true } } @@ -27,10 +27,8 @@ const postcssMangleTailwindcssPlugin: PostcssMangleTailwindcssPlugin = (options) // must set newClassMap options let set: Set = new Set() - if (options) { - if (options.runtimeSet) { - set = options.runtimeSet - } + if (options && options.runtimeSet) { + set = options.runtimeSet } return { postcssPlugin, @@ -54,10 +52,8 @@ const postcssMangleTailwindcssPlugin: PostcssMangleTailwindcssPlugin = (options) } else { let newClassMap: Record = {} - if (options) { - if (options.classGenerator) { - newClassMap = options.classGenerator.newClassMap - } + if (options && options.classGenerator) { + newClassMap = options.classGenerator.newClassMap } return { diff --git a/packages/core/src/html/index.ts b/packages/core/src/html/index.ts index 8cc5e410..3e9c89cb 100644 --- a/packages/core/src/html/index.ts +++ b/packages/core/src/html/index.ts @@ -8,15 +8,14 @@ export function htmlHandler(rawSource: string, options: IHtmlHandlerOptions) { const fragment = parse(rawSource) traverse(fragment, { element(node, parent) { - const attr = node.attrs.find((x) => x.name === 'class') - if (attr) { - const arr = splitCode(attr.value, { + const attribute = node.attrs.find((x) => x.name === 'class') + if (attribute) { + const array = splitCode(attribute.value, { splitQuote: false }) - for (let i = 0; i < arr.length; i++) { - const v = arr[i] + for (const v of array) { if (runtimeSet.has(v)) { - attr.value = attr.value.replace(makeRegex(v), classGenerator.generateClassName(v).name) + attribute.value = attribute.value.replace(makeRegex(v), classGenerator.generateClassName(v).name) } } } diff --git a/packages/core/src/js/index.ts b/packages/core/src/js/index.ts index c9fbb6ca..99953f2b 100644 --- a/packages/core/src/js/index.ts +++ b/packages/core/src/js/index.ts @@ -3,17 +3,16 @@ import * as t from '@babel/types' import { transformSync, type BabelFileResult, type NodePath } from '@babel/core' import type { IJsHandlerOptions } from '../types' import { makeRegex, splitCode } from '../shared' -import { isProd } from '../env' +import { isProd as isProduction } from '../env' -export function handleValue(str: string, node: StringLiteral | TemplateElement, options: IJsHandlerOptions) { +export function handleValue(string_: string, node: StringLiteral | TemplateElement, options: IJsHandlerOptions) { const { runtimeSet: set, classGenerator: clsGen, splitQuote = true } = options - const arr = splitCode(str, { + const array = splitCode(string_, { splitQuote }) - let rawStr = str - for (let i = 0; i < arr.length; i++) { - const v = arr[i] + let rawString = string_ + for (const v of array) { if (set.has(v)) { let ignoreFlag = false if (Array.isArray(node.leadingComments)) { @@ -21,11 +20,11 @@ export function handleValue(str: string, node: StringLiteral | TemplateElement, } if (!ignoreFlag) { - rawStr = rawStr.replace(makeRegex(v), clsGen.generateClassName(v).name) + rawString = rawString.replace(makeRegex(v), clsGen.generateClassName(v).name) } } } - return rawStr + return rawString } export function jsHandler(rawSource: string, options: IJsHandlerOptions) { @@ -52,12 +51,10 @@ export function jsHandler(rawSource: string, options: IJsHandlerOptions) { enter(p: NodePath) { const n = p.node // eval() - if (t.isIdentifier(n.callee) && n.callee.name === 'eval') { - if (t.isStringLiteral(n.arguments[0])) { - const res = jsHandler(n.arguments[0].value, options) - if (res.code) { - n.arguments[0].value = res.code - } + if (t.isIdentifier(n.callee) && n.callee.name === 'eval' && t.isStringLiteral(n.arguments[0])) { + const res = jsHandler(n.arguments[0].value, options) + if (res.code) { + n.arguments[0].value = res.code } } } @@ -67,7 +64,7 @@ export function jsHandler(rawSource: string, options: IJsHandlerOptions) { } } ], - minified: options.minified ?? isProd(), + minified: options.minified ?? isProduction(), sourceMaps: false, configFile: false }) diff --git a/packages/core/test/html.test.ts b/packages/core/test/html.test.ts index f8a09549..c643d5b5 100644 --- a/packages/core/test/html.test.ts +++ b/packages/core/test/html.test.ts @@ -10,9 +10,9 @@ describe('html handler', () => { it('common usage', () => { const runtimeSet = new Set() - splitCode('text-3xl font-bold underline').forEach((x) => { + for (const x of splitCode('text-3xl font-bold underline')) { runtimeSet.add(x) - }) + } const res = htmlHandler(getTestCase('hello-world.html'), { classGenerator, runtimeSet @@ -23,9 +23,9 @@ describe('html handler', () => { it('trailing slash case', () => { const runtimeSet = new Set() - splitCode('bg-red-500 bg-red-500/50').forEach((x) => { + for (const x of splitCode('bg-red-500 bg-red-500/50')) { runtimeSet.add(x) - }) + } const res = htmlHandler(getTestCase('trailing-slash.html'), { classGenerator, runtimeSet diff --git a/packages/core/test/js.test.ts b/packages/core/test/js.test.ts index 05f68b7d..5ae284ea 100644 --- a/packages/core/test/js.test.ts +++ b/packages/core/test/js.test.ts @@ -65,9 +65,9 @@ describe('js handler', () => { it('z-10 not transform', () => { const runtimeSet = new Set() - 'z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex'.split(' ').forEach((cls) => { + for (const cls of 'z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex'.split(' ')) { runtimeSet.add(cls) - }) + } const testCase = `{ className: "z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex" }` const code = jsHandler(testCase, { @@ -79,9 +79,9 @@ describe('js handler', () => { it('z-10 not transform with splitQuote false', () => { const runtimeSet = new Set() - 'z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex'.split(' ').forEach((cls) => { + for (const cls of 'z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex'.split(' ')) { runtimeSet.add(cls) - }) + } const testCase = `{ className: "z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex" }` const code = jsHandler(testCase, { diff --git a/packages/shared/src/classGenerator.ts b/packages/shared/src/classGenerator.ts index 693f54b1..8266f978 100644 --- a/packages/shared/src/classGenerator.ts +++ b/packages/shared/src/classGenerator.ts @@ -44,20 +44,12 @@ class ClassGenerator implements IClassGenerator { includeFilePath(filePath: string): boolean { const { include } = this.opts - if (Array.isArray(include)) { - return regExpTest(include, filePath) - } else { - return true - } + return Array.isArray(include) ? regExpTest(include, filePath) : true } excludeFilePath(filePath: string): boolean { const { exclude } = this.opts - if (Array.isArray(exclude)) { - return regExpTest(exclude, filePath) - } else { - return false - } + return Array.isArray(exclude) ? regExpTest(exclude, filePath) : false } isFileIncluded(filePath: string) { diff --git a/packages/shared/src/regex.ts b/packages/shared/src/regex.ts index da516e62..b69f9991 100644 --- a/packages/shared/src/regex.ts +++ b/packages/shared/src/regex.ts @@ -2,7 +2,7 @@ export function escapeStringRegexp(str: string) { if (typeof str !== 'string') { throw new TypeError('Expected a string') } - return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d') + return str.replaceAll(/[$()*+.?[\\\]^{|}]/g, '\\$&').replaceAll('-', '\\x2d') } export function makeRegex( diff --git a/packages/shared/src/split.ts b/packages/shared/src/split.ts index cf397bd2..7f6669c7 100644 --- a/packages/shared/src/split.ts +++ b/packages/shared/src/split.ts @@ -1,4 +1,4 @@ -export const validateFilterRE = /[\w\u00A0-\uFFFF-_:%-?]/ +export const validateFilterRE = /[\w%-?\u00A0-\uFFFF-]/ export function isValidSelector(selector = ''): selector is string { return validateFilterRE.test(selector) @@ -10,6 +10,6 @@ export const splitCode = ( splitQuote?: boolean } = { splitQuote: true } ) => { - const regex = options.splitQuote ? /[\s"]+/ : /[\s]+/ - return code.split(regex).filter(isValidSelector) + const regex = options.splitQuote ? /[\s"]+/ : /\s+/ + return code.split(regex).filter((x) => isValidSelector(x)) } diff --git a/packages/shared/src/utils.ts b/packages/shared/src/utils.ts index 7a9db21a..13b0f899 100644 --- a/packages/shared/src/utils.ts +++ b/packages/shared/src/utils.ts @@ -4,48 +4,47 @@ export const defaultMangleClassFilter = (className: string) => { // ignore className like 'filter','container' // it may be dangerous to mangle/rename all StringLiteral , so use /-/ test for only those with /-/ like: // bg-[#123456] w-1 etc... - return /[-:]/.test(className) + return /[:-]/.test(className) } export function groupBy(arr: T[], cb: (arg: T) => string): Record { if (!Array.isArray(arr)) { - throw new Error('expected an array for first argument') + throw new TypeError('expected an array for first argument') } if (typeof cb !== 'function') { - throw new Error('expected a function for second argument') + throw new TypeError('expected a function for second argument') } const result: Record = {} - for (let i = 0; i < arr.length; i++) { - const item = arr[i] + for (const item of arr) { const bucketCategory = cb(item) const bucket = result[bucketCategory] - if (!Array.isArray(bucket)) { - result[bucketCategory] = [item] - } else { + if (Array.isArray(bucket)) { result[bucketCategory].push(item) + } else { + result[bucketCategory] = [item] } } return result } -export const acceptChars = 'abcdefghijklmnopqrstuvwxyz'.split('') +export const acceptChars = [...'abcdefghijklmnopqrstuvwxyz'] export function stripEscapeSequence(words: string) { - return words.replace(/\\/g, '') + return words.replaceAll('\\', '') } export const validate = (opts: IClassGeneratorOptions, classGenerator: IClassGenerator) => { if (!opts.log) return for (const className in classGenerator.newClassMap) { const c = classGenerator.newClassMap[className] - if (c.usedBy.length >= 1) { + if (c.usedBy.length > 0) { continue } - if (c.usedBy[0].match(/.+\.css:*$/)) { + if (/.+\.css:*$/.test(c.usedBy[0])) { console.log(`The class name '${className}' is not used: defined at ${c.usedBy[0]}.`) } else { console.log(`The class name '${className}' is not defined: used at ${c.usedBy[0]}.`) @@ -63,8 +62,7 @@ export function isMap(value: unknown) { export function regExpTest(arr: (string | RegExp)[] = [], str: string) { if (Array.isArray(arr)) { - for (let i = 0; i < arr.length; i++) { - const item = arr[i] + for (const item of arr) { if (typeof item === 'string') { if (item === str) { return true diff --git a/packages/shared/test/reg.test.ts b/packages/shared/test/reg.test.ts index a3d4fb5b..2fcda930 100644 --- a/packages/shared/test/reg.test.ts +++ b/packages/shared/test/reg.test.ts @@ -4,7 +4,7 @@ describe('regex', () => { it('z-10 regex', () => { const testCase = 'z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex' const regex = makeRegex('z-10') - const arr = Array.from(testCase.matchAll(regex)) + const arr = [...testCase.matchAll(regex)] expect(arr.length).toBe(1) expect(arr).toMatchSnapshot() }) @@ -14,7 +14,7 @@ describe('regex', () => { const regex = makeRegex('bg-red-500', { exact: false }) - const arr = Array.from(testCase.matchAll(regex)) + const arr = [...testCase.matchAll(regex)] expect(arr.length).toBe(2) expect(arr).toMatchSnapshot() }) @@ -22,7 +22,7 @@ describe('regex', () => { it('trailing slash should exact match case 1', () => { const testCase = 'bg-red-500 bg-red-500/50' const regex = makeRegex('bg-red-500') - const arr = Array.from(testCase.matchAll(regex)) + const arr = [...testCase.matchAll(regex)] expect(arr.length).toBe(1) expect(arr).toMatchSnapshot() }) diff --git a/packages/shared/test/split.test.ts b/packages/shared/test/split.test.ts index d3716794..264c8f60 100644 --- a/packages/shared/test/split.test.ts +++ b/packages/shared/test/split.test.ts @@ -3,7 +3,7 @@ import { splitCode } from '../src/split' describe('split code', () => { it('split vue static str', () => { const testCase = - 'tl = ai("", 1),' + 'tl = ai("", 1),' const arr = splitCode(testCase) expect(arr).toMatchSnapshot() @@ -11,7 +11,7 @@ describe('split code', () => { it('split vue static str with splitQuote false', () => { const testCase = - 'tl = ai("", 1),' + 'tl = ai("", 1),' const arr = splitCode(testCase, { splitQuote: false diff --git a/packages/tailwindcss-patch/src/babel.ts b/packages/tailwindcss-patch/src/babel.ts index 3f6c82cb..59409c91 100644 --- a/packages/tailwindcss-patch/src/babel.ts +++ b/packages/tailwindcss-patch/src/babel.ts @@ -1,5 +1,3 @@ -import generate from '@babel/generator' -import { parse } from '@babel/parser' -import traverse from '@babel/traverse' - -export { generate, parse, traverse } +export { default as generate } from '@babel/generator' +export { default as traverse } from '@babel/traverse' +export { parse } from '@babel/parser' diff --git a/packages/tailwindcss-patch/src/cache.ts b/packages/tailwindcss-patch/src/cache.ts index 13ba8954..a023f8b1 100644 --- a/packages/tailwindcss-patch/src/cache.ts +++ b/packages/tailwindcss-patch/src/cache.ts @@ -1,5 +1,5 @@ -import fs from 'fs' -import path from 'path' +import fs from 'node:fs' +import path from 'node:path' import { pkgName } from './constants' import type { CacheOptions } from './type' import { log } from './logger' @@ -30,9 +30,9 @@ export function writeCache(data: Set, options: CacheOptions = {}) { try { const { dir, filename } = getCacheOptions(options) mkCacheDirectory(dir) - fs.writeFileSync(filename, JSON.stringify(Array.from(data), null, 2), 'utf-8') + fs.writeFileSync(filename, JSON.stringify([...data], undefined, 2), 'utf8') return filename - } catch (error) { + } catch { log('write cache file fail!') } } @@ -41,14 +41,14 @@ export function readCache(options: CacheOptions = {}) { const { filename } = getCacheOptions(options) try { if (fs.existsSync(filename)) { - const data = fs.readFileSync(filename, 'utf-8') + const data = fs.readFileSync(filename, 'utf8') return new Set(JSON.parse(data)) } - } catch (error) { + } catch { log('parse cache content fail! path:' + filename) try { fs.unlinkSync(filename) - } catch (error) { + } catch { log('delete cache file fail! path:' + filename) } } diff --git a/packages/tailwindcss-patch/src/class.ts b/packages/tailwindcss-patch/src/class.ts index b99b602f..a8c48d29 100644 --- a/packages/tailwindcss-patch/src/class.ts +++ b/packages/tailwindcss-patch/src/class.ts @@ -55,7 +55,7 @@ export class TailwindcssPatcher { getClassSet(basedir?: string) { const set = getClassCacheSet(basedir) - set.size && this.setCache(set) + set.size > 0 && this.setCache(set) return set } diff --git a/packages/tailwindcss-patch/src/exposeContext.ts b/packages/tailwindcss-patch/src/exposeContext.ts index df9ccd76..c8c4474c 100644 --- a/packages/tailwindcss-patch/src/exposeContext.ts +++ b/packages/tailwindcss-patch/src/exposeContext.ts @@ -1,5 +1,5 @@ -import path from 'path' -import fs from 'fs' +import path from 'node:path' +import fs from 'node:fs' import type { Rule } from 'postcss' import { requireResolve } from './utils' @@ -42,8 +42,7 @@ export function getClassCaches(basedir?: string): Map< export function getClassCacheSet(basedir?: string): Set { const classCaches = getClassCaches(basedir) const classSet = new Set() - for (let i = 0; i < classCaches.length; i++) { - const classCacheMap = classCaches[i] + for (const classCacheMap of classCaches) { const keys = classCacheMap.keys() for (const key of keys) { classSet.add(key) diff --git a/packages/tailwindcss-patch/src/inspector.ts b/packages/tailwindcss-patch/src/inspector.ts index b5c627b1..1ef6503a 100644 --- a/packages/tailwindcss-patch/src/inspector.ts +++ b/packages/tailwindcss-patch/src/inspector.ts @@ -8,18 +8,16 @@ export function inspectProcessTailwindFeaturesReturnContext(content: string) { traverse(ast, { FunctionDeclaration(p) { const n = p.node - if (n.id?.name === 'processTailwindFeatures') { - if (n.body.body.length === 1 && t.isReturnStatement(n.body.body[0])) { - const rts = n.body.body[0] - if (t.isFunctionExpression(rts.argument)) { - const body = rts.argument.body.body - const lastStatement = body[body.length - 1] - hasPatched = t.isReturnStatement(lastStatement) && t.isIdentifier(lastStatement.argument) && lastStatement.argument.name === 'context' - if (!hasPatched) { - // return context; - const rts = t.returnStatement(t.identifier('context')) - body.push(rts) - } + if (n.id?.name === 'processTailwindFeatures' && n.body.body.length === 1 && t.isReturnStatement(n.body.body[0])) { + const rts = n.body.body[0] + if (t.isFunctionExpression(rts.argument)) { + const body = rts.argument.body.body + const lastStatement = body.at(-1) + hasPatched = t.isReturnStatement(lastStatement) && t.isIdentifier(lastStatement.argument) && lastStatement.argument.name === 'context' + if (!hasPatched) { + // return context; + const rts = t.returnStatement(t.identifier('context')) + body.push(rts) } } } @@ -54,7 +52,7 @@ export function inspectPostcssPlugin(content: string) { if (idx > -1) { const prevStatement = n.body[idx - 1] - const lastStatement = n.body[n.body.length - 1] + const lastStatement = n.body.at(-1) const hasPatchedCondition0 = prevStatement && t.isVariableDeclaration(prevStatement) && @@ -94,81 +92,79 @@ export function inspectPostcssPlugin(content: string) { return } const n = p.node - if (n.id?.name === 'tailwindcss') { - if (n.body.body.length === 1 && t.isReturnStatement(n.body.body[0])) { - const returnStatement = n.body.body[0] - if (t.isObjectExpression(returnStatement.argument) && returnStatement.argument.properties.length === 2) { - const properties = returnStatement.argument.properties - if (t.isObjectProperty(properties[0]) && t.isObjectProperty(properties[1])) { - const keyMatched = t.isIdentifier(properties[0].key) && properties[0].key.name === 'postcssPlugin' - const pluginsMatched = t.isIdentifier(properties[1].key) && properties[1].key.name === 'plugins' - if ( - pluginsMatched && - keyMatched && - t.isCallExpression(properties[1].value) && - t.isMemberExpression(properties[1].value.callee) && - t.isArrayExpression(properties[1].value.callee.object) - ) { - const pluginsCode = properties[1].value.callee.object.elements - if (pluginsCode[1] && t.isFunctionExpression(pluginsCode[1])) { - const targetBlockStatement = pluginsCode[1].body + if (n.id?.name === 'tailwindcss' && n.body.body.length === 1 && t.isReturnStatement(n.body.body[0])) { + const returnStatement = n.body.body[0] + if (t.isObjectExpression(returnStatement.argument) && returnStatement.argument.properties.length === 2) { + const properties = returnStatement.argument.properties + if (t.isObjectProperty(properties[0]) && t.isObjectProperty(properties[1])) { + const keyMatched = t.isIdentifier(properties[0].key) && properties[0].key.name === 'postcssPlugin' + const pluginsMatched = t.isIdentifier(properties[1].key) && properties[1].key.name === 'plugins' + if ( + pluginsMatched && + keyMatched && + t.isCallExpression(properties[1].value) && + t.isMemberExpression(properties[1].value.callee) && + t.isArrayExpression(properties[1].value.callee.object) + ) { + const pluginsCode = properties[1].value.callee.object.elements + if (pluginsCode[1] && t.isFunctionExpression(pluginsCode[1])) { + const targetBlockStatement = pluginsCode[1].body - const lastStatement = targetBlockStatement.body[targetBlockStatement.body.length - 1] - if (t.isExpressionStatement(lastStatement)) { - // contextRef.value.push((0, _processTailwindFeatures.default)(context)(root, result)); - const newExpressionStatement = t.expressionStatement( - t.callExpression( - t.memberExpression( - t.memberExpression(t.identifier(variableName), t.identifier('value')), + const lastStatement = targetBlockStatement.body.at(-1) + if (t.isExpressionStatement(lastStatement)) { + // contextRef.value.push((0, _processTailwindFeatures.default)(context)(root, result)); + const newExpressionStatement = t.expressionStatement( + t.callExpression( + t.memberExpression( + t.memberExpression(t.identifier(variableName), t.identifier('value')), - t.identifier('push') - ), + t.identifier('push') + ), - [lastStatement.expression] - ) + [lastStatement.expression] ) - targetBlockStatement.body[targetBlockStatement.body.length - 1] = newExpressionStatement - } + ) + targetBlockStatement.body[targetBlockStatement.body.length - 1] = newExpressionStatement + } - const ifIdx = targetBlockStatement.body.findIndex((x) => t.isIfStatement(x)) - if (ifIdx > -1) { - const ifRoot = targetBlockStatement.body[ifIdx] - if (t.isBlockStatement(ifRoot.consequent) && ifRoot.consequent.body[1] && t.isForOfStatement(ifRoot.consequent.body[1])) { - const forOf: t.ForOfStatement = ifRoot.consequent.body[1] - if (t.isBlockStatement(forOf.body) && forOf.body.body.length === 1 && t.isIfStatement(forOf.body.body[0])) { - const if2: t.IfStatement = forOf.body.body[0] - if (t.isBlockStatement(if2.consequent) && if2.consequent.body.length === 1 && t.isExpressionStatement(if2.consequent.body[0])) { - const target = if2.consequent.body[0] - // contextRef.value.push((0, _processTailwindFeatures.default)(context)(root1, result)); - const newExpressionStatement = t.expressionStatement( - t.callExpression(t.memberExpression(t.memberExpression(t.identifier(variableName), t.identifier('value')), t.identifier('push')), [target.expression]) - ) - if2.consequent.body[0] = newExpressionStatement - } + const ifIdx = targetBlockStatement.body.findIndex((x) => t.isIfStatement(x)) + if (ifIdx > -1) { + const ifRoot = targetBlockStatement.body[ifIdx] + if (t.isBlockStatement(ifRoot.consequent) && ifRoot.consequent.body[1] && t.isForOfStatement(ifRoot.consequent.body[1])) { + const forOf: t.ForOfStatement = ifRoot.consequent.body[1] + if (t.isBlockStatement(forOf.body) && forOf.body.body.length === 1 && t.isIfStatement(forOf.body.body[0])) { + const if2: t.IfStatement = forOf.body.body[0] + if (t.isBlockStatement(if2.consequent) && if2.consequent.body.length === 1 && t.isExpressionStatement(if2.consequent.body[0])) { + const target = if2.consequent.body[0] + // contextRef.value.push((0, _processTailwindFeatures.default)(context)(root1, result)); + const newExpressionStatement = t.expressionStatement( + t.callExpression(t.memberExpression(t.memberExpression(t.identifier(variableName), t.identifier('value')), t.identifier('push')), [target.expression]) + ) + if2.consequent.body[0] = newExpressionStatement } } } - // clear contextRef.value - targetBlockStatement.body.unshift( - // contentRef.value = [] - // t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier(variableName), t.identifier(valueKey)), t.arrayExpression())) + } + // clear contextRef.value + targetBlockStatement.body.unshift( + // contentRef.value = [] + // t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier(variableName), t.identifier(valueKey)), t.arrayExpression())) - // contentRef.value.length = 0 - t.expressionStatement( - t.assignmentExpression( - '=', - t.memberExpression(t.memberExpression(t.identifier(variableName), t.identifier(valueKey)), t.identifier('length')), - t.numericLiteral(0) - ) + // contentRef.value.length = 0 + t.expressionStatement( + t.assignmentExpression( + '=', + t.memberExpression(t.memberExpression(t.identifier(variableName), t.identifier(valueKey)), t.identifier('length')), + t.numericLiteral(0) ) ) - } + ) } } } } - // start = true } + // start = true } // BlockStatement(p) { // const n = p.node diff --git a/packages/tailwindcss-patch/src/patcher.ts b/packages/tailwindcss-patch/src/patcher.ts index 3f79451b..642580a6 100644 --- a/packages/tailwindcss-patch/src/patcher.ts +++ b/packages/tailwindcss-patch/src/patcher.ts @@ -1,5 +1,5 @@ -import path from 'path' -import fs from 'fs' +import path from 'node:path' +import fs from 'node:fs' import { gte } from 'semver' import { inspectPostcssPlugin, inspectProcessTailwindFeaturesReturnContext } from './inspector' import type { PatchOptions, InternalPatchOptions } from './type' @@ -55,7 +55,7 @@ export function monkeyPatchForExposingContext(twDir: string, opt: InternalPatchO const { code, hasPatched } = inspectProcessTailwindFeaturesReturnContext(processTailwindFeaturesContent) if (!hasPatched && opt.overwrite) { fs.writeFileSync(processTailwindFeaturesFilePath, code, { - encoding: 'utf-8' + encoding: 'utf8' }) console.log('patch tailwindcss processTailwindFeatures for return content successfully!') } @@ -69,7 +69,7 @@ export function monkeyPatchForExposingContext(twDir: string, opt: InternalPatchO const { code, hasPatched } = inspectPostcssPlugin(pluginContent) if (!hasPatched && opt.overwrite) { fs.writeFileSync(pluginFilePath, code, { - encoding: 'utf-8' + encoding: 'utf8' }) console.log('patch tailwindcss for expose runtime content successfully!') } diff --git a/packages/tailwindcss-patch/src/utils.ts b/packages/tailwindcss-patch/src/utils.ts index 9c1f34f0..a27d3892 100644 --- a/packages/tailwindcss-patch/src/utils.ts +++ b/packages/tailwindcss-patch/src/utils.ts @@ -1,4 +1,4 @@ -import fs from 'fs' +import fs from 'node:fs' import { sync, type SyncOpts } from 'resolve' export function ensureFileContent(filepaths: string | string[]) { @@ -6,11 +6,10 @@ export function ensureFileContent(filepaths: string | string[]) { filepaths = [filepaths] } let content - for (let i = 0; i < filepaths.length; i++) { - const filepath = filepaths[i] + for (const filepath of filepaths) { if (fs.existsSync(filepath)) { content = fs.readFileSync(filepath, { - encoding: 'utf-8' + encoding: 'utf8' }) break } diff --git a/packages/unplugin-tailwindcss-mangle/src/index.ts b/packages/unplugin-tailwindcss-mangle/src/index.ts index 5e0545c8..77a916fc 100644 --- a/packages/unplugin-tailwindcss-mangle/src/index.ts +++ b/packages/unplugin-tailwindcss-mangle/src/index.ts @@ -5,8 +5,8 @@ import { getGroupedEntries, cacheDump } from './utils' import type { OutputAsset, OutputChunk } from 'rollup' import { cssHandler, htmlHandler, jsHandler } from 'tailwindcss-mangle-core' import type { sources } from 'webpack' -import path from 'path' -import fs from 'fs' +import path from 'node:path' +import fs from 'node:fs' import { getOptions } from './options' export { defaultMangleClassFilter } from 'tailwindcss-mangle-shared' @@ -31,12 +31,12 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) generateBundle: { handler(options, bundle, isWrite) { const runtimeSet = getCachedClassSet() - if (!runtimeSet.size) { + if (runtimeSet.size === 0) { return } const groupedEntries = getGroupedEntries(Object.entries(bundle)) - if (Array.isArray(groupedEntries.html) && groupedEntries.html.length) { + if (Array.isArray(groupedEntries.html) && groupedEntries.html.length > 0) { for (let i = 0; i < groupedEntries.html.length; i++) { const [file, asset] = groupedEntries.html[i] as [string, OutputAsset] if (isInclude(file)) { @@ -48,7 +48,7 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) } } } - if (Array.isArray(groupedEntries.js) && groupedEntries.js.length) { + if (Array.isArray(groupedEntries.js) && groupedEntries.js.length > 0) { for (let i = 0; i < groupedEntries.js.length; i++) { const [file, chunk] = groupedEntries.js[i] as [string, OutputChunk] if (isInclude(file)) { @@ -64,7 +64,7 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) } } - if (Array.isArray(groupedEntries.css) && groupedEntries.css.length) { + if (Array.isArray(groupedEntries.css) && groupedEntries.css.length > 0) { for (let i = 0; i < groupedEntries.css.length; i++) { const [file, css] = groupedEntries.css[i] as [string, OutputAsset] if (isInclude(file)) { @@ -91,7 +91,7 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) const abs = getAssetPath(outputPath, file) const rel = getAssetPath(outputPath, file, false) try { - fs.writeFileSync(abs, data, 'utf-8') + fs.writeFileSync(abs, data, 'utf8') console.log('[tailwindcss-mangle]: ' + rel + ' overwrited successfully') } catch (error) { console.log('[tailwindcss-mangle]: ' + rel + ' overwrited fail!') @@ -144,20 +144,20 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) const runtimeSet = getCachedClassSet() const groupedEntries = getGroupedEntries(Object.entries(assets)) // cache result - if (!runtimeSet.size) { + if (runtimeSet.size === 0) { const css = new Map() const html = new Map() const js = new Map() - groupedEntries.css.forEach(([file, source]) => { + for (const [file, source] of groupedEntries.css) { css.set(file, source) - }) - groupedEntries.html.forEach(([file, source]) => { + } + for (const [file, source] of groupedEntries.html) { html.set(file, source) - }) - groupedEntries.js.forEach(([file, source]) => { + } + for (const [file, source] of groupedEntries.js) { js.set(file, source) - }) - if (js.size || css.size || html.size) { + } + if (js.size > 0 || css.size > 0 || html.size > 0) { outputCachedMap.set(compiler.outputPath, { css, html, @@ -168,7 +168,7 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) return } - if (groupedEntries.html.length) { + if (groupedEntries.html.length > 0) { for (let i = 0; i < groupedEntries.html.length; i++) { const [file, asset] = groupedEntries.html[i] if (isInclude(file)) { @@ -183,7 +183,7 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) } } - if (groupedEntries.js.length) { + if (groupedEntries.js.length > 0) { for (let i = 0; i < groupedEntries.js.length; i++) { const [file, chunk] = groupedEntries.js[i] if (isInclude(file)) { @@ -200,7 +200,7 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) } } - if (groupedEntries.css.length) { + if (groupedEntries.css.length > 0) { for (let i = 0; i < groupedEntries.css.length; i++) { const [file, css] = groupedEntries.css[i] if (isInclude(file)) { @@ -215,9 +215,9 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) } } // overwrite ssr server side chunk - outputCachedMap.forEach(({ js, html, css }, key) => { - if (html.size) { - html.forEach((asset, file) => { + for (const [key, { js, html, css }] of outputCachedMap.entries()) { + if (html.size > 0) { + for (const [file, asset] of html.entries()) { if (isInclude(file)) { const html = htmlHandler((asset as sources.Source).source().toString(), { ...htmlHandlerOptions, @@ -226,12 +226,12 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) }) overwriteServerSideAsset(key, file, html) } - }) + } html.clear() } - if (js.size) { - js.forEach((chunk, file) => { + if (js.size > 0) { + for (const [file, chunk] of js.entries()) { if (isInclude(file)) { const rawCode = (chunk as sources.Source).source().toString() const code = jsHandler(rawCode, { @@ -243,12 +243,12 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) overwriteServerSideAsset(key, file, code) } } - }) + } js.clear() } - if (css.size) { - css.forEach((style, file) => { + if (css.size > 0) { + for (const [file, style] of css.entries()) { if (isInclude(file)) { const newCss = cssHandler((style as sources.Source).source().toString(), { ...cssHandlerOptions, @@ -258,17 +258,17 @@ export const unplugin = createUnplugin((options: Options | undefined = {}, meta) overwriteServerSideAsset(key, file, newCss) } - }) + } css.clear() } - }) + } } ) }) }, writeBundle() { const entries = Object.entries(classGenerator.newClassMap) - if (entries.length && classMapOutputOptions) { + if (entries.length > 0 && classMapOutputOptions) { cacheDump( classMapOutputOptions.filename, entries.map((x) => { diff --git a/packages/unplugin-tailwindcss-mangle/src/options.ts b/packages/unplugin-tailwindcss-mangle/src/options.ts index 1ccb0070..82304e38 100644 --- a/packages/unplugin-tailwindcss-mangle/src/options.ts +++ b/packages/unplugin-tailwindcss-mangle/src/options.ts @@ -34,15 +34,15 @@ export function getOptions(options: Options | undefined = {}) { const classGenerator = new ClassGenerator(options.classGenerator) function getCachedClassSet() { const set = twPatcher.getClassSet() - const isOutput = set.size && options.classSetOutput + const isOutput = set.size > 0 && options.classSetOutput if (isOutput && classSetOutputOptions.type === 'all') { cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir) } - set.forEach((c) => { + for (const c of set) { if (!currentMangleClassFilter(c)) { set.delete(c) } - }) + } if (isOutput && classSetOutputOptions.type === 'partial') { cacheDump(classSetOutputOptions.filename, set, classSetOutputOptions.dir) } diff --git a/packages/unplugin-tailwindcss-mangle/src/utils.ts b/packages/unplugin-tailwindcss-mangle/src/utils.ts index 12156c7f..7e94ec40 100644 --- a/packages/unplugin-tailwindcss-mangle/src/utils.ts +++ b/packages/unplugin-tailwindcss-mangle/src/utils.ts @@ -1,13 +1,11 @@ import micromatch from 'micromatch' -import fs from 'fs' -import path from 'path' +import fs from 'node:fs' +import path from 'node:path' import { pluginName } from './constants' -import { defaultMangleClassFilter, groupBy, isMap, isRegexp } from 'tailwindcss-mangle-shared' +import { groupBy } from 'tailwindcss-mangle-shared' const { isMatch } = micromatch -export { defaultMangleClassFilter, isMap, isRegexp } - export function getGroupedEntries( entries: [string, T][], options = { @@ -50,7 +48,7 @@ export function getGroupedEntries( } export function createGlobMatcher(pattern: string | string[] | undefined, fallbackValue: boolean = false) { - if (typeof pattern === 'undefined') { + if (pattern === undefined) { return function (file: string) { return fallbackValue } @@ -79,8 +77,10 @@ export function mkCacheDirectory(cwd = process.cwd()) { export function cacheDump(filename: string, data: any[] | Set, basedir?: string) { try { const dir = mkCacheDirectory(basedir) - fs.writeFileSync(path.resolve(dir, filename), JSON.stringify(Array.from(data), null, 2), 'utf-8') + fs.writeFileSync(path.resolve(dir, filename), JSON.stringify([...data], undefined, 2), 'utf8') } catch (error) { console.log(error) } } + +export { defaultMangleClassFilter, isMap, isRegexp } from 'tailwindcss-mangle-shared' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d237daa6..a997fb51 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ importers: eslint: specifier: ^8.42.0 version: 8.42.0 + eslint-plugin-unicorn: + specifier: ^47.0.0 + version: 47.0.0(eslint@8.42.0) jest: specifier: ^29.5.0 version: 29.5.0(@types/node@20.2.5)(ts-node@10.9.1) @@ -7495,6 +7498,13 @@ packages: source-map: 0.6.1 dev: true + /clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + /clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -9386,6 +9396,31 @@ packages: - typescript dev: true + /eslint-plugin-unicorn@47.0.0(eslint@8.42.0): + resolution: {integrity: sha512-ivB3bKk7fDIeWOUmmMm9o3Ax9zbMz1Bsza/R2qm46ufw4T6VBFBaJIR1uN3pCKSmSXm8/9Nri8V+iUut1NhQGA==} + engines: {node: '>=16'} + peerDependencies: + eslint: '>=8.38.0' + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0) + ci-info: 3.8.0 + clean-regexp: 1.0.0 + eslint: 8.42.0 + esquery: 1.5.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + lodash: 4.17.21 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.10.0 + safe-regex: 2.1.1 + semver: 7.5.1 + strip-indent: 3.0.0 + dev: true + /eslint-plugin-vue@9.14.1(eslint@8.42.0): resolution: {integrity: sha512-LQazDB1qkNEKejLe/b5a9VfEbtbczcOaui5lQ4Qw0tbRBbQYREyxxOV5BQgNDTqGPs9pxqiEpbMi9ywuIaF7vw==} engines: {node: ^14.17.0 || >=16.0.0} @@ -13735,6 +13770,11 @@ packages: mlly: 1.2.1 pathe: 1.1.0 + /pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + dev: true + /portfinder@1.0.32: resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==} engines: {node: '>= 0.12.0'} @@ -14888,6 +14928,11 @@ packages: '@babel/runtime': 7.21.0 dev: true + /regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + dev: true + /regexp.prototype.flags@1.5.0: resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} engines: {node: '>= 0.4'} @@ -14913,6 +14958,13 @@ packages: unicode-match-property-value-ecmascript: 2.1.0 dev: true + /regjsparser@0.10.0: + resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + /regjsparser@0.9.1: resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} hasBin: true @@ -15155,6 +15207,12 @@ packages: get-intrinsic: 1.2.0 is-regex: 1.1.4 + /safe-regex@2.1.1: + resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} + dependencies: + regexp-tree: 0.1.27 + dev: true + /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} From f2d32674693b0a02f9263f5197af11f3caf56897 Mon Sep 17 00:00:00 2001 From: ice breaker <1324318532@qq.com> Date: Wed, 7 Jun 2023 23:47:00 +0800 Subject: [PATCH 6/9] demo: add vue test page --- apps/vite-vue/src/App.vue | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/vite-vue/src/App.vue b/apps/vite-vue/src/App.vue index 987ca090..d5bfa4fb 100644 --- a/apps/vite-vue/src/App.vue +++ b/apps/vite-vue/src/App.vue @@ -3,7 +3,7 @@