1.0.3 • Published 7 years ago

architected v1.0.3

Weekly downloads
3
License
MIT
Repository
github
Last release
7 years ago

Architected Codestyle fyi Build Status Build status

A tool for cli utilities.

About

Architected is a small wrapper around inquirer, listr and argi. It seamlessly manages arguments, user input and tasks.

Install

$ npm install --save architected

Usage

const architected = require('architected');

const config = {
  // Configuration for architected
  config: {
    name: 'my cli app'
  },
  // The user input you want to receive.
  input: {
    name: {
      message: 'A short description',
      default: 'My default',
      type: 'input'
    }
  },
  // Cli commands
  commands: {
    name: {
      message: 'A short description',
      hidden: false
    }
  }
}

architected(config).then((result) => {
  const { run, add } = result;

  // Add a task
  add('my first task', (ctx, task) => {
    // Do the things
  });

  add('my second task', (ctx, task) => {
    // Do other tings
  });

  // Run tasks
  run().catch((err) => {
    console.error(err);
  });
}).catch((err) => {
  console.error(err);
})

API

architected(config)

config

Configuration for architected.

name

Type: string

Required

The name of your project(will be used for --help).

args

Type: array

Default: process.argv.slice(2)

Custom arguments. You should only change this if you have to.

commands

Commands passed as arguments.

Example:

Terminal:

my-app init

Code:

const architected = require('architected');

const config = {
  config: {
    name: 'my app'
  },
  commands: {
    init: {
      message: 'Add readme.md file'
    }
  }
}

architected(config).then((result) => {
  const { run, add, ctx } = result;

  // User called init
  if (ctx.init) {
    add('init stuff', (ctx, task) => {

    });
  }

  run()
})

input

Input you want to receive.

name

Type: object

What the user input should be called. You need this to get the value of the user input.

  • message Type: sting A short description. It will be displayed in --help and in the input prompt.

  • default Type: every Will be used if the user does not specify a value.

  • save Type: boolean If set to true the user input will be saved and will be suggested next time the user executes your cli utility.

  • boolean Type: boolean Force input to be either true or false. Only for arguments.

  • alias Type: string, array Alternative name(eg. a short version). Only for arguments.

  • hidden Type: boolean Specify if the input should be displayed in --help. Only for arguments.

  • type Type: string Type of the user input, can be input, confirm, list, rawlist, expand, checkbox, password, editor. Only for prompt. Learn more

  • choices Type: array, function Choices for the user can only be used for certain types. Only for prompt. Learn more

  • validate Type: function Receives user input as the first argument. Should return true if input is valid or false if input is invalid. Only for prompt.

  • filter Type: function Receives user input as the first argument. Should return the filtered value. Only for prompt.

  • when Type: function Receives the previous user input as the first argument. Should return true if the prompt can be displayed. Only for prompt.

  • pageSize Type: number The number of lines that will be rendered. Can only be used for list, rawList, expand or checkbox. Only for prompt.

Returns

Type: promise

Will be called when all the user input is received and parsed.

ctx

Type: object

An object containing the user input.

Example:

...
	console.log(ctx.name);
	// Logs name input to the console.
...

add(name, options, task)

Add a new task

Example:

...
  add('my-task', (ctx, task) => {
    // ctx = up to date user input
    // `task` can be used to control the task
    if (ctx.input === 'skip') {
      task.skip('reason');
    }

    ctx.enableOther = true;
  });

  add('my-task-2', { }, (ctx, task) => {
    if (ctx.input === 'skip') {
      task.skip('reason');
    }
  });
...
name

Type: string

The name of your task. Will be used for logging.

options

Type: object

Options for listr. Learn more

task

Type: function

You should do your stuff here.

Learn more

run(ctx)

Execute all tasks.

ctx

Type: object

Custom context. Will be Object.assigned to the user input.

Examples

Basic

A simple package.json generator.

#!/usr/bin/env node

const { writeFileSync, mkdirSync } = require('fs');
const { join } = require('path');

const architected = require('architected');

architected({
  config: {
    name: 'basic-example'
  },
  input: {
    path: {
      message: 'Where your project should be',
      default: process.cwd(),
      forceCli: true
    },
    name: {
      message: 'Whats the name',
      type: 'input',
      forceInput: true
    },
    description: {
      message: 'Whats your project about',
      type: 'input'
    }
  }
}).then((result) => {
  const { run, add } = result;

  add('generate package.json', (ctx, task) => {
    ctx.pkg = `{
  "name": "${ ctx.name }",
  "description": "${ ctx.description }",
  "version": "0.0.0",
  "license": "MIT"
}`
  });

  add('create project directory', (ctx, task) => {
    ctx.created = true;

    try {
      mkdirSync(join(ctx.path, ctx.name));
    } catch (err) {
      ctx.created = false;
      throw new Error(`Could not create project dir\n${ err }`);
    }
  });

  add('write package.json', { enabled: (ctx) => ctx.created }, (ctx, task) => {
    try {
      writeFileSync(join(ctx.path, ctx.name, 'package.json'), ctx.pkg);
    } catch (err) {
      throw new Error(`Could not create package.json\n${ err }`);
    }
  });

  run().catch((err) => {
    console.error(err);
  })
}).catch((err) => {
  console.error(err);
});

Observable

A simple node.js project boilerplate. Built using observables.

#!/usr/bin/env node

const { writeFileSync, mkdirSync } = require('fs');
const { join } = require('path');

const Observable = require('zen-observable');
const delay = require('delay'); // For a cool effect

const architected = require('architected');

architected({
  config: {
    name: 'observable-example'
  },
  input: {
    path: {
      message: 'Where your project should be',
      default: process.cwd(),
      forceCli: true
    },
    name: {
      message: 'Whats the name',
      type: 'input',
      forceInput: true
    },
    description: {
      message: 'Whats your project about',
      type: 'input'
    },
    cli: {
      message: 'Do you need a cli',
      type: 'confirm',
      default: false,
      boolean: true
    }
  }
}).then((result) => {
  const { run, add } = result;

  add('generate files', (ctx, task) => (
    new Observable(observer => {
      delay(100)
        .then(() => {
          observer.next('Generating package.json');

          ctx.pkg = `{
  "name": "${ ctx.name }",
  "description": "${ ctx.description }",
  "version": "0.0.0",
  "license": "MIT"${ ctx.cli ? ',\n  "bin": "./cli.js"' : '' }
}`;

          return delay(300);
        }).then(() => {
          observer.next('Generating index.js');

          ctx.i = `module.exports = () => {
  return {
    name: '${ ctx.name }'
  }
};`;

          return delay(300);
        }).then(() => {
          if (ctx.cli) {
            observer.next('Generating cli.js');

            ctx.clijs = `const ${ ctx.name } = require('./');

${ ctx.name }();`;
          }

          observer.complete();
        });
    })
  ));

  add('create project directory', (ctx, task) => {
    ctx.created = true;

    mkdirSync(join(ctx.path, ctx.name));
    try {
    } catch (err) {
      ctx.created = false;
      throw new Error(`Could not create project dir\n${ err }`);
    }
  });

  add('write files', { enabled: (ctx) => ctx.created }, (ctx, task) => (
    new Observable(observer => {
      delay(0)
        .then(() => {
          observer.next('Write package.json');
          writeFileSync(join(ctx.path, ctx.name, 'package.json'), ctx.pkg);

          return delay(300);
        }).then(() => {
          observer.next('Write index.js');
          writeFileSync(join(ctx.path, ctx.name, 'index.js'), ctx.i);

          return delay(300);
        }).then(() => {
          if (ctx.cli) {
            observer.next('Write cli.js');
            writeFileSync(join(ctx.path, ctx.name, 'cli.js'), ctx.clijs);
          }

          observer.complete();
        });
    })
  ));

  run().catch((err) => {
    console.error(err);
  })
}).catch((err) => {
  console.error(err);
});

License

MIT © Tobias Herber