@viewdo/dxp-story-cli
Version:
README.md
225 lines (198 loc) • 8.73 kB
JavaScript
/*
https://github.com/tj/commander.js
*/
const program = require('commander')
const path = require('path')
const env = require('dotenv')
const colors = require('colors')
env.config({ path: path.resolve(process.cwd(), '.env') })
const pkg = require('../package.json')
/* GLOBAL ============================== */
program.version(pkg.version)
let command_success = false
const runCommand = async (cmd, command_name, additional_args, next_command) => {
const flattenOptions = (cmd) => {
let options = cmd.parent
return Object.assign(options, cmd, additional_args)
}
try {
let command = require(`./commands/${command_name}`)
command_success = true
let result = await command(flattenOptions(cmd), next_command)
// chained command detection
if(typeof result == 'string')
await runCommand(cmd, result, additional_args)
else if(typeof result == 'object' && result.length == 2)
await runCommand(cmd, result[0], additional_args, result[1])
else process.exit(result)
} catch (err) {
console.error(err)
process.exit(1)
}
}
/* INIT COMMAND =================================== */
program
.command('init [keys...]').alias('i')
.description('Set up the required configuration files for using the CLI within a folder.')
.option("-v, --verbose", "Verbose logging.")
.option("-n, --namespace <ns>", "Namespace of the platform to use")
.option("-e, --email <email>", "Email address of the current user")
.option("-o, --output <dir>", "Folder for bundled story files, used to sync with the platform")
.action(async (keys, cmd) => {
await runCommand(cmd, 'init', { keys })
})
/* LOGIN COMMAND ================================= */
program
.command('login [email] [keys...]').alias('auth')
.description('Authenticates to the output using email verification code')
.option("-v, --verbose", "Verbose logging.")
.option("-n, --namespace <ns>", "Namespace to use against [local|dev|stage]")
.option("-t, --token <token>", "An existing token to write to the output")
.option("-f, --force", "Force new authentication")
.action(async (email, keys, cmd) => {
await runCommand(cmd, 'login', {email, keys})
})
/* SCAFFOLD COMMAND =============================== */
program
.command('scaffold [keys...]').alias('s')
.description('Creates all the asset files and folders for brand new story')
.option("-v, --verbose", "Verbose logging.")
.option("-k, --key <key>", "Scaffold using this story key")
.option("-x, --explicit", "In this mode, all files are declared in the dxp-config.json file. This mode is meant for shared-asset repositories")
.option("-o, --output <dir>", "Which output holds stories")
.action(async (keys, cmd) => {
await runCommand(cmd, 'scaffold', { keys })
})
/* BUILD COMMAND =============================== */
program
.command('build [keys...]').alias('b')
.description('')
.option("-v, --verbose", "Verbose logging.")
.option("-k, --key <key>", "Build only this story key")
.option("-a, --all", "Build all stories without prompting")
.option("-o, --output <dir>", "Which output holds stories")
.action(async (keys, cmd) => {
await runCommand(cmd, 'build', { keys })
})
/* PULL COMMAND =================================== */
program
.command('pull [keys...]').alias('p')
.description('Pulls down all the associated assets for a given set of story keys')
.option("-v, --verbose", "Verbose logging.")
.option("-n, --namespace <ns>", "Namespace to use against [local|dev|stage]")
.option("-k, --key <key>", "Org key to pull all assets for its stories")
.option("-x, --explicit", "In this mode, all files are declared in the dxp-config.json file. This mode is meant for shared-asset repositories")
.option("-a, --all", "Pull all stories without prompting")
.option("-o, --output <dir>", "Which output holds the assets")
.option("-i, --client_id <id>", "Auth0 Client ID")
.option("-s, --client_secret <id>", "Auth0 Client Secret")
.option("-A, --audience <audience>", "Auth0 audience")
.option("-c, --config_only", "Pull only the org & story config.")
.option("-t, --token", "Auth token")
.action(async (keys, cmd) => {
await runCommand(cmd, 'pull', { keys })
})
/* PUSH COMMAND =================================== */
program
.command('push [keys...]').alias('u')
.description('Pushes all the associated assets to a given story')
.option("-v, --verbose", "Verbose logging.")
.option("-n, --namespace <ns>", "Namespace to use against [local|dev|stage]")
.option("-k, --key <key>", "Org key to push all its stories")
.option("-a, --all", "Push all stories without prompting")
.option("-o, --output <dir>", "Which output holds stories")
.option("-i, --client_id <id>", "Auth0 Client ID")
.option("-s, --client_secret <id>", "Auth0 Client Secret")
.option("-A, --audience <audience>", "Auth0 audience")
.option("-t, --token", "Auth token")
.action(async (keys, cmd) => {
await runCommand(cmd, 'push',{ keys })
})
/* CHECK COMMAND =================================== */
program
.command('check [keys...]').alias('c')
.description('Checks to see what files are different on disc from the platform')
.option("-v, --verbose", "Verbose logging.")
.option("-n, --namespace <ns>", "Namespace to use against [local|dev|stage]")
.option("-k, --key <key>", "Story key to check")
.option("-a, --all", "Checks all stories without prompting")
.option("-o, --output <dir>", "Which output holds stories")
.option("-i, --client_id <id>", "Auth0 Client ID")
.option("-s, --client_secret <id>", "Auth0 Client Secret")
.option("-A, --audience <audience>", "Auth0 audience")
.option("-t, --token", "Auth token")
.action(async (keys, cmd) => {
await runCommand(cmd, 'check', { keys })
})
/* VALIDATE COMMAND =================================== */
program
.command('validate [keys...]').alias('v')
.description('Validate tokens in local files using the configured story')
.option("-v, --verbose", "Verbose logging.")
.option("-n, --namespace <ns>", "Namespace to use against [local|dev|stage]")
.option("-k, --key <key>", "Story key to validate")
.option("-a, --all", "Validates all stories without prompting")
.option("-o, --output <dir>", "Which output holds stories")
.option("-i, --client_id <id>", "Auth0 Client ID")
.option("-s, --client_secret <id>", "Auth0 Client Secret")
.option("-A, --audience <audience>", "Auth0 audience")
.option("-t, --token", "Auth token")
.action(async (keys, cmd) => {
await runCommand(cmd, 'validate', { keys })
})
/* UNPACK COMMAND ===============================
program
.command('unpack [keys...]').alias('un')
.description('Unpacks story json files in the output folder into settings js files in the source to be used with the build command.')
.option("-v, --verbose", "Verbose logging.")
.option("-k, --key <key>", "Unpack only this story key")
.option("-a, --all", "Unpacks all stories without prompting")
.option("-o, --output <dir>", "Which output holds the unpack story")
.action(async (keys, cmd) => {
await runCommand(cmd, 'unpack', { keys })
})
*/
program
.command('json-yaml <file> <output>').alias('to-yaml')
.description('Convert JSON to YAML')
.action(async (file, output, cmd) => {
await runCommand(cmd, 'json-to-yaml', { file, output })
})
program
.command('yaml-json <file> <output>').alias('to-json')
.description('Convert YAML to JSON')
.action(async (file, output, cmd) => {
await runCommand(cmd, 'json-from-yaml', { file, output })
})
program
.command('strip-html <file> <output>').alias('strip')
.description('Strip the HTML from a JSON file, and move them to "./json-html/**.html", leaving a path expression.')
.option("-d, --dir <dir>", "Directory to stash the html files", './json-html')
.action(async (file, output, cmd) => {
await runCommand(cmd, 'json-strip-html', { file, output })
})
program
.command('restore-html <file> <output>').alias('restore')
.description('Return HTML to a JSON from "./json-html/**.html" files, using expressions.')
.action(async (file, output, cmd) => {
await runCommand(cmd, 'json-restore-html', { file, output })
})
/* HELP COMMAND =================================== */
program
.command('help').alias('h')
.action(async (cmd) => {
program.outputHelp()
})
program.parse(process.argv)
if (!command_success) {
program.outputHelp()
process.exit(1)
}
program.on('option:verbose', function () {
process.env.VERBOSE = this.verbose;
});
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason)
});