import type { App, AppContext, Plugin } from 'vue' import { NOOP } from '@vue/shared' export type SFCWithInstall<T> = T & Plugin export type SFCInstallWithContext<T> = SFCWithInstall<T> & { _context: AppContext | null } export const withInstall = <T, E extends Record<string, any>>( main: T, extra?: E, ) => { (main as SFCWithInstall<T>).install = (app): void => { for (const comp of [main, ...Object.values(extra ?? {})]) app.component(comp.__name, comp) } if (extra) { for (const [key, comp] of Object.entries(extra)) (main as any)[key] = comp } return main as SFCWithInstall<T> & E } export const makeInstaller = (components: Plugin[] = []) => { const install = (app: App) => { components.forEach(c => app.use(c)) } return { install, version: '__VERSION__', } } export const withNoopInstall = <T>(component: T) => { (component as SFCWithInstall<T>).install = NOOP return component as SFCWithInstall<T> }