diff --git a/e2e/docs/.vuepress/components/OnContentUpdated.vue b/e2e/docs/.vuepress/components/OnContentUpdated.vue index 200a1acf58..9fdfd1d07c 100644 --- a/e2e/docs/.vuepress/components/OnContentUpdated.vue +++ b/e2e/docs/.vuepress/components/OnContentUpdated.vue @@ -17,16 +17,19 @@ watch(routePath, () => { const callback: ContentUpdatedCallback = (reason) => { switch (reason) { - case 'mounted': + case 'mounted': { mounted.value = routePath.value mountedCount.value++ break - case 'updated': + } + case 'updated': { updatedCount.value++ break - case 'beforeUnmount': + } + case 'beforeUnmount': { beforeUnmount.value = routePath.value break + } default: } } diff --git a/eslint.config.ts b/eslint.config.ts index f07fc42e63..9e625186a7 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -14,6 +14,8 @@ export default vuepress( typescript: { overrides: { '@typescript-eslint/no-useless-default-assignment': 'off', // TODO: crash + // we may need to mark some sync function as async + '@typescript-eslint/require-await': 'off', }, }, javascript: { diff --git a/packages/bundler-vite/src/build/renderPagePreloadLinks.ts b/packages/bundler-vite/src/build/renderPagePreloadLinks.ts index 06b481c7fd..8479587b2f 100644 --- a/packages/bundler-vite/src/build/renderPagePreloadLinks.ts +++ b/packages/bundler-vite/src/build/renderPagePreloadLinks.ts @@ -54,7 +54,7 @@ export const renderPagePreloadLinks = ({ } return `` }) .join('') diff --git a/packages/bundler-vite/src/plugins/vuepressConfigPlugin.ts b/packages/bundler-vite/src/plugins/vuepressConfigPlugin.ts index e12ac90922..f047524b02 100644 --- a/packages/bundler-vite/src/plugins/vuepressConfigPlugin.ts +++ b/packages/bundler-vite/src/plugins/vuepressConfigPlugin.ts @@ -28,15 +28,15 @@ const resolveAlias = async ({ Object.assign(alias, aliasObject) }) - return [ - ...Object.keys(alias) + return ( + Object.keys(alias) // sort alias by length in descending order to ensure longer alias is handled first .sort((a, b) => b.length - a.length) .map((item) => ({ find: item, replacement: alias[item], - })), - ] + })) + ) } /** diff --git a/packages/bundler-webpack/src/build/createClientConfig.ts b/packages/bundler-webpack/src/build/createClientConfig.ts index 4e72761df9..89ea8b81f4 100644 --- a/packages/bundler-webpack/src/build/createClientConfig.ts +++ b/packages/bundler-webpack/src/build/createClientConfig.ts @@ -54,7 +54,7 @@ export const createClientConfig = async ( styles: { idHint: 'styles', // necessary to ensure async chunks are also extracted - test: (m: Module) => m.type.includes('css/mini-extract'), + test: (module: Module) => module.type.includes('css/mini-extract'), chunks: 'all', enforce: true, reuseExistingChunk: true, diff --git a/packages/bundler-webpack/src/build/createClientPlugin.ts b/packages/bundler-webpack/src/build/createClientPlugin.ts index b375d4134c..7242d4b270 100644 --- a/packages/bundler-webpack/src/build/createClientPlugin.ts +++ b/packages/bundler-webpack/src/build/createClientPlugin.ts @@ -47,8 +47,10 @@ export const createClientPlugin = ( // get asset modules const assetModules = modules.filter( - (m): m is Required> & StatsModule => - Boolean(m.assets?.length), + ( + module, + ): module is Required> & StatsModule => + Boolean(module.assets?.length), ) // get modules for client manifest @@ -57,14 +59,14 @@ export const createClientPlugin = ( const fileToIndex = (file: number | string): number => allFiles.indexOf(file.toString()) - modules.forEach((m) => { + modules.forEach((module) => { // ignore modules duplicated in multiple chunks - if (m.chunks?.length !== 1) { + if (module.chunks?.length !== 1) { return } - const cid = m.chunks[0] - const chunk = chunks.find((c) => c.id === cid) + const cid = module.chunks[0] + const chunk = chunks.find(({ id }) => id === cid) if (!chunk?.files) { return @@ -72,10 +74,10 @@ export const createClientPlugin = ( // remove appended hash of module identifier // which is the request string of the module - const request = m.identifier?.replace(/\|\w+$/, '') + const request = module.identifier?.replace(/\|\w+$/, '') // get chunk files index - const files = [...chunk.files.map(fileToIndex)] + const files = chunk.files.map(fileToIndex) // find all asset modules associated with the same chunk assetModules.forEach((item) => { diff --git a/packages/bundler-webpack/src/build/renderPagePrefetchLinks.ts b/packages/bundler-webpack/src/build/renderPagePrefetchLinks.ts index 875013c598..71eeba8cbe 100644 --- a/packages/bundler-webpack/src/build/renderPagePrefetchLinks.ts +++ b/packages/bundler-webpack/src/build/renderPagePrefetchLinks.ts @@ -23,7 +23,7 @@ export const renderPagePrefetchLinks = ({ // async files excluding files used by current page should be prefetch const prefetchFilesMeta = asyncFilesMeta.filter( - ({ file }) => !pageClientFilesMeta.some((f) => f.file === file), + ({ file }) => !pageClientFilesMeta.some((meta) => meta.file === file), ) return prefetchFilesMeta diff --git a/packages/bundler-webpack/src/build/renderPagePreloadLinks.ts b/packages/bundler-webpack/src/build/renderPagePreloadLinks.ts index 5dbec08f0c..91796f20e8 100644 --- a/packages/bundler-webpack/src/build/renderPagePreloadLinks.ts +++ b/packages/bundler-webpack/src/build/renderPagePreloadLinks.ts @@ -37,7 +37,7 @@ export const renderPagePreloadLinks = ({ } return `` }) .join('') diff --git a/packages/cli/src/commands/dev/watchPageFiles.ts b/packages/cli/src/commands/dev/watchPageFiles.ts index 587691c063..1d6b3bd4bc 100644 --- a/packages/cli/src/commands/dev/watchPageFiles.ts +++ b/packages/cli/src/commands/dev/watchPageFiles.ts @@ -2,7 +2,7 @@ import type { App, Page } from '@vuepress/core' import { colors, logger, path, picomatch } from '@vuepress/utils' import type { FSWatcher } from 'chokidar' -import chokidar from 'chokidar' +import { watch } from 'chokidar' import { handlePageAdd } from './handlePageAdd.js' import { handlePageChange } from './handlePageChange.js' import { handlePageUnlink } from './handlePageUnlink.js' @@ -13,7 +13,7 @@ import { createPageDepsHelper } from './pageDepsHelper.js' */ export const watchPageFiles = (app: App): FSWatcher[] => { // watch page deps - const depsWatcher = chokidar.watch([], { + const depsWatcher = watch([], { ignoreInitial: true, }) const depsHelper = createPageDepsHelper() @@ -56,7 +56,7 @@ export const watchPageFiles = (app: App): FSWatcher[] => { const cacheDir = app.dir.cache() const ignoreMatcher = picomatch(ignorePatterns, { cwd: sourceDir }) const pageMatcher = picomatch(pagePatterns, { cwd: sourceDir }) - const pagesWatcher = chokidar.watch('.', { + const pagesWatcher = watch('.', { cwd: sourceDir, ignored: (filepath, stats) => { // This is important so that folders like node_modules will be ignored immediately without traversing their children diff --git a/packages/cli/src/commands/dev/watchUserConfigFile.ts b/packages/cli/src/commands/dev/watchUserConfigFile.ts index fa11200698..ff8c402890 100644 --- a/packages/cli/src/commands/dev/watchUserConfigFile.ts +++ b/packages/cli/src/commands/dev/watchUserConfigFile.ts @@ -1,7 +1,7 @@ import process from 'node:process' import { colors, logger } from '@vuepress/utils' import type { FSWatcher } from 'chokidar' -import chokidar from 'chokidar' +import { watch } from 'chokidar' export const watchUserConfigFile = ({ userConfigPath, @@ -14,7 +14,7 @@ export const watchUserConfigFile = ({ }): FSWatcher[] => { const cwd = process.cwd() - const configWatcher = chokidar.watch(userConfigPath, { + const configWatcher = watch(userConfigPath, { cwd, ignoreInitial: true, }) @@ -23,7 +23,7 @@ export const watchUserConfigFile = ({ void restart() }) - const depsWatcher = chokidar.watch(userConfigDependencies, { + const depsWatcher = watch(userConfigDependencies, { cwd, ignoreInitial: true, }) diff --git a/packages/client/src/components/Content.ts b/packages/client/src/components/Content.ts index 24bb5695e2..6937d59a72 100644 --- a/packages/client/src/components/Content.ts +++ b/packages/client/src/components/Content.ts @@ -33,7 +33,7 @@ export const Content = defineComponent({ if (!props.path) return pageComponent.value const route = resolveRoute(props.path) return defineAsyncComponent(async () => - route.loader().then((m) => m.default), + route.loader().then((module) => module.default), ) }) diff --git a/packages/client/src/components/RouteLink.ts b/packages/client/src/components/RouteLink.ts index ffff10e430..6e4cc0290f 100644 --- a/packages/client/src/components/RouteLink.ts +++ b/packages/client/src/components/RouteLink.ts @@ -92,7 +92,7 @@ export const RouteLink = defineComponent({ const path = computed(() => props.to.startsWith('#') || props.to.startsWith('?') ? props.to - : `${__VUEPRESS_BASE__}${resolveRouteFullPath(props.to, route.path).substring(1)}`, + : `${__VUEPRESS_BASE__}${resolveRouteFullPath(props.to, route.path).slice(1)}`, ) return () => @@ -103,7 +103,9 @@ export const RouteLink = defineComponent({ href: path.value, onClick: (event: MouseEvent = {} as MouseEvent) => { if (guardEvent(event)) { - void router.push(props.to).catch() + void router.push(props.to).catch(() => { + // ignore error here + }) } }, }, diff --git a/packages/client/src/setupGlobalComputed.ts b/packages/client/src/setupGlobalComputed.ts index 2c2504f932..74607cca24 100644 --- a/packages/client/src/setupGlobalComputed.ts +++ b/packages/client/src/setupGlobalComputed.ts @@ -51,8 +51,7 @@ export const setupGlobalComputed = ( default: oldPageChunk.default, _pageData: newPageData, } - routes.value[newPageData.path].loader = async () => - Promise.resolve(newPageChunk) + routes.value[newPageData.path].loader = async () => newPageChunk if ( newPageData.path === router.currentRoute.value.meta._pageChunk?._pageData.path diff --git a/packages/client/src/setupUpdateHead.ts b/packages/client/src/setupUpdateHead.ts index 2ad189ae52..fed6b101d1 100644 --- a/packages/client/src/setupUpdateHead.ts +++ b/packages/client/src/setupUpdateHead.ts @@ -33,7 +33,7 @@ export const queryHeadElement = ([ document.querySelectorAll(selector), ) const matchedHeadElement = headElements.find( - (item) => item.innerText === content, + (item) => item.textContent === content, ) return matchedHeadElement ?? null } @@ -66,7 +66,7 @@ export const createHeadElement = ([ // set content if (isString(content)) { - headElement.appendChild(document.createTextNode(content)) + headElement.append(document.createTextNode(content)) } return headElement @@ -145,7 +145,9 @@ export const setupUpdateHead = (): void => { } }) // append the rest new elements to head - newHeadElements.forEach((el) => document.head.appendChild(el)) + newHeadElements.forEach((el) => { + document.head.append(el) + }) // update managed head elements managedHeadElements = [ // filter out empty deleted items diff --git a/packages/core/src/app/resolveAppWriteTemp.ts b/packages/core/src/app/resolveAppWriteTemp.ts index 1a5648b36a..f7caa76940 100644 --- a/packages/core/src/app/resolveAppWriteTemp.ts +++ b/packages/core/src/app/resolveAppWriteTemp.ts @@ -30,20 +30,20 @@ export const resolveAppWriteTemp = (dir: AppDir): AppWriteTemp => { item.hash = contentHash - if (!item.current) { - item.current = (async () => { - await fs.outputFile(filePath, content) - // if there is a next writing promise, chain it with the current one - item.current = item.next?.() - return item.current - })() - } else { + if (item.current) { // if there is a current writing promise, save the next writing promise item.next = async () => { await fs.outputFile(filePath, content) item.next = undefined item.current = undefined } + } else { + item.current = (async () => { + await fs.outputFile(filePath, content) + // if there is a next writing promise, chain it with the current one + item.current = item.next?.() + return item.current + })() } await item.current return filePath diff --git a/packages/core/src/page/resolvePageContent.ts b/packages/core/src/page/resolvePageContent.ts index 51a1aa3ab2..a83fe450f6 100644 --- a/packages/core/src/page/resolvePageContent.ts +++ b/packages/core/src/page/resolvePageContent.ts @@ -29,8 +29,8 @@ export const resolvePageContent = async ({ try { const content = await fs.readFile(filePath, 'utf-8') return content - } catch (e) { - log(e instanceof Error ? e.message : e) + } catch (err) { + log(err instanceof Error ? err.message : err) } } diff --git a/packages/core/src/pluginApi/createHookQueue.ts b/packages/core/src/pluginApi/createHookQueue.ts index 9fb70cc9ad..cc2001c91d 100644 --- a/packages/core/src/pluginApi/createHookQueue.ts +++ b/packages/core/src/pluginApi/createHookQueue.ts @@ -43,13 +43,13 @@ export const createHookQueue = (name: T): HookQueue => { if (result !== undefined) { results.push(result) } - } catch (e) { + } catch (err) { logger.error( `error in hook ${colors.magenta(name)} from ${colors.magenta( item.pluginName, )}`, ) - throw e + throw err } } diff --git a/packages/core/src/pluginApi/createPluginApiRegisterHooks.ts b/packages/core/src/pluginApi/createPluginApiRegisterHooks.ts index 333e40174f..40ea54280c 100644 --- a/packages/core/src/pluginApi/createPluginApiRegisterHooks.ts +++ b/packages/core/src/pluginApi/createPluginApiRegisterHooks.ts @@ -16,8 +16,6 @@ export const createPluginApiRegisterHooks = plugins.forEach( ({ name: pluginName, - multiple, - alias, define, clientConfigFile, diff --git a/packages/core/src/types/app/options.ts b/packages/core/src/types/app/options.ts index 74a11478f6..cf6a294139 100644 --- a/packages/core/src/types/app/options.ts +++ b/packages/core/src/types/app/options.ts @@ -13,8 +13,6 @@ export interface AppConfigCommon extends Partial { * Source directory of the markdown files. * * Vuepress will load markdown files from this directory. - * - * @required */ source: string @@ -84,15 +82,11 @@ export interface AppConfigCommon extends Partial { /** * Vuepress bundler - * - * @required */ bundler: Bundler /** * Vuepress theme - * - * @required */ theme: Theme diff --git a/packages/core/src/types/pluginApi/hooks.ts b/packages/core/src/types/pluginApi/hooks.ts index 71d1f4a17e..2e602ce6e3 100644 --- a/packages/core/src/types/pluginApi/hooks.ts +++ b/packages/core/src/types/pluginApi/hooks.ts @@ -14,10 +14,10 @@ export interface Hook< Exposed, Normalized = Exposed, // eslint-disable-next-line @typescript-eslint/no-explicit-any -- `any` type is required to infer the result type correctly - Result = Normalized extends (...args: any) => infer U - ? U extends Promise - ? V - : U + Result = Normalized extends (...args: any) => infer Return + ? Return extends Promise + ? Value + : Return : never, > { exposed: Exposed @@ -85,21 +85,21 @@ export type HooksName = keyof Hooks * Exposed hooks API that can be accessed by a plugin */ export type HooksExposed = { - [K in HooksName]: Hooks[K]['exposed'] + [Key in HooksName]: Hooks[Key]['exposed'] } /** * Normalized hooks */ export type HooksNormalized = { - [K in HooksName]: Hooks[K]['normalized'] + [Key in HooksName]: Hooks[Key]['normalized'] } /** * Result of hooks */ export type HooksResult = { - [K in HooksName]: Hooks[K]['result'] + [Key in HooksName]: Hooks[Key]['result'] } /** diff --git a/packages/core/src/types/pluginApi/pluginApi.ts b/packages/core/src/types/pluginApi/pluginApi.ts index b11c71773e..60356573b1 100644 --- a/packages/core/src/types/pluginApi/pluginApi.ts +++ b/packages/core/src/types/pluginApi/pluginApi.ts @@ -14,7 +14,7 @@ export interface PluginApi { * All available hooks */ hooks: { - [K in HooksName]: HookQueue + [Key in HooksName]: HookQueue } /** diff --git a/packages/core/tests/app/createBuildApp.spec.ts b/packages/core/tests/app/createBuildApp.spec.ts index 4ddca78046..27b7bb8b6b 100644 --- a/packages/core/tests/app/createBuildApp.spec.ts +++ b/packages/core/tests/app/createBuildApp.spec.ts @@ -1,4 +1,4 @@ -import { expect, it } from 'vitest' +import { expect, expectTypeOf, it } from 'vitest' import type { App, BuildApp, Bundler } from '../../src/index.js' import { createBuildApp } from '../../src/index.js' @@ -8,7 +8,7 @@ it('should create build app correctly', () => { expect((app as unknown as { dev: never }).dev).toBeUndefined() expect(app.env.isBuild).toBe(true) - expect(typeof (app as BuildApp).build).toBe('function') + expectTypeOf((app as BuildApp).build).toBeFunction() } const buildApp = createBuildApp({ diff --git a/packages/core/tests/app/createDevApp.spec.ts b/packages/core/tests/app/createDevApp.spec.ts index a932ddf3b6..81d3166d42 100644 --- a/packages/core/tests/app/createDevApp.spec.ts +++ b/packages/core/tests/app/createDevApp.spec.ts @@ -1,11 +1,11 @@ -import { expect, it } from 'vitest' +import { expect, expectTypeOf, it } from 'vitest' import type { App, Bundler, DevApp } from '../../src/index.js' import { createDevApp } from '../../src/index.js' it('should create dev app correctly', () => { const checkApp = (app: App): void => { expect(app.env.isDev).toBe(true) - expect(typeof (app as DevApp).dev).toBe('function') + expectTypeOf((app as DevApp).dev).toBeFunction() expect(app.env.isBuild).toBe(false) expect((app as unknown as { build: never }).build).toBeUndefined() diff --git a/packages/core/tests/app/resolveAppWriteTemp.spec.ts b/packages/core/tests/app/resolveAppWriteTemp.spec.ts index 299084c90b..4acecbf4f8 100644 --- a/packages/core/tests/app/resolveAppWriteTemp.spec.ts +++ b/packages/core/tests/app/resolveAppWriteTemp.spec.ts @@ -4,7 +4,7 @@ import { createAppDirFunction } from '../../src/app/resolveAppDir.js' import { resolveAppWriteTemp } from '../../src/app/resolveAppWriteTemp.js' import type { AppDir } from '../../src/index.js' -vi.mock('@vuepress/utils', async (importOriginal) => { +vi.mock(import('@vuepress/utils'), async (importOriginal) => { // eslint-disable-next-line @typescript-eslint/consistent-type-imports const actual = await importOriginal() return { @@ -16,7 +16,7 @@ vi.mock('@vuepress/utils', async (importOriginal) => { } }) -describe('resolveAppWriteTemp', () => { +describe(resolveAppWriteTemp, () => { const dir = { temp: createAppDirFunction('/temp'), } as AppDir diff --git a/packages/core/tests/page/renderPageToVue.spec.ts b/packages/core/tests/page/renderPageToVue.spec.ts index f5823d3901..6193f0b843 100644 --- a/packages/core/tests/page/renderPageToVue.spec.ts +++ b/packages/core/tests/page/renderPageToVue.spec.ts @@ -40,7 +40,7 @@ const createTestPage = (partial: Partial = {}): Page => ...partial, }) as Page -describe('renderPageToVue', () => { +describe(renderPageToVue, () => { it('should render basic page with template and no script block', () => { const app = createTestApp() const page = createTestPage() diff --git a/packages/core/tests/page/resolvePageContent.spec.ts b/packages/core/tests/page/resolvePageContent.spec.ts index f7a22b50b4..0ce821dbee 100644 --- a/packages/core/tests/page/resolvePageContent.spec.ts +++ b/packages/core/tests/page/resolvePageContent.spec.ts @@ -49,7 +49,7 @@ it('should throw error if the file does not exist', async () => { filePath: '404', options: {}, }) - } catch (e) { - expect(e).not.toBeUndefined() + } catch (err) { + expect(err).not.toBeUndefined() } }) diff --git a/packages/core/tests/pluginApi/createHookQueue.spec.ts b/packages/core/tests/pluginApi/createHookQueue.spec.ts index 3a230e3f2f..b436b88c88 100644 --- a/packages/core/tests/pluginApi/createHookQueue.spec.ts +++ b/packages/core/tests/pluginApi/createHookQueue.spec.ts @@ -271,8 +271,8 @@ describe('client config file hook', () => { hookNames.forEach((hookName) => { it(hookName, async () => { const hook = createHookQueue(hookName) - const func1 = vi.fn(async () => Promise.resolve(file1)) - const func2 = vi.fn(async () => Promise.resolve(file2)) + const func1 = vi.fn(async () => file1) + const func2 = vi.fn(async () => file2) hook.add({ pluginName: 'test1', hook: func1, @@ -298,8 +298,8 @@ describe('bundler hooks', () => { hookNames.forEach((hookName) => { it(hookName, async () => { const hook = createHookQueue(hookName) - const func1 = vi.fn(async () => Promise.resolve({ foo: 'foo' })) - const func2 = vi.fn(async () => Promise.resolve({ bar: 'bar' })) + const func1 = vi.fn(async () => ({ foo: 'foo' })) + const func2 = vi.fn(async () => ({ bar: 'bar' })) hook.add({ pluginName: 'test1', hook: func1, diff --git a/packages/markdown/src/plugins/assetsPlugin/assetsPlugin.ts b/packages/markdown/src/plugins/assetsPlugin/assetsPlugin.ts index 7f919bd1e5..587cece418 100644 --- a/packages/markdown/src/plugins/assetsPlugin/assetsPlugin.ts +++ b/packages/markdown/src/plugins/assetsPlugin/assetsPlugin.ts @@ -40,7 +40,7 @@ export const assetsPlugin: PluginWithOptions = ( // replace the original link with resolved link tokens[idx].content = tokens[idx].content // handle src - .replace( + .replaceAll( /( `${prefix}${quote}${resolveLink(src.trim(), { @@ -49,7 +49,7 @@ export const assetsPlugin: PluginWithOptions = ( })}${quote}`, ) // handle srcset - .replace( + .replaceAll( /( `${prefix}${quote}${srcset @@ -61,7 +61,7 @@ export const assetsPlugin: PluginWithOptions = ( `${resolveLink(url.trim(), { env, absolutePathPrependBase, - })}${descriptor.replace(/[ \n]+/g, ' ').trimEnd()}`, + })}${descriptor.replaceAll(/[ \n]+/g, ' ').trimEnd()}`, ), ) .join(', ')}${quote}`, diff --git a/packages/markdown/tests/plugins/assetsPlugin.spec.ts b/packages/markdown/tests/plugins/assetsPlugin.spec.ts index e2780c2e51..72350dc316 100644 --- a/packages/markdown/tests/plugins/assetsPlugin.spec.ts +++ b/packages/markdown/tests/plugins/assetsPlugin.spec.ts @@ -545,8 +545,10 @@ describe('html tag', () => { `${expected.map((item) => item).join('\n')}\n`, ) // single quote - expect(md.render(source.join('\n\n').replace(/"/g, "'"), env)).toEqual( - `${expected.map((item) => item.replace(/"/g, "'")).join('\n')}\n`, + expect( + md.render(source.join('\n\n').replaceAll('"', "'"), env), + ).toEqual( + `${expected.map((item) => item.replaceAll('"', "'")).join('\n')}\n`, ) }) }) diff --git a/packages/shared/src/utils/omit.ts b/packages/shared/src/utils/omit.ts index ce9febaba6..8f3d25be17 100644 --- a/packages/shared/src/utils/omit.ts +++ b/packages/shared/src/utils/omit.ts @@ -1,10 +1,10 @@ /** * Omit properties from an object */ -export const omit = , U extends string[]>( +export const omit = , Keys extends string[]>( obj: T, - ...keys: U -): Omit => { + ...keys: Keys +): Omit => { const result = { ...obj } for (const key of keys) { delete result[key] diff --git a/packages/shared/src/utils/resolveHeadIdentifier.ts b/packages/shared/src/utils/resolveHeadIdentifier.ts index 2160862fd6..23a0a00410 100644 --- a/packages/shared/src/utils/resolveHeadIdentifier.ts +++ b/packages/shared/src/utils/resolveHeadIdentifier.ts @@ -1,7 +1,14 @@ import type { HeadConfig } from '../types/index.js' -const TAGS_ALLOWED = ['link', 'meta', 'script', 'style', 'noscript', 'template'] -const TAGS_UNIQUE = ['title', 'base'] +const TAGS_ALLOWED = new Set([ + 'link', + 'meta', + 'script', + 'style', + 'noscript', + 'template', +]) +const TAGS_UNIQUE = new Set(['title', 'base']) /** * Resolve identifier of a tag, to avoid duplicated tags in `` @@ -10,12 +17,12 @@ export const resolveHeadIdentifier = ([tag, attrs, content]: HeadConfig): | string | null => { // avoid duplicated unique tags - if (TAGS_UNIQUE.includes(tag)) { + if (TAGS_UNIQUE.has(tag)) { return tag } // avoid disallowed tags - if (!TAGS_ALLOWED.includes(tag)) { + if (!TAGS_ALLOWED.has(tag)) { return null } diff --git a/packages/shared/src/utils/routes/inferRoutePath.ts b/packages/shared/src/utils/routes/inferRoutePath.ts index 803cef50bf..fab227621f 100644 --- a/packages/shared/src/utils/routes/inferRoutePath.ts +++ b/packages/shared/src/utils/routes/inferRoutePath.ts @@ -10,7 +10,7 @@ export const inferRoutePath = (rawPath: string): string => { // convert /foo/bar.md to /foo/bar.html if (routePath.endsWith('.md')) { - routePath = `${routePath.substring(0, routePath.length - 3)}.html` + routePath = `${routePath.slice(0, -3)}.html` } // convert /foo/bar to /foo/bar.html else if (!routePath.endsWith('.html')) { @@ -19,7 +19,7 @@ export const inferRoutePath = (rawPath: string): string => { // convert /foo/index.html to /foo/ if (routePath.endsWith('/index.html')) { - routePath = routePath.substring(0, routePath.length - 10) + routePath = routePath.slice(0, -10) } return routePath diff --git a/packages/shared/tests/typeGuards.spec.ts b/packages/shared/tests/typeGuards.spec.ts index 21080f78a1..39b1e76fcf 100644 --- a/packages/shared/tests/typeGuards.spec.ts +++ b/packages/shared/tests/typeGuards.spec.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest' import { isPlainObject } from '../src/index.js' -describe('isPlainObject', () => { +describe(isPlainObject, () => { const TEST_CASES: [unknown, boolean][] = [ [true, false], [false, false], diff --git a/packages/utils/src/console/withSpinner.ts b/packages/utils/src/console/withSpinner.ts index fee698e911..21c6ac9155 100644 --- a/packages/utils/src/console/withSpinner.ts +++ b/packages/utils/src/console/withSpinner.ts @@ -17,8 +17,8 @@ export const withSpinner = const result = await target(spinner) spinner.succeed(`${msg} - done in ${formatMs(Date.now() - start)}`) return result - } catch (e) { + } catch (err) { spinner.fail(`${msg} - failed in ${formatMs(Date.now() - start)}`) - throw e + throw err } } diff --git a/packages/utils/src/module/importFile.ts b/packages/utils/src/module/importFile.ts index f4682c8000..94d895300f 100644 --- a/packages/utils/src/module/importFile.ts +++ b/packages/utils/src/module/importFile.ts @@ -12,4 +12,4 @@ export const importFile = async (filePath: string): Promise => * A wrapper of `importFile` and returns the default export */ export const importFileDefault = async (filePath: string): Promise => - importFile<{ default: T }>(filePath).then((m) => m.default) + importFile<{ default: T }>(filePath).then((module) => module.default) diff --git a/packages/utils/src/module/sanitizeFileName.ts b/packages/utils/src/module/sanitizeFileName.ts index aac43959d1..335dc5ae24 100644 --- a/packages/utils/src/module/sanitizeFileName.ts +++ b/packages/utils/src/module/sanitizeFileName.ts @@ -6,7 +6,7 @@ const INVALID_CHAR_REGEX = /[\u0000-\u001F"#$%&*+,:;<=>?[\]^`{|}\u007F]/g const DRIVE_LETTER_REGEX = /^[a-z]:/i export const sanitizeFileName = (name: string): string => { - const driveLetter = DRIVE_LETTER_REGEX.exec(name)?.[0] || '' + const driveLetter = DRIVE_LETTER_REGEX.exec(name)?.[0] ?? '' // A `:` is only allowed as part of a windows drive letter (ex: C:\foo) // Otherwise, avoid them because they can refer to NTFS alternate data streams. diff --git a/packages/utils/src/module/transformPathToFileName.ts b/packages/utils/src/module/transformPathToFileName.ts index 32bec8e79e..15a2aaadf0 100644 --- a/packages/utils/src/module/transformPathToFileName.ts +++ b/packages/utils/src/module/transformPathToFileName.ts @@ -4,4 +4,4 @@ import { sanitizeFileName } from './sanitizeFileName.js' * Transforms a path to a file name, replacing slashes with underscores */ export const transformPathToFileName = (rawPath: string): string => - sanitizeFileName(rawPath.replace(/\//g, '_')) + sanitizeFileName(rawPath.replaceAll('/', '_')) diff --git a/packages/utils/tests/console/withSpinner.spec.ts b/packages/utils/tests/console/withSpinner.spec.ts index eb45e6353e..e03b2beee3 100644 --- a/packages/utils/tests/console/withSpinner.spec.ts +++ b/packages/utils/tests/console/withSpinner.spec.ts @@ -20,7 +20,7 @@ const mocks = vi.hoisted(() => { } }) -vi.mock('ora', () => ({ +vi.mock(import('ora'), () => ({ default: mocks.ora, })) diff --git a/packages/utils/tests/module/isChildPath.spec.ts b/packages/utils/tests/module/isChildPath.spec.ts index 4f1801c430..f48dde2d0c 100644 --- a/packages/utils/tests/module/isChildPath.spec.ts +++ b/packages/utils/tests/module/isChildPath.spec.ts @@ -8,12 +8,12 @@ const TEST_CASES: [[string, string], boolean][] = [ [['/foo/bar', '/foo'], true], [['/foo', '/foo-bar'], false], [['/foo-bar', '/foo'], false], - [['C:\\foo', 'C:\\foo'], true], - [['C:\\foo', 'C:\\bar'], false], - [['C:\\foo', 'C:\\foo\\bar'], false], - [['C:\\foo\\bar', 'C:\\foo'], true], - [['C:\\foo', 'C:\\foo-bar'], false], - [['C:\\foo-bar', 'C:\\foo'], false], + [[String.raw`C:\foo`, String.raw`C:\foo`], true], + [[String.raw`C:\foo`, String.raw`C:\bar`], false], + [[String.raw`C:\foo`, String.raw`C:\foo\bar`], false], + [[String.raw`C:\foo\bar`, String.raw`C:\foo`], true], + [[String.raw`C:\foo`, String.raw`C:\foo-bar`], false], + [[String.raw`C:\foo-bar`, String.raw`C:\foo`], false], [['foo', 'foo'], false], [['foo', 'bar'], false], [['foo', 'foo/bar'], false], diff --git a/tsconfig.json b/tsconfig.json index 903939176f..7092e8ff18 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "./tsconfig.base.json", "compilerOptions": { - "baseUrl": ".", "declaration": false, "jsx": "preserve", "paths": {