@grey-ts/transpiler 1.4.3 → 2.0.0

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.
Files changed (2) hide show
  1. package/dist/index.js +312 -216
  2. package/package.json +6 -5
package/dist/index.js CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  // src/index.ts
4
4
  import * as fs3 from "node:fs";
5
- import path5 from "node:path";
5
+ import path6 from "node:path";
6
6
 
7
7
  // src/transpiler.ts
8
8
  import * as fs2 from "node:fs";
9
- import * as path4 from "node:path";
9
+ import * as path5 from "node:path";
10
10
  import ts14 from "typescript";
11
11
 
12
12
  // src/nodeHandler.ts
13
+ import * as path from "node:path";
13
14
  import ts from "typescript";
14
-
15
15
  class NodeHandler {
16
16
  static handlers = new Map;
17
17
  static transpileContext;
@@ -29,13 +29,32 @@ class NodeHandler {
29
29
  }
30
30
  try {
31
31
  const result = handler(node, this.transpileContext);
32
- return result;
32
+ const extra = this.transpileContext.extraOutput.get(node);
33
+ if (!extra)
34
+ return result;
35
+ return [
36
+ ...extra.before ? [extra.before] : [],
37
+ result,
38
+ ...extra.after ? [extra.after] : []
39
+ ].join(`
40
+ `);
33
41
  } catch (error) {
34
42
  console.error(error);
35
43
  this.printLineAndCol(node);
36
44
  return ts.isBlock(node.parent) || ts.isSourceFile(node.parent) ? "" : "null";
37
45
  }
38
46
  }
47
+ static addExtraOutput(node, before, after) {
48
+ let extra = this.transpileContext.extraOutput.get(node);
49
+ if (!extra) {
50
+ extra = { before: "", after: "" };
51
+ this.transpileContext.extraOutput.set(node, extra);
52
+ }
53
+ if (before)
54
+ extra.before += before;
55
+ if (after)
56
+ extra.after += after;
57
+ }
39
58
  static printLineAndCol(node) {
40
59
  const source = node.getSourceFile();
41
60
  const lineAndChar = source.getLineAndCharacterOfPosition(node.pos);
@@ -47,6 +66,29 @@ NodeHandler.register(ts.SyntaxKind.InterfaceDeclaration, () => "");
47
66
  NodeHandler.register(ts.SyntaxKind.ModuleDeclaration, () => "");
48
67
  NodeHandler.register(ts.SyntaxKind.EndOfFileToken, () => "");
49
68
  NodeHandler.register(ts.SyntaxKind.EmptyStatement, () => "");
69
+ NodeHandler.register(ts.SyntaxKind.SourceFile, (sourceFile, ctx) => {
70
+ if (ctx.visitedFiles.has(sourceFile.fileName))
71
+ return "";
72
+ ctx.visitedFiles.add(sourceFile.fileName);
73
+ if (sourceFile.isDeclarationFile)
74
+ return "";
75
+ if (program.isSourceFileDefaultLibrary(sourceFile) || program.isSourceFileFromExternalLibrary(sourceFile))
76
+ return "";
77
+ const prevFile = ctx.currentFilePath;
78
+ ctx.currentFilePath = sourceFile.fileName;
79
+ ctx.currentFolder = path.dirname(sourceFile.fileName);
80
+ ctx.namedImports[sourceFile.fileName] = {};
81
+ ctx.namespaceImports[sourceFile.fileName] = new Set;
82
+ sourceFile.forEachChild((node) => {
83
+ const result = NodeHandler.handle(node);
84
+ if (!result)
85
+ return;
86
+ ctx.output.push(result);
87
+ });
88
+ ctx.currentFilePath = prevFile;
89
+ ctx.currentFolder = path.dirname(prevFile);
90
+ return "";
91
+ });
50
92
 
51
93
  // src/parser.ts
52
94
  import ts2 from "typescript";
@@ -57,7 +99,7 @@ var parser_default = parseCode;
57
99
 
58
100
  // src/utils.ts
59
101
  import fs from "node:fs";
60
- import path from "node:path";
102
+ import path2 from "node:path";
61
103
  import ts3 from "typescript";
62
104
 
63
105
  // src/replaceKeywords.ts
@@ -127,7 +169,6 @@ var apiNameMap = {
127
169
  "GreyHack.File.setGroup": "set_group",
128
170
  "GreyHack.File.setOwner": "set_owner",
129
171
  "GreyHack.activeUser": "active_user",
130
- "GreyHack.clearScreen": "clear_screen",
131
172
  "GreyHack.commandInfo": "command_info",
132
173
  "GreyHack.currentDate": "current_date",
133
174
  "GreyHack.currentPath": "current_path",
@@ -218,26 +259,11 @@ var apiNameMap = {
218
259
  "Object.size": "len",
219
260
  "Array.length": "len",
220
261
  "Array.shift": "pull",
221
- "Array.push": "push_many"
262
+ "Array.push": "push_many",
263
+ "Map.size": "data.len",
264
+ "Set.size": "data.len"
222
265
  };
223
266
  var propertyAccessReplacements = {
224
- "Math.PI": "pi",
225
- "Math.abs": "abs",
226
- "Math.acos": "acos",
227
- "Math.asin": "asin",
228
- "Math.atan": "atan",
229
- "Math.ceil": "ceil",
230
- "Math.floor": "floor",
231
- "Math.cos": "cos",
232
- "Math.sin": "sin",
233
- "Math.tan": "tan",
234
- "Math.sqrt": "sqrt",
235
- "Math.sign": "sign",
236
- "Math.round": "round",
237
- "Math.random": "rnd",
238
- "Math.log": "log",
239
- "console.log": "print",
240
- "console.clear": "clear_screen",
241
267
  "String.prototype": "string",
242
268
  "Number.prototype": "number",
243
269
  "Boolean.prototype": "number",
@@ -263,6 +289,7 @@ var knownOperators = new Set([
263
289
  "!==",
264
290
  "??",
265
291
  "??=",
292
+ "||=",
266
293
  "in",
267
294
  "||",
268
295
  "<",
@@ -287,13 +314,13 @@ function getOperatorToken(node) {
287
314
  return null;
288
315
  if (!knownOperators.has(operatorToken))
289
316
  throw `Can't handle operator '${operatorToken}' yet`;
290
- if (operatorToken == "||")
317
+ if (operatorToken === "||")
291
318
  operatorToken = "or";
292
- else if (operatorToken == "&&")
319
+ else if (operatorToken === "&&")
293
320
  operatorToken = "and";
294
- else if (operatorToken == "===")
321
+ else if (operatorToken === "===")
295
322
  operatorToken = "==";
296
- else if (operatorToken == "!==")
323
+ else if (operatorToken === "!==")
297
324
  operatorToken = "!=";
298
325
  return operatorToken;
299
326
  }
@@ -315,7 +342,7 @@ function nodeIsFunctionReference(node, type) {
315
342
  function asRef(value) {
316
343
  if (value[0] === "@")
317
344
  return value;
318
- return "@" + value;
345
+ return `@${value}`;
319
346
  }
320
347
  function getSourceFiles(absPath) {
321
348
  if (!fs.existsSync(absPath))
@@ -326,7 +353,7 @@ function getSourceFiles(absPath) {
326
353
  const file = filePaths.shift();
327
354
  const stat = fs.statSync(file);
328
355
  if (stat.isDirectory()) {
329
- filePaths.push(...fs.readdirSync(file).map((name) => path.join(file, name)));
356
+ filePaths.push(...fs.readdirSync(file).map((name) => path2.join(file, name)));
330
357
  continue;
331
358
  }
332
359
  const existing = program.getSourceFile(file);
@@ -340,20 +367,16 @@ function getSourceFiles(absPath) {
340
367
  return output;
341
368
  }
342
369
  function replaceIdentifier(original, type, propertyName) {
343
- let symbol;
344
370
  if (type.isUnion()) {
345
- if (propertyName) {
346
- for (const t of type.types) {
347
- symbol = t.getProperty(propertyName);
348
- if (symbol)
349
- break;
350
- }
351
- } else {
352
- symbol = type.types.find((t) => t.flags !== ts3.TypeFlags.Undefined && t.symbol)?.symbol;
371
+ let result = original;
372
+ for (const t of type.types) {
373
+ result = replaceIdentifier(original, t, propertyName);
374
+ if (result !== original)
375
+ return result;
353
376
  }
354
- } else {
355
- symbol = propertyName ? type.getProperty(propertyName) : type.symbol;
377
+ return result;
356
378
  }
379
+ const symbol = propertyName ? type.getProperty(propertyName) : type.symbol;
357
380
  if (!symbol)
358
381
  return original;
359
382
  const symbolFullName = checker.getFullyQualifiedName(symbol);
@@ -362,7 +385,7 @@ function replaceIdentifier(original, type, propertyName) {
362
385
  return original;
363
386
  const dotIndex = symbolFullName.lastIndexOf(".");
364
387
  const strToReplace = dotIndex !== null ? symbolFullName.slice(dotIndex + 1) : symbolFullName;
365
- if (strToReplace != original)
388
+ if (strToReplace !== original)
366
389
  return original;
367
390
  return replaceValue;
368
391
  }
@@ -376,8 +399,8 @@ function replacePropertyAccess(original, symbol) {
376
399
  return replaceValue;
377
400
  }
378
401
  function findProjectRoot(dir, fileToSearch = "package.json") {
379
- while (!fs.existsSync(path.join(dir, fileToSearch))) {
380
- const parent = path.dirname(dir);
402
+ while (!fs.existsSync(path2.join(dir, fileToSearch))) {
403
+ const parent = path2.dirname(dir);
381
404
  if (parent === dir)
382
405
  throw new Error(`No ${fileToSearch} found`);
383
406
  dir = parent;
@@ -434,7 +457,7 @@ NodeHandler.register(ts5.SyntaxKind.ClassDeclaration, (node) => {
434
457
  const name = node.name ? node.name.text : "anon";
435
458
  const extensions = node.heritageClauses?.filter((h) => h.token === ts5.SyntaxKind.ExtendsKeyword);
436
459
  let output = `${name} = {}`;
437
- if (extensions && extensions.length && extensions[0].types.length)
460
+ if (extensions?.length && extensions[0].types.length)
438
461
  output = `${name} = new ${NodeHandler.handle(extensions[0].types[0].expression)}`;
439
462
  const declaredNames = new Set;
440
463
  let hasConstructor = false;
@@ -520,7 +543,7 @@ end function`;
520
543
  import ts7 from "typescript";
521
544
 
522
545
  // src/call_transformers/callTransformer.ts
523
- import path2 from "node:path";
546
+ import path3 from "node:path";
524
547
  import ts6 from "typescript";
525
548
  class CallTransformer {
526
549
  static handlers = new Map;
@@ -529,10 +552,23 @@ class CallTransformer {
529
552
  throw `Handler for '${symbolFullName}' was already registered`;
530
553
  this.handlers.set(symbolFullName, handler);
531
554
  }
532
- static handle(symbolFullName, functionName, callArgs, node, ctx) {
555
+ static handle(type, functionName, callArgs, node, ctx) {
556
+ let symbolFullName = "";
557
+ if (type.isUnion()) {
558
+ let result = null;
559
+ for (const t of type.types) {
560
+ const res = CallTransformer.handle(t, functionName, callArgs, node, ctx);
561
+ result ??= res;
562
+ }
563
+ return result;
564
+ } else if (type.symbol) {
565
+ symbolFullName = checker.getFullyQualifiedName(type.symbol);
566
+ }
567
+ if (!symbolFullName || symbolFullName.startsWith("__")) {
568
+ const symbol = checker.getSymbolAtLocation(node.expression);
569
+ symbolFullName = symbol ? checker.getFullyQualifiedName(symbol) : "";
570
+ }
533
571
  if (symbolFullName in extensionFunctions) {
534
- if (symbolFullName.startsWith("Math"))
535
- utilitiesToInsert.set("create_math", "Math = {}");
536
572
  utilitiesToInsert.set(symbolFullName, extensionFunctions[symbolFullName]);
537
573
  const params = callArgs.length ? `(${callArgs.join(",")})` : "";
538
574
  return `${functionName}${params}`;
@@ -543,41 +579,37 @@ class CallTransformer {
543
579
  return handler(functionName, callArgs, node, ctx);
544
580
  }
545
581
  }
546
- CallTransformer.register("Number.toString", (name) => {
547
- const number = name.slice(0, name.lastIndexOf("."));
548
- return `str(${number})`;
549
- });
550
582
  CallTransformer.register("Function.toString", (name) => {
551
583
  const func = name.slice(0, name.lastIndexOf("."));
552
584
  return `str(@${func})`;
553
585
  });
554
- CallTransformer.register("GreyHack.include", (name, args, node, ctx) => {
586
+ CallTransformer.register("GreyHack.include", (_name, _args, node, ctx) => {
555
587
  if (!node.arguments.length)
556
588
  return "";
557
589
  const fileArg = node.arguments[0];
558
590
  if (!ts6.isStringLiteralLike(fileArg))
559
591
  throw "You can't include variables";
560
- const absPath = path2.resolve(ctx.currentFolder, fileArg.text);
592
+ const absPath = path3.resolve(ctx.currentFolder, fileArg.text);
561
593
  const sources = getSourceFiles(absPath);
562
594
  for (const source of sources) {
563
- transpileSourceFile(source, ctx);
595
+ NodeHandler.handle(source);
564
596
  }
565
597
  return "";
566
598
  });
567
- CallTransformer.register("GreyHack.isType", (name, args) => {
599
+ CallTransformer.register("GreyHack.isType", (_name, args) => {
568
600
  return callUtilFunction("is_type", args.join(","));
569
601
  });
570
- CallTransformer.register("Boolean", (name, args) => {
602
+ CallTransformer.register("Boolean", (_name, args) => {
571
603
  if (!args.length)
572
604
  return "0";
573
605
  return `(not (not ${args[0]}))`;
574
606
  });
575
- CallTransformer.register("Number", (name, args) => {
607
+ CallTransformer.register("Number", (_name, args) => {
576
608
  if (!args.length)
577
609
  return "0";
578
610
  return `str(${args[0]}).val`;
579
611
  });
580
- CallTransformer.register("String", (name, args) => {
612
+ CallTransformer.register("String", (_name, args) => {
581
613
  if (!args.length)
582
614
  return "";
583
615
  return `str(${args[0]})`;
@@ -670,17 +702,12 @@ function handleCallArgs(callNode, ctx) {
670
702
  }
671
703
  NodeHandler.register(ts7.SyntaxKind.CallExpression, (node, ctx) => {
672
704
  const args = handleCallArgs(node, ctx);
673
- let name = NodeHandler.handle(node.expression);
705
+ const name = NodeHandler.handle(node.expression);
674
706
  const type = checker.getTypeAtLocation(node.expression);
675
- let symbolFullName = type.symbol ? checker.getFullyQualifiedName(type.symbol) : "";
676
- if (!symbolFullName || symbolFullName.startsWith("__")) {
677
- const symbol = checker.getSymbolAtLocation(node.expression);
678
- symbolFullName = symbol ? checker.getFullyQualifiedName(symbol) : "";
679
- }
680
- const transformed = CallTransformer.handle(symbolFullName, name, args, node, ctx);
707
+ const transformed = CallTransformer.handle(type, name, args, node, ctx);
681
708
  if (transformed !== null)
682
709
  return transformed;
683
- if (!args.length)
710
+ if (!args.length && !ts7.isParenthesizedExpression(node.expression))
684
711
  return name;
685
712
  return `${name}(${args.join(", ")})`;
686
713
  });
@@ -704,7 +731,7 @@ function shouldHaveOuterPrefix(node, operator) {
704
731
  const leftSymbol = checker.getSymbolAtLocation(node.left);
705
732
  if (!leftSymbol?.valueDeclaration)
706
733
  return false;
707
- return leftSymbol.valueDeclaration.pos < functionAncestor.pos || leftSymbol.valueDeclaration.pos > functionAncestor.end;
734
+ return leftSymbol.valueDeclaration.end < functionAncestor.pos || leftSymbol.valueDeclaration.pos > functionAncestor.end;
708
735
  }
709
736
  function isAssignmentChain(node, operator) {
710
737
  if (!assignmentOperators.has(operator))
@@ -715,7 +742,7 @@ function isAssignmentChain(node, operator) {
715
742
  return true;
716
743
  return false;
717
744
  }
718
- NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node) => {
745
+ NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node, ctx) => {
719
746
  let operatorToken = getOperatorToken(node.operatorToken) || node.operatorToken.getText();
720
747
  if (isAssignmentChain(node, operatorToken))
721
748
  throw `Assignment chaining is not supported`;
@@ -740,7 +767,7 @@ NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node) => {
740
767
  }
741
768
  let left = NodeHandler.handle(node.left);
742
769
  if (shouldHaveOuterPrefix(node, operatorToken))
743
- left = "outer." + left;
770
+ left = `outer.${left}`;
744
771
  if (nodeIsFunctionReference(node.left))
745
772
  left = asRef(left);
746
773
  if (operatorToken === "or" && ts7.hasOnlyExpressionInitializer(node.parent)) {
@@ -752,7 +779,15 @@ NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node) => {
752
779
  case "??":
753
780
  return callUtilFunction("nullish_coalescing_op", left, right);
754
781
  case "??=":
755
- return `${left} = ${callUtilFunction("nullish_coalescing_op", left, right)}`;
782
+ case "||=": {
783
+ const util = operatorToken === "??=" ? "nullish_coalescing_op" : "or_op";
784
+ ctx.forceSafeAccess = true;
785
+ let leftSafe = NodeHandler.handle(node.left);
786
+ ctx.forceSafeAccess = false;
787
+ if (nodeIsFunctionReference(node.left))
788
+ leftSafe = asRef(leftSafe);
789
+ return `${left} = ${callUtilFunction(util, leftSafe, right)}`;
790
+ }
756
791
  case "in":
757
792
  return `${right}.hasIndex(${left})`;
758
793
  case "&":
@@ -906,7 +941,7 @@ NodeHandler.register(ts8.SyntaxKind.Block, (node) => {
906
941
  const output = node.statements.map((val) => {
907
942
  let statement = NodeHandler.handle(val);
908
943
  statement = statement.split(`
909
- `).filter((s) => !!s).map((line) => "\t" + line).join(`
944
+ `).filter((s) => !!s).map((line) => ` ${line}`).join(`
910
945
  `);
911
946
  return statement;
912
947
  }).filter((s) => !!s).join(`
@@ -928,7 +963,13 @@ NodeHandler.register(ts8.SyntaxKind.ArrowFunction, (node) => {
928
963
  const params = node.parameters.map((param) => NodeHandler.handle(param));
929
964
  const body = ts8.isBlock(node.body) ? NodeHandler.handle(node.body) : ` return ${NodeHandler.handle(node.body)}`;
930
965
  if (ts8.isCallOrNewExpression(node.parent) || ts8.isParenthesizedExpression(node.parent)) {
931
- return "@" + createAnonFunction(body, params).name;
966
+ const mainNode = ts8.findAncestor(node.parent, (n) => n.parent && (ts8.isBlock(n.parent) || ts8.isSourceFile(n.parent)));
967
+ if (!mainNode) {
968
+ return `@${createAnonFunction(body, params).name}`;
969
+ }
970
+ const anon = createAnonFunction(body, params, false);
971
+ NodeHandler.addExtraOutput(mainNode, anon.str, null);
972
+ return `@${anon.name}`;
932
973
  }
933
974
  if (ts8.hasOnlyExpressionInitializer(node.parent) || ts8.isBinaryExpression(node.parent) || ts8.isReturnStatement(node.parent)) {
934
975
  return `function(${params.join(", ")})
@@ -949,20 +990,15 @@ NodeHandler.register(ts9.SyntaxKind.Identifier, (node, ctx) => {
949
990
  let name = node.text;
950
991
  if (name === "undefined")
951
992
  return "null";
952
- if (type.isUnion()) {
953
- const original = node.text;
954
- for (const t of type.types) {
955
- name = replaceIdentifier(node.text, t);
956
- if (name != original)
957
- break;
958
- }
959
- } else {
960
- name = replaceIdentifier(node.text, type);
993
+ name = replaceIdentifier(node.text, type);
994
+ const symbolFullName = type.symbol ? checker.getFullyQualifiedName(type.symbol) : "";
995
+ if (symbolFullName in globalObjects) {
996
+ utilitiesToInsert.set(symbolFullName, globalObjects[symbolFullName]);
961
997
  }
962
- if (ctx.namedImports[ctx.currentFilePath]?.[name]) {
998
+ if (ctx.namedImports[ctx.currentFilePath] && Object.hasOwn(ctx.namedImports[ctx.currentFilePath], name)) {
963
999
  name = ctx.namedImports[ctx.currentFilePath][name];
964
1000
  }
965
- if (ts9.isCallOrNewExpression(node.parent) && node != node.parent.expression) {
1001
+ if (ts9.isCallOrNewExpression(node.parent) && node !== node.parent.expression) {
966
1002
  if (nodeIsFunctionReference(node, type))
967
1003
  name = asRef(name);
968
1004
  }
@@ -1009,35 +1045,23 @@ NodeHandler.register(ts9.SyntaxKind.RegularExpressionLiteral, (node) => {
1009
1045
  });
1010
1046
 
1011
1047
  // src/visitors/imports.ts
1012
- import path3 from "node:path";
1048
+ import path4 from "node:path";
1013
1049
  import ts10 from "typescript";
1014
- function importFile(filePath, ctx, returnResult) {
1015
- let srcPath = path3.resolve(ctx.currentFolder, filePath);
1016
- if (!path3.extname(srcPath))
1050
+ function importFile(filePath, ctx) {
1051
+ let srcPath = path4.resolve(ctx.currentFolder, filePath);
1052
+ if (!path4.extname(srcPath))
1017
1053
  srcPath += ".ts";
1018
1054
  const source = program.getSourceFile(srcPath);
1019
1055
  if (!source) {
1020
1056
  console.error(`Failed to find source ${srcPath}`);
1021
1057
  return "";
1022
1058
  }
1023
- return transpileSourceFile(source, ctx, returnResult);
1059
+ return NodeHandler.handle(source);
1024
1060
  }
1025
1061
  NodeHandler.register(ts10.SyntaxKind.ImportDeclaration, (node, ctx) => {
1026
1062
  if (!node.importClause) {
1027
1063
  const moduleName = node.moduleSpecifier.text;
1028
- const transpiledFile = importFile(moduleName, ctx, true);
1029
- if (!transpiledFile)
1030
- return "";
1031
- const rndName = "func_" + (Date.now() * Math.random()).toString().slice(0, 6);
1032
- return [
1033
- `${rndName} = function`,
1034
- transpiledFile.split(`
1035
- `).map((line) => "\t" + line).join(`
1036
- `),
1037
- "end function",
1038
- `${rndName}()`
1039
- ].join(`
1040
- `);
1064
+ return importFile(moduleName, ctx);
1041
1065
  }
1042
1066
  if (node.importClause.phaseModifier)
1043
1067
  return "";
@@ -1061,37 +1085,38 @@ NodeHandler.register(ts10.SyntaxKind.ImportDeclaration, (node, ctx) => {
1061
1085
 
1062
1086
  // src/visitors/objects.ts
1063
1087
  import ts11 from "typescript";
1064
- function shouldGetSafely(node) {
1088
+ function shouldGetSafely(node, ctx) {
1065
1089
  if (ts11.isNonNullExpression(node.parent))
1066
1090
  return false;
1091
+ const callParent = ts11.findAncestor(node, (n) => n.parent && ts11.isCallExpression(n.parent) && n.parent.expression === n);
1092
+ if (callParent)
1093
+ return false;
1094
+ if (ctx.forceSafeAccess)
1095
+ return true;
1067
1096
  if (valueIsBeingAssignedToNode(node))
1068
1097
  return false;
1069
- if (ts11.isPropertyAccessExpression(node)) {
1070
- const rightType = checker.getTypeAtLocation(node.name);
1071
- if (!rightType.isUnion())
1072
- return !!node.questionDotToken;
1073
- const hasUndefined = rightType.types.some((t) => t.flags === ts11.TypeFlags.Undefined);
1074
- if (!hasUndefined)
1075
- return false;
1076
- if (!ts11.isCallExpression(node.parent))
1077
- return true;
1078
- if (node.parent.arguments.length)
1079
- return false;
1080
- } else {
1098
+ if (ts11.isElementAccessExpression(node)) {
1081
1099
  if (ts11.isNumericLiteral(node.argumentExpression) && !node.questionDotToken)
1082
1100
  return false;
1101
+ return true;
1083
1102
  }
1103
+ const type = checker.getTypeAtLocation(node);
1104
+ if (!type.isUnion())
1105
+ return !!node.questionDotToken;
1106
+ const hasNullish = type.types.some((t) => t.flags === ts11.TypeFlags.Undefined || ts11.TypeFlags.Null);
1107
+ if (!hasNullish)
1108
+ return false;
1084
1109
  return true;
1085
1110
  }
1086
1111
  NodeHandler.register(ts11.SyntaxKind.PropertyAccessExpression, (node, ctx) => {
1087
1112
  const left = NodeHandler.handle(node.expression);
1088
1113
  let right = NodeHandler.handle(node.name);
1089
1114
  right = replaceIdentifier(right, checker.getTypeAtLocation(node.expression), right);
1090
- const nodeSymbol = checker.getSymbolAtLocation(node);
1091
1115
  if (ctx.namespaceImports[ctx.currentFilePath]?.has(left))
1092
1116
  return right;
1093
- if (shouldGetSafely(node))
1117
+ if (shouldGetSafely(node, ctx))
1094
1118
  return callUtilFunction("get_property", left, `"${right}"`);
1119
+ const nodeSymbol = checker.getSymbolAtLocation(node);
1095
1120
  let output = `${left}.${right}`;
1096
1121
  output = replacePropertyAccess(output, nodeSymbol);
1097
1122
  if (nodeIsFunctionReference(node))
@@ -1107,7 +1132,7 @@ NodeHandler.register(ts11.SyntaxKind.ElementAccessExpression, (node, ctx) => {
1107
1132
  } else {
1108
1133
  right = NodeHandler.handle(node.argumentExpression);
1109
1134
  }
1110
- if (shouldGetSafely(node)) {
1135
+ if (shouldGetSafely(node, ctx)) {
1111
1136
  return callUtilFunction("get_property", left, `${right}`);
1112
1137
  }
1113
1138
  return `${left}[${right}]`;
@@ -1124,7 +1149,7 @@ function handleObjectLiteralExpression(node, ctx, currObj, outObjects, funcs) {
1124
1149
  function pushObj() {
1125
1150
  if (!currObj?.length)
1126
1151
  return "";
1127
- const res = currObj.filter((s) => s != "").join(",");
1152
+ const res = currObj.filter((s) => s !== "").join(",");
1128
1153
  if (res) {
1129
1154
  outObjects?.push(`{ ${res} }`);
1130
1155
  }
@@ -1170,8 +1195,8 @@ function handleObjectLiteralExpression(node, ctx, currObj, outObjects, funcs) {
1170
1195
  throw "You can't have method declarations inside an object that is not being assigned to a variable";
1171
1196
  }
1172
1197
  output += `
1173
- ` + funcs.map((func) => `${objectName}.${func}`).join(`
1174
- `);
1198
+ ${funcs.map((func) => `${objectName}.${func}`).join(`
1199
+ `)}`;
1175
1200
  }
1176
1201
  return output;
1177
1202
  }
@@ -1209,7 +1234,7 @@ NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
1209
1234
  ].join(`
1210
1235
  `);
1211
1236
  }
1212
- const incrementedStateVarName = "state_" + (Date.now() * Math.random()).toFixed(0).slice(0, 6);
1237
+ const incrementedStateVarName = `state_${(Date.now() * Math.random()).toFixed(0).slice(0, 6)}`;
1213
1238
  const output = [
1214
1239
  `${incrementedStateVarName} = 1`,
1215
1240
  `${initializer}`,
@@ -1290,7 +1315,7 @@ else
1290
1315
  end if`;
1291
1316
  return output;
1292
1317
  });
1293
- NodeHandler.register(ts12.SyntaxKind.WhileStatement, (node, ctx) => {
1318
+ NodeHandler.register(ts12.SyntaxKind.WhileStatement, (node) => {
1294
1319
  const expression = NodeHandler.handle(node.expression);
1295
1320
  const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1296
1321
  return [
@@ -1301,7 +1326,7 @@ NodeHandler.register(ts12.SyntaxKind.WhileStatement, (node, ctx) => {
1301
1326
  ].join(`
1302
1327
  `);
1303
1328
  });
1304
- NodeHandler.register(ts12.SyntaxKind.DoStatement, (node, ctx) => {
1329
+ NodeHandler.register(ts12.SyntaxKind.DoStatement, (node) => {
1305
1330
  const expression = NodeHandler.handle(node.expression);
1306
1331
  const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1307
1332
  return [
@@ -1314,7 +1339,7 @@ NodeHandler.register(ts12.SyntaxKind.DoStatement, (node, ctx) => {
1314
1339
  ].join(`
1315
1340
  `);
1316
1341
  });
1317
- NodeHandler.register(ts12.SyntaxKind.ContinueStatement, (node) => {
1342
+ NodeHandler.register(ts12.SyntaxKind.ContinueStatement, (_node) => {
1318
1343
  return "continue";
1319
1344
  });
1320
1345
  NodeHandler.register(ts12.SyntaxKind.BreakStatement, (node) => {
@@ -1342,7 +1367,7 @@ ${NodeHandler.handle(node.statement)}`;
1342
1367
 
1343
1368
  // src/visitors/variables.ts
1344
1369
  import ts13 from "typescript";
1345
- function handleVariableDeclaration(node, ctx) {
1370
+ function handleVariableDeclaration(node) {
1346
1371
  const left = NodeHandler.handle(node.name);
1347
1372
  const initializerType = node.initializer ? checker.getTypeAtLocation(node.initializer) : undefined;
1348
1373
  if (ts13.isPropertyDeclaration(node) && initializerType?.flags === ts13.TypeFlags.Object && !node.modifiers?.some((mod) => mod.kind === ts13.SyntaxKind.StaticKeyword) && !ts13.isFunctionLike(node.initializer)) {
@@ -1350,16 +1375,16 @@ function handleVariableDeclaration(node, ctx) {
1350
1375
  Initialize them in the constructor instead`);
1351
1376
  }
1352
1377
  let right = node.initializer ? NodeHandler.handle(node.initializer) || "null" : "null";
1353
- if (right != "null" && nodeIsFunctionReference(node.initializer, initializerType)) {
1378
+ if (right !== "null" && nodeIsFunctionReference(node.initializer, initializerType)) {
1354
1379
  right = asRef(right);
1355
1380
  }
1356
1381
  return `${left} = ${right}`;
1357
1382
  }
1358
- NodeHandler.register(ts13.SyntaxKind.VariableDeclarationList, (node, ctx) => {
1359
- return node.declarations.map((decl) => handleVariableDeclaration(decl, ctx)).join(`
1383
+ NodeHandler.register(ts13.SyntaxKind.VariableDeclarationList, (node) => {
1384
+ return node.declarations.map((decl) => handleVariableDeclaration(decl)).join(`
1360
1385
  `);
1361
1386
  });
1362
- NodeHandler.register(ts13.SyntaxKind.VariableStatement, (node, ctx) => {
1387
+ NodeHandler.register(ts13.SyntaxKind.VariableStatement, (node) => {
1363
1388
  if (node.modifiers?.some((modifier) => modifier.kind === ts13.SyntaxKind.DeclareKeyword))
1364
1389
  return "";
1365
1390
  return NodeHandler.handle(node.declarationList);
@@ -1370,7 +1395,7 @@ NodeHandler.register(ts13.SyntaxKind.EnumDeclaration, (node) => {
1370
1395
  const members = [];
1371
1396
  function addMember(name, initializer) {
1372
1397
  members.push(`${name}: ${initializer}`);
1373
- if (isNaN(+initializer))
1398
+ if (Number.isNaN(+initializer))
1374
1399
  return;
1375
1400
  members.push(`${initializer}: ${name}`);
1376
1401
  }
@@ -1392,51 +1417,42 @@ NodeHandler.register(ts13.SyntaxKind.EnumDeclaration, (node) => {
1392
1417
  return `${node.name.text} = { ${members.join(", ")} }`;
1393
1418
  });
1394
1419
 
1395
- // src/call_transformers/array.ts
1396
- CallTransformer.register("Array.slice", (name, args) => {
1397
- return name.slice(0, name.lastIndexOf(".")) + `[${args[0] ?? ""}:${args[1] ?? ""}]`;
1398
- });
1399
- CallTransformer.register("Array.toString", (name) => {
1400
- const arrayName = name.slice(0, name.lastIndexOf("."));
1401
- return `str(${arrayName})`;
1402
- });
1403
-
1404
1420
  // src/call_transformers/object.ts
1405
- CallTransformer.register("ObjectConstructor.hasOwn", (name, args) => {
1421
+ CallTransformer.register("ObjectConstructor.hasOwn", (_name, args) => {
1406
1422
  if (args.length < 2)
1407
1423
  throw "Invalid argument count";
1408
1424
  return `${args[0]}.hasIndex(${args[1]})`;
1409
1425
  });
1410
- CallTransformer.register("ObjectConstructor.assign", (name, args) => {
1426
+ CallTransformer.register("ObjectConstructor.assign", (_name, args) => {
1411
1427
  if (args.length < 2)
1412
1428
  throw "Invalid argument count";
1413
1429
  return callUtilFunction("assign_objects", args.join(","));
1414
1430
  });
1415
- CallTransformer.register("ObjectConstructor.keys", (name, args) => {
1431
+ CallTransformer.register("ObjectConstructor.keys", (_name, args) => {
1416
1432
  return `${args[0]}.indexes`;
1417
1433
  });
1418
- CallTransformer.register("ObjectConstructor.values", (name, args) => {
1434
+ CallTransformer.register("ObjectConstructor.values", (_name, args) => {
1419
1435
  return `${args[0]}.values`;
1420
1436
  });
1421
- CallTransformer.register("ObjectConstructor.sum", (name, args) => {
1437
+ CallTransformer.register("ObjectConstructor.sum", (_name, args) => {
1422
1438
  return `${args[0]}.sum`;
1423
1439
  });
1424
- CallTransformer.register("ObjectConstructor.shuffle", (name, args) => {
1440
+ CallTransformer.register("ObjectConstructor.shuffle", (_name, args) => {
1425
1441
  return `${args[0]}.shuffle`;
1426
1442
  });
1427
- CallTransformer.register("ObjectConstructor.replace", (name, args) => {
1443
+ CallTransformer.register("ObjectConstructor.replace", (_name, args) => {
1428
1444
  return `${args[0]}.replace(${args.slice(1).join(",")})`;
1429
1445
  });
1430
- CallTransformer.register("ObjectConstructor.remove", (name, args) => {
1446
+ CallTransformer.register("ObjectConstructor.remove", (_name, args) => {
1431
1447
  return `${args[0]}.remove(${args[1]})`;
1432
1448
  });
1433
- CallTransformer.register("ObjectConstructor.shift", (name, args) => {
1449
+ CallTransformer.register("ObjectConstructor.shift", (_name, args) => {
1434
1450
  return `${args[0]}.pull`;
1435
1451
  });
1436
- CallTransformer.register("ObjectConstructor.size", (name, args) => {
1452
+ CallTransformer.register("ObjectConstructor.size", (_name, args) => {
1437
1453
  return `${args[0]}.len`;
1438
1454
  });
1439
- CallTransformer.register("ObjectConstructor.indexOf", (name, args) => {
1455
+ CallTransformer.register("ObjectConstructor.indexOf", (_name, args) => {
1440
1456
  return `${args[0]}.indexOf(${args[1]})`;
1441
1457
  });
1442
1458
  CallTransformer.register("Object.toString", (name) => {
@@ -1444,14 +1460,6 @@ CallTransformer.register("Object.toString", (name) => {
1444
1460
  return `str(${objectName})`;
1445
1461
  });
1446
1462
 
1447
- // src/call_transformers/string.ts
1448
- CallTransformer.register("String.slice", (name, args) => {
1449
- return name.slice(0, name.lastIndexOf(".")) + `[${args[0] ?? ""}:${args[1] ?? ""}]`;
1450
- });
1451
- CallTransformer.register("String.toString", (name) => {
1452
- return name.slice(0, name.lastIndexOf("."));
1453
- });
1454
-
1455
1463
  // src/transpiler.ts
1456
1464
  var program;
1457
1465
  var checker;
@@ -1594,6 +1602,12 @@ var extensionFunctions = {
1594
1602
  "end function"
1595
1603
  ].join(`
1596
1604
  `),
1605
+ "Array.toString": `list.toString = function
1606
+ return str(self)
1607
+ end function`,
1608
+ "Array.slice": `list.slice = function(a, b)
1609
+ return self[a:b]
1610
+ end function`,
1597
1611
  "String.startsWith": [
1598
1612
  "string.startsWith = function(search, pos = 0)",
1599
1613
  "\tif pos < 0 then pos = 0",
@@ -1636,6 +1650,12 @@ var extensionFunctions = {
1636
1650
  "end function"
1637
1651
  ].join(`
1638
1652
  `),
1653
+ "String.toString": `string.toString = function
1654
+ return str(self)
1655
+ end function`,
1656
+ "String.slice": `string.slice = function(a, b)
1657
+ return self[a:b]
1658
+ end function`,
1639
1659
  "Number.toFixed": [
1640
1660
  "number.toFixed = function(digits = 0)",
1641
1661
  "\tdigits = floor(digits)",
@@ -1657,23 +1677,120 @@ var extensionFunctions = {
1657
1677
  "end function"
1658
1678
  ].join(`
1659
1679
  `),
1660
- "Math.min": [
1661
- "Math.min = function(numbers)",
1662
- "\tcurr_min = null",
1663
- "\tfor num in numbers",
1664
- "\t\tif curr_min == null or num < curr_min then curr_min = num",
1680
+ "Number.toString": `number.toString = function
1681
+ return str(self)
1682
+ end function`,
1683
+ "Function.toString": `funcRef.toString = function
1684
+ return str(@self)
1685
+ end function`
1686
+ };
1687
+ var globalObjects = {
1688
+ MapConstructor: [
1689
+ "Map = {}",
1690
+ "Map.constructor = function(entries)",
1691
+ "\tself.data = {}",
1692
+ "\tif not entries then return self",
1693
+ "\tfor entry in entries",
1694
+ "\t\tself.data[entry[0]] = entry[1]",
1665
1695
  "\tend for",
1666
- "\treturn curr_min",
1696
+ "\treturn self",
1697
+ "end function",
1698
+ "Map.clear = function",
1699
+ "\tfor key in self.data.indexes",
1700
+ "\t\tself.data.remove(@key)",
1701
+ "\tend for",
1702
+ "end function",
1703
+ "Map.delete = function(key)",
1704
+ "\treturn self.data.remove(key)",
1705
+ "end function",
1706
+ "Map.forEach = function(callback)",
1707
+ "\tfor item in self.data",
1708
+ "\t\tcallback(@item.value, @item.key, self)",
1709
+ "\tend for",
1710
+ "end function",
1711
+ "Map.get = function(key)",
1712
+ "\tif not self.data.hasIndex(@key) then retun null",
1713
+ "\treturn self.data[@key]",
1714
+ "end function",
1715
+ "Map.has = function(key)",
1716
+ "\treturn self.data.hasIndex(@key)",
1717
+ "end function",
1718
+ "Map.set = function(key, value)",
1719
+ "\tself.data[@key] = @value",
1720
+ "\treturn self",
1721
+ "end function",
1722
+ "Map.entries = function",
1723
+ "\tentries = []",
1724
+ "\tfor item in self.data",
1725
+ "\t\tentries.push([@item.key, @item.value])",
1726
+ "\tend for",
1727
+ "\treturn entries",
1728
+ "end function",
1729
+ "Map.keys = function",
1730
+ "\treturn self.data.indexes",
1731
+ "end function",
1732
+ "Map.values = function",
1733
+ "\treturn self.data.values",
1734
+ "end function"
1735
+ ].join(`
1736
+ `),
1737
+ SetConstructor: [
1738
+ "Set = {}",
1739
+ "Set.constructor = function(values)",
1740
+ "\tself.data = {}",
1741
+ "\tif not values then return self",
1742
+ "\tfor v in values",
1743
+ "\t\tself.data[@v] = 1",
1744
+ "\tend for",
1745
+ "\treturn self",
1746
+ "end function",
1747
+ "Set.add = function(value)",
1748
+ "\tself.data[@value] = 1",
1749
+ "\treturn self",
1750
+ "end function",
1751
+ "Set.clear = function",
1752
+ "\tfor key in self.data.indexes",
1753
+ "\t\tself.data.remove(@key)",
1754
+ "\tend for",
1755
+ "end function",
1756
+ "Set.delete = function(key)",
1757
+ "\treturn self.data.remove(key)",
1758
+ "end function",
1759
+ "Set.forEach = function(callback)",
1760
+ "\tfor key in self.data.indexes",
1761
+ "\t\tcallback(@key, self)",
1762
+ "\tend for",
1763
+ "end function",
1764
+ "Set.has = function(key)",
1765
+ "\treturn self.data.hasIndex(@key)",
1766
+ "end function",
1767
+ "Set.values = function",
1768
+ "\treturn self.data.indexes",
1667
1769
  "end function"
1668
1770
  ].join(`
1669
1771
  `),
1670
- "Math.max": [
1772
+ Math: [
1773
+ 'Math = { "PI": @pi, "abs": @abs, "acos": @acos, "asin": @asin, "atan": @atan, "ceil": @ceil, "floor": @floor, "cos": @cos, "sin": @sin, "tan": @tan, "sqrt": @sqrt, "sign": @sign, "round": @round, "random": @rnd, "log": @log }',
1671
1774
  "Math.max = function(numbers)",
1672
1775
  "\tcurr_max = null",
1673
1776
  "\tfor num in numbers",
1674
1777
  "\t\tif curr_max == null or num > curr_max then curr_max = num",
1675
1778
  "\tend for",
1676
1779
  "\treturn curr_max",
1780
+ "end function",
1781
+ "Math.min = function(numbers)",
1782
+ "\tcurr_min = null",
1783
+ "\tfor num in numbers",
1784
+ "\t\tif curr_min == null or num < curr_min then curr_min = num",
1785
+ "\tend for",
1786
+ "\treturn curr_min",
1787
+ "end function"
1788
+ ].join(`
1789
+ `),
1790
+ Console: [
1791
+ 'console = { "clear": @clear_screen }',
1792
+ "console.log = function(data)",
1793
+ '\tprint(data.join(", "))',
1677
1794
  "end function"
1678
1795
  ].join(`
1679
1796
  `)
@@ -1743,50 +1860,57 @@ var utilFunctions = {
1743
1860
  ].join(`
1744
1861
  `),
1745
1862
  nullish_coalescing_op: `nullish_coalescing_op = function(left, right)
1746
- if left == null then return @right
1863
+ if @left == null then return @right
1747
1864
  return @left
1748
1865
  end function`,
1749
1866
  or_op: `or_op = function(left, right)
1750
- if not left then return @right
1867
+ if not @left then return @right
1751
1868
  return @left
1752
1869
  end function`,
1753
1870
  is_type: `is_type = function(value, type)
1754
- return typeof(value) == type
1871
+ return typeof(@value) == type
1755
1872
  end function`,
1756
1873
  conditional_expr: `conditional_expr = function(cond, when_true, when_false)
1757
- if cond then return when_true
1758
- return when_false
1874
+ if cond then return @when_true
1875
+ return @when_false
1759
1876
  end function`
1760
1877
  };
1761
- function createAnonFunction(body, params) {
1878
+ var anonFunctionsCreated = 0;
1879
+ function createAnonFunction(body, params, insertToUtils = true) {
1762
1880
  const defaultParams = new Array(3).fill(0).map((_, i) => `param${i}`);
1763
- const nextName = `func_${utilitiesToInsert.size}`;
1881
+ const nextName = `func_${anonFunctionsCreated}`;
1764
1882
  const paramString = Object.assign(defaultParams, params).join(",");
1765
1883
  const result = `${nextName} = function(${paramString})
1766
1884
  ${body}
1767
1885
  end function`;
1768
- utilitiesToInsert.set(nextName, result);
1886
+ anonFunctionsCreated++;
1887
+ if (insertToUtils)
1888
+ utilitiesToInsert.set(nextName, result);
1769
1889
  return { name: nextName, str: result };
1770
1890
  }
1771
- function transpileProgram(entryFileRelativePath) {
1772
- const ctx = {
1773
- currentFolder: "",
1774
- currentFilePath: path4.resolve(process.cwd(), entryFileRelativePath),
1891
+ function createContext(currentFileName = "file.ts") {
1892
+ return {
1893
+ currentFolder: process.cwd(),
1894
+ currentFilePath: path5.resolve(process.cwd(), currentFileName),
1775
1895
  namedImports: {},
1776
1896
  namespaceImports: {},
1777
- visitedFiles: {},
1778
- output: []
1897
+ visitedFiles: new Set,
1898
+ output: [],
1899
+ extraOutput: new Map
1779
1900
  };
1901
+ }
1902
+ function transpileProgram(entryFileRelativePath) {
1903
+ const ctx = createContext(entryFileRelativePath);
1780
1904
  NodeHandler.transpileContext = ctx;
1781
- ctx.currentFolder = path4.dirname(ctx.currentFilePath);
1905
+ ctx.currentFolder = path5.dirname(ctx.currentFilePath);
1782
1906
  if (!fs2.existsSync(ctx.currentFilePath)) {
1783
1907
  console.error(`Error: file '${ctx.currentFilePath}' doesn't exist`);
1784
1908
  process.exit(1);
1785
1909
  }
1786
1910
  let start = Date.now();
1787
- const tsconfigPath = findProjectRoot(process.cwd(), "tsconfig.json") + "/tsconfig.json";
1911
+ const tsconfigPath = `${findProjectRoot(process.cwd(), "tsconfig.json")}/tsconfig.json`;
1788
1912
  const res = ts14.readConfigFile(tsconfigPath, ts14.sys.readFile);
1789
- const parsed = ts14.parseJsonConfigFileContent(res.config, ts14.sys, path4.dirname(tsconfigPath));
1913
+ const parsed = ts14.parseJsonConfigFileContent(res.config, ts14.sys, path5.dirname(tsconfigPath));
1790
1914
  if (!parsed.options.types)
1791
1915
  parsed.options.types = [];
1792
1916
  if (!parsed.options.types.includes("@grey-ts/types")) {
@@ -1805,7 +1929,7 @@ function transpileProgram(entryFileRelativePath) {
1805
1929
  console.error(`Error: failed to find '${ctx.currentFilePath}' from the included sources`);
1806
1930
  process.exit(1);
1807
1931
  }
1808
- transpileSourceFile(entry, ctx);
1932
+ NodeHandler.handle(entry);
1809
1933
  if (utilitiesToInsert.size) {
1810
1934
  ctx.output.unshift(...utilitiesToInsert.values());
1811
1935
  utilitiesToInsert.clear();
@@ -1813,34 +1937,6 @@ function transpileProgram(entryFileRelativePath) {
1813
1937
  console.log(`Transpiling took ${Date.now() - start} ms`);
1814
1938
  return ctx.output;
1815
1939
  }
1816
- function transpileSourceFile(sourceFile, ctx, returnResult) {
1817
- if (ctx.visitedFiles[sourceFile.fileName])
1818
- return "";
1819
- ctx.visitedFiles[sourceFile.fileName] = true;
1820
- if (sourceFile.isDeclarationFile)
1821
- return "";
1822
- if (program.isSourceFileDefaultLibrary(sourceFile) || program.isSourceFileFromExternalLibrary(sourceFile))
1823
- return "";
1824
- const prevFile = ctx.currentFilePath;
1825
- ctx.currentFilePath = sourceFile.fileName;
1826
- ctx.currentFolder = path4.dirname(sourceFile.fileName);
1827
- ctx.namedImports[sourceFile.fileName] = {};
1828
- ctx.namespaceImports[sourceFile.fileName] = new Set;
1829
- const output = [];
1830
- sourceFile.forEachChild((node) => {
1831
- const result = NodeHandler.handle(node);
1832
- if (!result)
1833
- return;
1834
- if (!returnResult)
1835
- ctx.output.push(result);
1836
- else
1837
- output.push(result);
1838
- });
1839
- ctx.currentFilePath = prevFile;
1840
- ctx.currentFolder = path4.dirname(prevFile);
1841
- return output.join(`
1842
- `);
1843
- }
1844
1940
 
1845
1941
  // src/index.ts
1846
1942
  var noMoreFlags = false;
@@ -1872,7 +1968,7 @@ function createOutputFile(fileIndex, basename, content) {
1872
1968
  if (fileIndex > 0)
1873
1969
  basename = `${basename}-${fileIndex}`;
1874
1970
  const outFileName = args.length > 1 ? args[1] : `${basename}.src`;
1875
- const outFilePath = path5.join(outDirPath, outFileName);
1971
+ const outFilePath = path6.join(outDirPath, outFileName);
1876
1972
  fs3.writeFileSync(outFilePath, content);
1877
1973
  }
1878
1974
  if (command === "transpile") {
@@ -1881,7 +1977,7 @@ if (command === "transpile") {
1881
1977
  process.exit(2);
1882
1978
  }
1883
1979
  const entryFile = args[0];
1884
- const basename = path5.basename(entryFile, ".ts");
1980
+ const basename = path6.basename(entryFile, ".ts");
1885
1981
  const transpiledStatements = transpileProgram(entryFile);
1886
1982
  if (flags.includes("--print") || flags.includes("-p")) {
1887
1983
  console.log(transpiledStatements.join(`
@@ -1899,7 +1995,7 @@ if (command === "transpile") {
1899
1995
  content = "";
1900
1996
  continue;
1901
1997
  }
1902
- content += statement + `
1998
+ content += `${statement}
1903
1999
  `;
1904
2000
  }
1905
2001
  if (content.length)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grey-ts/transpiler",
3
- "version": "1.4.3",
3
+ "version": "2.0.0",
4
4
  "description": "Transpiles TypeScript into GreyScript",
5
5
  "author": "Okka",
6
6
  "module": "src/index.ts",
@@ -31,14 +31,15 @@
31
31
  ],
32
32
  "scripts": {
33
33
  "prepare": "bun run build",
34
- "build": "bun run scripts/build.ts"
34
+ "build": "bun test --only-failures && bun run scripts/build.ts"
35
35
  },
36
36
  "devDependencies": {
37
- "@types/bun": "latest",
38
- "@grey-ts/types": "latest"
37
+ "@biomejs/biome": "2.3.14",
38
+ "@grey-ts/types": "^3.0.0",
39
+ "@types/bun": "latest"
39
40
  },
40
41
  "peerDependencies": {
41
- "typescript": "^5",
42
+ "typescript": "^5.9.3",
42
43
  "@grey-ts/types": "^2.2.0"
43
44
  }
44
45
  }