patriksimek / vm2

Advanced vm/sandbox for Node.js
MIT License
3.86k stars 293 forks source link

Typescript Set transpilation issues #530

Open RobPruzan opened 1 year ago

RobPruzan commented 1 year ago

When transpiling typescript that has Set usage, many operations do not work as expected. Works correctly when using conventional JS syntax. Example:

  var jsCode = `
  var visited = new Set();
  var visualization = [];
  visited.add(1);
  visited.add(2);
  console.log(visited, [...visited.keys()]);
  visited
  //... your other code ...
`;

  const vm = new VM({
    timeout: 10000,
    sandbox: {
      globalVar,
      console: {
        log: (...args) => {
          console.log('From sandbox:', ...args);
        },
      },
    },
  });

Output:

From sandbox: Set {} [ 1, 2 ]

When attempting to run transpiled typescript (ts is identical to js code in prev example) with the same operation:

  const jsCode = ts.transpileModule(code, {
    compilerOptions: { module: ts.ModuleKind.CommonJS },
  }).outputText;
  console.log('the js code', jsCode);

  const vm = new VM({
    timeout: 10000,
    sandbox: {
      globalVar,
      console: {
        log: (...args) => {
          console.log('From sandbox:', ...args);
        },
      },
    },
  });

Transpilled JS output:

code var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
var visited = new Set();
var visualization = [];
visited.add(1);
visited.add(2);
console.log(visited, __spreadArray([], visited.keys(), true));
visited

Program output:

From sandbox: Set {} []

Normal set operations work like .size or has, but there is no way to access the items in the Set other then an operation like:

var visited = new Set();
var visualization = [];
visited.add(1);
visited.add(2);
console.log(visited, visited.keys().next().value);
visited

Transpiled TS

code var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
var visited = new Set();
var visualization = [];
visited.add(1);
visited.add(2);
console.log(visited, __spreadArray([], visited.keys(), true));
visited;

Output of program:

From sandbox: Set {} 1