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