Skip to content

Commit

Permalink
Add option to generate TS string enums
Browse files Browse the repository at this point in the history
  • Loading branch information
codan84 committed May 15, 2024
1 parent 49fb14d commit 0312e9c
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ See [server demo](example) and [browser demo](https://github.com/bcherny/json-sc
| cwd | string | `process.cwd()` | Root directory for resolving [`$ref`](https://tools.ietf.org/id/draft-pbryan-zyp-json-ref-03.html)s |
| declareExternallyReferenced | boolean | `true` | Declare external schemas referenced via `$ref`? |
| enableConstEnums | boolean | `true` | Prepend enums with [`const`](https://www.typescriptlang.org/docs/handbook/enums.html#computed-and-constant-members)? |
| inferStringEnumKeysFromValues | boolean | `false` | Create enums from JSON enums with eponymous keys |
| format | boolean | `true` | Format code? Set this to `false` to improve performance. |
| ignoreMinAndMaxItems | boolean | `false` | Ignore maxItems and minItems for `array` types, preventing tuples being generated. |
| maxItems | number | `20` | Maximum number of unioned tuples to emit when representing bounded-size array types, before falling back to emitting unbounded arrays. Increase this to improve precision of emitted types, decrease it to improve performance, or set it to `-1` to ignore `maxItems`.
Expand Down
2 changes: 2 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ Boolean values can be set to false using the 'no-' prefix.
Declare external schemas referenced via '$ref'?
--enableConstEnums
Prepend enums with 'const'?
--inferStringEnumKeysFromValues
Create enums from JSON enums instead of union types
--format
Format code? Set this to false to improve performance.
--maxItems
Expand Down
5 changes: 5 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ export interface Options {
* Prepend enums with [`const`](https://www.typescriptlang.org/docs/handbook/enums.html#computed-and-constant-members)?
*/
enableConstEnums: boolean
/**
* Create enums from JSON enums with eponymous keys
*/
inferStringEnumKeysFromValues: boolean
/**
* Format code? Set this to `false` to improve performance.
*/
Expand Down Expand Up @@ -96,6 +100,7 @@ export const DEFAULT_OPTIONS: Options = {
cwd: process.cwd(),
declareExternallyReferenced: true,
enableConstEnums: true,
inferStringEnumKeysFromValues: false,
format: true,
ignoreMinAndMaxItems: false,
maxItems: 20,
Expand Down
9 changes: 9 additions & 0 deletions src/normalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ function isObjectType(schema: LinkedJSONSchema) {
function isArrayType(schema: LinkedJSONSchema) {
return schema.items !== undefined || hasType(schema, 'array') || hasType(schema, 'any')
}
function isEnumTypeWithoutTsEnumNames(schema: LinkedJSONSchema) {
return schema.type === 'string' && schema.enum !== undefined && schema.tsEnumNames === undefined
}

rules.set('Remove `type=["null"]` if `enum=[null]`', schema => {
if (
Expand Down Expand Up @@ -222,6 +225,12 @@ rules.set('Transform const to singleton enum', schema => {
}
})

rules.set('Add tsEnumNames to enum types', (schema, _, options) => {
if (isEnumTypeWithoutTsEnumNames(schema) && options.inferStringEnumKeysFromValues) {
schema.tsEnumNames = schema.enum?.map(String)
}
})

export function normalize(
rootSchema: LinkedJSONSchema,
dereferencedPaths: DereferencedPaths,
Expand Down
17 changes: 17 additions & 0 deletions test/normalizer/addTsEnumNames.1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "Add tsEnumNames to enum types (1)",
"in": {
"$id": "foo",
"type": "string",
"enum": ["foo", "bar"]
},
"options": {
"inferStringEnumKeysFromValues": true
},
"out": {
"$id": "foo",
"type": "string",
"enum": [ "foo", "bar" ],
"tsEnumNames": ["foo", "bar"]
}
}
16 changes: 16 additions & 0 deletions test/normalizer/addTsEnumNames.2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "Add tsEnumNames to enum types (2)",
"in": {
"$id": "foo",
"type": "string",
"enum": ["foo", "bar"]
},
"options": {
"inferStringEnumKeysFromValues": false
},
"out": {
"$id": "foo",
"type": "string",
"enum": [ "foo", "bar" ]
}
}
18 changes: 18 additions & 0 deletions test/normalizer/addTsEnumNames.3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "Add tsEnumNames to enum types (3)",
"in": {
"$id": "foo",
"type": "string",
"enum": ["foo", "bar"],
"tsEnumNames": ["FOO", "BAR"]
},
"options": {
"inferStringEnumKeysFromValues": true
},
"out": {
"$id": "foo",
"type": "string",
"enum": [ "foo", "bar" ],
"tsEnumNames": ["FOO", "BAR"]
}
}

0 comments on commit 0312e9c

Please sign in to comment.