rws-js-client
Version:
client for RWS frontend
112 lines (83 loc) • 3.64 kB
text/typescript
import { DI, InterfaceSymbol, inject, Key } from '@microsoft/fast-foundation';
import RWSViewComponent, { IWithCompose } from './_component';
import RWSContainer from './_container';
import 'reflect-metadata';
type Constructor<T = any> = new (...args: any[]) => T;
interface RWSDecoratorOptions {
template?: string,
styles?: string,
fastElementOptions?: any,
ignorePackaging?: boolean
}
type InjectDecoratorReturnType = (target: any, key?: string | number | undefined, parameterIndex?: number) => void;
const _PARAMTYPES_METADATA_KEY = 'design:paramtypes';
function RWSInject<T extends RWSViewComponent>(dependencyClass: Key): InjectDecoratorReturnType {
return (target: IWithCompose<T>, key?: keyof IWithCompose<T>, parameterIndex?: number) => {
const loadedDependency = RWSContainer().get(dependencyClass);
const paramNames = getFunctionParamNames(target.prototype.constructor);
target.prototype.constructor._toInject[paramNames[parameterIndex]] = loadedDependency;
};
}
function RWSView<T extends RWSViewComponent>(name: string, data?: RWSDecoratorOptions): (type: any) => void {
return (constructor: T) => {
};
}
function RWSIgnore(params: { mergeToApp?: boolean } = null): () => void {
return () => { };
}
function getFunctionParamNames(func: Function): string[] {
// Convert the function to its string form and extract the parameter names
const funcStr = func.toString().replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s))/mg, '');
return funcStr.slice(funcStr.indexOf('(')+1, funcStr.indexOf(')')).split(',');
}
function getParentConstructor(instance: any): any
{
const proto = Object.getPrototypeOf(instance.constructor.prototype);
if (proto && proto.constructor) {
return proto.constructor;
}
return null;
}
const applyConstructor = (component: RWSViewComponent): void => {
let mainConstructor = component.constructor;
const parent = getParentConstructor(component);
if(!mainConstructor.length){
mainConstructor = parent;
}
let topConstructor = mainConstructor;
if( parent && parent.name === RWSViewComponent.name){
topConstructor = parent;
}
const existingInjectedDependencies = (topConstructor as IWithCompose<RWSViewComponent>)._toInject;
Object.keys(existingInjectedDependencies).forEach((depKey: string) => {
const loadedDependency = existingInjectedDependencies[depKey];
if(!(component as any)[depKey]){
(component as any)[depKey] = loadedDependency;
}
});
};
const applyProp = (component: RWSViewComponent, propName: string | symbol): any => {
let mainConstructor = component.constructor;
const parent = getParentConstructor(component);
if(!mainConstructor.length){
mainConstructor = parent;
}
let topConstructor = mainConstructor;
if( parent && parent.name === RWSViewComponent.name){
topConstructor = parent;
}
if(typeof propName !== 'string'){
propName = propName.toString();
}
const existingInjectedDependencies = (topConstructor as IWithCompose<RWSViewComponent>)._toInject;
// console.log(propName);
if(!Object.keys(existingInjectedDependencies).includes(propName)){
return null;
}
const loadedDependency = existingInjectedDependencies[propName];
if(!(component as any)[propName]){
(component as any)[propName] = loadedDependency;
}
return loadedDependency;
};
export { RWSView, RWSDecoratorOptions, RWSIgnore, RWSInject, applyConstructor, applyProp }