import { App, Component } from 'vue'; import { ZeroInstallOptions } from './types/zeroInstallOptions'; import { ZeroPluginOptions } from './types/zeroPluginOptions'; import { Zero, ZeroLinkArea, ZeroOptions } from './types/zero'; import { createRouter, RouteRecordRaw, RouterOptions } from 'vue-router'; import registerDirectives from '../directives/register'; import registerComponents from '../components/register'; import registerEditorComponents from '../editor/register'; import { getRouterConfig, appendRouterGuards } from './router/routerConfig'; import { countryPlugin, applicationPlugin, settingsPlugin, languagePlugin, mediaPlugin, spacePlugin, pagePlugin, mailTemplatePlugin, translationPlugin, integrationPlugin, userPlugin, linksPlugin, pageModulePlugin } from '../modules'; import editorPlugin from '../editor/plugin'; import { ZeroSchema, ZeroSchemaExtension } from 'zero/schemas'; import { ZeroSchemaProp } from './zero'; import * as zeroOptions from '../options'; import plugins from '../plugins.generated'; import eventHub from '../services/eventhub'; import { Emitter, EventType } from 'mitt'; plugins.push( editorPlugin, countryPlugin, applicationPlugin, settingsPlugin, languagePlugin, mediaPlugin, spacePlugin, pagePlugin, mailTemplatePlugin, translationPlugin, integrationPlugin, userPlugin, linksPlugin, pageModulePlugin ); export class ZeroRuntime implements Zero { _app: App; _installOptions: ZeroInstallOptions; _routerConfig: RouterOptions; _schemas: Record = {}; _schemaExtensions: ZeroSchemaExtension[] = []; _fieldTypes: Record = {}; _linkAreas: Record = {}; /** * version of zero backoffice **/ get version(): string { return "0.0.1"; } /** * access the event hub **/ get events(): Emitter> { return eventHub; } /** * options **/ options: ZeroOptions; /** * runtime variables **/ runtimeVariables: Record = {}; constructor(app: App, options?: ZeroInstallOptions) { this._app = app; this._installOptions = options || {}; this._routerConfig = getRouterConfig('/zero', this); this.options = zeroOptions; } /** * register core components **/ useZero() { let app = this._app; registerDirectives(app); registerComponents(app); registerEditorComponents(app); } /** * create plugin options which are passed to install() for all plugins **/ usePlugins() { const pluginOptions = { vue: this._app, routes: this._routerConfig.routes, schemas: this._schemas, schemaExtensions: this._schemaExtensions, fieldTypes: this._fieldTypes, linkAreas: this._linkAreas, route(route: RouteRecordRaw) { this.routes.push(route); }, schema(alias: string, schema: ZeroSchemaProp) { this.schemas[alias] = schema; }, extendSchema(alias: string, extension: ((schema: ZeroSchema) => void)) { this.schemaExtensions.push({ alias, extension }); }, fieldType(alias: string, component: Component) // TODO v3 allow default field options { this.fieldTypes[alias] = component; }, linkArea(alias: string, name: string, component: Component) { this.linkAreas[alias] = { alias, name, component }; } } as ZeroPluginOptions; // install all plugins plugins.forEach(plugin => { plugin.install(pluginOptions); }); } runPlugins() { plugins.forEach(plugin => { if (typeof plugin.run === 'function') { plugin.run(this); } }); } /** * after all plugins were installed we can create the router * with the designated routes **/ useRouter() { const router = createRouter(this._routerConfig); appendRouterGuards(router); this._app.use(router); } /** * get a defined field type component **/ getFieldTypeComponent(alias: string): Component | undefined { return this._fieldTypes[alias]; } /** * get a defined list or editor schema **/ async getSchema(alias: string): Promise { let schema: ZeroSchemaProp = this._schemas[alias]; if (!schema) { return Promise.resolve(null); } if (typeof schema === 'function') { const res = await schema(); schema = res.default as ZeroSchema; } schema.alias = alias; return Promise.resolve(schema); } /** * get all defined extensions for a schema **/ getSchemaExtensions(alias: string): ZeroSchemaExtension[] { return this._schemaExtensions.filter(x => x.alias == alias); } /** * get all defined link areas **/ get linkAreas(): ZeroLinkArea[] { return Object.values(this._linkAreas); } /** * get a defined link area by alias **/ getLinkArea(alias: string): ZeroLinkArea | undefined { return this._linkAreas[alias]; } }