Skip to content

add constAsEnum flag to convert constant values to single value enum #571

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -539,3 +539,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