/js-exec

Programmatically execute JavaScript strings, safely

Primary LanguageTypeScriptMIT LicenseMIT

js-exec ๐Ÿงฐ

Execute sandboxed JavaScript strings.


Downloads Per Month Top Language License: MITNPM Maintenance

The problem

Executing an inputted string, as JS code can be Extremely risky. These risks can be reduced, when using new Function syntax; however, this can also be limiting, as it would only give you access to the global scope.

This solution โœจ

js-exec will sandbox the JavaScript code (passed as a string). It will only give it access to the objects that are given to the sandbox. This way, you will have full control of what the code can or cannot access.

Features

  • No Dependencies - no dependencies
  • TypeScript - Everything is TypeScript based
  • Lint - Preconfigured ESlint with Airbnb config
  • Interceptors - pass in interceptors to the sandbox, to manipulate the source, before being executed

Execute TypeScript

We are adding a TypeScript interceptors, very soon. Please stay tuned for exciting news.

Installation

This module is distributed via npm which should be installed as one of your project's dependencies:

npm i --save js-exec

Usage

Basic

  • Install js-exec
  • Import exec from the package
  • Pass the source to exec.
  • Use the sandbox returned to pass dependencies to the code.
import { exec } from "js-exec";

const source = `console.log("Hello from js-exec ๐Ÿ‘‹");`;

const sandbox = exec(source);

sandbox();
// Error: Cannot read property 'log' of undefined

sandbox({ console });
// Hello from js-exec ๐Ÿ‘‹

Callbacks

The execfunction will accept a second parameterโ€”i.e. optionsโ€”for additional customizations.

You can pass in onSuccess and onError callbacks to the options object:

import { exec } from "js-exec";

const source = `console.log("Hello from js-exec ๐Ÿ‘‹");`;

const sandbox = exec(source, {
  onSuccess: () => console.log("Taadaa ๐ŸŽ‰๐ŸŽ‰"),
  onError: (e: Error) => console.log("Something occurred ๐Ÿฅบ\n", e),
});

sandbox({});
// Something occurred ๐Ÿฅบ
// TypeError: Cannot read property 'log' of undefined

sandbox({ console });
// Hello from js-exec ๐Ÿ‘‹
// Taadaa ๐ŸŽ‰๐ŸŽ‰

Interceptors

Interceptors will help you run functions on the code, before it gets executed.

Each Interceptor receives a source: string and returns a transformed source: string.

import { exec, Source } from "js-exec";

const source = `console.log("There are some f***s here!");`;

//Removes bad words inside the source
const removeBadWords = (source: Source): Source => {
  let cleanSource = source;
  const badWordsArray = ["f***"];
  const textToReplace = "๐ŸšซBAD WORD๐Ÿšซ";
  badWordsArray.forEach(
    (word) => (cleanSource = cleanSource.replace(word, textToReplace))
  );
  return cleanSource;
};

//Interceptors are run sequentially
const interceptors = [removeBadWords];

//interceptors are passed into the options object
const runCode = exec(source, { interceptors });
runCode({ console });
// There are some ๐ŸšซBAD WORD๐Ÿšซs here!

Global Values

You can also make values available, on all executions of the sandbox; If, you wish to re-use them.

const pi = 3.141592;

const globalValues = { pi }

//pi will be available on every execution of runCode
const runCode = exec(source, { globalValues });

Contributing

This package is a beginner-friendly package. If you don't know where to start, visit Make a Pull Request to learn how to make pull requests.

Please visit Contributing for more info.

Code of Conduct

Please visit Code of Conduct.


License

MIT