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

scas

v0.0.17

Published

scas - Scaffolding console

Downloads

8

Readme

scas

Scaffolding console. It generates what you want by your templates.

Setup

npm install --global scas

Setup completion (auto complete)

Setup this automatically.

scas --completion-install

And restart your terminal.

If automatically setup does not work please follow steps bellow.

Setup manually

Make completion file.

scas --completion > your/cutom/path/scas.completion.sh

Add this to your bash profile. It depends on platform (OSX, Ubuntu, Linux, etc..)

## ~/.profile or ~/.bash_profile or ~/.bashrc
source your/cutom/path/scas.completion.sh

And restart your terminal.

How to use

Get help

scas

It will show available commands.

Init .scas.js file

scas init

It will generate .scas.js file with instructions.

Make your template

Create file template/class.js with class implementation. Its free form template with {{{ placeholder }}} or {{{ placeholder | pipe }}}

module.exports = class {{{ name | Camel }}} {

    constructor( {{{ name | camel }}} ) {
        this.{{{ name | camel }}} = {{{ name | camel }}};
    }
    
    // ...    
}

Make your action

Open .scas.js and replace or update actions section.


    // ....
    
    actions: {
        class: {
            title: 'Generate class - its your action', // free form title for help
            arguments: ['dir', 'name'], // required arguments
            input: 'template/class.js', // path to template
            out: '{{{ dir }}}/{{{ name | Camel }}}.class.js' // path to generated file
        }
    }
    
    // ....

Generate your code

scas

It should contains your action.

$ scas [actions] <arguments> <options>
  Scaffolding console

    class                        Generate class - its your action
....

Lets make your class

Use [TAB] it helps a lot

scas class dir tmp/example name user

It should generate class to local tmp/example folder.

cat tmp/example/User.class.js
module.exports = class User {

    constructor( user ) {
        this.user = user;
    }

    // ...
}

So thats it.

Multiple actions (batch)

Ok, you have one class but you want to generate module with multiple files.

Lets make batch action in .scas.js file.

Add to actions

        // ...
        module: {
            'title': 'Generate module', // your help line
            arguments: ['dir', 'name'], // required arguments
            batch: [
                'class', // #1 re-used: class action with same arguments - simply, generates class file. 
                { 
                    name: 'class', // #2 re-used class action with mapped arguments, generates module class file.
                    map: {
                        dir: '{{{ dir }}}', 
                        name: '{{{ name }}}Module'
                    }
                }
            ]
        }

Now actions section looks like:

    actions: {
        class: {
            title: 'Generate class - its your action', // free form title for help
            arguments: ['dir', 'name'], // required arguments
            input: 'template/class.js', // path to template
            out: '{{{ dir }}}/{{{ name | Camel }}}.class.js' // path to generated file
        },
        module: {
            'title': 'Generate module', // your help line
            arguments: ['dir', 'name'], // required arguments
            batch: [
                'class',
                {
                    name: 'class',
                    map: {
                        dir: '{{{ dir }}}',
                        name: '{{{ name }}}Module'
                    }
                }
            ]
        }
    }

Run your batch action.

scas

It will show your actions.

$ scas [actions] <arguments> <options>
  Scaffolding console

    class                        Generate class - its your action
    module                       Generate module
...

Lets generate your module.

scas module dir tmp/example name auth

Your will see output like this.

scas module dir tmp/example name auth
class                    
    input                        template/class.js
    out                          tmp/example/Auth.class.js
    content                      module.exports = class Auth { constructor( auth ) { this.aut...
class                    
    input                        template/class.js
    out                          tmp/example/AuthModule.class.js
    content                      module.exports = class AuthModule { constructor( authModule ...

API

.scas.js has easy structure. It contains next fields.

  • title - text presentation
  • description - text overview
  • actions - actions set
  • imports - array of imports with pathes to other .scas.js
  • pipes - custom set of functions to modify your arguments {{{ name | myCustomPipe }}}

Now .scas.js looks like:

module.exports = {
    title: '$ scas [actions] <arguments> <options>', // you can rewrite this for you goals
    description: 'Scaffolding console', // you can rewrite this for you goals
    
    // import other scas files or packages.
    imports: [
        // it needs to support default help
        { path: 'scas/.scas' }
    ],
    actions: {
        class: {
            title: 'Generate class - its your action', // free form title for help
            description: 'Some hint', // you can rewrite this for you goals
            help: 'More info about your action', // you can rewrite this for you goals            
            arguments: ['dir', 'name'], // required arguments
            input: 'template/class.js', // path to template
            out: '{{{ dir }}}/{{{ name | Camel }}}.class.js' // path to generated file
        },
        module: {
            'title': 'Generate module', // your help line
            arguments: ['dir', 'name'], // required arguments
            batch: [
                'class',
                {
                    name: 'class',
                    map: {
                        dir: '{{{ dir }}}',
                        name: '{{{ name }}}Module'
                    }
                }
            ]
        }
    },
    pipes: {
        myCustomPipe: (context) => (input) => 'my-pipe-changes' + input
    }

}
presentation fields

title and description are fields to present info about your scaffolding.

actions

Simple action

    actions: {
        myActionName: {
            title: 'Generate class - its your action', // free form title for help
            description: 'Some hint', // you can rewrite this for you goals, is not required
            help: 'More info about your action', // you can rewrite this for you goals, is not required            
            arguments: ['myDir', 'className'], // required arguments, is not required
            input: 'template/class.js', // path to template, required
            out: '{{{ myDir }}}/{{{ className | Camel }}}.class.js' // path to generated file, required
        }
   }        

Batch action

        // action section here ...
        myModuleName: {
            'title': 'Generate my module', // your help line
            arguments: ['moduleDir', 'moduleName'], // required arguments
            
            batch: [
                'myActionName', 
                'myOtherAction',
                {
                    // my custom action
                    name: 'myAction',

                    // myAction action requires arguments dir and name, just remap this.
                    map: {
                        dir: '{{{ moduleDir }}}',
                        name: '{{{ moduleName }}}Module'
                    }
                }
            ]
        }
imports

Imports section loads any other actions from any file like .scas.js or from any *.js or npm packages.

Now it loads only default help and init form scas npm package.

    imports: [
        // it needs to support default help
        { path: 'scas/.scas' }
    ]

Lets add yours. Make your own template/myRules.js

module.exports = {
    title: 'extended action',

    actions: {
        component: {
            title: 'Angular component',
            arguments: ['dir', 'name'],
            input: 'ngComponent.ts',
            out: '{{{ dir }}}/{{{ name | kebab }}}.component.ts'
        }
    }
}

It requires: ngComponent.ts Lets make it. template/ngComponent.ts

import {Component} from "@angular/core";

@Component({
    selector: '{{{ name | kebab }}}',
    template: `Hi {{{ name }}}`
})
export class {{{ name | Camel }}}Component {
    constructor() {

    }
}

Lets import this to main .scas.js

    imports: [
        { path: 'scas/.scas' },
        { path: 'template/myRules', as: 'angular' }
    ]

Run this

scas angular component dir tmp/ng name userDetails

Output

component                
    input                        ngComponent.ts
    out                          tmp/ng/user-details.component.ts
    content                      import {Component} from "@angular/core"; @Component({ select...

Result

cat tmp/ng/user-details.component.ts
import {Component} from "@angular/core";

@Component({
    selector: 'user-details',
    template: `Hi userDetails`
})
export class UserDetailsComponent {
    constructor() {

    }
}

You can import same rule to main namespace.

    imports: [
        { path: 'scas/.scas' },
        { path: 'template/myRules' }
    ]

It will be same:

scas component dir tmp/ng name userDetails
component                
    input                        ngComponent.ts
    out                          tmp/ng/user-details.component.ts
    content                      import {Component} from "@angular/core"; @Component({ select...
pipes

Pipes its awesome :)

Available pipes by default:

module.exports = {
    camel: (context) => (input) => _.camelCase(input),
    Camel: (context) => (input) => _.upperFirst(_.camelCase(input)),

    kebab: (context) => (input) => _.kebabCase(input),
    Kebab: (context) => (input) => _.upperFirst(_.kebabCase(input)),

    snake: (context) => (input) => _.snakeCase(input),
    Snake: (context) => (input) => _.upperFirst(_.snakeCase(input)),

    lower: (context) => (input) => _.toLower(input),
    upper: (context) => (input) => _.toUpper(input),

    toUpper: (context) => (input) => _.toUpper(input),
    toLower: (context) => (input) => _.toLower(input),

    camelCase: (context) => (input) => _.camelCase(input),
    kebabCase: (context) => (input) => _.kebabCase(input),
    snakeCase: (context) => (input) => _.snakeCase(input),
    startCase: (context) => (input) => _.startCase(input),

    lowerCase: (context) => (input) => _.lowerCase(input),
    upperCase: (context) => (input) => _.upperCase(input),

    lowerFirst: (context) => (input) => _.lowerFirst(input),
    upperFirst: (context) => (input) => _.upperFirst(input),

    capitalize: (context) => (input) => _.capitalize(input),
    trim: (context) => (input) => _.trim(input),

    trimStart: (context) => (input) => _.trimStart(input),
    trimEnd: (context) => (input) => _.trimEnd(input),

    plural: (context) => (input) => pluralize.plural(input),
    Plural: (context) => (input) => _.upperFirst(pluralize.plural(input)),

    singular: (context) => (input) => pluralize.singular(input),
    Singular: (context) => (input) => _.upperFirst(pluralize.singular(input)),

    toArray: (context) => (text) => _.snakeCase(text).split('_'),
    toString: (context) => (array) => _.isArray(array) ? array.join('_') : '' + array,

    first: (context) => (array) => _.first(array),
    last: (context) => (array) => _.last(array),

    slice: (context) => (input, start, end) => _.slice(input, start, end),
    join: (context) => (input, separator) => _.join(input, separator || ''),
}

Or you can make your custom pipes and declare in the pipe section.

    pipes: {
        myCustomPipe: (context) => (input) => 'my-pipe-changes' + input
    }

Have a fun +1G Team