Skip to content

Commit

Permalink
feat(kit,nuxt,vite,webpack): add toArray util (#24857)
Browse files Browse the repository at this point in the history
  • Loading branch information
DamianGlowala committed Dec 23, 2023
1 parent cf1a698 commit a2ef309
Show file tree
Hide file tree
Showing 24 changed files with 70 additions and 60 deletions.
13 changes: 3 additions & 10 deletions packages/kit/src/build.ts
@@ -1,6 +1,7 @@
import type { Configuration as WebpackConfig, WebpackPluginInstance } from 'webpack'
import type { UserConfig as ViteConfig, Plugin as VitePlugin } from 'vite'
import { useNuxt } from './context'
import { toArray } from './utils'

export interface ExtendConfigOptions {
/**
Expand Down Expand Up @@ -108,11 +109,7 @@ export function addWebpackPlugin (pluginOrGetter: WebpackPluginInstance | Webpac
const plugin = typeof pluginOrGetter === 'function' ? pluginOrGetter() : pluginOrGetter

config.plugins = config.plugins || []
if (Array.isArray(plugin)) {
config.plugins[method](...plugin)
} else {
config.plugins[method](plugin)
}
config.plugins[method](...toArray(plugin))
}, options)
}

Expand All @@ -125,11 +122,7 @@ export function addVitePlugin (pluginOrGetter: VitePlugin | VitePlugin[] | (() =
const plugin = typeof pluginOrGetter === 'function' ? pluginOrGetter() : pluginOrGetter

config.plugins = config.plugins || []
if (Array.isArray(plugin)) {
config.plugins[method](...plugin)
} else {
config.plugins[method](plugin)
}
config.plugins[method](...toArray(plugin))
}, options)
}

Expand Down
7 changes: 4 additions & 3 deletions packages/kit/src/imports.ts
Expand Up @@ -2,20 +2,21 @@ import type { Import } from 'unimport'
import type { ImportPresetWithDeprecation } from '@nuxt/schema'
import { useNuxt } from './context'
import { assertNuxtCompatibility } from './compatibility'
import { toArray } from './utils'

export function addImports (imports: Import | Import[]) {
assertNuxtCompatibility({ bridge: true })

useNuxt().hook('imports:extend', (_imports) => {
_imports.push(...(Array.isArray(imports) ? imports : [imports]))
_imports.push(...toArray(imports))
})
}

export function addImportsDir (dirs: string | string[], opts: { prepend?: boolean } = {}) {
assertNuxtCompatibility({ bridge: true })

useNuxt().hook('imports:dirs', (_dirs: string[]) => {
for (const dir of (Array.isArray(dirs) ? dirs : [dirs])) {
for (const dir of toArray(dirs)) {
_dirs[opts.prepend ? 'unshift' : 'push'](dir)
}
})
Expand All @@ -24,7 +25,7 @@ export function addImportsSources (presets: ImportPresetWithDeprecation | Import
assertNuxtCompatibility({ bridge: true })

useNuxt().hook('imports:sources', (_presets: ImportPresetWithDeprecation[]) => {
for (const preset of (Array.isArray(presets) ? presets : [presets])) {
for (const preset of toArray(presets)) {
_presets.push(preset)
}
})
Expand Down
6 changes: 2 additions & 4 deletions packages/kit/src/internal/template.ts
Expand Up @@ -5,6 +5,7 @@ import { genDynamicImport, genImport, genSafeVariableName } from 'knitwork'

import type { NuxtTemplate } from '@nuxt/schema'
import { logger } from '../logger'
import { toArray } from '../utils'

/** @deprecated */
// TODO: Remove support for compiling ejs templates in v4
Expand All @@ -30,10 +31,7 @@ const serialize = (data: any) => JSON.stringify(data, null, 2).replace(/"{(.+)}"

/** @deprecated */
const importSources = (sources: string | string[], { lazy = false } = {}) => {
if (!Array.isArray(sources)) {
sources = [sources]
}
return sources.map((src) => {
return toArray(sources).map((src) => {
if (lazy) {
return `const ${genSafeVariableName(src)} = ${genDynamicImport(src, { comment: `webpackChunkName: ${JSON.stringify(src)}` })}`
}
Expand Down
18 changes: 7 additions & 11 deletions packages/kit/src/nitro.ts
Expand Up @@ -2,6 +2,7 @@ import type { Nitro, NitroDevEventHandler, NitroEventHandler } from 'nitropack'
import type { Import } from 'unimport'
import { normalize } from 'pathe'
import { useNuxt } from './context'
import { toArray } from './utils'

/**
* normalize handler object
Expand Down Expand Up @@ -47,10 +48,8 @@ export function addServerPlugin (plugin: string) {
*/
export function addPrerenderRoutes (routes: string | string[]) {
const nuxt = useNuxt()
if (!Array.isArray(routes)) {
routes = [routes]
}
routes = routes.filter(Boolean)

routes = toArray(routes).filter(Boolean)
if (!routes.length) {
return
}
Expand Down Expand Up @@ -90,11 +89,8 @@ export function addServerImports (imports: Import[]) {
const nuxt = useNuxt()
nuxt.hook('nitro:config', (config) => {
config.imports = config.imports || {}
if (Array.isArray(config.imports.imports)) {
config.imports.imports.push(...imports)
} else {
config.imports.imports = [config.imports.imports, ...imports]
}
config.imports.imports = config.imports.imports || []
config.imports.imports.push(...imports)
})
}

Expand All @@ -103,7 +99,7 @@ export function addServerImports (imports: Import[]) {
*/
export function addServerImportsDir (dirs: string | string[], opts: { prepend?: boolean } = {}) {
const nuxt = useNuxt()
const _dirs = Array.isArray(dirs) ? dirs : [dirs]
const _dirs = toArray(dirs)
nuxt.hook('nitro:config', (config) => {
config.imports = config.imports || {}
config.imports.dirs = config.imports.dirs || []
Expand All @@ -120,7 +116,7 @@ export function addServerScanDir (dirs: string | string[], opts: { prepend?: boo
nuxt.hook('nitro:config', (config) => {
config.scanDirs = config.scanDirs || []

for (const dir of (Array.isArray(dirs) ? dirs : [dirs])) {
for (const dir of toArray(dirs)) {
config.scanDirs[opts.prepend ? 'unshift' : 'push'](dir)
}
})
Expand Down
3 changes: 2 additions & 1 deletion packages/kit/src/pages.ts
Expand Up @@ -4,6 +4,7 @@ import { defu } from 'defu'
import { useNuxt } from './context'
import { isNuxt2 } from './compatibility'
import { logger } from './logger'
import { toArray } from './utils'

export function extendPages (cb: NuxtHooks['pages:extend']) {
const nuxt = useNuxt()
Expand Down Expand Up @@ -45,7 +46,7 @@ export interface AddRouteMiddlewareOptions {

export function addRouteMiddleware (input: NuxtMiddleware | NuxtMiddleware[], options: AddRouteMiddlewareOptions = {}) {
const nuxt = useNuxt()
const middlewares = Array.isArray(input) ? input : [input]
const middlewares = toArray(input)
nuxt.hook('app:resolve', (app) => {
for (const middleware of middlewares) {
const find = app.middleware.findIndex(item => item.name === middleware.name)
Expand Down
6 changes: 2 additions & 4 deletions packages/kit/src/resolve.ts
Expand Up @@ -6,6 +6,7 @@ import { resolvePath as _resolvePath } from 'mlly'
import { resolveAlias as _resolveAlias } from 'pathe/utils'
import { tryUseNuxt } from './context'
import { isIgnored } from './ignore'
import { toArray } from './utils'

export interface ResolvePathOptions {
/** Base for resolving paths from. Default is Nuxt rootDir. */
Expand Down Expand Up @@ -84,10 +85,7 @@ export async function resolvePath (path: string, opts: ResolvePathOptions = {}):
* Try to resolve first existing file in paths
*/
export async function findPath (paths: string | string[], opts?: ResolvePathOptions, pathType: 'file' | 'dir' = 'file'): Promise<string | null> {
if (!Array.isArray(paths)) {
paths = [paths]
}
for (const path of paths) {
for (const path of toArray(paths)) {
const rPath = await resolvePath(path, opts)
if (await existsSensitive(rPath)) {
const _isDir = await isDirectory(rPath)
Expand Down
3 changes: 3 additions & 0 deletions packages/kit/src/utils.ts
@@ -0,0 +1,3 @@
export function toArray<T> (value: T | T[]): T[] {
return Array.isArray(value) ? value : [value]
}
5 changes: 3 additions & 2 deletions packages/nuxt/src/app/composables/asyncData.ts
Expand Up @@ -2,6 +2,7 @@ import { getCurrentInstance, onBeforeMount, onServerPrefetch, onUnmounted, ref,
import type { Ref, WatchSource } from 'vue'
import type { NuxtApp } from '../nuxt'
import { useNuxtApp } from '../nuxt'
import { toArray } from '../utils'
import type { NuxtError} from './error';
import { createError } from './error'
import { onNuxtReady } from './ready'
Expand Down Expand Up @@ -378,7 +379,7 @@ export async function refreshNuxtData (keys?: string | string[]): Promise<void>

await new Promise<void>(resolve => onNuxtReady(resolve))

const _keys = keys ? Array.isArray(keys) ? keys : [keys] : undefined
const _keys = keys ? toArray(keys) : undefined
await useNuxtApp().hooks.callHookParallel('app:data:refresh', _keys)
}

Expand All @@ -389,7 +390,7 @@ export function clearNuxtData (keys?: string | string[] | ((key: string) => bool
? _allKeys
: typeof keys === 'function'
? _allKeys.filter(keys)
: Array.isArray(keys) ? keys : [keys]
: toArray(keys)

for (const key of _keys) {
if (key in nuxtApp.payload.data) {
Expand Down
3 changes: 1 addition & 2 deletions packages/nuxt/src/app/composables/fetch.ts
Expand Up @@ -227,8 +227,7 @@ function generateOptionSegments <_ResT, DataT, DefaultT>(opts: UseFetchOptions<_
if (!obj) { continue }

const unwrapped: Record<string, string> = {}
const iterator = Array.isArray(obj) ? obj : Object.entries(obj)
for (const [key, value] of iterator) {
for (const [key, value] of Object.entries(obj)) {
unwrapped[toValue(key)] = toValue(value)
}
segments.push(unwrapped)
Expand Down
3 changes: 2 additions & 1 deletion packages/nuxt/src/app/composables/preload.ts
@@ -1,6 +1,7 @@
import type { Component } from 'vue'
import type { RouteLocationRaw, Router } from '#vue-router'
import { useNuxtApp } from '../nuxt'
import { toArray } from '../utils'
import { useRouter } from './router'

/**
Expand All @@ -11,7 +12,7 @@ export const preloadComponents = async (components: string | string[]) => {
if (import.meta.server) { return }
const nuxtApp = useNuxtApp()

components = Array.isArray(components) ? components : [components]
components = toArray(components)
await Promise.all(components.map(name => _loadAsyncComponent(nuxtApp.vueApp._context.components[name])))
}

Expand Down
3 changes: 2 additions & 1 deletion packages/nuxt/src/app/composables/ssr.ts
Expand Up @@ -2,6 +2,7 @@ import type { H3Event } from 'h3'
import { setResponseStatus as _setResponseStatus, appendHeader, getRequestHeader, getRequestHeaders } from 'h3'
import type { NuxtApp } from '../nuxt'
import { useNuxtApp } from '../nuxt'
import { toArray } from '../utils'

export function useRequestEvent (nuxtApp: NuxtApp = useNuxtApp()): H3Event {
return nuxtApp.ssrContext?.event as H3Event
Expand Down Expand Up @@ -44,6 +45,6 @@ export function setResponseStatus (arg1: H3Event | number | undefined, arg2?: nu
export function prerenderRoutes (path: string | string[]) {
if (!import.meta.server || !import.meta.prerender) { return }

const paths = Array.isArray(path) ? path : [path]
const paths = toArray(path)
appendHeader(useRequestEvent(), 'x-nitro-prerender', paths.map(p => encodeURIComponent(p)).join(', '))
}
3 changes: 2 additions & 1 deletion packages/nuxt/src/app/composables/state.ts
@@ -1,6 +1,7 @@
import { isRef, toRef } from 'vue'
import type { Ref } from 'vue'
import { useNuxtApp } from '../nuxt'
import { toArray } from '../utils'

const useStateKeyPrefix = '$s'
/**
Expand Down Expand Up @@ -47,7 +48,7 @@ export function clearNuxtState (
? _allKeys
: typeof keys === 'function'
? _allKeys.filter(keys)
: Array.isArray(keys) ? keys : [keys]
: toArray(keys)

for (const _key of _keys) {
const key = useStateKeyPrefix + _key
Expand Down
3 changes: 3 additions & 0 deletions packages/nuxt/src/app/utils.ts
@@ -0,0 +1,3 @@
export function toArray<T> (value: T | T[]): T[] {
return Array.isArray(value) ? value : [value]
}
3 changes: 2 additions & 1 deletion packages/nuxt/src/core/nitro.ts
Expand Up @@ -16,6 +16,7 @@ import type { Nuxt, RuntimeConfig } from 'nuxt/schema'
import { template as defaultSpaLoadingTemplate } from '@nuxt/ui-templates/templates/spa-loading-icon.mjs'
import { version as nuxtVersion } from '../../package.json'
import { distDir } from '../dirs'
import { toArray } from '../utils'
import { ImportProtectionPlugin } from './plugins/import-protection'

export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
Expand Down Expand Up @@ -333,7 +334,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {

// Register nuxt protection patterns
nitroConfig.rollupConfig!.plugins = await nitroConfig.rollupConfig!.plugins || []
nitroConfig.rollupConfig!.plugins = Array.isArray(nitroConfig.rollupConfig!.plugins) ? nitroConfig.rollupConfig!.plugins : [nitroConfig.rollupConfig!.plugins]
nitroConfig.rollupConfig!.plugins = toArray(nitroConfig.rollupConfig!.plugins)
nitroConfig.rollupConfig!.plugins!.push(
ImportProtectionPlugin.rollup({
rootDir: nuxt.options.rootDir,
Expand Down
7 changes: 2 additions & 5 deletions packages/nuxt/src/pages/runtime/page.ts
Expand Up @@ -4,6 +4,7 @@ import { RouterView } from '#vue-router'
import { defu } from 'defu'
import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from '#vue-router'

import { toArray } from './utils'
import type { RouterViewSlotProps } from './utils'
import { generateRouteKey, wrapInKeepAlive } from './utils'
import { RouteProvider } from '#app/components/route-provider'
Expand Down Expand Up @@ -127,14 +128,10 @@ export default defineComponent({
}
})

function _toArray (val: any) {
return Array.isArray(val) ? val : (val ? [val] : [])
}

function _mergeTransitionProps (routeProps: TransitionProps[]): TransitionProps {
const _props: TransitionProps[] = routeProps.map(prop => ({
...prop,
onAfterLeave: _toArray(prop.onAfterLeave)
onAfterLeave: prop.onAfterLeave ? toArray(prop.onAfterLeave) : undefined
}))
return defu(..._props as [TransitionProps, TransitionProps])
}
Expand Down
5 changes: 3 additions & 2 deletions packages/nuxt/src/pages/runtime/plugins/prefetch.client.ts
@@ -1,4 +1,5 @@
import { hasProtocol } from 'ufo'
import { toArray } from '../utils'
import { defineNuxtPlugin } from '#app/nuxt'
import { useRouter } from '#app/composables/router'
// @ts-expect-error virtual file
Expand All @@ -25,8 +26,8 @@ export default defineNuxtPlugin({
if (hasProtocol(url)) { return }
const route = router.resolve(url)
if (!route) { return }
const layout = route?.meta?.layout
let middleware = Array.isArray(route?.meta?.middleware) ? route?.meta?.middleware : [route?.meta?.middleware]
const layout = route.meta.layout
let middleware = toArray(route.meta.middleware)
middleware = middleware.filter(m => typeof m === 'string')

for (const name of middleware) {
Expand Down
9 changes: 3 additions & 6 deletions packages/nuxt/src/pages/runtime/plugins/router.ts
Expand Up @@ -13,6 +13,7 @@ import { isEqual, withoutBase } from 'ufo'

import type { PageMeta } from '../composables'

import { toArray } from '../utils'
import type { Plugin, RouteMiddleware } from '#app'
import { defineNuxtPlugin, useRuntimeConfig } from '#app/nuxt'
import { clearError, showError, useError } from '#app/composables/error'
Expand Down Expand Up @@ -155,12 +156,8 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
for (const component of to.matched) {
const componentMiddleware = component.meta.middleware as MiddlewareDef | MiddlewareDef[]
if (!componentMiddleware) { continue }
if (Array.isArray(componentMiddleware)) {
for (const entry of componentMiddleware) {
middlewareEntries.add(entry)
}
} else {
middlewareEntries.add(componentMiddleware)
for (const entry of toArray(componentMiddleware)) {
middlewareEntries.add(entry)
}
}

Expand Down
4 changes: 4 additions & 0 deletions packages/nuxt/src/pages/runtime/utils.ts
Expand Up @@ -21,3 +21,7 @@ export const generateRouteKey = (routeProps: RouterViewSlotProps, override?: str
export const wrapInKeepAlive = (props: any, children: any) => {
return { default: () => import.meta.client && props ? h(KeepAlive, props === true ? {} : props, children) : children }
}

export function toArray<T> (value: T | T[]): T[] {
return Array.isArray(value) ? value : [value]
}
3 changes: 2 additions & 1 deletion packages/nuxt/src/pages/utils.ts
Expand Up @@ -12,6 +12,7 @@ import type { CallExpression, ExpressionStatement, ObjectExpression, Program, Pr
import type { NuxtPage } from 'nuxt/schema'

import { uniqueBy } from '../core/utils'
import { toArray } from '../utils'

enum SegmentParserState {
initial,
Expand Down Expand Up @@ -325,7 +326,7 @@ export function normalizeRoutes (routes: NuxtPage[], metaImports: Set<string> =
metaImports.add(genImport(`${file}?macro=true`, [{ name: 'default', as: metaImportName }]))

let aliasCode = `${metaImportName}?.alias || []`
const alias = Array.isArray(page.alias) ? page.alias : [page.alias].filter(Boolean)
const alias = toArray(page.alias).filter(Boolean)
if (alias.length) {
aliasCode = `${JSON.stringify(alias)}.concat(${aliasCode})`
}
Expand Down
3 changes: 3 additions & 0 deletions packages/nuxt/src/utils.ts
@@ -0,0 +1,3 @@
export function toArray<T> (value: T | T[]): T[] {
return Array.isArray(value) ? value : [value]
}

0 comments on commit a2ef309

Please sign in to comment.