UNPKG

@litexa/core

Version:

Litexa, a programming language for writing Alexa skills

396 lines (358 loc) 15.1 kB
### # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ### program = require 'commander' chalk = require 'chalk' path = require 'path' validator = require './optionsValidator' GenerateCommandDirector = require './generateCommandDirector' isp = require './isp' localization = require './localization' projectClean = require './project-clean' packageVersion = require('../../package.json').version module.exports.run = -> root = process.cwd() program .version packageVersion .option '--no-color', 'disables print output coloring' .option '-r, --region [region]', 'execution region, e.g. en-US or de-DE', 'en-US' .option '-v, --verbose', 'verbose output' program .command 'model' .description "compiles a project's language model and prints it to the console." .option '-d --deployment [deployment]', "which deployment to run, using the name from the deployments map in the Litexa configuration file.", 'development' .action (cmd) -> chalk.enabled = cmd.parent.color options = root: root type: 'model' deployment: cmd.deployment region: cmd.parent.region require('./printers.coffee').run options program .command 'handler' .description "compiles a project's JavaScript handler and prints it to the console." .option '-d --deployment [deployment]', "which deployment to run, using the name from the deployments map in the Litexa configuration file.", 'development' .action (cmd) -> chalk.enabled = cmd.parent.color options = root: root deployment: cmd.deployment type: 'handler' require('./printers.coffee').run options program .command 'path [directory]' .description "prints the location of named paths within the current project." .option '-t --type [type]', "which path: root, litexa, or assets.", 'root' .option '-l --language [language]', "which language. Leave blank for the default language", 'default' .action (directory, cmd) -> errors = validator( cmd [ { name: 'type' valid: [ 'root' 'litexa' 'assets' ] message: 'invalid "type" option. valid type options are: root, litexa, or assets.' } ] ) errors.forEach (error) -> console.log chalk.red(error.message) directory = directory ? process.cwd() config = await require('./project-config.coffee').identifyConfigFileFromPath directory if config? root = path.dirname config if cmd.language == 'default' switch cmd.type when 'root' console.log root when 'litexa' console.log path.join root, 'litexa' when 'assets' console.log path.join root, 'litexa', 'assets' else console.error chalk.red("unknown path type #{cmd.type}") else switch cmd.type when 'root' console.log root when 'litexa' console.log path.join root, 'litexa', 'languages', cmd.language when 'assets' console.log path.join root, 'litexa', 'languages', cmd.language, 'assets' else console.error chalk.red("unknown path type #{cmd.type}") else console.error chalk.red("#{directory} does not appear to be in a litexa project") program .command 'deploy' .description "executes a deployment extension to push a skill project to the internet" .option '-d --deployment [deployment]', "which deployment to run, using the name from the deployments map in the Litexa configuration file.", 'development' .option '-t --type [type]', "what to deploy: all, assets, lambda, model or manifest.", 'all' .option '-w, --watch', "watch for file changes, then rerun deployment" .option '--no-cache', "disables local caching, used when the state of deployment is unknown and needs to be thoroughly verified" .action (cmd) -> errors = validator( cmd [ { name: 'type' valid: [ 'all' 'assets' 'lambda' 'model' 'manifest' ] message: 'valid type options are [all, assets, lambda, model manifest].' } ] ) errors.forEach (error) -> console.log chalk.red("unknown option value #{error.name} \"#{cmd[error.name]}\" : #{error.message}") process.exit(1) if errors.length > 0 chalk.enabled = cmd.parent.color options = root: root deployment: cmd.deployment type: cmd.type watch: cmd.watch verbose: cmd.parent.verbose cache: cmd.cache coreVersion: packageVersion await require('./deploy.coffee').run options program .command 'test [filter]' .description "executes a project's tests and prints the output to the console." .option '-d --deployment [deployment]', "which deployment to run, using the name from the deployments map in the Litexa configuration file.", 'development' .option '--no-strict', 'disable strict testing' .option '--device [device]', 'which device to emulate (dot, echo, show)', 'show' .option '--log-raw-data [logRawData]', 'dumps all raw requests, responses, and DB contents in .test/output.json' .option '-w, --watch', "watch for file changes, then rerun tests" .action (filter, cmd) -> errors = validator( cmd [ { name: 'device' valid: [ 'dot' 'show' 'echo' ] message: 'ignoring invalid device. valid device options are: dot, echo, show. defaulting to "show"' } ] true ) errors.forEach (error) -> if error.name == 'device' cmd.type = 'show' console.log(chalk.yellow error.message) chalk.enabled = cmd.parent.color options = root: root filter: filter deployment: cmd.deployment strict: cmd.strict region: cmd.parent.region watch: cmd.watch device: cmd.device logRawData: cmd.logRawData require('./test.coffee').run options program .command 'generate [dir]' .alias 'init' .description "creates any missing required files for a litexa project." .option '-c, --config-language [configLanguage]', 'language of the generated configuration file, can be javascript, json, typescript, or coffee' .option '-s, --source-language [sourceLanguage]', 'language of the generated source code, can be javascript, typescript, or coffee' .option '-b, --bundling-strategy [bundlingStrategy]', 'the structure of the code layout as it pertains to litexa, can be webpack, npm-link, or none' .action (dir, cmd) -> errors = validator( cmd [ { name: 'configLanguage' valid: [ 'javascript' 'json' 'typescript' 'coffee' ] message: 'valid config languages are [javascript, json, typescript, coffee].' } { name: 'sourceLanguage' valid: [ 'javascript' 'typescript' 'coffee' ] message: 'valid source languages are [javascript, typescript, coffee].' } { name: 'bundlingStrategy' valid: [ 'none' 'npm-link' 'webpack' ] message: 'valid bundling strategies are [none, npm-link, webpack].' } ] ) errors.forEach (error) -> console.log chalk.red("unknown option value #{error.name} \"#{cmd[error.name]}\" : #{error.message}") process.exit(1) if errors.length > 0 guided = new GenerateCommandDirector({ targetDirectory: dir selectedOptions: cmd availableOptions: [ 'configLanguage' 'sourceLanguage' 'bundlingStrategy' ] }) selections = await guided.direct() chalk.enabled = cmd.parent.color options = root: root dir: path.join(root, selections.dir || '.') configLanguage: selections.configLanguage ? 'javascript' sourceLanguage: selections.sourceLanguage ? 'javascript' bundlingStrategy: selections.bundlingStrategy ? 'none' require('./generate.coffee').run options program .command 'logs' .description "retrieves runtime logs from a deployed skill." .option '-d --deployment [deployment]', "which deployment to pull logs from, using the name from the deployments map in the Litexa configuration file.", 'development' .action (cmd) -> chalk.enabled = cmd.parent.color options = root: root deployment: cmd.deployment region: cmd.parent.region require('./logs.coffee').run options program .command 'info' .description "prints out a litexa project's information block." .action (cmd) -> chalk.enabled = cmd.parent.color options = root: root region: cmd.parent.region try config = await (require('./project-config').loadConfig root) info = new (require('./project-info'))({jsonConfig: config}) console.log JSON.stringify info, null, 2 catch err console.error err program .command 'pull [data]' .description "downloads specified data from the hosted skill via SMAPI. Currently supported for: isp (downloads remote in-skill products, and ovewrites local product files)" .option '-d --deployment [deployment]', "which deployment target to download specified data from, using the name from the deployments map in the Litexa configuration file.", 'development' .option '-s --stage [stage]', "stage for which to pull skill data (either development or live)", 'development' .action (data, cmd) -> options = root: root deployment: cmd.deployment stage: cmd.stage verbose: cmd.parent.verbose switch data when 'isp' try await isp.init options await isp.pullAndStoreRemoteProducts() catch err console.error chalk.red("failed to pull in-skill products") else console.error chalk.red("unknown data type '#{data}'. Currently supported data: isp") program .command 'push [data]' .description "pushes specified data from local to the hosted skill via SMAPI. Currently supports: isp (uploads local in-skill product files, and overrides remote products)" .option '-d --deployment [deployment]', "which deployment target to push specified data to, using the name from the deployments map in the Litexa configuration file.", 'development' .option '-s --stage [stage]', "stage for which to push skill data (either development or live)", 'development' .action (data, cmd) -> options = root: root deployment: cmd.deployment stage: cmd.stage verbose: cmd.parent.verbose switch data when 'isp' try await isp.init options await isp.pushLocalProducts() catch err console.error chalk.red("failed to push in-skill products") else console.error chalk.red("unknown data type '#{data}'. Currently supported data: isp") program .command 'reset [data]' .description "resets specified data from local to the hosted skill via SMAPI. Currently supports: isp (resets all in-skill products for testing)" .option '-d --deployment [deployment]', "which deployment target to reset specified data for, using the name from the deployments map in the Litexa configuration file.", 'development' .option '-s --stage [stage]', "stage for which to reset skill data (either development or live)", 'development' .action (data, cmd) -> options = root: root deployment: cmd.deployment stage: cmd.stage verbose: cmd.parent.verbose switch data when 'isp' try await isp.init options await isp.resetRemoteProductEntitlements() catch err console.error chalk.red("failed to reset in-skill product entitlements") else console.error chalk.red("unknown data type '#{data}'. Currently supported data: isp") program .command 'localize' .description "parses intents/utterances, and any say/reprompt speech from the default Litexa code files. Updates existing localization.json or creates new file in the Litexa project's root directory." .option '--clone-from [language]', 'specify source language for a cloning operation' .option '--clone-to [language]', 'copy all translations from the language specified by --clone-from to this language' .option '--disable-sort-languages', 'disables sorting languages in localization.json alphabetically' .option '--disable-sort-utterances', 'disables sorting utterances in localization.json alphabetically' .option '--remove-orphaned-utterances', 'remove all localization utterances that are no longer in the skill' .option '--remove-orphaned-speech', 'remove all speech lines that are no longer in the skill' # @TODO: Add options to support creating translation placeholders for languages, and warn about missing translations. # .option '--find-missing-translations [missingLanguage]', 'check for missing strings for a specific language' # .option '--create-localization-excel', 'generate Excel file from contents of localization.json' # .option '--parse-localization-excel [file path]', 'parse translations from indicated Excel file back into localization.json' .action (cmd) -> options = { root: root cloneFrom: cmd.cloneFrom cloneTo: cmd.cloneTo disableSortLanguages: cmd.disableSortLanguages disableSortUtterances: cmd.disableSortUtterances removeOrphanedUtterances: cmd.removeOrphanedUtterances removeOrphanedSpeech: cmd.removeOrphanedSpeech verbose: cmd.parent.verbose } localization.localizeSkill(options) program.on 'command:*', -> console.error """Invalid command: #{program.args.join(' ')} See --help for a list of available commands.""" process.exit 1 program.on '--help', -> console.log "" console.log " For help on each command, pass --help to each, e.g. litexa test --help" console.log "" unless process.argv.slice(2).length program.outputHelp() await projectClean.run({root}) program.parse process.argv