feat: better post valdiation + better error messages for validation
This commit is contained in:
parent
a80f0397f2
commit
0f0bebeec9
|
|
@ -139,11 +139,12 @@ export class PostsController {
|
||||||
|
|
||||||
@Post('/')
|
@Post('/')
|
||||||
@CheckPolicies([AuthorizationActions.Create, Sections.POSTS_PER_MONTH])
|
@CheckPolicies([AuthorizationActions.Create, Sections.POSTS_PER_MONTH])
|
||||||
createPost(
|
async createPost(
|
||||||
@GetOrgFromRequest() org: Organization,
|
@GetOrgFromRequest() org: Organization,
|
||||||
@Body() body: CreatePostDto
|
@Body() rawBody: any
|
||||||
) {
|
) {
|
||||||
console.log(JSON.stringify(body, null, 2));
|
console.log(JSON.stringify(rawBody, null, 2));
|
||||||
|
const body = await this._postsService.mapTypeToPost(rawBody, org.id);
|
||||||
return this._postsService.createPost(org.id, body);
|
return this._postsService.createPost(org.id, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ export class PublicIntegrationsController {
|
||||||
@Query() query: GetPostsDto
|
@Query() query: GetPostsDto
|
||||||
) {
|
) {
|
||||||
const posts = await this._postsService.getPosts(org.id, query);
|
const posts = await this._postsService.getPosts(org.id, query);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
posts,
|
posts,
|
||||||
// comments,
|
// comments,
|
||||||
|
|
@ -70,10 +69,12 @@ export class PublicIntegrationsController {
|
||||||
|
|
||||||
@Post('/posts')
|
@Post('/posts')
|
||||||
@CheckPolicies([AuthorizationActions.Create, Sections.POSTS_PER_MONTH])
|
@CheckPolicies([AuthorizationActions.Create, Sections.POSTS_PER_MONTH])
|
||||||
createPost(
|
async createPost(
|
||||||
@GetOrgFromRequest() org: Organization,
|
@GetOrgFromRequest() org: Organization,
|
||||||
@Body() body: CreatePostDto
|
@Body() rawBody: any
|
||||||
) {
|
) {
|
||||||
|
const body = await this._postsService.mapTypeToPost(rawBody, org.id);
|
||||||
|
|
||||||
console.log(JSON.stringify(body, null, 2));
|
console.log(JSON.stringify(body, null, 2));
|
||||||
return this._postsService.createPost(org.id, body);
|
return this._postsService.createPost(org.id, body);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -240,7 +240,7 @@ export const ManageModal: FC<AddEditModalProps> = (props) => {
|
||||||
posts: checkAllValid.map((p: any) => ({
|
posts: checkAllValid.map((p: any) => ({
|
||||||
integration: p.integration,
|
integration: p.integration,
|
||||||
group,
|
group,
|
||||||
settings: { ...(p.settings || {}), __type: p.integration.identifier },
|
settings: { ...(p.settings || {}) },
|
||||||
value: p.values.map((a: any) => ({
|
value: p.values.map((a: any) => ({
|
||||||
...a,
|
...a,
|
||||||
image: a.media || [],
|
image: a.media || [],
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
ForbiddenException,
|
||||||
|
Injectable,
|
||||||
|
ValidationPipe,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { PostsRepository } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.repository';
|
import { PostsRepository } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.repository';
|
||||||
import { CreatePostDto } from '@gitroom/nestjs-libraries/dtos/posts/create.post.dto';
|
import { CreatePostDto } from '@gitroom/nestjs-libraries/dtos/posts/create.post.dto';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
@ -29,6 +34,8 @@ import sharp from 'sharp';
|
||||||
import { UploadFactory } from '@gitroom/nestjs-libraries/upload/upload.factory';
|
import { UploadFactory } from '@gitroom/nestjs-libraries/upload/upload.factory';
|
||||||
import { Readable } from 'stream';
|
import { Readable } from 'stream';
|
||||||
import { OpenaiService } from '@gitroom/nestjs-libraries/openai/openai.service';
|
import { OpenaiService } from '@gitroom/nestjs-libraries/openai/openai.service';
|
||||||
|
import { plainToInstance } from 'class-transformer';
|
||||||
|
import { validate } from 'class-validator';
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
|
|
||||||
type PostWithConditionals = Post & {
|
type PostWithConditionals = Post & {
|
||||||
|
|
@ -50,7 +57,7 @@ export class PostsService {
|
||||||
private _mediaService: MediaService,
|
private _mediaService: MediaService,
|
||||||
private _shortLinkService: ShortLinkService,
|
private _shortLinkService: ShortLinkService,
|
||||||
private _webhookService: WebhooksService,
|
private _webhookService: WebhooksService,
|
||||||
private openaiService: OpenaiService,
|
private openaiService: OpenaiService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async getStatistics(orgId: string, id: string) {
|
async getStatistics(orgId: string, id: string) {
|
||||||
|
|
@ -65,6 +72,54 @@ export class PostsService {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async mapTypeToPost(
|
||||||
|
body: CreatePostDto,
|
||||||
|
organization: string
|
||||||
|
): Promise<CreatePostDto> {
|
||||||
|
if (!body?.posts?.every((p) => p?.integration?.id)) {
|
||||||
|
throw new BadRequestException('All posts must have an integration id');
|
||||||
|
}
|
||||||
|
|
||||||
|
const mappedValues = {
|
||||||
|
...body,
|
||||||
|
posts: await Promise.all(
|
||||||
|
body.posts.map(async (post) => {
|
||||||
|
const integration = await this._integrationService.getIntegrationById(
|
||||||
|
organization,
|
||||||
|
post.integration.id
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!integration) {
|
||||||
|
throw new BadRequestException(
|
||||||
|
`Integration with id ${post.integration.id} not found`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...post,
|
||||||
|
settings: {
|
||||||
|
...(post.settings || ({} as any)),
|
||||||
|
__type: integration.providerIdentifier,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
const validationPipe = new ValidationPipe({
|
||||||
|
skipMissingProperties: false,
|
||||||
|
transform: true,
|
||||||
|
transformOptions: {
|
||||||
|
enableImplicitConversion: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return await validationPipe.transform(mappedValues, {
|
||||||
|
type: 'body',
|
||||||
|
metatype: CreatePostDto,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async getPostsRecursively(
|
async getPostsRecursively(
|
||||||
id: string,
|
id: string,
|
||||||
includeIntegration = false,
|
includeIntegration = false,
|
||||||
|
|
@ -572,7 +627,10 @@ export class PostsService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async postArticle(integration: Integration, posts: Post[]): Promise<any> {
|
private async postArticle(
|
||||||
|
integration: Integration,
|
||||||
|
posts: Post[]
|
||||||
|
): Promise<any> {
|
||||||
const getIntegration = this._integrationManager.getArticlesIntegration(
|
const getIntegration = this._integrationManager.getArticlesIntegration(
|
||||||
integration.providerIdentifier
|
integration.providerIdentifier
|
||||||
);
|
);
|
||||||
|
|
@ -929,7 +987,10 @@ export class PostsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async findFreeDateTime(orgId: string, integrationId?: string) {
|
async findFreeDateTime(orgId: string, integrationId?: string) {
|
||||||
const findTimes = await this._integrationService.findFreeDateTime(orgId, integrationId);
|
const findTimes = await this._integrationService.findFreeDateTime(
|
||||||
|
orgId,
|
||||||
|
integrationId
|
||||||
|
);
|
||||||
return this.findFreeDateTimeRecursive(
|
return this.findFreeDateTimeRecursive(
|
||||||
orgId,
|
orgId,
|
||||||
findTimes,
|
findTimes,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue