@tsed/schema 8.13.5 → 8.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/components/default/anyMapper.js +1 -2
- package/lib/esm/components/default/classMapper.js +2 -22
- package/lib/esm/components/default/genericsMapper.js +62 -48
- package/lib/esm/components/default/lazyRefMapper.js +1 -2
- package/lib/esm/components/default/mapMapper.js +0 -2
- package/lib/esm/components/default/nextMapper.js +74 -0
- package/lib/esm/components/default/objectMapper.js +8 -3
- package/lib/esm/components/default/ofMapper.js +2 -5
- package/lib/esm/components/default/requiredMapper.js +2 -2
- package/lib/esm/components/default/schemaMapper.js +6 -7
- package/lib/esm/components/index.js +1 -7
- package/lib/esm/components/open-spec/nullableMapper.js +5 -1
- package/lib/esm/components/open-spec/operationInParameterMapper.js +3 -7
- package/lib/esm/components/open-spec/operationInQueryMapper.js +22 -17
- package/lib/esm/components/open-spec/operationMediaMapper.js +5 -2
- package/lib/esm/components/open-spec/operationRequestBodyMapper.js +2 -2
- package/lib/esm/constants/VendorKeys.js +11 -0
- package/lib/esm/decorators/collections/collectionOf.js +14 -3
- package/lib/esm/decorators/common/description.js +9 -12
- package/lib/esm/decorators/common/discriminatorKey.js +1 -1
- package/lib/esm/decorators/common/forwardGroups.js +1 -1
- package/lib/esm/decorators/common/groups.js +15 -26
- package/lib/esm/decorators/common/oneOf.js +1 -1
- package/lib/esm/decorators/generics/genericOf.js +8 -17
- package/lib/esm/decorators/generics/generics.js +3 -3
- package/lib/esm/decorators/operations/redirect.js +1 -1
- package/lib/esm/decorators/operations/returns.js +40 -63
- package/lib/esm/domain/JsonEntityStore.js +40 -41
- package/lib/esm/domain/JsonMedia.js +27 -6
- package/lib/esm/domain/JsonMethodStore.js +28 -9
- package/lib/esm/domain/JsonOperation.js +15 -0
- package/lib/esm/domain/JsonParameter.js +11 -10
- package/lib/esm/domain/JsonParameterStore.js +3 -9
- package/lib/esm/domain/JsonPropertyStore.js +14 -45
- package/lib/esm/domain/JsonSchema.js +287 -80
- package/lib/esm/fn/email.js +2 -2
- package/lib/esm/fn/uri.js +2 -2
- package/lib/esm/fn/url.js +2 -2
- package/lib/esm/index.js +3 -8
- package/lib/esm/utils/generics.js +3 -32
- package/lib/esm/utils/getJsonSchema.js +24 -17
- package/lib/esm/utils/mergeSchema.js +98 -0
- package/lib/esm/utils/ref.js +14 -13
- package/lib/types/components/default/classMapper.d.ts +1 -1
- package/lib/types/components/default/genericsMapper.d.ts +9 -2
- package/lib/types/components/default/lazyRefMapper.d.ts +1 -1
- package/lib/types/components/default/nextMapper.d.ts +5 -0
- package/lib/types/components/default/ofMapper.d.ts +1 -1
- package/lib/types/components/index.d.ts +1 -7
- package/lib/types/components/open-spec/nullableMapper.d.ts +2 -1
- package/lib/types/components/open-spec/operationInQueryMapper.d.ts +1 -1
- package/lib/types/constants/VendorKeys.d.ts +10 -0
- package/lib/types/decorators/collections/collectionOf.d.ts +1 -1
- package/lib/types/decorators/generics/genericOf.d.ts +3 -0
- package/lib/types/decorators/generics/generics.d.ts +2 -2
- package/lib/types/decorators/operations/returns.d.ts +11 -9
- package/lib/types/domain/JsonEntityStore.d.ts +20 -18
- package/lib/types/domain/JsonMedia.d.ts +4 -5
- package/lib/types/domain/JsonMethodStore.d.ts +9 -2
- package/lib/types/domain/JsonOperation.d.ts +1 -0
- package/lib/types/domain/JsonParameter.d.ts +2 -7
- package/lib/types/domain/JsonParameterStore.d.ts +0 -2
- package/lib/types/domain/JsonPropertyStore.d.ts +1 -20
- package/lib/types/domain/JsonSchema.d.ts +82 -39
- package/lib/types/index.d.ts +3 -8
- package/lib/types/interfaces/JsonSchemaOptions.d.ts +16 -2
- package/lib/types/utils/generics.d.ts +7 -48
- package/lib/types/utils/getJsonSchema.d.ts +2 -1
- package/lib/types/utils/mergeSchema.d.ts +2 -0
- package/lib/types/utils/ref.d.ts +4 -2
- package/package.json +7 -7
- package/lib/esm/components/async-api/channelsMapper.js +0 -57
- package/lib/esm/components/async-api/generate.js +0 -17
- package/lib/esm/components/async-api/messageMapper.js +0 -39
- package/lib/esm/components/async-api/payloadMapper.js +0 -47
- package/lib/esm/components/async-api/responseMapper.js +0 -53
- package/lib/esm/components/default/itemMapper.js +0 -5
- package/lib/esm/components/default/propertiesMapper.js +0 -20
- package/lib/esm/utils/somethingOf.js +0 -11
- package/lib/types/components/async-api/channelsMapper.d.ts +0 -2
- package/lib/types/components/async-api/generate.d.ts +0 -1
- package/lib/types/components/async-api/messageMapper.d.ts +0 -6
- package/lib/types/components/async-api/payloadMapper.d.ts +0 -4
- package/lib/types/components/async-api/responseMapper.d.ts +0 -6
- package/lib/types/components/default/itemMapper.d.ts +0 -2
- package/lib/types/components/default/propertiesMapper.d.ts +0 -3
- package/lib/types/utils/somethingOf.d.ts +0 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { JsonLazyRef } from "../../domain/JsonLazyRef.js";
|
|
2
2
|
import { JsonSchema } from "../../domain/JsonSchema.js";
|
|
3
3
|
import { execMapper, execOneOfMapper, registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
4
|
-
import { mapGenericsOptions } from "../../utils/generics.js";
|
|
5
4
|
import { toRef } from "../../utils/ref.js";
|
|
6
5
|
export function anyMapper(input, options = {}) {
|
|
7
6
|
if (typeof input !== "object" || input === null) {
|
|
@@ -16,7 +15,7 @@ export function anyMapper(input, options = {}) {
|
|
|
16
15
|
}
|
|
17
16
|
if (input.$kind && input.$isJsonDocument) {
|
|
18
17
|
const kind = execOneOfMapper([input.$kind, "map"], options);
|
|
19
|
-
const schema = execMapper(kind, [input],
|
|
18
|
+
const schema = execMapper(kind, [input], options);
|
|
20
19
|
return input.canRef ? toRef(input, schema, options) : schema;
|
|
21
20
|
}
|
|
22
21
|
return execMapper("object", [input], options);
|
|
@@ -1,37 +1,17 @@
|
|
|
1
1
|
import { getValue, setValue } from "@tsed/core";
|
|
2
2
|
import { JsonEntityStore } from "../../domain/JsonEntityStore.js";
|
|
3
3
|
import { execMapper, registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
4
|
-
import { mapGenericsOptions, popGenerics } from "../../utils/generics.js";
|
|
5
4
|
import { createRef, createRefName } from "../../utils/ref.js";
|
|
6
5
|
export function classMapper(value, options) {
|
|
7
6
|
const store = JsonEntityStore.from(value.class);
|
|
8
7
|
const name = createRefName(store.schema.getName() || value.getName(), options);
|
|
9
|
-
if (value.hasGenerics) {
|
|
10
|
-
// Inline generic
|
|
11
|
-
const { type, properties, additionalProperties, items, ...props } = value.toJSON(options);
|
|
12
|
-
const schema = {
|
|
13
|
-
...execMapper("any", [store.schema], {
|
|
14
|
-
...options,
|
|
15
|
-
...popGenerics(value),
|
|
16
|
-
root: false
|
|
17
|
-
}),
|
|
18
|
-
...props
|
|
19
|
-
};
|
|
20
|
-
if (schema.title) {
|
|
21
|
-
const name = createRefName(schema.title, options);
|
|
22
|
-
setValue(options.components, `schemas.${name}`, schema);
|
|
23
|
-
delete schema.title;
|
|
24
|
-
return createRef(name, value, options);
|
|
25
|
-
}
|
|
26
|
-
return schema;
|
|
27
|
-
}
|
|
28
8
|
if (!getValue(options, `components.schemas.${name}`)) {
|
|
29
9
|
// avoid infinite calls
|
|
30
10
|
setValue(options, `components.schemas.${name}`, {});
|
|
31
|
-
options.components.schemas[name] = execMapper("any", [store.schema],
|
|
11
|
+
options.components.schemas[name] = execMapper("any", [store.schema], {
|
|
32
12
|
...options,
|
|
33
13
|
root: false
|
|
34
|
-
})
|
|
14
|
+
});
|
|
35
15
|
}
|
|
36
16
|
return createRef(name, value, options);
|
|
37
17
|
}
|
|
@@ -1,57 +1,71 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isObject } from "@tsed/core";
|
|
2
|
+
import { VendorKeys } from "../../constants/VendorKeys.js";
|
|
3
|
+
import { JsonSchema } from "../../domain/JsonSchema.js";
|
|
3
4
|
import { execMapper, registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
5
|
+
import { toRef } from "../../utils/ref.js";
|
|
6
|
+
function getNestedSchema(propertyKey, schema, options) {
|
|
7
|
+
if ("isLazyRef" in schema) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
if (schema.isGeneric) {
|
|
11
|
+
const genericLabel = schema.get(VendorKeys.GENERIC_LABEL);
|
|
12
|
+
const genericValue = options.generics?.[genericLabel];
|
|
13
|
+
if (!genericValue) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const [model, next] = genericValue;
|
|
17
|
+
const refSchema = JsonSchema.from(model);
|
|
18
|
+
const modelSchema = execMapper("schema", [refSchema], {
|
|
19
|
+
...options,
|
|
20
|
+
generics: next
|
|
21
|
+
});
|
|
22
|
+
if (next || !refSchema.isClass) {
|
|
23
|
+
return modelSchema;
|
|
24
|
+
}
|
|
25
|
+
return toRef(refSchema, modelSchema, options);
|
|
26
|
+
}
|
|
27
|
+
if (schema?.has("items")) {
|
|
28
|
+
const nestedSchema = getNestedSchema(propertyKey, schema.get("items"), options);
|
|
29
|
+
if (nestedSchema) {
|
|
30
|
+
return {
|
|
31
|
+
type: "array",
|
|
32
|
+
items: nestedSchema
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (schema.has("additionalProperties") && isObject(schema.get("additionalProperties"))) {
|
|
37
|
+
const nestedSchema = getNestedSchema(propertyKey, schema.get("additionalProperties"), options);
|
|
38
|
+
if (nestedSchema) {
|
|
39
|
+
return {
|
|
40
|
+
type: "object",
|
|
41
|
+
additionalProperties: nestedSchema
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
6
47
|
/**
|
|
7
48
|
* @ignore
|
|
8
49
|
*/
|
|
9
|
-
export function genericsMapper(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
if (type === Date) {
|
|
20
|
-
return {
|
|
21
|
-
type: "string",
|
|
22
|
-
format: "date-time"
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
if (type.toJSON) {
|
|
26
|
-
return type.toJSON({
|
|
27
|
-
...options,
|
|
28
|
-
generics: undefined
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
if (type === Object) {
|
|
32
|
-
return {
|
|
33
|
-
type: "object"
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
if (isClass(type)) {
|
|
37
|
-
const model = {
|
|
38
|
-
class: type
|
|
39
|
-
};
|
|
40
|
-
if (options.nestedGenerics.length === 0) {
|
|
41
|
-
return execMapper("class", [model], {
|
|
42
|
-
...options,
|
|
43
|
-
generics: undefined
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
const store = JsonEntityStore.from(model.class);
|
|
47
|
-
return execMapper("schema", [store.schema], {
|
|
48
|
-
...options,
|
|
49
|
-
...popGenerics(options),
|
|
50
|
-
root: false
|
|
51
|
-
});
|
|
50
|
+
export function genericsMapper(baseObj, schema, options) {
|
|
51
|
+
if (schema.genericLabels?.length && schema.has("properties")) {
|
|
52
|
+
const properties = schema.get("properties");
|
|
53
|
+
let hasProps = false;
|
|
54
|
+
const additionalObj = Object.entries(properties || {}).reduce((obj, [propertyKey, jsonSchema]) => {
|
|
55
|
+
const nestedSchema = getNestedSchema(propertyKey, jsonSchema, options);
|
|
56
|
+
if (nestedSchema) {
|
|
57
|
+
obj[propertyKey] = nestedSchema;
|
|
58
|
+
hasProps = true;
|
|
52
59
|
}
|
|
60
|
+
return obj;
|
|
61
|
+
}, {});
|
|
62
|
+
if (hasProps) {
|
|
63
|
+
return {
|
|
64
|
+
allOf: [toRef(schema, baseObj, options), { properties: additionalObj, type: "object" }]
|
|
65
|
+
};
|
|
53
66
|
}
|
|
67
|
+
return baseObj;
|
|
54
68
|
}
|
|
55
|
-
return
|
|
69
|
+
return baseObj;
|
|
56
70
|
}
|
|
57
71
|
registerJsonSchemaMapper("generics", genericsMapper);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { execMapper, registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
2
|
-
import { mapGenericsOptions } from "../../utils/generics.js";
|
|
3
2
|
import { createRef, toRef } from "../../utils/ref.js";
|
|
4
3
|
export function lazyRefMapper(jsonLazyRef, options) {
|
|
5
4
|
const name = jsonLazyRef.name;
|
|
@@ -7,7 +6,7 @@ export function lazyRefMapper(jsonLazyRef, options) {
|
|
|
7
6
|
return createRef(name, jsonLazyRef.schema, options);
|
|
8
7
|
}
|
|
9
8
|
options.$refs = [...(options.$refs || []), jsonLazyRef.target];
|
|
10
|
-
const schema = jsonLazyRef.getType() && execMapper("schema", [jsonLazyRef.schema],
|
|
9
|
+
const schema = jsonLazyRef.getType() && execMapper("schema", [jsonLazyRef.schema], options);
|
|
11
10
|
return toRef(jsonLazyRef.schema, schema, options);
|
|
12
11
|
}
|
|
13
12
|
registerJsonSchemaMapper("lazyRef", lazyRefMapper);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { execMapper, registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
2
|
-
import { mapGenericsOptions } from "../../utils/generics.js";
|
|
3
2
|
/**
|
|
4
3
|
* Serialize class which inherit from Map like JsonMap, JsonOperation, JsonParameter.
|
|
5
4
|
* @param input
|
|
@@ -8,7 +7,6 @@ import { mapGenericsOptions } from "../../utils/generics.js";
|
|
|
8
7
|
* @ignore
|
|
9
8
|
*/
|
|
10
9
|
export function mapMapper(input, { ignore = [], ...options } = {}) {
|
|
11
|
-
options = mapGenericsOptions(options);
|
|
12
10
|
return Array.from(input.entries()).reduce((obj, [key, value]) => {
|
|
13
11
|
if (ignore.includes(key)) {
|
|
14
12
|
return obj;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { JsonSchema } from "../../domain/JsonSchema.js";
|
|
2
|
+
import { execMapper, registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
3
|
+
import { getGenericsOptions } from "../../utils/generics.js";
|
|
4
|
+
import { mergeSchema } from "../../utils/mergeSchema.js";
|
|
5
|
+
function getMapper(input, mapper, root) {
|
|
6
|
+
if (input.isClass && !input.isLocalSchema && !root) {
|
|
7
|
+
return mapper || "class";
|
|
8
|
+
}
|
|
9
|
+
return "any";
|
|
10
|
+
}
|
|
11
|
+
function buildAndMergeSchemas(mapper, schema1, schema2, options) {
|
|
12
|
+
const schema = execMapper(getMapper(schema2, mapper, options.root), [schema2], {
|
|
13
|
+
...options,
|
|
14
|
+
root: false,
|
|
15
|
+
mapper: mapper === "next" ? options.mapper : undefined
|
|
16
|
+
});
|
|
17
|
+
let extraSchema = execMapper(options.root ? "any" : mapper, [schema1], {
|
|
18
|
+
...options,
|
|
19
|
+
root: false,
|
|
20
|
+
generics: undefined,
|
|
21
|
+
mapper: mapper === "next" ? options.mapper : undefined
|
|
22
|
+
});
|
|
23
|
+
if ((schema.$ref || schema.allOf) && extraSchema.type && Object.keys(extraSchema).length === 1) {
|
|
24
|
+
extraSchema = {};
|
|
25
|
+
}
|
|
26
|
+
if (schema1.canRef) {
|
|
27
|
+
const name = extraSchema.$ref.split("/").pop();
|
|
28
|
+
const titleSchema = options.components.schemas[name];
|
|
29
|
+
options.components.schemas[name] = mergeSchema(schema, titleSchema);
|
|
30
|
+
return extraSchema;
|
|
31
|
+
}
|
|
32
|
+
return mergeSchema(schema, extraSchema);
|
|
33
|
+
}
|
|
34
|
+
export function itemMapper(input, options) {
|
|
35
|
+
if (input && input instanceof JsonSchema) {
|
|
36
|
+
if (!input.isCollection && input?.itemSchema?.()) {
|
|
37
|
+
const { generics, mapper } = getGenericsOptions(input, options);
|
|
38
|
+
const schema1 = input;
|
|
39
|
+
const schema2 = input.itemSchema();
|
|
40
|
+
return buildAndMergeSchemas("next", schema1, schema2, { ...options, generics, mapper });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return execMapper("next", [input], options);
|
|
44
|
+
}
|
|
45
|
+
export function nextMapper(input, options) {
|
|
46
|
+
if (input && input instanceof JsonSchema && !input.isLocalSchema) {
|
|
47
|
+
const refSchema = input.getRefSchema();
|
|
48
|
+
if (refSchema) {
|
|
49
|
+
let { generics, mapper } = getGenericsOptions(input, options);
|
|
50
|
+
mapper = getMapper(input, mapper);
|
|
51
|
+
return buildAndMergeSchemas(mapper, input, refSchema, {
|
|
52
|
+
...options,
|
|
53
|
+
generics
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return execMapper(getMapper(input, options.mapper), [input], {
|
|
58
|
+
...options,
|
|
59
|
+
root: false,
|
|
60
|
+
mapper: undefined
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
registerJsonSchemaMapper("item", itemMapper);
|
|
64
|
+
registerJsonSchemaMapper("next", nextMapper);
|
|
65
|
+
registerJsonSchemaMapper("properties", nextMapper);
|
|
66
|
+
registerJsonSchemaMapper("items", nextMapper);
|
|
67
|
+
registerJsonSchemaMapper("additionalProperties", nextMapper);
|
|
68
|
+
registerJsonSchemaMapper("propertyNames", nextMapper);
|
|
69
|
+
registerJsonSchemaMapper("contains", nextMapper);
|
|
70
|
+
registerJsonSchemaMapper("dependencies", nextMapper);
|
|
71
|
+
registerJsonSchemaMapper("patternProperties", nextMapper);
|
|
72
|
+
registerJsonSchemaMapper("additionalItems", nextMapper);
|
|
73
|
+
registerJsonSchemaMapper("not", nextMapper);
|
|
74
|
+
registerJsonSchemaMapper("definitions", nextMapper);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isArray } from "@tsed/core";
|
|
2
|
+
import { VendorKeys } from "../../constants/VendorKeys.js";
|
|
2
3
|
import { alterIgnore } from "../../hooks/alterIgnore.js";
|
|
3
4
|
import { execMapper, registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
4
5
|
/**
|
|
@@ -8,16 +9,20 @@ import { execMapper, registerJsonSchemaMapper } from "../../registries/JsonSchem
|
|
|
8
9
|
* @ignore
|
|
9
10
|
*/
|
|
10
11
|
export function objectMapper(input, options) {
|
|
11
|
-
const { specType, operationIdFormatter, root, components,
|
|
12
|
+
const { specType, operationIdFormatter, root, components, useAlias, ...ctx } = options;
|
|
12
13
|
return Object.entries(input).reduce((obj, [key, value]) => {
|
|
13
14
|
if (options.withIgnoredProps !== false && !alterIgnore(value, ctx)) {
|
|
14
15
|
const opts = {
|
|
15
16
|
...options,
|
|
16
|
-
|
|
17
|
+
parent: value,
|
|
18
|
+
groups: input?.get?.(VendorKeys.FORWARD_GROUPS) || value?.get?.(VendorKeys.FORWARD_GROUPS) ? options.groups : undefined
|
|
17
19
|
};
|
|
18
|
-
// remove groups to avoid bad schema generation over children models
|
|
19
20
|
obj[key] = execMapper("item", [value], opts);
|
|
20
21
|
obj[key] = execMapper("nullable", [obj[key], value], opts);
|
|
22
|
+
if (value.isGeneric && obj[key]?.type) {
|
|
23
|
+
const { type, ...rest } = obj[key];
|
|
24
|
+
obj[key] = rest;
|
|
25
|
+
}
|
|
21
26
|
}
|
|
22
27
|
return obj;
|
|
23
28
|
}, isArray(input) ? [] : {});
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { execMapper, registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
2
|
-
export function ofMapper(input, options
|
|
2
|
+
export function ofMapper(input, options) {
|
|
3
3
|
return input.map((value) => {
|
|
4
|
-
return execMapper("item", [value],
|
|
5
|
-
...options,
|
|
6
|
-
genericLabels: parent.genericLabels
|
|
7
|
-
});
|
|
4
|
+
return execMapper("item", [value], options);
|
|
8
5
|
});
|
|
9
6
|
}
|
|
10
7
|
registerJsonSchemaMapper("anyOf", ofMapper);
|
|
@@ -14,7 +14,7 @@ function mapRequiredProps(obj, schema, options = {}) {
|
|
|
14
14
|
}
|
|
15
15
|
function extractRequiredProps(obj, schema, options) {
|
|
16
16
|
let required = obj.required || [];
|
|
17
|
-
required = [...required, ...schema
|
|
17
|
+
required = [...required, ...schema.getRequiredFields()];
|
|
18
18
|
if (schema.get("properties")) {
|
|
19
19
|
required = Object.entries(schema.get("properties")).reduce((required, [key, prop]) => {
|
|
20
20
|
if (prop && prop.$selfRequired !== undefined) {
|
|
@@ -26,7 +26,7 @@ function extractRequiredProps(obj, schema, options) {
|
|
|
26
26
|
return alterRequiredGroups(uniq(required), schema, options);
|
|
27
27
|
}
|
|
28
28
|
export function requiredMapper(obj, schema, options) {
|
|
29
|
-
if (options.groups && options.groups
|
|
29
|
+
if (options.groups && options.groups?.includes("partial")) {
|
|
30
30
|
if (obj.discriminator) {
|
|
31
31
|
return {
|
|
32
32
|
...obj,
|
|
@@ -13,6 +13,7 @@ const IGNORES = ["name", "$required", "$hooks", "_nestedGenerics", SpecTypes.OPE
|
|
|
13
13
|
const IGNORES_OPENSPEC = [];
|
|
14
14
|
/**
|
|
15
15
|
* @ignore
|
|
16
|
+
* TODO check if we can remove this
|
|
16
17
|
*/
|
|
17
18
|
function isEmptyProperties(key, value) {
|
|
18
19
|
return typeof value === "object" && ["items", "properties", "additionalProperties"].includes(key) && Object.keys(value).length === 0;
|
|
@@ -28,7 +29,8 @@ function shouldMapAlias(key, value, useAlias) {
|
|
|
28
29
|
*/
|
|
29
30
|
function shouldSkipKey(key, { specType = SpecTypes.JSON, customKeys = false }) {
|
|
30
31
|
return (IGNORES.includes(key) ||
|
|
31
|
-
|
|
32
|
+
key.startsWith("x-") ||
|
|
33
|
+
(key.startsWith("#") && (!customKeys || specType !== SpecTypes.JSON)) ||
|
|
32
34
|
(specType !== SpecTypes.JSON && IGNORES_OPENSPEC.includes(key)));
|
|
33
35
|
}
|
|
34
36
|
function isExample(key, value, options) {
|
|
@@ -81,17 +83,13 @@ function mapKeys(schema, options) {
|
|
|
81
83
|
}
|
|
82
84
|
function serializeSchema(schema, options) {
|
|
83
85
|
let obj = mapKeys(schema, options);
|
|
84
|
-
if (schema.isClass) {
|
|
86
|
+
if (schema.isClass && !schema.isLocalSchema) {
|
|
85
87
|
obj = execMapper("inheritedClass", [obj], {
|
|
86
88
|
...options,
|
|
87
89
|
root: false,
|
|
88
|
-
target: schema.
|
|
90
|
+
target: schema.class
|
|
89
91
|
});
|
|
90
92
|
}
|
|
91
|
-
obj = execMapper("generics", [obj], {
|
|
92
|
-
...options,
|
|
93
|
-
root: false
|
|
94
|
-
});
|
|
95
93
|
if (schema.has(options.specType)) {
|
|
96
94
|
obj = {
|
|
97
95
|
...obj,
|
|
@@ -106,6 +104,7 @@ function serializeSchema(schema, options) {
|
|
|
106
104
|
obj = alterOneOf(obj, schema, options);
|
|
107
105
|
obj = execMapper("enums", [obj, schema], options);
|
|
108
106
|
obj = execMapper("discriminatorMapping", [obj, schema], options);
|
|
107
|
+
obj = execMapper("generics", [obj, schema], options);
|
|
109
108
|
return obj;
|
|
110
109
|
}
|
|
111
110
|
export function schemaMapper(schema, opts) {
|
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file Automatically generated by @tsed/barrels.
|
|
3
3
|
*/
|
|
4
|
-
export * from "./async-api/channelsMapper.js";
|
|
5
|
-
export * from "./async-api/generate.js";
|
|
6
|
-
export * from "./async-api/messageMapper.js";
|
|
7
|
-
export * from "./async-api/payloadMapper.js";
|
|
8
|
-
export * from "./async-api/responseMapper.js";
|
|
9
4
|
export * from "./default/anyMapper.js";
|
|
10
5
|
export * from "./default/classMapper.js";
|
|
11
6
|
export * from "./default/discriminatorMappingMapper.js";
|
|
12
7
|
export * from "./default/enumsMapper.js";
|
|
13
8
|
export * from "./default/genericsMapper.js";
|
|
14
9
|
export * from "./default/inheritedClassMapper.js";
|
|
15
|
-
export * from "./default/itemMapper.js";
|
|
16
10
|
export * from "./default/lazyRefMapper.js";
|
|
17
11
|
export * from "./default/mapMapper.js";
|
|
12
|
+
export * from "./default/nextMapper.js";
|
|
18
13
|
export * from "./default/nullableMapper.js";
|
|
19
14
|
export * from "./default/objectMapper.js";
|
|
20
15
|
export * from "./default/ofMapper.js";
|
|
21
|
-
export * from "./default/propertiesMapper.js";
|
|
22
16
|
export * from "./default/requiredMapper.js";
|
|
23
17
|
export * from "./default/schemaMapper.js";
|
|
24
18
|
export * from "./open-spec/discriminatorMappingMapper.js";
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { cleanObject } from "@tsed/core";
|
|
2
2
|
import { SpecTypes } from "../../domain/SpecTypes.js";
|
|
3
3
|
import { registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
4
|
-
|
|
4
|
+
import { nullableMapper } from "../default/nullableMapper.js";
|
|
5
|
+
export function nullableMapperOpenApi(obj, schema, options) {
|
|
5
6
|
if (!schema?.isNullable) {
|
|
6
7
|
return obj;
|
|
7
8
|
}
|
|
9
|
+
if (options.specVersion === "3.1.0") {
|
|
10
|
+
return nullableMapper(obj, schema);
|
|
11
|
+
}
|
|
8
12
|
if (obj.$ref) {
|
|
9
13
|
return cleanObject({
|
|
10
14
|
...obj,
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
import { camelCase } from "change-case";
|
|
2
2
|
import { JsonParameterTypes } from "../../domain/JsonParameterTypes.js";
|
|
3
3
|
import { execMapper, hasMapper, registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
4
|
-
import { popGenerics } from "../../utils/generics.js";
|
|
5
4
|
function mapOptions(parameter, options = {}) {
|
|
6
5
|
return {
|
|
7
6
|
...options,
|
|
8
|
-
groups: parameter.
|
|
9
|
-
groupsName: parameter.
|
|
7
|
+
groups: parameter.schema().getGroups(),
|
|
8
|
+
groupsName: parameter.schema().getGroupsName()
|
|
10
9
|
};
|
|
11
10
|
}
|
|
12
11
|
export function operationInParameterMapper(jsonParameter, opts) {
|
|
13
12
|
const options = mapOptions(jsonParameter, opts);
|
|
14
13
|
const schemas = { ...(options.components?.schemas || {}) };
|
|
15
14
|
const { type, schema, ...parameter } = execMapper("map", [jsonParameter], options);
|
|
16
|
-
const jsonSchema = execMapper("item", [jsonParameter
|
|
17
|
-
...options,
|
|
18
|
-
...popGenerics(jsonParameter)
|
|
19
|
-
});
|
|
15
|
+
const jsonSchema = execMapper("item", [jsonParameter.schema()], options);
|
|
20
16
|
parameter.required = parameter.required || jsonParameter.get("in") === JsonParameterTypes.PATH;
|
|
21
17
|
const paramOpts = {
|
|
22
18
|
...options,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cleanObject } from "@tsed/core";
|
|
2
2
|
import { registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
3
|
-
import { createRefName } from "../../utils/ref.js";
|
|
3
|
+
import { createRefName, getSchemaFromRef } from "../../utils/ref.js";
|
|
4
4
|
function buildExamples(property, examples) {
|
|
5
5
|
if (!examples) {
|
|
6
6
|
return undefined;
|
|
@@ -23,32 +23,37 @@ function buildExamples(property, examples) {
|
|
|
23
23
|
return hasKey ? newExamples : undefined;
|
|
24
24
|
}
|
|
25
25
|
function inlineReference(parameter, { jsonParameter, ...options }) {
|
|
26
|
-
const name = createRefName(jsonParameter
|
|
26
|
+
const name = createRefName(jsonParameter.schema().itemSchema().getName(), options);
|
|
27
27
|
const schema = options.components?.schemas?.[name];
|
|
28
28
|
if (schema && !options.oldSchemas?.[name]) {
|
|
29
|
-
delete options.components
|
|
29
|
+
delete options.components?.schemas?.[jsonParameter.schema().itemSchema().getName()];
|
|
30
30
|
}
|
|
31
31
|
return Object.entries(schema?.properties || {}).reduce((params, [key, { description, ...prop }]) => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
32
|
+
const style = parameter.style || (prop.$ref && !getSchemaFromRef(prop.$ref, options)?.enum) ? "deepObject" : undefined;
|
|
33
|
+
params.push(cleanObject({
|
|
34
|
+
...parameter,
|
|
35
|
+
style,
|
|
36
|
+
explode: style === "deepObject" ? true : parameter.explode,
|
|
37
|
+
name: key,
|
|
38
|
+
required: (schema?.required || []).includes(key),
|
|
39
|
+
description,
|
|
40
|
+
schema: prop,
|
|
41
|
+
examples: buildExamples(key, parameter.examples)
|
|
42
|
+
}));
|
|
43
|
+
return params;
|
|
44
44
|
}, []);
|
|
45
45
|
}
|
|
46
|
-
export function operationInQueryMapper(parameter, { jsonSchema,
|
|
46
|
+
export function operationInQueryMapper(parameter, { jsonSchema, ...options }) {
|
|
47
47
|
if (jsonSchema.$ref) {
|
|
48
48
|
if (!parameter.name) {
|
|
49
49
|
return inlineReference(parameter, options);
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
const schema = getSchemaFromRef(jsonSchema.$ref, options);
|
|
52
|
+
// if the reference is an enum, we don't need to set the style or explode
|
|
53
|
+
if (!schema?.enum) {
|
|
54
|
+
parameter.style = "deepObject";
|
|
55
|
+
parameter.explode = true;
|
|
56
|
+
}
|
|
52
57
|
}
|
|
53
58
|
parameter.schema = jsonSchema;
|
|
54
59
|
return parameter;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { execMapper, registerJsonSchemaMapper } from "../../registries/JsonSchemaMapperContainer.js";
|
|
2
2
|
export function operationMediaMapper(jsonMedia, options) {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
return execMapper("map", [jsonMedia], {
|
|
4
|
+
...options,
|
|
5
|
+
groups: [...(jsonMedia.schema().getGroups() || [])],
|
|
6
|
+
groupsName: jsonMedia.schema().getGroupsName()
|
|
7
|
+
});
|
|
5
8
|
}
|
|
6
9
|
registerJsonSchemaMapper("operationMedia", operationMediaMapper);
|
|
@@ -46,9 +46,9 @@ function buildSchemaFromBodyParameters(parameters, options) {
|
|
|
46
46
|
delete props.description;
|
|
47
47
|
}
|
|
48
48
|
return {
|
|
49
|
-
schema: schema.toJSON(options),
|
|
50
49
|
required: false,
|
|
51
|
-
...props
|
|
50
|
+
...props,
|
|
51
|
+
schema: schema.toJSON(options)
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
export function operationRequestBodyMapper(bodyParameters, { consumes, ...options }) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export var VendorKeys;
|
|
2
|
+
(function (VendorKeys) {
|
|
3
|
+
VendorKeys["GENERIC_LABELS"] = "genericLabels";
|
|
4
|
+
VendorKeys["GENERIC_LABEL"] = "genericLabel";
|
|
5
|
+
VendorKeys["GENERIC_OF"] = "genericOf";
|
|
6
|
+
VendorKeys["NULLABLE"] = "nullable";
|
|
7
|
+
VendorKeys["FORWARD_GROUPS"] = "forwardGroups";
|
|
8
|
+
VendorKeys["GROUPS"] = "groups";
|
|
9
|
+
VendorKeys["GROUPS_NAME"] = "groupsName";
|
|
10
|
+
VendorKeys["ALLOWED_GROUPS"] = "allowedGroups";
|
|
11
|
+
})(VendorKeys || (VendorKeys = {}));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DecoratorTypes } from "@tsed/core";
|
|
1
2
|
import { JsonEntityStore } from "../../domain/JsonEntityStore.js";
|
|
2
3
|
/**
|
|
3
4
|
* Set the type of the item collection. The possible value is String, Boolean, Number, Date, Object, Class, etc...
|
|
@@ -37,6 +38,7 @@ export function CollectionOf(type, collectionType) {
|
|
|
37
38
|
}
|
|
38
39
|
const schema = {};
|
|
39
40
|
let contains = false;
|
|
41
|
+
const nestedGenerics = [];
|
|
40
42
|
const decorator = (...args) => {
|
|
41
43
|
const store = JsonEntityStore.from(...args);
|
|
42
44
|
if (collectionType) {
|
|
@@ -46,6 +48,14 @@ export function CollectionOf(type, collectionType) {
|
|
|
46
48
|
store.type = type;
|
|
47
49
|
store.itemSchema.type(type);
|
|
48
50
|
store.schema.assign(schema);
|
|
51
|
+
if (nestedGenerics.length) {
|
|
52
|
+
if (store.is(DecoratorTypes.PARAM)) {
|
|
53
|
+
store.parameter.itemSchema().genericOf(...nestedGenerics);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
store.itemSchema.genericOf(...nestedGenerics);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
49
59
|
if (store.isArray && contains) {
|
|
50
60
|
store.schema.set("contains", store.schema.get("items"));
|
|
51
61
|
store.schema.delete("items");
|
|
@@ -79,9 +89,6 @@ export function CollectionOf(type, collectionType) {
|
|
|
79
89
|
schema.maxProperties = maxProperties;
|
|
80
90
|
return decorator;
|
|
81
91
|
};
|
|
82
|
-
/**
|
|
83
|
-
* @deprecated Since 2025-05-12. Use Contains decorator instead.
|
|
84
|
-
*/
|
|
85
92
|
decorator.Contains = () => {
|
|
86
93
|
contains = true;
|
|
87
94
|
return decorator;
|
|
@@ -93,6 +100,10 @@ export function CollectionOf(type, collectionType) {
|
|
|
93
100
|
schema.uniqueItems = uniqueItems;
|
|
94
101
|
return decorator;
|
|
95
102
|
};
|
|
103
|
+
decorator.Nested = (...generics) => {
|
|
104
|
+
nestedGenerics.push(generics);
|
|
105
|
+
return decorator;
|
|
106
|
+
};
|
|
96
107
|
return decorator;
|
|
97
108
|
}
|
|
98
109
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DecoratorTypes } from "@tsed/core";
|
|
2
2
|
import { JsonEntityFn } from "./jsonEntityFn.js";
|
|
3
3
|
/**
|
|
4
4
|
* Add a description to the class, method or property
|
|
@@ -54,17 +54,14 @@ import { JsonEntityFn } from "./jsonEntityFn.js";
|
|
|
54
54
|
*/
|
|
55
55
|
export function Description(description) {
|
|
56
56
|
return JsonEntityFn((store, args) => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
case DecoratorTypes.METHOD:
|
|
66
|
-
store.operation?.description(description);
|
|
67
|
-
break;
|
|
57
|
+
if (store.is(DecoratorTypes.PROP) || store.is(DecoratorTypes.CLASS)) {
|
|
58
|
+
store.schema.description(description);
|
|
59
|
+
}
|
|
60
|
+
else if (store.is(DecoratorTypes.PARAM)) {
|
|
61
|
+
store.parameter.description(description);
|
|
62
|
+
}
|
|
63
|
+
else if (store.is(DecoratorTypes.METHOD)) {
|
|
64
|
+
store.operation?.description(description);
|
|
68
65
|
}
|
|
69
66
|
});
|
|
70
67
|
}
|
|
@@ -3,6 +3,6 @@ import { JsonEntityFn } from "./jsonEntityFn.js";
|
|
|
3
3
|
import { Property } from "./property.js";
|
|
4
4
|
export function DiscriminatorKey() {
|
|
5
5
|
return useDecorators(Property(), JsonEntityFn((store) => {
|
|
6
|
-
store.discriminatorKey();
|
|
6
|
+
store.parent.schema.discriminatorKey(String(store.propertyKey));
|
|
7
7
|
}));
|
|
8
8
|
}
|