factory

Quick and easy template scaffolding for Node

Factory

Quick and easy template scaffolding for Node

npm install factory
var factory = require('factory');
 
var widgetFactory = factory({
    template: 'templates/widget',
    placeholders: [
        {
            name: 'foo',
            type: 'input',
            message: 'Enter a value for foo'
        },
        {
            name: 'bar',
            type: 'input',
            message: 'Enter a value for bar'
        }
    ]
});
 
var options = {
    destination: 'app/widgets',
    overwrite: true,
};
var context = {
    foo: 'baz'
};
 
// Node-style callback interface 
widgetFactory(options, context, function(errorresults) {
    if (error) {
        console.error('Widget creation failed: ' + error);
    } else {
        console.info('Widget created successfully');
    }
});
 
// Promise interface 
widgetFactory(options, context)
    .then(function(results) {
        console.info('Widget created successfully');
    }).catch(function(error) {
        console.error('Widget creation failed: ' + error);
    });

Contents of templates/widget/<%= foo %>.js:

module.exports = function <%= foo %>() {
    console.log('<%= bar %>');
};

Output at app/widgets/baz.js:

module.exports = function baz() {
    console.log('[user-prompted value]');
};
  • Call the factory() function with the following parameters:
    • template: path to the template folder
    • placeholders: (optional) array of inquirer prompts used to gather data for injecting into templates
    • getContext: (optional) function that transforms placeholder values before they are passed to the template
  • You can then call the function that is returned, specifying a destination path and any copy options, and optionally passing in a key/value object containing template placeholder values
  • The user is prompted for the value of any placeholders which were not provided in the placeholder values object
  • The files are copied from the template folder to the destination folder, replacing any placeholders in filenames and file content with the supplied values (using lodash template syntax)

Create a factory from an existing template

Template filenames/contents can use lodash template syntax to specify placeholder values. These are injected into the template when the factory function is invoked.

NameTypeRequiredDefaultDescription
templatestringYesN/APath to the template folder
placeholdersArrayNo[]Array of inquirer prompts used to gather data for injecting into templates
getContextfunctionNonullFunction that transforms placeholder values before they are passed to the template
  • getContext has the following signature:

    NameTypeDescription
    contextobjectKey/value object containing placeholder values, gathered from factory context and template placeholders

    object Key/value object containing transformed context placeholder for use in templates

  • Factory function used to create instances of the template

    The user will be prompted for the value of any placeholders which are not specified in the context object.

    NameTypeRequiredDefaultDescription
    options.destinationstringYesN/ADestination directory for output files
    options.overwritebooleanNofalseWhether to overwrite existing files
    contextobjectNo{}Preset template placeholder values
    callbackfunctionNonullNode-style callback that is invoked when the operation completes/fails

    Promise<Array> Promise, fulfilled with array of copy results:

    [
        {
            "src": "/path/to/src",
            "dest": "/path/to/dest",
            "stats": <Stats>
        },
        {
            "src": "/path/to/src/file.txt",
            "dest": "/path/to/dest/file.txt",
            "stats": <Stats>
        },
        {
            "src": "/path/to/src/subfolder",
            "dest": "/path/to/dest/subfolder",
            "stats": <Stats>
        },
        {
            "src": "/path/to/src/subfolder/nested.txt",
            "dest": "/path/to/dest/subfolder/nested.txt",
            "stats": <Stats>
        }
    ]

The value returned by the generated factory function implements the EventEmitter interface, and emits the following events:

EventHandler signature
factory.events.ERRORfunction(error, ErrorInfo)
factory.events.COMPLETEfunction(Array<CopyOperation>)
factory.events.CREATE_DIRECTORY_STARTfunction(CopyOperation)
factory.events.CREATE_DIRECTORY_ERRORfunction(error, CopyOperation)
factory.events.CREATE_DIRECTORY_COMPLETEfunction(CopyOperation)
factory.events.CREATE_SYMLINK_STARTfunction(CopyOperation)
factory.events.CREATE_SYMLINK_ERRORfunction(error, CopyOperation)
factory.events.CREATE_SYMLINK_COMPLETEfunction(CopyOperation)
factory.events.COPY_FILE_STARTfunction(CopyOperation)
factory.events.COPY_FILE_ERRORfunction(error, CopyOperation)
factory.events.COPY_FILE_COMPLETEfunction(CopyOperation)

...where the types referred to in the handler signature are as follows:

PropertyTypeDescription
srcstringSource path of the file/folder/symlink that failed to copy
deststringDestination path of the file/folder/symlink that failed to copy
PropertyTypeDescription
srcstringSource path of the relevant file/folder/symlink
deststringDestination path of the relevant file/folder/symlink
statsfs.StatsStats for the relevant file/folder/symlink
var factory = require('factory');
 
var widgetFactory = factory({
    template: 'templates/widget'
});
 
var options = {
    destination: 'app/widgets'
};
var context = {};
widgetFactory(options, context)
    .on(factory.events.COPY_FILE_START, function(copyOperation) {
        console.info('Copying file ' + copyOperation.src + '...');
    })
    .on(factory.events.COPY_FILE_COMPLETE, function(copyOperation) {
        console.info('Copied to ' + copyOperation.dest);
    })
    .on(factory.events.ERROR, function(errorcopyOperation) {
        console.error('Unable to copy ' + copyOperation.dest);
    })
    .then(function(results) {
        console.info('Widget created successfully');
    }).catch(function(error) {
        console.error('Widget creation failed: ' + error);
    });