Skip to content

Commit 9c66f23

Browse files
authored
Merge pull request #70 from techulus/develop
Add endpoint for fetching a post, Update docs
2 parents 2b63829 + 5ec59b2 commit 9c66f23

File tree

7 files changed

+109
-7
lines changed

7 files changed

+109
-7
lines changed

apps/docs/content/docs/api/page.mdx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Page
33
description: These are APIs that can be used to fetch page data
44
---
55

6-
### Get the latest post
6+
### Get latest post
77

88
This endpoint will return a JSON response of the latest post in the page.
99

@@ -70,3 +70,25 @@ GET https://yourpage.changes.page/changes.json
7070
}
7171
]
7272
```
73+
74+
### Get a post by id
75+
76+
This endpoint will return a JSON response of a post by id.
77+
78+
```text title="Request"
79+
GET https://yourpage.changes.page/changes.json/:id
80+
```
81+
82+
```json title="Response: 200 OK"
83+
{
84+
"id": "cf8c52a9-27b3-47df-9f22-0c0af15cfaca",
85+
"title": "Unlock Teamwork with Our Latest Feature Update",
86+
"content": "We're kicking off 2025 by introducing one of our most highly requested features!",
87+
"tags": ["announcement", "new"],
88+
"publication_date": "2025-02-14T12:22:16.571+00:00",
89+
"updated_at": "2025-02-14T12:22:17.887817+00:00",
90+
"created_at": "2025-02-14T09:42:52.934045+00:00",
91+
"url": "https://hey.changes.page/post/cf8c52a9-27b3-47df-9f22-0c0af15cfaca/unlock-teamwork-with-our-latest-feature-update",
92+
"plain_text_content": "We're kicking off 2025 by introducing one of our most highly requested features!"
93+
}
94+
```

apps/page/next.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ const moduleExports = {
8787
source: "/changes.json",
8888
destination: "/api/json",
8989
},
90+
{
91+
source: "/changes.json/:id",
92+
destination: "/api/post/:id",
93+
},
9094
{
9195
source: "/latest.json",
9296
destination: "/api/latest",

apps/page/pages/api/json.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import type { NextApiRequest, NextApiResponse } from "next";
21
import { IPost } from "@changes-page/supabase/types/page";
2+
import { convertMarkdownToPlainText } from "@changes-page/utils";
3+
import type { NextApiRequest, NextApiResponse } from "next";
34
import { allowCors } from "../../lib/cors";
45
import {
56
fetchPosts,
67
fetchRenderData,
78
translateHostToPageIdentifier,
89
} from "../../lib/data";
9-
import { convertMarkdownToPlainText } from "@changes-page/utils";
1010
import { getPageUrl, getPostUrl } from "../../lib/url";
1111

1212
async function handler(
@@ -43,7 +43,7 @@ async function handler(
4343

4444
res.status(200).json(postsWithUrl);
4545
} catch (e: Error | any) {
46-
console.log("changes.md [Error]", e);
46+
console.log("Failed to fetch posts [Error]", e);
4747
res.status(200).json([]);
4848
}
4949
}

apps/page/pages/api/latest.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ async function handler(
5959

6060
res.status(200).json(postsWithUrl[0] ?? null);
6161
} catch (e: Error | any) {
62-
console.log("changes.md [Error]", e);
62+
console.log("Failed to fetch latest post [Error]", e);
6363
res.status(404).json(null);
6464
}
6565
}

apps/page/pages/api/markdown.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ ${post.content}
4040

4141
res.status(200).send(markdown);
4242
} catch (e: Error | any) {
43-
console.log("changes.md [Error]", e);
43+
console.log("Failed to fetch posts [changes.md] [Error]", e);
4444
res.status(200).send("## No posts Found");
4545
}
4646
}

apps/page/pages/api/pinned.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ async function handler(
6060

6161
res.status(200).json(postsWithUrl[0]);
6262
} catch (e: Error | any) {
63-
console.log("changes.md [Error]", e);
63+
console.log("Failed to fetch pinned post [Error]", e);
6464
res.status(404).json(null);
6565
}
6666
}

apps/page/pages/api/post/[id].ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { supabaseAdmin } from "@changes-page/supabase/admin";
2+
import { IPost } from "@changes-page/supabase/types/page";
3+
import { convertMarkdownToPlainText } from "@changes-page/utils";
4+
import type { NextApiRequest, NextApiResponse } from "next";
5+
import { allowCors } from "../../../lib/cors";
6+
import {
7+
fetchRenderData,
8+
translateHostToPageIdentifier,
9+
} from "../../../lib/data";
10+
import { getPageUrl, getPostUrl } from "../../../lib/url";
11+
12+
type IPostWithUrl = Pick<
13+
IPost,
14+
"id" | "title" | "content" | "tags" | "created_at"
15+
> & { url: string; plain_text_content: string };
16+
17+
async function handler(
18+
req: NextApiRequest,
19+
res: NextApiResponse<IPostWithUrl | null>
20+
) {
21+
const { id } = req.query;
22+
if (!id) {
23+
res.status(404).json(null);
24+
return;
25+
}
26+
27+
await allowCors(req, res);
28+
29+
const hostname = String(req?.headers?.host);
30+
const { domain, page: url_slug } = translateHostToPageIdentifier(hostname);
31+
32+
try {
33+
const { page, settings } = await fetchRenderData(
34+
String(domain || url_slug)
35+
);
36+
37+
if (!page) throw new Error("Page not found");
38+
if (!settings) throw new Error("Settings not found");
39+
40+
const pageUrl = getPageUrl(page, settings, hostname);
41+
42+
const { data, error: postsError } = await supabaseAdmin
43+
.from("posts")
44+
.select("id,title,content,tags,publication_date,updated_at,created_at")
45+
.eq("id", String(id))
46+
.eq("page_id", String(page?.id))
47+
.eq("status", "published")
48+
.order("publication_date", { ascending: false })
49+
.limit(1);
50+
51+
if (postsError) {
52+
console.error("Fetch post error", postsError);
53+
throw new Error("Failed to fetch posts");
54+
}
55+
56+
const posts = data as Array<IPost>;
57+
58+
if (!posts?.length) {
59+
res.status(404).json(null);
60+
return;
61+
}
62+
63+
const post = posts[0];
64+
65+
res.status(200).json({
66+
...post,
67+
url: getPostUrl(pageUrl, post),
68+
plain_text_content: convertMarkdownToPlainText(post.content),
69+
});
70+
} catch (e: Error | any) {
71+
console.log("Failed to fetch post [Error]", e);
72+
res.status(404).json(null);
73+
}
74+
}
75+
76+
export default handler;

0 commit comments

Comments
 (0)