@clairejs/server 3.18.1 → 3.19.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.
- package/README.md +6 -1
- package/dist/http/controller/AbstractHttpController.d.ts +2 -2
- package/dist/http/controller/AbstractHttpController.js +4 -4
- package/dist/http/controller/CrudHttpController.d.ts +2 -2
- package/dist/http/controller/CrudHttpController.js +5 -5
- package/dist/http/repository/DtoRepository.d.ts +3 -2
- package/dist/http/repository/DtoRepository.js +9 -7
- package/dist/http/repository/ModelRepository.d.ts +3 -2
- package/dist/http/repository/ModelRepository.js +46 -48
- package/dist/job/AbstractJobRepository.d.ts +5 -5
- package/dist/job/LocalJobScheduler.js +3 -3
- package/dist/job/default-job-repo.d.ts +6 -5
- package/dist/job/default-job-repo.js +10 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@ import { type ITransactionFactory } from "@clairejs/orm";
|
|
|
2
2
|
import { type EndpointMetadata } from "../../common/request/endpoint-metadata";
|
|
3
3
|
import { Transactionable } from "../../common/Transactionable";
|
|
4
4
|
export declare abstract class AbstractHttpController extends Transactionable {
|
|
5
|
-
protected readonly
|
|
6
|
-
constructor(
|
|
5
|
+
protected readonly db: ITransactionFactory;
|
|
6
|
+
constructor(db: ITransactionFactory);
|
|
7
7
|
getEndpointMetadata(): Readonly<EndpointMetadata>[];
|
|
8
8
|
}
|
|
@@ -4,10 +4,10 @@ const isEndpoint = (metadata) => {
|
|
|
4
4
|
return !!metadata.method;
|
|
5
5
|
};
|
|
6
6
|
export class AbstractHttpController extends Transactionable {
|
|
7
|
-
|
|
8
|
-
constructor(
|
|
9
|
-
super(
|
|
10
|
-
this.
|
|
7
|
+
db;
|
|
8
|
+
constructor(db) {
|
|
9
|
+
super(db);
|
|
10
|
+
this.db = db;
|
|
11
11
|
}
|
|
12
12
|
getEndpointMetadata() {
|
|
13
13
|
const controllerMetadata = getObjectMetadata(this.constructor);
|
|
@@ -8,10 +8,10 @@ import { type ICrudRepository } from "../repository/ICrudRepository";
|
|
|
8
8
|
export declare class CrudHttpController<T extends Identifiable> extends AbstractHttpController {
|
|
9
9
|
protected readonly model: Constructor<T>;
|
|
10
10
|
protected readonly crudRepository: ICrudRepository<T>;
|
|
11
|
-
protected readonly
|
|
11
|
+
protected readonly db: ITransactionFactory & IQueryProvider;
|
|
12
12
|
protected readonly modelMetadata: ModelMetadata;
|
|
13
13
|
private principalResolver?;
|
|
14
|
-
constructor(model: Constructor<T>, crudRepository: ICrudRepository<T>,
|
|
14
|
+
constructor(model: Constructor<T>, crudRepository: ICrudRepository<T>, db: ITransactionFactory & IQueryProvider);
|
|
15
15
|
protected getMountedUrl(): string;
|
|
16
16
|
private getAuthProvider;
|
|
17
17
|
/**
|
|
@@ -19,14 +19,14 @@ import { AbstractHttpController } from "./AbstractHttpController";
|
|
|
19
19
|
export class CrudHttpController extends AbstractHttpController {
|
|
20
20
|
model;
|
|
21
21
|
crudRepository;
|
|
22
|
-
|
|
22
|
+
db;
|
|
23
23
|
modelMetadata;
|
|
24
24
|
principalResolver;
|
|
25
|
-
constructor(model, crudRepository,
|
|
26
|
-
super(
|
|
25
|
+
constructor(model, crudRepository, db) {
|
|
26
|
+
super(db);
|
|
27
27
|
this.model = model;
|
|
28
28
|
this.crudRepository = crudRepository;
|
|
29
|
-
this.
|
|
29
|
+
this.db = db;
|
|
30
30
|
this.modelMetadata = getObjectMetadata(model);
|
|
31
31
|
}
|
|
32
32
|
getMountedUrl() {
|
|
@@ -197,7 +197,7 @@ export class CrudHttpController extends AbstractHttpController {
|
|
|
197
197
|
async getMany(req) {
|
|
198
198
|
const result = await this.crudRepository.getMany({
|
|
199
199
|
queries: req.getQuery(),
|
|
200
|
-
queryProvider: this.
|
|
200
|
+
queryProvider: this.db,
|
|
201
201
|
});
|
|
202
202
|
return ResponseBuilder.json(result).get();
|
|
203
203
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AbstractLogger, AbstractModel, Constructor, CreateManyRequestBody, CreateManyResponseBody, DeepPartial, GetManyQueries, GetManyResponseBody, Identifiable, UpdateManyBody, UpdateManyQueries, UpdateManyResponse } from "@clairejs/core";
|
|
2
|
-
import { IQueryProvider, ITransaction, QueryCondition } from "@clairejs/orm";
|
|
2
|
+
import { AbstractDbAdapter, IQueryProvider, ITransaction, QueryCondition } from "@clairejs/orm";
|
|
3
3
|
import { IPrincipal } from "../../common/auth/IPrincipal";
|
|
4
4
|
import { AbstractRepository } from "./AbstractRepository";
|
|
5
5
|
import { ICrudRepository } from "./ICrudRepository";
|
|
@@ -30,8 +30,9 @@ export declare const MultipleMap: <R extends Identifiable, K extends AbstractMod
|
|
|
30
30
|
};
|
|
31
31
|
export declare class DtoRepository<T extends Identifiable> extends AbstractRepository<T> implements ICrudRepository<T> {
|
|
32
32
|
protected readonly model: Constructor<T>;
|
|
33
|
+
protected readonly db: AbstractDbAdapter;
|
|
33
34
|
protected readonly dissolver: DtoDissolver<T, any>;
|
|
34
|
-
constructor(model: Constructor<T>, dissolver: DtoDissolver<T, any>);
|
|
35
|
+
constructor(model: Constructor<T>, db: AbstractDbAdapter, dissolver: DtoDissolver<T, any>);
|
|
35
36
|
private getMapValue;
|
|
36
37
|
createMany({ principal, body, tx, logger, }: {
|
|
37
38
|
principal?: IPrincipal | undefined;
|
|
@@ -25,10 +25,12 @@ export const MultipleMap = (modelClass, forwardOps, forwardMapping, rootMapping,
|
|
|
25
25
|
});
|
|
26
26
|
export class DtoRepository extends AbstractRepository {
|
|
27
27
|
model;
|
|
28
|
+
db;
|
|
28
29
|
dissolver;
|
|
29
|
-
constructor(model, dissolver) {
|
|
30
|
+
constructor(model, db, dissolver) {
|
|
30
31
|
super(model);
|
|
31
32
|
this.model = model;
|
|
33
|
+
this.db = db;
|
|
32
34
|
this.dissolver = dissolver;
|
|
33
35
|
}
|
|
34
36
|
async getMapValue(root, currentInstancesResolver, mappers, preOperator, postOperator) {
|
|
@@ -56,7 +58,7 @@ export class DtoRepository extends AbstractRepository {
|
|
|
56
58
|
await this.beforeCreating(principal, body.records);
|
|
57
59
|
for (const record of body.records) {
|
|
58
60
|
await this.getMapValue(record, async (mapper) => {
|
|
59
|
-
const repo = new ModelRepository(mapper.modelClass);
|
|
61
|
+
const repo = new ModelRepository(mapper.modelClass, this.db);
|
|
60
62
|
const currentInstances = await repo.getMany({
|
|
61
63
|
ops: mapper.forwardOps(),
|
|
62
64
|
queryProvider: tx,
|
|
@@ -67,7 +69,7 @@ export class DtoRepository extends AbstractRepository {
|
|
|
67
69
|
if (!ks) {
|
|
68
70
|
return [];
|
|
69
71
|
}
|
|
70
|
-
const repo = new ModelRepository(mapper.modelClass);
|
|
72
|
+
const repo = new ModelRepository(mapper.modelClass, this.db);
|
|
71
73
|
const ops = mapper.forwardOps();
|
|
72
74
|
if (mapper.multiple) {
|
|
73
75
|
//-- if ks contain an array of instances, we need to remove old instances and create new ones
|
|
@@ -118,7 +120,7 @@ export class DtoRepository extends AbstractRepository {
|
|
|
118
120
|
const result = { ...body.update, id: queries.fields.id[0] };
|
|
119
121
|
await this.beforeCreating(principal, [result]);
|
|
120
122
|
await this.getMapValue(result, async (mapper) => {
|
|
121
|
-
const repo = new ModelRepository(mapper.modelClass);
|
|
123
|
+
const repo = new ModelRepository(mapper.modelClass, this.db);
|
|
122
124
|
const currentInstances = await repo.getMany({
|
|
123
125
|
ops: mapper.forwardOps(ops),
|
|
124
126
|
queryProvider: tx,
|
|
@@ -129,7 +131,7 @@ export class DtoRepository extends AbstractRepository {
|
|
|
129
131
|
if (!ks) {
|
|
130
132
|
return [];
|
|
131
133
|
}
|
|
132
|
-
const repo = new ModelRepository(mapper.modelClass);
|
|
134
|
+
const repo = new ModelRepository(mapper.modelClass, this.db);
|
|
133
135
|
const opsx = mapper.forwardOps(ops);
|
|
134
136
|
if (mapper.multiple) {
|
|
135
137
|
//-- if ks contain an array of instances, we need to remove old instances and create new ones
|
|
@@ -178,7 +180,7 @@ export class DtoRepository extends AbstractRepository {
|
|
|
178
180
|
}
|
|
179
181
|
const result = { id: queries.fields.id[0] };
|
|
180
182
|
await this.getMapValue(result, async () => [], this.dissolver(result), async (mapper) => {
|
|
181
|
-
const repo = new ModelRepository(mapper.modelClass);
|
|
183
|
+
const repo = new ModelRepository(mapper.modelClass, this.db);
|
|
182
184
|
//-- forward get
|
|
183
185
|
const instances = await repo.getMany({
|
|
184
186
|
ops: mapper.forwardOps(ops),
|
|
@@ -198,7 +200,7 @@ export class DtoRepository extends AbstractRepository {
|
|
|
198
200
|
}
|
|
199
201
|
const result = { id: queries.fields.id[0] };
|
|
200
202
|
await this.getMapValue(result, async () => [], this.dissolver(result), undefined, async (mapper) => {
|
|
201
|
-
const repo = new ModelRepository(mapper.modelClass);
|
|
203
|
+
const repo = new ModelRepository(mapper.modelClass, this.db);
|
|
202
204
|
//const nestedQueries = mapper.forwardQuery();
|
|
203
205
|
const nestedOps = mapper.forwardOps(ops);
|
|
204
206
|
const result = await repo.deleteMany({
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { AbstractModel, Constructor, CreateManyRequestBody, CreateManyResponseBody, GetManyQueries, GetManyResponseBody, UpdateManyBody, UpdateManyQueries, UpdateManyResponse, AbstractLogger } from "@clairejs/core";
|
|
2
|
-
import { IQueryProvider, ITransaction, QueryCondition } from "@clairejs/orm";
|
|
2
|
+
import { AbstractDbAdapter, 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
7
|
protected readonly model: Constructor<T>;
|
|
8
|
+
protected readonly db: AbstractDbAdapter;
|
|
8
9
|
private fileUploadHandler?;
|
|
9
|
-
constructor(model: Constructor<T
|
|
10
|
+
constructor(model: Constructor<T>, db: AbstractDbAdapter);
|
|
10
11
|
private getNestedQueries;
|
|
11
12
|
private getUploadHandler;
|
|
12
13
|
private getRequestQueryConditionFromQuery;
|
|
@@ -6,10 +6,12 @@ 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
|
+
db;
|
|
9
10
|
fileUploadHandler;
|
|
10
|
-
constructor(model) {
|
|
11
|
+
constructor(model, db) {
|
|
11
12
|
super(model);
|
|
12
13
|
this.model = model;
|
|
14
|
+
this.db = db;
|
|
13
15
|
}
|
|
14
16
|
getNestedQueries(queries) {
|
|
15
17
|
return this.modelMetadata.fields
|
|
@@ -229,8 +231,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
229
231
|
}
|
|
230
232
|
}
|
|
231
233
|
//-- create locale entries
|
|
232
|
-
const translationEntryData = originalRecords
|
|
233
|
-
.map((record, index) => {
|
|
234
|
+
const translationEntryData = originalRecords.flatMap((record, index) => {
|
|
234
235
|
return localeFields
|
|
235
236
|
.filter((f) => !!record[f.name])
|
|
236
237
|
.map((f) => ({
|
|
@@ -238,29 +239,26 @@ export class ModelRepository extends AbstractRepository {
|
|
|
238
239
|
field: f.name,
|
|
239
240
|
entryObject: {},
|
|
240
241
|
}));
|
|
241
|
-
})
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
.use(LocaleEntry)
|
|
242
|
+
});
|
|
243
|
+
const translationEntries = await this.db
|
|
244
|
+
.use(LocaleEntry, tx)
|
|
245
245
|
.createMany(translationEntryData.map((data) => data.entryObject));
|
|
246
246
|
//-- translation data will have same length as translationEntries
|
|
247
|
-
const translationData = originalRecords
|
|
248
|
-
.map((record) => {
|
|
247
|
+
const translationData = originalRecords.flatMap((record) => {
|
|
249
248
|
return localeFields.filter((f) => !!record[f.name]).map((f) => record[f.name]);
|
|
250
|
-
})
|
|
251
|
-
.flatMap((arr) => arr);
|
|
249
|
+
});
|
|
252
250
|
//-- mapping supplied data with entry ids
|
|
253
|
-
const translations = translationData
|
|
254
|
-
.
|
|
255
|
-
|
|
251
|
+
const translations = translationData.flatMap((data, index) => {
|
|
252
|
+
return Object.keys(data)
|
|
253
|
+
.filter((locale) => locale !== systemLocale)
|
|
254
|
+
.map((localeCode) => ({
|
|
256
255
|
localeCode,
|
|
257
256
|
entryId: translationEntries[index].id,
|
|
258
257
|
translation: data[localeCode],
|
|
259
258
|
}));
|
|
260
|
-
})
|
|
261
|
-
.flatMap((arr) => arr);
|
|
259
|
+
});
|
|
262
260
|
//-- create translation records
|
|
263
|
-
await
|
|
261
|
+
await this.db.use(LocaleTranslation, tx).createMany(translations);
|
|
264
262
|
//-- first create records for direct fields
|
|
265
263
|
body.records = originalRecords.map((record, index) => {
|
|
266
264
|
const data = directFields.reduce((collector, field) => {
|
|
@@ -282,7 +280,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
282
280
|
return data;
|
|
283
281
|
});
|
|
284
282
|
await this.beforeCreating(principal, body.records);
|
|
285
|
-
let records = body.records.length ? await
|
|
283
|
+
let records = body.records.length ? await this.db.use(this.model, tx).createMany(body.records) : [];
|
|
286
284
|
await this.beforeReturning(records);
|
|
287
285
|
const projection = this.modelMetadata.fields
|
|
288
286
|
.filter((field) => !field.multiLocaleColumn && (field.pk || field.serverValue || field.mimeProps))
|
|
@@ -305,7 +303,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
305
303
|
});
|
|
306
304
|
if (hasManyRecords.length) {
|
|
307
305
|
//-- insert to db
|
|
308
|
-
const innerService = new ModelRepository(getModelById(field.hasMany.relationDto.id));
|
|
306
|
+
const innerService = new ModelRepository(getModelById(field.hasMany.relationDto.id), this.db);
|
|
309
307
|
body.records = hasManyRecords;
|
|
310
308
|
const persistedInnerRecords = await innerService.createMany({ principal, body, tx });
|
|
311
309
|
//-- map back ids to hasManyRecords
|
|
@@ -343,7 +341,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
343
341
|
const localeOfFields = this.modelMetadata.fields.filter((f) => updatedFields.includes(f.name) && f.multiLocaleColumn);
|
|
344
342
|
const cleanUp = await this.uriHandling([body.update]);
|
|
345
343
|
//-- calculate direct update after uri handling
|
|
346
|
-
const directUpdate = leanData(directUpdateFields.
|
|
344
|
+
const directUpdate = leanData(Object.fromEntries(directUpdateFields.map((field) => [field.name, body.update[field.name]]))) || {};
|
|
347
345
|
if (systemLocale) {
|
|
348
346
|
//-- override values in record
|
|
349
347
|
for (const field of localeOfFields) {
|
|
@@ -366,12 +364,12 @@ export class ModelRepository extends AbstractRepository {
|
|
|
366
364
|
let modified = [];
|
|
367
365
|
let updatedRecords = [];
|
|
368
366
|
if (nestedQueries.length) {
|
|
369
|
-
const tobeUpdated = await
|
|
367
|
+
const tobeUpdated = await this.db.use(this.model, tx).getMany(condition, { projection: ["id"] }, nestedQueries);
|
|
370
368
|
modified = tobeUpdated.records.map((r) => r.id);
|
|
371
369
|
if (modified.length) {
|
|
372
370
|
if (directUpdateFields.length) {
|
|
373
|
-
updatedRecords = await
|
|
374
|
-
.use(this.model)
|
|
371
|
+
updatedRecords = await this.db
|
|
372
|
+
.use(this.model, tx)
|
|
375
373
|
.updateMany({ _in: { id: modified } }, directUpdate, true);
|
|
376
374
|
}
|
|
377
375
|
else {
|
|
@@ -381,21 +379,21 @@ export class ModelRepository extends AbstractRepository {
|
|
|
381
379
|
}
|
|
382
380
|
else {
|
|
383
381
|
if (directUpdateFields.length) {
|
|
384
|
-
updatedRecords = await
|
|
382
|
+
updatedRecords = await this.db.use(this.model, tx).updateMany(condition, directUpdate, true);
|
|
385
383
|
modified = updatedRecords.map((re) => re.id);
|
|
386
384
|
}
|
|
387
385
|
else {
|
|
388
|
-
const tobeUpdated = await
|
|
386
|
+
const tobeUpdated = await this.db.use(this.model, tx).getMany(condition, { projection: ["id"] });
|
|
389
387
|
modified = tobeUpdated.records.map((r) => r.id);
|
|
390
388
|
updatedRecords = modified.map((id) => ({ id }));
|
|
391
389
|
}
|
|
392
390
|
}
|
|
393
391
|
//-- body.update here had been modified by uri handling
|
|
394
|
-
const records = updatedRecords.map((re) => ({ ...body.update, ...re }));
|
|
392
|
+
const records = updatedRecords.map((re) => ({ ...body.update, ...directUpdate, ...re }));
|
|
395
393
|
//-- update translations
|
|
396
394
|
if (localeOfFields.length) {
|
|
397
395
|
//-- check if there is missing locale entry for localeFields
|
|
398
|
-
const records = await
|
|
396
|
+
const records = await this.db.use(this.model, tx).getRecords({
|
|
399
397
|
_in: { id: modified },
|
|
400
398
|
}, { projection: ["id", ...localeOfFields.map((f) => f.name)] });
|
|
401
399
|
//-- check missing
|
|
@@ -407,7 +405,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
407
405
|
field: field.name,
|
|
408
406
|
})))
|
|
409
407
|
.flatMap((arr) => arr);
|
|
410
|
-
const missingEntries = !missing.length ? [] : await
|
|
408
|
+
const missingEntries = !missing.length ? [] : await this.db.use(LocaleEntry, tx).createMany(missing.map(() => ({})));
|
|
411
409
|
const updateEntryRecords = [];
|
|
412
410
|
missingEntries.forEach((entry, index) => {
|
|
413
411
|
const missingData = missing[index];
|
|
@@ -424,7 +422,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
424
422
|
}
|
|
425
423
|
});
|
|
426
424
|
//-- update records
|
|
427
|
-
await Promise.all(updateEntryRecords.map((re) =>
|
|
425
|
+
await Promise.all(updateEntryRecords.map((re) => this.db.use(this.model, tx).updateById(re.id, omitData(re, ["id"]))));
|
|
428
426
|
const tobeModified = [];
|
|
429
427
|
for (const field of localeOfFields) {
|
|
430
428
|
const localOfData = body.update[field.name];
|
|
@@ -442,13 +440,13 @@ export class ModelRepository extends AbstractRepository {
|
|
|
442
440
|
}
|
|
443
441
|
if (tobeModified.length) {
|
|
444
442
|
//-- remove old translations
|
|
445
|
-
await
|
|
443
|
+
await this.db.use(LocaleTranslation, tx).deleteMany({
|
|
446
444
|
_or: tobeModified.map((rem) => ({
|
|
447
445
|
_eq: { entryId: rem.entryId, localeCode: rem.langCode },
|
|
448
446
|
})),
|
|
449
447
|
});
|
|
450
448
|
//-- add new translations
|
|
451
|
-
await
|
|
449
|
+
await this.db.use(LocaleTranslation, tx).createMany(tobeModified.map((rem) => ({
|
|
452
450
|
entryId: rem.entryId,
|
|
453
451
|
localeCode: rem.langCode,
|
|
454
452
|
translation: rem.translation,
|
|
@@ -467,7 +465,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
467
465
|
const theRecord = records.find((r) => r.id === modified[0]);
|
|
468
466
|
//-- get all inner records and compare
|
|
469
467
|
const model = getModelById(field.hasMany.relationDto.id);
|
|
470
|
-
const adapter =
|
|
468
|
+
const adapter = this.db.use(model, tx);
|
|
471
469
|
const allInnerRecords = await adapter.getRecords({ _eq: { [field.hasMany.column]: theRecord.id } }, { limit: field.hasMany?.single ? 1 : undefined });
|
|
472
470
|
const currentIds = allInnerRecords.map((r) => r.id);
|
|
473
471
|
const newIds = innerUpdates.map((r) => r.id).filter((id) => !!id);
|
|
@@ -479,7 +477,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
479
477
|
if (tobeRemovedIds.length) {
|
|
480
478
|
await adapter.deleteMany({ _in: { id: tobeRemovedIds } });
|
|
481
479
|
}
|
|
482
|
-
const modelService = new ModelRepository(model);
|
|
480
|
+
const modelService = new ModelRepository(model, this.db);
|
|
483
481
|
const added = await modelService.createMany({
|
|
484
482
|
principal,
|
|
485
483
|
body: { records: tobeAdded },
|
|
@@ -505,7 +503,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
505
503
|
//-- return result
|
|
506
504
|
projection = [
|
|
507
505
|
...projection,
|
|
508
|
-
...Object.keys(
|
|
506
|
+
...Object.keys(directUpdate).filter((key) => directUpdate[key] !== undefined),
|
|
509
507
|
"lastModified",
|
|
510
508
|
];
|
|
511
509
|
}
|
|
@@ -571,13 +569,13 @@ export class ModelRepository extends AbstractRepository {
|
|
|
571
569
|
//-- map back translation
|
|
572
570
|
if (!queries?.locale) {
|
|
573
571
|
//-- map as object
|
|
574
|
-
const fieldTranslations = translations
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
record[field.name] = fieldTranslations.reduce((collector, t) => Object.assign(collector, { [t.localeCode]: t.translation }), {});
|
|
572
|
+
const fieldTranslations = translations
|
|
573
|
+
.filter((t) => t.entryId === record[field.name])
|
|
574
|
+
.map((t) => [t.localeCode, t.translation]);
|
|
575
|
+
if (systemLocale) {
|
|
576
|
+
fieldTranslations.push([systemLocale, record[field.multiLocaleColumn]]);
|
|
580
577
|
}
|
|
578
|
+
record[field.name] = Object.fromEntries(fieldTranslations);
|
|
581
579
|
}
|
|
582
580
|
else {
|
|
583
581
|
//-- replace value
|
|
@@ -597,7 +595,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
597
595
|
if (!model) {
|
|
598
596
|
throw Errors.NOT_FOUND(`Model not found by id: ${field.hasMany.relationDto.id}`);
|
|
599
597
|
}
|
|
600
|
-
const service = new ModelRepository(model);
|
|
598
|
+
const service = new ModelRepository(model, this.db);
|
|
601
599
|
const innerRecords = !recordIds.length
|
|
602
600
|
? { records: [] }
|
|
603
601
|
: await service.getMany({
|
|
@@ -631,10 +629,10 @@ export class ModelRepository extends AbstractRepository {
|
|
|
631
629
|
const uriMapperFields = this.modelMetadata.fields.filter((f) => f.uriMapper);
|
|
632
630
|
const localeOfFields = this.modelMetadata.fields.filter((f) => f.multiLocaleColumn);
|
|
633
631
|
if (nestedQueries.length || localeOfFields.length || uriMapperFields.length) {
|
|
634
|
-
const tobeRemoved = await
|
|
635
|
-
.use(this.model)
|
|
632
|
+
const tobeRemoved = await this.db
|
|
633
|
+
.use(this.model, tx)
|
|
636
634
|
.getRecords(condition, { projection: ["id", ...[...localeOfFields, ...uriMapperFields].map((f) => f.name)] }, nestedQueries);
|
|
637
|
-
await
|
|
635
|
+
await this.db.use(this.model, tx).deleteMany({
|
|
638
636
|
_in: { id: tobeRemoved.map((r) => r.id) },
|
|
639
637
|
});
|
|
640
638
|
//-- collect uri to remove
|
|
@@ -659,8 +657,8 @@ export class ModelRepository extends AbstractRepository {
|
|
|
659
657
|
}
|
|
660
658
|
if (localeUriLocalEntryIds.length) {
|
|
661
659
|
//-- get all uris and add to remove list
|
|
662
|
-
const records = await
|
|
663
|
-
.use(LocaleTranslation)
|
|
660
|
+
const records = await this.db
|
|
661
|
+
.use(LocaleTranslation, tx)
|
|
664
662
|
.getRecords({ _in: { entryId: localeUriLocalEntryIds } }, { projection: ["translation"] });
|
|
665
663
|
for (const record of records) {
|
|
666
664
|
if (record.translation) {
|
|
@@ -675,7 +673,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
675
673
|
.filter((id) => !!id);
|
|
676
674
|
//-- remove locale entry, will cascade locale translations
|
|
677
675
|
if (localeEntryIds.length) {
|
|
678
|
-
await
|
|
676
|
+
await this.db.use(LocaleEntry, tx).deleteMany({ _in: { id: localeEntryIds } });
|
|
679
677
|
}
|
|
680
678
|
//-- remove uris
|
|
681
679
|
if (toBeRemovedUris.length) {
|
|
@@ -687,7 +685,7 @@ export class ModelRepository extends AbstractRepository {
|
|
|
687
685
|
returning = tobeRemoved;
|
|
688
686
|
}
|
|
689
687
|
else {
|
|
690
|
-
returning = await
|
|
688
|
+
returning = await this.db.use(this.model, tx).deleteMany(condition, queries?.returning);
|
|
691
689
|
}
|
|
692
690
|
return { modified: returning };
|
|
693
691
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CustomJobInfo } from "./interfaces";
|
|
1
|
+
import { type ITransaction } from "@clairejs/orm";
|
|
2
|
+
import { type CustomJobInfo } from "./interfaces";
|
|
3
3
|
export declare abstract class AbstractJobRepository<T extends CustomJobInfo> {
|
|
4
4
|
/**
|
|
5
5
|
* Return all persisted jobs
|
|
6
6
|
*/
|
|
7
|
-
abstract getJobs(
|
|
7
|
+
abstract getJobs(): Promise<T[]>;
|
|
8
8
|
/**
|
|
9
9
|
* Save the job info and return a unique id
|
|
10
10
|
* @param jobInfo The custom job info to save
|
|
11
11
|
*/
|
|
12
|
-
abstract saveJob(jobInfo: T,
|
|
12
|
+
abstract saveJob(jobInfo: T, tx?: ITransaction): Promise<string>;
|
|
13
13
|
/**
|
|
14
14
|
* Remove job info by id
|
|
15
15
|
* @param id Unique id of job
|
|
16
16
|
*/
|
|
17
|
-
abstract removeJobById(id: string,
|
|
17
|
+
abstract removeJobById(id: string, tx?: ITransaction): Promise<void>;
|
|
18
18
|
}
|
|
@@ -180,7 +180,7 @@ let LocalJobScheduler = class LocalJobScheduler extends AbstractJobScheduler {
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
//-- re-schedule jobs that are stored in repo
|
|
183
|
-
const allPersistedJobs = await this.jobRepo.getJobs(
|
|
183
|
+
const allPersistedJobs = await this.jobRepo.getJobs();
|
|
184
184
|
//-- run job anyway, expired job will be removed then
|
|
185
185
|
for (const job of allPersistedJobs) {
|
|
186
186
|
await this.scheduleJob(job);
|
|
@@ -205,7 +205,7 @@ let LocalJobScheduler = class LocalJobScheduler extends AbstractJobScheduler {
|
|
|
205
205
|
jobName: jobInfo.jobName,
|
|
206
206
|
params: jobInfo.params,
|
|
207
207
|
at: jobInfo.at,
|
|
208
|
-
}
|
|
208
|
+
}));
|
|
209
209
|
//-- use the lib
|
|
210
210
|
const scheduledJob = { ...jobInfo, id };
|
|
211
211
|
const timeout = setTimeout(() => {
|
|
@@ -256,7 +256,7 @@ let LocalJobScheduler = class LocalJobScheduler extends AbstractJobScheduler {
|
|
|
256
256
|
this.jobHolder[id] = undefined;
|
|
257
257
|
}
|
|
258
258
|
//-- remove from persistence
|
|
259
|
-
await this.jobRepo.removeJobById(id
|
|
259
|
+
await this.jobRepo.removeJobById(id);
|
|
260
260
|
}
|
|
261
261
|
else {
|
|
262
262
|
//-- get unique message id
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { AbstractModel, Constructor } from "@clairejs/core";
|
|
2
|
-
import {
|
|
2
|
+
import { type ITransaction, AbstractDbAdapter } from "@clairejs/orm";
|
|
3
3
|
import { CustomJobInfo } from "./interfaces";
|
|
4
4
|
import { AbstractJobRepository } from "./AbstractJobRepository";
|
|
5
5
|
export declare class DefaultJobRepository<T extends CustomJobInfo & AbstractModel> extends AbstractJobRepository<T> {
|
|
6
6
|
protected readonly model: Constructor<T>;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
protected db: AbstractDbAdapter;
|
|
8
|
+
constructor(model: Constructor<T>, db: AbstractDbAdapter);
|
|
9
|
+
getJobs(): Promise<T[]>;
|
|
10
|
+
saveJob({ id, ...jobInfo }: T, tx?: ITransaction): Promise<string>;
|
|
11
|
+
removeJobById(id: string, tx?: ITransaction): Promise<void>;
|
|
11
12
|
}
|
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
import { AbstractJobRepository } from "./AbstractJobRepository";
|
|
2
2
|
export class DefaultJobRepository extends AbstractJobRepository {
|
|
3
3
|
model;
|
|
4
|
-
|
|
4
|
+
db;
|
|
5
|
+
constructor(model, db) {
|
|
5
6
|
super();
|
|
6
7
|
this.model = model;
|
|
8
|
+
this.db = db;
|
|
7
9
|
}
|
|
8
|
-
async getJobs(
|
|
9
|
-
const jobs = await
|
|
10
|
+
async getJobs() {
|
|
11
|
+
const jobs = await this.db.use(this.model).getRecords();
|
|
10
12
|
return jobs;
|
|
11
13
|
}
|
|
12
|
-
async saveJob({ id, ...jobInfo },
|
|
14
|
+
async saveJob({ id, ...jobInfo }, tx) {
|
|
13
15
|
if (id) {
|
|
14
16
|
//-- update
|
|
15
|
-
await
|
|
17
|
+
await this.db.use(this.model, tx).updateById(id, jobInfo);
|
|
16
18
|
}
|
|
17
19
|
else {
|
|
18
20
|
//-- create new
|
|
19
|
-
const job = await
|
|
21
|
+
const job = await this.db.use(this.model, tx).createOne(jobInfo);
|
|
20
22
|
id = job.id;
|
|
21
23
|
}
|
|
22
24
|
return id;
|
|
23
25
|
}
|
|
24
|
-
async removeJobById(id,
|
|
25
|
-
await
|
|
26
|
+
async removeJobById(id, tx) {
|
|
27
|
+
await this.db.use(this.model, tx).deleteById(id);
|
|
26
28
|
}
|
|
27
29
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clairejs/server",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.19.0",
|
|
4
4
|
"description": "Claire server NodeJs framework written in Typescript.",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@clairejs/core": "^3.7.9",
|
|
37
|
-
"@clairejs/orm": "^3.
|
|
37
|
+
"@clairejs/orm": "^3.15.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/cookie-parser": "^1.4.3",
|