Skip to content

Commit 34ec652

Browse files
Add directory support
1 parent 85c3ab0 commit 34ec652

File tree

7 files changed

+224
-25
lines changed

7 files changed

+224
-25
lines changed

.vscode/settings.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
// Place your settings in this file to overwrite default and user settings.
22
{
33
"typescript.tsdk": "node_modules/typescript/lib",
4+
<<<<<<< HEAD
5+
"editor.tabSize": 2,
6+
"workbench.colorCustomizations": {
7+
"titleBar.activeBackground": "#b483d5",
8+
"titleBar.inactiveBackground": "#b483d599",
9+
"titleBar.activeForeground": "#15202b",
10+
"titleBar.inactiveForeground": "#15202b99",
11+
"statusBar.background": "#b483d5",
12+
"statusBarItem.hoverBackground": "#9d5dc8",
13+
"statusBar.foreground": "#15202b"
14+
},
15+
"peacock.color": "#b483d5"
16+
=======
417
"editor.tabSize": 2
18+
>>>>>>> f506531... fix revisions
519
}

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,26 @@
4545
},
4646
"homepage": "https://github.com/bcherny/json-schema-to-typescript#readme",
4747
"dependencies": {
48+
"@types/is-glob": "^4.0.1",
4849
"@types/json-schema": "^7.0.3",
50+
"@types/mkdirp": "^0.5.2",
4951
"@types/node": ">=4.5.0",
5052
"@types/prettier": "^1.16.1",
5153
"cli-color": "^1.4.0",
54+
"glob": "^7.1.4",
55+
"is-glob": "^4.0.1",
5256
"json-schema-ref-parser": "^6.1.0",
5357
"json-stringify-safe": "^5.0.1",
5458
"lodash": "^4.17.11",
5559
"minimist": "^1.2.0",
60+
"mkdirp": "^0.5.1",
5661
"mz": "^2.7.0",
5762
"prettier": "^1.18.2",
5863
"stdin": "0.0.1"
5964
},
6065
"devDependencies": {
6166
"@types/cli-color": "^0.3.29",
67+
"@types/glob": "^7.1.1",
6268
"@types/lodash": "^4.14.121",
6369
"@types/minimist": "^1.2.0",
6470
"@types/mz": "0.0.32",

src/cli.ts

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
#!/usr/bin/env node
22

33
import { whiteBright } from 'cli-color'
4-
import { JSONSchema4 } from 'json-schema'
54
import minimist = require('minimist')
6-
import { readFile, writeFile } from 'mz/fs'
7-
import { resolve } from 'path'
5+
import { readFile, writeFile, existsSync } from 'mz/fs'
6+
import * as _mkdirp from 'mkdirp'
7+
import * as _glob from 'glob'
8+
import isGlob = require('is-glob')
9+
import { promisify } from 'util'
10+
import { join, resolve, basename } from 'path'
811
import stdin = require('stdin')
912
import { compile, Options } from './index'
1013

14+
// Promisify mkdirp
15+
const mkdirp = (path: string) => new Promise((res, rej) => {
16+
_mkdirp(path, (err, made) => {
17+
if (err) rej(err)
18+
else res(made === null ? undefined : made)
19+
})
20+
})
21+
22+
const glob = promisify(_glob)
23+
1124
main(minimist(process.argv.slice(2), {
1225
alias: {
1326
help: ['h'],
1427
input: ['i'],
15-
output: ['o']
28+
output: ['o'],
29+
recursive: ['r']
1630
}
1731
}))
1832

@@ -27,14 +41,54 @@ async function main(argv: minimist.ParsedArgs) {
2741
const argOut: string = argv._[1] || argv.output
2842

2943
try {
30-
const schema: JSONSchema4 = JSON.parse(await readInput(argIn))
31-
const ts = await compile(schema, argIn, argv as Partial<Options>)
32-
await writeOutput(ts, argOut)
44+
let files = await getFilesToProcess(argIn, argOut, argv as Partial<Options>)
45+
await Promise.all(files)
3346
} catch (e) {
3447
console.error(whiteBright.bgRedBright('error'), e)
3548
process.exit(1)
3649
}
50+
}
51+
52+
function getFilesToProcess(argIn: string, argOut: string, argv: Partial<Options>): Promise<Promise<void>[]> {
53+
return new Promise(async (res, rej) => {
54+
try {
55+
if (isGlob(argIn)) {
56+
let files = await glob(join(process.cwd(), argIn))
57+
58+
if (files.length === 0) {
59+
rej('No files match glob pattern')
60+
}
61+
62+
if (argOut && !existsSync(argOut)) {
63+
await mkdirp(argOut)
64+
}
65+
66+
res(files.map(file => processFile(file, { dir: argOut }, argv)))
67+
return
68+
} else {
69+
res([processFile(argIn, { file: argOut }, argv)])
70+
}
71+
} catch (e) {
72+
console.error(whiteBright.bgRedBright('error'), e)
73+
process.exit(1)
74+
}
75+
})
76+
}
3777

78+
function processFile(file: string, out: {dir?: string, file?: string}, argv: Partial<Options>): Promise<void> {
79+
return new Promise(async (res, rej) => {
80+
try {
81+
const schema = JSON.parse(await readInput(file))
82+
const ts = await compile(schema, file, argv)
83+
await writeOutput(
84+
ts,
85+
out.dir ? join(process.cwd(), out.dir, `${basename(file, '.json')}.d.ts`) : out.file || ''
86+
)
87+
res()
88+
} catch (err) {
89+
rej(err)
90+
}
91+
})
3892
}
3993

4094
function readInput(argIn?: string) {

test/__snapshots__/test/test.ts.md

Lines changed: 95 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,101 @@ Generated by [AVA](https://ava.li).
15391539
}␊
15401540
`
15411541

1542+
## files in (-i), files out (-o)
1543+
1544+
> Snapshot 1
1545+
1546+
`/* tslint:disable */␊
1547+
/**␊
1548+
* This file was automatically generated by json-schema-to-typescript.␊
1549+
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,␊
1550+
* and run json-schema-to-typescript to regenerate this file.␊
1551+
*/␊
1552+
1553+
export interface ASchema {␊
1554+
f: string;␊
1555+
g?: number;␊
1556+
}␊
1557+
`
1558+
1559+
> Snapshot 2
1560+
1561+
`/* tslint:disable */␊
1562+
/**␊
1563+
* This file was automatically generated by json-schema-to-typescript.␊
1564+
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,␊
1565+
* and run json-schema-to-typescript to regenerate this file.␊
1566+
*/␊
1567+
1568+
export interface BSchema {␊
1569+
x?: string;␊
1570+
y: number;␊
1571+
[k: string]: any;␊
1572+
}␊
1573+
`
1574+
1575+
## files in (-i), files out (-o) nested dir does not exist
1576+
1577+
> Snapshot 1
1578+
1579+
`/* tslint:disable */␊
1580+
/**␊
1581+
* This file was automatically generated by json-schema-to-typescript.␊
1582+
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,␊
1583+
* and run json-schema-to-typescript to regenerate this file.␊
1584+
*/␊
1585+
1586+
export interface ASchema {␊
1587+
f: string;␊
1588+
g?: number;␊
1589+
}␊
1590+
`
1591+
1592+
> Snapshot 2
1593+
1594+
`/* tslint:disable */␊
1595+
/**␊
1596+
* This file was automatically generated by json-schema-to-typescript.␊
1597+
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,␊
1598+
* and run json-schema-to-typescript to regenerate this file.␊
1599+
*/␊
1600+
1601+
export interface BSchema {␊
1602+
x?: string;␊
1603+
y: number;␊
1604+
[k: string]: any;␊
1605+
}␊
1606+
`
1607+
1608+
## files in (-i), pipe out
1609+
1610+
> Snapshot 1
1611+
1612+
`/* tslint:disable */␊
1613+
/**␊
1614+
* This file was automatically generated by json-schema-to-typescript.␊
1615+
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,␊
1616+
* and run json-schema-to-typescript to regenerate this file.␊
1617+
*/␊
1618+
1619+
export interface ASchema {␊
1620+
f: string;␊
1621+
g?: number;␊
1622+
}␊
1623+
/* tslint:disable */␊
1624+
/**␊
1625+
* This file was automatically generated by json-schema-to-typescript.␊
1626+
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,␊
1627+
* and run json-schema-to-typescript to regenerate this file.␊
1628+
*/␊
1629+
1630+
export interface BSchema {␊
1631+
x?: string;␊
1632+
y: number;␊
1633+
[k: string]: any;␊
1634+
}␊
1635+
`
1636+
15421637
## formatterOptions.js
15431638

15441639
> Snapshot 1
@@ -9425,20 +9520,3 @@ Generated by [AVA](https://ava.li).
94259520
[k: string]: any;␊
94269521
}␊
94279522
`
9428-
9429-
## strictIndexSignatures.js
9430-
9431-
> Snapshot 1
9432-
9433-
`/* tslint:disable */␊
9434-
/**␊
9435-
* This file was automatically generated by json-schema-to-typescript.␊
9436-
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,␊
9437-
* and run json-schema-to-typescript to regenerate this file.␊
9438-
*/␊
9439-
9440-
export interface StrictIndexSignatures {␊
9441-
maybe?: string;␊
9442-
[k: string]: string | undefined;␊
9443-
}␊
9444-
`

test/resources/MultiSchema/a.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"title": "A schema",
3+
"type": "object",
4+
"properties": {
5+
"f": {"type": "string"},
6+
"g": {"type": "integer"}
7+
},
8+
"additionalProperties": false,
9+
"required": ["f"]
10+
}

test/resources/MultiSchema/b.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"title": "B schema",
3+
"type": "object",
4+
"properties": {
5+
"x": {"type": "string"},
6+
"y": {"type": "integer"}
7+
},
8+
"additionalProperties": true,
9+
"required": ["y"]
10+
}

test/testCLI.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import test from 'ava'
22
import { execSync } from 'child_process'
3-
import { readFileSync, unlinkSync } from 'fs'
3+
import { readFileSync, unlinkSync, readdirSync, rmdirSync } from 'fs'
44

55
export function run() {
66

@@ -82,4 +82,31 @@ export function run() {
8282
unlinkSync('./ReferencedType.d.ts')
8383
})
8484

85+
test('files in (-i), files out (-o)', t => {
86+
execSync('node dist/src/cli.js -i ./test/resources/MultiSchema/**/*.json -o ./test/resources/MultiSchema/out').toString()
87+
88+
readdirSync('./test/resources/MultiSchema/out').forEach(f => {
89+
const path = `./test/resources/MultiSchema/out/${f}`
90+
t.snapshot(readFileSync(path, 'utf-8'))
91+
unlinkSync(path)
92+
})
93+
rmdirSync('./test/resources/MultiSchema/out')
94+
})
95+
96+
test('files in (-i), pipe out', t => {
97+
t.snapshot(
98+
execSync('node dist/src/cli.js -i ./test/resources/MultiSchema/**/*.json').toString()
99+
)
100+
})
101+
102+
test('files in (-i), files out (-o) nested dir does not exist', t => {
103+
execSync('node dist/src/cli.js -i ./test/resources/MultiSchema/**/*.json -o ./test/resources/MultiSchema/foo/bar/out').toString()
104+
105+
readdirSync('./test/resources/MultiSchema/foo/bar/out').forEach(f => {
106+
const path = `./test/resources/MultiSchema/foo/bar/out/${f}`
107+
t.snapshot(readFileSync(path, 'utf-8'))
108+
unlinkSync(path)
109+
})
110+
rmdirSync('./test/resources/MultiSchema/foo/bar/out')
111+
})
85112
}

0 commit comments

Comments
 (0)