@deepkit/app
Version:
Deepkit App, CLI framework and service container
344 lines • 15.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppModule = exports.__ΩListenerType = exports.__ΩAppModuleClass = exports.ConfigurationInvalidError = exports.__ΩRootModuleDefinition = exports.__ΩFunctionalModuleFactory = exports.__ΩFunctionalModule = exports.__ΩCreateModuleDefinition = exports.__ΩModuleDefinition = exports.__ΩExportType = exports.__ΩMiddlewareFactory = exports.__ΩMiddlewareConfig = void 0;
exports.stringifyListener = stringifyListener;
exports.createModuleClass = createModuleClass;
exports.createModule = createModule;
const __ΩPartial = ['T', 'Partial', 'l+e#!e"!fRb!Pde"!gN#"w"y'];
/*@ts-ignore*/
const { __ΩClassType } = require('@deepkit/core');
/*@ts-ignore*/
const { __ΩExtractClassType } = require('@deepkit/core');
/*@ts-ignore*/
const { __ΩEventListener } = require('@deepkit/event');
/*@ts-ignore*/
const { __ΩAbstractClassType } = require('@deepkit/core');
/*
* Deepkit Framework
* Copyright (C) 2021 Deepkit UG, Marc J. Schmidt
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the MIT License.
*
* You should have received a copy of the MIT License along with this program.
*/
const injector_1 = require("@deepkit/injector");
const core_1 = require("@deepkit/core");
const workflow_1 = require("@deepkit/workflow");
const type_1 = require("@deepkit/type");
const __ΩMiddlewareConfig = [() => __ΩClassType, 'getClassTypes', 'MiddlewareConfig', 'PPn!F1"Mw#y'];
exports.__ΩMiddlewareConfig = __ΩMiddlewareConfig;
const __ΩMiddlewareFactory = [() => __ΩMiddlewareConfig, '', 'MiddlewareFactory', 'Pn!/"w#y'];
exports.__ΩMiddlewareFactory = __ΩMiddlewareFactory;
const __ΩExportType = [() => __ΩAbstractClassType, () => AppModule, 'Type', 'NormalizedProvider', 'ExportType', 'Pn!&P"7""w#"w$Jw%y'];
exports.__ΩExportType = __ΩExportType;
function stringifyListener(listener) {
if (listener.classType) {
return listener.classType.name + '.' + listener.methodName;
}
return listener.reflection.name || 'anonymous function';
}
stringifyListener.__type = ['AddedListener', 'listener', 'stringifyListener', 'P"w!2"&/#'];
const __ΩModuleDefinition = ['name', 'ProviderWithScope', 'providers', () => __ΩExportType, 'exports', () => __ΩClassType, () => Function, 'bootstrap', () => __ΩClassType, 'config', () => __ΩClassType, 'controllers', () => workflow_1.WorkflowDefinition, 'workflows', () => __ΩEventListener, () => __ΩClassType, 'listeners', () => __ΩMiddlewareFactory, 'middlewares', 'ModuleDefinition', 'P&4!8P"w""w"FJF4#8n$F4%8Pn&Pu\'J4(8n)4*8n+F4,8P"7-F4.8Pn/n0JF418n2F438Mw4y'];
exports.__ΩModuleDefinition = __ΩModuleDefinition;
const __ΩCreateModuleDefinition = [() => __ΩModuleDefinition, true, 'forRoot', 'imports', 'CreateModuleDefinition', 'Pn!."4#8-4$8Mw%y'];
exports.__ΩCreateModuleDefinition = __ΩCreateModuleDefinition;
const __ΩFunctionalModule = [() => AppModule, 'module', '', 'FunctionalModule', 'PP"7!2"$/#w$y'];
exports.__ΩFunctionalModule = __ΩFunctionalModule;
const __ΩFunctionalModuleFactory = ['args', () => AppModule, 'module', '', 'FunctionalModuleFactory', 'P"@2!PP"7"2#$/$/$w%y'];
exports.__ΩFunctionalModuleFactory = __ΩFunctionalModuleFactory;
const __ΩRootModuleDefinition = [() => __ΩModuleDefinition, () => AppModule, () => __ΩFunctionalModule, 'imports', 'RootModuleDefinition', 'Pn!PP"7"n#JF4$8Mw%y'];
exports.__ΩRootModuleDefinition = __ΩRootModuleDefinition;
class ConfigurationInvalidError extends core_1.CustomError {
}
exports.ConfigurationInvalidError = ConfigurationInvalidError;
ConfigurationInvalidError.__type = [() => core_1.CustomError, 'ConfigurationInvalidError', 'P7!5w"'];
let moduleId = 0;
const __ΩAppModuleClass = ['C', 'DeepPartial', 'config', () => AppModule, 'new', 'AppModuleClass', 'b!PP"w"2#8Pe$!7$1%Mw&y'];
exports.__ΩAppModuleClass = __ΩAppModuleClass;
/**
* Creates a new module class type from which you can extend.
*
* ```typescript
* class MyModule extends createModuleClass({}) {}
*
* //and used like this
* new App({
* imports: [new MyModule]
* });
* ```
*/
function createModuleClass(options) {
/** @reflection never */
return class AnonAppModule extends AppModule {
constructor(config) {
super(config, options);
}
};
}
createModuleClass.__type = [() => __ΩCreateModuleDefinition, () => __ΩClassType, 'config', 'options', () => __ΩAppModuleClass, 'createModuleClass', 'PPn!P"o""4#8MK2$"o%"/&'];
/**
* Creates a new module instance.
*
* This is mainly used for small non-reusable modules.
* It's recommended to use `createModuleClass` and extend from it.
*
* @example
* ```typescript
* const myModule = createModuleClass({
* config: MyConfig
* providers: [MyService]
* });
*
* const app = new App({
* imports: [myModule]
* });
* ```
*/
function createModule(options) {
return new (createModuleClass(options))();
}
createModule.__type = ['options', () => __ΩExtractClassType, "config", () => AppModule, 'createModule', 'P"2!P".#fo""7$/%'];
const __ΩListenerType = [() => __ΩEventListener, () => __ΩClassType, 'ListenerType', 'Pn!n"Jw#y'];
exports.__ΩListenerType = __ΩListenerType;
function extractConfigFromModuleClass(moduleClass) {
if (moduleClass === AppModule) {
// This is not supported right now `new AppModule<MyConfig>()`
const type = (0, type_1.resolveReceiveType)(moduleClass);
if (type.kind !== type_1.ReflectionKind.class)
return;
if (AppModule.isPrototypeOf(type.classType) || type.classType === AppModule) {
// This is the AppModule class itself, not a module extending it.
return;
}
return type.classType;
}
let current = moduleClass;
// Find classType that extends AppModule
while (current) {
const parent = Object.getPrototypeOf(current);
if (parent === AppModule) {
const type = (0, type_1.resolveReceiveType)(current);
if (type.kind !== type_1.ReflectionKind.class)
return;
const extendArgument = type.extendsArguments?.[0];
if (!extendArgument)
return;
if (extendArgument.kind !== type_1.ReflectionKind.class)
return;
if (AppModule.isPrototypeOf(extendArgument.classType) || extendArgument.classType === AppModule) {
// This is the AppModule class itself, not a module extending it.
return;
}
return extendArgument.classType;
}
current = parent;
}
return;
}
extractConfigFromModuleClass.__type = [() => __ΩClassType, 'moduleClass', () => __ΩClassType, 'extractConfigFromModuleClass', 'Pn!2"Pn#-J/$'];
/**
* The AppModule is the base class for all modules.
*
* You can use `createModule` to create a new module class or extend from `AppModule` manually.
*
* @example
* ```typescript
*
* class MyModule extends AppModule {
* providers = [MyService];
* exports = [MyService];
*
* constructor(config: MyConfig) {
* super();
* this.setConfigDefinition(MyConfig);
* this.configure(config);
* this.name = 'myModule';
* }
* }
*/
class AppModule extends injector_1.InjectorModule {
constructor(config = {}, options = {}, setups = [], id = moduleId++) {
super();
this.options = options;
this.setups = setups;
this.id = id;
this.setupConfigs = [];
this.imports = [];
this.controllers = [];
this.commands = [];
this.workflows = [];
this.listeners = [];
this.middlewares = [];
this.uses = [];
this.name = '';
if (options.name)
this.name = options.name;
if (this.options.imports)
for (const m of this.options.imports)
this.addModuleImport(m);
if (this.options.providers)
this.providers.push(...this.options.providers.flat());
if (this.options.exports)
this.exports.push(...this.options.exports);
if (this.options.controllers)
this.controllers.push(...this.options.controllers);
if (this.options.workflows)
this.workflows.push(...this.options.workflows);
if (this.options.listeners)
this.listeners.push(...this.options.listeners);
if (this.options.middlewares)
this.middlewares.push(...this.options.middlewares);
if ('forRoot' in this.options)
this.forRoot();
if (this.options.config) {
this.setConfigDefinition(this.options.config);
}
else {
const configFromClass = extractConfigFromModuleClass(this.constructor);
if (configFromClass) {
this.setConfigDefinition(configFromClass);
}
}
this.configure(config);
}
addModuleImport(m) {
if (m instanceof AppModule) {
this.addImport(m);
}
else {
const module = new AppModule({});
m(module);
this.addImport(module);
}
}
/**
* When all configuration loaders have been loaded, this method is called.
* It allows to further manipulate the module state depending on the final config.
* Possible use-cases:
* - Add more providers depending on the configuration.
* - Change the module imports depending on the configuration.
* - Change provider setup via this.configureProvider<Provider>(provider => {}) depending on the configuration.
*/
process() {
}
/**
* A hook that allows to react on a registered provider in some module.
*/
processProvider(module, token, provider) {
}
/**
* A hook that allows to react on a registered controller in some module.
*/
processController(module, config) {
}
/**
* A hook that allows to react on a registered event listeners in some module.
*/
processListener(module, listener) {
}
/**
* After `process` and when all modules have been processed by the service container.
* This is also after `processController` and `processProvider` have been called and the full
* final module tree is known. Adding now new providers or modules doesn't have any effect.
*
* Last chance to set up the injector context, via this.setupProvider().
*/
postProcess() {
}
/**
* Renames this module instance.
*/
rename(name) {
this.name = name;
return this;
}
getListeners() {
return this.listeners;
}
getWorkflows() {
return this.workflows;
}
getMiddlewares() {
return this.middlewares;
}
getControllers() {
return this.controllers;
}
getCommands() {
return this.commands;
}
addCommand(name, callback) {
this.assertInjectorNotBuilt();
this.commands.push({ name, callback });
return this;
}
addController(...controller) {
this.assertInjectorNotBuilt();
this.controllers.push(...controller);
return this;
}
addListener(...listener) {
this.assertInjectorNotBuilt();
for (const l of listener) {
if (!(0, core_1.isClass)(l))
continue;
if (this.isProvided(l))
continue;
this.addProvider(l);
}
this.listeners.push(...listener);
return this;
}
addMiddleware(...middlewares) {
this.middlewares.push(...middlewares);
return this;
}
/**
* Allows to change the module config before `setup` and bootstrap is called.
* This is the last step right before the config is validated.
*/
setupConfig(callback) {
this.setupConfigs.push(callback);
return this;
}
/**
* Allows to change the module after the configuration has been loaded, right before the service container is built.
*
* This enables you to change the module or its imports depending on the configuration the last time before their services are built.
*
* At this point no services can be requested as the service container was not built.
*/
setup(callback) {
this.setups.push(callback);
return this;
}
/**
* Allows to call services before the application bootstraps.
*
* This enables you to configure modules and request their services.
*/
use(callback) {
this.uses.push(callback);
return this;
}
getImports() {
return super.getImports();
}
getName() {
return this.name;
}
/**
* Sets configured values.
*/
configure(config) {
if (this.configDefinition) {
const configNormalized = (0, type_1.getPartialSerializeFunction)((0, type_1.resolveReceiveType)(this.configDefinition), type_1.serializer.deserializeRegistry)(config);
Object.assign(this.config, configNormalized);
}
return this;
}
}
exports.AppModule = AppModule;
AppModule.__type = ['C', () => injector_1.InjectorModule, () => AppModule, 'module', 'config', '', 'setupConfigs', function () { return []; }, () => AppModule, 'imports', function () { return []; }, () => __ΩClassType, 'controllers', function () { return []; }, 'name', () => Function, 'callback', 'commands', function () { return []; }, () => workflow_1.WorkflowDefinition, 'workflows', function () { return []; }, () => __ΩListenerType, 'listeners', function () { return []; }, () => __ΩMiddlewareFactory, 'middlewares', function () { return []; }, 'args', 'uses', function () { return []; }, function () { return ''; }, 'DeepPartial', () => ({}), () => __ΩRootModuleDefinition, 'options', () => ({}), () => AppModule, 'setups', () => [], 'id', () => moduleId++, 'constructor', () => AppModule, () => __ΩFunctionalModule, 'm', 'addModuleImport', 'process', () => AppModule, 'Token', 'token', 'ProviderWithScope', 'provider', 'processProvider', () => AppModule, 'ControllerConfig', 'processController', () => AppModule, 'AddedListener', 'listener', 'processListener', 'postProcess', 'rename', () => __ΩListenerType, 'getListeners', () => workflow_1.WorkflowDefinition, 'getWorkflows', () => __ΩMiddlewareFactory, 'getMiddlewares', () => __ΩClassType, 'getControllers', () => Function, 'getCommands', 'addCommand', () => __ΩClassType, 'controller', 'addController', () => __ΩEventListener, () => __ΩClassType, 'addListener', () => __ΩMiddlewareFactory, 'addMiddleware', () => AppModule, 'setupConfig', () => AppModule, 'setup', 'use', () => AppModule, 'getImports', 'getName', () => __ΩPartial, 'configure', 'AppModule', '"c!Pe"!7"PP"7#2$"2%$/&F3\'>(P"7)F3*>+n,F3->.P&4/8Pu041MF32>3P"74F35>6n7F38>9n:F3;><P"@2=$/&F3>>?&3/>@P"wA2%>BnC2D:>EPP"7F2$"2%$/&F2G:>H\'2I:>J"0KPPP"7LnMJ2N"0O<P"0PPP"7Q2$"wR2S"wT2U"0VPP"7W2$"wX2%"0YPP"7Z2$"w[2\\"0]P"0^P&2/!0_Pn`F0aPP"7bF0cPndF0ePnfF0gPP&4/8Puh41MF0iPP&-J2/PPG@2="/&21!0jPnk@2l!0mPPnnnoJ@2\\!0pPnq@2;!0rPPPe$!7s2$e#!2%$/&21!0tPPPe$!7u2$e#!2%$/&21!0vPP"@2=$/&21!0wPP"7xF0yP&0zPe"!o{"2%!0|5e!!6"w}'];
//# sourceMappingURL=module.js.map