UNPKG

zapier-platform-cli

Version:

The CLI for apps in the Zapier Developer Platform.

115 lines (101 loc) 5.29 kB
'use strict'; var path = require('path'); var _ = require('lodash'); var colors = require('colors'); var utils = require('../utils'); var scaffold = function scaffold(context, type, name) { if (!name) { context.line('Missing arguments. Please see `zaper help scaffold`.'); return Promise.resolve(); } var templateContext = { CAMEL: utils.camelCase(name), KEY: utils.snakeCase(name), NOUN: _.capitalize(name), LOWER_NOUN: name.toLowerCase(), INPUT_FIELDS: '' }; // what is the `resources: {}` app definition point? var typeMap = { resource: 'resources', trigger: 'triggers', search: 'searches', create: 'creates' }; // where will we create/required the new file? var destMap = { resource: 'resources/' + templateContext.KEY, trigger: 'triggers/' + templateContext.KEY, search: 'searches/' + templateContext.KEY, create: 'creates/' + templateContext.KEY }; if (!typeMap[type]) { context.line('Scaffold type "' + type + '" not found! Please see `zaper help scaffold`.'); return Promise.resolve(); } var templateFile = path.join(__dirname, '../../scaffold/' + type + '.template.js'); var dest = global.argOpts.dest || destMap[type]; var destFile = path.join(process.cwd(), dest + '.js'); var entry = global.argOpts.entry || 'index.js'; var entryFile = path.join(process.cwd(), entry); context.line('Adding ' + type + ' scaffold to your project.\n'); return utils.readFile(templateFile).then(function (templateBuf) { return templateBuf.toString(); }).then(function (template) { return _.template(template, { interpolate: /<%=([\s\S]+?)%>/g })(templateContext); }).then(function (rendered) { utils.printStarting('Writing new ' + dest + '.js'); return utils.ensureDir(path.dirname(destFile)).then(function () { return utils.writeFile(destFile, rendered); }); }).then(function () { return utils.printDone(); }).then(function () { return utils.readFile(entryFile); }).then(function (entryBuf) { return entryBuf.toString(); }).then(function (entryJs) { utils.printStarting('Rewriting your ' + entry); var lines = entryJs.split('\n'); // this is very dumb and will definitely break, it inserts lines of code // we should look at jscodeshift or friends to do this instead // insert Resource = require() line at top var varName = '' + templateContext.CAMEL + utils.camelCase(type); var importerLine = 'const ' + varName + ' = require(\'./' + dest + '\');'; lines.splice(0, 0, importerLine); // insert '[Resource.key]: Resource,' after 'resources:' line var injectAfter = typeMap[type] + ': {'; var injectorLine = '[' + varName + '.key]: ' + varName + ','; var linesDefIndex = _.findIndex(lines, function (line) { return _.endsWith(line, injectAfter); }); if (linesDefIndex === -1) { utils.printDone(false); context.line(); context.line(colors.bold('Oops, we could not reliably rewrite your ' + entry + '.') + ' Please add:'); context.line(' * `' + importerLine + '` to the top'); context.line(' * `' + injectAfter + ' ' + injectorLine + ' },` in your app definition'); return Promise.resolve(); } else { lines.splice(linesDefIndex + 1, 0, ' ' + injectorLine); return utils.writeFile(entryFile, lines.join('\n')).then(function () { return utils.printDone(); }); } }).then(function () { return context.line('\nFinished! We did the best we could, you might gut check your files though.'); }); }; scaffold.argsSpec = [{ name: 'type', help: 'what type of thing are you creating', required: true, choices: [ // 'index', // 'oauth2', 'resource', 'trigger', 'search', 'create'] }, { name: 'name', help: 'the name of the new thing to create', required: true, example: 'Some Name' }]; scaffold.argOptsSpec = { dest: { help: 'sets the new file\'s path', default: '{type}s/{name}' }, entry: { help: 'where to import the new file', default: 'index.js' } }; scaffold.help = 'Adds a starting resource, trigger, action or search to your app.'; scaffold.usage = 'zapier scaffold {resource|trigger|search|create} "Name"'; scaffold.example = 'zapier scaffold resource "Contact"'; scaffold.docs = '\nThe scaffold command does two general things:\n\n* Creates a new destination file like `resources/contact.js`\n* (Attempts to) import and register it inside your entry `index.js`\n\nYou can mix and match several options to customize the created scaffold for your project.\n\n> Note, we may fail to rewrite your `index.js` so you may need to handle the require and registration yourself.\n\n**Arguments**\n\n' + utils.argsFragment(scaffold.argsSpec) + '\n' + utils.argOptsFragment(scaffold.argOptsSpec) + '\n\n' + '```' + 'bash\n$ ' + scaffold.example + '\n$ zapier scaffold resource "Contact" --entry=index.js\n$ zapier scaffold resource "Contag Tag" --dest=resources/tag\n$ zapier scaffold resource "Tag" --entry=index.js --dest=resources/tag\n# Adding resource scaffold to your project.\n#\n# Writing new resources/tag.js - done!\n# Rewriting your index.js - done!\n#\n# Finished! We did the best we could, you might gut check your files though.\n' + '```' + '\n'; module.exports = scaffold;