/
insight-card.controller.ts
79 lines (72 loc) · 2.67 KB
/
insight-card.controller.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import {
Controller,
Get,
Header,
HttpStatus,
Param,
ParseIntPipe,
Redirect,
Res,
StreamableFile,
} from "@nestjs/common";
import {
ApiBadRequestResponse,
ApiForbiddenResponse,
ApiNoContentResponse,
ApiNotFoundResponse,
ApiOkResponse,
ApiOperation,
ApiResponse,
ApiTags,
} from "@nestjs/swagger";
import { FastifyReply } from "fastify";
import { InsightCardService } from "./insight-card.service";
@Controller("insights")
@ApiTags("Insight social cards")
export class InsightCardController {
constructor (private readonly insightCardService: InsightCardService) {}
@Get("/:id")
@ApiOperation({
operationId: "generateInsightSocialCard",
summary: "Gets latest cache aware social card link for :id or generates a new one",
})
@Header("Content-Type", "image/png")
@ApiOkResponse({ type: StreamableFile, description: "Social card image" })
@ApiNotFoundResponse({ description: "Insight not found" })
@ApiForbiddenResponse({ description: "Rate limit exceeded" })
@ApiBadRequestResponse({ description: "Invalid insight id" })
@Redirect()
async generateInsightSocialCard (
@Param("id", ParseIntPipe) id: number,
@Res({ passthrough: true }) res: FastifyReply,
): Promise<void> {
const { fileUrl, hasFile, needsUpdate } = await this.insightCardService.checkRequiresUpdate(id);
if (hasFile && !needsUpdate) {
return res.status(HttpStatus.FOUND).redirect(fileUrl);
}
const url = await this.insightCardService.getgetInsightCard(id);
return res.status(HttpStatus.FOUND).redirect(url);
}
@Get("/:id/metadata")
@ApiOperation({
operationId: "getInsightSocialCardMetadata",
summary: "Gets latest cache aware social card metadata for :id",
})
@ApiNoContentResponse({ description: "Insight social card image is up to date", status: HttpStatus.NO_CONTENT })
@ApiResponse({ description: "Insight social card image needs regeneration", status: HttpStatus.NOT_MODIFIED })
@ApiNotFoundResponse({ description: "Insight social card image not found", status: HttpStatus.NOT_FOUND })
@ApiBadRequestResponse({ description: "Invalid insight id", status: HttpStatus.BAD_REQUEST })
async checkInsightSocialCard (
@Param("id", ParseIntPipe) id: number,
@Res({ passthrough: true }) res: FastifyReply,
): Promise<void> {
const { fileUrl, hasFile, needsUpdate, lastModified } = await this.insightCardService.checkRequiresUpdate(id);
return res
.headers({
"x-amz-meta-last-modified": lastModified?.toISOString() ?? "",
"x-amz-meta-location": fileUrl,
})
.status(hasFile ? (needsUpdate ? HttpStatus.NOT_MODIFIED : HttpStatus.NO_CONTENT) : HttpStatus.NOT_FOUND)
.send();
}
}