> limitations under the License.
>
-## javascript-stringify
-
-License: MIT
-By: Blake Embrey
-Repository: git+https://github.com/blakeembrey/javascript-stringify.git
-
-> The MIT License (MIT)
->
-> Copyright (c) 2013 Blake Embrey (hello@blakeembrey.com)
->
-> Permission is hereby granted, free of charge, to any person obtaining a copy
-> of this software and associated documentation files (the "Software"), to deal
-> in the Software without restriction, including without limitation the rights
-> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-> copies of the Software, and to permit persons to whom the Software is
-> furnished to do so, subject to the following conditions:
->
-> The above copyright notice and this permission notice shall be included in
-> all copies or substantial portions of the Software.
->
-> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-> THE SOFTWARE.
->
-
## kleur
License: MIT
+++ /dev/null
-import { it, describe, expect } from 'vitest'
-import { getAdditionalConfigAndDependencies } from '../utils/renderEslint'
-
-describe('renderEslint', () => {
- it('should get additional dependencies and config with no test flags', () => {
- const { additionalConfig, additionalDependencies } = getAdditionalConfigAndDependencies({
- needsVitest: false,
- needsCypress: false,
- needsCypressCT: false,
- needsPlaywright: false
- })
- expect(additionalConfig).toStrictEqual({})
- expect(additionalDependencies).toStrictEqual({})
- })
-
- it('should get additional dependencies and config with for vitest', () => {
- const { additionalConfig, additionalDependencies } = getAdditionalConfigAndDependencies({
- needsVitest: true,
- needsCypress: false,
- needsCypressCT: false,
- needsPlaywright: false
- })
- expect(additionalConfig.overrides[0].files).toStrictEqual([
- 'src/**/*.{test,spec}.{js,ts,jsx,tsx}'
- ])
- expect(additionalConfig.overrides[0].extends).toStrictEqual([
- 'plugin:@vitest/legacy-recommended'
- ])
- expect(additionalDependencies['@vitest/eslint-plugin']).not.toBeUndefined()
- })
-
- it('should get additional dependencies and config with for cypress', () => {
- const { additionalConfig, additionalDependencies } = getAdditionalConfigAndDependencies({
- needsVitest: false,
- needsCypress: true,
- needsCypressCT: false,
- needsPlaywright: false
- })
- expect(additionalConfig.overrides[0].files).toStrictEqual([
- 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}',
- 'cypress/support/**/*.{js,ts,jsx,tsx}'
- ])
- expect(additionalConfig.overrides[0].extends).toStrictEqual(['plugin:cypress/recommended'])
- expect(additionalDependencies['eslint-plugin-cypress']).not.toBeUndefined()
- })
-
- it('should get additional dependencies and config with for cypress with component testing', () => {
- const { additionalConfig, additionalDependencies } = getAdditionalConfigAndDependencies({
- needsVitest: false,
- needsCypress: true,
- needsCypressCT: true,
- needsPlaywright: false
- })
- expect(additionalConfig.overrides[0].files).toStrictEqual([
- '**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}',
- 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}',
- 'cypress/support/**/*.{js,ts,jsx,tsx}'
- ])
- expect(additionalConfig.overrides[0].extends).toStrictEqual(['plugin:cypress/recommended'])
- expect(additionalDependencies['eslint-plugin-cypress']).not.toBeUndefined()
- })
-
- it('should get additional dependencies and config with for playwright', () => {
- const { additionalConfig, additionalDependencies } = getAdditionalConfigAndDependencies({
- needsVitest: false,
- needsCypress: false,
- needsCypressCT: false,
- needsPlaywright: true
- })
- expect(additionalConfig.overrides[0].files).toStrictEqual([
- 'e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'
- ])
- expect(additionalConfig.overrides[0].extends).toStrictEqual(['plugin:playwright/recommended'])
- expect(additionalDependencies['eslint-plugin-playwright']).not.toBeUndefined()
- })
-})
"@types/eslint": "^9.6.1",
"@types/node": "^20.16.10",
"@types/prompts": "^2.4.9",
- "@vue/create-eslint-config": "^0.3.3",
+ "@vue/create-eslint-config": "0.4.1",
"@vue/tsconfig": "^0.5.1",
"ejs": "^3.1.10",
"esbuild": "^0.18.20",
specifier: ^2.4.9
version: 2.4.9
'@vue/create-eslint-config':
- specifier: ^0.3.3
- version: 0.3.3
+ specifier: 0.4.1
+ version: 0.4.1
'@vue/tsconfig':
specifier: ^0.5.1
version: 0.5.1
specifier: ^6.2.3
version: 6.2.3
typescript:
- specifier: ~5.6.0
- version: 5.6.2
+ specifier: ~5.5.4
+ version: 5.5.4
vue-tsc:
specifier: ^2.1.6
- version: 2.1.6(typescript@5.6.2)
+ version: 2.1.6(typescript@5.5.4)
template/config/vitest:
dependencies:
'@vue/compiler-vue2@2.7.16':
resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==}
- '@vue/create-eslint-config@0.3.3':
- resolution: {integrity: sha512-eqy1kH6/0++oiRM5EkYrVaGjArrAJAhztdtKLB9FuKlid25jwUQ6nVMyuFXhxxnxl/ypxnGndMUGpVtYfNUX6w==}
+ '@vue/create-eslint-config@0.4.1':
+ resolution: {integrity: sha512-9AQ37YCSTSqP6vRv9rp9jri9Iv34UJP0WLD+FsVNYjDOxT37533zgOGZk4w3sw0KIAX8gxcgYx+5QFDuNQUhoA==}
engines: {node: ^16.14.0 || >= 18.0.0}
hasBin: true
engines: {node: '>=10'}
hasBin: true
- javascript-stringify@2.1.0:
- resolution: {integrity: sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==}
-
joi@17.13.3:
resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==}
resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==}
engines: {node: '>=8'}
+ typescript@5.5.4:
+ resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
typescript@5.6.2:
resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==}
engines: {node: '>=14.17'}
de-indent: 1.0.2
he: 1.2.0
- '@vue/create-eslint-config@0.3.3':
+ '@vue/create-eslint-config@0.4.1':
dependencies:
+ ejs: 3.1.10
enquirer: 2.4.1
- javascript-stringify: 2.1.0
kolorist: 1.8.0
'@vue/devtools-api@6.6.4': {}
dependencies:
rfdc: 1.4.1
- '@vue/language-core@2.1.6(typescript@5.6.2)':
+ '@vue/language-core@2.1.6(typescript@5.5.4)':
dependencies:
'@volar/language-core': 2.4.2
'@vue/compiler-dom': 3.5.8
muggle-string: 0.4.1
path-browserify: 1.0.1
optionalDependencies:
- typescript: 5.6.2
+ typescript: 5.5.4
'@vue/reactivity@3.5.10':
dependencies:
filelist: 1.0.4
minimatch: 3.1.2
- javascript-stringify@2.1.0: {}
-
joi@17.13.3:
dependencies:
'@hapi/hoek': 9.3.0
type-fest@0.7.1: {}
+ typescript@5.5.4: {}
+
typescript@5.6.2: {}
undici-types@6.19.8: {}
'@vue/devtools-api': 6.6.4
vue: 3.5.10(typescript@5.6.2)
- vue-tsc@2.1.6(typescript@5.6.2):
+ vue-tsc@2.1.6(typescript@5.5.4):
dependencies:
'@volar/typescript': 2.4.2
- '@vue/language-core': 2.1.6(typescript@5.6.2)
+ '@vue/language-core': 2.1.6(typescript@5.5.4)
semver: 7.5.4
- typescript: 5.6.2
+ typescript: 5.5.4
vue@3.5.10(typescript@5.6.2):
dependencies:
+import fs from 'node:fs'
+import path from 'node:path'
import * as esbuild from 'esbuild'
import esbuildPluginLicense from 'esbuild-plugin-license'
})
}
},
+
+ {
+ name: '@vue/create-eslint-config fix',
+ setup(build) {
+ // Update esbuild to support the import attributes syntax in this PR is too risky.
+ // TODO: update esbuild and remove the hack.
+ build.onLoad({ filter: /@vue.create-eslint-config.index.js$/ }, (args) => {
+ const text = fs.readFileSync(args.path, 'utf8')
+ return {
+ contents: text.replace(`with { type: 'json' }`, ''),
+ loader: 'js'
+ }
+ })
+
+ // The renderEjsFile.js module uses file system APIs therefore after bundling it will not work.
+ // So we need to preprocess it to remove the file system APIs.
+ build.onLoad({ filter: /@vue.create-eslint-config.renderEjsFile\.js$/ }, (args) => {
+ const pkgDir = path.dirname(args.path)
+ const templatesDir = path.resolve(pkgDir, './templates')
+
+ const allTemplateFileNames = fs.readdirSync(templatesDir)
+ const templateFiles = Object.fromEntries(
+ allTemplateFileNames.map((fileName) => {
+ const content = fs.readFileSync(path.resolve(templatesDir, fileName), 'utf8')
+ return [`./templates/${fileName}`, content]
+ })
+ )
+
+ return {
+ contents: `
+ import ejs from 'ejs'
+ const templates = ${JSON.stringify(templateFiles)}
+ export default function renderEjsFile(filePath, data) {
+ return ejs.render(templates[filePath], data, {})
+ }
+ `,
+ loader: 'js'
+ }
+ })
+ }
+ },
+
esbuildPluginLicense({
thirdParty: {
includePrivate: false,
"devDependencies": {
"@types/node": "^20.16.10",
"npm-run-all2": "^6.2.3",
- "typescript": "~5.6.0",
+ "typescript": "~5.5.4",
"vue-tsc": "^2.1.6"
}
}
import * as fs from 'node:fs'
import * as path from 'node:path'
-import type { Linter } from 'eslint'
-
import createESLintConfig from '@vue/create-eslint-config'
import sortDependencies from './sortDependencies'
rootDir,
{ needsTypeScript, needsVitest, needsCypress, needsCypressCT, needsPrettier, needsPlaywright }
) {
- const { additionalConfig, additionalDependencies } = getAdditionalConfigAndDependencies({
+ const additionalConfigs = getAdditionalConfigs({
needsVitest,
needsCypress,
needsCypressCT,
})
const { pkg, files } = createESLintConfig({
- vueVersion: '3.x',
- // we currently don't support other style guides
styleGuide: 'default',
hasTypeScript: needsTypeScript,
needsPrettier,
- additionalConfig,
- additionalDependencies
+ additionalConfigs
})
const scripts: Record<string, string> = {
- // Note that we reuse .gitignore here to avoid duplicating the configuration
- lint: needsTypeScript
- ? 'eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore'
- : 'eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore'
+ lint: 'eslint . --fix'
}
// Theoretically, we could add Prettier without requring ESLint.
const packageJsonPath = path.resolve(rootDir, 'package.json')
const existingPkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
const updatedPkg = sortDependencies(deepMerge(deepMerge(existingPkg, pkg), { scripts }))
- fs.writeFileSync(packageJsonPath, JSON.stringify(updatedPkg, null, 2) + '\n', 'utf-8')
+ fs.writeFileSync(packageJsonPath, JSON.stringify(updatedPkg, null, 2) + '\n', 'utf8')
- // write to .eslintrc.cjs, .prettierrc.json, etc.
+ // write to eslint.config.mjs, .prettierrc.json, .editorconfig, etc.
for (const [fileName, content] of Object.entries(files)) {
const fullPath = path.resolve(rootDir, fileName)
- fs.writeFileSync(fullPath, content as string, 'utf-8')
+ fs.writeFileSync(fullPath, content as string, 'utf8')
}
}
+type ConfigItemInESLintTemplate = {
+ importer: string
+ content: string
+}
+type AdditionalConfig = {
+ devDependencies: Record<string, string>
+ beforeVuePlugin?: Array<ConfigItemInESLintTemplate>
+ afterVuePlugin?: Array<ConfigItemInESLintTemplate>
+}
+type AdditionalConfigArray = Array<AdditionalConfig>
+
// visible for testing
-export function getAdditionalConfigAndDependencies({
+export function getAdditionalConfigs({
needsVitest,
needsCypress,
needsCypressCT,
needsPlaywright
}) {
- const additionalConfig: Linter.Config = {}
- const additionalDependencies = {}
+ const additionalConfigs: AdditionalConfigArray = []
if (needsVitest) {
- additionalConfig.overrides = [
- {
- files: ['src/**/*.{test,spec}.{js,ts,jsx,tsx}'],
- extends: ['plugin:@vitest/legacy-recommended']
- }
- ]
-
- additionalDependencies['@vitest/eslint-plugin'] = eslintDeps['@vitest/eslint-plugin']
+ additionalConfigs.push({
+ devDependencies: { '@vitest/eslint-plugin': eslintDeps['@vitest/eslint-plugin'] },
+ afterVuePlugin: [
+ {
+ importer: `import pluginVitest from '@vitest/eslint-plugin'`,
+ content: `
+ {
+ ...pluginVitest.configs['recommended'],
+ files: ['src/**/__tests__/*'],
+ },`
+ }
+ ]
+ })
}
if (needsCypress) {
- additionalConfig.overrides = [
- {
- files: needsCypressCT
- ? [
- '**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}',
- 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}',
- 'cypress/support/**/*.{js,ts,jsx,tsx}'
- ]
- : ['cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}', 'cypress/support/**/*.{js,ts,jsx,tsx}'],
- extends: ['plugin:cypress/recommended']
- }
- ]
-
- additionalDependencies['eslint-plugin-cypress'] = eslintDeps['eslint-plugin-cypress']
+ additionalConfigs.push({
+ devDependencies: { 'eslint-plugin-cypress': eslintDeps['eslint-plugin-cypress'] },
+ afterVuePlugin: [
+ {
+ importer: "import pluginCypress from 'eslint-plugin-cypress/flat'",
+ content: `
+ {
+ ...pluginCypress.configs.recommended,
+ files: [
+ ${[
+ ...(needsCypressCT ? ["'**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}',"] : []),
+ 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}',
+ 'cypress/support/**/*.{js,ts,jsx,tsx}'
+ ]
+ .map(JSON.stringify.bind(JSON))
+ .join(',\n ')}
+ ],
+ },`
+ }
+ ]
+ })
}
if (needsPlaywright) {
- additionalConfig.overrides = [
- {
- files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'],
- extends: ['plugin:playwright/recommended']
- }
- ]
-
- additionalDependencies['eslint-plugin-playwright'] = eslintDeps['eslint-plugin-playwright']
+ additionalConfigs.push({
+ devDependencies: { 'eslint-plugin-playwright': eslintDeps['eslint-plugin-playwright'] },
+ afterVuePlugin: [
+ {
+ importer: "import pluginPlaywright from 'eslint-plugin-playwright'",
+ content: `
+ {
+ ...pluginPlaywright.configs['flat/recommended'],
+ files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'],
+ },`
+ }
+ ]
+ })
}
- return { additionalConfig, additionalDependencies }
+
+ return additionalConfigs
}