UNPKG

hins

Version:

[![codecov](https://codecov.io/gh/l-zoy/hins/branch/main/graph/badge.svg)](https://codecov.io/gh/l-zoy/hins) [![GitHub license](https://img.shields.io/github/license/l-zoy/hins)](https://github.com/l-zoy/hins/blob/master/LICENSE) ![node-current](https://i

150 lines (125 loc) 3.93 kB
import assert from 'assert' import { pathToRegister } from './resolvePlugins' import { ICoreStage } from './enum' import type { IApiRegisterPlugins, IApiRegisterMethod, IApiDescribe, IApiOpitons, ICommands, IHook, IWorkDir } from './types' export default class Api { /** * @desc as an identifier */ path?: IWorkDir /** * @desc Core prototype */ core: IApiOpitons['core'] constructor(options: IApiOpitons) { const { core } = options // this.path = path this.core = core } describe(options: IApiDescribe) { const { key, config } = options const { plugins } = this.core assert(options.key, `api.describe() failed, the plugin is missing an 'key'.`) assert( options.config.schema && typeof options.config.schema === 'function', `api.describe() failed, the plugin is missing 'schema'` ) assert(this.path, `api.describe() failed, this.Path is not initialized`) plugins[this.path].key = key plugins[this.path].config = config } registerCommand(options: ICommands) { const { commands } = this.core const { command, alias } = options assert( !commands[command], `api.registerCommand() failed, the command ${command} is exists.` ) commands[command] = options if (alias) { commands[alias] = options } } registerPlugins(plugins: IApiRegisterPlugins) { assert( this.core.stage === ICoreStage.initPlugins, `api.registerPlugins() failed, it should only be used in registering stage.` ) assert(Array.isArray(plugins), `api.registerPlugins() failed, plugins must be Array.`) // dynamic registration support after processing const keepKeys = {} const extraPlugins = [] for (const plugin of plugins) { if (typeof plugin === 'string') { if (keepKeys[plugin]) { continue } const applyPlugin = pathToRegister(plugin) if (this.core.plugins[applyPlugin.path]) { throw new Error(`Same plugin registered ${applyPlugin.path}`) } this.core.extraPlugins.forEach(({ path }) => { if (path === applyPlugin.path) { throw new Error(`Repeat the plugin to be registered ${applyPlugin.path}`) } }) keepKeys[plugin] = 1 extraPlugins.push(pathToRegister(plugin)) continue } if (!plugin.key || !plugin.apply) { throw new Error(`Inline plugins must contain 'key' and 'apply'`) } if (keepKeys[plugin.key]) { continue } keepKeys[plugin.key] = 1 extraPlugins.push({ path: plugin.key, apply: () => plugin.apply }) } this.core.extraPlugins.unshift(...extraPlugins) } registerMethod(options: IApiRegisterMethod) { const { pluginMethods } = this.core const { fn, name } = options assert( !pluginMethods[name], `api.registerMethod() failed, method ${name} is already exist.` ) pluginMethods[name] = fn ?? function (this: Api, hookOptions: Omit<IHook, 'pluginId'> | (() => any)) { const hook = typeof hookOptions === 'function' ? { fn: hookOptions } : hookOptions this.register({ key: name, ...hook }) } } register(options: Omit<IHook, 'pluginId'>) { const { hooksByPluginId } = this.core assert( options.key && typeof options.key === 'string', `api.register() failed, hook.key must supplied and should be string, but got ${options.key}.` ) assert( typeof options.fn === 'function', `api.register() failed, hook.fn must supplied and should be function, but got ${options.fn}.` ) assert(this.path, `api.register() failed, this.Path is not initialized`) hooksByPluginId[options.key] = (hooksByPluginId[options.key] ?? []).concat({ pluginId: this.path, ...options }) } }