Skip to content

Commit

Permalink
add constAsEnum flag to convert constant values to single value enum (#…
Browse files Browse the repository at this point in the history
…571)

* add constAsEnum flag to convert constant values in properties to single value enum

* fix lint
  • Loading branch information
gassiss authored Sep 7, 2023
1 parent 3268f3b commit a9bb215
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Options:
--id Set schema id. [string] [default: ""]
--defaultNumberType Default number type. [choices: "number", "integer"] [default: "number"]
--tsNodeRegister Use ts-node/register (needed for require typescript files). [boolean] [default: false]
--constAsEnum Use enums with a single value when declaring constants. [boolean] [default: false]
```

### Programmatic use
Expand Down
3 changes: 3 additions & 0 deletions test/programs/const-as-enum/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface MyObject {
reference: true;
}
16 changes: 16 additions & 0 deletions test/programs/const-as-enum/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"reference": {
"enum": [
true
],
"type": "boolean"
}
},
"required": [
"reference"
],
"type": "object"
}
4 changes: 4 additions & 0 deletions test/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -543,3 +543,7 @@ describe("satisfies keyword - ignore from a \"satisfies\" and build by rally typ
describe("const keyword", () => {
assertSchema("const-keyword", "Object");
});

describe("constAsEnum option", () => {
assertSchema("const-as-enum", "MyObject", { constAsEnum: true });
});
3 changes: 3 additions & 0 deletions typescript-json-schema-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export function run() {
.describe("defaultNumberType", "Default number type.")
.boolean("tsNodeRegister").default("tsNodeRegister", defaultArgs.tsNodeRegister)
.describe("tsNodeRegister", "Use ts-node/register (needed for requiring typescript files).")
.boolean("constAsEnum").default("constAsEnum", defaultArgs.constAsEnum)
.describe("constAsEnum", "Use enums with a single value when declaring constants. Needed for OpenAPI compatibility")
.argv;

exec(args._[0], args._[1], {
Expand All @@ -78,6 +80,7 @@ export function run() {
id: args.id,
defaultNumberType: args.defaultNumberType,
tsNodeRegister: args.tsNodeRegister,
constAsEnum: args.constAsEnum,
});
}

Expand Down
15 changes: 14 additions & 1 deletion typescript-json-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export function getDefaultArgs(): Args {
id: "",
defaultNumberType: "number",
tsNodeRegister: false,
constAsEnum: false,
};
}

Expand Down Expand Up @@ -89,6 +90,7 @@ export type Args = {
id: string;
defaultNumberType: "number" | "integer";
tsNodeRegister: boolean;
constAsEnum: boolean;
};

export type PartialArgs = Partial<Args>;
Expand Down Expand Up @@ -486,6 +488,12 @@ export class JsonSchemaGenerator {
*/
private userValidationKeywords: ValidationKeywords;

/**
* If true, this makes constants be defined as enums with a single value. This is useful
* for cases where constant values are not supported, such as OpenAPI.
*/
private constAsEnum: boolean;

/**
* Types are assigned names which are looked up by their IDs. This is the
* map from type IDs to type names.
Expand All @@ -511,6 +519,7 @@ export class JsonSchemaGenerator {
this.inheritingTypes = inheritingTypes;
this.tc = tc;
this.userValidationKeywords = args.validationKeywords.reduce((acc, word) => ({ ...acc, [word]: true }), {});
this.constAsEnum = args.constAsEnum;
}

public get ReffedDefinitions(): { [key: string]: Definition } {
Expand Down Expand Up @@ -709,7 +718,11 @@ export class JsonSchemaGenerator {
default:
throw new Error(`Not supported: ${value} as a enum value`);
}
definition.const = value;
if (this.constAsEnum) {
definition.enum = [value];
} else {
definition.const = value;
}
} else if (arrayType !== undefined) {
if (
propertyType.flags & ts.TypeFlags.Object &&
Expand Down

0 comments on commit a9bb215

Please sign in to comment.