This commit is contained in:
Jordi Enric
2025-04-21 12:20:49 +02:00
parent 26f930d603
commit de5aa345d9
14 changed files with 248 additions and 35 deletions
@@ -0,0 +1,34 @@
import { CodeBlock } from "@/components/CodeBlock";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { EndpointCodeExamples } from "app/api/public/[...route]/public-api.types";
export function CodeExamples({ examples }: { examples: EndpointCodeExamples }) {
const keys = Object.keys(examples) as (keyof EndpointCodeExamples)[];
return (
<div className="flex flex-col gap-4">
<Tabs defaultValue={keys[0]}>
<TabsList>
{keys.map((key) => (
<TabsTrigger key={key} value={key}>
{key}
</TabsTrigger>
))}
</TabsList>
{keys.map((key) => (
<TabsContent key={key} value={key}>
<div className="flex flex-col gap-4">
{examples[key].map((example) => (
<CodeBlock key={example.description} hideHeader>
{`// ${example.description}
${example.code.trim()}
`}
</CodeBlock>
))}
</div>
</TabsContent>
))}
</Tabs>
</div>
);
}
@@ -1,10 +1,11 @@
import { ObjectRenderer } from "app/(docs)/ui/object-renderer";
import { useParams } from "next/navigation";
import {
BASE_API_URL,
endpoints,
} from "app/api/public/[...route]/public-api.constants";
import { Metadata } from "next";
import { CodeExamples } from "./code-examples";
import { CodeBlock } from "@/components/CodeBlock";
type Props = {
params: Promise<{ endpointId: string }>;
@@ -61,9 +62,11 @@ export default async function Endpoint(props: Props) {
<ul className="mt-2 list-disc space-y-2 pl-4">
{endpoint.headers?.map((header) => (
<li key={header.key}>
<div className="flex gap-2">
<div className="flex items-center gap-2">
<p className="font-medium">{header.key}</p>
<p>{header.required ? "Required" : "Optional"}</p>
<p className="text-xs text-zinc-400">
{header.required ? "Required" : "Optional"}
</p>
</div>
<p>{header.description}</p>
</li>
@@ -77,9 +80,11 @@ export default async function Endpoint(props: Props) {
<ul className="mt-2 list-disc space-y-2 pl-4">
{endpoint.query?.map((query) => (
<li key={query.key}>
<div className="flex gap-2">
<div className="flex items-center gap-2">
<p className="font-medium">{query.key}</p>
<p>{query.required ? "Required" : "Optional"}</p>
<p className="text-xs text-zinc-400">
{query.required ? "Required" : "Optional"}
</p>
</div>
<p>{query.description}</p>
</li>
@@ -97,13 +102,17 @@ export default async function Endpoint(props: Props) {
<p className="font-medium">{status}</p>
<p>{response.description}</p>
</div>
<pre className="mt-2 overflow-x-auto rounded-md bg-gray-100 p-4 text-xs">
{response.example}
</pre>
<CodeBlock language="typescript">{response.example}</CodeBlock>
</div>
))}
</div>
</div>
<hr className="my-4" />
<section>
<h3 className="text-md font-medium">Usage</h3>
<CodeExamples examples={endpoint.examples} />
</section>
</div>
</>
);
@@ -0,0 +1,34 @@
/**
* Checks if the code examples are valid with typescript
*/
import { createZenblogClient } from "zenblog";
const zenblog = createZenblogClient({
blogId: "doesnt-matter",
});
const posts = await zenblog.posts.list({
limit: 100,
offset: 0,
tags: ["tag1", "tag2"],
category: "category-slug",
author: "author-slug",
});
const postsBySlug = await zenblog.posts.get({
slug: "slug",
});
const categories = await zenblog.categories.list();
const tags = await zenblog.tags.list();
const authors = await zenblog.authors.list();
const authorBySlug = await zenblog.authors.get({
slug: "slug",
});
console.log(posts);
console.log(postsBySlug);
console.log(categories);
console.log(tags);
console.log(authors);
console.log(authorBySlug);
@@ -8,6 +8,38 @@ export const posts: Endpoint = {
method: "GET",
title: "Post list",
description: "Get posts for a blog",
examples: {
typescript: [
{
description: "Get posts for a blog",
code: `const { data: posts } = await zenblog.posts.list()`,
},
{
description: "Get posts for a blog filtered by a category",
code: `const { data: posts } = await zenblog.posts.list({
category: "news",
})`,
},
{
description: "Get posts limit results to 10",
code: `const { data: posts } = await zenblog.posts.list({
limit: 10,
})`,
},
{
description: "Get posts filtered by tag slugs",
code: `const { data: posts } = await zenblog.posts.list({
tags: ["tag1", "tag2"],
})`,
},
{
description: "Get posts filtered by author slug",
code: `const { data: posts } = await zenblog.posts.list({
author: "author-slug",
})`,
},
],
},
query: [
{
key: "offset",
@@ -22,8 +54,7 @@ export const posts: Endpoint = {
{
key: "category",
required: false,
description:
"The category slug to filter posts by. Example: &category=news",
description: "The category slug to filter posts by. Ex: &category=news",
},
{
key: "tags",
@@ -85,14 +116,36 @@ export const postBySlug: Endpoint = {
title: "string",
html_content: "string",
slug: "string",
category_name: "string",
category_slug: "string",
tags: "object",
excerpt: "string",
published_at: "string",
category?: {
name: "string",
slug: "string",
},
tags?: [{
name: "string",
slug: "string",
}],
authors?: [{
slug: "string",
name: "string",
image_url?: "string",
website?: "string",
twitter?: "string",
}],
excerpt: "string",
published_at: "string",
}`,
},
},
examples: {
typescript: [
{
description: "Get a post by its slug",
code: `const { data: post } = await zenblog.posts.get({
slug: "post-slug",
})`,
},
],
},
};
export const categories: Endpoint = {
id: "categories",
@@ -117,6 +170,14 @@ export const categories: Endpoint = {
}`,
},
},
examples: {
typescript: [
{
description: "Get the categories for a blog",
code: `const { data: categories } = await zenblog.categories.list()`,
},
],
},
};
export const tags: Endpoint = {
id: "tags",
@@ -141,6 +202,14 @@ export const tags: Endpoint = {
}`,
},
},
examples: {
typescript: [
{
description: "Get the tags for a blog",
code: `const { data: tags } = await zenblog.tags.list()`,
},
],
},
};
export const authors: Endpoint = {
@@ -149,9 +218,14 @@ export const authors: Endpoint = {
method: "GET",
title: "Authors list",
description: "Get the authors for a blog",
typescriptExample: `
const { data: authors } = await zenblogClient.authors.list()
`,
examples: {
typescript: [
{
description: "Get the authors for a blog",
code: `const { data: authors } = await zenblog.authors.list()`,
},
],
},
response: {
200: {
description: "The authors",
@@ -196,6 +270,16 @@ export const authorBySlug: Endpoint = {
}`,
},
},
examples: {
typescript: [
{
description: "Get an author by their slug",
code: `const { data: author } = await zenblog.authors.get({
slug: "author-slug",
})`,
},
],
},
};
export const endpoints = [
@@ -1,3 +1,12 @@
export type CodeExample = {
description: string;
code: string;
};
export type EndpointCodeExamples = {
typescript: CodeExample[];
};
export type Endpoint = {
id: string;
path: string;
@@ -7,7 +16,7 @@ export type Endpoint = {
headers?: Header[];
query?: Query[];
response: Response;
typescriptExample?: string;
examples: EndpointCodeExamples;
};
export type Header = {
+14 -10
View File
@@ -1,21 +1,23 @@
"use client";
import React, { PropsWithChildren } from "react";
import React from "react";
import SyntaxHighlighter from "react-syntax-highlighter";
import { atomOneDark } from "react-syntax-highlighter/dist/esm/styles/hljs";
import { Check, CheckCheck, Clipboard } from "lucide-react";
import { stackoverflowDark as codeTheme } from "react-syntax-highlighter/dist/esm/styles/hljs";
import { Check, Clipboard } from "lucide-react";
import useClipboard from "react-use-clipboard";
type Props = {
children: string;
language?: string;
title?: string;
hideHeader?: boolean;
};
export const CodeBlock = ({
children,
language = "typescript",
title,
hideHeader = false,
}: Props) => {
const [isCopied, copy] = useClipboard(children, {
successDuration: 1000,
@@ -23,12 +25,14 @@ export const CodeBlock = ({
return (
<div className="rounded-lg bg-zinc-900 font-mono text-white">
<div className="flex items-center justify-between pl-2">
<h2 className="text-xs text-zinc-300">{title || language}</h2>
<button onClick={copy} className="p-2 text-zinc-400">
{isCopied ? <Check size="15" /> : <Clipboard size="15" />}
</button>
</div>
{!hideHeader && (
<div className="flex items-center justify-between pl-2">
<h2 className="text-xs text-zinc-300">{title || language}</h2>
<button onClick={copy} className="p-2 text-zinc-400">
{isCopied ? <Check size="15" /> : <Clipboard size="15" />}
</button>
</div>
)}
<SyntaxHighlighter
customStyle={{
padding: "1rem",
@@ -37,7 +41,7 @@ export const CodeBlock = ({
fontSize: "0.82rem",
}}
language={language}
style={atomOneDark}
style={codeTheme}
>
{children}
</SyntaxHighlighter>
+1 -1
View File
@@ -25786,7 +25786,7 @@
}
},
"packages/zenblog": {
"version": "1.1.0",
"version": "1.2.0",
"license": "MIT",
"dependencies": {
"@types/node": "^20.17.6",
+7
View File
@@ -39,6 +39,13 @@ export declare function createZenblogClient({ blogId, _url, _debug, }: CreateCli
};
authors: {
list: () => Promise<PaginatedApiResponse<Author[]>>;
get: ({ slug }: {
slug: string;
}, opts?: {
cache?: RequestInit["cache"];
limit?: number;
offset?: number;
}) => Promise<ApiResponse<Author>>;
};
};
export {};
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAEvE,KAAK,WAAW,CAAC,CAAC,IAAI;IACpB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF,KAAK,oBAAoB,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AA2CF,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AACF,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,IAAI,EACJ,MAAM,GACP,EAAE,gBAAgB;;;oBAiBP,WAAW,CAAC,OAAO,CAAC;oBACpB,MAAM;qBACL,MAAM;;uBAIJ,MAAM;mBACV,MAAM,EAAE;qBACN,MAAM;cAWU,OAAO,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC;wBAkBhD;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE;oBArCtB,WAAW,CAAC,OAAO,CAAC;oBACpB,MAAM;qBACL,MAAM;cAqCV,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;;;oBAUf,OAAO,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC,CAAC;;;oBASzC,OAAO,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAAC,CAAC;;;oBASpC,OAAO,CAAC,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC;;EASrE"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAEvE,KAAK,WAAW,CAAC,CAAC,IAAI;IACpB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF,KAAK,oBAAoB,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AA2CF,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AACF,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,IAAI,EACJ,MAAM,GACP,EAAE,gBAAgB;;;oBAiBP,WAAW,CAAC,OAAO,CAAC;oBACpB,MAAM;qBACL,MAAM;;uBAIJ,MAAM;mBACV,MAAM,EAAE;qBACN,MAAM;cAWU,OAAO,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC;wBAkBhD;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE;oBArCtB,WAAW,CAAC,OAAO,CAAC;oBACpB,MAAM;qBACL,MAAM;cAqCV,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;;;oBAUf,OAAO,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC,CAAC;;;oBASzC,OAAO,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAAC,CAAC;;;oBASpC,OAAO,CAAC,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC;wBAQpD;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE;oBA3EtB,WAAW,CAAC,OAAO,CAAC;oBACpB,MAAM;qBACL,MAAM;cA2EV,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;;EAUpC"}
+7
View File
@@ -92,6 +92,13 @@ function createZenblogClient({ blogId, _url, _debug, }) {
});
return data;
},
get: async function ({ slug }, opts) {
const data = await fetcher(`authors/${slug}`, {
method: "GET",
cache: opts?.cache || "default",
});
return data;
},
},
};
}
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "zenblog",
"version": "1.1.0",
"version": "1.2.0",
"description": "The typescript client for zenblog",
"main": "dist/index.js",
"types": "dist/index.d.ts",
+11
View File
@@ -152,6 +152,17 @@ export function createZenblogClient({
return data as PaginatedApiResponse<Author[]>;
},
get: async function (
{ slug }: { slug: string },
opts?: ReqOpts
): Promise<ApiResponse<Author>> {
const data = await fetcher(`authors/${slug}`, {
method: "GET",
cache: opts?.cache || "default",
});
return data as ApiResponse<Author>;
},
},
};
}
+16 -2
View File
@@ -36,10 +36,12 @@ test("Posts get by slug", async () => {
blogId: DEMO_BLOG_ID,
});
const post = await client.posts.get({ slug: "test" });
const post = await client.posts.get({
slug: "reginald-lord-of-the-highlands",
});
expect(post).toBeDefined();
expect(post.data).toBeDefined();
expect(post.data.slug).toBe("test");
expect(post.data.slug).toBe("reginald-lord-of-the-highlands");
expect(post.data.html_content).toBeDefined();
});
@@ -57,6 +59,18 @@ test("Authors list", async () => {
expect(authors.limit).toBeDefined();
});
test("Authors get by slug", async () => {
const client = createZenblogClient({
blogId: DEMO_BLOG_ID,
});
const author = await client.authors.get({ slug: "pepe" });
expect(author).toBeDefined();
expect(author.data).toBeDefined();
expect(author.data.slug).toBe("pepe");
});
test("Tags list", async () => {
const client = createZenblogClient({
blogId: DEMO_BLOG_ID,