@clairejs/server 3.16.4 → 3.16.6

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/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  ## Change Log
2
2
 
3
- #### 3.16.4:
3
+ #### 3.16.6:
4
4
 
5
+ - do not throw when fail to clean up in ModelRepository
5
6
  - fix file controllers
6
7
  - fix socket authentication, fix http error code in response
7
8
  - update claire orm
@@ -2,7 +2,7 @@ import { Constructor, DeepPartial, Identifiable } from "@clairejs/core";
2
2
  import { ServerModelMetadata } from "../../common/ServerModelMetadata";
3
3
  import { IPrincipal } from "../../common/auth/IPrincipal";
4
4
  export declare abstract class AbstractRepository<T extends Identifiable> {
5
- readonly model: Constructor<T>;
5
+ protected readonly model: Constructor<T>;
6
6
  protected readonly modelMetadata: ServerModelMetadata;
7
7
  constructor(model: Constructor<T>);
8
8
  protected beforeCreating(principal: IPrincipal | undefined, records: DeepPartial<T>[]): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { AbstractModel, Constructor, CreateManyRequestBody, CreateManyResponseBody, DeepPartial, GetManyQueries, GetManyResponseBody, Identifiable, UpdateManyBody, UpdateManyQueries, UpdateManyResponse } from "@clairejs/core";
1
+ import { AbstractLogger, AbstractModel, Constructor, CreateManyRequestBody, CreateManyResponseBody, DeepPartial, GetManyQueries, GetManyResponseBody, Identifiable, UpdateManyBody, UpdateManyQueries, UpdateManyResponse } from "@clairejs/core";
2
2
  import { IQueryProvider, ITransaction, QueryCondition } from "@clairejs/orm";
3
3
  import { IPrincipal } from "../../common/auth/IPrincipal";
4
4
  import { AbstractRepository } from "./AbstractRepository";
@@ -29,30 +29,34 @@ export declare const MultipleMap: <R extends Identifiable, K extends AbstractMod
29
29
  nestedMapping: DtoDissolver<R, K> | undefined;
30
30
  };
31
31
  export declare class DtoRepository<T extends Identifiable> extends AbstractRepository<T> implements ICrudRepository<T> {
32
- readonly model: Constructor<T>;
33
- readonly dissolver: DtoDissolver<T, any>;
32
+ protected readonly model: Constructor<T>;
33
+ protected readonly dissolver: DtoDissolver<T, any>;
34
34
  constructor(model: Constructor<T>, dissolver: DtoDissolver<T, any>);
35
35
  private getMapValue;
36
- createMany({ principal, body, tx, }: {
36
+ createMany({ principal, body, tx, logger, }: {
37
37
  principal?: IPrincipal | undefined;
38
38
  body: CreateManyRequestBody<T>;
39
39
  tx: ITransaction & IQueryProvider;
40
+ logger?: AbstractLogger;
40
41
  }): Promise<CreateManyResponseBody<T>>;
41
- updateMany({ principal, queries, ops, body, tx, }: {
42
+ updateMany({ principal, queries, ops, body, tx, logger, }: {
42
43
  principal?: IPrincipal | undefined;
43
44
  queries?: UpdateManyQueries<T>;
44
45
  ops?: QueryCondition<T>[];
45
46
  body: UpdateManyBody<T>;
46
47
  tx: ITransaction & IQueryProvider;
48
+ logger?: AbstractLogger;
47
49
  }): Promise<UpdateManyResponse<T>>;
48
- getMany({ queries, ops, queryProvider, }: {
50
+ getMany({ queries, ops, queryProvider, logger, }: {
49
51
  queries?: GetManyQueries<T>;
50
52
  ops?: QueryCondition<T>[];
51
53
  queryProvider: IQueryProvider;
54
+ logger?: AbstractLogger;
52
55
  }): Promise<GetManyResponseBody<T>>;
53
- deleteMany({ queries, ops, tx, }: {
56
+ deleteMany({ queries, ops, tx, logger, }: {
54
57
  queries?: UpdateManyQueries<T>;
55
58
  ops?: QueryCondition<T>[];
56
59
  tx: ITransaction;
60
+ logger?: AbstractLogger;
57
61
  }): Promise<UpdateManyResponse<T>>;
58
62
  }
@@ -51,7 +51,7 @@ export class DtoRepository extends AbstractRepository {
51
51
  deepMerge(root, partial);
52
52
  }
53
53
  }
54
- async createMany({ principal, body, tx, }) {
54
+ async createMany({ principal, body, tx, logger, }) {
55
55
  const result = [];
56
56
  await this.beforeCreating(principal, body.records);
57
57
  for (const record of body.records) {
@@ -60,6 +60,7 @@ export class DtoRepository extends AbstractRepository {
60
60
  const currentInstances = await repo.getMany({
61
61
  ops: mapper.forwardOps(),
62
62
  queryProvider: tx,
63
+ logger,
63
64
  });
64
65
  return currentInstances.records;
65
66
  }, this.dissolver(record), async (mapper, ks, currentInstances) => {
@@ -70,9 +71,14 @@ export class DtoRepository extends AbstractRepository {
70
71
  const ops = mapper.forwardOps();
71
72
  if (mapper.multiple) {
72
73
  //-- if ks contain an array of instances, we need to remove old instances and create new ones
73
- await repo.deleteMany({ ops, tx });
74
+ await repo.deleteMany({ ops, tx, logger });
74
75
  //-- try creating new
75
- const createManyResult = await repo.createMany({ principal, body: { records: ks }, tx });
76
+ const createManyResult = await repo.createMany({
77
+ principal,
78
+ body: { records: ks },
79
+ tx,
80
+ logger,
81
+ });
76
82
  return createManyResult.records;
77
83
  }
78
84
  else {
@@ -87,11 +93,12 @@ export class DtoRepository extends AbstractRepository {
87
93
  principal,
88
94
  body: { records: ks },
89
95
  tx,
96
+ logger,
90
97
  });
91
98
  return instances.records;
92
99
  }
93
100
  else if (currentInstances.length === 1) {
94
- const result = await repo.updateMany({ principal, ops, body: { update: k }, tx });
101
+ const result = await repo.updateMany({ principal, ops, body: { update: k }, tx, logger });
95
102
  return [{ ...currentInstances[0], ...k, ...result.modified[0] }];
96
103
  }
97
104
  else {
@@ -103,7 +110,7 @@ export class DtoRepository extends AbstractRepository {
103
110
  }
104
111
  return { records: result };
105
112
  }
106
- async updateMany({ principal, queries, ops, body, tx, }) {
113
+ async updateMany({ principal, queries, ops, body, tx, logger, }) {
107
114
  //-- check queries for id field
108
115
  if (!queries?.fields?.id || queries.fields.id.length !== 1) {
109
116
  throw Errors.VALIDATION_ERROR("Missing required id field in query");
@@ -115,6 +122,7 @@ export class DtoRepository extends AbstractRepository {
115
122
  const currentInstances = await repo.getMany({
116
123
  ops: mapper.forwardOps(ops),
117
124
  queryProvider: tx,
125
+ logger,
118
126
  });
119
127
  return currentInstances.records;
120
128
  }, this.dissolver(result), async (mapper, ks, currentInstances) => {
@@ -125,9 +133,9 @@ export class DtoRepository extends AbstractRepository {
125
133
  const opsx = mapper.forwardOps(ops);
126
134
  if (mapper.multiple) {
127
135
  //-- if ks contain an array of instances, we need to remove old instances and create new ones
128
- await repo.deleteMany({ ops: opsx, tx });
136
+ await repo.deleteMany({ ops: opsx, tx, logger });
129
137
  //-- try creating new
130
- const createManyResult = await repo.createMany({ principal, body: { records: ks }, tx });
138
+ const createManyResult = await repo.createMany({ principal, body: { records: ks }, tx, logger });
131
139
  return createManyResult.records;
132
140
  }
133
141
  else {
@@ -142,13 +150,13 @@ export class DtoRepository extends AbstractRepository {
142
150
  }
143
151
  if (currentInstances.length > 1) {
144
152
  //-- remove all instances
145
- await repo.deleteMany({ ops: opsx, tx });
153
+ await repo.deleteMany({ ops: opsx, tx, logger });
146
154
  //-- try creating new
147
- await repo.createMany({ principal, body: { records: [k] }, tx });
155
+ await repo.createMany({ principal, body: { records: [k] }, tx, logger });
148
156
  }
149
157
  else {
150
158
  //-- update current instance
151
- await repo.updateMany({ principal, ops: opsx, body: { update: k }, tx });
159
+ await repo.updateMany({ principal, ops: opsx, body: { update: k }, tx, logger });
152
160
  }
153
161
  return currentInstances.map((re) => ({ ...re, ...k }));
154
162
  }
@@ -163,7 +171,7 @@ export class DtoRepository extends AbstractRepository {
163
171
  }
164
172
  return { modified: result.id ? this.project([result], projection) : [] };
165
173
  }
166
- async getMany({ queries, ops, queryProvider, }) {
174
+ async getMany({ queries, ops, queryProvider, logger, }) {
167
175
  //-- check queries for id field
168
176
  if (!queries?.fields?.id || queries.fields.id.length !== 1) {
169
177
  throw Errors.VALIDATION_ERROR("Missing required id field in query");
@@ -175,6 +183,7 @@ export class DtoRepository extends AbstractRepository {
175
183
  const instances = await repo.getMany({
176
184
  ops: mapper.forwardOps(ops),
177
185
  queryProvider,
186
+ logger,
178
187
  });
179
188
  return instances.records;
180
189
  });
@@ -182,7 +191,7 @@ export class DtoRepository extends AbstractRepository {
182
191
  ? { records: this.project([result], queries.projection), total: 1 }
183
192
  : { records: [], total: 0 };
184
193
  }
185
- async deleteMany({ queries, ops, tx, }) {
194
+ async deleteMany({ queries, ops, tx, logger, }) {
186
195
  //-- check queries for id field
187
196
  if (!queries?.fields?.id || queries.fields.id.length !== 1) {
188
197
  throw Errors.VALIDATION_ERROR("Missing required id field in query");
@@ -196,6 +205,7 @@ export class DtoRepository extends AbstractRepository {
196
205
  queries: { returning: queries?.returning },
197
206
  ops: nestedOps,
198
207
  tx,
208
+ logger,
199
209
  });
200
210
  return result.modified;
201
211
  });
@@ -1,27 +1,31 @@
1
- import { CreateManyRequestBody, CreateManyResponseBody, GetManyQueries, GetManyResponseBody, UpdateManyBody, UpdateManyQueries, UpdateManyResponse } from "@clairejs/core";
1
+ import { AbstractLogger, CreateManyRequestBody, CreateManyResponseBody, GetManyQueries, GetManyResponseBody, UpdateManyBody, UpdateManyQueries, UpdateManyResponse } from "@clairejs/core";
2
2
  import { IQueryProvider, ITransaction, QueryCondition } from "@clairejs/orm";
3
3
  import { IPrincipal } from "../../common/auth/IPrincipal";
4
4
  export interface ICrudRepository<T> {
5
- createMany({ principal, body, tx, }: {
6
- principal?: IPrincipal;
5
+ createMany({ principal, body, tx, logger, }: {
7
6
  body: CreateManyRequestBody<T>;
8
7
  tx: ITransaction;
8
+ logger?: AbstractLogger;
9
+ principal?: IPrincipal;
9
10
  }): Promise<CreateManyResponseBody<T>>;
10
- getMany({ queries, ops, queryProvider, }: {
11
+ getMany({ queries, ops, queryProvider, logger, }: {
11
12
  queries?: GetManyQueries<T>;
12
13
  ops?: QueryCondition<T>[];
13
14
  queryProvider: IQueryProvider;
15
+ logger?: AbstractLogger;
14
16
  }): Promise<GetManyResponseBody<T>>;
15
- updateMany({ principal, queries, ops, body, tx, }: {
17
+ updateMany({ principal, queries, ops, body, tx, logger, }: {
16
18
  principal?: IPrincipal;
17
19
  queries?: UpdateManyQueries<T>;
18
20
  ops?: QueryCondition<T>[];
19
21
  body: UpdateManyBody<T>;
20
22
  tx: ITransaction;
23
+ logger?: AbstractLogger;
21
24
  }): Promise<UpdateManyResponse<T>>;
22
- deleteMany({ queries, ops, tx, }: {
25
+ deleteMany({ queries, ops, tx, logger, }: {
23
26
  queries?: UpdateManyQueries<T>;
24
27
  ops?: QueryCondition<T>[];
25
28
  tx: ITransaction;
29
+ logger?: AbstractLogger;
26
30
  }): Promise<UpdateManyResponse<T>>;
27
31
  }
@@ -1,10 +1,10 @@
1
- import { AbstractModel, Constructor, CreateManyRequestBody, CreateManyResponseBody, GetManyQueries, GetManyResponseBody, UpdateManyBody, UpdateManyQueries, UpdateManyResponse } from "@clairejs/core";
1
+ import { AbstractModel, Constructor, CreateManyRequestBody, CreateManyResponseBody, GetManyQueries, GetManyResponseBody, UpdateManyBody, UpdateManyQueries, UpdateManyResponse, AbstractLogger } from "@clairejs/core";
2
2
  import { IQueryProvider, ITransaction, QueryCondition } from "@clairejs/orm";
3
3
  import { IPrincipal } from "../../common/auth/IPrincipal";
4
4
  import { ICrudRepository } from "./ICrudRepository";
5
5
  import { AbstractRepository } from "./AbstractRepository";
6
6
  export declare class ModelRepository<T extends AbstractModel> extends AbstractRepository<T> implements ICrudRepository<T> {
7
- readonly model: Constructor<T>;
7
+ protected readonly model: Constructor<T>;
8
8
  private fileUploadHandler?;
9
9
  constructor(model: Constructor<T>);
10
10
  private getNestedQueries;
@@ -12,26 +12,30 @@ export declare class ModelRepository<T extends AbstractModel> extends AbstractRe
12
12
  private getRequestQueryConditionFromQuery;
13
13
  protected uriHandling(records: Partial<T>[]): Promise<() => Promise<void>>;
14
14
  protected beforeReturning(records: Partial<T>[]): Promise<void>;
15
- createMany({ principal, body, tx, }: {
15
+ createMany({ principal, body, tx, logger, }: {
16
16
  principal?: IPrincipal;
17
17
  body: CreateManyRequestBody<T>;
18
18
  tx: ITransaction;
19
+ logger?: AbstractLogger;
19
20
  }): Promise<CreateManyResponseBody<T>>;
20
- updateMany({ principal, ops, queries, body, tx, }: {
21
+ updateMany({ principal, ops, queries, body, tx, logger, }: {
21
22
  principal?: IPrincipal;
22
23
  queries?: UpdateManyQueries<T>;
23
24
  ops?: QueryCondition<T>[];
24
25
  body: UpdateManyBody<T>;
25
26
  tx: ITransaction;
27
+ logger?: AbstractLogger;
26
28
  }): Promise<UpdateManyResponse<T>>;
27
- getMany({ queries, ops, queryProvider, }: {
29
+ getMany({ queries, ops, queryProvider, logger, }: {
28
30
  queries?: GetManyQueries<T>;
29
31
  ops?: QueryCondition<T>[];
30
32
  queryProvider: IQueryProvider;
33
+ logger?: AbstractLogger;
31
34
  }): Promise<GetManyResponseBody<T>>;
32
- deleteMany({ queries, ops, tx, }: {
35
+ deleteMany({ queries, ops, tx, logger, }: {
33
36
  queries?: UpdateManyQueries<T>;
34
37
  ops?: QueryCondition<T>[];
35
38
  tx: ITransaction;
39
+ logger?: AbstractLogger;
36
40
  }): Promise<UpdateManyResponse<T>>;
37
41
  }
@@ -209,7 +209,7 @@ export class ModelRepository extends AbstractRepository {
209
209
  }
210
210
  await Promise.all(mappingOperations);
211
211
  }
212
- async createMany({ principal, body, tx, }) {
212
+ async createMany({ principal, body, tx, logger, }) {
213
213
  const originalRecords = body.records;
214
214
  if (!originalRecords.length) {
215
215
  return { records: [] };
@@ -329,10 +329,10 @@ export class ModelRepository extends AbstractRepository {
329
329
  }
330
330
  }
331
331
  //-- everything is ok, remove original Uris
332
- await cleanUp();
332
+ cleanUp().catch((err) => logger?.error("Error in clean up", err));
333
333
  return { records };
334
334
  }
335
- async updateMany({ principal, ops, queries, body, tx, }) {
335
+ async updateMany({ principal, ops, queries, body, tx, logger, }) {
336
336
  const allConditions = ops || [];
337
337
  const hasManyFields = this.modelMetadata.fields.filter((f) => !!f.hasMany);
338
338
  const systemLocale = getSystemLocale();
@@ -510,11 +510,11 @@ export class ModelRepository extends AbstractRepository {
510
510
  ];
511
511
  }
512
512
  //-- ok clean up
513
- await cleanUp();
513
+ cleanUp().catch((err) => logger?.error("Error in clean up", err));
514
514
  await this.beforeReturning(records);
515
515
  return { modified: this.project(records, projection) };
516
516
  }
517
- async getMany({ queries, ops, queryProvider, }) {
517
+ async getMany({ queries, ops, queryProvider, logger: _logger, }) {
518
518
  const conditions = ops || [];
519
519
  if (queries?.fields) {
520
520
  conditions.push(...this.getRequestQueryConditionFromQuery(queries.fields, this.modelMetadata));
@@ -599,6 +599,9 @@ export class ModelRepository extends AbstractRepository {
599
599
  continue;
600
600
  }
601
601
  const model = getModelById(field.hasMany.relationDto.id);
602
+ if (!model) {
603
+ throw Errors.NOT_FOUND(`Model not found by id: ${field.hasMany.relationDto.id}`);
604
+ }
602
605
  const service = new ModelRepository(model);
603
606
  const innerRecords = !recordIds.length
604
607
  ? { records: [] }
@@ -619,7 +622,7 @@ export class ModelRepository extends AbstractRepository {
619
622
  [...queries.projection, ...(queries.locale ? [] : finalProjection || [])].reduce(uniqueReducer, [])),
620
623
  };
621
624
  }
622
- async deleteMany({ queries, ops, tx, }) {
625
+ async deleteMany({ queries, ops, tx, logger, }) {
623
626
  let allConditions = ops || [];
624
627
  if (queries?.fields) {
625
628
  const fieldOps = this.getRequestQueryConditionFromQuery(queries.fields, this.modelMetadata);
@@ -683,7 +686,7 @@ export class ModelRepository extends AbstractRepository {
683
686
  if (toBeRemovedUris.length) {
684
687
  const fileUploadHandler = await this.getUploadHandler();
685
688
  if (fileUploadHandler) {
686
- await Promise.all(toBeRemovedUris.map((uri) => fileUploadHandler.removeFile(uri)));
689
+ Promise.all(toBeRemovedUris.map((uri) => fileUploadHandler.removeFile(uri))).catch((err) => logger?.error("Fail to remove some files", err));
687
690
  }
688
691
  }
689
692
  returning = tobeRemoved;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clairejs/server",
3
- "version": "3.16.4",
3
+ "version": "3.16.6",
4
4
  "description": "Claire server NodeJs framework written in Typescript.",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",