Skip to content

Commit

Permalink
feat: enumerations
Browse files Browse the repository at this point in the history
  • Loading branch information
elyukai committed Feb 15, 2022
1 parent 576b9d6 commit faf2447
Showing 1 changed file with 55 additions and 2 deletions.
57 changes: 55 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ namespace JsonSchema {
const: string | number | boolean
}

export interface Enum extends Annotated {
enum: (string | number)[]
}

export interface Reference extends Annotated {
$ref: string
}
Expand All @@ -85,6 +89,7 @@ namespace JsonSchema {
| String
| Boolean
| Constant
| Enum
| Reference

export type NonStrictObject =
Expand All @@ -97,6 +102,7 @@ namespace JsonSchema {
| Reference
| Union
| Constant
| Enum

export type Definition =
| StrictObject
Expand All @@ -109,6 +115,7 @@ namespace JsonSchema {
| Reference
| Union
| Constant
| Enum

export interface Base extends Annotated {
$schema: string
Expand Down Expand Up @@ -151,6 +158,9 @@ namespace JsonSchema {
export const isConstant = (x: Definition): x is Constant =>
x.hasOwnProperty("const")

export const isEnum = (x: Definition): x is Enum =>
x.hasOwnProperty("enum")

export const isReference = (x: Definition): x is Reference =>
x.hasOwnProperty("$ref")

Expand Down Expand Up @@ -420,13 +430,40 @@ namespace TypeScriptToJsonSchema {
}
}

const toJsonSchemaEnum = (node: ts.EnumDeclaration) => {
const jsDoc = JSDoc.ofNode(node)

return {
...JSDoc.toAnnotations(jsDoc),
enum: node.members.flatMap((member): (string | number)[] => {
if (member.initializer) {
if (ts.isStringLiteral(member.initializer)) {
return [ member.initializer.text ]
}
else if (ts.isNumericLiteral(member.initializer)) {
return [ Number.parseFloat(member.initializer.text) ]
}
else {
return []
}
}
else {
return []
}
})
}
}

const toJsonSchemaType = (node: ts.Node): JsonSchema.Definition => {
if (ts.isTypeAliasDeclaration(node)) {
return toJsonSchemaType(node.type)
}
else if (ts.isInterfaceDeclaration(node)) {
return toJsonSchemaObject(node, JSDoc.ofNode(node))
}
else if (ts.isEnumDeclaration(node)) {
return toJsonSchemaEnum(node)
}
else if (ts.isTypeLiteralNode(node)) {
return toJsonSchemaObject(node, JSDoc.ofNode(node.parent))
}
Expand Down Expand Up @@ -468,7 +505,7 @@ namespace TypeScriptToJsonSchema {
}

const getDefinitionName = (statement: ts.Node) => {
if (ts.isTypeAliasDeclaration(statement) || ts.isInterfaceDeclaration(statement)) {
if (ts.isTypeAliasDeclaration(statement) || ts.isInterfaceDeclaration(statement) || ts.isEnumDeclaration(statement)) {
return statement.name.escapedText.toString()
}
else {
Expand All @@ -482,7 +519,11 @@ namespace TypeScriptToJsonSchema {
const definitions = Object.fromEntries(
file
.statements
.filter(x => ts.isInterfaceDeclaration(x) || ts.isTypeAliasDeclaration(x))
.filter(node =>
ts.isInterfaceDeclaration(node)
|| ts.isTypeAliasDeclaration(node)
|| ts.isEnumDeclaration(node)
)
.map(statement => [
getDefinitionName(statement),
toJsonSchemaType(statement)
Expand Down Expand Up @@ -666,6 +707,18 @@ namespace JsonSchemaToMarkdown {
},
})
}
else if (JsonSchema.isEnum(node)) {
return LabelledList.create(node, {
title: false,
description: false,
enum: {
label: "Possible values",
transform: values => values
.map(value => `\`${JSON.stringify(value)}\``)
.join(", ")
},
})
}
else {
throw new Error(`${JSON.stringify(node)} is not primitive`)
}
Expand Down

0 comments on commit faf2447

Please sign in to comment.