fix news api
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
import { Controller } from "@/common/controller";
|
import { Controller } from "@/common/controller";
|
||||||
import { createOrmContextMiddleware } from "@/common/middlewares/create-orm-context.middleware";
|
import { createOrmContextMiddleware } from "@/common/middlewares/create-orm-context.middleware";
|
||||||
import { isAdminMiddleware } from "@/common/middlewares/is-admin.middleware";
|
import { isAdminMiddleware } from "@/common/middlewares/is-admin.middleware";
|
||||||
import { paginationQuerySchema } from "@/common/schemas";
|
|
||||||
import type { AbstractFileStorage } from "@/common/services/file-storage/abstract.file-storage";
|
import type { AbstractFileStorage } from "@/common/services/file-storage/abstract.file-storage";
|
||||||
import type { AbstractJwtService } from "@/common/services/jwt-service/abstract.jwt-service";
|
import type { AbstractJwtService } from "@/common/services/jwt-service/abstract.jwt-service";
|
||||||
import type {
|
import type {
|
||||||
@@ -16,9 +15,11 @@ import { orm } from "@/database/orm";
|
|||||||
import type { ArticleMapper } from "@/modules/article/article.mapper";
|
import type { ArticleMapper } from "@/modules/article/article.mapper";
|
||||||
import {
|
import {
|
||||||
articleParamsSchema,
|
articleParamsSchema,
|
||||||
|
articleQuerySchema,
|
||||||
articleRequestSchema,
|
articleRequestSchema,
|
||||||
} from "@/modules/article/article.schemas";
|
} from "@/modules/article/article.schemas";
|
||||||
import type { ArticleResponse } from "@/modules/article/article.types";
|
import type { ArticleResponse } from "@/modules/article/article.types";
|
||||||
|
import type { FilterQuery } from "@mikro-orm/core";
|
||||||
import { Router, type Request, type Response } from "express";
|
import { Router, type Request, type Response } from "express";
|
||||||
import slugify from "slugify";
|
import slugify from "slugify";
|
||||||
import { ulid } from "ulid";
|
import { ulid } from "ulid";
|
||||||
@@ -83,7 +84,7 @@ export class ArticleController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async list(req: Request, res: Response) {
|
async list(req: Request, res: Response) {
|
||||||
const parseQueryResult = paginationQuerySchema.safeParse(req.query);
|
const parseQueryResult = articleQuerySchema.safeParse(req.query);
|
||||||
if (!parseQueryResult.success) {
|
if (!parseQueryResult.success) {
|
||||||
return this.handleZodError(parseQueryResult.error, res, "query");
|
return this.handleZodError(parseQueryResult.error, res, "query");
|
||||||
}
|
}
|
||||||
@@ -91,15 +92,16 @@ export class ArticleController extends Controller {
|
|||||||
|
|
||||||
const count = await orm.em.count(Article);
|
const count = await orm.em.count(Article);
|
||||||
|
|
||||||
const articles = await orm.em.find(
|
const filter: FilterQuery<Article> = {};
|
||||||
Article,
|
if (query.tag_slug) {
|
||||||
{},
|
filter.tags = { slug: query.tag_slug };
|
||||||
{
|
}
|
||||||
|
|
||||||
|
const articles = await orm.em.find(Article, filter, {
|
||||||
limit: query.per_page,
|
limit: query.per_page,
|
||||||
offset: (query.page - 1) * query.per_page,
|
offset: (query.page - 1) * query.per_page,
|
||||||
orderBy: { createdAt: "DESC" },
|
orderBy: { createdAt: "DESC" },
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
data: articles.map(this.mapper.mapEntityToResponse.bind(this.mapper)),
|
data: articles.map(this.mapper.mapEntityToResponse.bind(this.mapper)),
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { paginationQuerySchema } from "@/common/schemas";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
|
|
||||||
export const articleRequestSchema = z.object({
|
export const articleRequestSchema = z.object({
|
||||||
@@ -21,6 +22,17 @@ export const articleRequestSchema = z.object({
|
|||||||
.max(100, "Max 100 characters."),
|
.max(100, "Max 100 characters."),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const articleQuerySchema = z.intersection(
|
||||||
|
paginationQuerySchema,
|
||||||
|
z.object({
|
||||||
|
tag_slug: z
|
||||||
|
.string("Must be string.")
|
||||||
|
.nonempty("Must not empty.")
|
||||||
|
.max(100, "Max 100 characters.")
|
||||||
|
.optional(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
export const articleParamsSchema = z.object({
|
export const articleParamsSchema = z.object({
|
||||||
slug: z
|
slug: z
|
||||||
.string("Must be string.")
|
.string("Must be string.")
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type {
|
import type {
|
||||||
articleParamsSchema,
|
articleParamsSchema,
|
||||||
|
articleQuerySchema,
|
||||||
articleRequestSchema,
|
articleRequestSchema,
|
||||||
} from "@/modules/article/article.schemas";
|
} from "@/modules/article/article.schemas";
|
||||||
import type { TagResponse } from "@/modules/tag/tag.types";
|
import type { TagResponse } from "@/modules/tag/tag.types";
|
||||||
@@ -7,6 +8,8 @@ import z from "zod";
|
|||||||
|
|
||||||
export type ArticleRequest = z.infer<typeof articleRequestSchema>;
|
export type ArticleRequest = z.infer<typeof articleRequestSchema>;
|
||||||
|
|
||||||
|
export type ArticleQuery = z.infer<typeof articleQuerySchema>;
|
||||||
|
|
||||||
export type ArticleParams = z.infer<typeof articleParamsSchema>;
|
export type ArticleParams = z.infer<typeof articleParamsSchema>;
|
||||||
|
|
||||||
export type ArticleResponse = {
|
export type ArticleResponse = {
|
||||||
|
|||||||
@@ -87,13 +87,13 @@ export class TagController extends Controller {
|
|||||||
}
|
}
|
||||||
const params = parseParamsResult.data;
|
const params = parseParamsResult.data;
|
||||||
|
|
||||||
const tag = await orm.em.findOne(Tag, { id: params.id });
|
const tag = await orm.em.findOne(Tag, { slug: params.slug });
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
return res.status(404).json({
|
return res.status(404).json({
|
||||||
data: null,
|
data: null,
|
||||||
errors: [
|
errors: [
|
||||||
{
|
{
|
||||||
path: "id",
|
path: "slug",
|
||||||
location: "params",
|
location: "params",
|
||||||
message: "Tag not found.",
|
message: "Tag not found.",
|
||||||
},
|
},
|
||||||
@@ -120,13 +120,13 @@ export class TagController extends Controller {
|
|||||||
}
|
}
|
||||||
const body = parseBodyResult.data;
|
const body = parseBodyResult.data;
|
||||||
|
|
||||||
const tag = await orm.em.findOne(Tag, { id: params.id });
|
const tag = await orm.em.findOne(Tag, { slug: params.slug });
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
return res.status(404).json({
|
return res.status(404).json({
|
||||||
data: null,
|
data: null,
|
||||||
errors: [
|
errors: [
|
||||||
{
|
{
|
||||||
path: "id",
|
path: "slug",
|
||||||
location: "params",
|
location: "params",
|
||||||
message: "Tag not found.",
|
message: "Tag not found.",
|
||||||
},
|
},
|
||||||
@@ -155,7 +155,7 @@ export class TagController extends Controller {
|
|||||||
|
|
||||||
const tag = await orm.em.findOne(
|
const tag = await orm.em.findOne(
|
||||||
Tag,
|
Tag,
|
||||||
{ id: params.id },
|
{ slug: params.slug },
|
||||||
{
|
{
|
||||||
populate: ["*"],
|
populate: ["*"],
|
||||||
},
|
},
|
||||||
@@ -165,7 +165,7 @@ export class TagController extends Controller {
|
|||||||
data: null,
|
data: null,
|
||||||
errors: [
|
errors: [
|
||||||
{
|
{
|
||||||
path: "id",
|
path: "slug",
|
||||||
location: "params",
|
location: "params",
|
||||||
message: "Tag not found.",
|
message: "Tag not found.",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ export const tagRequestSchema = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const tagParamsSchema = z.object({
|
export const tagParamsSchema = z.object({
|
||||||
id: z
|
slug: z
|
||||||
.ulid("Must be ulid string.")
|
.string("Must be string.")
|
||||||
.nonempty("Must not empty.")
|
.nonempty("Must not empty.")
|
||||||
.max(30, "Max 30 characters."),
|
.max(100, "Max 100 characters."),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user