Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions src/published-data/interfaces/published-data.interface.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { FilterQuery } from "mongoose";
import { PublishedDataDocument } from "../schemas/published-data.schema";
import { ILimitsFilter } from "src/common/interfaces/common.interface";

export interface IPublishedDataFilters {
where?: FilterQuery<PublishedDataDocument>;
include?: { relation: string }[];
fields?: {
status: string;
};
limits?: {
skip: number;
limit: number;
order: string;
};
limits?: ILimitsFilter;
}

export class ICount {
Expand Down
27 changes: 22 additions & 5 deletions src/published-data/pipes/filter.pipe.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
import { FilterPipe } from "src/common/pipes/filter.pipe";
import { PublishedData } from "../schemas/published-data.schema";
import {
PublishedData,
PublishedDataDocument,
} from "../schemas/published-data.schema";
import { publishedDataV3toV4FieldMap } from "../dto/published-data.obsolete.dto";
import { JsonToStringPipe } from "src/common/pipes/json-to-string.pipe";
import { PipeTransform } from "@nestjs/common";
import { isEmpty } from "lodash";
import { IPublishedDataFilters } from "../interfaces/published-data.interface";
import { FilterQuery } from "mongoose";

class AppendFieldsToFilterPipe implements PipeTransform {
transform(value: {
filter: IPublishedDataFilters;
fields: FilterQuery<PublishedDataDocument>;
}) {
if (isEmpty(value.fields)) return value;
const filter = value.filter ?? {};
if (isEmpty(filter.where)) filter.where = value.fields;
else filter.where = { $and: [value.fields, filter.where] };
return { ...value, filter };
}
}

export const V3_FILTER_PIPE = [
new FilterPipe<PublishedData>({ apiToDBMap: publishedDataV3toV4FieldMap }),
new JsonToStringPipe("fields"),
];

export const V4_FILTER_PIPE = [
new FilterPipe<PublishedData>({ allowObjectFields: false }),
new JsonToStringPipe("fields"),
new JsonToStringPipe("limits"),
new AppendFieldsToFilterPipe(),
];
33 changes: 18 additions & 15 deletions src/published-data/pipes/registered.pipe.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,53 @@
import { Inject, Injectable, PipeTransform, Scope } from "@nestjs/common";
import { REQUEST } from "@nestjs/core";
import { Request } from "express";
import { omit } from "lodash";
import { IPublishedDataFilters } from "../interfaces/published-data.interface";

function addRegisteredStatusToJson(
json: Record<string, string>,
filter: IPublishedDataFilters,
isAuthenticated = false,
) {
if (isAuthenticated) return json;
return { ...json, status: "registered" };
if (isAuthenticated) return filter;
filter.where = {
...filter.where,
status: "registered",
};
return filter;
}

@Injectable({ scope: Scope.REQUEST })
export class RegisteredFilterPipe implements PipeTransform<
{ filter?: string; fields?: string; limits?: string },
{ filter?: string; fields?: string; limits?: string }
{ filter?: IPublishedDataFilters },
{ filter?: IPublishedDataFilters }
> {
constructor(@Inject(REQUEST) private readonly request: Request) {}

transform(value: { filter?: string; fields?: string; limits?: string }) {
const jsonFields = JSON.parse(value?.fields || "{}");
transform(value: { filter?: IPublishedDataFilters }) {
const withRegistered = addRegisteredStatusToJson(
jsonFields,
value?.filter ?? {},
this.request.isAuthenticated(),
);
return { ...value, fields: JSON.stringify(withRegistered) };
return { ...value, filter: withRegistered };
}
}

@Injectable({ scope: Scope.REQUEST })
export class RegisteredPipe implements PipeTransform<
Record<string, string>,
Record<string, string>
IPublishedDataFilters,
IPublishedDataFilters
> {
constructor(@Inject(REQUEST) private readonly request: Request) {}

transform(value: Record<string, string>) {
transform(value: IPublishedDataFilters) {
return addRegisteredStatusToJson(value, this.request.isAuthenticated());
}
}

export class IdToDoiPipe implements PipeTransform<
{ id: string },
{ doi: string }
{ where: { doi: string } }
> {
transform(value: { id: string }) {
return { ...omit(value, "id"), doi: value.id };
return { where: { doi: value.id } };
}
}
59 changes: 11 additions & 48 deletions src/published-data/published-data.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
ApiTags,
} from "@nestjs/swagger";
import { plainToInstance } from "class-transformer";
import { FilterQuery, QueryOptions } from "mongoose";
import { QueryOptions } from "mongoose";
import { firstValueFrom } from "rxjs";
import { AttachmentsService } from "src/attachments/attachments.service";
import { AllowAny } from "src/auth/decorators/allow-any.decorator";
Expand Down Expand Up @@ -65,10 +65,7 @@ import {
RegisteredPipe,
} from "./pipes/registered.pipe";
import { PublishedDataService } from "./published-data.service";
import {
PublishedData,
PublishedDataDocument,
} from "./schemas/published-data.schema";
import { PublishedData } from "./schemas/published-data.schema";
import { V3_FILTER_PIPE } from "./pipes/filter.pipe";

@ApiBearerAuth()
Expand Down Expand Up @@ -272,16 +269,6 @@ export class PublishedDataController {
description: "Database filters to apply when retrieve all published data",
required: false,
})
@ApiQuery({
name: "limits",
description: "Database limits to apply when retrieve all published data",
required: false,
})
@ApiQuery({
name: "fields",
description: "Database fields to apply apply filters on",
required: false,
})
@ApiResponse({
status: HttpStatus.OK,
type: PublishedDataObsoleteDto,
Expand All @@ -296,25 +283,9 @@ export class PublishedDataController {
@Query(...V3_FILTER_PIPE, RegisteredFilterPipe)
filter?: {
filter: IPublishedDataFilters;
fields: string;
limits: string;
},
): Promise<PublishedDataObsoleteDto[]> {
const publishedDataFilters: IPublishedDataFilters = filter?.filter ?? {};
const publishedDataLimits: {
skip: number;
limit: number;
order: string;
} = JSON.parse(filter?.limits ?? "{}");
const publishedDataFields = JSON.parse(filter?.fields ?? "{}");

if (!publishedDataFilters.limits) {
publishedDataFilters.limits = publishedDataLimits;
}
if (!publishedDataFilters.fields) {
publishedDataFilters.fields = publishedDataFields;
}

const fetchedData =
await this.publishedDataService.findAll(publishedDataFilters);

Expand Down Expand Up @@ -344,23 +315,12 @@ export class PublishedDataController {
@Query(...V3_FILTER_PIPE, RegisteredFilterPipe)
filter?: {
filter: IPublishedDataFilters;
fields: string;
limits: string;
},
) {
const jsonFilters: IPublishedDataFilters = filter?.filter ?? {};
const jsonFields: FilterQuery<PublishedDataDocument> = filter?.fields
? JSON.parse(filter.fields)
: {};

const filters: FilterQuery<PublishedDataDocument> = {
where: jsonFilters,
fields: jsonFields,
};

const filters: IPublishedDataFilters = filter?.filter ?? {};
const options: QueryOptions = {
limit: jsonFilters?.limits?.limit,
skip: jsonFilters?.limits?.skip,
limit: filters?.limits?.limit,
skip: filters?.limits?.skip,
};

return this.publishedDataService.countDocuments(filters, options);
Expand Down Expand Up @@ -454,11 +414,14 @@ export class PublishedDataController {
})
async findOne(
@Param(new IdToDoiPipe(), RegisteredPipe)
idFilter: {
doi: string;
registered?: string;
filter: {
where: {
doi: string;
registered?: string;
};
},
): Promise<PublishedDataObsoleteDto> {
const idFilter = filter.where;
const publishedData = await this.publishedDataService.findOne(idFilter);
if (!publishedData) {
throw new NotFoundException(
Expand Down
32 changes: 3 additions & 29 deletions src/published-data/published-data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { firstValueFrom } from "rxjs";
import { JWTUser } from "src/auth/interfaces/jwt-user.interface";
import {
addCreatedByFields,
createFullqueryFilter,
handleAxiosRequestError,
parseLimitFilters,
} from "src/common/utils";
Expand Down Expand Up @@ -79,47 +78,22 @@ export class PublishedDataService {
}

async findAll(filter: IPublishedDataFilters): Promise<PublishedData[]> {
const whereFilter: FilterQuery<PublishedDataDocument> = filter.where ?? {};
const fields = filter.fields ?? {};
const filterQuery: FilterQuery<PublishedDataDocument> =
createFullqueryFilter<PublishedDataDocument>(
this.publishedDataModel,
"doi",
fields,
);
const whereClause: FilterQuery<PublishedDataDocument> = {
...filterQuery,
...whereFilter,
};
const { limit, skip, sort } = parseLimitFilters(filter.limits);

return this.publishedDataModel
.find(whereClause)
.find(filter.where ?? {})
.limit(limit)
.skip(skip)
.sort(sort)
.select(filter.fields ?? {})
.exec();
}

async countDocuments(
filter: FilterQuery<PublishedDataDocument>,
options?: object,
): Promise<ICount> {
const whereFilter: FilterQuery<PublishedDataDocument> = filter.where ?? {};
const fields = filter.fields ?? {};
const filterQuery: FilterQuery<PublishedDataDocument> =
createFullqueryFilter<PublishedDataDocument>(
this.publishedDataModel,
"doi",
fields,
);
const whereClause: FilterQuery<PublishedDataDocument> = {
...filterQuery,
...whereFilter,
};

const count = await this.publishedDataModel
.countDocuments(whereClause, options)
.countDocuments(filter.where ?? {}, options)
.exec();
return { count };
}
Expand Down
32 changes: 12 additions & 20 deletions src/published-data/published-data.v4.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import {
PublishedDataDocument,
} from "./schemas/published-data.schema";
import { V4_FILTER_PIPE } from "./pipes/filter.pipe";
import { ILimitsFilter } from "src/common/interfaces/common.interface";

@ApiBearerAuth()
@ApiTags("published data v4")
Expand Down Expand Up @@ -120,24 +121,20 @@ export class PublishedDataV4Controller {
@Query(...V4_FILTER_PIPE, RegisteredFilterPipe)
filter?: {
filter: IPublishedDataFilters;
fields: string;
limits: string;
fields: FilterQuery<PublishedDataDocument>;
limits: ILimitsFilter;
},
) {
const publishedDataFilters: IPublishedDataFilters = filter?.filter ?? {};
const publishedDataLimits: {
skip: number;
limit: number;
order: string;
} = JSON.parse(filter?.limits ?? "{}");
const publishedDataFields = JSON.parse(filter?.fields ?? "{}");
skip?: number;
limit?: number;
order?: string;
} = filter?.limits ?? {};

if (!publishedDataFilters.limits) {
publishedDataFilters.limits = publishedDataLimits;
}
if (!publishedDataFilters.fields) {
publishedDataFilters.fields = publishedDataFields;
}

const ability = this.caslAbilityFactory.publishedDataInstanceAccess(
request.user as JWTUser,
Expand Down Expand Up @@ -180,13 +177,10 @@ export class PublishedDataV4Controller {
@Query(...V4_FILTER_PIPE, RegisteredFilterPipe)
filter?: {
filter: IPublishedDataFilters;
fields: string;
fields: FilterQuery<PublishedDataDocument>;
},
) {
const jsonFilters: IPublishedDataFilters = filter?.filter ?? {};
const jsonFields: FilterQuery<PublishedDataDocument> = filter?.fields
? JSON.parse(filter.fields)
: {};

const ability = this.caslAbilityFactory.datasetInstanceAccess(
request.user as JWTUser,
Expand All @@ -207,17 +201,15 @@ export class PublishedDataV4Controller {
};
}

const filters: FilterQuery<PublishedDataDocument> = {
where: jsonFilters.where,
fields: jsonFields,
};

const options: QueryOptions = {
limit: jsonFilters?.limits?.limit,
skip: jsonFilters?.limits?.skip,
};

return this.publishedDataService.countDocuments(filters, options);
return this.publishedDataService.countDocuments(
{ where: jsonFilters.where },
options,
);
}

// GET /publisheddata/formpopulate
Expand Down
Loading