@tsed/schema 8.16.0-rc.4 → 8.16.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.
@@ -195,8 +195,7 @@ class ReturnDecoratorContext extends DecoratorContext {
195
195
  }
196
196
  }
197
197
  map() {
198
- const model = this.get("model");
199
- const { entity, decoratorType } = this;
198
+ const { decoratorType } = this;
200
199
  const operation = this.entity.operation;
201
200
  const currentStatus = this.getStatus();
202
201
  const response = operation.ensureResponseOf(currentStatus);
@@ -211,12 +210,6 @@ class ReturnDecoratorContext extends DecoratorContext {
211
210
  response.headers(headers);
212
211
  }
213
212
  this.mapMedia(response);
214
- // if (isSuccessStatus(this.get("status")) || currentStatus === "default") {
215
- // if (model) {
216
- // // TODO Check why we need that ?
217
- // // entity.type = model;
218
- // }
219
- // }
220
213
  // additional info for OS2
221
214
  contentType && operation.addProduce(contentType);
222
215
  // run additional actions
@@ -17,6 +17,12 @@ export class JsonEntityStore {
17
17
  this.store = options.store;
18
18
  this.parent = this;
19
19
  }
20
+ get collectionType() {
21
+ return this._collectionType;
22
+ }
23
+ set collectionType(value) {
24
+ this._collectionType = value;
25
+ }
20
26
  get type() {
21
27
  return this._type;
22
28
  }
@@ -44,10 +50,10 @@ export class JsonEntityStore {
44
50
  return nameOf(this.token);
45
51
  }
46
52
  get isCollection() {
47
- return !!this.collectionType;
53
+ return !!this._collectionType;
48
54
  }
49
55
  get isArray() {
50
- return isArrayOrArrayClass(this.collectionType);
56
+ return isArrayOrArrayClass(this._collectionType);
51
57
  }
52
58
  get discriminatorAncestor() {
53
59
  const ancestors = ancestorsOf(this.target);
@@ -55,7 +61,7 @@ export class JsonEntityStore {
55
61
  return ancestor && JsonEntityStore.from(ancestor);
56
62
  }
57
63
  get isPrimitive() {
58
- return isPrimitiveOrPrimitiveClass(this._type);
64
+ return isPrimitiveOrPrimitiveClass(this.type);
59
65
  }
60
66
  get isDate() {
61
67
  return isDate(this.computedType);
@@ -145,7 +151,7 @@ export class JsonEntityStore {
145
151
  }
146
152
  buildType(type) {
147
153
  if (isCollection(type)) {
148
- this.collectionType = type;
154
+ this._collectionType = type;
149
155
  }
150
156
  else if (!(type && "$schema" in type && type.$schema.skip)) {
151
157
  this._type = type;
@@ -1,6 +1,7 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
- import { DecoratorTypes, deepMerge, descriptorOf, isClass, isCollection, isFunction, isPromise, Metadata, prototypeOf, Store } from "@tsed/core";
2
+ import { DecoratorTypes, deepMerge, descriptorOf, isFunction, prototypeOf, Store } from "@tsed/core";
3
3
  import { JsonEntityComponent } from "../decorators/config/jsonEntityComponent.js";
4
+ import { isSuccessStatus } from "../utils/isSuccessStatus.js";
4
5
  import { JsonEntityStore } from "./JsonEntityStore.js";
5
6
  import { JsonOperation } from "./JsonOperation.js";
6
7
  import { JsonSchema } from "./JsonSchema.js";
@@ -49,6 +50,34 @@ let JsonMethodStore = class JsonMethodStore extends JsonEntityStore {
49
50
  get operationPaths() {
50
51
  return this.operation.operationPaths;
51
52
  }
53
+ get collectionType() {
54
+ return this.schema.getTarget();
55
+ }
56
+ set collectionType(type) {
57
+ console.trace("collectionType is deprecated, use schema.collectionClass instead");
58
+ }
59
+ get isCollection() {
60
+ return this.schema.isCollection;
61
+ }
62
+ get schema() {
63
+ if (this._schema) {
64
+ return this._schema;
65
+ }
66
+ const responses = this.operation.getResponses();
67
+ const [, response] = [...responses.entries()].find(([key, response]) => {
68
+ return isSuccessStatus(key);
69
+ }) || [];
70
+ if (response) {
71
+ const firstMediaType = response.getContent().values().next().value;
72
+ if (firstMediaType) {
73
+ this._schema = firstMediaType.schema();
74
+ }
75
+ }
76
+ else {
77
+ this._schema = new JsonSchema();
78
+ }
79
+ return this._schema;
80
+ }
52
81
  /**
53
82
  * Get an endpoint.
54
83
  * @param target
@@ -75,7 +104,7 @@ let JsonMethodStore = class JsonMethodStore extends JsonEntityStore {
75
104
  }
76
105
  return { type: media.schema().collectionClass, groups };
77
106
  }
78
- return { type: this.type };
107
+ return { type: this.type || Object };
79
108
  }
80
109
  /**
81
110
  * Append middlewares to the beforeMiddlewares list.
@@ -120,38 +149,7 @@ let JsonMethodStore = class JsonMethodStore extends JsonEntityStore {
120
149
  }), {});
121
150
  }
122
151
  build() {
123
- if (!this._type) {
124
- let type = Metadata.getReturnType(this.target, this.propertyKey);
125
- type = isPromise(type) ? undefined : type;
126
- this.buildType(type);
127
- }
128
- this._type = this._type || Object;
129
152
  this.parent.children.set(this.propertyName, this);
130
- if (isCollection(this._type)) {
131
- this.collectionType = this._type;
132
- // @ts-ignore
133
- delete this._type;
134
- }
135
- // TODO est-ce que c'est tjrs d'actualité car on doit utiliser le decorator @Returns pour affecter correctement les data
136
- // peut etre que c'est pour les get/setter ou méthod n'étant pas un endpoint?
137
- if (this.collectionType) {
138
- this._schema = JsonSchema.from({
139
- type: this.collectionType
140
- });
141
- this._schema.itemSchema(this.type);
142
- }
143
- else if (isClass(this.type)) {
144
- this._schema = JsonSchema.from({
145
- type: "object"
146
- });
147
- this._schema.itemSchema(this.type);
148
- }
149
- else {
150
- this._schema = JsonSchema.from({
151
- type: this.type
152
- });
153
- }
154
- this.parent.schema.addProperty(this.propertyName, this.schema);
155
153
  }
156
154
  };
157
155
  JsonMethodStore = __decorate([
@@ -1,4 +1,6 @@
1
- import { isObject, uniq } from "@tsed/core";
1
+ import { cleanObject } from "@tsed/core/utils/cleanObject.js";
2
+ import { isObject } from "@tsed/core/utils/isObject.js";
3
+ import { uniq } from "@tsed/core/utils/uniq.js";
2
4
  function mergeProps(properties1, properties2) {
3
5
  if (!properties1 || !properties2) {
4
6
  return properties1 || properties2 || {};
@@ -17,40 +19,58 @@ function mergeProps(properties1, properties2) {
17
19
  return acc;
18
20
  }, {});
19
21
  }
22
+ function getSchemaType(schema) {
23
+ return schema.type || (schema.items && "array") || ((schema.properties || schema.additionalProperties) && "object") || "$any";
24
+ }
20
25
  function mergeManyOf(kind, schema1, schema2) {
21
- const refs = new Set();
22
- if (schema1.$ref && schema2.type && (schema2.readOnly || schema2.writeOnly) && kind === "allOf") {
23
- const { type, ...rest } = schema2;
24
- schema2 = rest;
25
- }
26
- let of = [...(schema1[kind] || [schema1]), ...(schema2[kind] || [schema2])].filter((schema) => {
27
- if ("$ref" in schema) {
28
- if (refs.has(schema.$ref)) {
29
- return false;
30
- }
31
- refs.add(schema.$ref);
32
- return true;
26
+ const { [kind]: kind1, ...$rest1 } = schema1;
27
+ const { [kind]: kind2, ...$rest2 } = schema2;
28
+ let hasRef = false;
29
+ const map = [kind1, $rest1, kind2, $rest2]
30
+ .flat()
31
+ .filter(Boolean)
32
+ .reduce((map, schema, index) => {
33
+ schema = cleanObject(schema);
34
+ if (schema.$ref) {
35
+ hasRef = true;
36
+ return map.set(schema.$ref, schema);
37
+ }
38
+ if (Object.keys(schema).length === 0) {
39
+ return map;
33
40
  }
34
- return Object.keys(schema).length > 0;
35
- });
36
- if (of.length > 2) {
37
- of = of.reduce((current, item, index) => {
38
- if (item.$ref) {
39
- return current.concat(item);
41
+ if (schema.type === "object" && Object.keys(schema).length === 2) {
42
+ if ("writeOnly" in schema || "readOnly" in schema || "deprecated" in schema) {
43
+ schema = { ...schema, type: undefined };
40
44
  }
41
- if (current.at(-1)?.type === item.type && item.type !== "array") {
42
- current[current.length - 1] = mergeSchema(current.at(-1), item);
43
- return current;
45
+ }
46
+ const type = getSchemaType(schema);
47
+ if (type === "array") {
48
+ map.set("array_" + index, schema);
49
+ return map;
50
+ }
51
+ if (map.has(type)) {
52
+ if (kind === "allOf") {
53
+ // we can merge allOf schemas to optimize the schema
54
+ map.set(type, mergeSchema(map.get(type), schema));
55
+ return map;
44
56
  }
45
- return current.concat(item);
46
- }, []);
47
- }
48
- return of.length > 1
57
+ map.set(type + "_" + index, schema);
58
+ return map;
59
+ }
60
+ return map.set(type, schema);
61
+ }, new Map());
62
+ const rest = map.get("$any");
63
+ map.delete("$any");
64
+ const of = Array.from(map.values());
65
+ return cleanObject(of.length > 1 || (hasRef && rest)
49
66
  ? {
50
- [kind]: of,
51
- ...(schema1.nullable || schema2.nullable ? { nullable: true } : {})
67
+ ...rest,
68
+ [kind]: of
52
69
  }
53
- : of[0];
70
+ : {
71
+ ...rest,
72
+ ...of[0]
73
+ });
54
74
  }
55
75
  export function mergeSchema(schema1, schema2) {
56
76
  if (schema1.$ref && schema2.$ref && schema1.$ref === schema2.$ref) {
@@ -42,21 +42,23 @@ export declare abstract class JsonEntityStore implements JsonEntityStoreOptions
42
42
  * Decorator type used to declare the JsonSchemaStore.
43
43
  */
44
44
  readonly decoratorType: DecoratorTypes;
45
- /**
46
- * Type of the collection (Array, Map, Set, etc...)
47
- */
48
- collectionType: Type<any>;
49
45
  token: Type<any>;
50
46
  readonly store: Store;
51
47
  readonly isStore = true;
52
48
  readonly parent: JsonEntityStore;
53
49
  readonly target: Type<any>;
50
+ [key: string]: any;
54
51
  constructor(options: JsonEntityStoreOptions);
52
+ /**
53
+ * Type of the collection (Array, Map, Set, etc...)
54
+ */
55
+ private _collectionType;
56
+ get collectionType(): Type<any> | undefined;
57
+ set collectionType(value: Type<any>);
55
58
  /**
56
59
  *
57
60
  */
58
61
  protected _type: Type<any>;
59
- [key: string]: any;
60
62
  get type(): Type<any> | any;
61
63
  /**
62
64
  * Get original type without transformation
@@ -1,7 +1,7 @@
1
1
  import { OS3MediaType } from "@tsed/openspec";
2
2
  import { JsonMap } from "./JsonMap.js";
3
3
  import { JsonSchema } from "./JsonSchema.js";
4
- export declare class JsonMedia extends JsonMap<OS3MediaType<JsonSchema>> {
4
+ export declare class JsonMedia extends JsonMap<any> {
5
5
  $kind: string;
6
6
  constructor(obj?: Partial<OS3MediaType<JsonSchema>>);
7
7
  schema(schema?: JsonSchema): JsonSchema;
@@ -1,8 +1,9 @@
1
1
  import { Type } from "@tsed/core";
2
- import type { JsonClassStore } from "./JsonClassStore.js";
2
+ import { type JsonClassStore } from "./JsonClassStore.js";
3
3
  import { JsonEntityStore, JsonEntityStoreOptions } from "./JsonEntityStore.js";
4
4
  import { JsonOperation } from "./JsonOperation.js";
5
- import type { JsonParameterStore } from "./JsonParameterStore.js";
5
+ import { type JsonParameterStore } from "./JsonParameterStore.js";
6
+ import { JsonSchema } from "./JsonSchema.js";
6
7
  export interface JsonViewOptions {
7
8
  path: string;
8
9
  options: any;
@@ -32,6 +33,10 @@ export declare class JsonMethodStore extends JsonEntityStore {
32
33
  set acceptMimes(mimes: string[]);
33
34
  get parameters(): JsonParameterStore[];
34
35
  get operationPaths(): Map<string, import("./JsonOperation.js").JsonMethodPath>;
36
+ get collectionType(): Type<any>;
37
+ set collectionType(type: Type<any>);
38
+ get isCollection(): boolean;
39
+ get schema(): JsonSchema;
35
40
  /**
36
41
  * Get an endpoint.
37
42
  * @param target
@@ -1,7 +1,8 @@
1
+ import type { Type } from "@tsed/core";
1
2
  import { JsonMap } from "../domain/JsonMap.js";
2
3
  /**
3
4
  * @ignore
4
5
  */
5
6
  export declare function toJsonMapCollection(content: {
6
7
  [key: string]: any;
7
- }, klass?: typeof JsonMap): JsonMap<any>;
8
+ }, klass?: Type<JsonMap<any>>): JsonMap<any>;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tsed/schema",
3
3
  "description": "JsonSchema module for Ts.ED Framework",
4
4
  "type": "module",
5
- "version": "8.16.0-rc.4",
5
+ "version": "8.16.0",
6
6
  "source": "./src/index.ts",
7
7
  "main": "./lib/esm/index.js",
8
8
  "module": "./lib/esm/index.js",
@@ -34,7 +34,7 @@
34
34
  "tsed"
35
35
  ],
36
36
  "dependencies": {
37
- "@tsed/openspec": "8.16.0-rc.4",
37
+ "@tsed/openspec": "8.16.0",
38
38
  "change-case": "^5.4.4",
39
39
  "json-schema": "0.4.0",
40
40
  "picomatch": "4.0.2",
@@ -43,11 +43,11 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "@apidevtools/swagger-parser": "10.1.0",
46
- "@tsed/barrels": "8.16.0-rc.4",
47
- "@tsed/core": "8.16.0-rc.4",
48
- "@tsed/hooks": "8.16.0-rc.4",
49
- "@tsed/openspec": "8.16.0-rc.4",
50
- "@tsed/typescript": "8.16.0-rc.4",
46
+ "@tsed/barrels": "8.16.0",
47
+ "@tsed/core": "8.16.0",
48
+ "@tsed/hooks": "8.16.0",
49
+ "@tsed/openspec": "8.16.0",
50
+ "@tsed/typescript": "8.16.0",
51
51
  "@types/fs-extra": "11.0.4",
52
52
  "@types/json-schema": "7.0.15",
53
53
  "@types/picomatch": "3.0.2",
@@ -76,8 +76,5 @@
76
76
  },
77
77
  "homepage": "https://github.com/tsedio/tsed/tree/production/packages/specs/schema",
78
78
  "author": "Romain Lenzotti",
79
- "license": "MIT",
80
- "publishConfig": {
81
- "tag": "rc"
82
- }
79
+ "license": "MIT"
83
80
  }