import { Doc, DocListCast } from '../../fields/Doc'; import { List } from '../../fields/List'; import { listSpec } from '../../fields/Schema'; import { Cast, StrCast } from '../../fields/Types'; import { Docs } from '../documents/Documents'; import { ScriptingGlobals } from './ScriptingGlobals'; export class ScriptManager { static _initialized = false; // eslint-disable-next-line no-use-before-define private static _instance: ScriptManager; public static get Instance(): ScriptManager { // eslint-disable-next-line no-return-assign return this._instance || (this._instance = new this()); } private constructor() { if (!ScriptManager._initialized) { ScriptManager._initialized = true; this.getAllScripts().forEach(scriptDoc => ScriptManager.addScriptToGlobals(scriptDoc)); } } public get ScriptManagerDoc(): Doc | undefined { return Docs.Prototypes.MainScriptDocument(); } public getAllScripts(): Doc[] { const sdoc = ScriptManager.Instance.ScriptManagerDoc; return sdoc ? DocListCast(sdoc.data) : []; } public addScript(scriptDoc: Doc): boolean { const scriptList = this.getAllScripts(); scriptList.push(scriptDoc); if (ScriptManager.Instance.ScriptManagerDoc) { ScriptManager.Instance.ScriptManagerDoc.data = new List(scriptList); ScriptManager.addScriptToGlobals(scriptDoc); return true; } return false; } public deleteScript(scriptDoc: Doc): boolean { if (scriptDoc.name) { ScriptingGlobals.removeGlobal(StrCast(scriptDoc.name)); } const scriptList = this.getAllScripts(); const index = scriptList.indexOf(scriptDoc); if (index > -1) { scriptList.splice(index, 1); if (ScriptManager.Instance.ScriptManagerDoc) { ScriptManager.Instance.ScriptManagerDoc.data = new List(scriptList); return true; } } return false; } public static addScriptToGlobals(scriptDoc: Doc): void { ScriptingGlobals.removeGlobal(StrCast(scriptDoc.name)); const params = Cast(scriptDoc['data-params'], listSpec('string'), []); const paramNames = params.reduce((o: string, p: string) => { let out = o; if (params.indexOf(p) === params.length - 1) { out += p.split(':')[0].trim(); } else { out += p.split(':')[0].trim() + ','; } return out; }, '' as string); // eslint-disable-next-line no-new-func const f = new Function(paramNames, StrCast(scriptDoc.script)); Object.defineProperty(f, 'name', { value: StrCast(scriptDoc.name), writable: false }); let parameters = '('; params.forEach((element: string, i: number) => { if (i === params.length - 1) { parameters = parameters + element + ')'; } else { parameters = parameters + element + ', '; } }); if (parameters === '(') { ScriptingGlobals.add(f, StrCast(scriptDoc.description)); } else { ScriptingGlobals.add(f, StrCast(scriptDoc.description), parameters); } } }