1 | const commander = require('commander');
|
2 | const { ModelIntrospector } = require('ask-smapi-sdk');
|
3 | const { kebabCase } = require('@src/utils/string-utils');
|
4 | const { CliCustomizationProcessor } = require('@src/commands/smapi/cli-customization-processor');
|
5 | const optionModel = require('@src/commands/option-model.json');
|
6 | const { smapiCommandHandler } = require('@src/commands/smapi/smapi-command-handler');
|
7 | const aliases = require('@src/commands/smapi/customizations/aliases.json');
|
8 | const { apiToCommanderMap } = require('@src/commands/smapi/customizations/parameters-map');
|
9 |
|
10 | const uploadCatalog = require('./appended-commands/upload-catalog');
|
11 | const exportPackage = require('./appended-commands/export-package');
|
12 | const getTask = require('./appended-commands/get-task');
|
13 | const searchTask = require('./appended-commands/search-task');
|
14 |
|
15 |
|
16 | const defaultOptions = [
|
17 | {
|
18 | flags: `-${optionModel.profile.alias}, --profile <profile>`,
|
19 | description: optionModel.profile.description
|
20 | },
|
21 | {
|
22 | flags: '--full-response',
|
23 | description: optionModel['full-response'].description
|
24 | },
|
25 | {
|
26 | flags: '--debug',
|
27 | description: optionModel.debug.description
|
28 | }
|
29 | ];
|
30 | const requiredTemplate = { true: '[REQUIRED]', false: '[OPTIONAL]' };
|
31 | const jsonTemplate = { true: '[JSON]: JSON string or a file. Example: "$(cat {filePath})" '
|
32 | + 'or "file:{filePath}", either absolute or relative path are supported.\n',
|
33 | false: '' };
|
34 |
|
35 | const _makeEnumTemplate = (param) => (param.enum ? `[ENUM]: ${param.enum.join()}.\n` : '');
|
36 | const _makeArrayTemplate = (param) => (param.isArray ? '[MULTIPLE]: Values can be separated by comma.\n' : '');
|
37 |
|
38 | const _makeAlias = (kebabName) => (aliases[kebabName] ? `-${aliases[kebabName]},` : '');
|
39 |
|
40 | const _makeOption = (param) => {
|
41 | const name = apiToCommanderMap.get(param.name) || param.name;
|
42 | const paramName = kebabCase(name);
|
43 | const alias = _makeAlias(paramName);
|
44 | const json = param.json || false;
|
45 | const enumTemplate = _makeEnumTemplate(param);
|
46 | const arrayTemplate = _makeArrayTemplate(param);
|
47 | return {
|
48 | name: `${alias}--${paramName} <${paramName}>`,
|
49 | description:
|
50 | (`${requiredTemplate[param.required]} ${(param.description || '').trim()} \n`
|
51 | + `${arrayTemplate}`
|
52 | + `${jsonTemplate[json]}`
|
53 | + `${enumTemplate} `).trim()
|
54 | };
|
55 | };
|
56 |
|
57 |
|
58 |
|
59 | const makeSmapiCommander = () => {
|
60 | const customizationProcessor = new CliCustomizationProcessor();
|
61 | const modelIntrospector = new ModelIntrospector(null, customizationProcessor);
|
62 | const operations = modelIntrospector.getOperations();
|
63 |
|
64 | const program = new commander.Command();
|
65 |
|
66 | let commanderInstance;
|
67 |
|
68 | operations.forEach((operation, commandName) => {
|
69 | const commanderToApiCustomizationMap = new Map();
|
70 | const { apiOperationName, description } = operation;
|
71 | commanderInstance = program
|
72 | .command(commandName)
|
73 | .description(description)
|
74 | .storeOptionsAsProperties(false);
|
75 | const { flatParamsMap } = operation.customizationMetadata;
|
76 | flatParamsMap.forEach(param => {
|
77 | const customizationValue = apiToCommanderMap.get(param.name);
|
78 | if (customizationValue) {
|
79 | commanderToApiCustomizationMap.set(customizationValue, param.name);
|
80 | }
|
81 | const option = _makeOption(param);
|
82 | if (param.required) {
|
83 | commanderInstance.requiredOption(option.name, option.description);
|
84 | } else {
|
85 | commanderInstance.option(option.name, option.description);
|
86 | }
|
87 | });
|
88 |
|
89 | defaultOptions.forEach(option => {
|
90 | commanderInstance.option(option.flags, option.description);
|
91 | });
|
92 | commanderInstance.action((inputCmdObj) => smapiCommandHandler(
|
93 | apiOperationName,
|
94 | flatParamsMap,
|
95 | commanderToApiCustomizationMap,
|
96 | inputCmdObj,
|
97 | modelIntrospector
|
98 | ));
|
99 | });
|
100 |
|
101 |
|
102 | uploadCatalog.createCommand(program);
|
103 | exportPackage.createCommand(program);
|
104 | getTask.createCommand(program);
|
105 | searchTask.createCommand(program);
|
106 |
|
107 | program._name = 'ask smapi';
|
108 | program
|
109 | .description('The smapi command provides a number of sub-commands that '
|
110 | + 'enable you to manage Alexa skills associated with your developer account.');
|
111 |
|
112 | program.on('command:*', () => {
|
113 | console.error(`Command not recognized. Please run "${program._name}" to check the user instructions.`);
|
114 | process.exit(1);
|
115 | });
|
116 |
|
117 | return program;
|
118 | };
|
119 |
|
120 | module.exports = { makeSmapiCommander };
|