2021-11-21 16:14:46 +00:00
import { normalize } from 'pathe'
import type { NuxtPlugin , NuxtPluginTemplate } from '@nuxt/schema'
import { useNuxt } from './context'
import { addTemplate } from './template'
2022-07-21 14:05:41 +00:00
import { resolveAlias } from './resolve'
2023-09-19 21:26:15 +00:00
import { logger } from './logger'
2021-11-21 16:14:46 +00:00
/ * *
* Normalize a nuxt plugin object
* /
export function normalizePlugin ( plugin : NuxtPlugin | string ) : NuxtPlugin {
// Normalize src
if ( typeof plugin === 'string' ) {
plugin = { src : plugin }
} else {
plugin = { . . . plugin }
}
if ( ! plugin . src ) {
throw new Error ( 'Invalid plugin. src option is required: ' + JSON . stringify ( plugin ) )
}
2023-03-01 12:08:58 +00:00
// TODO: only scan top-level files #18418
const nonTopLevelPlugin = plugin . src . match ( /\/plugins\/[^/]+\/index\.[^/]+$/i )
if ( nonTopLevelPlugin && nonTopLevelPlugin . length > 0 && ! useNuxt ( ) . options . plugins . find ( i = > ( typeof i === 'string' ? i : i.src ) . endsWith ( nonTopLevelPlugin [ 0 ] ) ) ) {
2023-10-18 10:59:43 +00:00
logger . warn ( ` [deprecation] You are using a plugin that is within a subfolder of your plugins directory without adding it to your config explicitly. You can move it to the top-level plugins directory, or include the file '~ ${ nonTopLevelPlugin [ 0 ] } ' in your plugins config (https://nuxt.com/docs/api/nuxt-config#plugins-1) to remove this warning. ` )
2023-03-01 12:08:58 +00:00
}
2021-11-21 16:14:46 +00:00
// Normalize full path to plugin
2022-07-21 14:05:41 +00:00
plugin . src = normalize ( resolveAlias ( plugin . src ) )
2021-11-21 16:14:46 +00:00
// Normalize mode
if ( plugin . ssr ) {
plugin . mode = 'server'
}
if ( ! plugin . mode ) {
const [ , mode = 'all' ] = plugin . src . match ( /\.(server|client)(\.\w+)*$/ ) || [ ]
plugin . mode = mode as 'all' | 'client' | 'server'
}
return plugin
}
/ * *
* Registers a nuxt plugin and to the plugins array .
*
* Note : You can use mode or . client and . server modifiers with fileName option
* to use plugin only in client or server side .
*
* Note : By default plugin is prepended to the plugins array . You can use second argument to append ( push ) instead .
* @example
* ` ` ` js
* addPlugin ( {
* src : path.resolve ( __dirname , 'templates/foo.js' ) ,
* filename : 'foo.server.js' // [optional] only include in server bundle
* } )
* ` ` `
* /
2022-02-03 18:02:55 +00:00
export interface AddPluginOptions { append? : boolean }
2021-11-21 16:14:46 +00:00
export function addPlugin ( _plugin : NuxtPlugin | string , opts : AddPluginOptions = { } ) {
const nuxt = useNuxt ( )
// Normalize plugin
const plugin = normalizePlugin ( _plugin )
// Remove any existing plugin with the same src
nuxt . options . plugins = nuxt . options . plugins . filter ( p = > normalizePlugin ( p ) . src !== plugin . src )
// Prepend to array by default to be before user provided plugins since is usually used by modules
nuxt . options . plugins [ opts . append ? 'push' : 'unshift' ] ( plugin )
return plugin
}
/ * *
* Adds a template and registers as a nuxt plugin .
* /
2022-03-08 17:42:46 +00:00
export function addPluginTemplate ( plugin : NuxtPluginTemplate | string , opts : AddPluginOptions = { } ) : NuxtPlugin {
const normalizedPlugin : NuxtPlugin = typeof plugin === 'string'
2022-02-28 10:07:20 +00:00
? { src : plugin }
// Update plugin src to template destination
2022-08-22 10:12:02 +00:00
: { . . . plugin , src : addTemplate ( plugin ) . dst ! }
2021-11-21 16:14:46 +00:00
2022-02-28 10:07:20 +00:00
return addPlugin ( normalizedPlugin , opts )
2021-11-21 16:14:46 +00:00
}