@clairejs/server 3.18.2 → 3.19.1

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,5 +1,10 @@
1
1
  ## Change Log
2
2
 
3
+ #### 3.19.1:
4
+
5
+ - fix ModelRepository getMany
6
+ - adapt interface with new claire orm
7
+
3
8
  #### 3.18.2:
4
9
 
5
10
  - fix multi locale issue with model repo
@@ -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 databaseAdapter: ITransactionFactory;
6
- constructor(databaseAdapter: ITransactionFactory);
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
- databaseAdapter;
8
- constructor(databaseAdapter) {
9
- super(databaseAdapter);
10
- this.databaseAdapter = databaseAdapter;
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 databaseAdapter: ITransactionFactory & IQueryProvider;
11
+ protected readonly db: ITransactionFactory & IQueryProvider;
12
12
  protected readonly modelMetadata: ModelMetadata;
13
13
  private principalResolver?;
14
- constructor(model: Constructor<T>, crudRepository: ICrudRepository<T>, databaseAdapter: ITransactionFactory & IQueryProvider);
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
- databaseAdapter;
22
+ db;
23
23
  modelMetadata;
24
24
  principalResolver;
25
- constructor(model, crudRepository, databaseAdapter) {
26
- super(databaseAdapter);
25
+ constructor(model, crudRepository, db) {
26
+ super(db);
27
27
  this.model = model;
28
28
  this.crudRepository = crudRepository;
29
- this.databaseAdapter = databaseAdapter;
29
+ this.db = db;
30
30
  this.modelMetadata = getObjectMetadata(model);
31
31
  }
32
32
  getMountedUrl() {
@@ -197,7 +197,6 @@ 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.databaseAdapter,
201
200
  });
202
201
  return ResponseBuilder.json(result).get();
203
202
  }
@@ -1,8 +1,8 @@
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";
3
- import { IPrincipal } from "../../common/auth/IPrincipal";
1
+ import { type Identifiable, type Constructor, type CreateManyRequestBody, type CreateManyResponseBody, type DeepPartial, type GetManyQueries, type GetManyResponseBody, type UpdateManyBody, type UpdateManyQueries, type UpdateManyResponse, AbstractLogger, AbstractModel } from "@clairejs/core";
2
+ import { type ITransaction, type QueryCondition, AbstractDbAdapter } from "@clairejs/orm";
3
+ import { type IPrincipal } from "../../common/auth/IPrincipal";
4
4
  import { AbstractRepository } from "./AbstractRepository";
5
- import { ICrudRepository } from "./ICrudRepository";
5
+ import { type ICrudRepository } from "./ICrudRepository";
6
6
  export type DtoDissolver<R extends Identifiable, K extends Identifiable> = (t: DeepPartial<K>) => MappingMetadata<R, any>[];
7
7
  export interface MappingMetadata<R extends Identifiable, K extends AbstractModel> {
8
8
  multiple: boolean;
@@ -30,13 +30,14 @@ 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;
38
39
  body: CreateManyRequestBody<T>;
39
- tx: ITransaction & IQueryProvider;
40
+ tx: ITransaction;
40
41
  logger?: AbstractLogger;
41
42
  }): Promise<CreateManyResponseBody<T>>;
42
43
  updateMany({ principal, queries, ops, body, tx, logger, }: {
@@ -44,13 +45,13 @@ export declare class DtoRepository<T extends Identifiable> extends AbstractRepos
44
45
  queries?: UpdateManyQueries<T>;
45
46
  ops?: QueryCondition<T>[];
46
47
  body: UpdateManyBody<T>;
47
- tx: ITransaction & IQueryProvider;
48
+ tx: ITransaction;
48
49
  logger?: AbstractLogger;
49
50
  }): Promise<UpdateManyResponse<T>>;
50
- getMany({ queries, ops, queryProvider, logger, }: {
51
+ getMany({ queries, ops, tx, logger, }: {
51
52
  queries?: GetManyQueries<T>;
52
53
  ops?: QueryCondition<T>[];
53
- queryProvider: IQueryProvider;
54
+ tx?: ITransaction;
54
55
  logger?: AbstractLogger;
55
56
  }): Promise<GetManyResponseBody<T>>;
56
57
  deleteMany({ queries, ops, tx, logger, }: {
@@ -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,10 +58,10 @@ 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
- queryProvider: tx,
64
+ tx,
63
65
  logger,
64
66
  });
65
67
  return currentInstances.records;
@@ -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,10 +120,10 @@ 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
- queryProvider: tx,
126
+ tx,
125
127
  logger,
126
128
  });
127
129
  return currentInstances.records;
@@ -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
@@ -171,18 +173,18 @@ export class DtoRepository extends AbstractRepository {
171
173
  }
172
174
  return { modified: result.id ? this.project([result], projection) : [] };
173
175
  }
174
- async getMany({ queries, ops, queryProvider, logger, }) {
176
+ async getMany({ queries, ops, tx, logger, }) {
175
177
  //-- check queries for id field
176
178
  if (!queries?.fields?.id || queries.fields.id.length !== 1) {
177
179
  throw Errors.VALIDATION_ERROR("Missing required id field in query");
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),
185
- queryProvider,
187
+ tx,
186
188
  logger,
187
189
  });
188
190
  return instances.records;
@@ -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,5 +1,5 @@
1
1
  import { type AbstractLogger, type CreateManyRequestBody, type CreateManyResponseBody, type GetManyQueries, type GetManyResponseBody, type UpdateManyBody, type UpdateManyQueries, type UpdateManyResponse } from "@clairejs/core";
2
- import { type IQueryProvider, type ITransaction, type QueryCondition } from "@clairejs/orm";
2
+ import { type ITransaction, type QueryCondition } from "@clairejs/orm";
3
3
  import { type IPrincipal } from "../../common/auth/IPrincipal";
4
4
  export interface ICrudRepository<T> {
5
5
  createMany({ principal, body, tx, logger, }: {
@@ -8,10 +8,10 @@ export interface ICrudRepository<T> {
8
8
  logger?: AbstractLogger;
9
9
  principal?: IPrincipal;
10
10
  }): Promise<CreateManyResponseBody<T>>;
11
- getMany({ queries, ops, queryProvider, logger, }: {
11
+ getMany({ queries, ops, tx, logger, }: {
12
12
  queries?: GetManyQueries<T>;
13
13
  ops?: QueryCondition<T>[];
14
- queryProvider: IQueryProvider;
14
+ tx?: ITransaction;
15
15
  logger?: AbstractLogger;
16
16
  }): Promise<GetManyResponseBody<T>>;
17
17
  updateMany({ principal, queries, ops, body, tx, logger, }: {
@@ -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, 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;
@@ -26,10 +27,10 @@ export declare class ModelRepository<T extends AbstractModel> extends AbstractRe
26
27
  tx: ITransaction;
27
28
  logger?: AbstractLogger;
28
29
  }): Promise<UpdateManyResponse<T>>;
29
- getMany({ queries, ops, queryProvider, logger, }: {
30
+ getMany({ queries, ops, tx, logger, }: {
30
31
  queries?: GetManyQueries<T>;
31
32
  ops?: QueryCondition<T>[];
32
- queryProvider: IQueryProvider;
33
+ tx?: ITransaction;
33
34
  logger?: AbstractLogger;
34
35
  }): Promise<GetManyResponseBody<T>>;
35
36
  deleteMany({ queries, ops, tx, logger, }: {
@@ -1,15 +1,17 @@
1
1
  import { DataType, getModelById, getServiceProvider, RangeQueryDto, uniqueReducer, leanData, getSystemLocale, Errors, omitData, } from "@clairejs/core";
2
- import { getDirectFields } from "@clairejs/orm";
2
+ import { getDirectFields, } from "@clairejs/orm";
3
3
  import { AbstractFileUploadHandler } from "../file-upload/AbstractFileUploadHandler";
4
4
  import { AbstractRepository } from "./AbstractRepository";
5
5
  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
@@ -238,8 +240,8 @@ export class ModelRepository extends AbstractRepository {
238
240
  entryObject: {},
239
241
  }));
240
242
  });
241
- const translationEntries = await tx
242
- .use(LocaleEntry)
243
+ const translationEntries = await this.db
244
+ .use(LocaleEntry, tx)
243
245
  .createMany(translationEntryData.map((data) => data.entryObject));
244
246
  //-- translation data will have same length as translationEntries
245
247
  const translationData = originalRecords.flatMap((record) => {
@@ -256,7 +258,7 @@ export class ModelRepository extends AbstractRepository {
256
258
  }));
257
259
  });
258
260
  //-- create translation records
259
- await tx.use(LocaleTranslation).createMany(translations);
261
+ await this.db.use(LocaleTranslation, tx).createMany(translations);
260
262
  //-- first create records for direct fields
261
263
  body.records = originalRecords.map((record, index) => {
262
264
  const data = directFields.reduce((collector, field) => {
@@ -278,7 +280,9 @@ export class ModelRepository extends AbstractRepository {
278
280
  return data;
279
281
  });
280
282
  await this.beforeCreating(principal, body.records);
281
- let records = body.records.length ? await tx.use(this.model).createMany(body.records) : [];
283
+ let records = body.records.length
284
+ ? await this.db.use(this.model, tx).createMany(body.records)
285
+ : [];
282
286
  await this.beforeReturning(records);
283
287
  const projection = this.modelMetadata.fields
284
288
  .filter((field) => !field.multiLocaleColumn && (field.pk || field.serverValue || field.mimeProps))
@@ -301,7 +305,7 @@ export class ModelRepository extends AbstractRepository {
301
305
  });
302
306
  if (hasManyRecords.length) {
303
307
  //-- insert to db
304
- const innerService = new ModelRepository(getModelById(field.hasMany.relationDto.id));
308
+ const innerService = new ModelRepository(getModelById(field.hasMany.relationDto.id), this.db);
305
309
  body.records = hasManyRecords;
306
310
  const persistedInnerRecords = await innerService.createMany({ principal, body, tx });
307
311
  //-- map back ids to hasManyRecords
@@ -362,12 +366,14 @@ export class ModelRepository extends AbstractRepository {
362
366
  let modified = [];
363
367
  let updatedRecords = [];
364
368
  if (nestedQueries.length) {
365
- const tobeUpdated = await tx.use(this.model).getMany(condition, { projection: ["id"] }, nestedQueries);
369
+ const tobeUpdated = await this.db
370
+ .use(this.model, tx)
371
+ .getMany(condition, { projection: ["id"] }, nestedQueries);
366
372
  modified = tobeUpdated.records.map((r) => r.id);
367
373
  if (modified.length) {
368
374
  if (directUpdateFields.length) {
369
- updatedRecords = await tx
370
- .use(this.model)
375
+ updatedRecords = await this.db
376
+ .use(this.model, tx)
371
377
  .updateMany({ _in: { id: modified } }, directUpdate, true);
372
378
  }
373
379
  else {
@@ -377,11 +383,11 @@ export class ModelRepository extends AbstractRepository {
377
383
  }
378
384
  else {
379
385
  if (directUpdateFields.length) {
380
- updatedRecords = await tx.use(this.model).updateMany(condition, directUpdate, true);
386
+ updatedRecords = await this.db.use(this.model, tx).updateMany(condition, directUpdate, true);
381
387
  modified = updatedRecords.map((re) => re.id);
382
388
  }
383
389
  else {
384
- const tobeUpdated = await tx.use(this.model).getMany(condition, { projection: ["id"] });
390
+ const tobeUpdated = await this.db.use(this.model, tx).getMany(condition, { projection: ["id"] });
385
391
  modified = tobeUpdated.records.map((r) => r.id);
386
392
  updatedRecords = modified.map((id) => ({ id }));
387
393
  }
@@ -391,7 +397,7 @@ export class ModelRepository extends AbstractRepository {
391
397
  //-- update translations
392
398
  if (localeOfFields.length) {
393
399
  //-- check if there is missing locale entry for localeFields
394
- const records = await tx.use(this.model).getRecords({
400
+ const records = await this.db.use(this.model, tx).getRecords({
395
401
  _in: { id: modified },
396
402
  }, { projection: ["id", ...localeOfFields.map((f) => f.name)] });
397
403
  //-- check missing
@@ -403,7 +409,9 @@ export class ModelRepository extends AbstractRepository {
403
409
  field: field.name,
404
410
  })))
405
411
  .flatMap((arr) => arr);
406
- const missingEntries = !missing.length ? [] : await tx.use(LocaleEntry).createMany(missing.map(() => ({})));
412
+ const missingEntries = !missing.length
413
+ ? []
414
+ : await this.db.use(LocaleEntry, tx).createMany(missing.map(() => ({})));
407
415
  const updateEntryRecords = [];
408
416
  missingEntries.forEach((entry, index) => {
409
417
  const missingData = missing[index];
@@ -420,7 +428,7 @@ export class ModelRepository extends AbstractRepository {
420
428
  }
421
429
  });
422
430
  //-- update records
423
- await Promise.all(updateEntryRecords.map((re) => tx.use(this.model).updateById(re.id, omitData(re, ["id"]))));
431
+ await Promise.all(updateEntryRecords.map((re) => this.db.use(this.model, tx).updateById(re.id, omitData(re, ["id"]))));
424
432
  const tobeModified = [];
425
433
  for (const field of localeOfFields) {
426
434
  const localOfData = body.update[field.name];
@@ -438,13 +446,13 @@ export class ModelRepository extends AbstractRepository {
438
446
  }
439
447
  if (tobeModified.length) {
440
448
  //-- remove old translations
441
- await tx.use(LocaleTranslation).deleteMany({
449
+ await this.db.use(LocaleTranslation, tx).deleteMany({
442
450
  _or: tobeModified.map((rem) => ({
443
451
  _eq: { entryId: rem.entryId, localeCode: rem.langCode },
444
452
  })),
445
453
  });
446
454
  //-- add new translations
447
- await tx.use(LocaleTranslation).createMany(tobeModified.map((rem) => ({
455
+ await this.db.use(LocaleTranslation, tx).createMany(tobeModified.map((rem) => ({
448
456
  entryId: rem.entryId,
449
457
  localeCode: rem.langCode,
450
458
  translation: rem.translation,
@@ -463,7 +471,7 @@ export class ModelRepository extends AbstractRepository {
463
471
  const theRecord = records.find((r) => r.id === modified[0]);
464
472
  //-- get all inner records and compare
465
473
  const model = getModelById(field.hasMany.relationDto.id);
466
- const adapter = tx.use(model);
474
+ const adapter = this.db.use(model, tx);
467
475
  const allInnerRecords = await adapter.getRecords({ _eq: { [field.hasMany.column]: theRecord.id } }, { limit: field.hasMany?.single ? 1 : undefined });
468
476
  const currentIds = allInnerRecords.map((r) => r.id);
469
477
  const newIds = innerUpdates.map((r) => r.id).filter((id) => !!id);
@@ -475,7 +483,7 @@ export class ModelRepository extends AbstractRepository {
475
483
  if (tobeRemovedIds.length) {
476
484
  await adapter.deleteMany({ _in: { id: tobeRemovedIds } });
477
485
  }
478
- const modelService = new ModelRepository(model);
486
+ const modelService = new ModelRepository(model, this.db);
479
487
  const added = await modelService.createMany({
480
488
  principal,
481
489
  body: { records: tobeAdded },
@@ -510,7 +518,7 @@ export class ModelRepository extends AbstractRepository {
510
518
  await this.beforeReturning(records);
511
519
  return { modified: this.project(records, projection) };
512
520
  }
513
- async getMany({ queries, ops, queryProvider, logger: _logger, }) {
521
+ async getMany({ queries, ops, tx, logger: _logger, }) {
514
522
  const conditions = ops || [];
515
523
  if (queries?.fields) {
516
524
  conditions.push(...this.getRequestQueryConditionFromQuery(queries.fields, this.modelMetadata));
@@ -533,7 +541,7 @@ export class ModelRepository extends AbstractRepository {
533
541
  ...queries.projection.filter((fieldName) => !this.modelMetadata.fields.find((f) => f.name === fieldName && !!f.hasMany)),
534
542
  ...localeOfFields.map((f) => f.name),
535
543
  ];
536
- const result = await queryProvider.use(this.model).getMany(conditions.length ? { _and: conditions } : {}, {
544
+ const result = await this.db.use(this.model, tx).getMany(conditions.length ? { _and: conditions } : {}, {
537
545
  limit: queries?.limit,
538
546
  page: queries?.page,
539
547
  projection: finalProjection,
@@ -551,12 +559,12 @@ export class ModelRepository extends AbstractRepository {
551
559
  ? []
552
560
  : !queries?.locale
553
561
  ? //-- if locale is not specified then get translation for all locales
554
- await queryProvider.use(LocaleTranslation).getRecords({
562
+ await this.db.use(LocaleTranslation, tx).getRecords({
555
563
  _in: { entryId: allLocaleEntries },
556
564
  }, { projection: ["entryId", "localeCode", "translation"] })
557
565
  : //-- if locale is specified then get only the translation of that locale
558
566
  queries.locale.toLowerCase() !== systemLocale
559
- ? await queryProvider.use(LocaleTranslation).getRecords({
567
+ ? await this.db.use(LocaleTranslation, tx).getRecords({
560
568
  _in: { entryId: allLocaleEntries },
561
569
  _eq: { localeCode: queries.locale },
562
570
  }, { projection: ["entryId", "localeCode", "translation"] })
@@ -593,12 +601,12 @@ export class ModelRepository extends AbstractRepository {
593
601
  if (!model) {
594
602
  throw Errors.NOT_FOUND(`Model not found by id: ${field.hasMany.relationDto.id}`);
595
603
  }
596
- const service = new ModelRepository(model);
604
+ const service = new ModelRepository(model, this.db);
597
605
  const innerRecords = !recordIds.length
598
606
  ? { records: [] }
599
607
  : await service.getMany({
600
608
  queries: { fields: { [field.hasMany.column]: recordIds }, limit: field.hasMany.single ? 1 : 0 },
601
- queryProvider,
609
+ tx,
602
610
  });
603
611
  //-- filter corresponding inner records for each master record
604
612
  for (const record of result.records) {
@@ -627,10 +635,10 @@ export class ModelRepository extends AbstractRepository {
627
635
  const uriMapperFields = this.modelMetadata.fields.filter((f) => f.uriMapper);
628
636
  const localeOfFields = this.modelMetadata.fields.filter((f) => f.multiLocaleColumn);
629
637
  if (nestedQueries.length || localeOfFields.length || uriMapperFields.length) {
630
- const tobeRemoved = await tx
631
- .use(this.model)
638
+ const tobeRemoved = await this.db
639
+ .use(this.model, tx)
632
640
  .getRecords(condition, { projection: ["id", ...[...localeOfFields, ...uriMapperFields].map((f) => f.name)] }, nestedQueries);
633
- await tx.use(this.model).deleteMany({
641
+ await this.db.use(this.model, tx).deleteMany({
634
642
  _in: { id: tobeRemoved.map((r) => r.id) },
635
643
  });
636
644
  //-- collect uri to remove
@@ -655,8 +663,8 @@ export class ModelRepository extends AbstractRepository {
655
663
  }
656
664
  if (localeUriLocalEntryIds.length) {
657
665
  //-- get all uris and add to remove list
658
- const records = await tx
659
- .use(LocaleTranslation)
666
+ const records = await this.db
667
+ .use(LocaleTranslation, tx)
660
668
  .getRecords({ _in: { entryId: localeUriLocalEntryIds } }, { projection: ["translation"] });
661
669
  for (const record of records) {
662
670
  if (record.translation) {
@@ -671,7 +679,7 @@ export class ModelRepository extends AbstractRepository {
671
679
  .filter((id) => !!id);
672
680
  //-- remove locale entry, will cascade locale translations
673
681
  if (localeEntryIds.length) {
674
- await tx.use(LocaleEntry).deleteMany({ _in: { id: localeEntryIds } });
682
+ await this.db.use(LocaleEntry, tx).deleteMany({ _in: { id: localeEntryIds } });
675
683
  }
676
684
  //-- remove uris
677
685
  if (toBeRemovedUris.length) {
@@ -683,7 +691,7 @@ export class ModelRepository extends AbstractRepository {
683
691
  returning = tobeRemoved;
684
692
  }
685
693
  else {
686
- returning = await tx.use(this.model).deleteMany(condition, queries?.returning);
694
+ returning = await this.db.use(this.model, tx).deleteMany(condition, queries?.returning);
687
695
  }
688
696
  return { modified: returning };
689
697
  }
@@ -1,18 +1,18 @@
1
- import { IQueryProvider } from "@clairejs/orm";
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(query: IQueryProvider): Promise<T[]>;
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, query: IQueryProvider): Promise<string>;
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, query: IQueryProvider): Promise<void>;
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(this.db);
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
- }, this.db));
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, this.db);
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 { IQueryProvider } from "@clairejs/orm";
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
- constructor(model: Constructor<T>);
8
- getJobs(query: IQueryProvider): Promise<T[]>;
9
- saveJob({ id, ...jobInfo }: T, query: IQueryProvider): Promise<string>;
10
- removeJobById(id: string, query: IQueryProvider): Promise<void>;
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
- constructor(model) {
4
+ db;
5
+ constructor(model, db) {
5
6
  super();
6
7
  this.model = model;
8
+ this.db = db;
7
9
  }
8
- async getJobs(query) {
9
- const jobs = await query.use(this.model).getRecords();
10
+ async getJobs() {
11
+ const jobs = await this.db.use(this.model).getRecords();
10
12
  return jobs;
11
13
  }
12
- async saveJob({ id, ...jobInfo }, query) {
14
+ async saveJob({ id, ...jobInfo }, tx) {
13
15
  if (id) {
14
16
  //-- update
15
- await query.use(this.model).updateById(id, jobInfo);
17
+ await this.db.use(this.model, tx).updateById(id, jobInfo);
16
18
  }
17
19
  else {
18
20
  //-- create new
19
- const job = await query.use(this.model).createOne(jobInfo);
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, query) {
25
- await query.use(this.model).deleteById(id);
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.18.2",
3
+ "version": "3.19.1",
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.14.0"
37
+ "@clairejs/orm": "^3.15.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/cookie-parser": "^1.4.3",