-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathutils.ts
More file actions
128 lines (103 loc) · 4.73 KB
/
Copy pathutils.ts
File metadata and controls
128 lines (103 loc) · 4.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import CSInterfaceBase from "./index";
/*
* This is needed if the return type of the original method is other than `void` and we want to change it.
* @link https://github.com/Microsoft/TypeScript/issues/4544
* type CSInterfaceWithoutEval = new() => { [P in Exclude<keyof CSInterfaceBase, 'evalScript'>] : CSInterfaceBase[P] }
* const CSInterfaceWithoutEval: CSInterfaceWithoutEval = CSInterfaceBase;
* class CSInterface extends CSInterfaceWithoutEval {}
*/
class CSInterface extends CSInterfaceBase {
/**
* @param {string} script
* @param {...*} args
*
* @return {Promise<*>}
*/
// TODO: Generic function evalScript<T extends (...args: any[]) => any>(script: string, ...args: Parameters<T>): void
evalScript(script: string, ...args: unknown[]): Promise<any>;
evalScript(script: string, callback?: (result?: any) => void): Promise<any> {
/**
* @param {*} value
*/
function escape(value: undefined | string | number | object | boolean): any {
switch (typeof value) {
case 'undefined':
return '"null"';
case 'string':
return JSON.stringify(value);
case 'number': {
if (Number.isNaN(value) || Infinity === value) {
return 0;
}
return value;
}
case 'object': {
if (value === null) {
return '"null"';
}
return escape(JSON.stringify(value));
}
case 'boolean': {
return value;
}
default:
throw TypeError(`Nicht unterstützter Typ "${typeof value}"`);
}
}
const args = Array.from(arguments);
// Hole den Befehl oder den Funktionsnamen
let eval_string = args.shift().trim();
// Der Nutzer hat mehr als 1 Parameter angegeben,
// a) Entweder eine callback, wenn du Funktion wie die original Function von CSInterface verwendet wird
// b) Andere Typen wenn die Funktion automatisch die Parameter einer Funktion escapen soll
let user_callback: any = null;
if (args.length > 0) {
if (typeof args[0] === 'function') {
// a)
user_callback = args.shift();
} else {
// b)
// Prüfe ob der Nutzer vielleicht bereits die runden Klammern "()" angegeben hat und entferne die
if (eval_string.length >= 3 && eval_string.substr(-3) === '();') {
eval_string = eval_string.substr(0, eval_string.length - 3);
} else if (eval_string.length >= 2 && eval_string.substr(-2) === '()') {
eval_string = eval_string.substr(0, eval_string.length - 2);
}
eval_string += `(${args.map(param => escape(param)).join(', ')});`;
}
}
return new Promise((resolve, reject) => {
// Ermöglicht es eine genauere Fehlermeldung zu erhalten ("e" besitzt noch folgende Eigenschaften: start, end, source, fileName, number)
// Von der Fehlerzeile müssen wir 1 abziehen, da der Try/Catch-Block mitgezählt wird
const script = `try {
${eval_string}
} catch(e) {
'{"error": "' + e.name + '", "message": "' + e.message.replace(/"/g, \"'\") + '", "line": "' + (e.line ? e.line - 1: -1) + '", "stack": "' + (e.stack ? e.stack.replace(/"/g, \"'\") : \"\") + '"}'
}`;
super.evalScript(script, (result: any) => {
// Wenn der Nutzer eine eigene Callback angegeben hat (evalScript legacy support)
if (user_callback) {
return resolve(user_callback(result) || result);
}
if (typeof result === 'string' && result === CSInterfaceBase.EvalScript_ErrMessage) {
return reject(result);
}
if (typeof result === 'string' && result.length > 0) {
try {
const obj = JSON.parse(result);
if (typeof obj.error === 'string') {
return reject(obj);
}
return resolve(JSON.parse(result));
} catch (e) {
// Ignoriere Parse Error und gebe den String zurück
}
}
return resolve(result);
});
});
}
// @TODO: loadBinAsync, loadBinSync -> Promise
}
export {CSInterface}
export default CSInterface