From de24f273c6548034001898c9b0c83fe96a585044 Mon Sep 17 00:00:00 2001 From: Dan Selman Date: Mon, 20 Mar 2023 20:26:21 +0000 Subject: [PATCH] fix(cli): options parsing Signed-off-by: Dan Selman --- package-lock.json | 9 ++++++ package.json | 3 +- src/index.ts | 28 +++++++++++------ src/modules.d.ts | 3 +- src/ten-generate.ts | 74 +++++++++++++++++++++++++++++++++------------ 5 files changed, 85 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index de954b8..ef784a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@accordproject/markdown-template": "^0.16.6-20230317163634", "@accordproject/markdown-transform": "^0.16.6-20230317163634", "@accordproject/template-engine": "^1.0.8", + "@commander-js/extra-typings": "^10.0.3", "commander": "^10.0.0", "dayjs": "^1.11.7", "figlet": "^1.5.2" @@ -580,6 +581,14 @@ "node": ">=0.1.90" } }, + "node_modules/@commander-js/extra-typings": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-10.0.3.tgz", + "integrity": "sha512-OIw28QV/GlP8k0B5CJTRsl8IyNvd0R8C8rfo54Yz9P388vCNDgdNrFlKxZTGqps+5j6lSw3Ss9JTQwcur1w1oA==", + "peerDependencies": { + "commander": "10.0.x" + } + }, "node_modules/@foliojs-fork/fontkit": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@foliojs-fork/fontkit/-/fontkit-1.9.1.tgz", diff --git a/package.json b/package.json index 661f38a..77f4724 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@accordproject/template-cli", - "version": "1.0.7", + "version": "1.0.8", "description": "Command Line Interface for template engine and data format conversion", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -31,6 +31,7 @@ "@accordproject/markdown-template": "^0.16.6-20230317163634", "@accordproject/markdown-transform": "^0.16.6-20230317163634", "@accordproject/template-engine": "^1.0.8", + "@commander-js/extra-typings": "^10.0.3", "commander": "^10.0.0", "dayjs": "^1.11.7", "figlet": "^1.5.2" diff --git a/src/index.ts b/src/index.ts index a2b9a9e..3473fe6 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,22 +1,30 @@ #!/usr/bin/env node -const { Command } = require("commander"); const figlet = require("figlet"); -import { generateCommand } from "./ten-generate"; - -const program = new Command(); - +import { Argument, program } from '@commander-js/extra-typings'; +import { generateCommandHandler } from './ten-generate'; console.log(figlet.textSync("Template Manager")); program .version('1.0.0') .name('ten') - .command('generate ') + .command('generate') .alias('gen') .description('Generate a document from a template') - .action(generateCommand); + .argument('', 'path to template directory') + .argument('', 'path to JSON data file') + .addArgument(new Argument('', 'output file format').choices(['pdf', 'markdown', 'html'])) + .argument('', 'path to output file') + .option('--libraryFile [value]', 'path to library file') + .option('--now [value]', 'date/time to use for \'now\' (ISO-8601 format)') + .option('--verbose', 'verbose output') + .action(generateCommandHandler); + +async function run() { + await program.parseAsync(); -if (!process.argv.slice(2).length) { - program.outputHelp(); + if (!process.argv.slice(2).length) { + program.outputHelp(); + } } -program.parseAsync(process.argv); \ No newline at end of file +run(); \ No newline at end of file diff --git a/src/modules.d.ts b/src/modules.d.ts index 2d826f0..94ee9e1 100644 --- a/src/modules.d.ts +++ b/src/modules.d.ts @@ -11,4 +11,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -declare module '@accordproject/markdown-template' \ No newline at end of file +declare module '@accordproject/markdown-template' +declare module '@accordproject/markdown-transform' \ No newline at end of file diff --git a/src/ten-generate.ts b/src/ten-generate.ts index 86d9716..ecdd1f9 100644 --- a/src/ten-generate.ts +++ b/src/ten-generate.ts @@ -1,29 +1,63 @@ -import { ModelManager } from "@accordproject/concerto-core"; -import { readFileSync, writeFileSync } from "fs"; +import * as path from 'path'; +import * as fs from 'fs'; +import dayjs from 'dayjs'; -const { TemplateMarkInterpreter } = require('@accordproject/template-engine'); +import { ModelManager } from "@accordproject/concerto-core"; +import { TemplateMarkInterpreter } from '@accordproject/template-engine'; import { TemplateMarkTransformer } from '@accordproject/markdown-template'; -const { transform } = require('@accordproject/markdown-transform'); -const dayjs = require('dayjs'); +import { transform } from '@accordproject/markdown-transform'; + +export async function generateCommandHandler(templateDir: string, dataFile: string, outputFormat: string, outputFile: string, options: { libraryFile?: string | true | undefined; now?: string | true | undefined; verbose?: true | undefined; }) { + + const template = fs.readFileSync(path.join(templateDir, 'template.md'), 'utf-8'); + const data = JSON.parse(fs.readFileSync(dataFile, 'utf-8')); + + const ctoFileNames = fs.readdirSync(templateDir, { withFileTypes: true }) + .filter(item => !item.isDirectory() && item.name.endsWith('.cto')) + .map(item => item.name); -export async function generateCommand(templateFile: string, modelFile: string, dataJson: string, outputFormat: string, outputFile: string) { - const model = readFileSync(modelFile, 'utf-8'); - const template = readFileSync(templateFile, 'utf-8'); - const data = JSON.parse(readFileSync(dataJson, 'utf-8')); const modelManager = new ModelManager({ strict: true }); - modelManager.addCTOModel(model); - const engine = new TemplateMarkInterpreter(modelManager, {}); + ctoFileNames.forEach( ctoFile => { + modelManager.addCTOModel(fs.readFileSync(path.join(templateDir, ctoFile), 'utf-8'), ctoFile, true); + }) + await modelManager.updateExternalModels(); + const clauseLibrary = options.libraryFile ? JSON.parse(fs.readFileSync(options.libraryFile as string, 'utf-8')) : {}; + + if(options.verbose) { + console.log('Library:'); + console.log(clauseLibrary); + } + + const engine = new TemplateMarkInterpreter(modelManager, clauseLibrary); const templateMarkTransformer = new TemplateMarkTransformer(); + const templateMarkDom = templateMarkTransformer.fromMarkdownTemplate({ content: template }, modelManager, 'contract', { verbose: options.verbose }); + + if(options.verbose) { + console.log('TemplateMark DOM:'); + console.log(JSON.stringify(templateMarkDom, null, 2)); + } + + const genNow = options.now ? dayjs(options.now as string) : dayjs(); + + if(options.now ) { + console.log(`Value of 'now' is: ${genNow.toISOString()}` ); + } + + const ciceroMark = await engine.generate(templateMarkDom, data, genNow); + + if(options.verbose) { + console.log('AgreementMark DOM:'); + console.log(JSON.stringify(ciceroMark, null, 2)); + } + + const result = await transform(ciceroMark.toJSON(), 'ciceromark_parsed', [outputFormat], {}, {verbose: options.verbose}); - const templateMarkDom = templateMarkTransformer.fromMarkdownTemplate({ content: template }, modelManager, 'contract', { verbose: false }); + if(options.verbose) { + console.log(`${outputFormat}:`); + console.log(result); + } - //const now = dayjs('2023-03-17T00:00:00.000Z'); - const now = null; - const ciceroMark = await engine.generate(templateMarkDom, data, now); - console.log(typeof ciceroMark); - console.log(JSON.stringify(ciceroMark, null, 2)); - const result = await transform(ciceroMark.toJSON(), 'ciceromark_parsed', [outputFormat], {}, {}); - console.log(JSON.stringify(result, null, 2)); - writeFileSync(outputFile, result); + fs.writeFileSync(outputFile, result); + console.log(`Created ${outputFormat} and saved to file: ${outputFile}`); } \ No newline at end of file