starlight-cli 1.1.16 → 1.1.18

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 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));
10417
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
+ });
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';
@@ -10423,6 +10466,8 @@ formatValue(value, seen = new Set()) {
10423
10466
  this.global.define('isNaN', arg => {
10424
10467
  return typeof arg !== 'number' || Number.isNaN(arg);
10425
10468
  });
10469
+
10470
+
10426
10471
  this.global.define('random', (min, max) => {
10427
10472
  if (max === undefined) {
10428
10473
  // Only one argument → random between 0 and min
@@ -10525,6 +10570,9 @@ this.global.define('encodeURLComponent', arg => {
10525
10570
 
10526
10571
  return acc;
10527
10572
  });
10573
+ this.global.define('hasOwn', (obj, prop) => {
10574
+ return Object.prototype.hasOwnProperty.call(obj, prop)
10575
+ });
10528
10576
 
10529
10577
  this.global.define('keys', arg => arg && typeof arg === 'object' ? Object.keys(arg) : []);
10530
10578
  this.global.define('values', arg => arg && typeof arg === 'object' ? Object.values(arg) : []);
@@ -10563,6 +10611,72 @@ this.global.define('range', (...args) => {
10563
10611
 
10564
10612
  return result;
10565
10613
  });
10614
+ this.global.define('floor', arg => Math.floor(Number(arg)));
10615
+ this.global.define('ceil', arg => Math.ceil(Number(arg)));
10616
+ this.global.define('round', arg => Math.round(Number(arg)));
10617
+ this.global.define('abs', arg => Math.abs(Number(arg)));
10618
+ this.global.define('pow', (base, exp) => Math.pow(Number(base), Number(exp)));
10619
+ this.global.define('sqrt', arg => Math.sqrt(Number(arg)));
10620
+ this.global.define('min', (...args) => Math.min(...args.map(Number)));
10621
+ this.global.define('max', (...args) => Math.max(...args.map(Number)));
10622
+ this.global.define('randomFloat', (min, max) => {
10623
+ min = Number(min); max = Number(max);
10624
+ if (isNaN(min) || isNaN(max)) return 0;
10625
+ return Math.random() * (max - min) + min;
10626
+ });
10627
+
10628
+ this.global.define('push', (arr, val) => {
10629
+ if (!Array.isArray(arr)) throw new RuntimeError('push() expects an array', null, this.source);
10630
+ arr.push(val); return arr.length;
10631
+ });
10632
+ this.global.define('pop', arr => {
10633
+ if (!Array.isArray(arr)) throw new RuntimeError('pop() expects an array', null, this.source);
10634
+ return arr.pop();
10635
+ });
10636
+ this.global.define('shift', arr => {
10637
+ if (!Array.isArray(arr)) throw new RuntimeError('shift() expects an array', null, this.source);
10638
+ return arr.shift();
10639
+ });
10640
+ this.global.define('unshift', (arr, val) => {
10641
+ if (!Array.isArray(arr)) throw new RuntimeError('unshift() expects an array', null, this.source);
10642
+ arr.unshift(val); return arr.length;
10643
+ });
10644
+ this.global.define('sort', (arr, fn) => {
10645
+ if (!Array.isArray(arr)) throw new RuntimeError('sort() expects an array', null, this.source);
10646
+ if (fn && typeof fn === 'function') return arr.sort(fn);
10647
+ return arr.sort();
10648
+ });
10649
+ this.global.define('reverse', arr => {
10650
+ if (!Array.isArray(arr)) throw new RuntimeError('reverse() expects an array', null, this.source);
10651
+ return arr.reverse();
10652
+ });
10653
+
10654
+ this.global.define('has', (obj, key) => obj && typeof obj === 'object' ? obj.hasOwnProperty(key) : false);
10655
+ this.global.define('merge', (obj1, obj2) => {
10656
+ if (!obj1 || typeof obj1 !== 'object') obj1 = {};
10657
+ if (!obj2 || typeof obj2 !== 'object') obj2 = {};
10658
+ return { ...obj1, ...obj2 };
10659
+ });
10660
+
10661
+ this.global.define('uuid', () => {
10662
+ // simple random UUID v4
10663
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
10664
+ const r = Math.random() * 16 | 0;
10665
+ const v = c === 'x' ? r : (r & 0x3 | 0x8);
10666
+ return v.toString(16);
10667
+ });
10668
+ });
10669
+ this.global.define('timestamp', () => Date.now());
10670
+ this.global.define('clone', arg => {
10671
+ if (Array.isArray(arg)) return [...arg];
10672
+ if (arg && typeof arg === 'object') return { ...arg };
10673
+ return arg; // primitive types
10674
+ });
10675
+ this.global.define('typeOf', arg => {
10676
+ if (arg === null) return 'null';
10677
+ if (Array.isArray(arg)) return 'array';
10678
+ return typeof arg;
10679
+ });
10566
10680
 
10567
10681
  this.global.define('ask', prompt => {
10568
10682
  const readlineSync = __nccwpck_require__(552);
@@ -10619,6 +10733,271 @@ this.global.define('sleep', async (ms) => {
10619
10733
  this.global.define('str', arg => {
10620
10734
  return String(arg);
10621
10735
  });
10736
+ this.global.define('now', () => Date.now());
10737
+ this.global.define('formatDate', (timestamp, locale = 'en-US', options = {}) => {
10738
+ if (timestamp === null || timestamp === undefined) timestamp = Date.now();
10739
+ const t = typeof timestamp === 'number' ? timestamp : Number(timestamp);
10740
+ if (isNaN(t)) t = Date.now();
10741
+ return new Date(t).toLocaleString(locale, options);
10742
+ });
10743
+
10744
+ this.global.define('readFile', path => {
10745
+ if (typeof path !== 'string') path = String(path);
10746
+ try {
10747
+ return fs.readFileSync(path, 'utf-8');
10748
+ } catch (e) {
10749
+ throw new RuntimeError('readFile error: ' + e.message, null, this.source);
10750
+ }
10751
+ });
10752
+ this.global.define('writeFile', (path, content) => {
10753
+ if (typeof path !== 'string') path = String(path);
10754
+ if (typeof content !== 'string') content = String(content);
10755
+ try {
10756
+ fs.writeFileSync(path, content, 'utf-8');
10757
+ return true;
10758
+ } catch (e) {
10759
+ throw new RuntimeError('writeFile error: ' + e.message, null, this.source);
10760
+ }
10761
+ });
10762
+
10763
+ this.global.define('split', (str, separator) => {
10764
+ if (typeof str !== 'string') str = String(str);
10765
+ if (separator === undefined) separator = '';
10766
+ return str.split(separator);
10767
+ });
10768
+
10769
+ this.global.define('join', (arr, separator = '') => {
10770
+ if (!Array.isArray(arr)) throw new RuntimeError('join() expects an array', null, this.source);
10771
+ return arr.join(separator);
10772
+ });
10773
+
10774
+ this.global.define('substring', (str, start, end) => {
10775
+ if (typeof str !== 'string') str = String(str);
10776
+ start = Number(start) || 0;
10777
+ end = end !== undefined ? Number(end) : undefined;
10778
+ return str.substring(start, end);
10779
+ });
10780
+
10781
+ this.global.define('padStart', (str, targetLength, padString = ' ') => {
10782
+ if (typeof str !== 'string') str = String(str);
10783
+ targetLength = Number(targetLength) || 0;
10784
+ return str.padStart(targetLength, padString);
10785
+ });
10786
+
10787
+ this.global.define('padEnd', (str, targetLength, padString = ' ') => {
10788
+ if (typeof str !== 'string') str = String(str);
10789
+ targetLength = Number(targetLength) || 0;
10790
+ return str.padEnd(targetLength, padString);
10791
+ });
10792
+ this.global.define('unique', arr => {
10793
+ if (!Array.isArray(arr)) throw new RuntimeError('unique() expects an array', null, this.source);
10794
+ return [...new Set(arr)];
10795
+ });
10796
+
10797
+ this.global.define('indexOf', (arr, val) => {
10798
+ if (!Array.isArray(arr)) throw new RuntimeError('indexOf() expects an array', null, this.source);
10799
+ return arr.indexOf(val);
10800
+ });
10801
+
10802
+ this.global.define('includesArr', (arr, val) => {
10803
+ if (!Array.isArray(arr)) throw new RuntimeError('includesArr() expects an array', null, this.source);
10804
+ return arr.includes(val);
10805
+ });
10806
+
10807
+ this.global.define('flatten', arr => {
10808
+ if (!Array.isArray(arr)) throw new RuntimeError('flatten() expects an array', null, this.source);
10809
+ return arr.flat(Infinity);
10810
+ });
10811
+
10812
+ this.global.define('randomChoice', arr => {
10813
+ if (!Array.isArray(arr)) throw new RuntimeError('randomChoice() expects an array', null, this.source);
10814
+ return arr[Math.floor(Math.random() * arr.length)];
10815
+ });
10816
+
10817
+ this.global.define('entries', obj => {
10818
+ if (!obj || typeof obj !== 'object') throw new RuntimeError('entries() expects an object', null, this.source);
10819
+ return Object.entries(obj);
10820
+ });
10821
+
10822
+ this.global.define('invert', obj => {
10823
+ if (!obj || typeof obj !== 'object') throw new RuntimeError('invert() expects an object', null, this.source);
10824
+ const result = {};
10825
+ for (const key in obj) result[obj[key]] = key;
10826
+ return result;
10827
+ });
10828
+
10829
+ this.global.define('isEmpty', arg => {
10830
+ if (arg == null) return true;
10831
+ if (Array.isArray(arg) || typeof arg === 'string') return arg.length === 0;
10832
+ if (typeof arg === 'object') return Object.keys(arg).length === 0;
10833
+ return false;
10834
+ });
10835
+
10836
+ this.global.define('deepClone', arg => {
10837
+ return JSON.parse(JSON.stringify(arg));
10838
+ });
10839
+
10840
+ this.global.define('capitalize', str => {
10841
+ if (typeof str !== 'string') str = String(str);
10842
+ if (str.length === 0) return '';
10843
+ return str[0].toUpperCase() + str.slice(1);
10844
+ });
10845
+
10846
+ this.global.define('reverseStr', str => {
10847
+ if (typeof str !== 'string') str = String(str);
10848
+ return str.split('').reverse().join('');
10849
+ });
10850
+
10851
+ this.global.define('trimStart', str => {
10852
+ if (typeof str !== 'string') str = String(str);
10853
+ return str.trimStart();
10854
+ });
10855
+
10856
+ this.global.define('trimEnd', str => {
10857
+ if (typeof str !== 'string') str = String(str);
10858
+ return str.trimEnd();
10859
+ });
10860
+
10861
+ this.global.define('clamp', (value, min, max) => {
10862
+ value = Number(value); min = Number(min); max = Number(max);
10863
+ return Math.min(Math.max(value, min), max);
10864
+ });
10865
+
10866
+ this.global.define('sign', value => {
10867
+ value = Number(value);
10868
+ return Math.sign(value);
10869
+ });
10870
+
10871
+ this.global.define('appendFile', (path, content) => {
10872
+ if (typeof path !== 'string') path = String(path);
10873
+ if (typeof content !== 'string') content = String(content);
10874
+ try {
10875
+ fs.appendFileSync(path, content, 'utf-8');
10876
+ return true;
10877
+ } catch (e) {
10878
+ throw new RuntimeError('appendFile error: ' + e.message, null, this.source);
10879
+ }
10880
+ });
10881
+
10882
+ this.global.define('exists', path => {
10883
+ if (typeof path !== 'string') path = String(path);
10884
+ return fs.existsSync(path);
10885
+ });
10886
+
10887
+ this.global.define('mkdir', path => {
10888
+ if (typeof path !== 'string') path = String(path);
10889
+ if (!fs.existsSync(path)) fs.mkdirSync(path, { recursive: true });
10890
+ return true;
10891
+ });
10892
+ this.global.define('count', (arr, value) => {
10893
+ if (!Array.isArray(arr)) throw new RuntimeError('count() expects an array', null, this.source);
10894
+ return arr.filter(x => x === value).length;
10895
+ });
10896
+
10897
+ this.global.define('uniqueBy', (arr, fn) => {
10898
+ if (!Array.isArray(arr)) throw new RuntimeError('uniqueBy() expects an array', null, this.source);
10899
+ const seen = new Set();
10900
+ const result = [];
10901
+ for (const item of arr) {
10902
+ const key = fn ? fn(item) : item;
10903
+ if (!seen.has(key)) {
10904
+ seen.add(key);
10905
+ result.push(item);
10906
+ }
10907
+ }
10908
+ return result;
10909
+ });
10910
+ this.global.define('getProp', (obj, key, defaultValue = null) => {
10911
+ if (!obj || typeof obj !== 'object') return defaultValue;
10912
+ const keys = key.split('.');
10913
+ let current = obj;
10914
+ for (const k of keys) {
10915
+ if (current[k] === undefined) return defaultValue;
10916
+ current = current[k];
10917
+ }
10918
+ return current;
10919
+ });
10920
+
10921
+ this.global.define('setProp', (obj, key, value) => {
10922
+ if (!obj || typeof obj !== 'object') throw new RuntimeError('setProp() expects an object', null, this.source);
10923
+ const keys = key.split('.');
10924
+ let current = obj;
10925
+ for (let i = 0; i < keys.length - 1; i++) {
10926
+ if (!current[keys[i]] || typeof current[keys[i]] !== 'object') current[keys[i]] = {};
10927
+ current = current[keys[i]];
10928
+ }
10929
+ current[keys[keys.length - 1]] = value;
10930
+ return obj;
10931
+ });
10932
+
10933
+ this.global.define('mergeDeep', (obj1, obj2) => {
10934
+ const isObject = val => val && typeof val === 'object';
10935
+ const result = {...obj1};
10936
+ for (const key in obj2) {
10937
+ if (isObject(obj2[key]) && isObject(result[key])) {
10938
+ result[key] = this.global.get('mergeDeep')(result[key], obj2[key]);
10939
+ } else {
10940
+ result[key] = obj2[key];
10941
+ }
10942
+ }
10943
+ return result;
10944
+ });
10945
+ this.global.define('camelCase', str => {
10946
+ if (typeof str !== 'string') str = String(str);
10947
+ return str
10948
+ .replace(/[-_ ]+./g, s => s.charAt(s.length - 1).toUpperCase())
10949
+ .replace(/^[A-Z]/, s => s.toLowerCase());
10950
+ });
10951
+
10952
+ this.global.define('kebabCase', str => {
10953
+ if (typeof str !== 'string') str = String(str);
10954
+ return str
10955
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
10956
+ .replace(/\s+/g, '-')
10957
+ .replace(/_+/g, '-')
10958
+ .toLowerCase();
10959
+ });
10960
+
10961
+ this.global.define('repeatStr', (str, times) => {
10962
+ if (typeof str !== 'string') str = String(str);
10963
+ return str.repeat(Number(times) || 0);
10964
+ });
10965
+ this.global.define('randomInt', (min, max) => {
10966
+ min = Number(min); max = Number(max);
10967
+ if (isNaN(min) || isNaN(max)) return 0;
10968
+ return Math.floor(Math.random() * (max - min + 1)) + min;
10969
+ });
10970
+
10971
+ this.global.define('lerp', (a, b, t) => {
10972
+ a = Number(a); b = Number(b); t = Number(t);
10973
+ return a + (b - a) * t;
10974
+ });
10975
+
10976
+ this.global.define('degToRad', deg => Number(deg) * (Math.PI / 180));
10977
+ this.global.define('radToDeg', rad => Number(rad) * (180 / Math.PI));
10978
+ this.global.define('readJSON', path => {
10979
+ const content = this.global.get('readFile')(path);
10980
+ return JSON.parse(content);
10981
+ });
10982
+
10983
+ this.global.define('writeJSON', (path, obj) => {
10984
+ const content = JSON.stringify(obj, null, 2);
10985
+ return this.global.get('writeFile')(path, content);
10986
+ });
10987
+
10988
+ this.global.define('deleteFile', path => {
10989
+ if (typeof path !== 'string') path = String(path);
10990
+ if (!fs.existsSync(path)) return false;
10991
+ fs.unlinkSync(path);
10992
+ return true;
10993
+ });
10994
+
10995
+ this.global.define('rmdir', path => {
10996
+ if (typeof path !== 'string') path = String(path);
10997
+ if (!fs.existsSync(path)) return false;
10998
+ fs.rmSync(path, { recursive: true, force: true });
10999
+ return true;
11000
+ });
10622
11001
 
10623
11002
  }
10624
11003
 
@@ -10748,8 +11127,6 @@ async evalProgram(node, env) {
10748
11127
  async evalSlice(node, env) {
10749
11128
  try {
10750
11129
  const arr = await this.evaluate(node.object, env);
10751
- const start = node.start ? await this.evaluate(node.start, env) : 0;
10752
- const end = node.end ? await this.evaluate(node.end, env) : arr.length;
10753
11130
 
10754
11131
  if (!Array.isArray(arr)) {
10755
11132
  throw new RuntimeError(
@@ -10760,10 +11137,37 @@ async evalSlice(node, env) {
10760
11137
  );
10761
11138
  }
10762
11139
 
10763
- const s = start < 0 ? Math.max(arr.length + start, 0) : Math.min(start, arr.length);
10764
- const e = end < 0 ? Math.max(arr.length + end, 0) : Math.min(end, arr.length);
11140
+ let start = node.start ? await this.evaluate(node.start, env) : 0;
11141
+ let end = node.end ? await this.evaluate(node.end, env) : arr.length;
11142
+ let step = node.step ? await this.evaluate(node.step, env) : 1;
11143
+
11144
+ if (step === 0) {
11145
+ throw new RuntimeError(
11146
+ 'Slice step cannot be zero',
11147
+ node,
11148
+ this.source,
11149
+ env
11150
+ );
11151
+ }
11152
+ start = start < 0 ? arr.length + start : start;
11153
+ end = end < 0 ? arr.length + end : end;
11154
+
11155
+ start = Math.min(Math.max(start, 0), arr.length);
11156
+ end = Math.min(Math.max(end, 0), arr.length);
10765
11157
 
10766
- return arr.slice(s, e);
11158
+ const result = [];
11159
+
11160
+ if (step > 0) {
11161
+ for (let i = start; i < end; i += step) {
11162
+ result.push(arr[i]);
11163
+ }
11164
+ } else {
11165
+ for (let i = start; i > end; i += step) {
11166
+ result.push(arr[i]);
11167
+ }
11168
+ }
11169
+
11170
+ return result;
10767
11171
 
10768
11172
  } catch (err) {
10769
11173
  if (err instanceof RuntimeError) throw err;
@@ -10776,6 +11180,7 @@ async evalSlice(node, env) {
10776
11180
  }
10777
11181
  }
10778
11182
 
11183
+
10779
11184
  async evalStartStatement(node, env) {
10780
11185
  try {
10781
11186
  const value = await this.evaluate(node.discriminant, env);
@@ -11300,12 +11705,49 @@ async evalLogical(node, env) {
11300
11705
 
11301
11706
  async evalUnary(node, env) {
11302
11707
  try {
11708
+ // Handle prefix update operators
11709
+ if (node.type === 'UpdateExpression' && node.prefix) {
11710
+ if (node.argument.type !== 'Identifier') {
11711
+ throw new RuntimeError(
11712
+ `Invalid operand for update operator: ${node.operator}`,
11713
+ node,
11714
+ this.source,
11715
+ env
11716
+ );
11717
+ }
11718
+
11719
+ const varName = node.argument.name;
11720
+ let currentVal = await env.get(varName); // assuming env.get returns the variable value
11721
+
11722
+ switch (node.operator) {
11723
+ case 'PLUSPLUS':
11724
+ currentVal++;
11725
+ await env.set(varName, currentVal);
11726
+ return currentVal;
11727
+ case 'MINUSMINUS':
11728
+ currentVal--;
11729
+ await env.set(varName, currentVal);
11730
+ return currentVal;
11731
+ default:
11732
+ throw new RuntimeError(
11733
+ `Unknown update operator: ${node.operator}`,
11734
+ node,
11735
+ this.source,
11736
+ env
11737
+ );
11738
+ }
11739
+ }
11740
+
11741
+ // Evaluate the argument first
11303
11742
  const val = await this.evaluate(node.argument, env);
11304
11743
 
11305
11744
  switch (node.operator) {
11306
- case 'NOT': return !val;
11307
- case 'MINUS': return -val;
11308
- case 'PLUS': return +val;
11745
+ case 'NOT':
11746
+ return !val;
11747
+ case 'MINUS':
11748
+ return -val;
11749
+ case 'PLUS':
11750
+ return +val;
11309
11751
  default:
11310
11752
  throw new RuntimeError(
11311
11753
  `Unknown unary operator: ${node.operator}`,
@@ -11314,7 +11756,6 @@ async evalUnary(node, env) {
11314
11756
  env
11315
11757
  );
11316
11758
  }
11317
-
11318
11759
  } catch (e) {
11319
11760
  if (e instanceof RuntimeError) throw e;
11320
11761
  throw new RuntimeError(
@@ -11326,6 +11767,51 @@ async evalUnary(node, env) {
11326
11767
  }
11327
11768
  }
11328
11769
 
11770
+ // Handle postfix updates (x++ or x--)
11771
+ async evalPostfixUpdate(node, env) {
11772
+ if (node.type !== 'UpdateExpression' || node.prefix) {
11773
+ throw new RuntimeError(
11774
+ `Invalid postfix update node`,
11775
+ node,
11776
+ this.source,
11777
+ env
11778
+ );
11779
+ }
11780
+
11781
+ if (node.argument.type !== 'Identifier') {
11782
+ throw new RuntimeError(
11783
+ `Invalid operand for postfix update operator: ${node.operator}`,
11784
+ node,
11785
+ this.source,
11786
+ env
11787
+ );
11788
+ }
11789
+
11790
+ const varName = node.argument.name;
11791
+ let currentVal = await env.get(varName);
11792
+
11793
+ let returnVal = currentVal;
11794
+
11795
+ switch (node.operator) {
11796
+ case 'PLUSPLUS':
11797
+ currentVal++;
11798
+ await env.set(varName, currentVal);
11799
+ return returnVal; // return original value
11800
+ case 'MINUSMINUS':
11801
+ currentVal--;
11802
+ await env.set(varName, currentVal);
11803
+ return returnVal; // return original value
11804
+ default:
11805
+ throw new RuntimeError(
11806
+ `Unknown postfix operator: ${node.operator}`,
11807
+ node,
11808
+ this.source,
11809
+ env
11810
+ );
11811
+ }
11812
+ }
11813
+
11814
+
11329
11815
  async evalIf(node, env) {
11330
11816
  let test = await this.evaluate(node.test, env);
11331
11817
  test = !!test; // coerce to boolean
@@ -11604,7 +12090,8 @@ async evalIndex(node, env) {
11604
12090
  env
11605
12091
  );
11606
12092
  }
11607
- }
12093
+ }
12094
+
11608
12095
  async evalObject(node, env) {
11609
12096
  try {
11610
12097
  const out = {};
@@ -13243,192 +13730,111 @@ unary() {
13243
13730
 
13244
13731
  return this.postfix();
13245
13732
  }
13733
+
13246
13734
  postfix() {
13247
13735
  let node = this.primary();
13248
13736
 
13249
13737
  while (true) {
13250
13738
  const t = this.current;
13251
13739
 
13252
- if (t.type === 'LBRACKET') {
13253
- const startLine = t.line;
13254
- const startCol = t.column;
13255
- this.eat('LBRACKET');
13256
-
13257
- let start = null;
13258
- let end = null;
13259
- let step = null;
13260
-
13261
- if (this.current.type === 'COLON') {
13262
- this.eat('COLON');
13263
-
13264
- if (this.current.type !== 'RBRACKET' && this.current.type !== 'COLON') {
13265
- end = this.expression();
13266
- }
13267
-
13268
- if (this.current.type === 'COLON') {
13269
- this.eat('COLON');
13270
- if (this.current.type !== 'RBRACKET') {
13271
- step = this.expression();
13272
- }
13273
- }
13274
-
13275
- if (this.current.type !== 'RBRACKET') {
13276
- throw new ParseError(
13277
- "Expected ']' after slice",
13278
- this.current,
13279
- this.source
13280
- );
13281
- }
13282
-
13283
- this.eat('RBRACKET');
13284
-
13285
- node = {
13286
- type: 'SliceExpression',
13287
- object: node,
13288
- start,
13289
- end,
13290
- step,
13291
- line: startLine,
13292
- column: startCol
13293
- };
13294
-
13295
- } else {
13296
- start = this.expression();
13297
-
13298
- if (this.current.type === 'COLON') {
13299
- this.eat('COLON');
13740
+ // Handle indexing / slicing
13741
+ if (t.type === 'LBRACKET') {
13742
+ const startLine = t.line;
13743
+ const startCol = t.column;
13744
+ this.eat('LBRACKET');
13300
13745
 
13301
- if (this.current.type !== 'RBRACKET' && this.current.type !== 'COLON') {
13302
- end = this.expression();
13303
- }
13746
+ let start = null;
13747
+ let end = null;
13748
+ let step = null;
13304
13749
 
13750
+ // Slice: [:end:step] or [start:end:step]
13305
13751
  if (this.current.type === 'COLON') {
13306
13752
  this.eat('COLON');
13753
+ if (this.current.type !== 'RBRACKET' && this.current.type !== 'COLON') {
13754
+ end = this.expression();
13755
+ }
13756
+ if (this.current.type === 'COLON') {
13757
+ this.eat('COLON');
13758
+ if (this.current.type !== 'RBRACKET') {
13759
+ step = this.expression();
13760
+ }
13761
+ }
13307
13762
  if (this.current.type !== 'RBRACKET') {
13308
- step = this.expression();
13763
+ throw new ParseError("Expected ']' after slice", this.current, this.source);
13309
13764
  }
13310
- }
13765
+ this.eat('RBRACKET');
13311
13766
 
13312
- if (this.current.type !== 'RBRACKET') {
13313
- throw new ParseError(
13314
- "Expected ']' after slice",
13315
- this.current,
13316
- this.source
13317
- );
13318
- }
13319
-
13320
- this.eat('RBRACKET');
13321
-
13322
- node = {
13323
- type: 'SliceExpression',
13324
- object: node,
13325
- start,
13326
- end,
13327
- step,
13328
- line: startLine,
13329
- column: startCol
13330
- };
13767
+ node = { type: 'SliceExpression', object: node, start, end, step, line: startLine, column: startCol };
13768
+ } else {
13769
+ // Normal index or slice starting with an expression
13770
+ start = this.expression();
13771
+ if (this.current.type === 'COLON') {
13772
+ this.eat('COLON');
13773
+ if (this.current.type !== 'RBRACKET' && this.current.type !== 'COLON') {
13774
+ end = this.expression();
13775
+ }
13776
+ if (this.current.type === 'COLON') {
13777
+ this.eat('COLON');
13778
+ if (this.current.type !== 'RBRACKET') {
13779
+ step = this.expression();
13780
+ }
13781
+ }
13782
+ if (this.current.type !== 'RBRACKET') {
13783
+ throw new ParseError("Expected ']' after slice", this.current, this.source);
13784
+ }
13785
+ this.eat('RBRACKET');
13331
13786
 
13332
- } else {
13333
- this.eat('RBRACKET');
13334
- node = {
13335
- type: 'IndexExpression',
13336
- object: node,
13337
- indexer: start,
13338
- line: startLine,
13339
- column: startCol
13340
- };
13787
+ node = { type: 'SliceExpression', object: node, start, end, step, line: startLine, column: startCol };
13788
+ } else {
13789
+ this.eat('RBRACKET');
13790
+ node = { type: 'IndexExpression', object: node, indexer: start, line: startLine, column: startCol };
13791
+ }
13792
+ }
13793
+ continue; // continue to allow . or () after []
13341
13794
  }
13342
- }
13343
- }
13344
-
13345
-
13346
13795
 
13796
+ // Handle function call
13347
13797
  if (t.type === 'LPAREN') {
13348
13798
  const startLine = t.line;
13349
13799
  const startCol = t.column;
13350
13800
  this.eat('LPAREN');
13351
13801
 
13352
13802
  const args = [];
13353
-
13354
13803
  while (this.current.type !== 'RPAREN') {
13355
13804
  if (this.current.type === 'EOF') {
13356
- throw new ParseError(
13357
- "Unterminated function call",
13358
- this.current,
13359
- this.source,
13360
- "Did you forget to close ')'?"
13361
- );
13805
+ throw new ParseError("Unterminated function call", this.current, this.source, "Did you forget to close ')'?");
13362
13806
  }
13363
-
13364
13807
  args.push(this.expression());
13365
-
13366
- if (this.current.type === 'COMMA') {
13367
- this.eat('COMMA');
13368
- } else {
13369
- break;
13370
- }
13371
- }
13372
-
13373
- if (this.current.type !== 'RPAREN') {
13374
- throw new ParseError(
13375
- "Expected ')' after function arguments",
13376
- this.current,
13377
- this.source,
13378
- "Function calls must be closed with ')'"
13379
- );
13808
+ if (this.current.type === 'COMMA') this.eat('COMMA');
13380
13809
  }
13381
13810
 
13382
13811
  this.eat('RPAREN');
13383
13812
 
13384
- node = {
13385
- type: 'CallExpression',
13386
- callee: node,
13387
- arguments: args,
13388
- line: startLine,
13389
- column: startCol
13390
- };
13813
+ node = { type: 'CallExpression', callee: node, arguments: args, line: startLine, column: startCol };
13391
13814
  continue;
13392
13815
  }
13393
13816
 
13817
+ // Handle member access
13394
13818
  if (t.type === 'DOT') {
13395
13819
  const startLine = t.line;
13396
13820
  const startCol = t.column;
13397
13821
  this.eat('DOT');
13398
13822
 
13399
13823
  if (this.current.type !== 'IDENTIFIER') {
13400
- throw new ParseError(
13401
- "Expected property name after '.'",
13402
- this.current,
13403
- this.source,
13404
- "Member access requires a property name, e.g. obj.value"
13405
- );
13824
+ throw new ParseError("Expected property name after '.'", this.current, this.source, "Member access requires a property name, e.g. obj.value");
13406
13825
  }
13407
13826
 
13408
13827
  const property = this.current.value;
13409
13828
  this.eat('IDENTIFIER');
13410
13829
 
13411
- node = {
13412
- type: 'MemberExpression',
13413
- object: node,
13414
- property,
13415
- line: startLine,
13416
- column: startCol
13417
- };
13830
+ node = { type: 'MemberExpression', object: node, property, line: startLine, column: startCol };
13418
13831
  continue;
13419
13832
  }
13420
13833
 
13834
+ // Handle postfix update operators
13421
13835
  if (t.type === 'PLUSPLUS' || t.type === 'MINUSMINUS') {
13422
13836
  this.eat(t.type);
13423
-
13424
- node = {
13425
- type: 'UpdateExpression',
13426
- operator: t.type,
13427
- argument: node,
13428
- prefix: false,
13429
- line: t.line,
13430
- column: t.column
13431
- };
13837
+ node = { type: 'UpdateExpression', operator: t.type, argument: node, prefix: false, line: t.line, column: t.column };
13432
13838
  continue;
13433
13839
  }
13434
13840
 
@@ -13438,6 +13844,7 @@ postfix() {
13438
13844
  return node;
13439
13845
  }
13440
13846
 
13847
+
13441
13848
  arrowFunction(params) {
13442
13849
  const t = this.current;
13443
13850
  this.eat('ARROW');
@@ -13788,8 +14195,8 @@ if (t.type === 'FUNC') {
13788
14195
  }
13789
14196
 
13790
14197
  }
13791
-
13792
- module.exports = Parser;
14198
+ module.exports = Parser;
14199
+
13793
14200
 
13794
14201
  /***/ }),
13795
14202
 
@@ -13969,7 +14376,7 @@ const Lexer = __nccwpck_require__(211);
13969
14376
  const Parser = __nccwpck_require__(222);
13970
14377
  const Evaluator = __nccwpck_require__(112);
13971
14378
 
13972
- const VERSION = '1.1.16';
14379
+ const VERSION = '1.1.18';
13973
14380
 
13974
14381
  const COLOR = {
13975
14382
  reset: '\x1b[0m',
@@ -14129,7 +14536,7 @@ Usage:
14129
14536
 
14130
14537
  if (args[0] === '-v' || args[0] === '--version') {
14131
14538
  console.log(`${COLOR.bold}Starlight CLI v${VERSION}${COLOR.reset}`);
14132
- console.log(`${COLOR.magenta}Developed by Macedon${COLOR.reset}`);
14539
+ console.log(`${COLOR.magenta}Developed by Dominex Macedon${COLOR.reset}`);
14133
14540
  process.exit(0);
14134
14541
  }
14135
14542