chalknotes 0.0.32 → 0.0.34

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 CHANGED
@@ -9,15 +9,15 @@ console.log("šŸš€ Initializing ChalkNotes...");
9
9
 
10
10
  // Check environment variables
11
11
  if (!process.env.NOTION_TOKEN) {
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);
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
- 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);
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
- console.log("\nāŒ blog.config.js not found");
30
- console.log("This file is required to configure your blog settings.");
29
+ console.log("\nāŒ blog.config.js not found");
30
+ console.log("This file is required to configure your blog settings.");
31
31
 
32
- const rl = readline.createInterface({
33
- input: process.stdin,
34
- output: process.stdout
35
- });
32
+ const rl = readline.createInterface({
33
+ input: process.stdin,
34
+ output: process.stdout
35
+ });
36
36
 
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...");
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
- const configTemplate = `module.exports = {
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
- 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;
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
- config = require(configPath);
63
+ config = require(configPath);
64
64
  } catch (error) {
65
- console.error("āŒ Error loading blog.config.js:", error.message);
66
- process.exit(1);
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,56 +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
- const routePath = routeBasePath.replace(/^\//, ''); // Remove leading slash
89
-
90
- if (theme === 'dark') {
91
- return {
92
- pageRouter: `
93
- import { getStaticPropsForPost, getStaticPathsForPosts } from 'chalknotes';
94
- import NotionRenderer from './NotionRenderer';
95
-
96
- export const getStaticProps = getStaticPropsForPost;
97
- export const getStaticPaths = getStaticPathsForPosts;
98
-
99
- export default function BlogPost({ post }) {
100
- return (
101
- <div className="min-h-screen bg-gray-900">
102
- <main className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
103
- <article className="bg-gray-800 rounded-lg shadow-lg border border-gray-700 p-8">
104
- <h1 className="text-4xl font-bold text-white mb-6 leading-tight">
105
- {post.title}
106
- </h1>
107
- <NotionRenderer blocks={post.blocks} />
108
- </article>
109
- </main>
110
- </div>
111
- );
112
- }`.trim(),
113
- appRouter: `
114
- import { getPostBySlug } from 'chalknotes';
115
- import NotionRenderer from './NotionRenderer';
116
-
117
- export default async function BlogPost({ params }) {
118
- const post = await getPostBySlug(params.slug);
88
+ const routePath = routeBasePath.replace(/^\//, ''); // Remove leading slash
119
89
 
120
- return (
121
- <div className="min-h-screen bg-gray-900">
122
- <main className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
123
- <article className="bg-gray-800 rounded-lg shadow-lg border border-gray-700 p-8">
124
- <h1 className="text-4xl font-bold text-white mb-6 leading-tight">
125
- {post.title}
126
- </h1>
127
- <NotionRenderer blocks={post.blocks} />
128
- </article>
129
- </main>
130
- </div>
131
- );
132
- }`.trim()
133
- };
134
- } else {
135
- // Default theme (light mode)
136
- return {
137
- pageRouter: `
90
+ // Both themes now use responsive dark mode
91
+ return {
92
+ pageRouter: `
138
93
  import { getStaticPropsForPost, getStaticPathsForPosts } from 'chalknotes';
139
94
  import NotionRenderer from './NotionRenderer';
140
95
 
@@ -143,10 +98,10 @@ export const getStaticPaths = getStaticPathsForPosts;
143
98
 
144
99
  export default function BlogPost({ post }) {
145
100
  return (
146
- <div className="min-h-screen bg-gray-50">
101
+ <div className="min-h-screen bg-gray-50 dark:bg-gray-900">
147
102
  <main className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
148
- <article className="bg-white rounded-lg shadow-sm border border-gray-200 p-8">
149
- <h1 className="text-4xl font-bold text-gray-900 mb-6 leading-tight">
103
+ <article className="bg-white dark:bg-gray-800 rounded-lg shadow-sm dark:shadow-lg border border-gray-200 dark:border-gray-700 p-8">
104
+ <h1 className="text-4xl font-bold text-gray-900 dark:text-white mb-6 leading-tight">
150
105
  {post.title}
151
106
  </h1>
152
107
  <NotionRenderer blocks={post.blocks} />
@@ -155,7 +110,7 @@ export default function BlogPost({ post }) {
155
110
  </div>
156
111
  );
157
112
  }`.trim(),
158
- appRouter: `
113
+ appRouter: `
159
114
  import { getPostBySlug } from 'chalknotes';
160
115
  import NotionRenderer from './NotionRenderer';
161
116
 
@@ -163,10 +118,10 @@ export default async function BlogPost({ params }) {
163
118
  const post = await getPostBySlug(params.slug);
164
119
 
165
120
  return (
166
- <div className="min-h-screen bg-gray-50">
121
+ <div className="min-h-screen bg-gray-50 dark:bg-gray-900">
167
122
  <main className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
168
- <article className="bg-white rounded-lg shadow-sm border border-gray-200 p-8">
169
- <h1 className="text-4xl font-bold text-gray-900 mb-6 leading-tight">
123
+ <article className="bg-white dark:bg-gray-800 rounded-lg shadow-sm dark:shadow-lg border border-gray-200 dark:border-gray-700 p-8">
124
+ <h1 className="text-4xl font-bold text-gray-900 dark:text-white mb-6 leading-tight">
170
125
  {post.title}
171
126
  </h1>
172
127
  <NotionRenderer blocks={post.blocks} />
@@ -175,28 +130,18 @@ export default async function BlogPost({ params }) {
175
130
  </div>
176
131
  );
177
132
  }`.trim()
178
- };
179
- }
133
+ };
180
134
  }
181
135
 
182
- // Create blog page templates
183
- if (fs.existsSync(pageRouter)) {
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";
136
+ // NotionRenderer component template
137
+ const notionRendererTemplate = `import React from "react";
193
138
  import Image from "next/image";
194
139
 
195
140
  export default function NotionRenderer({ blocks }) {
196
141
  if (!blocks || blocks.length === 0) return null;
197
142
 
198
143
  return (
199
- <div className="prose prose-lg max-w-none prose-headings:font-semibold prose-headings:text-gray-900 dark:prose-headings:text-gray-100 prose-p:text-gray-700 dark:prose-p:text-gray-300 prose-li:text-gray-700 dark:prose-li:text-gray-300">
144
+ <div className="max-w-none">
200
145
  {blocks.map((block, i) => {
201
146
  switch (block.type) {
202
147
  case "heading_1":
@@ -300,119 +245,44 @@ export default function NotionRenderer({ blocks }) {
300
245
  </div>
301
246
  );
302
247
  }`;
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
248
 
324
- export default function NotionRenderer({ blocks }) {
325
- if (!blocks || blocks.length === 0) return null;
326
-
327
- return (
328
- <div className="prose prose-lg max-w-none text-slate-700 leading-relaxed dark:prose-invert dark:text-slate-300">
329
- {blocks.map((block, i) => {
330
- switch (block.type) {
331
- case "heading_1":
332
- return <h1 key={i}>{block.text}</h1>;
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>;
249
+ // Create blog page templates
250
+ if (fs.existsSync(pageRouter)) {
251
+ console.log("āœ… Page router found");
252
+ const routePath = config.routeBasePath.replace(/^\//, ''); // Remove leading slash
253
+ const slugDir = path.join(pageRouter, routePath, "[slug].js")
254
+ const dirPath = path.dirname(slugDir);
339
255
 
340
- case "paragraph":
341
- return <p key={i}>{block.text}</p>;
256
+ const templates = getTemplates(config.theme, config.routeBasePath);
342
257
 
343
- case "bulleted_list_item":
344
- return (
345
- <ul key={i} className="list-disc ml-6">
346
- <li>{block.text}</li>
347
- </ul>
348
- );
258
+ // Create NotionRenderer component in the same directory as the blog page
259
+ fs.mkdirSync(dirPath, { recursive: true });
260
+ fs.writeFileSync(path.join(dirPath, 'NotionRenderer.jsx'), notionRendererTemplate);
261
+ console.log(`āœ… Created ${routePath}/NotionRenderer.jsx`);
349
262
 
350
- case "numbered_list_item":
351
- return (
352
- <ol key={i} className="list-decimal ml-6">
353
- <li>{block.text}</li>
354
- </ol>
355
- );
263
+ fs.writeFileSync(slugDir, templates.pageRouter);
264
+ console.log(`āœ… Created pages/${routePath}/[slug].js`);
356
265
 
357
- case "quote":
358
- return (
359
- <blockquote key={i} className="border-l-4 pl-4 italic text-slate-600 bg-slate-50 p-4 rounded-r">
360
- {block.text}
361
- </blockquote>
362
- );
266
+ } else if (fs.existsSync(appRouter)) {
267
+ console.log("āœ… App router found");
268
+ const routePath = config.routeBasePath.replace(/^\//, ''); // Remove leading slash
269
+ const slugDir = path.join(appRouter, routePath, "[slug]", "page.jsx")
270
+ const dirPath = path.dirname(slugDir);
363
271
 
364
- case "code":
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
- );
272
+ const templates = getTemplates(config.theme, config.routeBasePath);
370
273
 
371
- case "divider":
372
- return <hr key={i} className="my-8 border-slate-300" />;
274
+ // Create NotionRenderer component in the same directory as the blog page
275
+ fs.mkdirSync(dirPath, { recursive: true });
276
+ fs.writeFileSync(path.join(dirPath, 'NotionRenderer.jsx'), notionRendererTemplate);
277
+ console.log(`āœ… Created ${routePath}/[slug]/NotionRenderer.jsx`);
373
278
 
374
- case "image":
375
- return (
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
- );
279
+ fs.writeFileSync(slugDir, templates.appRouter);
280
+ console.log(`āœ… Created app/${routePath}/[slug]/page.jsx`);
392
281
 
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
282
  } else {
413
- console.log("āŒ Neither pages/ nor app/ directory found");
414
- console.log("šŸ’” Please make sure you're running this in a Next.js project");
415
- process.exit(1);
283
+ console.log("āŒ Neither pages/ nor app/ directory found");
284
+ console.log("šŸ’” Please make sure you're running this in a Next.js project");
285
+ process.exit(1);
416
286
  }
417
287
 
418
288
  console.log("\nšŸŽ‰ Blog page scaffolded successfully!");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chalknotes",
3
- "version": "0.0.32",
3
+ "version": "0.0.34",
4
4
  "description": "A tool that simplifies blogs.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -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,