chalknotes 0.0.32 ā 0.0.33
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 +72 -156
- package/package.json +1 -1
- package/src/lib/getPostBySlug.js +17 -0
package/bin/cli.js
CHANGED
@@ -9,15 +9,15 @@ console.log("š Initializing ChalkNotes...");
|
|
9
9
|
|
10
10
|
// Check environment variables
|
11
11
|
if (!process.env.NOTION_TOKEN) {
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
console.error("ā NOTION_TOKEN is not set in .env file");
|
13
|
+
console.log("š” Please create a .env file with your NOTION_TOKEN");
|
14
|
+
process.exit(1);
|
15
15
|
}
|
16
16
|
|
17
17
|
if (!process.env.NOTION_DATABASE_ID) {
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
console.error("ā NOTION_DATABASE_ID is not set in .env file");
|
19
|
+
console.log("š” Please create a .env file with your NOTION_DATABASE_ID");
|
20
|
+
process.exit(1);
|
21
21
|
}
|
22
22
|
|
23
23
|
console.log("ā
Environment variables are set");
|
@@ -26,19 +26,19 @@ const configPath = path.join(process.cwd(), 'blog.config.js');
|
|
26
26
|
|
27
27
|
// Check if blog.config.js exists
|
28
28
|
if (!fs.existsSync(configPath)) {
|
29
|
-
|
30
|
-
|
29
|
+
console.log("\nā blog.config.js not found");
|
30
|
+
console.log("This file is required to configure your blog settings.");
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
const rl = readline.createInterface({
|
33
|
+
input: process.stdin,
|
34
|
+
output: process.stdout
|
35
|
+
});
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
rl.question("Would you like to create a default blog.config.js? (y/n): ", (answer) => {
|
38
|
+
if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
|
39
|
+
console.log("š Creating blog.config.js with default configuration...");
|
40
40
|
|
41
|
-
|
41
|
+
const configTemplate = `module.exports = {
|
42
42
|
notionToken: process.env.NOTION_TOKEN,
|
43
43
|
notionDatabaseId: process.env.NOTION_DATABASE_ID,
|
44
44
|
routeBasePath: '/blog',
|
@@ -46,24 +46,24 @@ if (!fs.existsSync(configPath)) {
|
|
46
46
|
plugins: [],
|
47
47
|
};`.trim();
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
49
|
+
fs.writeFileSync(configPath, configTemplate);
|
50
|
+
console.log("ā
Created blog.config.js with default configuration");
|
51
|
+
console.log("\nš” Now you can re-run 'npx chalknotes' to scaffold your blog pages!");
|
52
|
+
} else {
|
53
|
+
console.log("ā Please create a blog.config.js file and try again.");
|
54
|
+
}
|
55
|
+
rl.close();
|
56
|
+
});
|
57
|
+
return;
|
58
58
|
}
|
59
59
|
|
60
60
|
// Load configuration
|
61
61
|
let config;
|
62
62
|
try {
|
63
|
-
|
63
|
+
config = require(configPath);
|
64
64
|
} catch (error) {
|
65
|
-
|
66
|
-
|
65
|
+
console.error("ā Error loading blog.config.js:", error.message);
|
66
|
+
process.exit(1);
|
67
67
|
}
|
68
68
|
|
69
69
|
// Set defaults for missing config values
|
@@ -85,11 +85,11 @@ const appRouter = path.join(process.cwd(), '/app')
|
|
85
85
|
|
86
86
|
// Generate templates based on theme
|
87
87
|
function getTemplates(theme, routeBasePath) {
|
88
|
-
|
88
|
+
const routePath = routeBasePath.replace(/^\//, ''); // Remove leading slash
|
89
89
|
|
90
|
-
|
91
|
-
|
92
|
-
|
90
|
+
if (theme === 'dark') {
|
91
|
+
return {
|
92
|
+
pageRouter: `
|
93
93
|
import { getStaticPropsForPost, getStaticPathsForPosts } from 'chalknotes';
|
94
94
|
import NotionRenderer from './NotionRenderer';
|
95
95
|
|
@@ -110,7 +110,7 @@ export default function BlogPost({ post }) {
|
|
110
110
|
</div>
|
111
111
|
);
|
112
112
|
}`.trim(),
|
113
|
-
|
113
|
+
appRouter: `
|
114
114
|
import { getPostBySlug } from 'chalknotes';
|
115
115
|
import NotionRenderer from './NotionRenderer';
|
116
116
|
|
@@ -130,11 +130,11 @@ export default async function BlogPost({ params }) {
|
|
130
130
|
</div>
|
131
131
|
);
|
132
132
|
}`.trim()
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
133
|
+
};
|
134
|
+
} else {
|
135
|
+
// Default theme (light mode)
|
136
|
+
return {
|
137
|
+
pageRouter: `
|
138
138
|
import { getStaticPropsForPost, getStaticPathsForPosts } from 'chalknotes';
|
139
139
|
import NotionRenderer from './NotionRenderer';
|
140
140
|
|
@@ -155,7 +155,7 @@ export default function BlogPost({ post }) {
|
|
155
155
|
</div>
|
156
156
|
);
|
157
157
|
}`.trim(),
|
158
|
-
|
158
|
+
appRouter: `
|
159
159
|
import { getPostBySlug } from 'chalknotes';
|
160
160
|
import NotionRenderer from './NotionRenderer';
|
161
161
|
|
@@ -175,28 +175,19 @@ export default async function BlogPost({ params }) {
|
|
175
175
|
</div>
|
176
176
|
);
|
177
177
|
}`.trim()
|
178
|
-
|
179
|
-
|
178
|
+
};
|
179
|
+
}
|
180
180
|
}
|
181
181
|
|
182
|
-
//
|
183
|
-
|
184
|
-
console.log("ā
Page router found");
|
185
|
-
const routePath = config.routeBasePath.replace(/^\//, ''); // Remove leading slash
|
186
|
-
const slugDir = path.join(pageRouter, routePath, "[slug].js")
|
187
|
-
const dirPath = path.dirname(slugDir);
|
188
|
-
|
189
|
-
const templates = getTemplates(config.theme, config.routeBasePath);
|
190
|
-
|
191
|
-
// Create NotionRenderer component in the same directory as the blog page
|
192
|
-
const notionRendererContent = `import React from "react";
|
182
|
+
// NotionRenderer component template
|
183
|
+
const notionRendererTemplate = `import React from "react";
|
193
184
|
import Image from "next/image";
|
194
185
|
|
195
186
|
export default function NotionRenderer({ blocks }) {
|
196
187
|
if (!blocks || blocks.length === 0) return null;
|
197
188
|
|
198
189
|
return (
|
199
|
-
<div className="
|
190
|
+
<div className="max-w-none">
|
200
191
|
{blocks.map((block, i) => {
|
201
192
|
switch (block.type) {
|
202
193
|
case "heading_1":
|
@@ -300,119 +291,44 @@ export default function NotionRenderer({ blocks }) {
|
|
300
291
|
</div>
|
301
292
|
);
|
302
293
|
}`;
|
303
|
-
|
304
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
305
|
-
fs.writeFileSync(path.join(dirPath, 'NotionRenderer.jsx'), notionRendererContent);
|
306
|
-
console.log(`ā
Created ${routePath}/NotionRenderer.jsx`);
|
307
|
-
|
308
|
-
fs.writeFileSync(slugDir, templates.pageRouter);
|
309
|
-
console.log(`ā
Created pages/${routePath}/[slug].js`);
|
310
|
-
|
311
|
-
} else if (fs.existsSync(appRouter)) {
|
312
|
-
console.log("ā
App router found");
|
313
|
-
const routePath = config.routeBasePath.replace(/^\//, ''); // Remove leading slash
|
314
|
-
const slugDir = path.join(appRouter, routePath, "[slug]", "page.jsx")
|
315
|
-
const dirPath = path.dirname(slugDir);
|
316
|
-
|
317
|
-
const templates = getTemplates(config.theme, config.routeBasePath);
|
318
|
-
|
319
|
-
|
320
|
-
// Create NotionRenderer component in the same directory as the blog page
|
321
|
-
const notionRendererContent = `import React from "react";
|
322
|
-
import Image from "next/image";
|
323
|
-
|
324
|
-
export default function NotionRenderer({ blocks }) {
|
325
|
-
if (!blocks || blocks.length === 0) return null;
|
326
294
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
case "heading_2":
|
335
|
-
return <h2 key={i}>{block.text}</h2>;
|
336
|
-
|
337
|
-
case "heading_3":
|
338
|
-
return <h3 key={i}>{block.text}</h3>;
|
295
|
+
// Create blog page templates
|
296
|
+
if (fs.existsSync(pageRouter)) {
|
297
|
+
console.log("ā
Page router found");
|
298
|
+
const routePath = config.routeBasePath.replace(/^\//, ''); // Remove leading slash
|
299
|
+
const slugDir = path.join(pageRouter, routePath, "[slug].js")
|
300
|
+
const dirPath = path.dirname(slugDir);
|
339
301
|
|
340
|
-
|
341
|
-
return <p key={i}>{block.text}</p>;
|
302
|
+
const templates = getTemplates(config.theme, config.routeBasePath);
|
342
303
|
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
</ul>
|
348
|
-
);
|
304
|
+
// Create NotionRenderer component in the same directory as the blog page
|
305
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
306
|
+
fs.writeFileSync(path.join(dirPath, 'NotionRenderer.jsx'), notionRendererTemplate);
|
307
|
+
console.log(`ā
Created ${routePath}/NotionRenderer.jsx`);
|
349
308
|
|
350
|
-
|
351
|
-
|
352
|
-
<ol key={i} className="list-decimal ml-6">
|
353
|
-
<li>{block.text}</li>
|
354
|
-
</ol>
|
355
|
-
);
|
309
|
+
fs.writeFileSync(slugDir, templates.pageRouter);
|
310
|
+
console.log(`ā
Created pages/${routePath}/[slug].js`);
|
356
311
|
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
);
|
312
|
+
} else if (fs.existsSync(appRouter)) {
|
313
|
+
console.log("ā
App router found");
|
314
|
+
const routePath = config.routeBasePath.replace(/^\//, ''); // Remove leading slash
|
315
|
+
const slugDir = path.join(appRouter, routePath, "[slug]", "page.jsx")
|
316
|
+
const dirPath = path.dirname(slugDir);
|
363
317
|
|
364
|
-
|
365
|
-
return (
|
366
|
-
<pre key={i} className="bg-slate-900 text-slate-100 p-4 rounded-xl overflow-x-auto text-sm">
|
367
|
-
<code className={\`language-\${block.language}\`}>{block.code}</code>
|
368
|
-
</pre>
|
369
|
-
);
|
318
|
+
const templates = getTemplates(config.theme, config.routeBasePath);
|
370
319
|
|
371
|
-
|
372
|
-
|
320
|
+
// Create NotionRenderer component in the same directory as the blog page
|
321
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
322
|
+
fs.writeFileSync(path.join(dirPath, 'NotionRenderer.jsx'), notionRendererTemplate);
|
323
|
+
console.log(`ā
Created ${routePath}/[slug]/NotionRenderer.jsx`);
|
373
324
|
|
374
|
-
|
375
|
-
|
376
|
-
<figure key={i} className="max-w-[400px] mx-auto my-6 px-4">
|
377
|
-
<Image
|
378
|
-
src={block.imageUrl}
|
379
|
-
alt={block.alt || "Image"}
|
380
|
-
width={400}
|
381
|
-
height={300}
|
382
|
-
className="rounded-xl object-contain"
|
383
|
-
unoptimized={true}
|
384
|
-
/>
|
385
|
-
{block.caption && (
|
386
|
-
<figcaption className="text-sm text-center text-slate-500 mt-2 italic">
|
387
|
-
{block.caption}
|
388
|
-
</figcaption>
|
389
|
-
)}
|
390
|
-
</figure>
|
391
|
-
);
|
325
|
+
fs.writeFileSync(slugDir, templates.appRouter);
|
326
|
+
console.log(`ā
Created app/${routePath}/[slug]/page.jsx`);
|
392
327
|
|
393
|
-
default:
|
394
|
-
return (
|
395
|
-
<p key={i} className="text-sm text-red-500 italic">
|
396
|
-
ā ļø Unsupported block: {block.type}
|
397
|
-
</p>
|
398
|
-
);
|
399
|
-
}
|
400
|
-
})}
|
401
|
-
</div>
|
402
|
-
);
|
403
|
-
}`;
|
404
|
-
|
405
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
406
|
-
fs.writeFileSync(path.join(dirPath, 'NotionRenderer.jsx'), notionRendererContent);
|
407
|
-
console.log(`ā
Created ${routePath}/[slug]/NotionRenderer.jsx`);
|
408
|
-
|
409
|
-
fs.writeFileSync(slugDir, templates.appRouter);
|
410
|
-
console.log(`ā
Created app/${routePath}/[slug]/page.jsx`);
|
411
|
-
|
412
328
|
} else {
|
413
|
-
|
414
|
-
|
415
|
-
|
329
|
+
console.log("ā Neither pages/ nor app/ directory found");
|
330
|
+
console.log("š” Please make sure you're running this in a Next.js project");
|
331
|
+
process.exit(1);
|
416
332
|
}
|
417
333
|
|
418
334
|
console.log("\nš Blog page scaffolded successfully!");
|
package/package.json
CHANGED
package/src/lib/getPostBySlug.js
CHANGED
@@ -105,6 +105,23 @@ function convertBlockToStructuredJSON(block) {
|
|
105
105
|
case "divider":
|
106
106
|
return { ...base };
|
107
107
|
|
108
|
+
case "callout":
|
109
|
+
return { ...base };
|
110
|
+
|
111
|
+
case "toggle":
|
112
|
+
return { ...base };
|
113
|
+
|
114
|
+
case "table_of_contents":
|
115
|
+
return { ...base };
|
116
|
+
case "bookmark":
|
117
|
+
return { ...base };
|
118
|
+
|
119
|
+
case "equation":
|
120
|
+
return { ...base };
|
121
|
+
|
122
|
+
case "table":
|
123
|
+
return { ...base };
|
124
|
+
|
108
125
|
default:
|
109
126
|
return {
|
110
127
|
...base,
|