1 | /*
|
2 | * Licensed under the Apache License, Version 2.0 (the "License");
|
3 | * you may not use this file except in compliance with the License.
|
4 | * You may obtain a copy of the License at
|
5 | *
|
6 | * http://www.apache.org/licenses/LICENSE-2.0
|
7 | *
|
8 | * Unless required by applicable law or agreed to in writing, software
|
9 | * distributed under the License is distributed on an "AS IS" BASIS,
|
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11 | * See the License for the specific language governing permissions and
|
12 | * limitations under the License.
|
13 | */
|
14 |
|
15 | ;
|
16 |
|
17 | const fs = require('fs');
|
18 | const logger = require('@accordproject/concerto-core').Logger;
|
19 | const formatDescriptor = require('@accordproject/markdown-transform').formatDescriptor;
|
20 | const transform = require('@accordproject/markdown-transform').transform;
|
21 |
|
22 | /**
|
23 | * Utility class that implements the commands exposed by the CLI.
|
24 | * @class
|
25 | */
|
26 | class Commands {
|
27 | /**
|
28 | * Load an input file
|
29 | * @param {string} filePath the file name
|
30 | * @param {string} format the format
|
31 | * @returns {*} the content of the file
|
32 | */
|
33 | static loadFormatFromFile(filePath,format) {
|
34 | const fileFormat = formatDescriptor(format).fileFormat;
|
35 | if (fileFormat === 'json') {
|
36 | return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
37 | } else if (fileFormat === 'binary') {
|
38 | return fs.readFileSync(filePath);
|
39 | } else {
|
40 | return fs.readFileSync(filePath, 'utf8');
|
41 | }
|
42 | }
|
43 |
|
44 | /**
|
45 | * Prints a format to string
|
46 | * @param {*} input the input
|
47 | * @param {string} format the format
|
48 | * @returns {string} the string representation
|
49 | */
|
50 | static printFormatToString(input,format) {
|
51 | const fileFormat = formatDescriptor(format).fileFormat;
|
52 | if (fileFormat === 'json') {
|
53 | return JSON.stringify(input);
|
54 | } else {
|
55 | return input;
|
56 | }
|
57 | }
|
58 |
|
59 | /**
|
60 | * Prints a format to file
|
61 | * @param {*} input the input
|
62 | * @param {string} format the format
|
63 | * @param {string} filePath the file name
|
64 | */
|
65 | static printFormatToFile(input,format,filePath) {
|
66 | logger.info('Creating file: ' + filePath);
|
67 | fs.writeFileSync(filePath, Commands.printFormatToString(input,format));
|
68 | }
|
69 |
|
70 | /**
|
71 | * Set a default for a file argument
|
72 | *
|
73 | * @param {object} argv the inbound argument values object
|
74 | * @param {string} argName the argument name
|
75 | * @param {string} argDefaultName the argument default name
|
76 | * @param {Function} argDefaultFun how to compute the argument default
|
77 | * @returns {object} a modified argument object
|
78 | */
|
79 | static setDefaultFileArg(argv, argName, argDefaultName, argDefaultFun) {
|
80 | if(!argv[argName]){
|
81 | logger.info(`Loading a default ${argDefaultName} file.`);
|
82 | argv[argName] = argDefaultFun(argv, argDefaultName);
|
83 | }
|
84 |
|
85 | let argExists = true;
|
86 | argExists = fs.existsSync(argv[argName]);
|
87 |
|
88 | if (!argExists){
|
89 | throw new Error(`A ${argDefaultName} file is required. Try the --${argName} flag or create a ${argDefaultName}.`);
|
90 | } else {
|
91 | return argv;
|
92 | }
|
93 | }
|
94 |
|
95 | /**
|
96 | * Set default params before we transform
|
97 | *
|
98 | * @param {object} argv the inbound argument values object
|
99 | * @returns {object} a modfied argument object
|
100 | */
|
101 | static validateTransformArgs(argv) {
|
102 | argv = Commands.setDefaultFileArg(argv, 'input', 'input.md', ((argv, argDefaultName) => { return argDefaultName; }));
|
103 |
|
104 | if(argv.verbose) {
|
105 | logger.info(`transform input ${argv.input} printing intermediate transformations.`);
|
106 | }
|
107 |
|
108 | return argv;
|
109 | }
|
110 |
|
111 | /**
|
112 | * Transform between formats
|
113 | *
|
114 | * @param {string} inputPath to the input file
|
115 | * @param {string} from the source format
|
116 | * @param {string[]} via intermediate formats
|
117 | * @param {string} to the target format
|
118 | * @param {string} outputPath to an output file
|
119 | * @param {object} parameters the transform parameters
|
120 | * @param {object} [options] configuration options
|
121 | * @param {boolean} [options.verbose] verbose output
|
122 | * @param {boolean} [options.roundtrip] roundtrip transform back to source format
|
123 | * @returns {object} Promise to the result of parsing
|
124 | */
|
125 | static async transform(inputPath, from, via, to, outputPath, parameters, options) {
|
126 | const input = Commands.loadFormatFromFile(inputPath, from);
|
127 | parameters.inputFileName = inputPath;
|
128 | if (parameters.template) {
|
129 | parameters.templateFileName = parameters.template;
|
130 | parameters.template = Commands.loadFormatFromFile(parameters.template,'markdown_template');
|
131 | }
|
132 | const pathTo = via.concat([to]);
|
133 | let result = await transform(input, from, pathTo, parameters, options);
|
134 | let finalFormat = to;
|
135 | if (options && options.roundtrip) {
|
136 | const pathFrom = via.reverse().concat([from]);
|
137 | result = await transform(result, to, pathFrom, parameters, options);
|
138 | finalFormat = from;
|
139 | }
|
140 |
|
141 | if (outputPath) { Commands.printFormatToFile(result,finalFormat,outputPath); }
|
142 | return Promise.resolve(Commands.printFormatToString(result,finalFormat));
|
143 | }
|
144 | }
|
145 |
|
146 | module.exports = Commands;
|