Skip to content

A set of pure JS extensions for QuickJS

Notifications You must be signed in to change notification settings

nicolasduteil/qjs-ext-lib

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

85 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A set of pure JS extensions for QuickJS

  • parse command line arguments and build static command line utilities using JS (see doc)
  • execute external processes asynchronously (see doc)
  • setInterval / clearInterval / wait functions (see doc)
  • curl wrapper supporting all HTTP methods and most of curl options (see doc)
  • ssh wrapper (for quick-and-dirty remote scripting without ansible) (see doc)
  • minimal unit testing library (see doc)
  • semver versions comparison (see doc)
  • interact with pass (see doc)
  • build glamorous shell scripts using gum (see doc)

Rational

I'm focused on building static binaries targeting linux command line. This library is an intent at providing just enough to make creating static adhoc scripts easier on linux

Nix

In order to get a shell with the static interpreter (qjs.sh) and compiler (qjsc.sh), as well as this library, run following command

nix develop github:ctn-malone/qjs-ext-lib

Inside the Nix shell, any .js file from the library can be imported from an ext directory

import { curlRequest } from 'ext/curl.js';

/*
    Perform a POST request to https://jsonplaceholder.typicode.com/posts and print response payload
 */

const main = async () => {
    const body = await curlRequest('https://jsonplaceholder.typicode.com/posts', {
        method:'post',
        json: {
            title: 'foo',
            body: 'bar',
            userId: 1
        }
    });
    console.log(JSON.stringify(body, null, 4));
}

main();

Examples

Execute external processes

import { exec } from '../../src/process.js';

/*
    Run 3 external commands in parallel 
 */

const main = async () => {
    const commands = [
        'date',
        'uptime',
        'which sh'
    ];
    const promises = [];
    commands.forEach(c => promises.push(exec(c)));
    (await Promise.all(promises)).forEach((output, i) => {
        console.log(`${commands[i]} => ${output}`);
    });
}

main();

See more examples

Perform REST calls

import { curlRequest } from '../../src/curl.js';

/*
    Perform a POST request to https://jsonplaceholder.typicode.com/posts and print response payload
 */

const main = async () => {
    const body = await curlRequest('https://jsonplaceholder.typicode.com/posts', {
        method:'post',
        json: {
            title: 'foo',
            body: 'bar',
            userId: 1
        }
    });
    console.log(JSON.stringify(body, null, 4));
}

main();

See more examples

Execute remote command through SSH

import { Ssh } from 'ext/ssh.js';
import * as std from 'std';

const main = async () => {
    /* 
        Setup local port forwarding for 30s
        - 127.0.0.1:10000 => test:10000
        - 127.0.0.1:10001 => test:20001
    */
    const ssh = new Ssh(`root@test:2222`, 'sleep 30', {
        localForward:[
            {remotePort:10000},
            {remotePort:20001, localPort:10001}
        ]
    });
    const p = ssh.run();
    const success = await ssh.waitForSessionSetup();
    await p;
}

main();

See more examples

Build CLI tools

import * as gum from 'ext/gum.js';

while (true) {
  const expectedNumber = (Math.floor(Math.random() * 5) + 1).toString();
  const item = gum.chooseItemFromList(
    [1, 2, 3, 4, 5].map((e) => e.toString()),
    {
      header: 'Please try to guess my number',
      cursor: '-> ',
    }
  );
  if (!item) {
    break;
  }
  let message =
    item.value === expectedNumber.toString()
      ? gum.style('Correct !', { foreground: '#00ff00' })
      : gum.style('Wrong !', { foreground: '#ff0000' });
  console.log(
    `${message} The number was ${gum.style(expectedNumber, { bold: true })}`
  );
  if (!gum.confirm({ prompt: 'Do you want to play again ?' })) {
    break;
  }
}
console.log('Goodbye !');

Example

See more examples

Run unit tests

Run run.js under test directory

qjs run.js

NB: some tests will be skipped unless specific environment variables are defined

  • ssh : by default, no real SSH connection will be made from unit tests. Following environment variables can be defined to change behaviour
    • QJS_EXT_LIB_TEST_SSH_REAL_CONNECT : if set to 1, SSH connections will be made to localhost to execute scripts located under test/data (ensure that current user is allowed to SSH to localhost using default SSH key)
    • QJS_EXT_LIB_TEST_SSH_REAL_LOCAL_FORWARD : if set to 1, real local SSH forward will be tested (will be ignored if QJS_EXT_TEST_SSH_REAL_CONNECT != 1)
    • QJS_EXT_LIB_TEST_SSH_REAL_REMOTE_FORWARD : if set to 1, real remote SSH forward will be tested (will be ignored if QJS_EXT_TEST_SSH_REAL_CONNECT != 1)

About

A set of pure JS extensions for QuickJS

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 98.7%
  • Other 1.3%