Skip to content

chore: use eslint-config-vuetify v4 #74

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
export { default } from 'eslint-config-vuetify/index.ts.mjs'
import vuetify from 'eslint-config-vuetify'

export default vuetify({
vue: true,
perfectionist: {
import: false,
},
}, {
rules: {
'unicorn/no-process-exit': 'off',
},
})
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"@types/validate-npm-package-name": "^4.0.2",
"esbuild": "^0.25.1",
"eslint": "^9.23.0",
"eslint-config-vuetify": "^3.0.3",
"eslint-config-vuetify": "4.0.0",
"nypm": "^0.6.0",
"release-it": "^18.1.2",
"typescript": "^5.8.2"
Expand Down
1,085 changes: 998 additions & 87 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async function bundle () {
}

bundle()
.catch(err => {
console.error(err)
.catch(error => {
console.error(error)
process.exit(1)
})
17 changes: 7 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Node
import { dirname, join, resolve } from 'path'
import { fileURLToPath } from 'url'
import { mkdirSync, rmSync, writeFileSync } from 'fs'
import { dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { mkdirSync, rmSync, writeFileSync } from 'node:fs'

// Types
import type { ContextState } from './utils/prompts'
Expand All @@ -19,7 +19,7 @@ const validPresets = ['base', 'custom', 'default', 'essentials']
async function run () {
const argv = minimist(process.argv.slice(2), {
alias: {
'typescript': ['ts'],
typescript: ['ts'],
},
})

Expand Down Expand Up @@ -50,8 +50,6 @@ async function run () {
usePackageManager,
installDependencies: installDeps,
usePreset,
useStore,
useEslint,
useNuxtV4Compat,
useNuxtModule,
useNuxtSSR,
Expand Down Expand Up @@ -83,8 +81,7 @@ async function run () {
useNuxtSSR,
useNuxtSSRClientHints,
})
}
else {
} else {
// Create project directory
mkdirSync(projectRoot)

Expand Down Expand Up @@ -122,7 +119,7 @@ run()
console.log('Support Vuetify: https://github.com/sponsors/johnleider')
process.exit(0)
})
.catch(err => {
console.error(`\n${red('✖')} ${err}\n`)
.catch(error => {
console.error(`\n${red('✖')} ${error}\n`)
process.exit(1)
})
10 changes: 5 additions & 5 deletions src/utils/deepMerge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ interface DeepMerge {

const isObject: { (key: any): boolean } = (v: unknown): boolean => {
return (
v === Object(v) &&
v !== null &&
!Array.isArray(v)
v === Object(v)
&& v !== null
&& !Array.isArray(v)
)
}

const deepMerge: DeepMerge = <T extends GenericObject[]>(...sources: T): GenericObject =>
sources.reduce((acc, curr) => {
Object.keys(curr).forEach(key => {
for (const key of Object.keys(curr)) {
if (Array.isArray(acc[key]) && Array.isArray(curr[key])) {
acc[key] = Array.from(new Set((acc[key]).concat(curr[key])))
} else if (isObject(acc[key]) && isObject(curr[key])) {
acc[key] = deepMerge(acc[key], curr[key])
} else {
acc[key] = curr[key]
}
})
}

return acc
}, {})
Expand Down
8 changes: 2 additions & 6 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import { installDependencies } from './installDependencies'
import { renderTemplate } from './renderTemplate'
export { installDependencies } from './installDependencies'

export {
installDependencies,
renderTemplate,
}
export { renderTemplate } from './renderTemplate'
2 changes: 1 addition & 1 deletion src/utils/installDependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export async function installDependencies (root: string = process.cwd(), manager
})
.catch(() => {
console.error(
`Failed to install dependencies using ${manager}.`
`Failed to install dependencies using ${manager}.`,
)
})
if (manager === 'pnpm') {
Expand Down
49 changes: 27 additions & 22 deletions src/utils/nuxt/renderNuxtTemplate.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Node
import fs from 'fs'
import path from 'path'
import { spawnSync } from 'child_process'
import fs from 'node:fs'
import path from 'node:path'
import { spawnSync } from 'node:child_process'

// Types
import type { NuxtContext, PackageJsonEntry } from './types'
Expand Down Expand Up @@ -35,14 +35,17 @@ export async function renderNuxtTemplate (ctx: NuxtContext) {
.replace('@latest', () => (isYarn1 ? '' : '@latest'))
.replace(/^npm exec/, () => {
// Prefer `pnpm dlx`, `yarn dlx`, or `bun x`
if (pkgManager === 'pnpm')
if (pkgManager === 'pnpm') {
return 'pnpm dlx'
}

if (pkgManager === 'yarn' && !isYarn1)
if (pkgManager === 'yarn' && !isYarn1) {
return 'yarn dlx'
}

if (pkgManager === 'bun')
if (pkgManager === 'bun') {
return 'bun x'
}

// Use `npm exec` in all other cases,
// including Yarn 1.x and other custom npm clients.
Expand Down Expand Up @@ -87,7 +90,7 @@ function configurePackageJson ({
nuxtPreset,
}: NuxtContext) {
const packageJson = path.join(projectRoot, 'package.json')
const pkg = JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf-8'))
const pkg = JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8'))
pkg.name = projectName

// prepare scripts
Expand All @@ -104,7 +107,7 @@ function configurePackageJson ({
const dependencies: PackageJsonEntry[] = [
['vuetify', versions.vuetify],
]
if (dependencies.length) {
if (dependencies.length > 0) {
addPackageObject('dependencies', dependencies, pkg)
}

Expand All @@ -118,21 +121,20 @@ function configurePackageJson ({
]
if (useNuxtModule) {
devDependencies.push(['vuetify-nuxt-module', versions['vuetify-nuxt-module']])
}
else {
} else {
devDependencies.push(['upath', versions['upath']])
devDependencies.push(['@vuetify/loader-shared', versions['@vuetify/loader-shared']])
devDependencies.push(['vite-plugin-vuetify', versions['vite-plugin-vuetify']])
}
if (devDependencies.length) {
if (devDependencies.length > 0) {
addPackageObject('devDependencies', devDependencies, pkg)
}

// add scripts
addPackageObject('scripts', scripts, pkg, false)

// save package.json
fs.writeFileSync(packageJson, JSON.stringify(pkg, null, 2), 'utf-8')
fs.writeFileSync(packageJson, JSON.stringify(pkg, null, 2), 'utf8')
}

function configureVuetify (ctx: NuxtContext, nuxtConfig: ReturnType<typeof parseModule>) {
Expand Down Expand Up @@ -283,9 +285,11 @@ function prepareNuxtModule (
useBrowserThemeOnly: false,
},
},
styles: ctx.nuxtPreset === 'nuxt-default' ? true : {
configFile: 'assets/settings.scss',
},
styles: ctx.nuxtPreset === 'nuxt-default'
? true
: {
configFile: 'assets/settings.scss',
},
}
configureVuetify(ctx, nuxtConfig)
addNuxtModule(
Expand All @@ -304,9 +308,11 @@ function prepareVuetifyModule (
const config = configureVuetify(ctx, nuxtConfig)

// enable auto import and include styles
const styles = ctx.nuxtPreset !== 'nuxt-essentials' ? true : {
configFile: 'assets/settings.scss',
}
const styles = ctx.nuxtPreset === 'nuxt-essentials'
? {
configFile: 'assets/settings.scss',
}
: true
config.vuetify = { autoImport: true, styles }
}

Expand All @@ -323,13 +329,12 @@ function prepareProject (ctx: NuxtContext) {
// v4 compat: rootPath is `${rootPath}/app`
// https://nuxt.com/docs/getting-started/upgrade#migrating-to-nuxt-4
const nuxtConfigFile = path.join(rootPath, useNuxtV4Compat ? '../nuxt.config.ts' : 'nuxt.config.ts')
const nuxtConfig = parseModule(fs.readFileSync(nuxtConfigFile, 'utf-8'))
const nuxtConfig = parseModule(fs.readFileSync(nuxtConfigFile, 'utf8'))

// prepare nuxt config
if (useNuxtModule) {
prepareNuxtModule(ctx, nuxtConfig)
}
else {
} else {
prepareVuetifyModule(ctx, nuxtConfig)
}

Expand Down Expand Up @@ -368,7 +373,7 @@ function prepareProject (ctx: NuxtContext) {
fs.writeFileSync(
nuxtConfigFile,
code,
'utf-8',
'utf8',
)

// prepare resources
Expand Down
26 changes: 14 additions & 12 deletions src/utils/nuxt/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Node
import process from 'process'
import path from 'path'
import { spawnSync } from 'child_process'
import fs from 'fs'
import process from 'node:process'
import path from 'node:path'
import { spawnSync } from 'node:child_process'
import fs from 'node:fs'

// Types
import type { PackageJsonEntry } from './types'
Expand All @@ -13,8 +13,9 @@ import { resolveCommand } from 'package-manager-detector/commands'

export function detectPkgInfo () {
const userAgent = process.env.npm_config_user_agent
if (!userAgent)
if (!userAgent) {
return undefined
}
const pkgSpec = userAgent.split(' ')[0]
const pkgSpecArr = pkgSpec.split('/')
return {
Expand All @@ -31,20 +32,21 @@ export function addPackageObject (
) {
pkg[key] ??= {}
if (!sort) {
for (const [name, value] of entry)
for (const [name, value] of entry) {
pkg[key][name] = value
}

return
}

const entries = Object.entries(pkg[key])
pkg[key] = {}
entry.forEach(([name, value]) => {
for (const [name, value] of entry) {
entries.push([name, value])
})
entries.sort(([a], [b]) => a.localeCompare(b)).forEach(([k, v]) => {
}
for (const [k, v] of entries.sort(([a], [b]) => a.localeCompare(b))) {
pkg[key][k] = v
})
}
}

export function runCommand (
Expand Down Expand Up @@ -77,8 +79,8 @@ export function runCommand (
}

export function editFile (file: string, callback: (content: string) => string, destination?: string) {
const content = fs.readFileSync(file, 'utf-8')
fs.writeFileSync(destination ?? file, callback(content), 'utf-8')
const content = fs.readFileSync(file, 'utf8')
fs.writeFileSync(destination ?? file, callback(content), 'utf8')
}

export function getPaths (
Expand Down
35 changes: 18 additions & 17 deletions src/utils/prompts.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Node
import { join, resolve } from 'path'
import { existsSync, readdirSync } from 'fs'
import { join, resolve } from 'node:path'
import { existsSync, readdirSync } from 'node:fs'

// Types
import type { Options as PromptOptions } from 'prompts'
Expand All @@ -13,15 +13,15 @@ import { packageManager as defaultPackageManager } from './installDependencies'
import validate from 'validate-npm-package-name'

type ContextState = {
cwd: string,
projectName?: string,
canOverwrite?: boolean,
useTypeScript?: boolean,
usePackageManager?: 'npm' | 'pnpm' | 'yarn' | 'bun',
installDependencies?: boolean,
cwd: string
projectName?: string
canOverwrite?: boolean
useTypeScript?: boolean
usePackageManager?: 'npm' | 'pnpm' | 'yarn' | 'bun'
installDependencies?: boolean
usePreset?: 'base' | 'default' | 'essentials' | 'nuxt-base' | 'nuxt-default' | 'nuxt-essentials'
useEslint?: boolean,
useRouter?: boolean,
useEslint?: boolean
useRouter?: boolean
useStore?: boolean
useNuxtV4Compat?: boolean
useNuxtModule?: boolean
Expand All @@ -38,8 +38,7 @@ const promptOptions: PromptOptions = {
type DefinedContextState = { [P in keyof ContextState]-?: ContextState[P] }

const initPrompts = async (context: ContextState) => {

let answers: prompts.Answers<
type Answers = prompts.Answers<
'projectName' | 'canOverwrite' | 'usePreset' | 'useTypeScript' | 'usePackageManager' | 'installDependencies' | 'useNuxtV4Compat' | 'useNuxtModule' | 'useNuxtSSR' | 'useNuxtSSRClientHints'
>

Expand All @@ -50,7 +49,7 @@ const initPrompts = async (context: ContextState) => {
}
}

answers = await prompts([
const answers: Answers = await prompts([
{
name: 'projectName',
type: 'text',
Expand All @@ -60,7 +59,7 @@ const initPrompts = async (context: ContextState) => {
validate: (v: string) => {
const { errors, warnings, validForNewPackages: isValid } = validate(String(v).trim())

const error = isValid ? null : errors ? errors[0] : warnings![0]
const error = isValid ? null : (errors ? errors[0] : warnings![0])

if (!isValid) {
return `Package ${error}`
Expand All @@ -77,9 +76,11 @@ const initPrompts = async (context: ContextState) => {
const projectPath = join(context.cwd, projectName)

return (
!existsSync(projectPath) ||
readdirSync(projectPath).length === 0
) ? null : 'toggle'
!existsSync(projectPath)
|| readdirSync(projectPath).length === 0
)
? null
: 'toggle'
},
onState (a) {
if (!a.value) {
Expand Down
Loading