Skip to content

Commit f59a837

Browse files
committed
prettier (blocked on prettier/issues/648) (fix #45)
1 parent dd00edd commit f59a837

File tree

7 files changed

+83
-59
lines changed

7 files changed

+83
-59
lines changed

ARCHITECTURE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ Optimizes the IR to produce concise and readable TypeScript in step (6).
2323
#### 6. Generator
2424

2525
Converts the intermediate respresentation to TypeScript code.
26+
27+
#### 7. Formatter
28+
29+
Formats the code so it is properly indented, etc.

README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,7 @@ See [server demo](example) and [browser demo](https://github.com/bcherny/json-sc
8686
| cwd | string | Root directory for resolving `$ref`s |
8787
| declareExternallyReferenced | boolean | Declare external schemas referenced via `$ref`? |
8888
| enableConstEnums | boolean | Prepend enums with `const`? |
89-
| enableTrailingSemicolonForTypes | boolean | |
90-
| enableTrailingSemicolonForEnums | boolean | |
91-
| enableTrailingSemicolonForInterfaceProperties | boolean | |
92-
| enableTrailingSemicolonForInterfaces | boolean | |
93-
| indentWith | string | Tabs or spaces? |
89+
| style | object | A [Prettier](https://prettier.io/docs/en/options.html) configuration |
9490

9591
## CLI
9692

package.json

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050
"json-stringify-safe": "^5.0.1",
5151
"lodash": "^4.17.4",
5252
"minimist": "^1.2.0",
53-
"mz": "^2.7.0",
53+
"mz": "^2.6.0",
54+
"prettier": "^1.7.0",
5455
"stdin": "0.0.1"
5556
},
5657
"devDependencies": {
@@ -59,10 +60,11 @@
5960
"@types/lodash": "4.14.74",
6061
"@types/minimist": "^1.2.0",
6162
"@types/mz": "0.0.31",
62-
"@types/node": "^8.0.28",
63-
"ava": "^0.22.0",
64-
"browserify": "^14.4.0",
65-
"concurrently": "^3.5.0",
63+
"@types/node": "^7.0.13",
64+
"@types/prettier": "^1.6.1",
65+
"ava": "^0.19.1",
66+
"browserify": "^14.3.0",
67+
"concurrently": "^3.4.0",
6668
"fast-diff": "^1.1.1",
6769
"shx": "^0.2.2",
6870
"table-layout": "^0.4.2",

src/formatter.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { format as prettify } from 'prettier'
2+
import { DEFAULT_OPTIONS, Options } from './'
3+
4+
export function format(code: string, options: Options = DEFAULT_OPTIONS): string {
5+
return prettify(code, { parser: 'typescript', ...options.style })
6+
}

src/generator.ts

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ function declareNamedTypes(
127127
return type
128128
}
129129

130-
function generateType(ast: AST, options: Options, indentDepth: number): string {
130+
function generateType(ast: AST, options: Options): string {
131131
log(whiteBright.bgMagenta('generator'), ast)
132132

133133
if (hasStandaloneName(ast)) {
@@ -137,94 +137,84 @@ function generateType(ast: AST, options: Options, indentDepth: number): string {
137137
switch (ast.type) {
138138
case 'ANY': return 'any'
139139
case 'ARRAY': return (() => {
140-
let type = generateType(ast.params, options, indentDepth + 1)
140+
let type = generateType(ast.params, options)
141141
return type.endsWith('"') ? '(' + type + ')[]' : type + '[]'
142142
})()
143143
case 'BOOLEAN': return 'boolean'
144-
case 'INTERFACE': return generateInterface(ast, options, indentDepth + 1)
145-
case 'INTERSECTION': return generateSetOperation(ast, options, indentDepth)
144+
case 'INTERFACE': return generateInterface(ast, options)
145+
case 'INTERSECTION': return generateSetOperation(ast, options)
146146
case 'LITERAL': return JSON.stringify(ast.params)
147147
case 'NUMBER': return 'number'
148148
case 'NULL': return 'null'
149149
case 'OBJECT': return 'object'
150150
case 'REFERENCE': return ast.params
151151
case 'STRING': return 'string'
152152
case 'TUPLE': return '['
153-
+ ast.params.map(_ => generateType(_, options, indentDepth + 1)).join(', ')
153+
+ ast.params.map(_ => generateType(_, options)).join(', ')
154154
+ ']'
155-
case 'UNION': return generateSetOperation(ast, options, indentDepth)
155+
case 'UNION': return generateSetOperation(ast, options)
156156
}
157157
}
158158

159159
/**
160160
* Generate a Union or Intersection
161161
*/
162-
function generateSetOperation(ast: TIntersection | TUnion, options: Options, indentDepth: number): string {
163-
const members = (ast as TUnion).params.map(_ => generateType(_, options, indentDepth))
162+
function generateSetOperation(ast: TIntersection | TUnion, options: Options): string {
163+
const members = (ast as TUnion).params.map(_ => generateType(_, options))
164164
const separator = ast.type === 'UNION' ? '|' : '&'
165165
return members.length === 1 ? members[0] : '(' + members.join(' ' + separator + ' ') + ')'
166166
}
167167

168168
function generateInterface(
169169
ast: TInterface,
170-
options: Options,
171-
indentDepth: number
170+
options: Options
172171
): string {
173172
return `{`
174173
+ '\n'
175-
+ options.indentWith.repeat(indentDepth)
176174
+ ast.params
177-
.map(({ isRequired, keyName, ast }) => [isRequired, keyName, ast, generateType(ast, options, indentDepth)] as [boolean, string, AST, string])
175+
.map(({ isRequired, keyName, ast }) => [isRequired, keyName, ast, generateType(ast, options)] as [boolean, string, AST, string])
178176
.map(([isRequired, keyName, ast, type]) =>
179-
(hasComment(ast) && !ast.standaloneName ? generateComment(ast.comment, options, indentDepth + 1) + '\n' : '')
180-
+ options.indentWith
177+
(hasComment(ast) && !ast.standaloneName ? generateComment(ast.comment) + '\n' : '')
181178
+ escapeKeyName(keyName)
182179
+ (isRequired ? '' : '?')
183180
+ ': '
184181
+ (hasStandaloneName(ast) ? toSafeString(type) : type)
185-
+ (options.enableTrailingSemicolonForInterfaceProperties ? ';' : '')
186182
)
187-
.join('\n' + options.indentWith.repeat(indentDepth))
183+
.join('\n')
188184
+ '\n'
189-
+ options.indentWith.repeat(indentDepth) + '}'
185+
+ '}'
190186
}
191187

192-
function generateComment(comment: string, options: Options, indentDepth: number): string {
193-
return options.indentWith.repeat(indentDepth)
194-
+ [
195-
'/**',
196-
...comment.split('\n').map(_ => ' * ' + _),
197-
' */'
198-
].join('\n' + options.indentWith.repeat(indentDepth))
188+
function generateComment(comment: string): string {
189+
return [
190+
'/**',
191+
...comment.split('\n').map(_ => ' * ' + _),
192+
' */'
193+
].join('\n')
199194
}
200195

201196
function generateStandaloneEnum(ast: TEnum, options: Options): string {
202-
return (hasComment(ast) ? generateComment(ast.comment, options, 0) + '\n' : '')
197+
return (hasComment(ast) ? generateComment(ast.comment) + '\n' : '')
203198
+ 'export ' + (options.enableConstEnums ? 'const ' : '') + `enum ${toSafeString(ast.standaloneName)} {`
204199
+ '\n'
205200
+ ast.params.map(({ ast, keyName }) =>
206-
options.indentWith
207-
+ keyName
208-
+ ' = '
209-
+ generateType(ast, options, 0)
201+
keyName + ' = ' + generateType(ast, options)
210202
)
211203
.join(',\n')
212204
+ '\n'
213205
+ '}'
214206
}
215207

216208
function generateStandaloneInterface(ast: TNamedInterface, options: Options): string {
217-
return (hasComment(ast) ? generateComment(ast.comment, options, 0) + '\n' : '')
209+
return (hasComment(ast) ? generateComment(ast.comment) + '\n' : '')
218210
+ `export interface ${toSafeString(ast.standaloneName)} `
219211
+ (ast.superTypes.length > 0 ? `extends ${ast.superTypes.map(superType => toSafeString(superType.standaloneName)).join(', ')} ` : '')
220-
+ generateInterface(ast, options, 0)
221-
+ (options.enableTrailingSemicolonForInterfaces ? ';' : '')
212+
+ generateInterface(ast, options)
222213
}
223214

224215
function generateStandaloneType(ast: ASTWithStandaloneName, options: Options): string {
225-
return (hasComment(ast) ? generateComment(ast.comment, options, 0) + '\n' : '')
226-
+ `export type ${toSafeString(ast.standaloneName)} = ${generateType(omit<ASTWithStandaloneName, AST>(ast, 'standaloneName'), options, 0)}`
227-
+ (options.enableTrailingSemicolonForTypes ? ';' : '')
216+
return (hasComment(ast) ? generateComment(ast.comment) + '\n' : '')
217+
+ `export type ${toSafeString(ast.standaloneName)} = ${generateType(omit<ASTWithStandaloneName, AST>(ast, 'standaloneName'), options)}`
228218
}
229219

230220
function escapeKeyName(keyName: string): string {

src/index.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { readFileSync } from 'fs'
22
import { JSONSchema4 } from 'json-schema'
3-
import { endsWith } from 'lodash'
3+
import { endsWith, merge } from 'lodash'
44
import { dirname } from 'path'
5+
import { Options as PrettierOptions } from 'prettier'
6+
import { format } from './formatter'
57
import { generate } from './generator'
68
import { normalize } from './normalizer'
79
import { optimize } from './optimizer'
@@ -17,11 +19,7 @@ export interface Options {
1719
cwd: string
1820
declareExternallyReferenced: boolean
1921
enableConstEnums: boolean
20-
enableTrailingSemicolonForTypes: boolean
21-
enableTrailingSemicolonForEnums: boolean
22-
enableTrailingSemicolonForInterfaceProperties: boolean
23-
enableTrailingSemicolonForInterfaces: boolean
24-
indentWith: string
22+
style: PrettierOptions
2523
}
2624

2725
export const DEFAULT_OPTIONS: Options = {
@@ -33,11 +31,15 @@ export const DEFAULT_OPTIONS: Options = {
3331
cwd: process.cwd(),
3432
declareExternallyReferenced: true,
3533
enableConstEnums: true, // by default, avoid generating code
36-
enableTrailingSemicolonForEnums: false,
37-
enableTrailingSemicolonForInterfaceProperties: true,
38-
enableTrailingSemicolonForInterfaces: false,
39-
enableTrailingSemicolonForTypes: true,
40-
indentWith: ' '
34+
style: {
35+
bracketSpacing: false,
36+
printWidth: 120,
37+
semi: true,
38+
singleQuote: false,
39+
tabWidth: 2,
40+
trailingComma: 'none',
41+
useTabs: false
42+
}
4143
}
4244

4345
export function compileFromFile(
@@ -65,7 +67,7 @@ export async function compile(
6567
options: Partial<Options> = {}
6668
): Promise<string> {
6769

68-
const _options = { ...DEFAULT_OPTIONS, ...options }
70+
const _options = merge({}, DEFAULT_OPTIONS, options)
6971

7072
const errors = validate(schema, name)
7173
if (errors.length) {
@@ -78,10 +80,10 @@ export async function compile(
7880
_options.cwd += '/'
7981
}
8082

81-
return generate(
83+
return format(generate(
8284
optimize(parse(await dereference(normalize(schema, name), _options.cwd))),
8385
_options
84-
)
86+
))
8587
}
8688

8789
export class ValidationError extends Error {}

yarn.lock

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
dependencies:
4545
arrify "^1.0.1"
4646

47+
"@types/babel-types@*":
48+
version "6.25.1"
49+
resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-6.25.1.tgz#ce8f126a4403e11e1b0033a424f11638afac7889"
50+
4751
"@types/cli-color@^0.3.29":
4852
version "0.3.29"
4953
resolved "https://registry.yarnpkg.com/@types/cli-color/-/cli-color-0.3.29.tgz#c83a71fe02c8c7e1ccec048dd6a2458d1f6c96ea"
@@ -72,6 +76,16 @@
7276
version "8.0.28"
7377
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.28.tgz#86206716f8d9251cf41692e384264cbd7058ad60"
7478

79+
"@types/node@^7.0.13":
80+
version "7.0.43"
81+
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c"
82+
83+
"@types/prettier@^1.6.1":
84+
version "1.6.1"
85+
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.6.1.tgz#b92e866b098e5d37b2d4dd2402291a8eb6072bf8"
86+
dependencies:
87+
"@types/babel-types" "*"
88+
7589
JSONStream@^1.0.3:
7690
version "1.3.1"
7791
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.1.tgz#707f761e01dae9e16f1bcf93703b78c70966579a"
@@ -2922,6 +2936,16 @@ preserve@^0.2.0:
29222936
version "0.2.0"
29232937
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
29242938

2939+
prettier@^1.7.0:
2940+
version "1.7.0"
2941+
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.7.0.tgz#47481588f41f7c90f63938feb202ac82554e7150"
2942+
2943+
pretty-format@^19.0.0:
2944+
version "19.0.0"
2945+
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-19.0.0.tgz#56530d32acb98a3fa4851c4e2b9d37b420684c84"
2946+
dependencies:
2947+
ansi-styles "^3.0.0"
2948+
29252949
pretty-ms@^0.2.1:
29262950
version "0.2.2"
29272951
resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-0.2.2.tgz#da879a682ff33a37011046f13d627f67c73b84f6"

0 commit comments

Comments
 (0)