From f8f14758d3a3ce092ee377f71820bfebae72863f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 18:40:23 +0000 Subject: [PATCH 1/4] chore(deps): bump codecov/codecov-action from 4 to 5 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4 to 5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4...v5) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 2404da2..bd93341 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -19,4 +19,4 @@ jobs: - name: Collect coverage run: npm run test:coverage - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 From 666416c208d0388749279d5bce53c1145bffb1cc Mon Sep 17 00:00:00 2001 From: allohamora Date: Thu, 30 Jan 2025 19:33:20 +0200 Subject: [PATCH 2/4] chore: apply npm audit fix --- package-lock.json | 62 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2032513..d4d286c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1236,6 +1236,19 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", @@ -1318,12 +1331,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@eslint/core": "^0.10.0", "levn": "^0.4.1" }, "engines": { @@ -2250,6 +2264,13 @@ "pretty-format": "^29.0.0" } }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -3764,10 +3785,11 @@ "dev": true }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -10352,6 +10374,15 @@ "minimatch": "^3.1.2" } }, + "@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.15" + } + }, "@eslint/eslintrc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", @@ -10408,11 +10439,12 @@ "dev": true }, "@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", "dev": true, "requires": { + "@eslint/core": "^0.10.0", "levn": "^0.4.1" } }, @@ -11105,6 +11137,12 @@ "pretty-format": "^29.0.0" } }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -12155,9 +12193,9 @@ "dev": true }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "requires": { "path-key": "^3.1.0", From 47062f58280021d045c268b694d0d4cf93bc4115 Mon Sep 17 00:00:00 2001 From: allohamora Date: Thu, 30 Jan 2025 19:59:49 +0200 Subject: [PATCH 3/4] feat: add prettier format for eslint config --- .../js/eslint/eslint.entrypoint.test.ts | 60 +++++-------- __tests__/setup-after-env.ts | 4 + __tests__/utils/javascript.test.ts | 31 +++++++ jest.config.cjs | 3 +- package-lock.json | 8 +- package.json | 4 +- src/categories/js/eslint/eslint.entrypoint.ts | 85 +++++++++---------- src/utils/javascript.ts | 8 ++ 8 files changed, 112 insertions(+), 91 deletions(-) create mode 100644 __tests__/setup-after-env.ts create mode 100644 __tests__/utils/javascript.test.ts create mode 100644 src/utils/javascript.ts diff --git a/__tests__/categories/js/eslint/eslint.entrypoint.test.ts b/__tests__/categories/js/eslint/eslint.entrypoint.test.ts index e376c35..309123b 100644 --- a/__tests__/categories/js/eslint/eslint.entrypoint.test.ts +++ b/__tests__/categories/js/eslint/eslint.entrypoint.test.ts @@ -2,6 +2,7 @@ import * as fs from 'src/utils/fs'; import * as npm from 'src/utils/npm'; import * as mutation from 'src/utils/mutation'; import * as config from 'src/categories/js/eslint/eslint.config'; +import * as javascript from 'src/utils/javascript'; import { eslint } from 'src/categories/js/eslint/eslint.entrypoint'; import { createConfig } from './eslint-test.utils'; import { Config } from 'src/categories/js/eslint/config/config.interface'; @@ -18,6 +19,14 @@ const mutationMocked = jest.mocked(mutation); jest.mock('src/categories/js/eslint/eslint.config'); const configMocked = jest.mocked(config); +// we need to mock prettier because it doesn't work with jest +// TypeError: A dynamic import callback was invoked without --experimental-vm-modules +// https://github.com/prettier/prettier/issues/15769 +jest.mock('src/utils/javascript', () => ({ + format: jest.fn().mockImplementation(async (config) => config), +})); +const javascriptMocked = jest.mocked(javascript); + beforeEach(() => { jest.clearAllMocks(); }); @@ -57,15 +66,12 @@ describe('eslint', () => { configMocked.getConfig.mockReturnValueOnce(config); const configFile = `export default [ - { - ignores: [ - '__test__' - ], - } +{ignores: ["__test__"]} ];`; await eslint(); + expect(javascriptMocked.format).toHaveBeenCalledWith(configFile); expect(fsMocked.addFileToRoot).toHaveBeenCalledWith('eslint.config.mjs', configFile); }); @@ -74,12 +80,12 @@ describe('eslint', () => { configMocked.getConfig.mockReturnValueOnce(config); const configFile = `export default [ - {\n - } +{} ];`; await eslint(); + expect(javascriptMocked.format).toHaveBeenCalledWith(configFile); expect(fsMocked.addFileToRoot).toHaveBeenCalledWith('eslint.config.mjs', configFile); }); @@ -94,16 +100,12 @@ describe('eslint', () => { configMocked.getConfig.mockReturnValueOnce(config); const configFile = `export default [ - { - languageOptions: { - globals: {\n - } - }, - } +{languageOptions: {}} ];`; await eslint(); + expect(javascriptMocked.format).toHaveBeenCalledWith(configFile); expect(fsMocked.addFileToRoot).toHaveBeenCalledWith('eslint.config.mjs', configFile); }); @@ -114,14 +116,14 @@ describe('eslint', () => { configMocked.getConfig.mockReturnValueOnce(config); const configFile = `export default [ - __test1__, - __test2__, - {\n - } +__test1__, +__test2__, +{} ];`; await eslint(); + expect(javascriptMocked.format).toHaveBeenCalledWith(configFile); expect(fsMocked.addFileToRoot).toHaveBeenCalledWith('eslint.config.mjs', configFile); }); @@ -149,32 +151,14 @@ describe('eslint', () => { configMocked.getConfig.mockReturnValueOnce(config); const configFile = `// @ts-check -import globals from "globals";\n +import globals from "globals"; export default tseslint.config( - { - files: ['src/**/*.ts'], - ignores: [ - 'node_modules' - ], - languageOptions: { - globals: { - ...globals.window - }, - parserOptions: { - ecmaVersion: 2020 - } - }, - plugins: { - '@typescript-eslint': eslintPluginTs - }, - rules: { - 'no-console': 'warn' - }, - } +{files: ["src/**/*.ts"],ignores: ["node_modules"],languageOptions: {globals: {...globals.window},parserOptions: {"ecmaVersion":2020}},plugins: {'@typescript-eslint': eslintPluginTs},rules: {"no-console":"warn"}} );`; await eslint(); + expect(javascriptMocked.format).toHaveBeenCalledWith(configFile); expect(fsMocked.addFileToRoot).toHaveBeenCalledWith('eslint.config.mjs', configFile); }); diff --git a/__tests__/setup-after-env.ts b/__tests__/setup-after-env.ts new file mode 100644 index 0000000..723c181 --- /dev/null +++ b/__tests__/setup-after-env.ts @@ -0,0 +1,4 @@ +// we need to mock prettier in all tests because it doesn't work with jest +// TypeError: A dynamic import callback was invoked without --experimental-vm-modules +// https://github.com/prettier/prettier/issues/15769 +jest.mock('prettier', () => jest.fn()); diff --git a/__tests__/utils/javascript.test.ts b/__tests__/utils/javascript.test.ts new file mode 100644 index 0000000..50d79bd --- /dev/null +++ b/__tests__/utils/javascript.test.ts @@ -0,0 +1,31 @@ +import prettier from 'prettier'; +import { getConfig } from 'src/categories/js/prettier/prettier.config'; +import { defaultConfig } from 'src/categories/js/prettier/config/default.config'; +import { format } from 'src/utils/javascript'; + +// we need to mock prettier because it doesn't work with jest +// TypeError: A dynamic import callback was invoked without --experimental-vm-modules +// https://github.com/prettier/prettier/issues/15769 +jest.mock('prettier', () => ({ + format: jest.fn(), +})); +const prettierMocked = jest.mocked(prettier); + +jest.mock('src/categories/js/prettier/prettier.config', () => ({ getConfig: jest.fn() })); +const getConfigMocked = jest.mocked(getConfig); + +describe('format', () => { + test('formats input with default config', async () => { + const input = `const foo = "bar"`; + const formatted = `const foo = 'bar';`; + + getConfigMocked.mockImplementation(() => ({ config: { printWidth: 90 } }) as typeof defaultConfig); + prettierMocked.format.mockResolvedValueOnce(formatted); + + const actual = await format(input); + const expected = formatted; + + expect(actual).toBe(expected); + expect(prettierMocked.format).toHaveBeenCalledWith(input, { parser: 'typescript', printWidth: 90 }); + }); +}); diff --git a/jest.config.cjs b/jest.config.cjs index d3db317..5e3c946 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -9,7 +9,8 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', moduleDirectories: ['', 'node_modules'], - testRegex: '.*\.(spec|test)\.ts$', + testRegex: '.*.(spec|test).ts$', collectCoverageFrom: ['src/**/*.ts'], passWithNoTests: true, + setupFilesAfterEnv: ['./__tests__/setup-after-env.ts'], }; diff --git a/package-lock.json b/package-lock.json index d4d286c..3945d83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "MIT", "dependencies": { "inquirer": "8.2.4", - "ora": "5.4.1" + "ora": "5.4.1", + "prettier": "^3.3.3" }, "bin": { "cli": "bin/cli.js" @@ -30,7 +31,6 @@ "husky": "^9.1.6", "jest": "^29.7.0", "lint-staged": "^15.2.10", - "prettier": "^3.3.3", "rimraf": "^6.0.1", "rollup": "^3.29.5", "rollup-plugin-typescript2": "^0.36.0", @@ -7697,7 +7697,6 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true, "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" @@ -14915,8 +14914,7 @@ "prettier": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==" }, "prettier-linter-helpers": { "version": "1.0.0", diff --git a/package.json b/package.json index 6566b00..1a5babe 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,6 @@ "husky": "^9.1.6", "jest": "^29.7.0", "lint-staged": "^15.2.10", - "prettier": "^3.3.3", "rimraf": "^6.0.1", "rollup": "^3.29.5", "rollup-plugin-typescript2": "^0.36.0", @@ -83,7 +82,8 @@ }, "dependencies": { "inquirer": "8.2.4", - "ora": "5.4.1" + "ora": "5.4.1", + "prettier": "^3.3.3" }, "lint-staged": { "*.ts": [ diff --git a/src/categories/js/eslint/eslint.entrypoint.ts b/src/categories/js/eslint/eslint.entrypoint.ts index af57aaf..396d692 100644 --- a/src/categories/js/eslint/eslint.entrypoint.ts +++ b/src/categories/js/eslint/eslint.entrypoint.ts @@ -4,55 +4,50 @@ import { addScripts, installDevelopmentDependencies } from 'src/utils/npm'; import { CONFIG_FILE_NAME, PACKAGE_NAME } from './eslint.const'; import { applyMutations } from 'src/utils/mutation'; import { Config } from './config/config.interface'; +import { format } from 'src/utils/javascript'; -const buildConfig = (config: Config) => { - const start = config.typescript ? `// @ts-check\n` : ''; +const optional = (value: T | undefined, map: (value: T) => string) => (value ? map(value) : ''); + +export const buildConfig = (config: Config) => { + const start = optional(config.typescript, () => '// @ts-check'); + + const imports = `${config.imports.map((item) => `${item};`).join('\n')}\n`.trim(); const exportStart = config.typescript ? `export default tseslint.config(` : `export default [`; const exportEnd = config.typescript ? `);` : `];`; - const imports = `${start}${config.imports.join(';\n')}${config.imports.length ? ';\n' : ''}`; - const configs = config.configs.map((item) => ` ${item},`).join('\n'); - - const files = config.eslintConfig.files - ? ` files: ${JSON.stringify(config.eslintConfig.files).replace(/"/gim, `'`)},` - : ''; - const ignores = config.eslintConfig.ignores - ? ` ignores: [\n${config.eslintConfig.ignores.map((item) => ` '${item}'`).join(',\n')}\n ],` - : ''; - - const globals = config.eslintConfig.languageOptions?.globals - ? config.eslintConfig.languageOptions.globals.map((item) => ` ...globals.${item}`).join(',\n') - : ''; - const parserOptions = config.eslintConfig.languageOptions?.parserOptions - ? ` parserOptions: {\n${Object.entries(config.eslintConfig.languageOptions.parserOptions) - .map(([key, value]) => ` ${key}: ${value}`) - .join(',\n')}\n }` - : ''; - - const plugins = config.eslintConfig.plugins - ? ` plugins: { ${Object.entries(config.eslintConfig.plugins) - .map(([key, value]) => `\n '${key}': ${value}`) - .join(',')}\n },` - : ''; - const rules = config.eslintConfig.rules - ? ` rules: ${JSON.stringify(config.eslintConfig.rules, null, 2) - .replace(/"/gim, "'") - .replace(/\n {2}/gim, '\n' + ' '.repeat(6)) - .replace('\n}', '\n }')},` - : ''; - - const languageOptions = config.eslintConfig.languageOptions - ? ` languageOptions: { - globals: { -${globals} - }${parserOptions ? `,\n${parserOptions}` : ''} - },` - : ''; - - const mainConfig = ` {\n${[files, ignores, languageOptions, plugins, rules].filter(Boolean).join('\n')}\n }`; - - return [imports, exportStart, configs, mainConfig, exportEnd].filter(Boolean).join('\n'); + const configs = config.configs.map((item) => `${item},`).join('\n'); + + const files = optional(config.eslintConfig.files, (value) => `files: ${JSON.stringify(value)}`); + const ignores = optional(config.eslintConfig.ignores, (value) => `ignores: ${JSON.stringify(value)}`); + + const plugins = optional( + config.eslintConfig.plugins, + (values) => + `plugins: {${Object.entries(values) + .map(([key, value]) => `'${key}': ${value}`) + .join(',')}}`, + ); + + const rules = optional(config.eslintConfig.rules, (value) => `rules: ${JSON.stringify(value)}`); + + const globals = optional( + config.eslintConfig.languageOptions?.globals, + (value) => `globals: {${value.map((item) => `...globals.${item}`).join(',')}}`, + ); + const parserOptions = optional( + config.eslintConfig.languageOptions?.parserOptions, + (value) => `parserOptions: ${JSON.stringify(value)}`, + ); + + const languageOptions = optional( + config.eslintConfig.languageOptions, + () => `languageOptions: {${[globals, parserOptions].filter(Boolean).join(',')}}`, + ); + + const mainConfig = `{${[files, ignores, languageOptions, plugins, rules].filter(Boolean).join(',')}}`; + + return [start, imports, exportStart, configs, mainConfig, exportEnd].filter(Boolean).join('\n'); }; export const eslint = async () => { @@ -63,7 +58,7 @@ export const eslint = async () => { await installDevelopmentDependencies(PACKAGE_NAME, ...dependencies); - const eslintConfig = buildConfig(config); + const eslintConfig = await format(buildConfig(config)); await addFileToRoot(CONFIG_FILE_NAME, eslintConfig); await addScripts(...scripts); diff --git a/src/utils/javascript.ts b/src/utils/javascript.ts new file mode 100644 index 0000000..2109687 --- /dev/null +++ b/src/utils/javascript.ts @@ -0,0 +1,8 @@ +import prettier from 'prettier'; +import { getConfig } from 'src/categories/js/prettier/prettier.config'; + +export const format = async (input: string) => { + const { config } = getConfig(); + + return await prettier.format(input, { parser: 'typescript', ...config } as prettier.Options); +}; From 859eff828d195ae811bb2ed568666c1670af7082 Mon Sep 17 00:00:00 2001 From: allohamora Date: Thu, 30 Jan 2025 20:06:13 +0200 Subject: [PATCH 4/4] feat: move ignores to separate config --- __tests__/categories/js/eslint/eslint.entrypoint.test.ts | 7 +++---- src/categories/js/eslint/eslint.entrypoint.ts | 8 +++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/__tests__/categories/js/eslint/eslint.entrypoint.test.ts b/__tests__/categories/js/eslint/eslint.entrypoint.test.ts index 309123b..ab45471 100644 --- a/__tests__/categories/js/eslint/eslint.entrypoint.test.ts +++ b/__tests__/categories/js/eslint/eslint.entrypoint.test.ts @@ -66,7 +66,7 @@ describe('eslint', () => { configMocked.getConfig.mockReturnValueOnce(config); const configFile = `export default [ -{ignores: ["__test__"]} +{ignores: ["__test__"]}, ];`; await eslint(); @@ -80,7 +80,6 @@ describe('eslint', () => { configMocked.getConfig.mockReturnValueOnce(config); const configFile = `export default [ -{} ];`; await eslint(); @@ -118,7 +117,6 @@ describe('eslint', () => { const configFile = `export default [ __test1__, __test2__, -{} ];`; await eslint(); @@ -153,7 +151,8 @@ __test2__, const configFile = `// @ts-check import globals from "globals"; export default tseslint.config( -{files: ["src/**/*.ts"],ignores: ["node_modules"],languageOptions: {globals: {...globals.window},parserOptions: {"ecmaVersion":2020}},plugins: {'@typescript-eslint': eslintPluginTs},rules: {"no-console":"warn"}} +{ignores: ["node_modules"]}, +{files: ["src/**/*.ts"],languageOptions: {globals: {...globals.window},parserOptions: {"ecmaVersion":2020}},plugins: {'@typescript-eslint': eslintPluginTs},rules: {"no-console":"warn"}} );`; await eslint(); diff --git a/src/categories/js/eslint/eslint.entrypoint.ts b/src/categories/js/eslint/eslint.entrypoint.ts index 396d692..df9adb5 100644 --- a/src/categories/js/eslint/eslint.entrypoint.ts +++ b/src/categories/js/eslint/eslint.entrypoint.ts @@ -19,7 +19,6 @@ export const buildConfig = (config: Config) => { const configs = config.configs.map((item) => `${item},`).join('\n'); const files = optional(config.eslintConfig.files, (value) => `files: ${JSON.stringify(value)}`); - const ignores = optional(config.eslintConfig.ignores, (value) => `ignores: ${JSON.stringify(value)}`); const plugins = optional( config.eslintConfig.plugins, @@ -45,9 +44,12 @@ export const buildConfig = (config: Config) => { () => `languageOptions: {${[globals, parserOptions].filter(Boolean).join(',')}}`, ); - const mainConfig = `{${[files, ignores, languageOptions, plugins, rules].filter(Boolean).join(',')}}`; + const ignoresConfig = optional(config.eslintConfig.ignores, (value) => `{ignores: ${JSON.stringify(value)}},`); - return [start, imports, exportStart, configs, mainConfig, exportEnd].filter(Boolean).join('\n'); + const mainContent = [files, languageOptions, plugins, rules].filter(Boolean).join(','); + const mainConfig = optional(mainContent, (content) => `{${content}}`); + + return [start, imports, exportStart, configs, ignoresConfig, mainConfig, exportEnd].filter(Boolean).join('\n'); }; export const eslint = async () => {