Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Commit 766cba6

Browse files
committed
Merge branch 'master' into emilio/luis
2 parents 975900a + 7f51ce5 commit 766cba6

File tree

82 files changed

+21067
-89
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+21067
-89
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"name": "root",
3+
"version": "1.0.0",
34
"scripts": {
45
"build": "lerna run build && lerna bootstrap",
56
"test": "lerna run test",

packages/luis/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
# Commands
1212
<!-- commands -->
1313
* [`bf luis:convert`](#bf-luisconvert)
14+
* [`bf luis:generate:cs`](#bf-luisgeneratecs)
15+
* [`bf luis:generate:ts`](#bf-luisgeneratets)
1416
* [`bf luis:translate`](#bf-luistranslate)
1517
* [`bf qnamaker:convert`](#bf-qnamakerconvert)
1618
* [`bf qnamaker:translate`](#bf-qnamakertranslate)
@@ -38,6 +40,38 @@ OPTIONS
3840

3941
_See code: [src/commands/luis/convert.ts](https://github.com/microsoft/botframework-cli/blob/v1.0.0/src/commands/luis/convert.ts)_
4042

43+
## `bf luis:generate:cs`
44+
45+
Generate:cs generates a strongly typed C# source code from an exported (json) LUIS model.
46+
47+
```
48+
USAGE
49+
$ bf luis:generate:cs
50+
51+
OPTIONS
52+
--className=className Name of the class
53+
--in=in Source .lu file(s) or LUIS application JSON model
54+
--out=out Output file or folder name. If not specified stdout will be used as output
55+
```
56+
57+
_See code: [src/commands/luis/generate/cs.ts](https://github.com/microsoft/botframework-cli/blob/v1.0.0/src/commands/luis/generate/cs.ts)_
58+
59+
## `bf luis:generate:ts`
60+
61+
Generate:ts generates a strongly typed typescript source code from an exported (json) LUIS model.
62+
63+
```
64+
USAGE
65+
$ bf luis:generate:ts
66+
67+
OPTIONS
68+
--className=className Name of the class
69+
--in=in Source .lu file(s) or LUIS application JSON model
70+
--out=out Output file or folder name. If not specified stdout will be used as output
71+
```
72+
73+
_See code: [src/commands/luis/generate/ts.ts](https://github.com/microsoft/botframework-cli/blob/v1.0.0/src/commands/luis/generate/ts.ts)_
74+
4175
## `bf luis:translate`
4276

4377
Translate given LUIS application JSON model or lu file(s)

packages/luis/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@
77
"dependencies": {
88
"@microsoft/bf-cli-command": "1.0.0",
99
"@oclif/config": "~1.13.3",
10+
"antlr4": "^4.7.2",
1011
"chalk": "2.4.1",
12+
"console-stream": "^0.1.1",
1113
"deep-equal": "^1.0.1",
1214
"fs-extra": "^8.1.0",
1315
"get-stdin": "^6.0.0",
1416
"intercept-stdout": "^0.1.2",
17+
"lodash": "^4.17.15",
1518
"node-fetch": "^2.1.2",
1619
"semver": "^5.5.1",
17-
"tslib": "^1.10.0",
18-
"antlr4": "^4.7.2"
20+
"tslib": "^1.10.0"
1921
},
2022
"devDependencies": {
2123
"@oclif/dev-cli": "^1.22.2",
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import {Command, flags} from '@microsoft/bf-cli-command'
2+
import {camelCase, upperFirst} from 'lodash'
3+
import * as path from 'path'
4+
5+
import {LuisToCsConverter} from '../../../parser/converters/luis-to-cs-converter'
6+
import {Utils} from '../../../utils'
7+
8+
const fs = require('fs-extra')
9+
10+
export default class LuisGenerateCs extends Command {
11+
static description = 'Generate:cs generates a strongly typed C# source code from an exported (json) LUIS model.'
12+
13+
static flags: flags.Input<any> = {
14+
in: flags.string({description: 'Source .lu file(s) or LUIS application JSON model'}),
15+
out: flags.string({description: 'Output file or folder name. If not specified stdout will be used as output', default: ''}),
16+
className: flags.string({description: 'Name of the class'}),
17+
}
18+
19+
reorderEntities(app: any, name: string): void {
20+
if (app[name] !== null && app[name] !== undefined) {
21+
app[name].sort((a: any, b: any) => (a.name > b.name ? 1 : -1))
22+
}
23+
}
24+
25+
async run() {
26+
const {flags} = this.parse(LuisGenerateCs)
27+
let space = 'Luis'
28+
let stdInput = await this.readStdin()
29+
30+
const pathPrefix = path.isAbsolute(flags.in) ? '' : process.cwd()
31+
const app = stdInput ? JSON.parse(stdInput as string) : await fs.readJSON(path.join(pathPrefix, flags.in))
32+
33+
flags.className = flags.className || app.name
34+
flags.className = upperFirst(camelCase(flags.className))
35+
36+
const dot_index = flags.className ? flags.className.indexOf('.') : -1
37+
if (dot_index !== -1) {
38+
space = flags.className.substr(dot_index + 1)
39+
flags.className = flags.className.substr(0, dot_index)
40+
}
41+
42+
this.reorderEntities(app, 'entities')
43+
this.reorderEntities(app, 'prebuiltEntities')
44+
this.reorderEntities(app, 'closedLists')
45+
this.reorderEntities(app, 'regex_entities')
46+
this.reorderEntities(app, 'patternAnyEntities')
47+
this.reorderEntities(app, 'composites')
48+
49+
const outputPath = Utils.validatePath(flags.out, process.cwd(), flags.className + '.cs')
50+
51+
this.log(
52+
`Generating file at ${outputPath || ''} that contains class ${space}.${flags.className}.`
53+
)
54+
55+
await LuisToCsConverter.writeFromLuisJson(app, flags.className, space, outputPath)
56+
}
57+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {Command, flags} from '@microsoft/bf-cli-command'
2+
import {camelCase, kebabCase, upperFirst} from 'lodash'
3+
import * as path from 'path'
4+
5+
import {LuisToTsConverter} from '../../../parser/converters/luis-to-ts-converter'
6+
import {Utils} from '../../../utils'
7+
8+
const fs = require('fs-extra')
9+
10+
export default class LuisGenerateTs extends Command {
11+
static description = 'Generate:ts generates a strongly typed typescript source code from an exported (json) LUIS model.'
12+
13+
static flags: flags.Input<any> = {
14+
in: flags.string({description: 'Source .lu file(s) or LUIS application JSON model'}),
15+
out: flags.string({description: 'Output file or folder name. If not specified stdout will be used as output', default: ''}),
16+
className: flags.string({description: 'Name of the class'}),
17+
}
18+
19+
reorderEntities(app: any, name: string): void {
20+
if (app[name] !== null && app[name] !== undefined) {
21+
app[name].sort((a: any, b: any) => (a.name > b.name ? 1 : -1))
22+
}
23+
}
24+
25+
async run() {
26+
const {flags} = this.parse(LuisGenerateTs)
27+
let stdInput = await this.readStdin()
28+
29+
const pathPrefix = path.isAbsolute(flags.in) ? '' : process.cwd()
30+
const app = stdInput ? JSON.parse(stdInput as string) : await fs.readJSON(path.join(pathPrefix, flags.in))
31+
32+
flags.className = flags.className || app.name
33+
flags.className = upperFirst(camelCase(flags.className))
34+
35+
this.reorderEntities(app, 'entities')
36+
this.reorderEntities(app, 'prebuiltEntities')
37+
this.reorderEntities(app, 'closedLists')
38+
this.reorderEntities(app, 'regex_entities')
39+
this.reorderEntities(app, 'patternAnyEntities')
40+
this.reorderEntities(app, 'composites')
41+
42+
const outputPath = Utils.validatePath(flags.out, process.cwd(), kebabCase(flags.className) + '.ts')
43+
44+
this.log(
45+
`Generating file at ${outputPath || ''} that contains class ${flags.className}.`
46+
)
47+
48+
await LuisToTsConverter.writeFromLuisJson(app, flags.className, outputPath)
49+
}
50+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import {createWriteStream, WriteStream} from 'fs'
2+
import {Writable} from 'stream'
3+
4+
export class Writer {
5+
public indentSize = 4
6+
public indentLevel = 0
7+
private outputStream?: Writable = undefined
8+
9+
public async setOutputStream(outputPath: string): Promise<void> {
10+
const ConsoleStream = require('console-stream')
11+
const stream: Writable = outputPath ? createWriteStream(outputPath) : ConsoleStream()
12+
const streamPromise = new Promise((resolve: any) => {
13+
if (stream instanceof WriteStream) {
14+
stream.once('ready', (_fd: number) => {
15+
this.outputStream = stream
16+
resolve()
17+
})
18+
} else {
19+
this.outputStream = stream
20+
resolve()
21+
}
22+
})
23+
24+
const timeoutPromise = new Promise((resolve: (...args: any) => void) => {
25+
setTimeout(resolve, 2000)
26+
this.outputStream = stream
27+
})
28+
29+
return Promise.race([streamPromise, timeoutPromise]).then(() => {
30+
})
31+
}
32+
33+
public increaseIndentation(): void {
34+
this.indentLevel += this.indentSize
35+
}
36+
37+
public decreaseIndentation(): void {
38+
this.indentLevel -= this.indentSize
39+
}
40+
41+
public write(str: string): void {
42+
this.outputStream!.write(str)
43+
}
44+
45+
public writeLine(str: string | string[] = ''): void {
46+
if (typeof str === 'string') {
47+
this.write(str + '\n')
48+
} else {
49+
str.forEach(line => {
50+
this.write(line + '\n')
51+
})
52+
}
53+
}
54+
55+
public writeIndented(str: string | string[]): void {
56+
let writeFunction = (text: string) => {
57+
for (let index = 0; index < this.indentLevel; index++) {
58+
this.write(' ')
59+
}
60+
this.write(text)
61+
}
62+
63+
writeFunction.bind(this)
64+
65+
if (typeof str === 'string') {
66+
writeFunction(str)
67+
} else {
68+
str.forEach(line => {
69+
writeFunction(line)
70+
})
71+
}
72+
}
73+
74+
public writeLineIndented(lines: string | string[]): void {
75+
if (typeof lines === 'string') {
76+
this.writeIndented(lines + '\n')
77+
} else {
78+
lines.forEach(line => {
79+
this.writeIndented(line + '\n')
80+
})
81+
}
82+
}
83+
84+
public async closeOutputStream(): Promise<void> {
85+
this.outputStream!.end()
86+
const streamPromise = new Promise((resolve: any) => {
87+
if (this.outputStream instanceof WriteStream) {
88+
this.outputStream!.on('finish', (_fd: number) => {
89+
resolve()
90+
})
91+
} else {
92+
resolve()
93+
}
94+
})
95+
96+
const timeoutPromise = new Promise((resolve: (...args: any) => void) => {
97+
setTimeout(resolve, 1000)
98+
})
99+
100+
return Promise.race([streamPromise, timeoutPromise]).then(() => {
101+
this.outputStream = undefined
102+
})
103+
}
104+
}

0 commit comments

Comments
 (0)