From 43ea245c6b973314eb4e92e13d7f4d9ee1a45699 Mon Sep 17 00:00:00 2001 From: "Azat S." Date: Tue, 16 Jul 2024 15:50:05 +0300 Subject: [PATCH 1/4] docs: update apple touch icon --- docs/public/apple-touch-icon.png | Bin 3832 -> 3669 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/public/apple-touch-icon.png b/docs/public/apple-touch-icon.png index 97396f803d3a7d947a73a2439a7e9d04812ed876..9367ef79d9d4ac41fc9f3ef5cef49468b7462cc4 100644 GIT binary patch delta 3619 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 Date: Tue, 16 Jul 2024 18:36:01 +0300 Subject: [PATCH 2/4] feat!: make new config export --- configs/recommended-alphabetical.ts | 8 -- configs/recommended-line-length.ts | 8 -- configs/recommended-natural.ts | 8 -- .../configs/recommended-alphabetical.mdx | 6 +- .../configs/recommended-line-length.mdx | 6 +- docs/content/configs/recommended-natural.mdx | 6 +- index.ts | 108 +++++++++++------- package.json | 12 -- readme.md | 64 +++++------ vite.config.ts | 7 +- 10 files changed, 107 insertions(+), 126 deletions(-) delete mode 100644 configs/recommended-alphabetical.ts delete mode 100644 configs/recommended-line-length.ts delete mode 100644 configs/recommended-natural.ts diff --git a/configs/recommended-alphabetical.ts b/configs/recommended-alphabetical.ts deleted file mode 100644 index 2682804c4..000000000 --- a/configs/recommended-alphabetical.ts +++ /dev/null @@ -1,8 +0,0 @@ -import mod from '../index' - -export default { - rules: mod.configs['recommended-alphabetical'].rules, - plugins: { - perfectionist: mod, - }, -} diff --git a/configs/recommended-line-length.ts b/configs/recommended-line-length.ts deleted file mode 100644 index a849b7d6e..000000000 --- a/configs/recommended-line-length.ts +++ /dev/null @@ -1,8 +0,0 @@ -import mod from '../index' - -export default { - rules: mod.configs['recommended-line-length'].rules, - plugins: { - perfectionist: mod, - }, -} diff --git a/configs/recommended-natural.ts b/configs/recommended-natural.ts deleted file mode 100644 index 1de981e0a..000000000 --- a/configs/recommended-natural.ts +++ /dev/null @@ -1,8 +0,0 @@ -import mod from '../index' - -export default { - rules: mod.configs['recommended-natural'].rules, - plugins: { - perfectionist: mod, - }, -} diff --git a/docs/content/configs/recommended-alphabetical.mdx b/docs/content/configs/recommended-alphabetical.mdx index 09d5bb2fb..b86a124be 100644 --- a/docs/content/configs/recommended-alphabetical.mdx +++ b/docs/content/configs/recommended-alphabetical.mdx @@ -27,10 +27,10 @@ It makes it just a tiny bit faster to find a declaration in a large list. Rememb { source: dedent` // eslint.config.js - import perfectionistAlphabetical from 'eslint-plugin-perfectionist/configs/recommended-alphabetical' + import perfectionist from 'eslint-plugin-perfectionist' export default [ - perfectionistAlphabetical, + perfectionist.configs['recommended-alphabetical'], ] `, name: 'Flat Config', @@ -41,7 +41,7 @@ It makes it just a tiny bit faster to find a declaration in a large list. Rememb // .eslintrc.js export default { extends: [ - 'plugin:perfectionist/recommended-alphabetical', + 'plugin:perfectionist/recommended-alphabetical-legacy', ], } `, diff --git a/docs/content/configs/recommended-line-length.mdx b/docs/content/configs/recommended-line-length.mdx index b436fa96d..3d76694ba 100644 --- a/docs/content/configs/recommended-line-length.mdx +++ b/docs/content/configs/recommended-line-length.mdx @@ -36,10 +36,10 @@ This configuration will make your code prettier and more pleasing to the eye. { source: dedent` // eslint.config.js - import perfectionistLineLength from 'eslint-plugin-perfectionist/configs/recommended-line-length' + import perfectionist from 'eslint-plugin-perfectionist' export default [ - perfectionistLineLength, + perfectionist.configs['recommended-line-length'], ] `, name: 'Flat Config', @@ -50,7 +50,7 @@ This configuration will make your code prettier and more pleasing to the eye. // .eslintrc.js export default { extends: [ - 'plugin:perfectionist/recommended-line-length', + 'plugin:perfectionist/recommended-line-length-legacy', ], } `, diff --git a/docs/content/configs/recommended-natural.mdx b/docs/content/configs/recommended-natural.mdx index 644133fd9..c32035001 100644 --- a/docs/content/configs/recommended-natural.mdx +++ b/docs/content/configs/recommended-natural.mdx @@ -34,10 +34,10 @@ This configuration will allow you to navigate through your code faster because a { source: dedent` // eslint.config.js - import perfectionistNatural from 'eslint-plugin-perfectionist/configs/recommended-natural' + import perfectionist from 'eslint-plugin-perfectionist' export default [ - perfectionistNatural, + perfectionist.configs['recommended-natural'], ] `, name: 'Flat Config', @@ -48,7 +48,7 @@ This configuration will allow you to navigate through your code faster because a // .eslintrc.js export default { extends: [ - 'plugin:perfectionist/recommended-natural', + 'plugin:perfectionist/recommended-natural-legacy', ], } `, diff --git a/index.ts b/index.ts index 37c568d17..0b9e9619a 100644 --- a/index.ts +++ b/index.ts @@ -16,19 +16,42 @@ import sortClasses, { RULE_NAME as sortClassesName } from './rules/sort-classes' import sortEnums, { RULE_NAME as sortEnumsName } from './rules/sort-enums' import sortMaps, { RULE_NAME as sortMapsName } from './rules/sort-maps' +interface BaseOptions { + type: 'alphabetical' | 'line-length' | 'natural' + order: 'desc' | 'asc' +} + type RuleSeverity = 'error' | 'warn' | 'off' type RuleDeclaration = [RuleSeverity, { [key: string]: unknown }?] -let createConfigWithOptions = (options: { - type: 'alphabetical' | 'line-length' | 'natural' - order: 'desc' | 'asc' - ignoreCase?: boolean -}): { +let plugin = { rules: { - [key: string]: RuleDeclaration - } - plugins: ['perfectionist'] + [sortIntersectionTypesName]: sortIntersectionTypes, + [sortSvelteAttributesName]: sortSvelteAttributes, + [sortAstroAttributesName]: sortAstroAttributes, + [sortArrayIncludesName]: sortArrayIncludes, + [sortVueAttributesName]: sortVueAttributes, + [sortNamedExportsName]: sortNamedExports, + [sortNamedImportsName]: sortNamedImports, + [sortObjectTypesName]: sortObjectTypes, + [sortInterfacesName]: sortInterfaces, + [sortUnionTypesName]: sortUnionTypes, + [sortJsxPropsName]: sortJsxProps, + [sortClassesName]: sortClasses, + [sortExportsName]: sortExports, + [sortImportsName]: sortImports, + [sortObjectsName]: sortObjects, + [sortEnumsName]: sortEnums, + [sortMapsName]: sortMaps, + }, + name: 'perfectionist', +} + +let getRules = ( + options: BaseOptions, +): { + [key: string]: RuleDeclaration } => { let recommendedRules: { [key: string]: RuleDeclaration @@ -97,53 +120,52 @@ let createConfigWithOptions = (options: { [sortEnumsName]: ['error'], [sortMapsName]: ['error'], } - return { - rules: Object.fromEntries( - Object.entries(recommendedRules).map(([key, [message, baseOptions = {}]]) => [ - `perfectionist/${key}`, - [message, Object.assign(baseOptions, options)], - ]), - ), - plugins: ['perfectionist'], - } + return Object.fromEntries( + Object.entries(recommendedRules).map(([key, [message, baseOptions = {}]]) => [ + `perfectionist/${key}`, + [message, Object.assign(baseOptions, options)], + ]), + ) } -/* eslint-disable perfectionist/sort-objects */ -export default { - rules: { - [sortArrayIncludesName]: sortArrayIncludes, - [sortAstroAttributesName]: sortAstroAttributes, - [sortClassesName]: sortClasses, - [sortEnumsName]: sortEnums, - [sortExportsName]: sortExports, - [sortImportsName]: sortImports, - [sortInterfacesName]: sortInterfaces, - [sortJsxPropsName]: sortJsxProps, - [sortMapsName]: sortMaps, - [sortNamedExportsName]: sortNamedExports, - [sortNamedImportsName]: sortNamedImports, - [sortObjectTypesName]: sortObjectTypes, - [sortObjectsName]: sortObjects, - [sortSvelteAttributesName]: sortSvelteAttributes, - [sortIntersectionTypesName]: sortIntersectionTypes, - [sortUnionTypesName]: sortUnionTypes, - [sortVueAttributesName]: sortVueAttributes, +let createConfig = (options: BaseOptions) => ({ + plugins: { + perfectionist: plugin, }, + rules: getRules(options), +}) + +let createLegacyConfig = (options: BaseOptions) => ({ + plugins: ['perfectionist'], + rules: getRules(options), +}) + +export default { + ...plugin, configs: { - 'recommended-alphabetical': createConfigWithOptions({ + 'recommended-alphabetical-legacy': createLegacyConfig({ type: 'alphabetical', order: 'asc', - ignoreCase: true, }), - 'recommended-natural': createConfigWithOptions({ + 'recommended-line-length-legacy': createLegacyConfig({ + type: 'line-length', + order: 'desc', + }), + 'recommended-natural-legacy': createLegacyConfig({ type: 'natural', order: 'asc', - ignoreCase: true, }), - 'recommended-line-length': createConfigWithOptions({ + 'recommended-alphabetical': createConfig({ + type: 'alphabetical', + order: 'asc', + }), + 'recommended-line-length': createConfig({ type: 'line-length', order: 'desc', }), + 'recommended-natural': createConfig({ + type: 'natural', + order: 'asc', + }), }, - name: 'eslint-plugin-perfectionist', } diff --git a/package.json b/package.json index 13d0014e6..2d470e932 100644 --- a/package.json +++ b/package.json @@ -44,18 +44,6 @@ "require": "./dist/index.js", "import": "./dist/index.mjs" }, - "./configs/recommended-alphabetical": { - "require": "./dist/configs/recommended-alphabetical.js", - "import": "./dist/configs/recommended-alphabetical.mjs" - }, - "./configs/recommended-line-length": { - "require": "./dist/configs/recommended-line-length.js", - "import": "./dist/configs/recommended-line-length.mjs" - }, - "./configs/recommended-natural": { - "require": "./dist/configs/recommended-natural.js", - "import": "./dist/configs/recommended-natural.mjs" - }, "./package.json": "./package.json" }, "peerDependenciesMeta": { diff --git a/readme.md b/readme.md index d8c7e54ab..ec23f49a9 100644 --- a/readme.md +++ b/readme.md @@ -55,27 +55,7 @@ npm install --save-dev eslint-plugin-perfectionist Add `eslint-plugin-perfectionist` to the plugins section of the ESLint configuration file and define the list of rules you will use. -### Legacy Config ([`.eslintrc`](https://eslint.org/docs/latest/use/configure/configuration-files)) - - -```json -{ - "plugins": [ - "perfectionist" - ], - "rules": { - "perfectionist/sort-objects": [ - "error", - { - "type": "natural", - "order": "asc" - } - ] - } -} -``` - -### Flat Config ([`eslint.config.js`](https://eslint.org/docs/latest/use/configure/configuration-files-new)) (requires eslint >= v8.23.0) +### Flat Config ([`eslint.config.js`](https://eslint.org/docs/latest/use/configure/configuration-files)) ```js import perfectionist from 'eslint-plugin-perfectionist' @@ -98,32 +78,52 @@ export default [ ] ``` -## ⚙️ Configs - -The easiest way to use `eslint-plugin-perfectionist` is to use ready-made configs. Config files use all the rules of the current plugin, but you can override them. - -### Legacy Config ([`.eslintrc`](https://eslint.org/docs/latest/use/configure/configuration-files)) +### Legacy Config ([`.eslintrc`](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated)) ```json { - "extends": [ - "plugin:perfectionist/recommended-natural" - ] + "plugins": [ + "perfectionist" + ], + "rules": { + "perfectionist/sort-objects": [ + "error", + { + "type": "natural", + "order": "asc" + } + ] + } } ``` -### Flat Config ([`eslint.config.js`](https://eslint.org/docs/latest/use/configure/configuration-files-new)) +## ⚙️ Configs + +The easiest way to use `eslint-plugin-perfectionist` is to use ready-made configs. Config files use all the rules of the current plugin, but you can override them. + +### Flat Config ([`eslint.config.js`](https://eslint.org/docs/latest/use/configure/configuration-files)) ```js -import perfectionistNatural from 'eslint-plugin-perfectionist/configs/recommended-natural' +import perfectionist from 'eslint-plugin-perfectionist' export default [ - perfectionistNatural, + perfectionist.configs['recommended-natural'], ] ``` +### Legacy Config ([`.eslintrc`](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated)) + + +```json +{ + "extends": [ + "plugin:perfectionist/recommended-natural-legacy" + ] +} +``` + ### List of Configs | Name | Description | diff --git a/vite.config.ts b/vite.config.ts index 499d28b3d..25b72ae57 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -4,12 +4,6 @@ import path from 'node:path' export default defineConfig({ build: { lib: { - entry: [ - path.resolve(__dirname, 'configs/recommended-alphabetical.ts'), - path.resolve(__dirname, 'configs/recommended-line-length.ts'), - path.resolve(__dirname, 'configs/recommended-natural.ts'), - path.resolve(__dirname, 'index.ts'), - ], fileName: (format, entryName) => { let directory = '' @@ -19,6 +13,7 @@ export default defineConfig({ return `${directory}${entryName}.${format === 'es' ? 'mjs' : 'js'}` }, + entry: path.resolve(__dirname, 'index.ts'), name: 'eslint-plugin-perfectionist', formats: ['cjs', 'es'], }, From e6d16f598d4ff1e160f8ea1f46b31c67ad8a33f3 Mon Sep 17 00:00:00 2001 From: "Azat S." Date: Tue, 16 Jul 2024 18:44:47 +0300 Subject: [PATCH 3/4] feat: add sort-switch-case rule --- docs/content/rules/sort-switch-case.mdx | 242 ++++++++ index.ts | 3 + readme.md | 3 +- rules/sort-switch-case.ts | 198 ++++++ test/sort-switch-case.test.ts | 792 ++++++++++++++++++++++++ typings/index.ts | 4 +- 6 files changed, 1239 insertions(+), 3 deletions(-) create mode 100644 docs/content/rules/sort-switch-case.mdx create mode 100644 rules/sort-switch-case.ts create mode 100644 test/sort-switch-case.test.ts diff --git a/docs/content/rules/sort-switch-case.mdx b/docs/content/rules/sort-switch-case.mdx new file mode 100644 index 000000000..a6d916453 --- /dev/null +++ b/docs/content/rules/sort-switch-case.mdx @@ -0,0 +1,242 @@ +--- +title: sort-switch-case +description: Ensure consistent and readable switch statements with the sort-switch-case ESLint rule. Automatically sort case clauses within switch statements to improve code clarity and maintainability +shortDescription: Enforce sorted switch case statements +keywords: + - eslint + - sort switch case + - eslint rule + - coding standards + - code quality + - javascript linting + - switch statements + - case sorting + - switch case order +--- + +import CodeExample from '../../components/CodeExample.svelte' +import Important from '../../components/Important.astro' +import CodeTabs from '../../components/CodeTabs.svelte' +import { dedent } from 'ts-dedent' + +Enforce sorted switch case statements. + +Switch statements with numerous cases can quickly become cumbersome and hard to navigate. With this rule, you can easily locate specific cases and ensure that your codebase adheres to a predictable and standardized format. + +This practice contributes to a more readable and maintainable codebase, allowing developers to quickly understand and modify the logic without getting lost in a jumble of unsorted case clauses. + +By integrating this rule into your ESLint configuration, you can focus on the functionality of your code, confident that your switch statements are consistently structured and easy to manage. + +## Try it out + + { + switch (action.type) { + case 'ADD_USER': + return { + ...state, + users: [...state.users, action.payload], + } + case 'DELETE_USER': + return { + ...state, + users: state.users.filter(user => user.id !== action.payload.id), + } + case 'FETCH_USER_ERROR': + return { + ...state, + loading: false, + error: action.payload, + } + case 'FETCH_USER_REQUEST': + return { + ...state, + loading: true, + error: null, + } + case 'FETCH_USER_SUCCESS': + return { + ...state, + loading: false, + currentUser: action.payload, + } + default: + return state + } + } + `} + lineLength={dedent` + const userReducer = (state = initialState, action) => { + switch (action.type) { + case 'FETCH_USER_REQUEST': + return { + ...state, + loading: true, + error: null, + } + case 'FETCH_USER_SUCCESS': + return { + ...state, + loading: false, + currentUser: action.payload, + } + case 'FETCH_USER_ERROR': + return { + ...state, + loading: false, + error: action.payload, + } + case 'DELETE_USER': + return { + ...state, + users: state.users.filter(user => user.id !== action.payload.id), + } + case 'ADD_USER': + return { + ...state, + users: [...state.users, action.payload], + } + default: + return state + } + } + `} + initial={dedent` + const userReducer = (state = initialState, action) => { + switch (action.type) { + case 'FETCH_USER_ERROR': + return { + ...state, + loading: false, + error: action.payload, + } + case 'FETCH_USER_SUCCESS': + return { + ...state, + loading: false, + currentUser: action.payload, + } + case 'DELETE_USER': + return { + ...state, + users: state.users.filter(user => user.id !== action.payload.id), + } + case 'FETCH_USER_REQUEST': + return { + ...state, + loading: true, + error: null, + } + case 'ADD_USER': + return { + ...state, + users: [...state.users, action.payload], + } + default: + return state + } + } + `} + client:load + lang="tsx" +/> + +## Options + +This rule accepts an options object with the following properties: + +```ts +interface Options { + type?: 'alphabetical' | 'natural' | 'line-length' + order?: 'asc' | 'desc' + ignoreCase?: boolean +} +``` + +### type + +(default: `'alphabetical'`) + +- `alphabetical` — sort alphabetically. +- `natural` — sort in natural order. +- `line-length` — sort by code line length. + +### order + +(default: `'asc'`) + +- `asc` — enforce properties to be in ascending order. +- `desc` — enforce properties to be in descending order. + +### ignoreCase + +(default: `false`) + +Only affects alphabetical and natural sorting. When `true` the rule ignores the case-sensitivity of the order. + +## Usage + + + +## Version + +This rule was introduced in [v0.2.0](https://github.com/azat-io/eslint-plugin-perfectionist/releases/tag/v3.0.0). + +## Resources + +- [Rule source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/rules/sort-switch-case.ts) +- [Test source](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/test/sort-switch-case.test.ts) + diff --git a/index.ts b/index.ts index 0b9e9619a..295857dfa 100644 --- a/index.ts +++ b/index.ts @@ -6,6 +6,7 @@ import sortVueAttributes, { RULE_NAME as sortVueAttributesName } from './rules/s import sortNamedExports, { RULE_NAME as sortNamedExportsName } from './rules/sort-named-exports' import sortNamedImports, { RULE_NAME as sortNamedImportsName } from './rules/sort-named-imports' import sortObjectTypes, { RULE_NAME as sortObjectTypesName } from './rules/sort-object-types' +import sortSwitchCase, { RULE_NAME as sortSwitchCaseName } from './rules/sort-switch-case' import sortUnionTypes, { RULE_NAME as sortUnionTypesName } from './rules/sort-union-types' import sortInterfaces, { RULE_NAME as sortInterfacesName } from './rules/sort-interfaces' import sortJsxProps, { RULE_NAME as sortJsxPropsName } from './rules/sort-jsx-props' @@ -36,6 +37,7 @@ let plugin = { [sortNamedImportsName]: sortNamedImports, [sortObjectTypesName]: sortObjectTypes, [sortInterfacesName]: sortInterfaces, + [sortSwitchCaseName]: sortSwitchCase, [sortUnionTypesName]: sortUnionTypes, [sortJsxPropsName]: sortJsxProps, [sortClassesName]: sortClasses, @@ -115,6 +117,7 @@ let getRules = ( [sortObjectTypesName]: ['error'], [sortUnionTypesName]: ['error'], [sortInterfacesName]: ['error'], + [sortSwitchCaseName]: ['error'], [sortJsxPropsName]: ['error'], [sortExportsName]: ['error'], [sortEnumsName]: ['error'], diff --git a/readme.md b/readme.md index ec23f49a9..ced113d2b 100644 --- a/readme.md +++ b/readme.md @@ -147,6 +147,7 @@ export default [ | [sort-exports](https://eslint-plugin-perfectionist.azat.io/rules/sort-exports) | enforce sorted exports | 🔧 | | [sort-imports](https://eslint-plugin-perfectionist.azat.io/rules/sort-imports) | enforce sorted imports | 🔧 | | [sort-interfaces](https://eslint-plugin-perfectionist.azat.io/rules/sort-interfaces) | enforce sorted interface properties | 🔧 | +| [sort-intersection-types](https://eslint-plugin-perfectionist.azat.io/rules/sort-intersection-types) | enforce sorted intersection types | 🔧 | | [sort-jsx-props](https://eslint-plugin-perfectionist.azat.io/rules/sort-jsx-props) | enforce sorted JSX props | 🔧 | | [sort-maps](https://eslint-plugin-perfectionist.azat.io/rules/sort-maps) | enforce sorted Map elements | 🔧 | | [sort-named-exports](https://eslint-plugin-perfectionist.azat.io/rules/sort-named-exports) | enforce sorted named exports | 🔧 | @@ -154,7 +155,7 @@ export default [ | [sort-object-types](https://eslint-plugin-perfectionist.azat.io/rules/sort-object-types) | enforce sorted object types | 🔧 | | [sort-objects](https://eslint-plugin-perfectionist.azat.io/rules/sort-objects) | enforce sorted objects | 🔧 | | [sort-svelte-attributes](https://eslint-plugin-perfectionist.azat.io/rules/sort-svelte-attributes) | enforce sorted Svelte attributes | 🔧 | -| [sort-intersection-types](https://eslint-plugin-perfectionist.azat.io/rules/sort-intersection-types) | enforce sorted intersection types | 🔧 | +| [sort-switch-case](https://eslint-plugin-perfectionist.azat.io/rules/sort-switch-case) | enforce sorted switch case statements | 🔧 | | [sort-union-types](https://eslint-plugin-perfectionist.azat.io/rules/sort-union-types) | enforce sorted union types | 🔧 | | [sort-vue-attributes](https://eslint-plugin-perfectionist.azat.io/rules/sort-vue-attributes) | enforce sorted Vue attributes | 🔧 | diff --git a/rules/sort-switch-case.ts b/rules/sort-switch-case.ts new file mode 100644 index 000000000..462eb9a89 --- /dev/null +++ b/rules/sort-switch-case.ts @@ -0,0 +1,198 @@ +import type { TSESTree } from '@typescript-eslint/types' + +import type { SortingNode } from '../typings' + +import { createEslintRule } from '../utils/create-eslint-rule' +import { rangeToDiff } from '../utils/range-to-diff' +import { isPositive } from '../utils/is-positive' +import { makeFixes } from '../utils/make-fixes' +import { sortNodes } from '../utils/sort-nodes' +import { pairwise } from '../utils/pairwise' +import { complete } from '../utils/complete' +import { compare } from '../utils/compare' + +type MESSAGE_ID = 'unexpectedSwitchCaseOrder' + +type Options = [ + Partial<{ + type: 'alphabetical' | 'line-length' | 'natural' + order: 'desc' | 'asc' + ignoreCase: boolean + }>, +] + +export const RULE_NAME = 'sort-switch-case' + +export default createEslintRule({ + name: RULE_NAME, + meta: { + type: 'suggestion', + docs: { + description: 'enforce sorted switch cases', + }, + fixable: 'code', + schema: [ + { + type: 'object', + properties: { + type: { + enum: ['alphabetical', 'natural', 'line-length'], + default: 'alphabetical', + type: 'string', + }, + order: { + enum: ['asc', 'desc'], + default: 'asc', + type: 'string', + }, + ignoreCase: { + type: 'boolean', + default: true, + }, + }, + additionalProperties: false, + }, + ], + messages: { + unexpectedSwitchCaseOrder: + 'Expected "{{right}}" to come before "{{left}}"', + }, + }, + defaultOptions: [ + { + type: 'alphabetical', + order: 'asc', + }, + ], + create: context => ({ + SwitchStatement: node => { + let options = complete(context.options.at(0), { + type: 'alphabetical', + ignoreCase: false, + order: 'asc', + } as const) + + let isDiscriminantIdentifier = node.discriminant.type === 'Identifier' + let isCasesHasBreak = node.cases + .filter(caseNode => caseNode.test !== null) + .every( + caseNode => + caseNode.consequent.length === 0 || + caseNode.consequent.some( + currentConsequent => + currentConsequent.type === 'BreakStatement' || + currentConsequent.type === 'ReturnStatement', + ), + ) + + if (isDiscriminantIdentifier && isCasesHasBreak) { + let nodes = node.cases.map>( + (caseNode: TSESTree.SwitchCase) => { + let name + if (caseNode.test?.type === 'Literal') { + name = `${caseNode.test.value}` + } else { + name = 'default' + } + + return { + size: rangeToDiff(caseNode.test?.range ?? caseNode.range), + node: caseNode, + name, + } + }, + ) + + pairwise(nodes, (left, right, iteration) => { + let compareValue: boolean + let lefter = nodes.at(iteration - 1) + let isCaseGrouped = + lefter?.node.consequent.length === 0 && + left.node.consequent.length !== 0 + + let caseGroup = [left] + for (let i = iteration - 1; i >= 0; i--) { + if (nodes.at(i)!.node.consequent.length === 0) { + caseGroup.unshift(nodes.at(i)!) + } else { + break + } + } + + if (left.name === 'default') { + compareValue = true + } else if (right.name === 'default') { + compareValue = false + } else if (isCaseGrouped) { + compareValue = isPositive(compare(caseGroup[0], right, options)) + } else { + compareValue = isPositive(compare(left, right, options)) + } + + if (compareValue) { + context.report({ + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: left.name, + right: right.name, + }, + node: right.node, + fix: fixer => { + let nodeGroups = nodes.reduce< + SortingNode[][] + >( + ( + accumulator: SortingNode[][], + currentNode: SortingNode, + index, + ) => { + if (index === 0) { + accumulator.at(-1)!.push(currentNode) + } else if ( + accumulator.at(-1)!.at(-1)?.node.consequent.length === 0 + ) { + accumulator.at(-1)!.push(currentNode) + } else { + accumulator.push([currentNode]) + } + return accumulator + }, + [[]], + ) + + let sortedNodeGroups = nodeGroups + .map(group => { + let { consequent } = group.at(-1)!.node + group.at(-1)!.node.consequent = [] + let sortedGroup = sortNodes(group, options) + sortedGroup.at(-1)!.node.consequent = consequent + return sortedGroup + }) + .toSorted((a, b) => { + let isGroupContainsDefault = (group: SortingNode[]) => + group.some(currentNode => currentNode.name === 'default') + if (isGroupContainsDefault(a)) { + return 1 + } else if (isGroupContainsDefault(b)) { + return -1 + } + return compare(a.at(0)!, b.at(0)!, options) + }) + + let sortedNodes = sortedNodeGroups.flat() + + for (let i = 0, max = sortedNodes.length; i < max; i++) { + if (sortedNodes.at(i)!.name === 'default') { + sortedNodes.push(sortedNodes.splice(i, 1).at(0)!) + } + } + + return makeFixes(fixer, nodes, sortedNodes, context.sourceCode) + }, + }) + } + }) + } + }, + }), +}) diff --git a/test/sort-switch-case.test.ts b/test/sort-switch-case.test.ts new file mode 100644 index 000000000..9cea9b2fc --- /dev/null +++ b/test/sort-switch-case.test.ts @@ -0,0 +1,792 @@ +import { RuleTester } from '@typescript-eslint/rule-tester' +import { afterAll, describe, it } from 'vitest' +import { dedent } from 'ts-dedent' + +import rule, { RULE_NAME } from '../rules/sort-switch-case' + +describe(RULE_NAME, () => { + RuleTester.describeSkip = describe.skip + RuleTester.afterAll = afterAll + RuleTester.describe = describe + RuleTester.itOnly = it.only + RuleTester.itSkip = it.skip + RuleTester.it = it + + let ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + }) + + describe(`${RULE_NAME}: sorting by alphabetical order`, () => { + let type = 'alphabetical-order' + + let options = { + type: 'alphabetical', + ignoreCase: true, + order: 'asc', + } as const + + ruleTester.run( + `${RULE_NAME}(${type}): sorts switch cases with return statements`, + rule, + { + valid: [ + { + code: dedent` + function func(name) { + switch(name) { + case 'aaa': + return 'a' + case 'bb': + return 'b' + case 'c': + return 'c' + default: + return 'x' + } + } + `, + options: [options], + }, + ], + invalid: [ + { + code: dedent` + function func(name) { + switch(name) { + case 'bb': + return 'b' + case 'aaa': + return 'a' + case 'c': + return 'c' + default: + return 'x' + } + } + `, + output: dedent` + function func(name) { + switch(name) { + case 'aaa': + return 'a' + case 'bb': + return 'b' + case 'c': + return 'c' + default: + return 'x' + } + } + `, + options: [options], + errors: [ + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'bb', + right: 'aaa', + }, + }, + ], + }, + ], + }, + ) + + ruleTester.run( + `${RULE_NAME}(${type}): sorts switch cases with break statements`, + rule, + { + valid: [ + { + code: dedent` + function func(name) { + let size + switch(name) { + case 'aaa': + height = 1 + break + case 'bb': + height = 2 + break + case 'c': + height = 3 + break + default: + height = NaN + } + return size + } + `, + options: [options], + }, + ], + invalid: [ + { + code: dedent` + function func(name) { + let size + switch(name) { + case 'aaa': + height = 1 + break + case 'c': + height = 3 + break + case 'bb': + height = 2 + break + default: + height = NaN + } + return size + } + `, + output: dedent` + function func(name) { + let size + switch(name) { + case 'aaa': + height = 1 + break + case 'bb': + height = 2 + break + case 'c': + height = 3 + break + default: + height = NaN + } + return size + } + `, + options: [options], + errors: [ + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'c', + right: 'bb', + }, + }, + ], + }, + ], + }, + ) + + ruleTester.run(`${RULE_NAME}(${type}): works with grouped cases`, rule, { + valid: [ + { + code: dedent` + switch (value) { + case 'aaaaaa': + return 'primary' + case 'bbbbb': + case 'ddd': + return 'secondary' + case 'cccc': + case 'ee': + case 'f': + return 'tertiary' + case 'x': + default: + return 'unknown' + } + `, + options: [options], + }, + ], + invalid: [ + { + code: dedent` + switch (value) { + case 'aaaaaa': + return 'primary' + case 'ee': + case 'cccc': + case 'f': + return 'tertiary' + case 'bbbbb': + case 'ddd': + return 'secondary' + case 'x': + default: + return 'unknown' + } + `, + output: dedent` + switch (value) { + case 'aaaaaa': + return 'primary' + case 'bbbbb': + case 'ddd': + return 'secondary' + case 'cccc': + case 'ee': + case 'f': + return 'tertiary' + case 'x': + default: + return 'unknown' + } + `, + options: [options], + errors: [ + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'ee', + right: 'cccc', + }, + }, + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'f', + right: 'bbbbb', + }, + }, + ], + }, + ], + }) + }) + + describe(`${RULE_NAME}: sorts switch cases with return statements`, () => { + let type = 'natural-order' + + let options = { + ignoreCase: true, + type: 'natural', + order: 'asc', + } as const + + ruleTester.run( + `${RULE_NAME}(${type}): sorts switch cases with return statements`, + rule, + { + valid: [ + { + code: dedent` + function func(name) { + switch(name) { + case 'aaa': + return 'a' + case 'bb': + return 'b' + case 'c': + return 'c' + default: + return 'x' + } + } + `, + options: [options], + }, + ], + invalid: [ + { + code: dedent` + function func(name) { + switch(name) { + case 'bb': + return 'b' + case 'aaa': + return 'a' + case 'c': + return 'c' + default: + return 'x' + } + } + `, + output: dedent` + function func(name) { + switch(name) { + case 'aaa': + return 'a' + case 'bb': + return 'b' + case 'c': + return 'c' + default: + return 'x' + } + } + `, + options: [options], + errors: [ + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'bb', + right: 'aaa', + }, + }, + ], + }, + ], + }, + ) + + ruleTester.run( + `${RULE_NAME}(${type}): sorts switch cases with break statements`, + rule, + { + valid: [ + { + code: dedent` + function func(name) { + let size + switch(name) { + case 'aaa': + height = 1 + break + case 'bb': + height = 2 + break + case 'c': + height = 3 + break + default: + height = NaN + } + return size + } + `, + options: [options], + }, + ], + invalid: [ + { + code: dedent` + function func(name) { + let size + switch(name) { + case 'aaa': + height = 1 + break + case 'c': + height = 3 + break + case 'bb': + height = 2 + break + default: + height = NaN + } + return size + } + `, + output: dedent` + function func(name) { + let size + switch(name) { + case 'aaa': + height = 1 + break + case 'bb': + height = 2 + break + case 'c': + height = 3 + break + default: + height = NaN + } + return size + } + `, + options: [options], + errors: [ + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'c', + right: 'bb', + }, + }, + ], + }, + ], + }, + ) + + ruleTester.run(`${RULE_NAME}(${type}): works with grouped cases`, rule, { + valid: [ + { + code: dedent` + switch (value) { + case 'aaaaaa': + return 'primary' + case 'bbbbb': + case 'ddd': + return 'secondary' + case 'cccc': + case 'ee': + case 'f': + return 'tertiary' + case 'x': + default: + return 'unknown' + } + `, + options: [options], + }, + ], + invalid: [ + { + code: dedent` + switch (value) { + case 'aaaaaa': + return 'primary' + case 'ee': + case 'cccc': + case 'f': + return 'tertiary' + case 'bbbbb': + case 'ddd': + return 'secondary' + case 'x': + default: + return 'unknown' + } + `, + output: dedent` + switch (value) { + case 'aaaaaa': + return 'primary' + case 'bbbbb': + case 'ddd': + return 'secondary' + case 'cccc': + case 'ee': + case 'f': + return 'tertiary' + case 'x': + default: + return 'unknown' + } + `, + options: [options], + errors: [ + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'ee', + right: 'cccc', + }, + }, + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'f', + right: 'bbbbb', + }, + }, + ], + }, + ], + }) + }) + + describe(`${RULE_NAME}: sorts switch cases with return statements`, () => { + let type = 'line-length-order' + + let options = { + type: 'line-length', + order: 'desc', + } as const + + ruleTester.run( + `${RULE_NAME}(${type}): sorts switch cases with return statements`, + rule, + { + valid: [ + { + code: dedent` + function func(name) { + switch(name) { + case 'aaa': + return 'a' + case 'bb': + return 'b' + case 'c': + return 'c' + default: + return 'x' + } + } + `, + options: [options], + }, + ], + invalid: [ + { + code: dedent` + function func(name) { + switch(name) { + case 'bb': + return 'b' + case 'aaa': + return 'a' + case 'c': + return 'c' + default: + return 'x' + } + } + `, + output: dedent` + function func(name) { + switch(name) { + case 'aaa': + return 'a' + case 'bb': + return 'b' + case 'c': + return 'c' + default: + return 'x' + } + } + `, + options: [options], + errors: [ + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'bb', + right: 'aaa', + }, + }, + ], + }, + ], + }, + ) + + ruleTester.run( + `${RULE_NAME}(${type}): sorts switch cases with break statements`, + rule, + { + valid: [ + { + code: dedent` + function func(name) { + let size + switch(name) { + case 'aaa': + height = 1 + break + case 'bb': + height = 2 + break + case 'c': + height = 3 + break + default: + height = NaN + } + return size + } + `, + options: [options], + }, + ], + invalid: [ + { + code: dedent` + function func(name) { + let size + switch(name) { + case 'aaa': + height = 1 + break + case 'c': + height = 3 + break + case 'bb': + height = 2 + break + default: + height = NaN + } + return size + } + `, + output: dedent` + function func(name) { + let size + switch(name) { + case 'aaa': + height = 1 + break + case 'bb': + height = 2 + break + case 'c': + height = 3 + break + default: + height = NaN + } + return size + } + `, + options: [options], + errors: [ + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'c', + right: 'bb', + }, + }, + ], + }, + ], + }, + ) + + ruleTester.run(`${RULE_NAME}(${type}): works with grouped cases`, rule, { + valid: [ + { + code: dedent` + switch (value) { + case 'aaaaaa': + return 'primary' + case 'bbbbb': + case 'ddd': + return 'secondary' + case 'cccc': + case 'ee': + case 'f': + return 'tertiary' + case 'x': + default: + return 'unknown' + } + `, + options: [options], + }, + ], + invalid: [ + { + code: dedent` + switch (value) { + case 'aaaaaa': + return 'primary' + case 'ee': + case 'cccc': + case 'f': + return 'tertiary' + case 'bbbbb': + case 'ddd': + return 'secondary' + case 'x': + default: + return 'unknown' + } + `, + output: dedent` + switch (value) { + case 'aaaaaa': + return 'primary' + case 'bbbbb': + case 'ddd': + return 'secondary' + case 'cccc': + case 'ee': + case 'f': + return 'tertiary' + case 'x': + default: + return 'unknown' + } + `, + options: [options], + errors: [ + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'ee', + right: 'cccc', + }, + }, + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'f', + right: 'bbbbb', + }, + }, + ], + }, + ], + }) + }) + + describe(`${RULE_NAME}: misc`, () => { + ruleTester.run( + `${RULE_NAME}: not works if discriminant is not literal`, + rule, + { + valid: [ + dedent` + switch (true) { + case name === 'bb': + return 'b' + case name === 'aaa': + return 'a' + case name === 'c': + return 'c' + default: + return 'x' + } + `, + ], + invalid: [], + }, + ) + }) + + ruleTester.run(`${RULE_NAME}: default should be last`, rule, { + valid: [], + invalid: [ + { + code: dedent` + switch (value) { + case 'aa': + return true + default: + return false + case 'b': + return true + } + `, + output: dedent` + switch (value) { + case 'aa': + return true + case 'b': + return true + default: + return false + } + `, + errors: [ + { + messageId: 'unexpectedSwitchCaseOrder', + data: { + left: 'default', + right: 'b', + }, + }, + ], + }, + ], + }) +}) diff --git a/typings/index.ts b/typings/index.ts index 15ed31730..64829d64c 100644 --- a/typings/index.ts +++ b/typings/index.ts @@ -8,11 +8,11 @@ export enum OptionalityOrder { export type PartitionComment = string[] | boolean | string -export interface SortingNode { +export interface SortingNode { hasMultipleImportDeclarations?: boolean dependencies?: string[] - node: TSESTree.Node group?: string name: string size: number + node: Node } From 1b29cdb8917c3e7e4f6cd897d05dde140bccf68f Mon Sep 17 00:00:00 2001 From: "Azat S." Date: Tue, 16 Jul 2024 19:58:57 +0300 Subject: [PATCH 4/4] feat: add typescript types --- index.ts | 8 +- package.json | 7 +- pnpm-lock.yaml | 367 +++++++++++++++++++++++++++++++++++++++++++++++++ vite.config.ts | 73 +++++++++- 4 files changed, 450 insertions(+), 5 deletions(-) diff --git a/index.ts b/index.ts index 295857dfa..7c450315a 100644 --- a/index.ts +++ b/index.ts @@ -1,3 +1,5 @@ +import type { Linter, ESLint } from 'eslint' + import sortIntersectionTypes, { RULE_NAME as sortIntersectionTypesName } from './rules/sort-intersection-types' import sortSvelteAttributes, { RULE_NAME as sortSvelteAttributesName } from './rules/sort-svelte-attributes' import sortAstroAttributes, { RULE_NAME as sortAstroAttributesName } from './rules/sort-astro-attributes' @@ -48,7 +50,7 @@ let plugin = { [sortMapsName]: sortMaps, }, name: 'perfectionist', -} +} as unknown as ESLint.Plugin let getRules = ( options: BaseOptions, @@ -131,14 +133,14 @@ let getRules = ( ) } -let createConfig = (options: BaseOptions) => ({ +let createConfig = (options: BaseOptions): Linter.FlatConfig => ({ plugins: { perfectionist: plugin, }, rules: getRules(options), }) -let createLegacyConfig = (options: BaseOptions) => ({ +let createLegacyConfig = (options: BaseOptions): Linter.Config => ({ plugins: ['perfectionist'], rules: getRules(options), }) diff --git a/package.json b/package.json index 2d470e932..4b0ece556 100644 --- a/package.json +++ b/package.json @@ -39,10 +39,13 @@ "./dist" ], "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", "exports": { ".": { "require": "./dist/index.js", - "import": "./dist/index.mjs" + "import": "./dist/index.mjs", + "types": "./dist/index.d.ts" }, "./package.json": "./package.json" }, @@ -86,6 +89,7 @@ "@nanostores/vue": "^0.10.0", "@playform/compress": "^0.0.13", "@poppanator/sveltekit-svg": "5.0.0-svelte5.3", + "@types/eslint": "^8.56.10", "@types/mdast": "^4.0.4", "@types/natural-compare-lite": "^1.4.2", "@types/node": "^20.14.10", @@ -144,6 +148,7 @@ "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "vite": "^5.3.3", + "vite-plugin-dts": "^3.9.1", "vite-plugin-lightningcss": "^0.0.5", "vitest": "^2.0.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b808aa619..1e56dd680 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,6 +60,9 @@ importers: '@poppanator/sveltekit-svg': specifier: 5.0.0-svelte5.3 version: 5.0.0-svelte5.3(rollup@4.18.1)(svelte@5.0.0-next.133)(svgo@3.3.2)(vite@5.3.3(@types/node@20.14.10)(lightningcss@1.25.1)(terser@5.31.2)) + '@types/eslint': + specifier: ^8.56.10 + version: 8.56.10 '@types/mdast': specifier: ^4.0.4 version: 4.0.4 @@ -231,6 +234,9 @@ importers: vite: specifier: ^5.3.3 version: 5.3.3(@types/node@20.14.10)(lightningcss@1.25.1)(terser@5.31.2) + vite-plugin-dts: + specifier: ^3.9.1 + version: 3.9.1(@types/node@20.14.10)(rollup@4.18.1)(typescript@5.5.3)(vite@5.3.3(@types/node@20.14.10)(lightningcss@1.25.1)(terser@5.31.2)) vite-plugin-lightningcss: specifier: ^0.0.5 version: 0.0.5 @@ -1116,6 +1122,19 @@ packages: '@mdx-js/mdx@3.0.1': resolution: {integrity: sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==} + '@microsoft/api-extractor-model@7.28.13': + resolution: {integrity: sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==} + + '@microsoft/api-extractor@7.43.0': + resolution: {integrity: sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==} + hasBin: true + + '@microsoft/tsdoc-config@0.16.2': + resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} + + '@microsoft/tsdoc@0.14.2': + resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + '@nanostores/persistent@0.10.1': resolution: {integrity: sha512-BMYj47ONmkrPkHfomimtBAwtDNNjO57lw0uk7jB35GHVwixmqWtlK6DVAAbioqwJn9WEaWSB/9Ss5ukBG0NHlQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1342,6 +1361,28 @@ packages: cpu: [x64] os: [win32] + '@rushstack/node-core-library@4.0.2': + resolution: {integrity: sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + '@rushstack/rig-package@0.5.2': + resolution: {integrity: sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==} + + '@rushstack/terminal@0.10.0': + resolution: {integrity: sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + '@rushstack/ts-command-line@4.19.1': + resolution: {integrity: sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==} + '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} @@ -1379,6 +1420,9 @@ packages: '@types/acorn@4.0.6': resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} + '@types/argparse@1.0.38': + resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1406,6 +1450,9 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/eslint@8.56.10': + resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} + '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} @@ -1418,6 +1465,9 @@ packages: '@types/html-minifier-terser@7.0.2': resolution: {integrity: sha512-mm2HqV22l8lFQh4r2oSsOEVea+m0qqxEmwpc9kC1p/XzmjLWrReR9D/GRs8Pex2NX/imyEH9c5IU/7tMBQCHOA==} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} @@ -1581,6 +1631,9 @@ packages: peerDependencies: typescript: '*' + '@volar/language-core@1.11.1': + resolution: {integrity: sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==} + '@volar/language-core@2.2.5': resolution: {integrity: sha512-2htyAuxRrAgETmFeUhT4XLELk3LiEcqoW/B8YUXMF6BrGWLMwIR09MFaZYvrA2UhbdAeSyeQ726HaWSWkexUcQ==} @@ -1593,9 +1646,15 @@ packages: '@volar/snapshot-document@2.2.5': resolution: {integrity: sha512-MTOvWVKxM7ugKO3Amffkv2pND03fe2JtfygYaputqjVFML7YxtTXj8SPnI2pODLeSwOKzDYL6Q8r5j6Y5AgUzQ==} + '@volar/source-map@1.11.1': + resolution: {integrity: sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==} + '@volar/source-map@2.2.5': resolution: {integrity: sha512-wrOEIiZNf4E+PWB0AxyM4tfhkfldPsb3bxg8N6FHrxJH2ohar7aGu48e98bp3pR9HUA7P/pR9VrLmkTrgCCnWQ==} + '@volar/typescript@1.11.1': + resolution: {integrity: sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==} + '@volar/typescript@2.2.5': resolution: {integrity: sha512-eSV/n75+ppfEVugMC/salZsI44nXDPAyL6+iTYCNLtiLHGJsnMv9GwiDMujrvAUj/aLQyqRJgYtXRoxop2clCw==} @@ -1620,6 +1679,14 @@ packages: '@vue/compiler-ssr@3.4.31': resolution: {integrity: sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==} + '@vue/language-core@1.8.27': + resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@vue/reactivity@3.4.31': resolution: {integrity: sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==} @@ -2028,6 +2095,10 @@ packages: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + comment-json@4.2.4: resolution: {integrity: sha512-E5AjpSW+O+N5T2GsOQMHLLsJvrYw6G/AFt9GvU6NguEAfzKShh7hRiLtVo6S9KbRpFMGqE5ojo0/hE+sdteWvQ==} engines: {node: '>= 6'} @@ -2038,6 +2109,9 @@ packages: compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + computeds@0.0.1: + resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -2200,6 +2274,9 @@ packages: resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} engines: {node: '>= 0.4'} + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -2782,6 +2859,10 @@ packages: resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} engines: {node: '>=14'} + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + fs-minipass@2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} @@ -3000,6 +3081,10 @@ packages: hastscript@8.0.0: resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + hex-rgb@4.3.0: resolution: {integrity: sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==} engines: {node: '>=6'} @@ -3055,6 +3140,10 @@ packages: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + import-meta-resolve@4.1.0: resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} @@ -3331,6 +3420,9 @@ packages: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} hasBin: true + jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -3386,6 +3478,9 @@ packages: jsonc-parser@2.3.1: resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==} + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} @@ -3416,6 +3511,9 @@ packages: known-css-properties@0.31.0: resolution: {integrity: sha512-sBPIUGTNF0czz0mwGGUoKKJC8Q7On1GPbCSFPfyEsfHb2DyBG0Y4QtV+EVWpINSaiGKZblDNuF5AezxSgOhesQ==} + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -3517,6 +3615,12 @@ packages: lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} @@ -3566,6 +3670,10 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} @@ -3779,6 +3887,9 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + minimatch@3.0.8: + resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -3831,6 +3942,9 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + muggle-string@0.3.1: + resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} + muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} @@ -4285,6 +4399,9 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.19.0: + resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} + resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -4379,6 +4496,11 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true + semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + semver@7.6.2: resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} engines: {node: '>=10'} @@ -4519,6 +4641,10 @@ packages: stream-replace-string@2.0.0: resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -4634,6 +4760,10 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + supports-hyperlinks@3.0.0: resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} engines: {node: '>=14.18'} @@ -4862,6 +4992,11 @@ packages: typescript-auto-import-cache@0.3.3: resolution: {integrity: sha512-ojEC7+Ci1ij9eE6hp8Jl9VUNnsEKzztktP5gtYNRMrTmfXVwA1PITYYAkpxCvvupdSYa/Re51B6KMcv1CTZEUA==} + typescript@5.4.2: + resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} + engines: {node: '>=14.17'} + hasBin: true + typescript@5.5.3: resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} engines: {node: '>=14.17'} @@ -4928,6 +5063,10 @@ packages: unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + untildify@4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} @@ -4947,6 +5086,10 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + validator@13.12.0: + resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} + engines: {node: '>= 0.10'} + vfile-location@5.0.2: resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==} @@ -4961,6 +5104,16 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true + vite-plugin-dts@3.9.1: + resolution: {integrity: sha512-rVp2KM9Ue22NGWB8dNtWEr+KekN3rIgz1tWD050QnRGlriUCmaDwa7qA5zDEjbXg5lAXhYMSBJtx3q3hQIJZSg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + typescript: '*' + vite: '*' + peerDependenciesMeta: + vite: + optional: true + vite-plugin-lightningcss@0.0.5: resolution: {integrity: sha512-lhz5GkXeRT/k09A7qEqmoL3CwdJDHgODPeGVlWGU1UxuGPEKfvSpKnDXza8nawKvxvc0eawJEsKjBzQP4AeGHw==} @@ -5114,6 +5267,15 @@ packages: peerDependencies: eslint: '>=6.0.0' + vue-template-compiler@2.7.16: + resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} + + vue-tsc@1.8.27: + resolution: {integrity: sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==} + hasBin: true + peerDependencies: + typescript: '*' + vue@3.4.31: resolution: {integrity: sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==} peerDependencies: @@ -5227,6 +5389,11 @@ packages: yoga-wasm-web@0.3.3: resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==} + z-schema@5.0.5: + resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} + engines: {node: '>=8.0.0'} + hasBin: true + zimmerframe@1.1.2: resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} @@ -6207,6 +6374,41 @@ snapshots: transitivePeerDependencies: - supports-color + '@microsoft/api-extractor-model@7.28.13(@types/node@20.14.10)': + dependencies: + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 4.0.2(@types/node@20.14.10) + transitivePeerDependencies: + - '@types/node' + + '@microsoft/api-extractor@7.43.0(@types/node@20.14.10)': + dependencies: + '@microsoft/api-extractor-model': 7.28.13(@types/node@20.14.10) + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 4.0.2(@types/node@20.14.10) + '@rushstack/rig-package': 0.5.2 + '@rushstack/terminal': 0.10.0(@types/node@20.14.10) + '@rushstack/ts-command-line': 4.19.1(@types/node@20.14.10) + lodash: 4.17.21 + minimatch: 3.0.8 + resolve: 1.22.8 + semver: 7.5.4 + source-map: 0.6.1 + typescript: 5.4.2 + transitivePeerDependencies: + - '@types/node' + + '@microsoft/tsdoc-config@0.16.2': + dependencies: + '@microsoft/tsdoc': 0.14.2 + ajv: 6.12.6 + jju: 1.4.0 + resolve: 1.19.0 + + '@microsoft/tsdoc@0.14.2': {} + '@nanostores/persistent@0.10.1(nanostores@0.10.3)': dependencies: nanostores: 0.10.3 @@ -6376,6 +6578,38 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.18.1': optional: true + '@rushstack/node-core-library@4.0.2(@types/node@20.14.10)': + dependencies: + fs-extra: 7.0.1 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.22.8 + semver: 7.5.4 + z-schema: 5.0.5 + optionalDependencies: + '@types/node': 20.14.10 + + '@rushstack/rig-package@0.5.2': + dependencies: + resolve: 1.22.8 + strip-json-comments: 3.1.1 + + '@rushstack/terminal@0.10.0(@types/node@20.14.10)': + dependencies: + '@rushstack/node-core-library': 4.0.2(@types/node@20.14.10) + supports-color: 8.1.1 + optionalDependencies: + '@types/node': 20.14.10 + + '@rushstack/ts-command-line@4.19.1(@types/node@20.14.10)': + dependencies: + '@rushstack/terminal': 0.10.0(@types/node@20.14.10) + '@types/argparse': 1.0.38 + argparse: 1.0.10 + string-argv: 0.3.2 + transitivePeerDependencies: + - '@types/node' + '@sec-ant/readable-stream@0.4.1': {} '@shikijs/core@1.10.1': {} @@ -6416,6 +6650,8 @@ snapshots: dependencies: '@types/estree': 1.0.5 + '@types/argparse@1.0.38': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.24.7 @@ -6453,6 +6689,11 @@ snapshots: dependencies: '@types/ms': 0.7.34 + '@types/eslint@8.56.10': + dependencies: + '@types/estree': 1.0.5 + '@types/json-schema': 7.0.15 + '@types/estree-jsx@1.0.5': dependencies: '@types/estree': 1.0.5 @@ -6465,6 +6706,8 @@ snapshots: '@types/html-minifier-terser@7.0.2': {} + '@types/json-schema@7.0.15': {} + '@types/json5@0.0.29': {} '@types/mdast@4.0.4': @@ -6694,6 +6937,10 @@ snapshots: vscode-languageserver-textdocument: 1.0.11 vscode-uri: 3.0.8 + '@volar/language-core@1.11.1': + dependencies: + '@volar/source-map': 1.11.1 + '@volar/language-core@2.2.5': dependencies: '@volar/source-map': 2.2.5 @@ -6724,10 +6971,19 @@ snapshots: vscode-languageserver-protocol: 3.17.5 vscode-languageserver-textdocument: 1.0.11 + '@volar/source-map@1.11.1': + dependencies: + muggle-string: 0.3.1 + '@volar/source-map@2.2.5': dependencies: muggle-string: 0.4.1 + '@volar/typescript@1.11.1': + dependencies: + '@volar/language-core': 1.11.1 + path-browserify: 1.0.1 + '@volar/typescript@2.2.5': dependencies: '@volar/language-core': 2.2.5 @@ -6775,6 +7031,20 @@ snapshots: '@vue/compiler-dom': 3.4.31 '@vue/shared': 3.4.31 + '@vue/language-core@1.8.27(typescript@5.5.3)': + dependencies: + '@volar/language-core': 1.11.1 + '@volar/source-map': 1.11.1 + '@vue/compiler-dom': 3.4.31 + '@vue/shared': 3.4.31 + computeds: 0.0.1 + minimatch: 9.0.5 + muggle-string: 0.3.1 + path-browserify: 1.0.1 + vue-template-compiler: 2.7.16 + optionalDependencies: + typescript: 5.5.3 + '@vue/reactivity@3.4.31': dependencies: '@vue/shared': 3.4.31 @@ -7377,6 +7647,9 @@ snapshots: commander@7.2.0: {} + commander@9.5.0: + optional: true + comment-json@4.2.4: dependencies: array-timsort: 1.0.3 @@ -7392,6 +7665,8 @@ snapshots: array-ify: 1.0.0 dot-prop: 5.3.0 + computeds@0.0.1: {} + concat-map@0.0.1: {} confbox@0.1.7: {} @@ -7600,6 +7875,8 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.1 + de-indent@1.0.2: {} + debug@3.2.7: dependencies: ms: 2.1.3 @@ -8394,6 +8671,12 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + fs-minipass@2.1.0: dependencies: minipass: 3.3.6 @@ -8706,6 +8989,8 @@ snapshots: property-information: 6.5.0 space-separated-tokens: 2.0.2 + he@1.2.0: {} + hex-rgb@4.3.0: {} hosted-git-info@2.8.9: {} @@ -8752,6 +9037,8 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 + import-lazy@4.0.0: {} + import-meta-resolve@4.1.0: {} imurmurhash@0.1.4: {} @@ -8988,6 +9275,8 @@ snapshots: jiti@1.21.6: {} + jju@1.4.0: {} + js-tokens@4.0.0: {} js-tokens@9.0.0: {} @@ -9025,6 +9314,10 @@ snapshots: jsonc-parser@2.3.1: {} + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + jsonparse@1.3.1: {} jsx-ast-utils@3.3.5: @@ -9048,6 +9341,8 @@ snapshots: known-css-properties@0.31.0: {} + kolorist@1.8.0: {} + language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -9132,6 +9427,10 @@ snapshots: lodash.camelcase@4.3.0: {} + lodash.get@4.4.2: {} + + lodash.isequal@4.5.0: {} + lodash.isplainobject@4.0.6: {} lodash.kebabcase@4.1.1: {} @@ -9173,6 +9472,10 @@ snapshots: dependencies: yallist: 3.1.1 + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + magic-string@0.30.10: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 @@ -9649,6 +9952,10 @@ snapshots: min-indent@1.0.1: {} + minimatch@3.0.8: + dependencies: + brace-expansion: 1.1.11 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -9693,6 +10000,8 @@ snapshots: ms@2.1.3: {} + muggle-string@0.3.1: {} + muggle-string@0.4.1: {} nanoid@3.3.7: {} @@ -10208,6 +10517,11 @@ snapshots: resolve-pkg-maps@1.0.0: {} + resolve@1.19.0: + dependencies: + is-core-module: 2.14.0 + path-parse: 1.0.7 + resolve@1.22.8: dependencies: is-core-module: 2.14.0 @@ -10363,6 +10677,10 @@ snapshots: semver@6.3.1: {} + semver@7.5.4: + dependencies: + lru-cache: 6.0.0 + semver@7.6.2: {} set-function-length@1.2.2: @@ -10512,6 +10830,8 @@ snapshots: stream-replace-string@2.0.0: {} + string-argv@0.3.2: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -10674,6 +10994,10 @@ snapshots: dependencies: has-flag: 4.0.0 + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + supports-hyperlinks@3.0.0: dependencies: has-flag: 4.0.0 @@ -10905,6 +11229,8 @@ snapshots: dependencies: semver: 7.6.2 + typescript@5.4.2: {} + typescript@5.5.3: {} ufo@1.5.3: {} @@ -11001,6 +11327,8 @@ snapshots: unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 + universalify@0.1.2: {} + untildify@4.0.0: {} update-browserslist-db@1.1.0(browserslist@4.23.1): @@ -11020,6 +11348,8 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + validator@13.12.0: {} + vfile-location@5.0.2: dependencies: '@types/unist': 3.0.2 @@ -11053,6 +11383,23 @@ snapshots: - supports-color - terser + vite-plugin-dts@3.9.1(@types/node@20.14.10)(rollup@4.18.1)(typescript@5.5.3)(vite@5.3.3(@types/node@20.14.10)(lightningcss@1.25.1)(terser@5.31.2)): + dependencies: + '@microsoft/api-extractor': 7.43.0(@types/node@20.14.10) + '@rollup/pluginutils': 5.1.0(rollup@4.18.1) + '@vue/language-core': 1.8.27(typescript@5.5.3) + debug: 4.3.5 + kolorist: 1.8.0 + magic-string: 0.30.10 + typescript: 5.5.3 + vue-tsc: 1.8.27(typescript@5.5.3) + optionalDependencies: + vite: 5.3.3(@types/node@20.14.10)(lightningcss@1.25.1)(terser@5.31.2) + transitivePeerDependencies: + - '@types/node' + - rollup + - supports-color + vite-plugin-lightningcss@0.0.5: dependencies: browserslist: 4.23.1 @@ -11213,6 +11560,18 @@ snapshots: transitivePeerDependencies: - supports-color + vue-template-compiler@2.7.16: + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + vue-tsc@1.8.27(typescript@5.5.3): + dependencies: + '@volar/typescript': 1.11.1 + '@vue/language-core': 1.8.27(typescript@5.5.3) + semver: 7.6.2 + typescript: 5.5.3 + vue@3.4.31(typescript@5.5.3): dependencies: '@vue/compiler-dom': 3.4.31 @@ -11338,6 +11697,14 @@ snapshots: yoga-wasm-web@0.3.3: {} + z-schema@5.0.5: + dependencies: + lodash.get: 4.4.2 + lodash.isequal: 4.5.0 + validator: 13.12.0 + optionalDependencies: + commander: 9.5.0 + zimmerframe@1.1.2: {} zod-to-json-schema@3.23.1(zod@3.23.8): diff --git a/vite.config.ts b/vite.config.ts index 25b72ae57..3bfebd12b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,62 @@ +import type { Plugin } from 'vite' + import { defineConfig } from 'vite' +import dts from 'vite-plugin-dts' +import fs from 'node:fs/promises' +import prettier from 'prettier' import path from 'node:path' +let getAllFiles = async (dir: string) => { + let files = await fs.readdir(dir) + files = (await Promise.all( + files.map(async file => { + let filePath = path.join(dir, file) + let stats = await fs.stat(filePath) + if (stats.isDirectory()) { + return getAllFiles(filePath) + } else if (stats.isFile()) { + return filePath + } + return null + }), + )) as string[] + return files + .reduce((all: string[], folderContents) => [...all, folderContents], []) + .flat() +} + +let prettierPlugin = (): Plugin => { + let outDir: string = 'dist' + return { + closeBundle: async () => { + let outputDir = path.resolve(outDir) + + if (!outputDir) { + console.warn( + 'Output directory or file is not specified in the bundle options.', + ) + return + } + + let files = await getAllFiles(outputDir) + + for (let file of files) { + let fileContent = await fs.readFile(file, 'utf8') + let prettierConfig = await prettier.resolveConfig(file) + let formattedContent = await prettier.format(fileContent, { + ...prettierConfig, + filepath: file, + }) + await fs.writeFile(file, formattedContent, 'utf8') + } + }, + configResolved: config => { + ;({ outDir } = config.build) + }, + name: 'vite-plugin-prettier', + } +} + export default defineConfig({ build: { lib: { @@ -18,13 +74,28 @@ export default defineConfig({ formats: ['cjs', 'es'], }, rollupOptions: { - external: (id: string) => !id.startsWith('.') && !path.isAbsolute(id), output: { preserveModules: true, + exports: 'named', }, + external: (id: string) => !id.startsWith('.') && !path.isAbsolute(id), }, minify: false, }, + plugins: [ + dts({ + include: [ + path.join(__dirname, 'index.ts'), + path.join(__dirname, 'typings'), + path.join(__dirname, 'rules'), + path.join(__dirname, 'utils'), + ], + insertTypesEntry: true, + strictOutput: true, + rollupTypes: true, + }), + prettierPlugin(), + ], test: { coverage: { all: false,