Skip to content

Commit 45cee7e

Browse files
committed
Add loader and schema
1 parent df7c2a1 commit 45cee7e

File tree

7 files changed

+166
-25
lines changed

7 files changed

+166
-25
lines changed

.yarnrc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nodeLinker: node-modules

index.ts

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,2 @@
1-
import type { AstroIntegration } from 'astro';
2-
3-
export default function createIntegration(): AstroIntegration {
4-
// See the Integration API docs for full details
5-
// https://docs.astro.build/en/reference/integrations-reference/
6-
return {
7-
name: '@example/my-integration',
8-
hooks: {
9-
'astro:config:setup': () => {
10-
// See the @astrojs/react integration for an example
11-
// https://github.com/withastro/astro/blob/main/packages/integrations/react/src/index.ts
12-
},
13-
'astro:build:setup': () => {
14-
// See the @astrojs/react integration for an example
15-
// https://github.com/withastro/astro/blob/main/packages/integrations/react/src/index.ts
16-
},
17-
'astro:build:done': () => {
18-
// See the @astrojs/partytown integration for an example
19-
// https://github.com/withastro/astro/blob/main/packages/integrations/partytown/src/index.ts
20-
},
21-
},
22-
};
23-
}
1+
export { qiitaLoader } from "./src/loader";
2+
export type { Item, User, Tagging, TeamMembership } from "./src/schema";

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"author": "t0yohei <k.t0yohei@gmail.com>",
2424
"license": "MIT",
2525
"devDependencies": {
26-
"astro": "^5.3.0"
26+
"astro": "^5.3.0",
27+
"typescript": "^5.7.3"
2728
},
2829
"peerDependencies": {
2930
"astro": "^5.0.0"

src/loader.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import type { Loader } from "astro/loaders";
2+
import { ItemSchema, type Item } from "./schema";
3+
4+
export const qiitaLoader = (options: {
5+
url: string;
6+
authToken?: string;
7+
}): Loader => {
8+
const qiitaUrl = new URL(options.url);
9+
return {
10+
name: "qiita-loader",
11+
load: async ({
12+
store,
13+
logger,
14+
parseData,
15+
meta,
16+
generateDigest,
17+
}): Promise<void> => {
18+
logger.info("Loading posts from Qiita");
19+
20+
const headers = options.authToken
21+
? {
22+
Authorization: `Bearer ${options.authToken}`,
23+
}
24+
: {};
25+
const response = await fetch(qiitaUrl, {
26+
headers: headers as HeadersInit,
27+
});
28+
29+
if (!response.ok) {
30+
throw new Error(`Failed to fetch items: ${response.statusText}`);
31+
}
32+
33+
store.clear();
34+
35+
const responseJson = await response.json();
36+
37+
responseJson.forEach(async (item: Item) => {
38+
const data = await parseData({
39+
id: item.id,
40+
data: item,
41+
});
42+
43+
const digest = generateDigest(data);
44+
45+
store.set({
46+
id: data.id,
47+
data,
48+
rendered: {
49+
html: data.rendered_body,
50+
},
51+
digest,
52+
});
53+
});
54+
55+
logger.info(`Loaded ${responseJson.length} posts from Qiita`);
56+
},
57+
schema: ItemSchema,
58+
};
59+
};

src/schema.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { z } from "astro/zod";
2+
3+
// https://qiita.com/api/v2/docs#%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97
4+
export const GroupSchema = z.object({
5+
created_at: z.coerce.date(),
6+
description: z.string(),
7+
name: z.string(),
8+
private: z.boolean(),
9+
updated_at: z.coerce.date(),
10+
url_name: z.string(),
11+
});
12+
13+
// https://qiita.com/api/v2/docs#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC
14+
export const UserSchema = z.object({
15+
description: z.string().nullable(),
16+
facebook_id: z.string().nullable(),
17+
followees_count: z.number(),
18+
followers_count: z.number(),
19+
github_login_name: z.string().nullable(),
20+
id: z.string(),
21+
items_count: z.number(),
22+
linkedin_id: z.string().nullable(),
23+
location: z.string().nullable(),
24+
name: z.string().nullable(),
25+
organization: z.string().nullable(),
26+
permanent_id: z.number(),
27+
profile_image_url: z.string(),
28+
team_only: z.boolean(),
29+
twitter_screen_name: z.string().nullable(),
30+
website_url: z.string().nullable(),
31+
});
32+
33+
// https://qiita.com/api/v2/docs#%E3%82%BF%E3%82%AE%E3%83%B3%E3%82%B0
34+
export const TaggingSchema = z.object({
35+
name: z.string(),
36+
versions: z.array(z.string()),
37+
});
38+
39+
// https://qiita.com/api/v2/docs#%E3%83%81%E3%83%BC%E3%83%A0%E3%83%A1%E3%83%B3%E3%83%90%E3%83%BC
40+
export const TeamMembershipSchema = z.object({
41+
description: z.string(),
42+
email: z.string(),
43+
id: z.string(),
44+
last_accessed_at: z.string(),
45+
name: z.string(),
46+
});
47+
48+
// https://qiita.com/api/v2/docs#%E6%8A%95%E7%A8%BF
49+
export const ItemSchema = z.object({
50+
rendered_body: z.string(),
51+
body: z.string(),
52+
coediting: z.boolean(),
53+
comments_count: z.number(),
54+
created_at: z.coerce.date(),
55+
group: GroupSchema.nullable(),
56+
id: z.string(),
57+
likes_count: z.number(),
58+
private: z.boolean(),
59+
reactions_count: z.number(),
60+
stocks_count: z.number(),
61+
tags: z.array(TaggingSchema),
62+
title: z.string(),
63+
updated_at: z.coerce.date(),
64+
url: z.string(),
65+
user: UserSchema,
66+
page_views_count: z.number().nullable(),
67+
team_membership: TeamMembershipSchema.nullable(),
68+
organization_url_name: z.string().nullable(),
69+
slide: z.boolean(),
70+
});
71+
72+
export type Group = z.infer<typeof GroupSchema>;
73+
export type User = z.infer<typeof UserSchema>;
74+
export type Tagging = z.infer<typeof TaggingSchema>;
75+
export type TeamMembership = z.infer<typeof TeamMembershipSchema>;
76+
export type Item = z.infer<typeof ItemSchema>;

tsconfig.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
{
2-
"extends": "astro/tsconfigs/strict"
2+
"extends": "astro/tsconfigs/strict",
3+
"include": ["index.ts", "src/*.ts"],
4+
"compilerOptions": {
5+
"strictNullChecks": true
6+
}
37
}

yarn.lock

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,7 @@ __metadata:
955955
resolution: "astro-qiita-loader@workspace:."
956956
dependencies:
957957
astro: "npm:^5.3.0"
958+
typescript: "npm:^5.7.3"
958959
peerDependencies:
959960
astro: ^5.0.0
960961
languageName: unknown
@@ -3813,6 +3814,26 @@ __metadata:
38133814
languageName: node
38143815
linkType: hard
38153816

3817+
"typescript@npm:^5.7.3":
3818+
version: 5.7.3
3819+
resolution: "typescript@npm:5.7.3"
3820+
bin:
3821+
tsc: bin/tsc
3822+
tsserver: bin/tsserver
3823+
checksum: 10c0/b7580d716cf1824736cc6e628ab4cd8b51877408ba2be0869d2866da35ef8366dd6ae9eb9d0851470a39be17cbd61df1126f9e211d8799d764ea7431d5435afa
3824+
languageName: node
3825+
linkType: hard
3826+
3827+
"typescript@patch:typescript@npm%3A^5.7.3#optional!builtin<compat/typescript>":
3828+
version: 5.7.3
3829+
resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin<compat/typescript>::version=5.7.3&hash=5786d5"
3830+
bin:
3831+
tsc: bin/tsc
3832+
tsserver: bin/tsserver
3833+
checksum: 10c0/6fd7e0ed3bf23a81246878c613423730c40e8bdbfec4c6e4d7bf1b847cbb39076e56ad5f50aa9d7ebd89877999abaee216002d3f2818885e41c907caaa192cc4
3834+
languageName: node
3835+
linkType: hard
3836+
38163837
"ufo@npm:^1.5.4":
38173838
version: 1.5.4
38183839
resolution: "ufo@npm:1.5.4"

0 commit comments

Comments
 (0)