Skip to content

Commit 5413eaa

Browse files
committed
fix(schema): fix schema error when enums() is used with a mongoose schema
1 parent 7f12225 commit 5413eaa

File tree

8 files changed

+116
-4
lines changed

8 files changed

+116
-4
lines changed

packages/orm/mongoose/src/utils/createSchema.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {cleanObject, nameOf, Store, Type} from "@tsed/core";
22
import {deserialize, serialize} from "@tsed/json-mapper";
3-
import {getProperties, JsonEntityStore} from "@tsed/schema";
3+
import {getProperties, JsonEntityStore, JsonSchema} from "@tsed/schema";
44
import {pascalCase} from "change-case";
55
import mongoose, {Schema, SchemaDefinition, SchemaOptions, SchemaTypeOptions} from "mongoose";
66
import {MONGOOSE_SCHEMA, MONGOOSE_SCHEMA_OPTIONS} from "../constants/constants";
@@ -170,7 +170,7 @@ export function createSchemaTypeOptions<T = any>(propEntity: JsonEntityStore): S
170170
max,
171171
minlength,
172172
maxlength,
173-
enum: jsonSchema["enum"],
173+
enum: /*jsonSchema["enum"] instanceof JsonSchema ? jsonSchema["enum"].toJSON().enum :*/ jsonSchema["enum"],
174174
default: jsonSchema["default"]
175175
};
176176
} else if (!rawMongooseSchema.ref) {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import {Model} from "@tsed/mongoose";
2+
import {CollectionOf, Default, Description, Enum, enums, getJsonSchema, MaxLength, MinLength, Required} from "@tsed/schema";
3+
import {TestMongooseContext} from "@tsed/testing-mongoose";
4+
5+
export enum ComponentStatuses {
6+
UNDER_MAINTENANCE = "UNDER_MAINTENANCE",
7+
DEGRADED_PERFORMANCE = "DEGRADED_PERFORMANCE",
8+
PARTIAL_OUTAGE = "PARTIAL_OUTAGE",
9+
MAJOR_OUTAGE = "MAJOR_OUTAGE"
10+
}
11+
12+
enums(ComponentStatuses).label("ComponentStatuses");
13+
14+
export class ResponseTimeThreshold {
15+
@Enum(ComponentStatuses)
16+
@Required()
17+
@Default(ComponentStatuses.MAJOR_OUTAGE)
18+
status: ComponentStatuses = ComponentStatuses.MAJOR_OUTAGE;
19+
}
20+
21+
@Model({
22+
name: "components-statuses-settings"
23+
})
24+
export class ComponentStatusSettings {
25+
@Required()
26+
@Description("The settings name")
27+
@MinLength(3)
28+
@MaxLength(100)
29+
name: string;
30+
31+
@CollectionOf(ResponseTimeThreshold)
32+
responseTimes: ResponseTimeThreshold[];
33+
}
34+
35+
describe("Enums integration", () => {
36+
beforeEach(TestMongooseContext.create);
37+
afterEach(TestMongooseContext.clearDatabase);
38+
afterEach(TestMongooseContext.reset);
39+
40+
it("should not fail when the enum is used with enums() utils", () => {
41+
expect(getJsonSchema(ComponentStatusSettings)).toEqual({
42+
definitions: {
43+
ComponentStatuses: {
44+
enum: ["UNDER_MAINTENANCE", "DEGRADED_PERFORMANCE", "PARTIAL_OUTAGE", "MAJOR_OUTAGE"],
45+
type: "string"
46+
},
47+
ResponseTimeThreshold: {
48+
properties: {
49+
status: {
50+
$ref: "#/definitions/ComponentStatuses",
51+
minLength: 1
52+
}
53+
},
54+
required: ["status"],
55+
type: "object"
56+
}
57+
},
58+
properties: {
59+
name: {
60+
description: "The settings name",
61+
maxLength: 100,
62+
minLength: 3,
63+
type: "string"
64+
},
65+
responseTimes: {
66+
items: {
67+
$ref: "#/definitions/ResponseTimeThreshold"
68+
},
69+
type: "array"
70+
}
71+
},
72+
required: ["name"],
73+
type: "object"
74+
});
75+
});
76+
});

packages/specs/schema/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module.exports = {
77
coverageThreshold: {
88
global: {
99
statements: 99.45,
10-
branches: 96.13,
10+
branches: 96.14,
1111
functions: 100,
1212
lines: 99.45
1313
}

packages/specs/schema/src/components/schemaMapper.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {JsonSchemaOptions} from "../interfaces/JsonSchemaOptions";
66
import {execMapper, hasMapper, registerJsonSchemaMapper} from "../registries/JsonSchemaMapperContainer";
77
import {getRequiredProperties} from "../utils/getRequiredProperties";
88
import {alterOneOf} from "../hooks/alterOneOf";
9+
import {inlineEnums} from "../utils/inlineEnums";
910
import {mapNullableType} from "../utils/mapNullableType";
1011

1112
/**
@@ -107,6 +108,7 @@ export function schemaMapper(schema: JsonSchema, options: JsonSchemaOptions): an
107108
obj = getRequiredProperties(obj, schema, {...options, useAlias});
108109
obj = mapNullableType(obj, schema, options);
109110
obj = alterOneOf(obj, schema, options);
111+
obj = inlineEnums(obj, schema, options);
110112

111113
return obj;
112114
}

packages/specs/schema/src/domain/JsonSchema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ export class JsonSchema extends Map<string, any> implements NestedGenerics {
934934

935935
if (!options) {
936936
addDef = true;
937-
options = {schemas: {}};
937+
options = {schemas: {}, inlineEnums: true};
938938
}
939939

940940
const schema = execMapper("schema", this, options);

packages/specs/schema/src/interfaces/JsonSchemaOptions.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,7 @@ export interface JsonSchemaOptions {
2828
*/
2929
customKeys?: boolean;
3030

31+
inlineEnums?: boolean;
32+
3133
[key: string]: any;
3234
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import {inlineEnums} from "./inlineEnums";
2+
3+
describe("inlineEnums()", () => {
4+
it("should inline enums", () => {
5+
const result = inlineEnums(
6+
{
7+
enum: {
8+
isJsonSchema: true,
9+
toJSON() {
10+
return {enum: ["type"]};
11+
}
12+
}
13+
},
14+
{} as any,
15+
{inlineEnums: true}
16+
);
17+
18+
expect(result).toEqual({
19+
enum: ["type"]
20+
});
21+
});
22+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {JsonSchema} from "../domain/JsonSchema";
2+
import {JsonSchemaOptions} from "../interfaces/JsonSchemaOptions";
3+
4+
export function inlineEnums(obj: any, schema: JsonSchema, options: JsonSchemaOptions) {
5+
if (options.inlineEnums && obj.enum?.isJsonSchema) {
6+
obj.enum = obj.enum.toJSON().enum;
7+
}
8+
9+
return obj;
10+
}

0 commit comments

Comments
 (0)