import { Arr, Optional, Strings } from '@ephox/katamari'; interface Annotation { readonly name: string; readonly parameters: string[]; } export type FunctionWithAnnotation = T & { toFunctionAnnotation?: () => Annotation }; const markAsBehaviourApi = (f: T, apiName: string, apiFunction: Function): FunctionWithAnnotation => { const delegate = apiFunction.toString(); const endIndex = delegate.indexOf(')') + 1; const openBracketIndex = delegate.indexOf('('); const parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\s*/); (f as FunctionWithAnnotation).toFunctionAnnotation = () => ({ name: apiName, parameters: cleanParameters(parameters.slice(0, 1).concat(parameters.slice(3))) }); return f; }; // Remove any comment (/*) at end of parameter names const cleanParameters = (parameters: string[]) => Arr.map(parameters, (p) => Strings.endsWith(p, '/*') ? p.substring(0, p.length - '/*'.length) : p); const markAsExtraApi = (f: T, extraName: string): FunctionWithAnnotation => { const delegate = f.toString(); const endIndex = delegate.indexOf(')') + 1; const openBracketIndex = delegate.indexOf('('); const parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\s*/); (f as FunctionWithAnnotation).toFunctionAnnotation = () => ({ name: extraName, parameters: cleanParameters(parameters) }); return f; }; const markAsSketchApi = (f: T, apiFunction: Function): FunctionWithAnnotation => { const delegate = apiFunction.toString(); const endIndex = delegate.indexOf(')') + 1; const openBracketIndex = delegate.indexOf('('); const parameters = delegate.substring(openBracketIndex + 1, endIndex - 1).split(/,\s*/); (f as FunctionWithAnnotation).toFunctionAnnotation = () => ({ name: 'OVERRIDE', parameters: cleanParameters(parameters.slice(1)) }); return f; }; const getAnnotation = (f: FunctionWithAnnotation): Optional => Optional.from(f.toFunctionAnnotation?.()); export { markAsBehaviourApi, markAsExtraApi, markAsSketchApi, getAnnotation };