@sklechko/framework
Advanced tools
Comparing version 0.0.1 to 0.1.0
@@ -0,12 +1,24 @@ | ||
import 'zone.js'; | ||
import "zone.js/dist/long-stack-trace-zone.js"; | ||
import "reflect-metadata"; | ||
export { Component } from "./lib/decorators/ComponentDecorator"; | ||
export { Qualifier } from "./lib/decorators/QualifierDecorator"; | ||
export { ComponentScan } from "./lib/decorators/ComponentScanDecorator"; | ||
export { Import } from "./lib/decorators/ImportDecorator"; | ||
export { Configuration } from "./lib/decorators/ConfigurationDecorator"; | ||
export { Controller } from "./lib/decorators/ControllerDecorator"; | ||
export { Inject, Value } from "./lib/decorators/InjectionDecorators"; | ||
export { Inject, DynamicInject, Value, Autowire, ThreadLocal } from "./lib/decorators/InjectionDecorators"; | ||
export { PostConstruct, PreDestroy } from "./lib/decorators/LifeCycleHooksDecorators"; | ||
export { Profile, ActiveProfiles } from "./lib/decorators/ProfileDecorators"; | ||
export { PropertySource } from "./lib/decorators/PropertySourceDecorator"; | ||
export { View } from "./lib/decorators/ViewDecorator"; | ||
export { RequestMapping, RequestMappingConfig, RequestMethod } from "./lib/decorators/RequestMappingDecorator"; | ||
export { Interceptor } from "./lib/decorators/InterceptorDecorator"; | ||
export { Order } from "./lib/decorators/OrderDecorator"; | ||
export { RequestContext, REQUEST_TOKEN, RESPONSE_TOKEN } from "./lib/web/context/RequestContext"; | ||
export { RequestContextHolder } from "./lib/web/context/RequestContextHolder"; | ||
export { ApplicationContext } from "./lib/di/ApplicationContext"; | ||
export { Dispatcher } from "./lib/dispatcher/Dispatcher"; | ||
export { Interceptor } from "./lib/interceptors/InterceptorDecorator"; | ||
export { Dispatcher } from "./lib/web/Dispatcher"; | ||
export { ComponentDefinitionPostProcessor } from "./lib/processors/ComponentDefinitionPostProcessor"; | ||
export { ComponentPostProcessor } from "./lib/processors/ComponentPostProcessor"; | ||
export { Environment } from "./lib/di/Environment"; |
35
index.js
"use strict"; | ||
require('zone.js'); | ||
require("zone.js/dist/long-stack-trace-zone.js"); | ||
// NOTE: prototype for the ES7 Reflect API. Added for easier manipulating with metadata. | ||
require("reflect-metadata"); | ||
var ComponentDecorator_1 = require("./lib/decorators/ComponentDecorator"); | ||
exports.Component = ComponentDecorator_1.Component; | ||
var QualifierDecorator_1 = require("./lib/decorators/QualifierDecorator"); | ||
exports.Qualifier = QualifierDecorator_1.Qualifier; | ||
var ComponentScanDecorator_1 = require("./lib/decorators/ComponentScanDecorator"); | ||
exports.ComponentScan = ComponentScanDecorator_1.ComponentScan; | ||
var ImportDecorator_1 = require("./lib/decorators/ImportDecorator"); | ||
exports.Import = ImportDecorator_1.Import; | ||
var ConfigurationDecorator_1 = require("./lib/decorators/ConfigurationDecorator"); | ||
@@ -12,14 +20,33 @@ exports.Configuration = ConfigurationDecorator_1.Configuration; | ||
exports.Inject = InjectionDecorators_1.Inject; | ||
exports.DynamicInject = InjectionDecorators_1.DynamicInject; | ||
exports.Value = InjectionDecorators_1.Value; | ||
exports.Autowire = InjectionDecorators_1.Autowire; | ||
exports.ThreadLocal = InjectionDecorators_1.ThreadLocal; | ||
var LifeCycleHooksDecorators_1 = require("./lib/decorators/LifeCycleHooksDecorators"); | ||
exports.PostConstruct = LifeCycleHooksDecorators_1.PostConstruct; | ||
exports.PreDestroy = LifeCycleHooksDecorators_1.PreDestroy; | ||
var ProfileDecorators_1 = require("./lib/decorators/ProfileDecorators"); | ||
exports.Profile = ProfileDecorators_1.Profile; | ||
exports.ActiveProfiles = ProfileDecorators_1.ActiveProfiles; | ||
var PropertySourceDecorator_1 = require("./lib/decorators/PropertySourceDecorator"); | ||
exports.PropertySource = PropertySourceDecorator_1.PropertySource; | ||
var ViewDecorator_1 = require("./lib/decorators/ViewDecorator"); | ||
exports.View = ViewDecorator_1.View; | ||
var RequestMappingDecorator_1 = require("./lib/decorators/RequestMappingDecorator"); | ||
exports.RequestMapping = RequestMappingDecorator_1.RequestMapping; | ||
exports.RequestMethod = RequestMappingDecorator_1.RequestMethod; | ||
var InterceptorDecorator_1 = require("./lib/decorators/InterceptorDecorator"); | ||
exports.Interceptor = InterceptorDecorator_1.Interceptor; | ||
var OrderDecorator_1 = require("./lib/decorators/OrderDecorator"); | ||
exports.Order = OrderDecorator_1.Order; | ||
var RequestContext_1 = require("./lib/web/context/RequestContext"); | ||
exports.RequestContext = RequestContext_1.RequestContext; | ||
exports.REQUEST_TOKEN = RequestContext_1.REQUEST_TOKEN; | ||
exports.RESPONSE_TOKEN = RequestContext_1.RESPONSE_TOKEN; | ||
var RequestContextHolder_1 = require("./lib/web/context/RequestContextHolder"); | ||
exports.RequestContextHolder = RequestContextHolder_1.RequestContextHolder; | ||
var ApplicationContext_1 = require("./lib/di/ApplicationContext"); | ||
exports.ApplicationContext = ApplicationContext_1.ApplicationContext; | ||
var Dispatcher_1 = require("./lib/dispatcher/Dispatcher"); | ||
var Dispatcher_1 = require("./lib/web/Dispatcher"); | ||
exports.Dispatcher = Dispatcher_1.Dispatcher; | ||
var InterceptorDecorator_1 = require("./lib/interceptors/InterceptorDecorator"); | ||
exports.Interceptor = InterceptorDecorator_1.Interceptor; | ||
var ComponentDefinitionPostProcessor_1 = require("./lib/processors/ComponentDefinitionPostProcessor"); | ||
@@ -29,2 +56,4 @@ exports.ComponentDefinitionPostProcessor = ComponentDefinitionPostProcessor_1.ComponentDefinitionPostProcessor; | ||
exports.ComponentPostProcessor = ComponentPostProcessor_1.ComponentPostProcessor; | ||
var Environment_1 = require("./lib/di/Environment"); | ||
exports.Environment = Environment_1.Environment; | ||
//# sourceMappingURL=index.js.map |
import { InjectionData } from "./InjectionDecorators"; | ||
export declare class ComponentData { | ||
token: Symbol; | ||
classToken: Symbol; | ||
aliasTokens: Array<Symbol>; | ||
injectionData: InjectionData; | ||
profile: string; | ||
constructor(token?: Symbol); | ||
profiles: Array<string>; | ||
constructor(); | ||
} | ||
export declare const COMPONENT_DECORATOR_TOKEN: symbol; | ||
export declare function Component(token?: Symbol): (target: any) => void; | ||
export declare function Profile(profile: string): (target: any) => void; | ||
export declare function Component(): (target: any) => void; | ||
export declare class ComponentUtil { | ||
static getComponentData(target: any): ComponentData; | ||
static isComponent(target: any): boolean; | ||
static getToken(target: any): Symbol; | ||
static getClassToken(target: any): Symbol; | ||
static getAliasTokens(target: any): Array<Symbol>; | ||
static getInjectionData(target: any): InjectionData; | ||
static isController(target: any): boolean; | ||
static isInterceptor(target: any): boolean; | ||
static isComponentDefinitionPostProcessor(target: any): boolean; | ||
static isComponentPostProcessor(target: any): boolean; | ||
} |
"use strict"; | ||
const InjectionDecorators_1 = require("./InjectionDecorators"); | ||
const ControllerDecorator_1 = require("./ControllerDecorator"); | ||
const InterceptorDecorator_1 = require("../interceptors/InterceptorDecorator"); | ||
const InterceptorDecorator_1 = require("./InterceptorDecorator"); | ||
const ComponentDefinitionPostProcessor_1 = require("../processors/ComponentDefinitionPostProcessor"); | ||
const ComponentPostProcessor_1 = require("../processors/ComponentPostProcessor"); | ||
class ComponentData { | ||
constructor(token) { | ||
this.token = token || Symbol('di_token'); | ||
constructor() { | ||
this.classToken = Symbol('classToken'); | ||
this.aliasTokens = []; | ||
this.profiles = []; | ||
this.injectionData = new InjectionDecorators_1.InjectionData(); | ||
@@ -12,22 +16,16 @@ } | ||
exports.ComponentData = ComponentData; | ||
exports.COMPONENT_DECORATOR_TOKEN = Symbol('component_decorator_token'); | ||
function Component(token) { | ||
const COMPONENT_DECORATOR_TOKEN = Symbol('component_decorator_token'); | ||
function Component() { | ||
return function (target) { | ||
var componentData = new ComponentData(token); | ||
let componentData = new ComponentData(); | ||
componentData.injectionData = InjectionDecorators_1.InjectUtil.initIfDoesntExist(target.prototype); | ||
target[exports.COMPONENT_DECORATOR_TOKEN] = componentData; | ||
target[COMPONENT_DECORATOR_TOKEN] = componentData; | ||
}; | ||
} | ||
exports.Component = Component; | ||
function Profile(profile) { | ||
return function (target) { | ||
if (!ComponentUtil.isComponent(target)) | ||
throw '@Profile can be set only on @Component!'; | ||
ComponentUtil.getComponentData(target).profile = profile; | ||
}; | ||
} | ||
exports.Profile = Profile; | ||
class ComponentUtil { | ||
static getComponentData(target) { | ||
return target[exports.COMPONENT_DECORATOR_TOKEN]; | ||
if (target) { | ||
return target[COMPONENT_DECORATOR_TOKEN]; | ||
} | ||
} | ||
@@ -37,5 +35,8 @@ static isComponent(target) { | ||
} | ||
static getToken(target) { | ||
return this.getComponentData(target).token; | ||
static getClassToken(target) { | ||
return this.getComponentData(target).classToken; | ||
} | ||
static getAliasTokens(target) { | ||
return this.getComponentData(target).aliasTokens; | ||
} | ||
static getInjectionData(target) { | ||
@@ -50,4 +51,10 @@ return this.getComponentData(target).injectionData; | ||
} | ||
static isComponentDefinitionPostProcessor(target) { | ||
return !!target[ComponentDefinitionPostProcessor_1.COMPONENT_DEFINITION_POST_PROCESSOR_DECORATOR_TOKEN]; | ||
} | ||
static isComponentPostProcessor(target) { | ||
return !!target[ComponentPostProcessor_1.COMPONENT_POST_PROCESSOR_DECORATOR_TOKEN]; | ||
} | ||
} | ||
exports.ComponentUtil = ComponentUtil; | ||
//# sourceMappingURL=ComponentDecorator.js.map |
@@ -0,1 +1,13 @@ | ||
import { ProfiledPath } from "./ConfigurationDecorator"; | ||
import { Environment } from "../di/Environment"; | ||
/** | ||
*A decorator for setting up project files to be component-scanned. | ||
* May only be put on @Configuration() classes. | ||
* @param path for the root directory. (For relative paths use __dirname) | ||
*/ | ||
export declare function ComponentScan(path: any): (target: any) => void; | ||
export declare class ComponentScanUtil { | ||
static getComponentsFromPaths(paths: Array<ProfiledPath>, environment: Environment): Set<any>; | ||
private static getModulesStartingFrom(path); | ||
private static getComponentsFromModule(module); | ||
} |
@@ -7,39 +7,57 @@ "use strict"; | ||
const ComponentDecorator_1 = require("./ComponentDecorator"); | ||
// todo revert the logic in the function to match it's name | ||
let getModulesStartingFrom = function* (path) { | ||
let stat = fileSystem.lstatSync(path); | ||
if (stat.isDirectory()) { | ||
// we have a directory: do a tree walk | ||
var files = fileSystem.readdirSync(path); | ||
for (let file of files) { | ||
const RequireUtils_1 = require("../helpers/RequireUtils"); | ||
/** | ||
*A decorator for setting up project files to be component-scanned. | ||
* May only be put on @Configuration() classes. | ||
* @param path for the root directory. (For relative paths use __dirname) | ||
*/ | ||
function ComponentScan(path) { | ||
return function (target) { | ||
if (!ConfigurationDecorator_1.ConfigurationUtil.isConfigurationClass(target)) { | ||
throw new Error('@ComponentScan is allowed on @Configuration classes only!'); | ||
} | ||
ConfigurationDecorator_1.ConfigurationUtil.addComponentScanPath(target, path); | ||
}; | ||
} | ||
exports.ComponentScan = ComponentScan; | ||
class ComponentScanUtil { | ||
static getComponentsFromPaths(paths, environment) { | ||
let result = new Set(); | ||
for (let path of paths) { | ||
if (path.profiles.length === 0 || environment.acceptsProfiles(...path.profiles)) { | ||
for (let module of this.getModulesStartingFrom(path.path)) { | ||
for (let component of this.getComponentsFromModule(module)) { | ||
result.add(component); | ||
} | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
; | ||
static *getModulesStartingFrom(path) { | ||
if (!fileSystem.lstatSync(path).isDirectory()) { | ||
throw new Error(`Given path must be a valid directory. Path: ${path}`); | ||
} | ||
let files = fileSystem.readdirSync(path); | ||
for (let fileName of files) { | ||
let filePath = path_module.join(path, fileName); | ||
let lstat = fileSystem.lstatSync(filePath); | ||
// if it's JavaScript file load it | ||
if (path_module.extname(file) === '.js') { | ||
yield* getModulesStartingFrom(path_module.join(path, file)); | ||
if (lstat.isFile() && path_module.extname(fileName) === '.js') { | ||
console.log(`Loading dynamically by @ComponentScan: ${fileName} (${filePath})`); | ||
yield RequireUtils_1.RequireUtils.require(filePath); | ||
} | ||
if (lstat.isDirectory()) { | ||
yield* this.getModulesStartingFrom(filePath); | ||
} | ||
} | ||
} | ||
else { | ||
console.log('Loading dynamically by ComponentScan: ', path); | ||
yield require(path); | ||
; | ||
static getComponentsFromModule(module) { | ||
return _.filter(module, (exportable) => ComponentDecorator_1.ComponentUtil.isComponent(exportable)); | ||
} | ||
}; | ||
let getComponentsFromModule = function (module) { | ||
return _.filter(module, (exportable) => exportable[ComponentDecorator_1.COMPONENT_DECORATOR_TOKEN]); | ||
}; | ||
let loadComponents = function (path, configurationData) { | ||
for (let module of getModulesStartingFrom(path)) { | ||
for (let component of getComponentsFromModule(module)) { | ||
configurationData.componentFactory.components.push(component); | ||
} | ||
} | ||
}; | ||
function ComponentScan(path) { | ||
return function (target) { | ||
var configurationData = ConfigurationDecorator_1.ConfigurationUtil.getConfigurationData(target); | ||
if (!configurationData) | ||
throw '@ComponentScan is allowed on @Configuration classes only!'; | ||
loadComponents(path, configurationData); | ||
}; | ||
; | ||
} | ||
exports.ComponentScan = ComponentScan; | ||
exports.ComponentScanUtil = ComponentScanUtil; | ||
//# sourceMappingURL=ComponentScanDecorator.js.map |
import { ComponentFactory } from "../di/ComponentFactory"; | ||
export declare const CONFIGURATION_HOLDER_TOKEN: symbol; | ||
import { Environment } from "../di/Environment"; | ||
export declare class ProfiledPath { | ||
profiles: Array<string>; | ||
path: string; | ||
constructor(profiles: Array<string>, path: string); | ||
} | ||
export declare class ConfigurationData { | ||
@@ -7,4 +12,7 @@ componentFactory: ComponentFactory; | ||
componentPostProcessorFactory: ComponentFactory; | ||
properties: Map<string, string>; | ||
componentScanPaths: Array<ProfiledPath>; | ||
propertySourcePaths: Array<ProfiledPath>; | ||
activeProfiles: Array<string>; | ||
constructor(); | ||
loadAllComponents(environment: Environment): void; | ||
} | ||
@@ -14,2 +22,5 @@ export declare function Configuration(): (target: any) => void; | ||
static getConfigurationData(target: any): ConfigurationData; | ||
static isConfigurationClass(target: any): boolean; | ||
static addComponentScanPath(target: any, path: string): void; | ||
static addPropertySourcePath(target: any, path: string): void; | ||
} |
"use strict"; | ||
const ComponentFactory_1 = require("../di/ComponentFactory"); | ||
exports.CONFIGURATION_HOLDER_TOKEN = Symbol('configuration_holder_token'); | ||
const ComponentScanDecorator_1 = require("./ComponentScanDecorator"); | ||
const ComponentDecorator_1 = require("./ComponentDecorator"); | ||
const CONFIGURATION_HOLDER_TOKEN = Symbol('configuration_holder_token'); | ||
class ProfiledPath { | ||
constructor(profiles, path) { | ||
this.profiles = profiles; | ||
this.path = path; | ||
} | ||
} | ||
exports.ProfiledPath = ProfiledPath; | ||
class ConfigurationData { | ||
@@ -9,4 +18,20 @@ constructor() { | ||
this.componentDefinitionPostProcessorFactory = new ComponentFactory_1.ComponentFactory(); | ||
this.properties = new Map(); | ||
this.componentScanPaths = []; | ||
this.propertySourcePaths = []; | ||
this.activeProfiles = []; | ||
} | ||
loadAllComponents(environment) { | ||
ComponentScanDecorator_1.ComponentScanUtil.getComponentsFromPaths(this.componentScanPaths, environment) | ||
.forEach((component) => { | ||
if (ComponentDecorator_1.ComponentUtil.isComponentDefinitionPostProcessor(component)) { | ||
this.componentDefinitionPostProcessorFactory.components.push(component); | ||
} | ||
else if (ComponentDecorator_1.ComponentUtil.isComponentPostProcessor(component)) { | ||
this.componentPostProcessorFactory.components.push(component); | ||
} | ||
else { | ||
this.componentFactory.components.push(component); | ||
} | ||
}); | ||
} | ||
} | ||
@@ -16,5 +41,7 @@ exports.ConfigurationData = ConfigurationData; | ||
return function (target) { | ||
if (target[exports.CONFIGURATION_HOLDER_TOKEN]) | ||
throw 'Duplicate @Configuration decorator'; | ||
target[exports.CONFIGURATION_HOLDER_TOKEN] = new ConfigurationData(); | ||
if (target[CONFIGURATION_HOLDER_TOKEN]) { | ||
throw new Error('Duplicate @Configuration decorator'); | ||
} | ||
ComponentDecorator_1.Component()(target); | ||
target[CONFIGURATION_HOLDER_TOKEN] = new ConfigurationData(); | ||
// todo allow registering components in this target class | ||
@@ -26,8 +53,18 @@ }; | ||
static getConfigurationData(target) { | ||
if (!target[exports.CONFIGURATION_HOLDER_TOKEN]) | ||
if (!this.isConfigurationClass(target)) { | ||
throw new Error('Given target is not a @Configuration class'); | ||
return target[exports.CONFIGURATION_HOLDER_TOKEN]; | ||
} | ||
return target[CONFIGURATION_HOLDER_TOKEN]; | ||
} | ||
static isConfigurationClass(target) { | ||
return !!target[CONFIGURATION_HOLDER_TOKEN]; | ||
} | ||
static addComponentScanPath(target, path) { | ||
this.getConfigurationData(target).componentScanPaths.push(new ProfiledPath(ComponentDecorator_1.ComponentUtil.getComponentData(target).profiles, path)); | ||
} | ||
static addPropertySourcePath(target, path) { | ||
this.getConfigurationData(target).propertySourcePaths.push(new ProfiledPath(ComponentDecorator_1.ComponentUtil.getComponentData(target).profiles, path)); | ||
} | ||
} | ||
exports.ConfigurationUtil = ConfigurationUtil; | ||
//# sourceMappingURL=ConfigurationDecorator.js.map |
export declare const CONTROLLER_DECORATOR_TOKEN: symbol; | ||
export declare function Controller(token?: Symbol): (target: any) => void; | ||
export declare function Controller(): (target: any) => void; |
"use strict"; | ||
const ComponentDecorator_1 = require("./ComponentDecorator"); | ||
exports.CONTROLLER_DECORATOR_TOKEN = Symbol('controller_decorator_token'); | ||
function Controller(token) { | ||
function Controller() { | ||
return function (target) { | ||
ComponentDecorator_1.Component(token)(target); | ||
ComponentDecorator_1.Component()(target); | ||
target[exports.CONTROLLER_DECORATOR_TOKEN] = true; | ||
@@ -8,0 +8,0 @@ }; |
@@ -1,13 +0,22 @@ | ||
export declare const INJECT_DECORATOR_TOKEN: symbol; | ||
export declare class DependencyData { | ||
token: Symbol; | ||
isArray: boolean; | ||
constructor(token: Symbol, isArray: boolean); | ||
} | ||
export declare class InjectionData { | ||
dependencies: Map<string, Symbol>; | ||
dependencies: Map<string, DependencyData>; | ||
dynamicDependencies: Map<string, DependencyData>; | ||
properties: Map<string, string>; | ||
constructor(); | ||
} | ||
export declare function Inject(dependency: any): (target: any, fieldName: string) => void; | ||
export declare function Inject(dependencyToken?: Symbol): (target: any, fieldName: string) => void; | ||
export declare function Autowire(): (target: any, fieldName: string) => void; | ||
export declare function Value(preopertyKey: any): (target: any, fieldName: string) => void; | ||
export declare function DynamicInject(dependencyToken?: Symbol): (target: any, fieldName: string) => void; | ||
export declare function ThreadLocal(): (target: any, fieldName: string) => void; | ||
export declare class InjectUtil { | ||
static getDependencies(target: any): Map<string, Symbol>; | ||
static createDependencyData(token: any, type: any): DependencyData; | ||
static getDependencies(target: any): Map<string, DependencyData>; | ||
static getProperties(target: any): Map<string, string>; | ||
static initIfDoesntExist(target: any): InjectionData; | ||
} |
"use strict"; | ||
const ComponentDecorator_1 = require("./ComponentDecorator"); | ||
exports.INJECT_DECORATOR_TOKEN = Symbol('injector_decorator_token'); | ||
const TypeUtils_1 = require("../helpers/TypeUtils"); | ||
const INJECT_DECORATOR_TOKEN = Symbol('injector_decorator_token'); | ||
class DependencyData { | ||
constructor(token, isArray) { | ||
this.token = token; | ||
this.isArray = isArray; | ||
} | ||
} | ||
exports.DependencyData = DependencyData; | ||
class InjectionData { | ||
constructor() { | ||
this.dependencies = new Map(); | ||
this.dynamicDependencies = new Map(); | ||
this.properties = new Map(); | ||
@@ -11,10 +20,14 @@ } | ||
exports.InjectionData = InjectionData; | ||
function Inject(dependency) { | ||
function Inject(dependencyToken) { | ||
return function (target, fieldName) { | ||
if (!ComponentDecorator_1.ComponentUtil.isComponent(dependency)) | ||
throw new Error('Cannot inject dependency which is not a @Component!'); | ||
InjectUtil.initIfDoesntExist(target).dependencies.set(fieldName, ComponentDecorator_1.ComponentUtil.getToken(dependency)); | ||
let type = Reflect.getMetadata('design:type', target, fieldName); | ||
let dependencyData = InjectUtil.createDependencyData(dependencyToken, type); | ||
InjectUtil.initIfDoesntExist(target).dependencies.set(fieldName, dependencyData); | ||
}; | ||
} | ||
exports.Inject = Inject; | ||
function Autowire() { | ||
return Inject(); | ||
} | ||
exports.Autowire = Autowire; | ||
function Value(preopertyKey) { | ||
@@ -26,3 +39,32 @@ return function (target, fieldName) { | ||
exports.Value = Value; | ||
function DynamicInject(dependencyToken) { | ||
return function (target, fieldName) { | ||
let type = Reflect.getMetadata('design:type', target, fieldName); | ||
let dependencyData = InjectUtil.createDependencyData(dependencyToken, type); | ||
InjectUtil.initIfDoesntExist(target).dynamicDependencies.set(fieldName, dependencyData); | ||
}; | ||
} | ||
exports.DynamicInject = DynamicInject; | ||
function ThreadLocal() { | ||
return function (target, fieldName) { | ||
let className = target.constructor.name; | ||
let token = Symbol(`thread-local:${className}#${fieldName}`); | ||
InjectUtil.initIfDoesntExist(target).dynamicDependencies.set(fieldName, new DependencyData(token, false)); | ||
}; | ||
} | ||
exports.ThreadLocal = ThreadLocal; | ||
class InjectUtil { | ||
static createDependencyData(token, type) { | ||
if (!token) { | ||
// fallback to field type | ||
if (ComponentDecorator_1.ComponentUtil.isComponent(type)) { | ||
token = ComponentDecorator_1.ComponentUtil.getClassToken(type); | ||
} | ||
else { | ||
throw new Error('Cannot inject dependency which is not a @Component!'); | ||
} | ||
} | ||
// NOTE assumption: if type not declared or any then type is Object and isArray is false | ||
return new DependencyData(token, TypeUtils_1.TypeUtils.isA(type, Array)); | ||
} | ||
static getDependencies(target) { | ||
@@ -36,5 +78,6 @@ return this.initIfDoesntExist(target).dependencies; | ||
static initIfDoesntExist(target) { | ||
if (!target[exports.INJECT_DECORATOR_TOKEN]) | ||
target[exports.INJECT_DECORATOR_TOKEN] = new InjectionData(); | ||
return target[exports.INJECT_DECORATOR_TOKEN]; | ||
if (!target[INJECT_DECORATOR_TOKEN]) { | ||
target[INJECT_DECORATOR_TOKEN] = new InjectionData(); | ||
} | ||
return target[INJECT_DECORATOR_TOKEN]; | ||
} | ||
@@ -41,0 +84,0 @@ } |
@@ -1,1 +0,10 @@ | ||
export declare function PropertySource(properties: any): (target: any) => void; | ||
/** | ||
* A decorator for defining a JSON property source for the configuration properties. | ||
* May only be put on @Configuration() classes. | ||
* @param path to the property source. (For relative paths use __dirname) | ||
*/ | ||
export declare function PropertySource(path: string): (target: any) => void; | ||
export declare class PropertySourceUtil { | ||
static getPropertiesFromPaths(...propertySourcePaths: Array<string>): Map<string, string>; | ||
private static parseProperties(properties); | ||
} |
"use strict"; | ||
const _ = require("lodash"); | ||
const ConfigurationDecorator_1 = require("./ConfigurationDecorator"); | ||
const _ = require("lodash"); | ||
const GeneralUtils_1 = require("../helpers/GeneralUtils"); | ||
function parseProperties(properties) { | ||
if (_.isObject(properties)) { | ||
return GeneralUtils_1.GeneralUtils.flattenObject(properties); | ||
} | ||
return new Map(); | ||
} | ||
function PropertySource(properties) { | ||
const RequireUtils_1 = require("../helpers/RequireUtils"); | ||
/** | ||
* A decorator for defining a JSON property source for the configuration properties. | ||
* May only be put on @Configuration() classes. | ||
* @param path to the property source. (For relative paths use __dirname) | ||
*/ | ||
function PropertySource(path) { | ||
return function (target) { | ||
var configurationData = ConfigurationDecorator_1.ConfigurationUtil.getConfigurationData(target); | ||
parseProperties(properties).forEach((value, prop) => configurationData.properties.set(prop, value)); | ||
if (!ConfigurationDecorator_1.ConfigurationUtil.isConfigurationClass(target)) { | ||
throw new Error('@PropertySource can be used only on @Configuration classes.'); | ||
} | ||
ConfigurationDecorator_1.ConfigurationUtil.addPropertySourcePath(target, path); | ||
}; | ||
} | ||
exports.PropertySource = PropertySource; | ||
class PropertySourceUtil { | ||
static getPropertiesFromPaths(...propertySourcePaths) { | ||
let resultPropertiesMap = new Map(); | ||
for (let path of propertySourcePaths) { | ||
console.log(`Loading properties by @PropertySource from "${path}"`); | ||
let properties = RequireUtils_1.RequireUtils.require(path); | ||
this.parseProperties(properties).forEach((value, prop) => resultPropertiesMap.set(prop, value)); | ||
} | ||
return resultPropertiesMap; | ||
} | ||
static parseProperties(properties) { | ||
if (_.isObject(properties)) { | ||
return GeneralUtils_1.GeneralUtils.flattenObject(properties); | ||
} | ||
return new Map(); | ||
} | ||
} | ||
exports.PropertySourceUtil = PropertySourceUtil; | ||
//# sourceMappingURL=PropertySourceDecorator.js.map |
@@ -11,9 +11,10 @@ export declare class RequestMethod { | ||
path: string; | ||
method: string; | ||
method?: string; | ||
} | ||
export declare const ROUTER_CONFIG: symbol; | ||
export declare class RouterConfigItem { | ||
requestConfig: RequestMappingConfig; | ||
methodHandler: string; | ||
view: string; | ||
constructor(requestConfig: RequestMappingConfig, handler: string); | ||
isValid(): string; | ||
} | ||
@@ -23,5 +24,7 @@ export declare class RouterConfig { | ||
} | ||
export declare function RequestMapping(config: RequestMappingConfig): (target: any, method: any) => void; | ||
export declare function RequestMapping(config: RequestMappingConfig): (...args: any[]) => void; | ||
export declare class RequestMappingUtil { | ||
static getRouterConfig(target: any): RouterConfig; | ||
static getValidRoutes(target: any): Array<RouterConfigItem>; | ||
static initRouterConfigIfDoesntExist(target: any): RouterConfig; | ||
static getControllerRequestMappingPath(target: any): any; | ||
} |
"use strict"; | ||
const _ = require("lodash"); | ||
const DecoratorUtils_1 = require("../helpers/DecoratorUtils"); | ||
// NOTE: These are methods defined on the Express Router | ||
@@ -13,3 +15,4 @@ // http://expressjs.com/en/4x/api.html#router | ||
exports.RequestMethod = RequestMethod; | ||
exports.ROUTER_CONFIG = Symbol('router_config'); | ||
const ROUTER_CONFIG = Symbol('router_config'); | ||
const CLASS_ROUTER_CONFIG = Symbol('class_router_config'); | ||
class RouterConfigItem { | ||
@@ -20,2 +23,5 @@ constructor(requestConfig, handler) { | ||
} | ||
isValid() { | ||
return this.requestConfig && this.methodHandler; | ||
} | ||
} | ||
@@ -30,6 +36,26 @@ exports.RouterConfigItem = RouterConfigItem; | ||
function RequestMapping(config) { | ||
return function (target, method) { | ||
if (!target[exports.ROUTER_CONFIG]) | ||
target[exports.ROUTER_CONFIG] = new RouterConfig(); | ||
target[exports.ROUTER_CONFIG].routes.push(new RouterConfigItem(config, method)); | ||
return function (...args) { | ||
let type = DecoratorUtils_1.DecoratorUtil.getType(args); | ||
let target = args[0]; | ||
if (type === DecoratorUtils_1.DecoratorType.METHOD) { | ||
if (config.method === undefined) { | ||
throw new Error("When using @RequestMapping on methods you must provide the request method type"); | ||
} | ||
let method = args[1]; | ||
let routerConfig = RequestMappingUtil.initRouterConfigIfDoesntExist(target); | ||
let routeConfig = _.find(routerConfig.routes, { methodHandler: method }); | ||
if (routeConfig) { | ||
routeConfig.requestConfig = config; | ||
} | ||
else { | ||
routerConfig.routes.push(new RouterConfigItem(config, method)); | ||
} | ||
} | ||
else if (type === DecoratorUtils_1.DecoratorType.CLASS) { | ||
// TODO: refactor when new options are added on @RequestMapping for classes | ||
target[CLASS_ROUTER_CONFIG] = config.path; | ||
} | ||
else { | ||
throw new Error("@RequestMapping decorator can only be used on classes and methods!"); | ||
} | ||
}; | ||
@@ -39,7 +65,17 @@ } | ||
class RequestMappingUtil { | ||
static getRouterConfig(target) { | ||
return target.prototype[exports.ROUTER_CONFIG] || new RouterConfig(); | ||
static getValidRoutes(target) { | ||
let routerConfig = this.initRouterConfigIfDoesntExist(target.prototype); | ||
return _.filter(routerConfig.routes, (route) => route.isValid()); | ||
} | ||
static initRouterConfigIfDoesntExist(target) { | ||
if (_.isUndefined(target[ROUTER_CONFIG])) { | ||
target[ROUTER_CONFIG] = new RouterConfig(); | ||
} | ||
return target[ROUTER_CONFIG]; | ||
} | ||
static getControllerRequestMappingPath(target) { | ||
return target[CLASS_ROUTER_CONFIG] || ""; | ||
} | ||
} | ||
exports.RequestMappingUtil = RequestMappingUtil; | ||
//# sourceMappingURL=RequestMappingDecorator.js.map |
import { Router } from "express"; | ||
import { Environment } from "./Environment"; | ||
export declare class ApplicationContextState { | ||
static NOT_INITIALIZED: string; | ||
static INITIALIZING: string; | ||
static READY: string; | ||
} | ||
export declare class ApplicationContext { | ||
private static ACTIVE_PROFILE_PROPERTY_KEY; | ||
private state; | ||
private injector; | ||
private dispatcher; | ||
private environment; | ||
private configurationData; | ||
private unRegisterExitListenerCallback; | ||
constructor(configurationClass: any); | ||
getComponent<T>(componentClass: any): T; | ||
getComponentWithToken<T>(token: Symbol): T; | ||
getComponentsWithToken<T>(token: Symbol): Array<T>; | ||
getRouter(): Router; | ||
private initializeComponents(configurationData); | ||
private wireComponents(configurationData); | ||
private getActiveComponents(configurationData); | ||
private getActiveProfile(configurationData); | ||
private getConfigurationProperty(configurationData, propertyKey); | ||
getEnvironment(): Environment; | ||
/** | ||
* Starts the application context by initializing the DI components container. | ||
* */ | ||
start(): Promise<void>; | ||
/** | ||
* Manually destroys the application context. Running @PreDestroy method on all components. | ||
*/ | ||
destroy(): Promise<void>; | ||
/** | ||
* Registers hook on process exit event for destroying the application context. | ||
* Registers process.exit() on process SIGINT event. | ||
*/ | ||
registerExitHook(): void; | ||
private initializeComponents(); | ||
private wireComponents(); | ||
private initializeDefinitionPostProcessors(); | ||
private initializePostProcessors(); | ||
private postProcessDefinition(); | ||
private postProcessBeforeInit(); | ||
private postProcessAfterInit(); | ||
private executePostConstruction(); | ||
private executePreDestruction(); | ||
private getActiveComponents(); | ||
private getActiveDefinitionPostProcessors(); | ||
private getActivePostProcessors(); | ||
private getOrderedDefinitionPostProcessors(); | ||
private getOrderedPostProcessors(); | ||
private initializeEnvironment(); | ||
private verifyContextReady(); | ||
} |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments)).next()); | ||
}); | ||
}; | ||
const ConfigurationDecorator_1 = require("../decorators/ConfigurationDecorator"); | ||
const ComponentDecorator_1 = require("../decorators/ComponentDecorator"); | ||
const Injector_1 = require("./Injector"); | ||
const AsyncEngineComponentDefinitionPostProcessor_1 = require("../processors/impl/AsyncEngineComponentDefinitionPostProcessor"); | ||
const Dispatcher_1 = require("../dispatcher/Dispatcher"); | ||
const Dispatcher_1 = require("../web/Dispatcher"); | ||
const _ = require("lodash"); | ||
const LifeCycleHooksDecorators_1 = require("../decorators/LifeCycleHooksDecorators"); | ||
const ProcessHandler_1 = require("../helpers/ProcessHandler"); | ||
const ComponentPostProcessor_1 = require("../processors/ComponentPostProcessor"); | ||
const ComponentDefinitionPostProcessor_1 = require("../processors/ComponentDefinitionPostProcessor"); | ||
const OrderDecorator_1 = require("../decorators/OrderDecorator"); | ||
const Environment_1 = require("./Environment"); | ||
class ApplicationContextState { | ||
} | ||
ApplicationContextState.NOT_INITIALIZED = 'NOT_INITIALIZED'; | ||
ApplicationContextState.INITIALIZING = 'INITIALIZING'; | ||
ApplicationContextState.READY = 'READY'; | ||
exports.ApplicationContextState = ApplicationContextState; | ||
const DynamicDependencyResolver_1 = require("./DynamicDependencyResolver"); | ||
class ApplicationContext { | ||
constructor(configurationClass) { | ||
this.state = ApplicationContextState.NOT_INITIALIZED; | ||
this.injector = new Injector_1.Injector(); | ||
this.dispatcher = new Dispatcher_1.Dispatcher(); | ||
let configurationData = ConfigurationDecorator_1.ConfigurationUtil.getConfigurationData(configurationClass); | ||
this.initializeComponents(configurationData); | ||
this.wireComponents(configurationData); | ||
this.configurationData = ConfigurationDecorator_1.ConfigurationUtil.getConfigurationData(configurationClass); | ||
this.initializeEnvironment(); | ||
this.configurationData.loadAllComponents(this.environment); | ||
} | ||
getComponent(componentClass) { | ||
return this.injector.getComponent(ComponentDecorator_1.ComponentUtil.getToken(componentClass)); | ||
this.verifyContextReady(); | ||
return this.injector.getComponent(ComponentDecorator_1.ComponentUtil.getClassToken(componentClass)); | ||
} | ||
getComponentWithToken(token) { | ||
this.verifyContextReady(); | ||
return this.injector.getComponent(token); | ||
} | ||
getComponentsWithToken(token) { | ||
this.verifyContextReady(); | ||
return this.injector.getComponents(token); | ||
} | ||
getRouter() { | ||
this.verifyContextReady(); | ||
return this.dispatcher.getRouter(); | ||
} | ||
initializeComponents(configurationData) { | ||
var asyncEngine = AsyncEngineComponentDefinitionPostProcessor_1.AsyncEngineComponentDefinitionPostProcessor.getInstance(); | ||
for (let CompConstructor of this.getActiveComponents(configurationData)) { | ||
var componentData = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor); | ||
// todo pass the comp constructor through the registered definition post processors | ||
// configurationData.componentDefinitionPostProcessorFactory | ||
var PostProcessedComponentConstructor = asyncEngine.postProcessDefinition(CompConstructor); | ||
let instance = new PostProcessedComponentConstructor(); | ||
this.injector.register(componentData.token, instance); | ||
getEnvironment() { | ||
return this.environment; | ||
} | ||
/** | ||
* Starts the application context by initializing the DI components container. | ||
* */ | ||
start() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.state !== ApplicationContextState.NOT_INITIALIZED) { | ||
console.warn("Application context was already initialized or it is initializing at the moment."); | ||
} | ||
yield this.initializeDefinitionPostProcessors(); | ||
yield this.initializePostProcessors(); | ||
yield this.postProcessDefinition(); | ||
this.state = ApplicationContextState.INITIALIZING; | ||
yield this.initializeComponents(); | ||
yield this.wireComponents(); | ||
yield this.postProcessBeforeInit(); | ||
yield this.executePostConstruction(); | ||
yield this.dispatcher.postConstruct(); | ||
yield this.postProcessAfterInit(); | ||
this.state = ApplicationContextState.READY; | ||
}); | ||
} | ||
/** | ||
* Manually destroys the application context. Running @PreDestroy method on all components. | ||
*/ | ||
destroy() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.state === ApplicationContextState.READY) { | ||
yield this.executePreDestruction(); | ||
} | ||
this.dispatcher = null; | ||
this.injector = null; | ||
if (_.isFunction(this.unRegisterExitListenerCallback)) { | ||
this.unRegisterExitListenerCallback(); | ||
} | ||
this.state = ApplicationContextState.NOT_INITIALIZED; | ||
}); | ||
} | ||
/** | ||
* Registers hook on process exit event for destroying the application context. | ||
* Registers process.exit() on process SIGINT event. | ||
*/ | ||
registerExitHook() { | ||
this.unRegisterExitListenerCallback = ProcessHandler_1.ProcessHandler.getInstance().registerOnExitListener(() => this.destroy()); | ||
} | ||
initializeComponents() { | ||
for (let CompConstructor of this.getActiveComponents()) { | ||
let componentData = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor); | ||
let instance = new CompConstructor(); | ||
this.injector.register(componentData.classToken, instance); | ||
for (let token of componentData.aliasTokens) { | ||
this.injector.register(token, instance); | ||
} | ||
} | ||
} | ||
wireComponents(configurationData) { | ||
for (let CompConstructor of this.getActiveComponents(configurationData)) { | ||
var componentData = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor); | ||
var instance = this.injector.getComponent(componentData.token); | ||
// todo throw if injections fails => early failure | ||
wireComponents() { | ||
for (let CompConstructor of this.getActiveComponents()) { | ||
let componentData = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor); | ||
let injectionData = ComponentDecorator_1.ComponentUtil.getInjectionData(CompConstructor); | ||
injectionData.dependencies.forEach((dependencyToken, fieldName) => { | ||
Reflect.set(instance, fieldName, this.injector.getComponent(dependencyToken)); | ||
let instance = this.injector.getComponent(componentData.classToken); | ||
injectionData.dependencies.forEach((dependencyData, fieldName) => { | ||
let dependency = dependencyData.isArray ? this.injector.getComponents(dependencyData.token) : | ||
this.injector.getComponent(dependencyData.token); | ||
Reflect.set(instance, fieldName, dependency); | ||
}); | ||
injectionData.dynamicDependencies.forEach((dependencyData, fieldName) => { | ||
let dynamicResolver = new DynamicDependencyResolver_1.DynamicDependencyResolver(this.injector, dependencyData); | ||
Object.defineProperty(instance, fieldName, dynamicResolver.getPropertyDescriptor()); | ||
}); | ||
injectionData.properties.forEach((propertyKey, fieldName) => { | ||
Reflect.set(instance, fieldName, this.getConfigurationProperty(configurationData, propertyKey)); | ||
Reflect.set(instance, fieldName, this.environment.getProperty(propertyKey)); | ||
}); | ||
this.dispatcher.processAfterInit(CompConstructor, instance); | ||
// todo pass through the post processors configurationData.componentPostProcessorFactory | ||
this.injector.register(componentData.token, instance); | ||
} | ||
} | ||
getActiveComponents(configurationData) { | ||
let activeProfile = this.getActiveProfile(configurationData); | ||
return _.filter(configurationData.componentFactory.components, (CompConstructor) => { | ||
let profile = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor).profile; | ||
if (profile) | ||
return profile === activeProfile; | ||
initializeDefinitionPostProcessors() { | ||
for (let CompConstructor of this.getActiveDefinitionPostProcessors()) { | ||
let componentData = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor); | ||
let instance = new CompConstructor(); | ||
if (!ComponentDefinitionPostProcessor_1.ComponentDefinitionPostProcessorUtil.isIComponentDefinitionPostProcessor(instance)) { | ||
throw new Error('Components annotated with @ComponentDefinitionPostProcessor must implement the ' + | ||
'IComponentDefinitionPostProcessor interface'); | ||
} | ||
this.injector.register(componentData.classToken, instance); | ||
for (let token of componentData.aliasTokens) { | ||
this.injector.register(token, instance); | ||
} | ||
} | ||
} | ||
initializePostProcessors() { | ||
for (let CompConstructor of this.getActivePostProcessors()) { | ||
let componentData = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor); | ||
let instance = new CompConstructor(); | ||
if (!ComponentPostProcessor_1.ComponentPostProcessorUtil.isIComponentPostProcessor(instance)) { | ||
throw new Error('Components annotated with @ComponentPostProcessor must implement the ' + | ||
'IComponentPostProcessor interface'); | ||
} | ||
this.injector.register(componentData.classToken, instance); | ||
for (let token of componentData.aliasTokens) { | ||
this.injector.register(token, instance); | ||
} | ||
} | ||
} | ||
postProcessDefinition() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.configurationData.componentFactory.components = _.map(this.configurationData.componentFactory.components, (componentDefinition) => { | ||
for (let componentDefinitionPostProcessor of this.getOrderedDefinitionPostProcessors()) { | ||
let result = componentDefinitionPostProcessor.postProcessDefinition(componentDefinition); | ||
if (_.isFunction(result)) { | ||
componentDefinition = result; | ||
} | ||
else if (!_.isUndefined(result)) { | ||
throw new Error('Component Definition Post Processor must return a constructor function'); | ||
} | ||
} | ||
return componentDefinition; | ||
}); | ||
}); | ||
} | ||
postProcessBeforeInit() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
for (let componentPostProcessor of this.getOrderedPostProcessors()) { | ||
for (let componentConstructor of this.getActiveComponents()) { | ||
let componentData = ComponentDecorator_1.ComponentUtil.getComponentData(componentConstructor); | ||
let instance = this.injector.getComponent(componentData.classToken); | ||
componentPostProcessor.postProcessBeforeInit(instance); | ||
} | ||
} | ||
}); | ||
} | ||
postProcessAfterInit() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
for (let componentPostProcessor of this.getOrderedPostProcessors()) { | ||
for (let componentConstructor of this.getActiveComponents()) { | ||
let componentData = ComponentDecorator_1.ComponentUtil.getComponentData(componentConstructor); | ||
let instance = this.injector.getComponent(componentData.classToken); | ||
componentPostProcessor.postProcessAfterInit(instance); | ||
} | ||
} | ||
}); | ||
} | ||
executePostConstruction() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let postConstructInvocations = []; | ||
for (let CompConstructor of this.getActiveComponents()) { | ||
let componentData = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor); | ||
let postConstructMethod = LifeCycleHooksDecorators_1.LifeCycleHooksUtil.getConfig(CompConstructor).postConstructMethod; | ||
if (postConstructMethod) { | ||
let instance = this.injector.getComponent(componentData.classToken); | ||
if (!_.isFunction(instance[postConstructMethod])) { | ||
throw new Error(`@PostConstruct is not on a method (${postConstructMethod})`); | ||
} | ||
let invocationResult = instance[postConstructMethod](); | ||
postConstructInvocations.push(invocationResult); | ||
} | ||
} | ||
yield Promise.all(postConstructInvocations); | ||
}); | ||
} | ||
executePreDestruction() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let preDestroyInvocations = []; | ||
for (let CompConstructor of this.getActiveComponents()) { | ||
let componentData = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor); | ||
let preDestroyMethod = LifeCycleHooksDecorators_1.LifeCycleHooksUtil.getConfig(CompConstructor).preDestroyMethod; | ||
if (preDestroyMethod) { | ||
let instance = this.injector.getComponent(componentData.classToken); | ||
if (!_.isFunction(instance[preDestroyMethod])) { | ||
throw new Error(`@PreDestroy is not on a method (${preDestroyMethod})`); | ||
} | ||
let invocationResult = instance[preDestroyMethod](); | ||
preDestroyInvocations.push(invocationResult); | ||
} | ||
} | ||
yield Promise.all(preDestroyInvocations); | ||
}); | ||
} | ||
getActiveComponents() { | ||
return _.filter(this.configurationData.componentFactory.components, (CompConstructor) => { | ||
let profiles = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor).profiles; | ||
if (profiles.length > 0) { | ||
let notUsedProfiles = _.map(_.filter(profiles, (profile) => (profile[0] === '!')), (profile) => profile.substr(1)); | ||
return _.some(notUsedProfiles, (profile) => !this.environment.acceptsProfiles(profile)) | ||
|| this.environment.acceptsProfiles(...profiles); | ||
} | ||
return true; | ||
}); | ||
} | ||
getActiveProfile(configurationData) { | ||
return this.getConfigurationProperty(configurationData, ApplicationContext.ACTIVE_PROFILE_PROPERTY_KEY); | ||
getActiveDefinitionPostProcessors() { | ||
let activeProfiles = this.environment.getActiveProfiles(); | ||
let definitionPostProcessors = _.filter(this.configurationData.componentDefinitionPostProcessorFactory.components, (CompConstructor) => { | ||
let profiles = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor).profiles; | ||
if (profiles.length === 0) { | ||
return true; | ||
} | ||
for (let profile of profiles) { | ||
for (let activeProfile of activeProfiles) { | ||
return profile === activeProfile; | ||
} | ||
} | ||
}); | ||
return OrderDecorator_1.OrderUtil.orderList(definitionPostProcessors); | ||
} | ||
getConfigurationProperty(configurationData, propertyKey) { | ||
return process.env[propertyKey] || configurationData.properties.get(propertyKey); | ||
getActivePostProcessors() { | ||
let activeProfiles = this.environment.getActiveProfiles(); | ||
let postProcessors = _.filter(this.configurationData.componentPostProcessorFactory.components, (CompConstructor) => { | ||
let profiles = ComponentDecorator_1.ComponentUtil.getComponentData(CompConstructor).profiles; | ||
if (profiles.length === 0) { | ||
return true; | ||
} | ||
for (let profile of profiles) { | ||
for (let activeProfile of activeProfiles) { | ||
return profile === activeProfile; | ||
} | ||
} | ||
}); | ||
return OrderDecorator_1.OrderUtil.orderList(postProcessors); | ||
} | ||
// return the definitionPostProcessors ordered by the value extracted if it implements the IOrdered interface | ||
getOrderedDefinitionPostProcessors() { | ||
let definitionPostProcessors = []; | ||
for (let componentDefinitionPostProcessor of this.getActiveDefinitionPostProcessors()) { | ||
let componentData = ComponentDecorator_1.ComponentUtil.getComponentData(componentDefinitionPostProcessor); | ||
let definitionPostProcessor = this.injector | ||
.getComponent(componentData.classToken); | ||
definitionPostProcessors.push(definitionPostProcessor); | ||
} | ||
return definitionPostProcessors; | ||
} | ||
// return the postProcessors ordered by the value extracted if it implements the IOrdered interface | ||
getOrderedPostProcessors() { | ||
let postProcessors = []; | ||
for (let componentPostProcessor of this.getActivePostProcessors()) { | ||
let componentData = ComponentDecorator_1.ComponentUtil.getComponentData(componentPostProcessor); | ||
let postProcessor = this.injector.getComponent(componentData.classToken); | ||
postProcessors.push(postProcessor); | ||
} | ||
return postProcessors; | ||
} | ||
initializeEnvironment() { | ||
this.environment = new Environment_1.Environment(); | ||
this.environment.setActiveProfiles(...this.configurationData.activeProfiles); | ||
this.environment.setApplicationProperties(this.configurationData.propertySourcePaths); | ||
this.injector.register(ComponentDecorator_1.ComponentUtil.getComponentData(Environment_1.Environment).classToken, this.environment); | ||
} | ||
verifyContextReady() { | ||
if (this.state !== ApplicationContextState.READY) { | ||
throw new Error('Application context is not yet initialized. Start method needs to be called first.'); | ||
} | ||
} | ||
} | ||
ApplicationContext.ACTIVE_PROFILE_PROPERTY_KEY = 'application.profiles.active'; | ||
exports.ApplicationContext = ApplicationContext; | ||
//# sourceMappingURL=ApplicationContext.js.map |
@@ -6,2 +6,3 @@ export declare class Injector { | ||
getComponent(token: Symbol): Object; | ||
getComponents(token: Symbol): Array<Object>; | ||
} |
"use strict"; | ||
const _ = require("lodash"); | ||
class Injector { | ||
@@ -7,9 +8,23 @@ constructor() { | ||
register(token, component) { | ||
this.components.set(token, component); | ||
if (!this.components.has(token)) { | ||
this.components.set(token, []); | ||
} | ||
this.components.get(token).push(component); | ||
} | ||
// TODO: user should know for which type the error is thrown | ||
getComponent(token) { | ||
return this.components.get(token); | ||
let components = this.components.get(token); | ||
if (_.isUndefined(components)) { | ||
throw new Error('No such component'); | ||
} | ||
if (components.length > 1) { | ||
throw new Error(`Ambiguous injection. ${components.length} components found in the injector.`); | ||
} | ||
return components[0]; | ||
} | ||
getComponents(token) { | ||
return this.components.get(token) || []; | ||
} | ||
} | ||
exports.Injector = Injector; | ||
//# sourceMappingURL=Injector.js.map |
@@ -5,10 +5,14 @@ "use strict"; | ||
static flattenObject(ob) { | ||
var flatMap = new Map(); | ||
let flatMap = new Map(); | ||
_.forEach(ob, (value, prop) => { | ||
if (_.isString(value)) | ||
flatMap.set(prop, value); | ||
if (_.isObject(value)) { | ||
if (_.isPlainObject(value)) { | ||
this.flattenObject(value) | ||
.forEach((value, key) => flatMap.set(`${prop}.${key}`, value)); | ||
} | ||
else if (_.isArray(value)) { | ||
flatMap.set(prop, value.join(',')); | ||
} | ||
else { | ||
flatMap.set(prop, value); | ||
} | ||
}); | ||
@@ -15,0 +19,0 @@ return flatMap; |
@@ -11,4 +11,4 @@ "use strict"; | ||
static getClassHierarchy(clazz) { | ||
var prototypeChain = []; | ||
var currentType = clazz; | ||
let prototypeChain = []; | ||
let currentType = clazz; | ||
while (currentType.name !== '') { | ||
@@ -15,0 +15,0 @@ prototypeChain.push(currentType); |
@@ -1,5 +0,8 @@ | ||
export interface ComponentDefinitionPostProcessor { | ||
export interface IComponentDefinitionPostProcessor { | ||
postProcessDefinition(componentConstructor: any): any; | ||
} | ||
export declare const COMPONENT_DEFINITION_POST_PROCESSOR_DECORATOR_TOKEN: symbol; | ||
export declare function ComponentDefinitionPostProcessor(token?: Symbol): (target: any) => void; | ||
export declare function ComponentDefinitionPostProcessor(): (target: any) => void; | ||
export declare class ComponentDefinitionPostProcessorUtil { | ||
static isIComponentDefinitionPostProcessor(arg: any): arg is IComponentDefinitionPostProcessor; | ||
} |
"use strict"; | ||
const ComponentDecorator_1 = require("../decorators/ComponentDecorator"); | ||
exports.COMPONENT_DEFINITION_POST_PROCESSOR_DECORATOR_TOKEN = Symbol('component_definition_post_processor_decorator_token'); | ||
function ComponentDefinitionPostProcessor(token) { | ||
function ComponentDefinitionPostProcessor() { | ||
return function (target) { | ||
ComponentDecorator_1.Component(token)(target); | ||
ComponentDecorator_1.Component()(target); | ||
target[exports.COMPONENT_DEFINITION_POST_PROCESSOR_DECORATOR_TOKEN] = true; | ||
@@ -11,2 +11,8 @@ }; | ||
exports.ComponentDefinitionPostProcessor = ComponentDefinitionPostProcessor; | ||
class ComponentDefinitionPostProcessorUtil { | ||
static isIComponentDefinitionPostProcessor(arg) { | ||
return arg.postProcessDefinition !== undefined; | ||
} | ||
} | ||
exports.ComponentDefinitionPostProcessorUtil = ComponentDefinitionPostProcessorUtil; | ||
//# sourceMappingURL=ComponentDefinitionPostProcessor.js.map |
@@ -1,2 +0,2 @@ | ||
export interface ComponentPostProcessor { | ||
export interface IComponentPostProcessor { | ||
postProcessBeforeInit(componentConstructor: any): any; | ||
@@ -6,2 +6,5 @@ postProcessAfterInit(componentConstructor: any): any; | ||
export declare const COMPONENT_POST_PROCESSOR_DECORATOR_TOKEN: symbol; | ||
export declare function ComponentPostProcessor(token?: Symbol): (target: any) => void; | ||
export declare function ComponentPostProcessor(): (target: any) => void; | ||
export declare class ComponentPostProcessorUtil { | ||
static isIComponentPostProcessor(arg: any): arg is IComponentPostProcessor; | ||
} |
"use strict"; | ||
const ComponentDecorator_1 = require("../decorators/ComponentDecorator"); | ||
exports.COMPONENT_POST_PROCESSOR_DECORATOR_TOKEN = Symbol('component_definition_post_processor_decorator_token'); | ||
function ComponentPostProcessor(token) { | ||
function ComponentPostProcessor() { | ||
return function (target) { | ||
ComponentDecorator_1.Component(token)(target); | ||
ComponentDecorator_1.Component()(target); | ||
target[exports.COMPONENT_POST_PROCESSOR_DECORATOR_TOKEN] = true; | ||
@@ -11,2 +11,8 @@ }; | ||
exports.ComponentPostProcessor = ComponentPostProcessor; | ||
class ComponentPostProcessorUtil { | ||
static isIComponentPostProcessor(arg) { | ||
return (arg.postProcessBeforeInit !== undefined) && (arg.postProcessAfterInit !== undefined); | ||
} | ||
} | ||
exports.ComponentPostProcessorUtil = ComponentPostProcessorUtil; | ||
//# sourceMappingURL=ComponentPostProcessor.js.map |
{ | ||
"name": "@sklechko/framework", | ||
"version": "0.0.1", | ||
"version": "0.1.0", | ||
"description": "Lightweight web framework inspired by Spring framework.", | ||
"author": "Sashe Klechkovski <sasko_dh@hotmail.com>", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/saskodh/framework.git" | ||
}, | ||
"license": "MIT", | ||
@@ -10,7 +14,15 @@ "keywords": [], | ||
"clean": "rm -rf dist", | ||
"build": "npm run clean && npm run tsc && npm run test && npm run prepare", | ||
"test": "tsc && mocha --recursive ./dist/test", | ||
"tsc": "tsc --declaration", | ||
"typings": "typings install", | ||
"disable_zonejs_typings": "ts-node ./scripts/disable_zonejs_typings.ts", | ||
"build": "npm run clean && tsc && npm run lint && npm run test && npm run prepare", | ||
"test:clean": "rm -rf coverage", | ||
"test:run": "istanbul cover node_modules/mocha/bin/_mocha --report none -- --recursive ./dist", | ||
"test:coverage:lcov": "remap-istanbul -i ./coverage/coverage.json -o ./coverage/lcov.info -t lcovonly", | ||
"test:coverage:html": "remap-istanbul -i ./coverage/coverage.json -o ./coverage/html-report -t html", | ||
"test:coverage": "npm run test:coverage:lcov && npm run test:coverage:html", | ||
"test": "tsc && npm run test:clean && npm run test:run && npm run test:coverage", | ||
"lint": "tslint ./src/**/*.ts", | ||
"prepare": "cp package.json typings.json README.md ./dist/src", | ||
"_prepublish": "typings install && npm run build" | ||
"_prepublish": "npm run build", | ||
"postinstall": "npm run typings && npm run disable_zonejs_typings" | ||
}, | ||
@@ -22,12 +34,19 @@ "engines": { | ||
"express": "^4.14.0", | ||
"lodash": "^4.12.0" | ||
"lodash": "^4.12.0", | ||
"reflect-metadata": "^0.1.3", | ||
"zone.js": "^0.6.15" | ||
}, | ||
"devDependencies": { | ||
"chai": "3.5.0", | ||
"coveralls": "2.11.11", | ||
"istanbul": "0.4.4", | ||
"mocha": "2.5.3", | ||
"remap-istanbul": "0.6.4", | ||
"sinon": "1.17.4", | ||
"ts-node": "0.9.1", | ||
"typescript": "1.8.10" | ||
"tslint": "3.13.0", | ||
"typescript": "1.8.10", | ||
"typings": "1.3.2" | ||
}, | ||
"typings": "./index.d.ts" | ||
} |
@@ -1,1 +0,6 @@ | ||
Lightweight web framework inspired by Spring framework. | ||
Lightweight web framework inspired by Spring framework. | ||
[![Build Status](https://travis-ci.org/saskodh/framework.svg?branch=master)](https://travis-ci.org/saskodh/framework) | ||
[![Coverage Status](https://coveralls.io/repos/github/saskodh/framework/badge.svg?branch=master)](https://coveralls.io/github/saskodh/framework?branch=master) | ||
[![Join the chat at https://gitter.im/saskodh/framework](https://badges.gitter.im/saskodh/framework.svg)](https://gitter.im/saskodh/framework?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) |
@@ -6,11 +6,15 @@ { | ||
"lodash": "registry:dt/lodash#3.10.0+20160330154726", | ||
"node": "registry:dt/node#6.0.0+20160514165920" | ||
"node": "registry:dt/node#6.0.0+20160514165920", | ||
"zone.js": "registry:dt/zone.js#0.0.0+20160316155526" | ||
}, | ||
"globalDevDependencies": { | ||
"body-parser": "registry:dt/body-parser#0.0.0+20160317120654", | ||
"chai": "registry:dt/chai#3.4.0+20160601211834", | ||
"express": "registry:dt/express#4.0.0+20160317120654", | ||
"express-serve-static-core": "registry:dt/express-serve-static-core#0.0.0+20160322035842", | ||
"mime": "registry:dt/mime#0.0.0+20160316155526", | ||
"serve-static": "registry:dt/serve-static#0.0.0+20160501131543" | ||
"mocha": "registry:dt/mocha#2.2.5+20160619032855", | ||
"serve-static": "registry:dt/serve-static#0.0.0+20160501131543", | ||
"sinon": "registry:dt/sinon#1.16.0+20160517064723" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
144520
108
2038
6
3
4
10
1
1
+ Addedreflect-metadata@^0.1.3
+ Addedzone.js@^0.6.15
+ Addedreflect-metadata@0.1.14(transitive)
+ Addedzone.js@0.6.26(transitive)