-
Notifications
You must be signed in to change notification settings - Fork 128
/
cs.ts
96 lines (80 loc) · 3.37 KB
/
cs.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*!
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import {CLIError, Command, flags} from '@microsoft/bf-cli-command'
import {camelCase, upperFirst} from 'lodash'
import * as path from 'path'
const LuisToCsConverter = require('@microsoft/bf-lu/lib/parser/converters/luistocsconverter')
const file = require('@microsoft/bf-lu/lib/utils/filehelper')
const fs = require('fs-extra')
const exception = require('@microsoft/bf-lu').V2.Exception
export default class LuisGenerateCs extends Command {
static description = 'Generate:cs generates a strongly typed C# source code from an exported (json) LUIS model.'
static flags: flags.Input<any> = {
in: flags.string({char: 'i', description: 'Path to the file containing the LUIS application JSON model'}),
out: flags.string({char: 'o', description: 'Output file or folder name. If not specified stdout will be used as output', default: ''}),
className: flags.string({description: 'Name of the autogenerated class (can include namespace)'}),
force: flags.boolean({char: 'f', description: 'If --out flag is provided with the path to an existing file, overwrites that file', default: false}),
help: flags.help({char: 'h', description: 'luis:generate:cs help'})
}
renameProp(
oldProp: string,
newProp: string,
{[oldProp]: old, ...others}
): any {
return {
[newProp]: old,
...others
}
}
reorderEntities(app: any, name: string): void {
if (app[name] !== null && app[name] !== undefined) {
app[name].sort((a: any, b: any) => (a.name > b.name ? 1 : -1))
}
}
async run() {
try {
const {flags} = this.parse(LuisGenerateCs)
let space = 'Luis'
let stdInput = await this.readStdin()
if (!flags.in && !stdInput) {
throw new CLIError('Missing input. Please use stdin or pass a file location with --in flag')
}
const pathPrefix = flags.in && path.isAbsolute(flags.in) ? '' : process.cwd()
let app: any
try {
app = flags.in ? await fs.readJSON(path.join(pathPrefix, flags.in)) : JSON.parse(stdInput as string)
} catch (err) {
throw new CLIError(err)
}
flags.className = flags.className || app.name
const dot_index = flags.className ? flags.className.lastIndexOf('.') : -1
if (dot_index !== -1) {
space = flags.className.substr(0, dot_index)
flags.className = flags.className.substr(dot_index + 1)
} else {
flags.className = upperFirst(camelCase(flags.className))
}
if ('regexEntities' in app) {
app = this.renameProp('regexEntities', 'regex_entities', app)
}
this.reorderEntities(app, 'entities')
this.reorderEntities(app, 'prebuiltEntities')
this.reorderEntities(app, 'closedLists')
this.reorderEntities(app, 'regex_entities')
this.reorderEntities(app, 'patternAnyEntities')
this.reorderEntities(app, 'composites')
const outputPath = flags.out ? file.validatePath(flags.out, flags.className + '.cs', flags.force) : flags.out
this.log(
`Generating file at ${outputPath || 'stdout'} that contains class ${space}.${flags.className}.`
)
await LuisToCsConverter.writeFromLuisJson(app, flags.className, space, outputPath)
} catch (err) {
if (err instanceof exception) {
throw new CLIError(err.text)
}
throw err
}
}
}