@tsed/mongoose 8.0.0 → 8.0.2

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.
Files changed (77) hide show
  1. package/package.json +15 -14
  2. package/src/MongooseModule.ts +32 -0
  3. package/src/constants/constants.ts +20 -0
  4. package/src/decorators/auto.spec.ts +30 -0
  5. package/src/decorators/auto.ts +24 -0
  6. package/src/decorators/discriminatorKey.ts +1 -0
  7. package/src/decorators/dynamicRef.spec.ts +46 -0
  8. package/src/decorators/dynamicRef.ts +76 -0
  9. package/src/decorators/excludeIndexes.spec.ts +30 -0
  10. package/src/decorators/excludeIndexes.ts +24 -0
  11. package/src/decorators/expires.spec.ts +18 -0
  12. package/src/decorators/expires.ts +24 -0
  13. package/src/decorators/immutable.spec.ts +30 -0
  14. package/src/decorators/immutable.ts +26 -0
  15. package/src/decorators/indexed.spec.ts +19 -0
  16. package/src/decorators/indexed.ts +24 -0
  17. package/src/decorators/lowercase.spec.ts +30 -0
  18. package/src/decorators/lowercase.ts +24 -0
  19. package/src/decorators/model.ts +69 -0
  20. package/src/decorators/mongooseIndex.spec.ts +26 -0
  21. package/src/decorators/mongooseIndex.ts +35 -0
  22. package/src/decorators/mongooseIndexes.spec.ts +35 -0
  23. package/src/decorators/mongooseIndexes.ts +35 -0
  24. package/src/decorators/mongoosePlugin.spec.ts +25 -0
  25. package/src/decorators/mongoosePlugin.ts +20 -0
  26. package/src/decorators/numberDecimal.spec.ts +266 -0
  27. package/src/decorators/numberDecimal.ts +84 -0
  28. package/src/decorators/objectID.spec.ts +24 -0
  29. package/src/decorators/objectID.ts +39 -0
  30. package/src/decorators/postHook.spec.ts +44 -0
  31. package/src/decorators/postHook.ts +72 -0
  32. package/src/decorators/preHook.spec.ts +75 -0
  33. package/src/decorators/preHook.ts +70 -0
  34. package/src/decorators/ref.spec.ts +361 -0
  35. package/src/decorators/ref.ts +111 -0
  36. package/src/decorators/schema.ts +79 -0
  37. package/src/decorators/schemaIgnore.spec.ts +18 -0
  38. package/src/decorators/schemaIgnore.ts +24 -0
  39. package/src/decorators/select.spec.ts +18 -0
  40. package/src/decorators/select.ts +24 -0
  41. package/src/decorators/sparse.spec.ts +30 -0
  42. package/src/decorators/sparse.ts +26 -0
  43. package/src/decorators/text.spec.ts +30 -0
  44. package/src/decorators/text.ts +25 -0
  45. package/src/decorators/trim.spec.ts +18 -0
  46. package/src/decorators/trim.ts +23 -0
  47. package/src/decorators/unique.spec.ts +18 -0
  48. package/src/decorators/unique.ts +23 -0
  49. package/src/decorators/uppercase.spec.ts +30 -0
  50. package/src/decorators/uppercase.ts +24 -0
  51. package/src/decorators/versionKey.spec.ts +19 -0
  52. package/src/decorators/versionKey.ts +9 -0
  53. package/src/decorators/virtualRef.spec.ts +383 -0
  54. package/src/decorators/virtualRef.ts +73 -0
  55. package/src/index.ts +47 -0
  56. package/src/interfaces/MongooseConnectionOptions.ts +10 -0
  57. package/src/interfaces/MongooseDocument.ts +3 -0
  58. package/src/interfaces/MongooseModel.ts +10 -0
  59. package/src/interfaces/MongooseModelOptions.ts +8 -0
  60. package/src/interfaces/MongooseSchemaOptions.ts +51 -0
  61. package/src/interfaces/MongooseSchemaTypes.ts +5 -0
  62. package/src/interfaces/MongooseVirtualRefOptions.ts +10 -0
  63. package/src/interfaces/interfaces.ts +9 -0
  64. package/src/registries/MongooseModels.ts +3 -0
  65. package/src/services/MongooseConnection.spec.ts +70 -0
  66. package/src/services/MongooseConnections.ts +58 -0
  67. package/src/services/MongooseService.spec.ts +73 -0
  68. package/src/services/MongooseService.ts +77 -0
  69. package/src/utils/buildMongooseSchema.spec.ts +67 -0
  70. package/src/utils/createModel.spec.ts +49 -0
  71. package/src/utils/createModel.ts +54 -0
  72. package/src/utils/createSchema.spec.ts +771 -0
  73. package/src/utils/createSchema.ts +198 -0
  74. package/src/utils/resolveRefType.spec.ts +30 -0
  75. package/src/utils/resolveRefType.ts +18 -0
  76. package/src/utils/schemaOptions.spec.ts +68 -0
  77. package/src/utils/schemaOptions.ts +74 -0
@@ -0,0 +1,75 @@
1
+ import {MongooseNextCB, PreHook, schemaOptions} from "../../src/index.js";
2
+
3
+ describe("@PreHook()", () => {
4
+ describe("when decorator is used as class decorator", () => {
5
+ it("should call applySchemaOptions", () => {
6
+ // GIVEN
7
+ const fn = vi.fn();
8
+
9
+ // WHEN
10
+ @PreHook("method", fn, {query: true})
11
+ class Test {}
12
+
13
+ // THEN
14
+ const options = schemaOptions(Test);
15
+
16
+ expect(options).toEqual({
17
+ pre: [
18
+ {
19
+ method: "method",
20
+ fn,
21
+ options: {
22
+ query: true
23
+ }
24
+ }
25
+ ]
26
+ });
27
+ });
28
+ it("should call applySchemaOptions with more options", () => {
29
+ // GIVEN
30
+ const fn: any = vi.fn((instance: any, next: MongooseNextCB, options: any) => {
31
+ return instance;
32
+ });
33
+
34
+ // WHEN
35
+ @PreHook("method", fn, {query: true})
36
+ class Test {}
37
+
38
+ // THEN
39
+ const options = schemaOptions(Test);
40
+
41
+ expect(options).toEqual({
42
+ pre: [
43
+ {
44
+ method: "method",
45
+ fn,
46
+ options: {
47
+ query: true
48
+ }
49
+ }
50
+ ]
51
+ });
52
+ });
53
+ });
54
+
55
+ describe("when decorator is used as method decorator", () => {
56
+ it("should call applySchemaOptions", () => {
57
+ class Test {
58
+ @PreHook("save", {
59
+ query: true
60
+ })
61
+ static method() {}
62
+ }
63
+
64
+ const {
65
+ pre: [options]
66
+ } = schemaOptions(Test);
67
+
68
+ expect(options.method).toBe("save");
69
+ expect(options.fn).toBeInstanceOf(Function);
70
+ expect(options.options).toEqual({
71
+ query: true
72
+ });
73
+ });
74
+ });
75
+ });
@@ -0,0 +1,70 @@
1
+ import {decoratorTypeOf, DecoratorTypes} from "@tsed/core";
2
+
3
+ import {MongooseHookOptions, MongoosePreHookCB} from "../interfaces/MongooseSchemaOptions.js";
4
+ import {schemaOptions} from "../utils/schemaOptions.js";
5
+
6
+ /**
7
+ *
8
+ * We can simply attach a `@PreHook` decorator to your model class and
9
+ * define the hook function like you normally would in Mongoose.
10
+ *
11
+ * ```typescript
12
+ * import {Ignore, Required} from "@tsed/platform-http";
13
+ * import {PreHook, Model} from "@tsed/mongoose";
14
+ *
15
+ * @Model()
16
+ * @PreHook("save", (car: CarModel, next) => {
17
+ * if (car.model === 'Tesla') {
18
+ * car.isFast = true;
19
+ * }
20
+ * next();
21
+ *})
22
+ * export class CarModel {
23
+ *
24
+ * @Ignore()
25
+ * _id: string;
26
+ *
27
+ * @Required()
28
+ * model: string;
29
+ *
30
+ * @Required()
31
+ * isFast: boolean;
32
+ *
33
+ * // or Prehook on static method
34
+ * @PreHook("save")
35
+ * static preSave(car: CarModel, next) {
36
+ * if (car.model === 'Tesla') {
37
+ * car.isFast = true;
38
+ * }
39
+ * next();
40
+ * }
41
+ * }
42
+ * ```
43
+ *
44
+ * This will execute the pre-save hook each time a `CarModel` document is saved.
45
+ *
46
+ * @param {string} method
47
+ * @param fn
48
+ * @param options
49
+ * @returns {Function}
50
+ * @decorator
51
+ * @class
52
+ */
53
+ export function PreHook<T = any>(method: string, fn?: MongoosePreHookCB<T> | MongooseHookOptions, options?: MongooseHookOptions): Function {
54
+ return (...args: any[]) => {
55
+ if (decoratorTypeOf(args) === DecoratorTypes.METHOD_STC) {
56
+ options = fn as MongooseHookOptions;
57
+ fn = args[0][args[1]].bind(args[0]);
58
+ }
59
+
60
+ schemaOptions(args[0], {
61
+ pre: [
62
+ {
63
+ method,
64
+ fn: fn as MongoosePreHookCB<T>,
65
+ options
66
+ }
67
+ ]
68
+ });
69
+ };
70
+ }
@@ -0,0 +1,361 @@
1
+ import {catchError, Store} from "@tsed/core";
2
+ import {getJsonSchema, Property} from "@tsed/schema";
3
+ import {Schema} from "mongoose";
4
+
5
+ import {MONGOOSE_MODEL_NAME, MONGOOSE_SCHEMA} from "../constants/constants.js";
6
+ import {MongooseModels} from "../registries/MongooseModels.js";
7
+ import {Ref} from "./ref.js";
8
+
9
+ describe("@Ref()", () => {
10
+ describe("type is a class", () => {
11
+ it("should set metadata and catch error", () => {
12
+ const error = catchError(() => {
13
+ class Model {
14
+ @Ref(undefined)
15
+ num: number[];
16
+ }
17
+ });
18
+
19
+ expect(error?.message).toEqual(
20
+ "A model is required on `@Ref(model)` decorator. Please give a model or wrap it inside an arrow function if you have a circular reference."
21
+ );
22
+ });
23
+
24
+ it("should set metadata", () => {
25
+ class RefTest {
26
+ @Property()
27
+ id: string;
28
+ }
29
+
30
+ Store.from(RefTest).set(MONGOOSE_MODEL_NAME, "RefTest");
31
+
32
+ class Test {
33
+ @Ref(RefTest)
34
+ test: Ref<RefTest>;
35
+ }
36
+
37
+ const store = Store.from(Test, "test");
38
+ const schema = getJsonSchema(Test);
39
+
40
+ expect(schema).toEqual({
41
+ definitions: {
42
+ RefTest: {
43
+ type: "object",
44
+ properties: {
45
+ id: {
46
+ type: "string"
47
+ }
48
+ }
49
+ }
50
+ },
51
+ properties: {
52
+ test: {
53
+ oneOf: [
54
+ {
55
+ description: "A reference ObjectID",
56
+ examples: ["5ce7ad3028890bd71749d477"],
57
+ type: "string"
58
+ },
59
+ {
60
+ $ref: "#/definitions/RefTest"
61
+ }
62
+ ]
63
+ }
64
+ },
65
+ type: "object"
66
+ });
67
+
68
+ expect(store.get(MONGOOSE_SCHEMA)).toEqual({
69
+ type: Schema.Types.ObjectId,
70
+ ref: RefTest
71
+ });
72
+ });
73
+ });
74
+ describe("type is a map of class", () => {
75
+ it("should set metadata", () => {
76
+ class RefTest {
77
+ @Property()
78
+ id: string;
79
+ }
80
+
81
+ Store.from(RefTest).set(MONGOOSE_MODEL_NAME, "RefTest");
82
+ MongooseModels.set("RefTest", RefTest);
83
+
84
+ class Test {
85
+ @Ref(RefTest)
86
+ test: Map<string, Ref<RefTest>>;
87
+ }
88
+
89
+ const store = Store.from(Test, "test");
90
+ const schema = getJsonSchema(Test);
91
+
92
+ expect(schema).toEqual({
93
+ definitions: {
94
+ RefTest: {
95
+ properties: {
96
+ id: {
97
+ type: "string"
98
+ }
99
+ },
100
+ type: "object"
101
+ }
102
+ },
103
+ properties: {
104
+ test: {
105
+ additionalProperties: {
106
+ oneOf: [
107
+ {
108
+ description: "A reference ObjectID",
109
+ examples: ["5ce7ad3028890bd71749d477"],
110
+ type: "string"
111
+ },
112
+ {
113
+ $ref: "#/definitions/RefTest"
114
+ }
115
+ ]
116
+ },
117
+ type: "object"
118
+ }
119
+ },
120
+ type: "object"
121
+ });
122
+
123
+ expect(store.get(MONGOOSE_SCHEMA)).toEqual({
124
+ type: Schema.Types.ObjectId,
125
+ ref: RefTest
126
+ });
127
+ });
128
+ });
129
+ describe("type is a Function", () => {
130
+ it("should set metadata", () => {
131
+ class RefTest {
132
+ @Property()
133
+ id: string;
134
+ }
135
+
136
+ Store.from(RefTest).set(MONGOOSE_MODEL_NAME, "RefTest");
137
+ const arrow = () => RefTest;
138
+
139
+ class Test {
140
+ @Ref(arrow)
141
+ test: Ref<RefTest>;
142
+ }
143
+
144
+ const store = Store.from(Test, "test");
145
+ const schema = getJsonSchema(Test);
146
+
147
+ expect(schema).toEqual({
148
+ definitions: {
149
+ RefTest: {
150
+ type: "object",
151
+ properties: {
152
+ id: {
153
+ type: "string"
154
+ }
155
+ }
156
+ }
157
+ },
158
+ properties: {
159
+ test: {
160
+ oneOf: [
161
+ {
162
+ description: "A reference ObjectID",
163
+ examples: ["5ce7ad3028890bd71749d477"],
164
+ type: "string"
165
+ },
166
+ {
167
+ $ref: "#/definitions/RefTest"
168
+ }
169
+ ]
170
+ }
171
+ },
172
+ type: "object"
173
+ });
174
+
175
+ expect(store.get(MONGOOSE_SCHEMA)).toEqual({
176
+ type: Schema.Types.ObjectId,
177
+ ref: arrow
178
+ });
179
+ });
180
+ });
181
+ describe("type is a string (deprecated)", () => {
182
+ it("should set metadata", () => {
183
+ class RefTest {}
184
+
185
+ class Test {
186
+ @Ref("RefTest")
187
+ test: Ref<RefTest>;
188
+ }
189
+
190
+ MongooseModels.set("RefTest", RefTest);
191
+ const store = Store.from(Test, "test");
192
+
193
+ expect(getJsonSchema(Test)).toEqual({
194
+ definitions: {
195
+ RefTest: {
196
+ properties: {
197
+ id: {
198
+ type: "string"
199
+ }
200
+ },
201
+ type: "object"
202
+ }
203
+ },
204
+ properties: {
205
+ test: {
206
+ oneOf: [
207
+ {
208
+ description: "A reference ObjectID",
209
+ examples: ["5ce7ad3028890bd71749d477"],
210
+ type: "string"
211
+ },
212
+ {
213
+ $ref: "#/definitions/RefTest"
214
+ }
215
+ ]
216
+ }
217
+ },
218
+ type: "object"
219
+ });
220
+ expect(store.get(MONGOOSE_SCHEMA)).toEqual({
221
+ type: Schema.Types.ObjectId,
222
+ ref: "RefTest"
223
+ });
224
+ });
225
+ });
226
+ describe("JsonSchema gets generated based on populated groups", () => {
227
+ class MyChildModel {
228
+ @Property()
229
+ test: string;
230
+ }
231
+
232
+ class MyParentModel {
233
+ @Property()
234
+ id: string;
235
+
236
+ @Ref(MyChildModel, {populatedGroups: ["group1", "group2"]})
237
+ child1: Ref<MyChildModel>;
238
+
239
+ @Ref(MyChildModel, {populatedGroups: ["group2"]})
240
+ child2: Ref<MyChildModel>;
241
+
242
+ @Ref(MyChildModel)
243
+ child3: Ref<MyChildModel>;
244
+ }
245
+
246
+ it("should reflect the populated groups options in the schema (with given groups)", () => {
247
+ const spec = getJsonSchema(MyParentModel, {
248
+ groups: ["group1", "group3"]
249
+ });
250
+
251
+ expect(spec).toEqual({
252
+ definitions: {
253
+ MyChildModel: {
254
+ properties: {
255
+ test: {
256
+ type: "string"
257
+ }
258
+ },
259
+ type: "object"
260
+ },
261
+ MyChildModelGroup1Group3: {
262
+ properties: {
263
+ test: {
264
+ type: "string"
265
+ }
266
+ },
267
+ type: "object"
268
+ }
269
+ },
270
+ properties: {
271
+ child1: {
272
+ oneOf: [
273
+ {
274
+ $ref: "#/definitions/MyChildModelGroup1Group3"
275
+ }
276
+ ]
277
+ },
278
+ child2: {
279
+ oneOf: [
280
+ {
281
+ description: "A reference ObjectID",
282
+ examples: ["5ce7ad3028890bd71749d477"],
283
+ type: "string"
284
+ }
285
+ ]
286
+ },
287
+ child3: {
288
+ oneOf: [
289
+ {
290
+ description: "A reference ObjectID",
291
+ examples: ["5ce7ad3028890bd71749d477"],
292
+ type: "string"
293
+ },
294
+ {
295
+ $ref: "#/definitions/MyChildModel"
296
+ }
297
+ ]
298
+ },
299
+ id: {
300
+ type: "string"
301
+ }
302
+ },
303
+ type: "object"
304
+ });
305
+ });
306
+
307
+ it("should reflect the populated groups options in the schema (without given groups)", () => {
308
+ const spec = getJsonSchema(MyParentModel, {
309
+ groups: []
310
+ });
311
+ expect(spec).toEqual({
312
+ definitions: {
313
+ MyChildModel: {
314
+ properties: {
315
+ test: {
316
+ type: "string"
317
+ }
318
+ },
319
+ type: "object"
320
+ }
321
+ },
322
+ properties: {
323
+ child1: {
324
+ oneOf: [
325
+ {
326
+ description: "A reference ObjectID",
327
+ examples: ["5ce7ad3028890bd71749d477"],
328
+ type: "string"
329
+ }
330
+ ]
331
+ },
332
+ child2: {
333
+ oneOf: [
334
+ {
335
+ description: "A reference ObjectID",
336
+ examples: ["5ce7ad3028890bd71749d477"],
337
+ type: "string"
338
+ }
339
+ ]
340
+ },
341
+ child3: {
342
+ oneOf: [
343
+ {
344
+ description: "A reference ObjectID",
345
+ examples: ["5ce7ad3028890bd71749d477"],
346
+ type: "string"
347
+ },
348
+ {
349
+ $ref: "#/definitions/MyChildModel"
350
+ }
351
+ ]
352
+ },
353
+ id: {
354
+ type: "string"
355
+ }
356
+ },
357
+ type: "object"
358
+ });
359
+ });
360
+ });
361
+ });
@@ -0,0 +1,111 @@
1
+ import {isArrowFn, isCollection, isObject, isObjectID, isString, StoreMerge, Type, useDecorators} from "@tsed/core";
2
+ import {deserialize, OnDeserialize, OnSerialize, serialize} from "@tsed/json-mapper";
3
+ import {ForwardGroups, JsonEntityFn, lazyRef, matchGroups, OneOf, Property, string} from "@tsed/schema";
4
+ import {Schema as MongooseSchema} from "mongoose";
5
+
6
+ import {MONGOOSE_SCHEMA} from "../constants/constants.js";
7
+ import {MongooseSchemaTypes} from "../interfaces/MongooseSchemaTypes.js";
8
+ import {MongooseModels} from "../registries/MongooseModels.js";
9
+
10
+ interface RefOptions {
11
+ type?: MongooseSchemaTypes;
12
+ populatedGroups?: string[];
13
+ }
14
+
15
+ function isRef(value: undefined | string | any) {
16
+ return isObjectID(value) || isString(value);
17
+ }
18
+
19
+ function PopulateGroups(populatedGroups: string[]) {
20
+ return useDecorators(
21
+ ForwardGroups(true),
22
+ JsonEntityFn((store) => {
23
+ store.schema.$hooks.on("oneOf", (obj: any[], givenGroups: string[]) => {
24
+ if (matchGroups(populatedGroups, givenGroups)) {
25
+ return obj.filter((x) => x.type === "string"); // keep the object id;
26
+ } else {
27
+ return obj.filter((x) => x.type !== "string"); // keep the ref definition
28
+ }
29
+ });
30
+ })
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Define a property as mongoose reference to other Model (decorated with @Model).
36
+ *
37
+ * ### Example
38
+ *
39
+ * ```typescript
40
+ *
41
+ * @Model()
42
+ * class FooModel {
43
+ *
44
+ * @Ref(Foo2Model)
45
+ * field: Ref<Foo2Model>
46
+ *
47
+ * @Ref(Foo2Model)
48
+ * list: Ref<Foo2Model>[]
49
+ * }
50
+ *
51
+ * @Model()
52
+ * class Foo2Model {
53
+ * }
54
+ * ```
55
+ *
56
+ * @param model
57
+ * @param options
58
+ * @returns {Function}
59
+ * @decorator
60
+ * @mongoose
61
+ * @property
62
+ */
63
+ export function Ref(
64
+ model: string | (() => Type) | any,
65
+ options: RefOptions | MongooseSchemaTypes = MongooseSchemaTypes.OBJECT_ID
66
+ ): PropertyDecorator {
67
+ if (!model) {
68
+ throw new Error(
69
+ "A model is required on `@Ref(model)` decorator. Please give a model or wrap it inside an arrow function if you have a circular reference."
70
+ );
71
+ }
72
+
73
+ const getType = () => (isString(model) ? MongooseModels.get(model) : isArrowFn(model) ? model() : model);
74
+ const populatedGroups = (isObject(options) && options.populatedGroups) || [];
75
+
76
+ return useDecorators(
77
+ Property(Object),
78
+ StoreMerge(MONGOOSE_SCHEMA, {
79
+ type: MongooseSchema.Types[isObject(options) ? options.type || MongooseSchemaTypes.OBJECT_ID : options],
80
+ ref: model
81
+ }),
82
+ OnDeserialize((value) => {
83
+ if (isRef(value)) {
84
+ return value.toString();
85
+ }
86
+
87
+ if (isCollection(value) && isRef(value[0])) {
88
+ return value.map(String);
89
+ }
90
+
91
+ return deserialize(value, {type: getType(), useAlias: false});
92
+ }),
93
+ OnSerialize((value: any, ctx) => {
94
+ if (isRef(value)) {
95
+ return value.toString();
96
+ }
97
+
98
+ if (isCollection(value) && isRef(value[0])) {
99
+ return value.map(String);
100
+ }
101
+
102
+ const type = getType();
103
+
104
+ return serialize(value, {...ctx, type});
105
+ }),
106
+ OneOf(string().example("5ce7ad3028890bd71749d477").description("A reference ObjectID"), lazyRef(getType)),
107
+ populatedGroups.length && PopulateGroups(populatedGroups)
108
+ ) as PropertyDecorator;
109
+ }
110
+
111
+ export type Ref<T> = T | string;
@@ -0,0 +1,79 @@
1
+ import {decoratorTypeOf, StoreMerge, useDecorators} from "@tsed/core";
2
+ import {injectable} from "@tsed/di";
3
+ import {Property} from "@tsed/schema";
4
+ import {SchemaTypeOptions} from "mongoose";
5
+
6
+ import {MONGOOSE_SCHEMA} from "../constants/constants.js";
7
+ import {MongooseSchemaOptions} from "../interfaces/MongooseSchemaOptions.js";
8
+ import {getSchema, getSchemaToken} from "../utils/createSchema.js";
9
+
10
+ /**
11
+ * Define a class as a Mongoose Schema ready to be used to compose other schemes and models.
12
+ *
13
+ * ### Example
14
+ *
15
+ * ```typescript
16
+ * @MongooseSchema()
17
+ * export class EventSchema {
18
+ * @Property()
19
+ * field: string;
20
+ * }
21
+ * ```
22
+ *
23
+ * ### Options
24
+ *
25
+ * - `schemaOptions` (mongoose.SchemaOptions): Option to configure the schema behavior.
26
+ *
27
+ * @param {MongooseSchemaOptions | undefined} options
28
+ * @returns {(target: any) => void}
29
+ * @decorator
30
+ * @mongoose
31
+ * @property
32
+ * @class
33
+ */
34
+ export function Schema(options?: MongooseSchemaOptions): (target: any) => void;
35
+ export function Schema(definition: SchemaTypeOptions<any>): Function;
36
+ export function Schema(options: MongooseSchemaOptions | SchemaTypeOptions<any> = {}) {
37
+ return (...parameters: any[]) => {
38
+ switch (decoratorTypeOf(parameters)) {
39
+ case "property":
40
+ return useDecorators(Property(), StoreMerge(MONGOOSE_SCHEMA, options))(parameters[0], parameters[1], parameters[2]);
41
+
42
+ case "class":
43
+ const {token} = getSchemaToken(parameters[0], options);
44
+
45
+ injectable(token).factory(() => getSchema(parameters[0], options as any));
46
+ break;
47
+ }
48
+ };
49
+ }
50
+
51
+ /**
52
+ * Define a class as a Mongoose Schema ready to be used to compose other schemes and models.
53
+ *
54
+ * ### Example
55
+ *
56
+ * ```typescript
57
+ * @MongooseSchema()
58
+ * export class EventSchema {
59
+ * @Property()
60
+ * field: string;
61
+ * }
62
+ * ```
63
+ *
64
+ * ### Options
65
+ *
66
+ * - `schemaOptions` (mongoose.SchemaOptions): Option to configure the schema behavior.
67
+ *
68
+ * @param {MongooseSchemaOptions | undefined} options
69
+ * @returns {(target: any) => void}
70
+ * @decorator
71
+ * @mongoose
72
+ * @property
73
+ * @class
74
+ */
75
+ export function MongooseSchema(options?: MongooseSchemaOptions): (target: any) => void;
76
+ export function MongooseSchema(definition: SchemaTypeOptions<any>): Function;
77
+ export function MongooseSchema(options: MongooseSchemaOptions | SchemaTypeOptions<any> = {}) {
78
+ return Schema(options as any);
79
+ }
@@ -0,0 +1,18 @@
1
+ import {Store} from "@tsed/core";
2
+
3
+ import {MONGOOSE_SCHEMA} from "../constants/constants.js";
4
+ import {SchemaIgnore} from "./schemaIgnore.js";
5
+
6
+ describe("@SchemaIgnore()", () => {
7
+ it("should set metadata", () => {
8
+ class Test {
9
+ @SchemaIgnore()
10
+ test: any;
11
+ }
12
+
13
+ const store = Store.from(Test, "test");
14
+ expect(store.get(MONGOOSE_SCHEMA)).toEqual({
15
+ schemaIgnore: true
16
+ });
17
+ });
18
+ });