@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 +2 -1
- package/dist/http/repository/AbstractRepository.d.ts +1 -1
- package/dist/http/repository/DtoRepository.d.ts +11 -7
- package/dist/http/repository/DtoRepository.js +22 -12
- package/dist/http/repository/ICrudRepository.d.ts +10 -6
- package/dist/http/repository/ModelRepository.d.ts +10 -6
- package/dist/http/repository/ModelRepository.js +10 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -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({
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|