chalknotes 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +74 -0
- package/package.json +22 -0
- package/src/index.js +7 -0
- package/src/lib/getAllPosts.js +33 -0
- package/src/lib/getPostBySlug.js +90 -0
- package/src/lib/notion.js +11 -0
- package/src/utils.js +6 -0
package/bin/cli.js
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
const fs = require("fs");
|
3
|
+
const path = require("path");
|
4
|
+
|
5
|
+
console.log("Initializing ChalkNotes...");
|
6
|
+
|
7
|
+
const configPath = path.join(process.cwd(), 'blog.config.js');
|
8
|
+
const pageRouter = path.join(process.cwd(), '/pages')
|
9
|
+
const appRouter = path.join(process.cwd(), '/app')
|
10
|
+
|
11
|
+
|
12
|
+
if (fs.existsSync(pageRouter)) {
|
13
|
+
console.log("✅ Page router found");
|
14
|
+
const slugDir = path.join(pageRouter, "blog", "[slug].js")
|
15
|
+
const dirPath = path.dirname(slugDir);
|
16
|
+
|
17
|
+
const pageRouterTemplate = `
|
18
|
+
import { getStaticPropsForPost, getStaticPathsForPosts } from 'chalknotes';
|
19
|
+
|
20
|
+
export const getStaticProps = getStaticPropsForPost;
|
21
|
+
export const getStaticPaths = getStaticPathsForPosts;
|
22
|
+
|
23
|
+
export default function BlogPost({ post }) {
|
24
|
+
return (
|
25
|
+
<article>
|
26
|
+
<h1>{post.title}</h1>
|
27
|
+
<div dangerouslySetInnerHTML={{ __html: post.content }} />
|
28
|
+
</article>
|
29
|
+
);
|
30
|
+
}
|
31
|
+
`.trim();
|
32
|
+
|
33
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
34
|
+
fs.writeFileSync(slugDir, pageRouterTemplate)
|
35
|
+
} else if (fs.existsSync(appRouter)) {
|
36
|
+
console.log("✅ App router found");
|
37
|
+
const slugDir = path.join(appRouter, 'blog', "[slug]", "page.jsx")
|
38
|
+
const dirPath = path.dirname(slugDir);
|
39
|
+
|
40
|
+
const appRouterTemplate = `
|
41
|
+
import { getPostBySlug } from 'chalknotes';
|
42
|
+
|
43
|
+
export default async function BlogPost({ params }) {
|
44
|
+
const post = await getPostBySlug(params.slug);
|
45
|
+
|
46
|
+
return (
|
47
|
+
<article>
|
48
|
+
<h1>{post.title}</h1>
|
49
|
+
<div dangerouslySetInnerHTML={{ __html: post.content }} />
|
50
|
+
</article>
|
51
|
+
);
|
52
|
+
}
|
53
|
+
`.trim();
|
54
|
+
|
55
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
56
|
+
fs.writeFileSync(slugDir, appRouterTemplate)
|
57
|
+
} else {
|
58
|
+
console.log("❌ Page router and app router not found");
|
59
|
+
}
|
60
|
+
|
61
|
+
// if (!fs.existsSync(configPath)) {
|
62
|
+
// const configTemplate = `
|
63
|
+
// module.exports = {
|
64
|
+
// notionDatabaseId: '',
|
65
|
+
// notionToken: process.env.NOTION_TOKEN,
|
66
|
+
// routeBasePath: '/blog',
|
67
|
+
// plugins: [],
|
68
|
+
// };
|
69
|
+
// `;
|
70
|
+
// fs.writeFileSync(configPath, configTemplate.trim());
|
71
|
+
// console.log("✅ Created blog.config.js");
|
72
|
+
// } else {
|
73
|
+
// console.log("⚠️ blog.config.js already exists");
|
74
|
+
// }
|
package/package.json
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
{
|
2
|
+
"name": "chalknotes",
|
3
|
+
"version": "0.0.1",
|
4
|
+
"description": "A tool that simplifies blogs.",
|
5
|
+
"main": "src/index.js",
|
6
|
+
"bin": {
|
7
|
+
"chalknotes": "./bin/cli.js"
|
8
|
+
},
|
9
|
+
"scripts": {
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
11
|
+
},
|
12
|
+
"keywords": [
|
13
|
+
"blog",
|
14
|
+
"notion"
|
15
|
+
],
|
16
|
+
"author": "NepTune",
|
17
|
+
"license": "MIT",
|
18
|
+
"dependencies": {
|
19
|
+
"@notionhq/client": "^4.0.1",
|
20
|
+
"dotenv": "^17.2.1"
|
21
|
+
}
|
22
|
+
}
|
package/src/index.js
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
const { notion, dbId } = require('../notion/notion');
|
2
|
+
const { slugify } = require('../utils');
|
3
|
+
|
4
|
+
|
5
|
+
const getAllPosts = async () => {
|
6
|
+
const response = await notion.databases.query({
|
7
|
+
database_id: dbId,
|
8
|
+
filter: {
|
9
|
+
property: "Published",
|
10
|
+
checkbox: {
|
11
|
+
equals: true
|
12
|
+
}
|
13
|
+
}
|
14
|
+
})
|
15
|
+
|
16
|
+
const posts = []
|
17
|
+
console.log(response.results.length)
|
18
|
+
for (const page of response.results) {
|
19
|
+
const titleProperty = page.properties["Name"];
|
20
|
+
const title = titleProperty?.title?.[0]?.plain_text;
|
21
|
+
const pageSlug = slugify(title);
|
22
|
+
|
23
|
+
console.log(title, pageSlug, page.id)
|
24
|
+
posts.push({
|
25
|
+
title,
|
26
|
+
slug: pageSlug,
|
27
|
+
notionPageId: page.id,
|
28
|
+
})
|
29
|
+
}
|
30
|
+
return posts
|
31
|
+
}
|
32
|
+
|
33
|
+
getAllPosts()
|
@@ -0,0 +1,90 @@
|
|
1
|
+
const { notion, dbId } = require('../notion/notion');
|
2
|
+
const { slugify } = require('../utils');
|
3
|
+
|
4
|
+
const getPostBySlug = async (slug) => {
|
5
|
+
try {
|
6
|
+
const response = await notion.databases.query({
|
7
|
+
database_id: dbId,
|
8
|
+
filter: {
|
9
|
+
property: "Published",
|
10
|
+
checkbox: {
|
11
|
+
equals: true
|
12
|
+
}
|
13
|
+
}
|
14
|
+
})
|
15
|
+
|
16
|
+
for (const page of response.results) {
|
17
|
+
const titleProperty = page.properties["Name"];
|
18
|
+
const title = titleProperty?.title?.[0]?.plain_text;
|
19
|
+
const pageSlug = slugify(title);
|
20
|
+
|
21
|
+
if (pageSlug === slug) {
|
22
|
+
const response = await notion.blocks.children.list({
|
23
|
+
block_id: page.id,
|
24
|
+
})
|
25
|
+
let content = ""
|
26
|
+
for (const block of response.results) {
|
27
|
+
switch (block.type) {
|
28
|
+
case "paragraph":
|
29
|
+
const textHTML = block.paragraph.rich_text.map(text => text.plain_text).join("");
|
30
|
+
content += `<p>${textHTML}</p>`
|
31
|
+
break;
|
32
|
+
case "heading_1":
|
33
|
+
const headingHTML = block.heading_1.rich_text.map(text => text.plain_text).join("");
|
34
|
+
content += `<h1>${headingHTML}</h1>`
|
35
|
+
break;
|
36
|
+
case "heading_2":
|
37
|
+
const heading2HTML = block.heading_2.rich_text.map(text => text.plain_text).join("");
|
38
|
+
content += `<h2>${heading2HTML}</h2>`
|
39
|
+
break;
|
40
|
+
case "heading_3":
|
41
|
+
const heading3HTML = block.heading_3.rich_text.map(text => text.plain_text).join("");
|
42
|
+
content += `<h3>${heading3HTML}</h3>`
|
43
|
+
break;
|
44
|
+
}
|
45
|
+
console.log(content)
|
46
|
+
}
|
47
|
+
return {
|
48
|
+
title,
|
49
|
+
slug: pageSlug,
|
50
|
+
content: content,
|
51
|
+
notionPageId: page.id,
|
52
|
+
};
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
throw new Error(`No post found with slug "${slug}"`);
|
57
|
+
} catch (error) {
|
58
|
+
console.error(error)
|
59
|
+
throw new Error(`Error fetching posts from Notion: ${error.message}`);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
getPostBySlug("blog-posts")
|
64
|
+
|
65
|
+
module.exports = {
|
66
|
+
getPostBySlug
|
67
|
+
}
|
68
|
+
// const slugify = (title) =>
|
69
|
+
// title
|
70
|
+
// .toLowerCase()
|
71
|
+
// .replace(/[^a-z0-9]+/g, "-")
|
72
|
+
// .replace(/(^-|-$)/g, "");
|
73
|
+
|
74
|
+
// for (const page of response.results) {
|
75
|
+
// const titleProperty = page.properties["Name"];
|
76
|
+
// const title = titleProperty?.title?.[0]?.plain_text;
|
77
|
+
|
78
|
+
// const pageSlug = slugify(title);
|
79
|
+
|
80
|
+
// if (pageSlug === slug) {
|
81
|
+
// // FOUND IT
|
82
|
+
// return {
|
83
|
+
// title,
|
84
|
+
// slug: pageSlug,
|
85
|
+
// notionPageId: page.id,
|
86
|
+
// };
|
87
|
+
// }
|
88
|
+
// }
|
89
|
+
|
90
|
+
// throw new Error(`No post found with slug "${slug}"`);
|
@@ -0,0 +1,11 @@
|
|
1
|
+
const { Client } = require('@notionhq/client');
|
2
|
+
const dotenv = require('dotenv');
|
3
|
+
dotenv.config();
|
4
|
+
|
5
|
+
const notion = new Client({ auth: process.env.NOTION_TOKEN });
|
6
|
+
const dbId = process.env.NOTION_DATABASE_ID;
|
7
|
+
|
8
|
+
module.exports = {
|
9
|
+
notion,
|
10
|
+
dbId
|
11
|
+
}
|