Skip to content

Commit

Permalink
Merge pull request #600 from Sanofi-IADC/feat/ARM-2020
Browse files Browse the repository at this point in the history
feat: ARM-2020 Add APIs for Official PDF Exports - Custom Content
  • Loading branch information
kr1shnadas authored Jan 7, 2025
2 parents 46f1300 + 4762744 commit 49df5cc
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"start:prod": "node dist/src/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --max-warnings 3",
"lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix --max-warnings 3",
"test": "npm run test:unit:cov && npm run test:e2e",
"test": "npm run test:unit:cov",
"test:unit:watch": "jest --config jest-unit.config.js --watch",
"test:unit:cov": "jest --config jest-unit.config.js --coverage",
"test:unit:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
Expand Down
78 changes: 78 additions & 0 deletions src/confluence/confluence.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,4 +463,82 @@ export class ConfluenceService {
);
return data;
}

/**
* @function getCustomContentByTypeInSpace
* @description Return custom content of specified type in the given space
* @param type {string} - type of content to retrieve
* @param spaceId {number} - id of the space to retrieve content from
* @param next {string} - starting cursor used for pagination
* @param collection {array} - recursive array of collection
* @return Promise {any}
*/
async getCustomContentsByTypeInSpace(
type: string,
spaceId: number,
next?: string,
collection = [],
): Promise<any> {
const defaultParams = {
type,
limit: 250,
'body-format': 'atlas_doc_format',
};
try {
const { data }: AxiosResponse = await firstValueFrom(
this.http.get(next || `/wiki/api/v2/spaces/${spaceId}/custom-content`, { params: !next && defaultParams }),
);
this.logger.log(
`Retrieving Custom content of ${type} in Space ${spaceId} via REST API`,
);
collection.push(...data.results);
if (data._links?.next) {
await this.getSpacesMeta(type, data._links?.next, collection);
}
return collection;
} catch (err: any) {
this.logger.log(err, 'error:getCustomContentByTypeInSpace');
throw new HttpException(`error:getCustomContentByTypeInSpace > ${err}`, 404);
}
}

/**
* @function getCustomContentById
* @description Return custom content by id
* @param id {number} id of the custom content to retrieve
* @return Promise {any}
* @throws {HttpException} if there is a problem with the request
*/
async getCustomContentById(id: number): Promise<any> {
try {
const { data }: AxiosResponse = await firstValueFrom(
this.http.get(`/wiki/api/v2/custom-content/${id}`),
);
this.logger.log(`Retrieving custom-content ${id} via REST API`);
return data;
} catch (err: any) {
this.logger.log(err, `error:getCustomContentById ${id}`);
throw new HttpException(`error:getCustomContentById > ${err}`, 404);
}
}

/**
* @function getAttchmentById
* @description Return attachment info by id
* @param id {string} id of the attachment to retrieve
* @return Promise {any}
* @throws {HttpException} if there is a problem with the request
*/
async getAttachmentById(id: string): Promise<any> {
try {
const { data }: AxiosResponse = await firstValueFrom(
this.http.get(`/wiki/api/v2/attachments/${id}`),
);
this.logger.log(`Retrieving attachment ${id} via REST API`);
return data;
} catch (err: any) {
this.logger.log(err, `error:getAttchmentById ${id}`);
throw new HttpException(`error:getAttchmentById > ${err}`, 404);
}
}
}
15 changes: 15 additions & 0 deletions src/proxy-api/dto/GetAttachmentByIdParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ApiProperty } from '@nestjs/swagger';
import {
IsNotEmpty, IsString,
} from 'class-validator';

export default class GetAttachmentByIdParamsDTO {
@ApiProperty({
type: String,
description: 'The Id of attachment to retrieve',
example: '1234',
})
@IsNotEmpty()
@IsString()
id: string;
}
15 changes: 15 additions & 0 deletions src/proxy-api/dto/GetCustomContentByIdParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ApiProperty } from '@nestjs/swagger';
import {
IsNotEmpty, IsString,
} from 'class-validator';

export default class GetCustomContentByIdParamsDTO {
@ApiProperty({
type: Number,
description: 'The Id of custom content to retrieve',
example: '1234',
})
@IsNotEmpty()
@IsString()
id: number;
}
15 changes: 15 additions & 0 deletions src/proxy-api/dto/GetCustomContentsInSpaceParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ApiProperty } from '@nestjs/swagger';
import {
IsNotEmpty, IsString,
} from 'class-validator';

export default class GetCustomContentsInSpaceParamsDTO {
@ApiProperty({
type: Number,
description: 'The Id of space to retrieve custom contents from',
example: '1234',
})
@IsNotEmpty()
@IsString()
spaceId: number;
}
29 changes: 29 additions & 0 deletions src/proxy-api/dto/GetCustomContentsInSpaceQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
IsInt,

Check warning on line 4 in src/proxy-api/dto/GetCustomContentsInSpaceQuery.ts

View workflow job for this annotation

GitHub Actions / Quality (14.x)

'IsInt' is defined but never used

Check warning on line 4 in src/proxy-api/dto/GetCustomContentsInSpaceQuery.ts

View workflow job for this annotation

GitHub Actions / Quality (16.x)

'IsInt' is defined but never used

Check warning on line 4 in src/proxy-api/dto/GetCustomContentsInSpaceQuery.ts

View workflow job for this annotation

GitHub Actions / Quality (17.x)

'IsInt' is defined but never used
IsNotEmpty,
IsOptional,
IsString,
} from 'class-validator';

export default class GetCustomContentsInSpaceQueryDTO {
@ApiProperty({
type: String,
description: 'The type of custom content to retrieve',
example: 'forge:42bc20e9-123e-4153-bcd1-02a43d44cc6e:847c9fab-7106-4bde-b688-25e9cd330117:custom-content-sanofi-forge-official-exports',
})
@IsNotEmpty()
@IsString()
type: string;

@ApiProperty({
type: String,
description: 'Starting cursor used for pagination',
example: 'xyz',
})
@IsOptional()
@IsString()
@Type(() => String)
next = '';
}
60 changes: 60 additions & 0 deletions src/proxy-api/proxy-api.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import GetScreenDetailsDTO from './dto/GetScreenDetailsQuery';
import SearchProjectUsersQueryDTO from './dto/SearchProjectUsersQuery';
import SearchProjectVersionsQueryDTO from './dto/SearchProjectVersionsQuery';
import GetSpacesMetaParamsDTO from './dto/GetSpacesMetaParams';
import GetCustomContentsInSpaceParamsDTO from './dto/GetCustomContentsInSpaceParams';
import GetCustomContentsInSpaceQueryDTO from './dto/GetCustomContentsInSpaceQuery';
import GetCustomContentByIdParamsDTO from './dto/GetCustomContentByIdParams';
import GetAttachmentByIdParamsDTO from './dto/GetAttachmentByIdParams';

@ApiTags('proxy-api')
@Controller('api')
Expand Down Expand Up @@ -245,4 +249,60 @@ export class ProxyApiController {
);
return this.proxyApi.getPage(params.spaceKey, params.pageId, queries.type);
}

/**
* @GET (controller) api/spaces/:id/custom-content
* @description Retrieve custom content of the specified type from a given space.
* Utilizes pagination to accumulate all results.
* @return {Promise<any>} - A promise resolving to the accumulated content.
* @param {GetCustomContentsInSpaceParamsDTO} params - Parameters object, must contain the spaceId property.
* @param {GetCustomContentsInSpaceQueryDTO} queries - Query object,
* must contain the type property and optionally the next property for pagination.
*/
@ApiOkResponse({
description: 'Get Custom Contents by Type in a Space',
})
@Get('spaces/:id/custom-content')
async getCustomContentsByTypeInSpace(
@Param() params: GetCustomContentsInSpaceParamsDTO,
@Query() queries: GetCustomContentsInSpaceQueryDTO,
): Promise<any> {
return this.proxyApi.getCustomContentsByTypeInSpace(
queries.type,
params.spaceId,
queries.next,
);
}

/**
* @GET (controller) api/custom-content/:id
* @description Retrieves a single custom content by its id.
* @return {Promise<any>} - A promise resolving to the custom content.
* @param {GetCustomContentByIdParamsDTO} params - Parameters object, must contain the id property.
*/
@ApiOkResponse({
description: 'Get Custom Content By Id',
})
@Get('custom-content/:id')
async getCustomContentById(
@Param() params: GetCustomContentByIdParamsDTO,
): Promise<any> {
return this.proxyApi.getCustomContentById(params.id);
}

/**
* @GET (controller) api/attachments/:id
* @description Retrieves a single attachment by its id.
* @return {Promise<any>} - A promise resolving to the attachment.
* @param {GetAttachmentByIdParamsDTO} params - Parameters object, must contain the id property.
*/
@ApiOkResponse({
description: 'Get Attachment By Id',
})
@Get('attachments/:id')
async getAttachmentById(
@Param() params: GetAttachmentByIdParamsDTO,
): Promise<any> {
return this.proxyApi.getAttachmentById(params.id);
}
}
47 changes: 47 additions & 0 deletions src/proxy-api/proxy-api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -522,4 +522,51 @@ export class ProxyApiService {
space: this.context.getSpaceKey(),
};
}

/**
* @function getAttchmentById
* @description Retrieves attachment information by its ID from Confluence.
* @param id {string} The ID of the attachment to retrieve.
* @return Promise {any} A promise that resolves to the attachment data.
*/
async getAttachmentById(id: string): Promise<any> {
const data = await this.confluence.getAttachmentById(id);
return data;
}

/**
* @function getCustomContentById
* @description Retrieves custom content information by its ID from Confluence.
* @param id {number} The ID of the custom content to retrieve.
* @return Promise {any} A promise that resolves to the custom content data.
*/
async getCustomContentById(id: number): Promise<any> {
const data = await this.confluence.getCustomContentById(id);
return data;
}

/**
* @function getCustomContentByTypeInSpace
* @description Retrieves custom content of the specified type from a given space.
* Utilizes pagination to accumulate all results.
* @param type {string} - The type of content to retrieve.
* @param spaceId {number} - The ID of the space to retrieve content from.
* @param next {string} - An optional cursor for pagination.
* @param collection {array} - Accumulates the retrieved content across paginated requests.
* @return Promise {any} - A promise resolving to the accumulated content.
*/
async getCustomContentsByTypeInSpace(
type: string,
spaceId: number,
next?: string,
collection = [],
): Promise<any> {
const data = await this.confluence.getCustomContentsByTypeInSpace(
type,
spaceId,
next,
collection,
);
return data;
}
}

0 comments on commit 49df5cc

Please sign in to comment.