@snipsonian/core
Version:
Core/base reusable javascript code snippets
53 lines (42 loc) • 1.78 kB
text/typescript
import isArray from '../../is/isArray';
import isUndefined from '../../is/isUndefined';
import { TDecorator } from '../index';
export interface IBuilderOptions {
initialBuildParams?: object;
buildStateName?: string;
}
export interface IBuilder<Result = object> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
getBuildParam: (key: string) => any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
with: (key: string, val: any) => IBuilder<Result>;
build: () => Result;
}
export default function builder({
initialBuildParams = {},
buildStateName = '_builder',
}: IBuilderOptions = {}): TDecorator {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return function decorate(target: any) {
if (isArray(target)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return target.map((entity: any) => enrichToBeBuilder(entity, { initialBuildParams, buildStateName }));
}
return enrichToBeBuilder(target, { initialBuildParams, buildStateName });
};
}
function enrichToBeBuilder(target: object, { initialBuildParams, buildStateName }: IBuilderOptions): IBuilder {
const enrichedTarget = target as IBuilder;
if (isUndefined(enrichedTarget[buildStateName])) {
enrichedTarget[buildStateName] = initialBuildParams;
} else {
Object.assign(enrichedTarget[buildStateName], initialBuildParams);
}
enrichedTarget.with = (key, val) => {
enrichedTarget[buildStateName][key] = val;
return enrichedTarget;
};
enrichedTarget.getBuildParam = (key) => enrichedTarget[buildStateName][key];
enrichedTarget.build = () => enrichedTarget[buildStateName];
return enrichedTarget;
}