UNPKG

3.03 kBJavaScriptView Raw
1/*
2 * Copyright 2019 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12const path = require('path');
13const fse = require('fs-extra');
14const dotenv = require('dotenv');
15
16/**
17 * Decoded the params string. First as JSON and if this fails, as ENV format.
18 *
19 * @param {string} params Params string.
20 * @param {string} cwd CWD of to resolve file, assumes that `param` is a file path.
21 * @returns {*} Decoded params object.
22 */
23function decodeParamString(params, cwd = '') {
24 let content = params.trim();
25 if (cwd) {
26 const filename = path.resolve(cwd, content);
27 if (!fse.existsSync(filename)) {
28 throw Error(`Specified param file does not exist: ${path.relative(process.cwd(), filename)}`);
29 }
30 content = fse.readFileSync(filename, 'utf-8').trim();
31 }
32 let data;
33 if (content.startsWith('{')) {
34 data = JSON.parse(content);
35 } else {
36 data = dotenv.parse(content);
37 }
38 return data;
39}
40
41/**
42 * Decodes a file params.
43 * @param {string[]} filenames Filename
44 * @param {string} [cwd=process.cwd()] Current work directory.
45 * @returns {*}
46 */
47function decodeFileParams(filenames, cwd = process.cwd()) {
48 return filenames
49 .reduce((prev, filename) => (Object.assign(prev, decodeParamString(filename, cwd))), {});
50}
51
52/**
53 * Decodes a param array.
54 * @param {string[]} values Param values.
55 * @param {string} name Informational name of the option that is parsed.
56 * @returns {{}|*}
57 */
58function decodeParams(values, name) {
59 if (!values && values.length === 0) {
60 return {};
61 }
62 if (values.length % 2 === 0) {
63 return values.reduce((p, c, i) => {
64 if (i % 2 === 0) {
65 // eslint-disable-next-line no-param-reassign
66 p[c] = values[i + 1];
67 }
68 return p;
69 }, {});
70 } else if (values.length === 1) {
71 return decodeParamString(values[0]);
72 } else {
73 throw new Error(`${name} needs either a JSON string or key-value pairs`);
74 }
75}
76
77module.exports = function commonArgs(yargs, options) {
78 const fileOptions = {
79 ...options,
80 name: `${options.name}-file`,
81 alias: options.alias ? `${options.alias}File` : `${options.name}File`,
82 describe: `${options.describe} (JSON or env file)`,
83 };
84 return yargs
85 .option(options.name, options)
86 .coerce(options.name, (argv) => decodeParams(argv, options.name))
87 .option(fileOptions.name, fileOptions)
88 .coerce(fileOptions.name, (argv) => decodeFileParams.bind(decodeFileParams, argv));
89};
90
91// for testing
92module.exports.decodeFileParams = decodeFileParams;