Skip to content

Commit

Permalink
refactor(api): move from purify-ts to fp-ts, fix swagger docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Dyostiq committed Jun 30, 2021
1 parent 45d48bd commit fbb7c45
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 14 deletions.
14 changes: 14 additions & 0 deletions api/apps/api/src/modules/projects/dto/planning-area-created.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ApiProperty } from '@nestjs/swagger';
import { GeoJSON } from 'geojson';

export class PlanningAreaCreatedDto {
@ApiProperty({
description: 'An ID of the created planning area',
})
id!: string;

@ApiProperty({
description: 'GeoJSON of the created planning area',
})
data!: GeoJSON;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import {
Inject,
Injectable,
} from '@nestjs/common';
import { Either, Left, Right } from 'purify-ts/Either';
import { Either, left, right } from 'fp-ts/Either';
import { AppConfig } from '@marxan-api/utils/config.utils';
import { apiGlobalPrefixes } from '@marxan-api/api.config';
import { GeoJSON } from 'geojson';

export const validationFailed = Symbol('validation failed');
export const geoprocessingUrlToken = Symbol('geoprocessing url token');
Expand All @@ -25,8 +26,16 @@ export class CustomPlanningAreasUploader {

async savePlanningAreaFromShapefile(
file: Express.Multer.File,
): Promise<Either<typeof validationFailed, unknown>> {
const { data: geoJson, status } = await this.httpService
): Promise<
Either<
typeof validationFailed,
{
id: string;
data: GeoJSON;
}
>
> {
const { data, status } = await this.httpService
.post(
`${this.geoprocessingUrl}${apiGlobalPrefixes.v1}/projects/planning-area/shapefile`,
file,
Expand All @@ -38,8 +47,8 @@ export class CustomPlanningAreasUploader {
)
.toPromise();
if (status >= 400) {
return Left(validationFailed);
return left(validationFailed);
}
return Right(geoJson);
return right(data);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as nock from 'nock';
import { isEqual } from 'lodash';
import { PromiseType } from 'utility-types';
import { Either, Left, Right } from 'purify-ts/Either';
import { Either, left, right } from 'fp-ts/Either';
import { Test } from '@nestjs/testing';
import { HttpModule } from '@nestjs/common';
import {
Expand Down Expand Up @@ -30,7 +30,7 @@ describe(`when file validated successfully`, () => {

// then
it(`should pass the response`, () => {
expect(result).toEqual(Right(fixtures.validResponse));
expect(result).toEqual(right(fixtures.validResponse));
});
});

Expand All @@ -46,7 +46,7 @@ describe(`when file validation failed`, () => {

// then
it(`should return validation failed`, () => {
expect(result).toStrictEqual(Left(validationFailed));
expect(result).toStrictEqual(left(validationFailed));
});
});

Expand Down
17 changes: 11 additions & 6 deletions api/apps/api/src/modules/projects/projects.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Controller,
Delete,
Get,
InternalServerErrorException,
NotFoundException,
Param,
Patch,
Expand Down Expand Up @@ -53,6 +54,8 @@ import { GeoFeatureSerializer } from './dto/geo-feature.serializer';
import { ProjectSerializer } from './dto/project.serializer';
import { ProjectJobsStatusDto } from './dto/project-jobs-status.dto';
import { JobStatusSerializer } from './dto/job-status.serializer';
import { PlanningAreaCreatedDto } from './dto/planning-area-created.dto';
import { isLeft } from 'fp-ts/Either';

@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
Expand Down Expand Up @@ -206,27 +209,29 @@ export class ProjectsController {
return;
}

@ApiConsumesShapefile(true)
@ApiOkResponse({ type: PlanningAreaCreatedDto })
@ApiOperation({
description: 'Upload shapefile with project planning-area',
})
@ApiConsumesShapefile(false)
@UseInterceptors(FileInterceptor('file', uploadOptions))
@Post('planning-area/shapefile')
async shapefileWithProjectPlanningArea(
@UploadedFile() file: Express.Multer.File,
) {
): Promise<PlanningAreaCreatedDto> {
const result = await this.projectsService.savePlanningAreaFromShapefile(
file,
);
if (result.isLeft()) {
const mapping: Record<ReturnType<typeof result.extract>, () => never> = {
if (isLeft(result)) {
const mapping: Record<typeof result['left'], () => never> = {
[validationFailed]: () => {
throw new BadRequestException();
},
};
mapping[result.extract()]();
mapping[result.left]();
throw new InternalServerErrorException();
}

return result.extract();
return result.right;
}
}
1 change: 1 addition & 0 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"config": "^3.3.3",
"express": "^4.17.1",
"faker": "^5.1.0",
"fp-ts": "^2.10.5",
"geojson": "0.5.0",
"helmet": "^4.3.1",
"http-proxy": "^1.18.1",
Expand Down
5 changes: 5 additions & 0 deletions api/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4882,6 +4882,11 @@ forwarded@~0.1.2:
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=

fp-ts@^2.10.5:
version "2.10.5"
resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-2.10.5.tgz#7c77868fe8bd9b229743303c1bec505b959f631b"
integrity sha512-X2KfTIV0cxIk3d7/2Pvp/pxL/xr2MV1WooyEzKtTWYSc1+52VF4YzjBTXqeOlSiZsPCxIBpDGfT9Dyo7WEY0DQ==

fragment-cache@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
Expand Down

0 comments on commit fbb7c45

Please sign in to comment.