npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

scriptease-cli

v2.1.0

Published

ScriptEase is a powerful tool that allows for easy management and execution of npm scripts, written in JavaScript, on any operating system, enabling the creation of complex scripts

Downloads

17

Readme

NPM version Tests semantic-release: angular Commitizen friendly Commitizen friendly

ScriptEase is a powerful tool that allows for easy management and execution of npm scripts, written in JavaScript, on any operating system, enabling the creation of complex scripts

This is a beta version of ScriptEase. A stable and complete version with features such as variables, hooks, better parameters, more flexibility, and more useful built-in commands is coming soon. Users are encouraged to submit any issues they encounter on the project's GitHub page.

Additionally, the log system will be upgraded to be more simple and flexible, with different levels of logs.

Table of content

Installation

Install using npm:

npm install --save-dev scriptease-cli

npm is the only package manager yet supported.

Getting Started

npm install --save-dev scriptease-cli
mkdir scripts
touch seconfig.json scripts/all.script.js
$EDITOR scritps/all.script.js
$EDITOR seconfig.json

Writing up your first script:

  • scritps/all.script.js

    const { leaf } = require('scriptease-cli');
    
    leaf('ping', () => {
      console.log('Pong!');
    });
  • seconfig.json

    {
      "directories": ["scripts"]
    }

Back in the terminal:

$ npx se run ping
# or
$ npx se run ping -d scripts # if the seconfig.json is no set

# Logs messages...

Pong!

# Logs messages...

Set up your script in package.json:

"scripts": {
    "ping": "se ping"
}

In a future version, there will be no need to specify the script to execute inside the package.json.

"scripts": {
   "ping": "se"
}

Then run your script:

npm run ping

Run Cycle Overview

  1. User (you) executes ScriptEase (se run).
  2. ScriptEase loads options from the config file (seconfig.json) and checks the validity of the given options.
  3. ScriptEase gets args options given by the user in the command line and overwrites/adds them to the merged options.
  4. ScriptEase searches for the scripts files:
    1. ScriptEase searches for all .script.js files inside the given directories.
    2. ScriptEase adds the files directly given inside the config (seconfig.json) and in the args.
  5. ScriptEase builds the scripts Tree from the scripts files.
  6. ScriptEase gets the identifier (script name) given by the user and searches if the script exists inside the built tree.
  7. If the script exists, ScriptEase executes the script.
  8. At the end of the execution, ScriptEase shows the status of the execution.

Async / Await

You can (and it is advise) use asynchronous, like this:

leaf('test', async () => {
  const resultParser = await runner.run('test:parser');
  const resultExecutor = await runner.run('test:executor');
  // ...
});

Hooks

Not available yet (coming soon)

Dynamically generate script

Given ScriptEase’s use of function expressions to define suites and test cases, it’s straightforward to generate your scripts dynamically. No special syntax is required which you may have seen in other frameworks like mocha.

branch('test', () => {
  const components = ['parser', 'ast', 'executor', 'logger'];

  for (const component of components) {
    leaf(component, async () => {
      console.log(`Running unit tests for '${component}'`);
      await runner.npxExec('mocha', [`tests/${component}/**/*.spec.js`]); // will throw if mocha exit code != 0
    });
  }
});

Runners

The runner interface can be accessible as follow:

const { runner } = require('scriptease-cli');

This interface gives you some useful function to execute other scripts or shell commands.

Functions:

  • run(identifier: string): Promise<Result>
  • runCatch(identifier: string): Promise<Result>
  • runAllStopOnFailure(identifiers: string[]): Promise<MultipleResult<Result>>
  • runAllStopOnFailureCatch(identifiers: string[]): Promise<MultipleResult<Result>>
  • runAllIgnoreFailure(identifiers: string[]): Promise<MultipleResult<Result>>
  • runAllIgnoreFailureCatch(identifiers: string[]): Promise<MultipleResult<Result>>
  • exec(cmd: string, config: ExecConfig = {}): Promise<ExecResult>
  • npxExec(cmd: string, args: string[] = [], options: NpxExecOption[] = [], config: NpxExecConfig = {}): Promise<ExecResult>

example :

leaf('test', async () => {
  await runner.run('test:unit'); // will throw if the 'test:unit' script has thrown
  const result = await runner.runCatch('test:integration'); // will not throw even if the 'test:unit' script has thrown
  console.log(result.isOK()); // 'true' if the sub script didn't throw, 'false' otherwise.
});

branch('test', () => {
  leaf('unit', async () => {
    await runner.npxExec('mocha', ...); // will throw if mocha fail
  });
  leaf('integration', async () => {
    await runner.exec('./myIntegrationScript.sh', ...); // will throw if the command fail
  });
});

example with suites :

leaf('test', async () => {
  await runner.runAllStopOnFailure(['test:unit', 'test:integration']); // will throw, and 'test:integration' will not be executed
  await runner.runAllIgnoreFailure(['test:unit', 'test:integration']); // will execute the two script and throw after
});

branch('test', () => {
  leaf('unit', async () => {
    throw new Error('');
  });
  leaf('integration', async () => {
    // ...
  });
});

Script Throw system

The script leaves have a custom error handler.

leaf('all', async () => {
  const result = await runner.runCatch('1');
  console.log(result.getError()); // 1;

  // or (do the same)

  try {
    const result = await runner.run('1');
  } catch (result) {
    console.log(result.getError()); // 1;
  }
});

leaf('1', async () => {
  throw 1;
});

throw a Result :

leaf('all', async () => {
  const result = await runner.runCatch('1');
  console.log(result.getCmd()); // 'unknown_command';
  console.log(result.getCode()); // 127;
});

leaf('1', async () => {
  await runner.exec('unknown_command'); // throw
});

Leaves Payload

Your scripts can return values.

Basic example:

leaf('script1', async => {
  const result1 = await runner.run('script2');
  const result2 = await runner.run('script3');
  console.log(result1.getPayload()); // 5
  console.log(result2.getPayload().key1); // Hello
});
leaf('script2', async => {
  return 5;
});
leaf('script3', async => {
  return {key1: 'Hello'}
});

Advanced example:

leaf('cover', async () => {
  const multipleResult = await runner.runAllIgnoreFailureCatch(['cover:parser', 'cover:logger']);
  const paths = multipleResult.getResults().map((result) => result.getPayload());
  console.log(paths); // ['./cover/parser', './cover/logger']
  // merge all cover reports and show the final coverage
  // ...
  if (multipleResult.isKO()) throw multipleResult;
});

branch('cover', () => {
  leaf('parser', async () => {
    const reportPath = './cover/parser';
    const result = await runner.npxExec('nyc', ... , { crash: false }); // 'crash' have been set to true for stoping the function to throw
    result.setPayload(reportPath);
    if (result.isKO()) throw result;
    return result;
  });
  leaf('logger', async () => {
    const reportPath = './cover/logger';
    const result = await runner.npxExec('nyc', ... , { crash: false });
    result.setPayload(reportPath);
    if (result.isKO()) throw result;
    return result;
  });
});

Use Typescript

By default, scriptEase will not be able to load your typescript files. But you can make this possible by loading a module that will compile your typescript files on the fly.

For example, you can use ts-node :

npm install -D ts-node
npx se run -r ts-node/register ...

Command line usage

npx se --help # Show the main help
#npx se <cmd> --help # Show the help of a specific command
npx se run --help # Show the run command help

Options

--file <file1> ... <fileN>

Alias: -f

Load the given file.

--directory <dir1> ... <dirN>

Alias: -d

Load all the files in the given directories. files must have the following extension: .script.js or .script.ts

By default, scriptEase is not able to load Typescript files. Use Typescript

--require <module1> ... <moduleN>

Alias: -r

Require the given module before running.