Skip to content

Programmatically execute JavaScript strings, safely

License

Notifications You must be signed in to change notification settings

parsasi/js-exec

Repository files navigation

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

About

Programmatically execute JavaScript strings, safely

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published