UNPKG

@atomist/automation-client

Version:

Atomist API for software low-level client

254 lines (228 loc) • 8.25 kB
import { Group, ParameterType, } from "../../metadata/automationMetadata"; import { registerCommand, registerEvent, } from "../../scan"; export interface BaseParameter { readonly pattern?: RegExp; readonly required?: boolean; readonly description?: string; readonly displayName?: string; readonly validInput?: string; readonly displayable?: boolean; readonly maxLength?: number; readonly minLength?: number; readonly type?: ParameterType; readonly order?: number; readonly group?: Group; readonly control?: "input" | "textarea"; } export interface Parameter extends BaseParameter { readonly name: string; // readonly default?: string; } export interface BaseValue { path: string; required?: boolean; type?: "string" | "number" | "boolean"; } function set_metadata(obj: any, key: string, value: any) { let target = obj; if (!!obj.prototype) { // should only be true for class Decorators target = obj.prototype; } Object.defineProperty(target, key, { value, writable: false, enumerable: false, configurable: false, }); } function get_metadata(obj: any, key: string) { if (!obj) { return null; } let desc = Object.getOwnPropertyDescriptor(obj, key); if (!desc && !!Object.getPrototypeOf(obj)) { desc = get_metadata(Object.getPrototypeOf(obj), key); } if (!!desc) { return desc.value; } return null; } export function declareParameter(target: any, propertyKey: string, details: BaseParameter) { let params: any[] = get_metadata(target, "__parameters"); if (!params) { params = []; } else { // remove any that have the same name already (i.e. if folk are calling declareParameter) // use a cheeky method so that we can reuse the same array const found: any[] = params.filter(p => p.name === propertyKey); if (!!found && found.length > 0) { const index = params.indexOf(found[0]); params.splice(index, 1); } } const copy: any = { ...details }; // Make required = true the default copy.required = copy.required !== undefined && copy.required !== null ? copy.required : true; copy.name = propertyKey; params.push(copy); // merge parameters from parent if it has some let parent = Object.getPrototypeOf(target); while (!!parent) { const protoParams: any[] = get_metadata(parent, "__parameters"); if (!!protoParams) { protoParams.forEach(protoParam => { // if we don't already have a parameter with the same name if (!params.some(param => param.name === protoParam.name)) { params.push(protoParam); } }); } parent = Object.getPrototypeOf(parent); } set_metadata(target, "__parameters", params); return target; } export function declareMappedParameter(target: any, name: string, uri: string, required: boolean) { let params = get_metadata(target, "__mappedParameters"); if (!params) { params = []; } else { // remove any that have the same name already (i.e. if folk are calling declareMappedParameter) // use a cheeky method so that we can reuse the same array const found: any[] = params.filter(p => p.localKey === name); if (!!found && found.length > 0) { const index = params.indexOf(found[0]); params.splice(index, 1); } } const param = { name, uri, required }; params.push(param); // merge mapped_parameters from parent if it has some let parent = Object.getPrototypeOf(target); while (!!parent) { const protoParams: any[] = get_metadata(parent, "__mappedParameters"); if (!!protoParams) { protoParams.forEach(protoParam => { // if we don't already have a parameter with the same name if (!params.some(p => p.name === protoParam.name)) { params.push(protoParam); } }); } parent = Object.getPrototypeOf(parent); } set_metadata(target, "__mappedParameters", params); return target; } export function declareValue(target: any, name: string, value: BaseValue) { let params = get_metadata(target, "__values"); if (!params) { params = []; } else { // remove any that have the same name already (i.e. if folk are calling declareValue) // use a cheeky method so that we can reuse the same array const found: any[] = params.filter(p => p.localKey === name); if (!!found && found.length > 0) { const index = params.indexOf(found[0]); params.splice(index, 1); } } const param = { name, value }; params.push(param); // merge values from parent if it has some let parent = Object.getPrototypeOf(target); while (!!parent) { const protoParams: any[] = get_metadata(parent, "__values"); if (!!protoParams) { protoParams.forEach(protoParam => { // if we don't already have a value with the same name if (!params.some(p => p.name === protoParam.name)) { params.push(protoParam); } }); } parent = Object.getPrototypeOf(parent); } set_metadata(target, "__values", params); return target; } export function declareSecret(target: any, name: string, uri: string) { let params = get_metadata(target, "__secrets"); if (!params) { params = []; } else { // remove any that have the same name already (i.e. if folk are calling declareSecret) // use a cheeky method so that we can reuse the same array const found: any[] = params.filter(p => p.name === name); if (!!found && found.length > 0) { const index = params.indexOf(found[0]); params.splice(index, 1); } } const param = { name, uri }; params.push(param); // merge secrets from parent if it has some let parent = Object.getPrototypeOf(target); while (!!parent) { const protoParams: any[] = get_metadata(parent, "__secrets"); if (!!protoParams) { protoParams.forEach(protoParam => { // if we don't already have a parameter with the same name if (!params.some(p => p.name === protoParam.name)) { params.push(protoParam); } }); } parent = Object.getPrototypeOf(parent); } set_metadata(target, "__secrets", params); return target; } export function declareCommandHandler(obj: any, description: string, autoSubmit: boolean, intent?: string[]) { declareRug(obj, "command-handler", description); declareIntent(obj, intent); if (autoSubmit) { declareAutoSubmit(obj, autoSubmit); } registerCommand(obj); return obj; } export function declareParameters(obj: any) { set_metadata(obj, "__name", obj.prototype.constructor.name); set_metadata(obj, "__kind", "parameters"); return obj; } type RugKind = "command-handler" | "event-handler"; function declareRug(obj: any, kind: RugKind, description: string) { set_metadata(obj, "__description", description); set_metadata(obj, "__name", obj.prototype.constructor.name); set_metadata(obj, "__kind", kind); } export function declareEventHandler( obj: any, description: string, subscription: string) { declareRug(obj, "event-handler", description); set_metadata(obj, "__subscription", subscription); registerEvent(obj); return obj; } export function declareTags(target: any, tags: string[]) { set_metadata(target, "__tags", tags.map(t => ({ name: t, description: t }))); return target; } export function declareIntent(target: any, intent: string[]) { set_metadata(target, "__intent", intent); return target; } export function declareAutoSubmit(target: any, autoSubmit: boolean) { set_metadata(target, "__autoSubmit", autoSubmit); return target; }