Skip to content

Commit bb808cd

Browse files
committed
feat(json-api-nestjs-microorm): enhance getOne and getAll with transform toggles and additional query params, add relationship loading utility and improve logging
1 parent c322379 commit bb808cd

File tree

5 files changed

+77
-8
lines changed

5 files changed

+77
-8
lines changed

libs/json-api/json-api-nestjs-microorm/src/lib/orm-helper/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { EntityKey, EntityMetadata } from '@mikro-orm/core';
2+
import { Logger } from '@nestjs/common';
23
import {
34
EntityParam,
45
TypeField,
@@ -7,6 +8,7 @@ import {
78
import { MicroOrmParam } from '../type';
89
import { DEFAULT_ARRAY_TYPE } from '../constants';
910

11+
1012
export const getRelation = <E extends object>(
1113
entityMetadata: EntityMetadata<E>
1214
) =>
@@ -30,6 +32,7 @@ export const getPropsType = <E extends object>(
3032
entityMetadata: EntityMetadata<E>,
3133
config: PrepareParams<MicroOrmParam>['options']['arrayType'] = DEFAULT_ARRAY_TYPE
3234
): EntityParam<E>['propsType'] => {
35+
const logger = new Logger('JSON-API:MkroORM: init');
3336
const field = getProps(entityMetadata);
3437

3538
const result = {} as any;
@@ -56,6 +59,10 @@ export const getPropsType = <E extends object>(
5659
case 'object':
5760
typeProps = TypeField.object;
5861
break;
62+
case 'any':
63+
logger.warn(`The field "${item}" in entity ${entityMetadata.name} has runtime type "any". Should be use object type.`);
64+
typeProps = TypeField.object;
65+
break;
5966
default:
6067
typeProps = TypeField.string;
6168
}

libs/json-api/json-api-nestjs-microorm/src/lib/orm-methods/get-all/get-all.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { getQueryForCount, getSortObject } from './get-query-for-count';
66

77
export async function getAll<E extends object, IdKey extends string>(
88
this: MicroOrmService<E, IdKey>,
9-
query: Query<E, IdKey>
9+
query: Query<E, IdKey>,
10+
additionalQueryParams?: Record<string, unknown>
1011
): Promise<{
1112
totalItems: number;
1213
items: E[];
@@ -18,6 +19,10 @@ export async function getAll<E extends object, IdKey extends string>(
1819
ReturnType<typeof getQueryForCount<E, IdKey>>
1920
>(this, ...[query]);
2021

22+
if (additionalQueryParams) {
23+
countSubQuery.andWhere(additionalQueryParams);
24+
}
25+
2126
const skip = (page.number - 1) * page.size;
2227

2328
await countSubQuery.applyFilters();

libs/json-api/json-api-nestjs-microorm/src/lib/orm-methods/get-one/get-one.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { MicroOrmService } from '../../service';
66
export async function getOne<E extends object, IdKey extends string>(
77
this: MicroOrmService<E, IdKey>,
88
id: number | string,
9-
query: QueryOne<E, IdKey>
9+
query: QueryOne<E, IdKey>,
10+
additionalQueryParams?: Record<string, unknown>
1011
): Promise<E> {
1112
const queryBuilder = this.microOrmUtilService.queryBuilder().where({
1213
[this.microOrmUtilService.currentPrimaryColumn]: id,
@@ -17,6 +18,10 @@ export async function getOne<E extends object, IdKey extends string>(
1718
query as any
1819
);
1920

21+
if (additionalQueryParams) {
22+
resultQueryBuilder.andWhere(additionalQueryParams);
23+
}
24+
2025
await resultQueryBuilder.applyFilters();
2126

2227
const resultItem = await resultQueryBuilder.getSingleResult();

libs/json-api/json-api-nestjs-microorm/src/lib/service/micro-orm-util.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ export class MicroOrmUtilService<
567567
});
568568
}
569569

570-
private async *asyncIterateFindRelationships(
570+
async *asyncIterateFindRelationships(
571571
relationships: NonNullable<Relationships<E, IdKey>>
572572
): AsyncGenerator<RelationshipsResult<E>> {
573573
for (const entries of ObjectTyped.entries(relationships)) {

libs/json-api/json-api-nestjs-microorm/src/lib/service/microorm-service.ts

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { Inject } from '@nestjs/common';
22
import {
3+
ObjectTyped,
34
QueryField,
45
ResourceObject,
56
ResourceObjectRelationships,
7+
RelationKeys
68
} from '@klerick/json-api-nestjs-shared';
79
import {
810
JsonApiTransformerService,
@@ -27,7 +29,6 @@ import {
2729
postRelationship,
2830
} from '../orm-methods';
2931
import { MicroOrmUtilService } from './micro-orm-util.service';
30-
import { RelationKeys } from '@klerick/json-api-nestjs-shared';
3132

3233
export class MicroOrmService<E extends object, IdKey extends string = 'id'>
3334
implements OrmService<E, IdKey>
@@ -41,14 +42,29 @@ export class MicroOrmService<E extends object, IdKey extends string = 'id'>
4142

4243
async getAll(
4344
query: Query<E, IdKey>
44-
): Promise<ResourceObject<E, 'array', null, IdKey>> {
45+
): Promise<ResourceObject<E, 'array', null, IdKey>>;
46+
async getAll(
47+
query: Query<E, IdKey>,
48+
transformData?: boolean,
49+
additionalQueryParams?: Record<string, unknown>
50+
): Promise<ResourceObject<E, 'array', null, IdKey>>;
51+
async getAll(
52+
query: Query<E, IdKey>,
53+
transformData = true,
54+
additionalQueryParams?: Record<string, unknown>
55+
): Promise<
56+
ResourceObject<E, 'array', null, IdKey> | { totalItems: number; items: E[] }
57+
> {
4558
const { page } = query;
4659
const { totalItems, items } = await getAll.call<
4760
MicroOrmService<E, IdKey>,
4861
Parameters<typeof getAll<E, IdKey>>,
4962
ReturnType<typeof getAll<E, IdKey>>
50-
>(this, query);
63+
>(this, query, additionalQueryParams);
5164

65+
if (!transformData) {
66+
return { totalItems, items };
67+
}
5268
const { data, included } = this.jsonApiTransformerService.transformData(
5369
items,
5470
query
@@ -70,12 +86,29 @@ export class MicroOrmService<E extends object, IdKey extends string = 'id'>
7086
async getOne(
7187
id: number | string,
7288
query: QueryOne<E, IdKey>
73-
): Promise<ResourceObject<E, 'object', null, IdKey>> {
89+
): Promise<ResourceObject<E, 'object', null, IdKey>>;
90+
async getOne(
91+
id: number | string,
92+
query: QueryOne<E, IdKey>,
93+
transformData?: boolean,
94+
additionalQueryParams?: Record<string, unknown>
95+
): Promise<ResourceObject<E, 'object', null, IdKey> | E>;
96+
async getOne(
97+
id: number | string,
98+
query: QueryOne<E, IdKey>,
99+
transformData = true,
100+
additionalQueryParams?: Record<string, unknown>
101+
): Promise<ResourceObject<E, 'object', null, IdKey> | E> {
74102
const result = await getOne.call<
75103
MicroOrmService<E, IdKey>,
76104
Parameters<typeof getOne<E, IdKey>>,
77105
ReturnType<typeof getOne<E, IdKey>>
78-
>(this, id, query);
106+
>(this, id, query, additionalQueryParams);
107+
108+
if (!transformData) {
109+
return result;
110+
}
111+
79112
const { data, included } = this.jsonApiTransformerService.transformData(
80113
result,
81114
query
@@ -226,4 +259,23 @@ export class MicroOrmService<E extends object, IdKey extends string = 'id'>
226259
data: this.jsonApiTransformerService.transformRel(result, rel),
227260
};
228261
}
262+
263+
async loadRelations(
264+
relationships: PatchData<E, IdKey>['relationships'] | PostData<E, IdKey>['relationships']
265+
): Promise<{
266+
[K in RelationKeys<E>]: E[K];
267+
}> {
268+
const result = {} as { [K in RelationKeys<E> ]: E[K]; };
269+
270+
for await (const item of this.microOrmUtilService.asyncIterateFindRelationships(
271+
relationships as any
272+
)) {
273+
const itemProps = ObjectTyped.entries(item).at(0);
274+
if (!itemProps) continue;
275+
const [nameProps, data] = itemProps;
276+
Reflect.set(result, nameProps, data);
277+
}
278+
279+
return result;
280+
}
229281
}

0 commit comments

Comments
 (0)