starlight-cli 1.1.16 → 1.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +376 -2
- package/package.json +1 -1
- package/src/evaluator.js +375 -1
- package/src/starlight.js +1 -1
package/dist/index.js
CHANGED
|
@@ -10213,7 +10213,6 @@ const fs = __nccwpck_require__(896);
|
|
|
10213
10213
|
const Lexer = __nccwpck_require__(211);
|
|
10214
10214
|
const Parser = __nccwpck_require__(222);
|
|
10215
10215
|
const path = __nccwpck_require__(928);
|
|
10216
|
-
|
|
10217
10216
|
class ReturnValue {
|
|
10218
10217
|
constructor(value) { this.value = value; }
|
|
10219
10218
|
}
|
|
@@ -10414,7 +10413,51 @@ formatValue(value, seen = new Set()) {
|
|
|
10414
10413
|
if (arg && typeof arg === 'object') return Object.keys(arg).length;
|
|
10415
10414
|
return 0;
|
|
10416
10415
|
});
|
|
10416
|
+
this.global.define('lower', arg => {
|
|
10417
|
+
if (typeof arg !== 'string') return String(arg).toLowerCase();
|
|
10418
|
+
return arg.toLowerCase();
|
|
10419
|
+
});
|
|
10420
|
+
this.global.define('toStr', arg => String(arg));
|
|
10421
|
+
|
|
10422
|
+
this.global.define('upper', arg => {
|
|
10423
|
+
if (typeof arg !== 'string') return String(arg).toUpperCase();
|
|
10424
|
+
return arg.toUpperCase();
|
|
10425
|
+
});
|
|
10426
|
+
|
|
10427
|
+
this.global.define('trim', arg => {
|
|
10428
|
+
if (typeof arg !== 'string') return String(arg).trim();
|
|
10429
|
+
return arg.trim();
|
|
10430
|
+
});
|
|
10431
|
+
|
|
10432
|
+
this.global.define('startsWith', (str, prefix) => {
|
|
10433
|
+
if (typeof str !== 'string') str = String(str);
|
|
10434
|
+
if (typeof prefix !== 'string') prefix = String(prefix);
|
|
10435
|
+
return str.startsWith(prefix);
|
|
10436
|
+
});
|
|
10417
10437
|
|
|
10438
|
+
this.global.define('endsWith', (str, suffix) => {
|
|
10439
|
+
if (typeof str !== 'string') str = String(str);
|
|
10440
|
+
if (typeof suffix !== 'string') suffix = String(suffix);
|
|
10441
|
+
return str.endsWith(suffix);
|
|
10442
|
+
});
|
|
10443
|
+
|
|
10444
|
+
this.global.define('includes', (str, substr) => {
|
|
10445
|
+
if (typeof str !== 'string') str = String(str);
|
|
10446
|
+
if (typeof substr !== 'string') substr = String(substr);
|
|
10447
|
+
return str.includes(substr);
|
|
10448
|
+
});
|
|
10449
|
+
|
|
10450
|
+
this.global.define('repeat', (str, times) => {
|
|
10451
|
+
if (typeof str !== 'string') str = String(str);
|
|
10452
|
+
return str.repeat(Number(times) || 0);
|
|
10453
|
+
});
|
|
10454
|
+
|
|
10455
|
+
this.global.define('replace', (str, search, replacement) => {
|
|
10456
|
+
if (typeof str !== 'string') str = String(str);
|
|
10457
|
+
if (typeof search !== 'string') search = String(search);
|
|
10458
|
+
if (typeof replacement !== 'string') replacement = String(replacement);
|
|
10459
|
+
return str.split(search).join(replacement);
|
|
10460
|
+
});
|
|
10418
10461
|
this.global.define('print', arg => { console.log(arg); return null; });
|
|
10419
10462
|
this.global.define('type', arg => {
|
|
10420
10463
|
if (Array.isArray(arg)) return 'array';
|
|
@@ -10563,6 +10606,72 @@ this.global.define('range', (...args) => {
|
|
|
10563
10606
|
|
|
10564
10607
|
return result;
|
|
10565
10608
|
});
|
|
10609
|
+
this.global.define('floor', arg => Math.floor(Number(arg)));
|
|
10610
|
+
this.global.define('ceil', arg => Math.ceil(Number(arg)));
|
|
10611
|
+
this.global.define('round', arg => Math.round(Number(arg)));
|
|
10612
|
+
this.global.define('abs', arg => Math.abs(Number(arg)));
|
|
10613
|
+
this.global.define('pow', (base, exp) => Math.pow(Number(base), Number(exp)));
|
|
10614
|
+
this.global.define('sqrt', arg => Math.sqrt(Number(arg)));
|
|
10615
|
+
this.global.define('min', (...args) => Math.min(...args.map(Number)));
|
|
10616
|
+
this.global.define('max', (...args) => Math.max(...args.map(Number)));
|
|
10617
|
+
this.global.define('randomFloat', (min, max) => {
|
|
10618
|
+
min = Number(min); max = Number(max);
|
|
10619
|
+
if (isNaN(min) || isNaN(max)) return 0;
|
|
10620
|
+
return Math.random() * (max - min) + min;
|
|
10621
|
+
});
|
|
10622
|
+
|
|
10623
|
+
this.global.define('push', (arr, val) => {
|
|
10624
|
+
if (!Array.isArray(arr)) throw new RuntimeError('push() expects an array', null, this.source);
|
|
10625
|
+
arr.push(val); return arr.length;
|
|
10626
|
+
});
|
|
10627
|
+
this.global.define('pop', arr => {
|
|
10628
|
+
if (!Array.isArray(arr)) throw new RuntimeError('pop() expects an array', null, this.source);
|
|
10629
|
+
return arr.pop();
|
|
10630
|
+
});
|
|
10631
|
+
this.global.define('shift', arr => {
|
|
10632
|
+
if (!Array.isArray(arr)) throw new RuntimeError('shift() expects an array', null, this.source);
|
|
10633
|
+
return arr.shift();
|
|
10634
|
+
});
|
|
10635
|
+
this.global.define('unshift', (arr, val) => {
|
|
10636
|
+
if (!Array.isArray(arr)) throw new RuntimeError('unshift() expects an array', null, this.source);
|
|
10637
|
+
arr.unshift(val); return arr.length;
|
|
10638
|
+
});
|
|
10639
|
+
this.global.define('sort', (arr, fn) => {
|
|
10640
|
+
if (!Array.isArray(arr)) throw new RuntimeError('sort() expects an array', null, this.source);
|
|
10641
|
+
if (fn && typeof fn === 'function') return arr.sort(fn);
|
|
10642
|
+
return arr.sort();
|
|
10643
|
+
});
|
|
10644
|
+
this.global.define('reverse', arr => {
|
|
10645
|
+
if (!Array.isArray(arr)) throw new RuntimeError('reverse() expects an array', null, this.source);
|
|
10646
|
+
return arr.reverse();
|
|
10647
|
+
});
|
|
10648
|
+
|
|
10649
|
+
this.global.define('has', (obj, key) => obj && typeof obj === 'object' ? obj.hasOwnProperty(key) : false);
|
|
10650
|
+
this.global.define('merge', (obj1, obj2) => {
|
|
10651
|
+
if (!obj1 || typeof obj1 !== 'object') obj1 = {};
|
|
10652
|
+
if (!obj2 || typeof obj2 !== 'object') obj2 = {};
|
|
10653
|
+
return { ...obj1, ...obj2 };
|
|
10654
|
+
});
|
|
10655
|
+
|
|
10656
|
+
this.global.define('uuid', () => {
|
|
10657
|
+
// simple random UUID v4
|
|
10658
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
|
10659
|
+
const r = Math.random() * 16 | 0;
|
|
10660
|
+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
10661
|
+
return v.toString(16);
|
|
10662
|
+
});
|
|
10663
|
+
});
|
|
10664
|
+
this.global.define('timestamp', () => Date.now());
|
|
10665
|
+
this.global.define('clone', arg => {
|
|
10666
|
+
if (Array.isArray(arg)) return [...arg];
|
|
10667
|
+
if (arg && typeof arg === 'object') return { ...arg };
|
|
10668
|
+
return arg; // primitive types
|
|
10669
|
+
});
|
|
10670
|
+
this.global.define('typeOf', arg => {
|
|
10671
|
+
if (arg === null) return 'null';
|
|
10672
|
+
if (Array.isArray(arg)) return 'array';
|
|
10673
|
+
return typeof arg;
|
|
10674
|
+
});
|
|
10566
10675
|
|
|
10567
10676
|
this.global.define('ask', prompt => {
|
|
10568
10677
|
const readlineSync = __nccwpck_require__(552);
|
|
@@ -10619,6 +10728,271 @@ this.global.define('sleep', async (ms) => {
|
|
|
10619
10728
|
this.global.define('str', arg => {
|
|
10620
10729
|
return String(arg);
|
|
10621
10730
|
});
|
|
10731
|
+
this.global.define('now', () => Date.now());
|
|
10732
|
+
this.global.define('formatDate', (timestamp, locale = 'en-US', options = {}) => {
|
|
10733
|
+
if (timestamp === null || timestamp === undefined) timestamp = Date.now();
|
|
10734
|
+
const t = typeof timestamp === 'number' ? timestamp : Number(timestamp);
|
|
10735
|
+
if (isNaN(t)) t = Date.now();
|
|
10736
|
+
return new Date(t).toLocaleString(locale, options);
|
|
10737
|
+
});
|
|
10738
|
+
|
|
10739
|
+
this.global.define('readFile', path => {
|
|
10740
|
+
if (typeof path !== 'string') path = String(path);
|
|
10741
|
+
try {
|
|
10742
|
+
return fs.readFileSync(path, 'utf-8');
|
|
10743
|
+
} catch (e) {
|
|
10744
|
+
throw new RuntimeError('readFile error: ' + e.message, null, this.source);
|
|
10745
|
+
}
|
|
10746
|
+
});
|
|
10747
|
+
this.global.define('writeFile', (path, content) => {
|
|
10748
|
+
if (typeof path !== 'string') path = String(path);
|
|
10749
|
+
if (typeof content !== 'string') content = String(content);
|
|
10750
|
+
try {
|
|
10751
|
+
fs.writeFileSync(path, content, 'utf-8');
|
|
10752
|
+
return true;
|
|
10753
|
+
} catch (e) {
|
|
10754
|
+
throw new RuntimeError('writeFile error: ' + e.message, null, this.source);
|
|
10755
|
+
}
|
|
10756
|
+
});
|
|
10757
|
+
|
|
10758
|
+
this.global.define('split', (str, separator) => {
|
|
10759
|
+
if (typeof str !== 'string') str = String(str);
|
|
10760
|
+
if (separator === undefined) separator = '';
|
|
10761
|
+
return str.split(separator);
|
|
10762
|
+
});
|
|
10763
|
+
|
|
10764
|
+
this.global.define('join', (arr, separator = '') => {
|
|
10765
|
+
if (!Array.isArray(arr)) throw new RuntimeError('join() expects an array', null, this.source);
|
|
10766
|
+
return arr.join(separator);
|
|
10767
|
+
});
|
|
10768
|
+
|
|
10769
|
+
this.global.define('substring', (str, start, end) => {
|
|
10770
|
+
if (typeof str !== 'string') str = String(str);
|
|
10771
|
+
start = Number(start) || 0;
|
|
10772
|
+
end = end !== undefined ? Number(end) : undefined;
|
|
10773
|
+
return str.substring(start, end);
|
|
10774
|
+
});
|
|
10775
|
+
|
|
10776
|
+
this.global.define('padStart', (str, targetLength, padString = ' ') => {
|
|
10777
|
+
if (typeof str !== 'string') str = String(str);
|
|
10778
|
+
targetLength = Number(targetLength) || 0;
|
|
10779
|
+
return str.padStart(targetLength, padString);
|
|
10780
|
+
});
|
|
10781
|
+
|
|
10782
|
+
this.global.define('padEnd', (str, targetLength, padString = ' ') => {
|
|
10783
|
+
if (typeof str !== 'string') str = String(str);
|
|
10784
|
+
targetLength = Number(targetLength) || 0;
|
|
10785
|
+
return str.padEnd(targetLength, padString);
|
|
10786
|
+
});
|
|
10787
|
+
this.global.define('unique', arr => {
|
|
10788
|
+
if (!Array.isArray(arr)) throw new RuntimeError('unique() expects an array', null, this.source);
|
|
10789
|
+
return [...new Set(arr)];
|
|
10790
|
+
});
|
|
10791
|
+
|
|
10792
|
+
this.global.define('indexOf', (arr, val) => {
|
|
10793
|
+
if (!Array.isArray(arr)) throw new RuntimeError('indexOf() expects an array', null, this.source);
|
|
10794
|
+
return arr.indexOf(val);
|
|
10795
|
+
});
|
|
10796
|
+
|
|
10797
|
+
this.global.define('includesArr', (arr, val) => {
|
|
10798
|
+
if (!Array.isArray(arr)) throw new RuntimeError('includesArr() expects an array', null, this.source);
|
|
10799
|
+
return arr.includes(val);
|
|
10800
|
+
});
|
|
10801
|
+
|
|
10802
|
+
this.global.define('flatten', arr => {
|
|
10803
|
+
if (!Array.isArray(arr)) throw new RuntimeError('flatten() expects an array', null, this.source);
|
|
10804
|
+
return arr.flat(Infinity);
|
|
10805
|
+
});
|
|
10806
|
+
|
|
10807
|
+
this.global.define('randomChoice', arr => {
|
|
10808
|
+
if (!Array.isArray(arr)) throw new RuntimeError('randomChoice() expects an array', null, this.source);
|
|
10809
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
10810
|
+
});
|
|
10811
|
+
|
|
10812
|
+
this.global.define('entries', obj => {
|
|
10813
|
+
if (!obj || typeof obj !== 'object') throw new RuntimeError('entries() expects an object', null, this.source);
|
|
10814
|
+
return Object.entries(obj);
|
|
10815
|
+
});
|
|
10816
|
+
|
|
10817
|
+
this.global.define('invert', obj => {
|
|
10818
|
+
if (!obj || typeof obj !== 'object') throw new RuntimeError('invert() expects an object', null, this.source);
|
|
10819
|
+
const result = {};
|
|
10820
|
+
for (const key in obj) result[obj[key]] = key;
|
|
10821
|
+
return result;
|
|
10822
|
+
});
|
|
10823
|
+
|
|
10824
|
+
this.global.define('isEmpty', arg => {
|
|
10825
|
+
if (arg == null) return true;
|
|
10826
|
+
if (Array.isArray(arg) || typeof arg === 'string') return arg.length === 0;
|
|
10827
|
+
if (typeof arg === 'object') return Object.keys(arg).length === 0;
|
|
10828
|
+
return false;
|
|
10829
|
+
});
|
|
10830
|
+
|
|
10831
|
+
this.global.define('deepClone', arg => {
|
|
10832
|
+
return JSON.parse(JSON.stringify(arg));
|
|
10833
|
+
});
|
|
10834
|
+
|
|
10835
|
+
this.global.define('capitalize', str => {
|
|
10836
|
+
if (typeof str !== 'string') str = String(str);
|
|
10837
|
+
if (str.length === 0) return '';
|
|
10838
|
+
return str[0].toUpperCase() + str.slice(1);
|
|
10839
|
+
});
|
|
10840
|
+
|
|
10841
|
+
this.global.define('reverseStr', str => {
|
|
10842
|
+
if (typeof str !== 'string') str = String(str);
|
|
10843
|
+
return str.split('').reverse().join('');
|
|
10844
|
+
});
|
|
10845
|
+
|
|
10846
|
+
this.global.define('trimStart', str => {
|
|
10847
|
+
if (typeof str !== 'string') str = String(str);
|
|
10848
|
+
return str.trimStart();
|
|
10849
|
+
});
|
|
10850
|
+
|
|
10851
|
+
this.global.define('trimEnd', str => {
|
|
10852
|
+
if (typeof str !== 'string') str = String(str);
|
|
10853
|
+
return str.trimEnd();
|
|
10854
|
+
});
|
|
10855
|
+
|
|
10856
|
+
this.global.define('clamp', (value, min, max) => {
|
|
10857
|
+
value = Number(value); min = Number(min); max = Number(max);
|
|
10858
|
+
return Math.min(Math.max(value, min), max);
|
|
10859
|
+
});
|
|
10860
|
+
|
|
10861
|
+
this.global.define('sign', value => {
|
|
10862
|
+
value = Number(value);
|
|
10863
|
+
return Math.sign(value);
|
|
10864
|
+
});
|
|
10865
|
+
|
|
10866
|
+
this.global.define('appendFile', (path, content) => {
|
|
10867
|
+
if (typeof path !== 'string') path = String(path);
|
|
10868
|
+
if (typeof content !== 'string') content = String(content);
|
|
10869
|
+
try {
|
|
10870
|
+
fs.appendFileSync(path, content, 'utf-8');
|
|
10871
|
+
return true;
|
|
10872
|
+
} catch (e) {
|
|
10873
|
+
throw new RuntimeError('appendFile error: ' + e.message, null, this.source);
|
|
10874
|
+
}
|
|
10875
|
+
});
|
|
10876
|
+
|
|
10877
|
+
this.global.define('exists', path => {
|
|
10878
|
+
if (typeof path !== 'string') path = String(path);
|
|
10879
|
+
return fs.existsSync(path);
|
|
10880
|
+
});
|
|
10881
|
+
|
|
10882
|
+
this.global.define('mkdir', path => {
|
|
10883
|
+
if (typeof path !== 'string') path = String(path);
|
|
10884
|
+
if (!fs.existsSync(path)) fs.mkdirSync(path, { recursive: true });
|
|
10885
|
+
return true;
|
|
10886
|
+
});
|
|
10887
|
+
this.global.define('count', (arr, value) => {
|
|
10888
|
+
if (!Array.isArray(arr)) throw new RuntimeError('count() expects an array', null, this.source);
|
|
10889
|
+
return arr.filter(x => x === value).length;
|
|
10890
|
+
});
|
|
10891
|
+
|
|
10892
|
+
this.global.define('uniqueBy', (arr, fn) => {
|
|
10893
|
+
if (!Array.isArray(arr)) throw new RuntimeError('uniqueBy() expects an array', null, this.source);
|
|
10894
|
+
const seen = new Set();
|
|
10895
|
+
const result = [];
|
|
10896
|
+
for (const item of arr) {
|
|
10897
|
+
const key = fn ? fn(item) : item;
|
|
10898
|
+
if (!seen.has(key)) {
|
|
10899
|
+
seen.add(key);
|
|
10900
|
+
result.push(item);
|
|
10901
|
+
}
|
|
10902
|
+
}
|
|
10903
|
+
return result;
|
|
10904
|
+
});
|
|
10905
|
+
this.global.define('getProp', (obj, key, defaultValue = null) => {
|
|
10906
|
+
if (!obj || typeof obj !== 'object') return defaultValue;
|
|
10907
|
+
const keys = key.split('.');
|
|
10908
|
+
let current = obj;
|
|
10909
|
+
for (const k of keys) {
|
|
10910
|
+
if (current[k] === undefined) return defaultValue;
|
|
10911
|
+
current = current[k];
|
|
10912
|
+
}
|
|
10913
|
+
return current;
|
|
10914
|
+
});
|
|
10915
|
+
|
|
10916
|
+
this.global.define('setProp', (obj, key, value) => {
|
|
10917
|
+
if (!obj || typeof obj !== 'object') throw new RuntimeError('setProp() expects an object', null, this.source);
|
|
10918
|
+
const keys = key.split('.');
|
|
10919
|
+
let current = obj;
|
|
10920
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
10921
|
+
if (!current[keys[i]] || typeof current[keys[i]] !== 'object') current[keys[i]] = {};
|
|
10922
|
+
current = current[keys[i]];
|
|
10923
|
+
}
|
|
10924
|
+
current[keys[keys.length - 1]] = value;
|
|
10925
|
+
return obj;
|
|
10926
|
+
});
|
|
10927
|
+
|
|
10928
|
+
this.global.define('mergeDeep', (obj1, obj2) => {
|
|
10929
|
+
const isObject = val => val && typeof val === 'object';
|
|
10930
|
+
const result = {...obj1};
|
|
10931
|
+
for (const key in obj2) {
|
|
10932
|
+
if (isObject(obj2[key]) && isObject(result[key])) {
|
|
10933
|
+
result[key] = this.global.get('mergeDeep')(result[key], obj2[key]);
|
|
10934
|
+
} else {
|
|
10935
|
+
result[key] = obj2[key];
|
|
10936
|
+
}
|
|
10937
|
+
}
|
|
10938
|
+
return result;
|
|
10939
|
+
});
|
|
10940
|
+
this.global.define('camelCase', str => {
|
|
10941
|
+
if (typeof str !== 'string') str = String(str);
|
|
10942
|
+
return str
|
|
10943
|
+
.replace(/[-_ ]+./g, s => s.charAt(s.length - 1).toUpperCase())
|
|
10944
|
+
.replace(/^[A-Z]/, s => s.toLowerCase());
|
|
10945
|
+
});
|
|
10946
|
+
|
|
10947
|
+
this.global.define('kebabCase', str => {
|
|
10948
|
+
if (typeof str !== 'string') str = String(str);
|
|
10949
|
+
return str
|
|
10950
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
10951
|
+
.replace(/\s+/g, '-')
|
|
10952
|
+
.replace(/_+/g, '-')
|
|
10953
|
+
.toLowerCase();
|
|
10954
|
+
});
|
|
10955
|
+
|
|
10956
|
+
this.global.define('repeatStr', (str, times) => {
|
|
10957
|
+
if (typeof str !== 'string') str = String(str);
|
|
10958
|
+
return str.repeat(Number(times) || 0);
|
|
10959
|
+
});
|
|
10960
|
+
this.global.define('randomInt', (min, max) => {
|
|
10961
|
+
min = Number(min); max = Number(max);
|
|
10962
|
+
if (isNaN(min) || isNaN(max)) return 0;
|
|
10963
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
10964
|
+
});
|
|
10965
|
+
|
|
10966
|
+
this.global.define('lerp', (a, b, t) => {
|
|
10967
|
+
a = Number(a); b = Number(b); t = Number(t);
|
|
10968
|
+
return a + (b - a) * t;
|
|
10969
|
+
});
|
|
10970
|
+
|
|
10971
|
+
this.global.define('degToRad', deg => Number(deg) * (Math.PI / 180));
|
|
10972
|
+
this.global.define('radToDeg', rad => Number(rad) * (180 / Math.PI));
|
|
10973
|
+
this.global.define('readJSON', path => {
|
|
10974
|
+
const content = this.global.get('readFile')(path);
|
|
10975
|
+
return JSON.parse(content);
|
|
10976
|
+
});
|
|
10977
|
+
|
|
10978
|
+
this.global.define('writeJSON', (path, obj) => {
|
|
10979
|
+
const content = JSON.stringify(obj, null, 2);
|
|
10980
|
+
return this.global.get('writeFile')(path, content);
|
|
10981
|
+
});
|
|
10982
|
+
|
|
10983
|
+
this.global.define('deleteFile', path => {
|
|
10984
|
+
if (typeof path !== 'string') path = String(path);
|
|
10985
|
+
if (!fs.existsSync(path)) return false;
|
|
10986
|
+
fs.unlinkSync(path);
|
|
10987
|
+
return true;
|
|
10988
|
+
});
|
|
10989
|
+
|
|
10990
|
+
this.global.define('rmdir', path => {
|
|
10991
|
+
if (typeof path !== 'string') path = String(path);
|
|
10992
|
+
if (!fs.existsSync(path)) return false;
|
|
10993
|
+
fs.rmSync(path, { recursive: true, force: true });
|
|
10994
|
+
return true;
|
|
10995
|
+
});
|
|
10622
10996
|
|
|
10623
10997
|
}
|
|
10624
10998
|
|
|
@@ -13969,7 +14343,7 @@ const Lexer = __nccwpck_require__(211);
|
|
|
13969
14343
|
const Parser = __nccwpck_require__(222);
|
|
13970
14344
|
const Evaluator = __nccwpck_require__(112);
|
|
13971
14345
|
|
|
13972
|
-
const VERSION = '1.1.
|
|
14346
|
+
const VERSION = '1.1.17';
|
|
13973
14347
|
|
|
13974
14348
|
const COLOR = {
|
|
13975
14349
|
reset: '\x1b[0m',
|
package/package.json
CHANGED
package/src/evaluator.js
CHANGED
|
@@ -3,7 +3,6 @@ const fs = require('fs');
|
|
|
3
3
|
const Lexer = require('./lexer');
|
|
4
4
|
const Parser = require('./parser');
|
|
5
5
|
const path = require('path');
|
|
6
|
-
|
|
7
6
|
class ReturnValue {
|
|
8
7
|
constructor(value) { this.value = value; }
|
|
9
8
|
}
|
|
@@ -204,7 +203,51 @@ formatValue(value, seen = new Set()) {
|
|
|
204
203
|
if (arg && typeof arg === 'object') return Object.keys(arg).length;
|
|
205
204
|
return 0;
|
|
206
205
|
});
|
|
206
|
+
this.global.define('lower', arg => {
|
|
207
|
+
if (typeof arg !== 'string') return String(arg).toLowerCase();
|
|
208
|
+
return arg.toLowerCase();
|
|
209
|
+
});
|
|
210
|
+
this.global.define('toStr', arg => String(arg));
|
|
211
|
+
|
|
212
|
+
this.global.define('upper', arg => {
|
|
213
|
+
if (typeof arg !== 'string') return String(arg).toUpperCase();
|
|
214
|
+
return arg.toUpperCase();
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
this.global.define('trim', arg => {
|
|
218
|
+
if (typeof arg !== 'string') return String(arg).trim();
|
|
219
|
+
return arg.trim();
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
this.global.define('startsWith', (str, prefix) => {
|
|
223
|
+
if (typeof str !== 'string') str = String(str);
|
|
224
|
+
if (typeof prefix !== 'string') prefix = String(prefix);
|
|
225
|
+
return str.startsWith(prefix);
|
|
226
|
+
});
|
|
207
227
|
|
|
228
|
+
this.global.define('endsWith', (str, suffix) => {
|
|
229
|
+
if (typeof str !== 'string') str = String(str);
|
|
230
|
+
if (typeof suffix !== 'string') suffix = String(suffix);
|
|
231
|
+
return str.endsWith(suffix);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
this.global.define('includes', (str, substr) => {
|
|
235
|
+
if (typeof str !== 'string') str = String(str);
|
|
236
|
+
if (typeof substr !== 'string') substr = String(substr);
|
|
237
|
+
return str.includes(substr);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
this.global.define('repeat', (str, times) => {
|
|
241
|
+
if (typeof str !== 'string') str = String(str);
|
|
242
|
+
return str.repeat(Number(times) || 0);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
this.global.define('replace', (str, search, replacement) => {
|
|
246
|
+
if (typeof str !== 'string') str = String(str);
|
|
247
|
+
if (typeof search !== 'string') search = String(search);
|
|
248
|
+
if (typeof replacement !== 'string') replacement = String(replacement);
|
|
249
|
+
return str.split(search).join(replacement);
|
|
250
|
+
});
|
|
208
251
|
this.global.define('print', arg => { console.log(arg); return null; });
|
|
209
252
|
this.global.define('type', arg => {
|
|
210
253
|
if (Array.isArray(arg)) return 'array';
|
|
@@ -353,6 +396,72 @@ this.global.define('range', (...args) => {
|
|
|
353
396
|
|
|
354
397
|
return result;
|
|
355
398
|
});
|
|
399
|
+
this.global.define('floor', arg => Math.floor(Number(arg)));
|
|
400
|
+
this.global.define('ceil', arg => Math.ceil(Number(arg)));
|
|
401
|
+
this.global.define('round', arg => Math.round(Number(arg)));
|
|
402
|
+
this.global.define('abs', arg => Math.abs(Number(arg)));
|
|
403
|
+
this.global.define('pow', (base, exp) => Math.pow(Number(base), Number(exp)));
|
|
404
|
+
this.global.define('sqrt', arg => Math.sqrt(Number(arg)));
|
|
405
|
+
this.global.define('min', (...args) => Math.min(...args.map(Number)));
|
|
406
|
+
this.global.define('max', (...args) => Math.max(...args.map(Number)));
|
|
407
|
+
this.global.define('randomFloat', (min, max) => {
|
|
408
|
+
min = Number(min); max = Number(max);
|
|
409
|
+
if (isNaN(min) || isNaN(max)) return 0;
|
|
410
|
+
return Math.random() * (max - min) + min;
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
this.global.define('push', (arr, val) => {
|
|
414
|
+
if (!Array.isArray(arr)) throw new RuntimeError('push() expects an array', null, this.source);
|
|
415
|
+
arr.push(val); return arr.length;
|
|
416
|
+
});
|
|
417
|
+
this.global.define('pop', arr => {
|
|
418
|
+
if (!Array.isArray(arr)) throw new RuntimeError('pop() expects an array', null, this.source);
|
|
419
|
+
return arr.pop();
|
|
420
|
+
});
|
|
421
|
+
this.global.define('shift', arr => {
|
|
422
|
+
if (!Array.isArray(arr)) throw new RuntimeError('shift() expects an array', null, this.source);
|
|
423
|
+
return arr.shift();
|
|
424
|
+
});
|
|
425
|
+
this.global.define('unshift', (arr, val) => {
|
|
426
|
+
if (!Array.isArray(arr)) throw new RuntimeError('unshift() expects an array', null, this.source);
|
|
427
|
+
arr.unshift(val); return arr.length;
|
|
428
|
+
});
|
|
429
|
+
this.global.define('sort', (arr, fn) => {
|
|
430
|
+
if (!Array.isArray(arr)) throw new RuntimeError('sort() expects an array', null, this.source);
|
|
431
|
+
if (fn && typeof fn === 'function') return arr.sort(fn);
|
|
432
|
+
return arr.sort();
|
|
433
|
+
});
|
|
434
|
+
this.global.define('reverse', arr => {
|
|
435
|
+
if (!Array.isArray(arr)) throw new RuntimeError('reverse() expects an array', null, this.source);
|
|
436
|
+
return arr.reverse();
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
this.global.define('has', (obj, key) => obj && typeof obj === 'object' ? obj.hasOwnProperty(key) : false);
|
|
440
|
+
this.global.define('merge', (obj1, obj2) => {
|
|
441
|
+
if (!obj1 || typeof obj1 !== 'object') obj1 = {};
|
|
442
|
+
if (!obj2 || typeof obj2 !== 'object') obj2 = {};
|
|
443
|
+
return { ...obj1, ...obj2 };
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
this.global.define('uuid', () => {
|
|
447
|
+
// simple random UUID v4
|
|
448
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
|
449
|
+
const r = Math.random() * 16 | 0;
|
|
450
|
+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
451
|
+
return v.toString(16);
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
this.global.define('timestamp', () => Date.now());
|
|
455
|
+
this.global.define('clone', arg => {
|
|
456
|
+
if (Array.isArray(arg)) return [...arg];
|
|
457
|
+
if (arg && typeof arg === 'object') return { ...arg };
|
|
458
|
+
return arg; // primitive types
|
|
459
|
+
});
|
|
460
|
+
this.global.define('typeOf', arg => {
|
|
461
|
+
if (arg === null) return 'null';
|
|
462
|
+
if (Array.isArray(arg)) return 'array';
|
|
463
|
+
return typeof arg;
|
|
464
|
+
});
|
|
356
465
|
|
|
357
466
|
this.global.define('ask', prompt => {
|
|
358
467
|
const readlineSync = require('readline-sync');
|
|
@@ -409,6 +518,271 @@ this.global.define('sleep', async (ms) => {
|
|
|
409
518
|
this.global.define('str', arg => {
|
|
410
519
|
return String(arg);
|
|
411
520
|
});
|
|
521
|
+
this.global.define('now', () => Date.now());
|
|
522
|
+
this.global.define('formatDate', (timestamp, locale = 'en-US', options = {}) => {
|
|
523
|
+
if (timestamp === null || timestamp === undefined) timestamp = Date.now();
|
|
524
|
+
const t = typeof timestamp === 'number' ? timestamp : Number(timestamp);
|
|
525
|
+
if (isNaN(t)) t = Date.now();
|
|
526
|
+
return new Date(t).toLocaleString(locale, options);
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
this.global.define('readFile', path => {
|
|
530
|
+
if (typeof path !== 'string') path = String(path);
|
|
531
|
+
try {
|
|
532
|
+
return fs.readFileSync(path, 'utf-8');
|
|
533
|
+
} catch (e) {
|
|
534
|
+
throw new RuntimeError('readFile error: ' + e.message, null, this.source);
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
this.global.define('writeFile', (path, content) => {
|
|
538
|
+
if (typeof path !== 'string') path = String(path);
|
|
539
|
+
if (typeof content !== 'string') content = String(content);
|
|
540
|
+
try {
|
|
541
|
+
fs.writeFileSync(path, content, 'utf-8');
|
|
542
|
+
return true;
|
|
543
|
+
} catch (e) {
|
|
544
|
+
throw new RuntimeError('writeFile error: ' + e.message, null, this.source);
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
this.global.define('split', (str, separator) => {
|
|
549
|
+
if (typeof str !== 'string') str = String(str);
|
|
550
|
+
if (separator === undefined) separator = '';
|
|
551
|
+
return str.split(separator);
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
this.global.define('join', (arr, separator = '') => {
|
|
555
|
+
if (!Array.isArray(arr)) throw new RuntimeError('join() expects an array', null, this.source);
|
|
556
|
+
return arr.join(separator);
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
this.global.define('substring', (str, start, end) => {
|
|
560
|
+
if (typeof str !== 'string') str = String(str);
|
|
561
|
+
start = Number(start) || 0;
|
|
562
|
+
end = end !== undefined ? Number(end) : undefined;
|
|
563
|
+
return str.substring(start, end);
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
this.global.define('padStart', (str, targetLength, padString = ' ') => {
|
|
567
|
+
if (typeof str !== 'string') str = String(str);
|
|
568
|
+
targetLength = Number(targetLength) || 0;
|
|
569
|
+
return str.padStart(targetLength, padString);
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
this.global.define('padEnd', (str, targetLength, padString = ' ') => {
|
|
573
|
+
if (typeof str !== 'string') str = String(str);
|
|
574
|
+
targetLength = Number(targetLength) || 0;
|
|
575
|
+
return str.padEnd(targetLength, padString);
|
|
576
|
+
});
|
|
577
|
+
this.global.define('unique', arr => {
|
|
578
|
+
if (!Array.isArray(arr)) throw new RuntimeError('unique() expects an array', null, this.source);
|
|
579
|
+
return [...new Set(arr)];
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
this.global.define('indexOf', (arr, val) => {
|
|
583
|
+
if (!Array.isArray(arr)) throw new RuntimeError('indexOf() expects an array', null, this.source);
|
|
584
|
+
return arr.indexOf(val);
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
this.global.define('includesArr', (arr, val) => {
|
|
588
|
+
if (!Array.isArray(arr)) throw new RuntimeError('includesArr() expects an array', null, this.source);
|
|
589
|
+
return arr.includes(val);
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
this.global.define('flatten', arr => {
|
|
593
|
+
if (!Array.isArray(arr)) throw new RuntimeError('flatten() expects an array', null, this.source);
|
|
594
|
+
return arr.flat(Infinity);
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
this.global.define('randomChoice', arr => {
|
|
598
|
+
if (!Array.isArray(arr)) throw new RuntimeError('randomChoice() expects an array', null, this.source);
|
|
599
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
this.global.define('entries', obj => {
|
|
603
|
+
if (!obj || typeof obj !== 'object') throw new RuntimeError('entries() expects an object', null, this.source);
|
|
604
|
+
return Object.entries(obj);
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
this.global.define('invert', obj => {
|
|
608
|
+
if (!obj || typeof obj !== 'object') throw new RuntimeError('invert() expects an object', null, this.source);
|
|
609
|
+
const result = {};
|
|
610
|
+
for (const key in obj) result[obj[key]] = key;
|
|
611
|
+
return result;
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
this.global.define('isEmpty', arg => {
|
|
615
|
+
if (arg == null) return true;
|
|
616
|
+
if (Array.isArray(arg) || typeof arg === 'string') return arg.length === 0;
|
|
617
|
+
if (typeof arg === 'object') return Object.keys(arg).length === 0;
|
|
618
|
+
return false;
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
this.global.define('deepClone', arg => {
|
|
622
|
+
return JSON.parse(JSON.stringify(arg));
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
this.global.define('capitalize', str => {
|
|
626
|
+
if (typeof str !== 'string') str = String(str);
|
|
627
|
+
if (str.length === 0) return '';
|
|
628
|
+
return str[0].toUpperCase() + str.slice(1);
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
this.global.define('reverseStr', str => {
|
|
632
|
+
if (typeof str !== 'string') str = String(str);
|
|
633
|
+
return str.split('').reverse().join('');
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
this.global.define('trimStart', str => {
|
|
637
|
+
if (typeof str !== 'string') str = String(str);
|
|
638
|
+
return str.trimStart();
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
this.global.define('trimEnd', str => {
|
|
642
|
+
if (typeof str !== 'string') str = String(str);
|
|
643
|
+
return str.trimEnd();
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
this.global.define('clamp', (value, min, max) => {
|
|
647
|
+
value = Number(value); min = Number(min); max = Number(max);
|
|
648
|
+
return Math.min(Math.max(value, min), max);
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
this.global.define('sign', value => {
|
|
652
|
+
value = Number(value);
|
|
653
|
+
return Math.sign(value);
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
this.global.define('appendFile', (path, content) => {
|
|
657
|
+
if (typeof path !== 'string') path = String(path);
|
|
658
|
+
if (typeof content !== 'string') content = String(content);
|
|
659
|
+
try {
|
|
660
|
+
fs.appendFileSync(path, content, 'utf-8');
|
|
661
|
+
return true;
|
|
662
|
+
} catch (e) {
|
|
663
|
+
throw new RuntimeError('appendFile error: ' + e.message, null, this.source);
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
this.global.define('exists', path => {
|
|
668
|
+
if (typeof path !== 'string') path = String(path);
|
|
669
|
+
return fs.existsSync(path);
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
this.global.define('mkdir', path => {
|
|
673
|
+
if (typeof path !== 'string') path = String(path);
|
|
674
|
+
if (!fs.existsSync(path)) fs.mkdirSync(path, { recursive: true });
|
|
675
|
+
return true;
|
|
676
|
+
});
|
|
677
|
+
this.global.define('count', (arr, value) => {
|
|
678
|
+
if (!Array.isArray(arr)) throw new RuntimeError('count() expects an array', null, this.source);
|
|
679
|
+
return arr.filter(x => x === value).length;
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
this.global.define('uniqueBy', (arr, fn) => {
|
|
683
|
+
if (!Array.isArray(arr)) throw new RuntimeError('uniqueBy() expects an array', null, this.source);
|
|
684
|
+
const seen = new Set();
|
|
685
|
+
const result = [];
|
|
686
|
+
for (const item of arr) {
|
|
687
|
+
const key = fn ? fn(item) : item;
|
|
688
|
+
if (!seen.has(key)) {
|
|
689
|
+
seen.add(key);
|
|
690
|
+
result.push(item);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return result;
|
|
694
|
+
});
|
|
695
|
+
this.global.define('getProp', (obj, key, defaultValue = null) => {
|
|
696
|
+
if (!obj || typeof obj !== 'object') return defaultValue;
|
|
697
|
+
const keys = key.split('.');
|
|
698
|
+
let current = obj;
|
|
699
|
+
for (const k of keys) {
|
|
700
|
+
if (current[k] === undefined) return defaultValue;
|
|
701
|
+
current = current[k];
|
|
702
|
+
}
|
|
703
|
+
return current;
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
this.global.define('setProp', (obj, key, value) => {
|
|
707
|
+
if (!obj || typeof obj !== 'object') throw new RuntimeError('setProp() expects an object', null, this.source);
|
|
708
|
+
const keys = key.split('.');
|
|
709
|
+
let current = obj;
|
|
710
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
711
|
+
if (!current[keys[i]] || typeof current[keys[i]] !== 'object') current[keys[i]] = {};
|
|
712
|
+
current = current[keys[i]];
|
|
713
|
+
}
|
|
714
|
+
current[keys[keys.length - 1]] = value;
|
|
715
|
+
return obj;
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
this.global.define('mergeDeep', (obj1, obj2) => {
|
|
719
|
+
const isObject = val => val && typeof val === 'object';
|
|
720
|
+
const result = {...obj1};
|
|
721
|
+
for (const key in obj2) {
|
|
722
|
+
if (isObject(obj2[key]) && isObject(result[key])) {
|
|
723
|
+
result[key] = this.global.get('mergeDeep')(result[key], obj2[key]);
|
|
724
|
+
} else {
|
|
725
|
+
result[key] = obj2[key];
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
return result;
|
|
729
|
+
});
|
|
730
|
+
this.global.define('camelCase', str => {
|
|
731
|
+
if (typeof str !== 'string') str = String(str);
|
|
732
|
+
return str
|
|
733
|
+
.replace(/[-_ ]+./g, s => s.charAt(s.length - 1).toUpperCase())
|
|
734
|
+
.replace(/^[A-Z]/, s => s.toLowerCase());
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
this.global.define('kebabCase', str => {
|
|
738
|
+
if (typeof str !== 'string') str = String(str);
|
|
739
|
+
return str
|
|
740
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
741
|
+
.replace(/\s+/g, '-')
|
|
742
|
+
.replace(/_+/g, '-')
|
|
743
|
+
.toLowerCase();
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
this.global.define('repeatStr', (str, times) => {
|
|
747
|
+
if (typeof str !== 'string') str = String(str);
|
|
748
|
+
return str.repeat(Number(times) || 0);
|
|
749
|
+
});
|
|
750
|
+
this.global.define('randomInt', (min, max) => {
|
|
751
|
+
min = Number(min); max = Number(max);
|
|
752
|
+
if (isNaN(min) || isNaN(max)) return 0;
|
|
753
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
this.global.define('lerp', (a, b, t) => {
|
|
757
|
+
a = Number(a); b = Number(b); t = Number(t);
|
|
758
|
+
return a + (b - a) * t;
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
this.global.define('degToRad', deg => Number(deg) * (Math.PI / 180));
|
|
762
|
+
this.global.define('radToDeg', rad => Number(rad) * (180 / Math.PI));
|
|
763
|
+
this.global.define('readJSON', path => {
|
|
764
|
+
const content = this.global.get('readFile')(path);
|
|
765
|
+
return JSON.parse(content);
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
this.global.define('writeJSON', (path, obj) => {
|
|
769
|
+
const content = JSON.stringify(obj, null, 2);
|
|
770
|
+
return this.global.get('writeFile')(path, content);
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
this.global.define('deleteFile', path => {
|
|
774
|
+
if (typeof path !== 'string') path = String(path);
|
|
775
|
+
if (!fs.existsSync(path)) return false;
|
|
776
|
+
fs.unlinkSync(path);
|
|
777
|
+
return true;
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
this.global.define('rmdir', path => {
|
|
781
|
+
if (typeof path !== 'string') path = String(path);
|
|
782
|
+
if (!fs.existsSync(path)) return false;
|
|
783
|
+
fs.rmSync(path, { recursive: true, force: true });
|
|
784
|
+
return true;
|
|
785
|
+
});
|
|
412
786
|
|
|
413
787
|
}
|
|
414
788
|
|