chalknotes 0.0.34 ā 1.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/README.md +144 -188
- package/bin/chalknotes.js +31 -0
- package/bin/cli.js +27 -288
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +196 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/scaffold.d.ts +6 -0
- package/dist/commands/scaffold.d.ts.map +1 -0
- package/dist/commands/scaffold.js +196 -0
- package/dist/commands/scaffold.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +163 -0
- package/dist/index.js.map +1 -0
- package/dist/notion/client.d.ts +14 -0
- package/dist/notion/client.d.ts.map +1 -0
- package/dist/notion/client.js +191 -0
- package/dist/notion/client.js.map +1 -0
- package/dist/plugins/parser.d.ts +10 -0
- package/dist/plugins/parser.d.ts.map +1 -0
- package/dist/plugins/parser.js +310 -0
- package/dist/plugins/parser.js.map +1 -0
- package/dist/templates/components.d.ts +4 -0
- package/dist/templates/components.d.ts.map +1 -0
- package/dist/templates/components.js +557 -0
- package/dist/templates/components.js.map +1 -0
- package/dist/templates/pages.d.ts +4 -0
- package/dist/templates/pages.d.ts.map +1 -0
- package/dist/templates/pages.js +321 -0
- package/dist/templates/pages.js.map +1 -0
- package/dist/types/index.d.ts +64 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/config.d.ts +12 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +99 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/detection.d.ts +19 -0
- package/dist/utils/detection.d.ts.map +1 -0
- package/dist/utils/detection.js +246 -0
- package/dist/utils/detection.js.map +1 -0
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +62 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +47 -10
- package/templates/example-config.js +34 -0
- package/templates/example-env +3 -0
- package/src/index.js +0 -10
- package/src/lib/getAllPosts.js +0 -35
- package/src/lib/getPostBySlug.js +0 -380
- package/src/lib/nextHelpers.js +0 -36
- package/src/lib/notion.js +0 -11
- package/src/utils.js +0 -6
package/bin/cli.js
CHANGED
|
@@ -1,292 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const fs = require("fs");
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const dotenv = require("dotenv");
|
|
5
|
-
const readline = require("readline");
|
|
6
|
-
dotenv.config();
|
|
7
2
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
output: process.stdout
|
|
3
|
+
const { program } = require('commander');
|
|
4
|
+
const { init } = require('../dist/commands/init');
|
|
5
|
+
const { scaffold } = require('../dist/commands/scaffold');
|
|
6
|
+
const { version } = require('../package.json');
|
|
7
|
+
|
|
8
|
+
program
|
|
9
|
+
.name('chalknotes')
|
|
10
|
+
.description('Transform your Notion pages into beautiful developer blogs')
|
|
11
|
+
.version(version);
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.command('init')
|
|
15
|
+
.description('Initialize ChalkNotes in your Next.js project')
|
|
16
|
+
.option('-f, --force', 'Force initialization even if config exists')
|
|
17
|
+
.action(init);
|
|
18
|
+
|
|
19
|
+
program
|
|
20
|
+
.command('scaffold')
|
|
21
|
+
.description('Scaffold blog pages and components')
|
|
22
|
+
.option('-t, --theme <theme>', 'Theme to use (modern, minimal, dev)', 'modern')
|
|
23
|
+
.action(scaffold);
|
|
24
|
+
|
|
25
|
+
// Default command - run init if no command specified
|
|
26
|
+
program
|
|
27
|
+
.action(() => {
|
|
28
|
+
init();
|
|
35
29
|
});
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
|
|
39
|
-
console.log("š Creating blog.config.js with default configuration...");
|
|
40
|
-
|
|
41
|
-
const configTemplate = `module.exports = {
|
|
42
|
-
notionToken: process.env.NOTION_TOKEN,
|
|
43
|
-
notionDatabaseId: process.env.NOTION_DATABASE_ID,
|
|
44
|
-
routeBasePath: '/blog',
|
|
45
|
-
theme: 'default',
|
|
46
|
-
plugins: [],
|
|
47
|
-
};`.trim();
|
|
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;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Load configuration
|
|
61
|
-
let config;
|
|
62
|
-
try {
|
|
63
|
-
config = require(configPath);
|
|
64
|
-
} catch (error) {
|
|
65
|
-
console.error("ā Error loading blog.config.js:", error.message);
|
|
66
|
-
process.exit(1);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Set defaults for missing config values
|
|
70
|
-
config.routeBasePath = config.routeBasePath || '/blog';
|
|
71
|
-
config.theme = config.theme || 'default';
|
|
72
|
-
|
|
73
|
-
console.log("ā
Configuration loaded successfully");
|
|
74
|
-
console.log(`š Route base path: ${config.routeBasePath}`);
|
|
75
|
-
console.log(`šØ Theme: ${config.theme}`);
|
|
76
|
-
|
|
77
|
-
// Ask to proceed with scaffolding
|
|
78
|
-
console.log("\nšØ Ready to scaffold your blog page?");
|
|
79
|
-
console.log("This will create a clean, responsive blog template using Tailwind CSS.");
|
|
80
|
-
console.log("Press Enter to continue or Ctrl+C to cancel...");
|
|
81
|
-
|
|
82
|
-
// Create blog page templates based on theme and route
|
|
83
|
-
const pageRouter = path.join(process.cwd(), '/pages')
|
|
84
|
-
const appRouter = path.join(process.cwd(), '/app')
|
|
85
|
-
|
|
86
|
-
// Generate templates based on theme
|
|
87
|
-
function getTemplates(theme, routeBasePath) {
|
|
88
|
-
const routePath = routeBasePath.replace(/^\//, ''); // Remove leading slash
|
|
89
|
-
|
|
90
|
-
// Both themes now use responsive dark mode
|
|
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-50 dark: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-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">
|
|
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);
|
|
119
|
-
|
|
120
|
-
return (
|
|
121
|
-
<div className="min-h-screen bg-gray-50 dark: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-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">
|
|
125
|
-
{post.title}
|
|
126
|
-
</h1>
|
|
127
|
-
<NotionRenderer blocks={post.blocks} />
|
|
128
|
-
</article>
|
|
129
|
-
</main>
|
|
130
|
-
</div>
|
|
131
|
-
);
|
|
132
|
-
}`.trim()
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// NotionRenderer component template
|
|
137
|
-
const notionRendererTemplate = `import React from "react";
|
|
138
|
-
import Image from "next/image";
|
|
139
|
-
|
|
140
|
-
export default function NotionRenderer({ blocks }) {
|
|
141
|
-
if (!blocks || blocks.length === 0) return null;
|
|
142
|
-
|
|
143
|
-
return (
|
|
144
|
-
<div className="max-w-none">
|
|
145
|
-
{blocks.map((block, i) => {
|
|
146
|
-
switch (block.type) {
|
|
147
|
-
case "heading_1":
|
|
148
|
-
return (
|
|
149
|
-
<h1 key={i} className="text-3xl font-bold text-gray-900 dark:text-gray-100 mb-6 mt-8 first:mt-0 border-b border-gray-200 dark:border-gray-700 pb-2">
|
|
150
|
-
{block.text}
|
|
151
|
-
</h1>
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
case "heading_2":
|
|
155
|
-
return (
|
|
156
|
-
<h2 key={i} className="text-2xl font-semibold text-gray-900 dark:text-gray-100 mb-4 mt-6 first:mt-0">
|
|
157
|
-
{block.text}
|
|
158
|
-
</h2>
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
case "heading_3":
|
|
162
|
-
return (
|
|
163
|
-
<h3 key={i} className="text-xl font-medium text-gray-900 dark:text-gray-100 mb-3 mt-5 first:mt-0">
|
|
164
|
-
{block.text}
|
|
165
|
-
</h3>
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
case "paragraph":
|
|
169
|
-
return (
|
|
170
|
-
<p key={i} className="text-gray-700 dark:text-gray-300 leading-relaxed mb-4 last:mb-0">
|
|
171
|
-
{block.text}
|
|
172
|
-
</p>
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
case "bulleted_list_item":
|
|
176
|
-
return (
|
|
177
|
-
<div key={i} className="flex items-start mb-2">
|
|
178
|
-
<div className="w-2 h-2 bg-gray-400 dark:bg-gray-500 rounded-full mt-2 mr-3 flex-shrink-0"></div>
|
|
179
|
-
<p className="text-gray-700 dark:text-gray-300 leading-relaxed">{block.text}</p>
|
|
180
|
-
</div>
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
case "numbered_list_item":
|
|
184
|
-
return (
|
|
185
|
-
<div key={i} className="flex items-start mb-2">
|
|
186
|
-
<span className="text-gray-500 dark:text-gray-400 font-medium mr-3 mt-0.5 flex-shrink-0">{(i + 1)}.</span>
|
|
187
|
-
<p className="text-gray-700 dark:text-gray-300 leading-relaxed">{block.text}</p>
|
|
188
|
-
</div>
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
case "quote":
|
|
192
|
-
return (
|
|
193
|
-
<blockquote key={i} className="border-l-4 border-blue-500 dark:border-blue-400 pl-6 py-4 my-6 bg-blue-50 dark:bg-blue-900/20 rounded-r-lg shadow-sm">
|
|
194
|
-
<p className="text-gray-700 dark:text-gray-300 italic text-lg leading-relaxed">
|
|
195
|
-
{block.text}
|
|
196
|
-
</p>
|
|
197
|
-
</blockquote>
|
|
198
|
-
);
|
|
199
|
-
|
|
200
|
-
case "code":
|
|
201
|
-
return (
|
|
202
|
-
<div key={i} className="my-6">
|
|
203
|
-
<pre className="bg-gray-900 dark:bg-gray-800 text-gray-100 p-4 rounded-lg shadow-md overflow-x-auto text-sm border border-gray-700 dark:border-gray-600">
|
|
204
|
-
<code className={\`language-\${block.language}\`}>{block.code}</code>
|
|
205
|
-
</pre>
|
|
206
|
-
</div>
|
|
207
|
-
);
|
|
208
|
-
|
|
209
|
-
case "divider":
|
|
210
|
-
return (
|
|
211
|
-
<hr key={i} className="my-8 border-gray-200 dark:border-gray-700 shadow-sm" />
|
|
212
|
-
);
|
|
213
|
-
|
|
214
|
-
case "image":
|
|
215
|
-
return (
|
|
216
|
-
<figure key={i} className="my-8">
|
|
217
|
-
<div className="bg-gray-50 dark:bg-gray-800 rounded-lg p-4 shadow-sm border border-gray-200 dark:border-gray-700">
|
|
218
|
-
<Image
|
|
219
|
-
src={block.imageUrl}
|
|
220
|
-
alt={block.alt || "Image"}
|
|
221
|
-
width={400}
|
|
222
|
-
height={300}
|
|
223
|
-
className="rounded-lg object-contain w-full h-auto shadow-sm"
|
|
224
|
-
unoptimized={true}
|
|
225
|
-
/>
|
|
226
|
-
{block.caption && (
|
|
227
|
-
<figcaption className="text-sm text-center text-gray-500 dark:text-gray-400 mt-3 italic">
|
|
228
|
-
{block.caption}
|
|
229
|
-
</figcaption>
|
|
230
|
-
)}
|
|
231
|
-
</div>
|
|
232
|
-
</figure>
|
|
233
|
-
);
|
|
234
|
-
|
|
235
|
-
default:
|
|
236
|
-
return (
|
|
237
|
-
<div key={i} className="my-4 p-3 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg">
|
|
238
|
-
<p className="text-sm text-yellow-700 dark:text-yellow-300 italic">
|
|
239
|
-
ā ļø Unsupported block type: {block.type}
|
|
240
|
-
</p>
|
|
241
|
-
</div>
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
})}
|
|
245
|
-
</div>
|
|
246
|
-
);
|
|
247
|
-
}`;
|
|
248
|
-
|
|
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);
|
|
255
|
-
|
|
256
|
-
const templates = getTemplates(config.theme, config.routeBasePath);
|
|
257
|
-
|
|
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`);
|
|
262
|
-
|
|
263
|
-
fs.writeFileSync(slugDir, templates.pageRouter);
|
|
264
|
-
console.log(`ā
Created pages/${routePath}/[slug].js`);
|
|
265
|
-
|
|
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);
|
|
271
|
-
|
|
272
|
-
const templates = getTemplates(config.theme, config.routeBasePath);
|
|
273
|
-
|
|
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`);
|
|
278
|
-
|
|
279
|
-
fs.writeFileSync(slugDir, templates.appRouter);
|
|
280
|
-
console.log(`ā
Created app/${routePath}/[slug]/page.jsx`);
|
|
281
|
-
|
|
282
|
-
} else {
|
|
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);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
console.log("\nš Blog page scaffolded successfully!");
|
|
289
|
-
console.log(`\nš Next steps:`);
|
|
290
|
-
console.log("1. Add Tailwind CSS to your project if not already installed");
|
|
291
|
-
console.log("2. Start your development server");
|
|
292
|
-
console.log(`3. Visit ${config.routeBasePath}/[your-post-slug] to see your blog`);
|
|
31
|
+
program.parse();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AASA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8DnE"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.init = init;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const detection_1 = require("../utils/detection");
|
|
40
|
+
const config_1 = require("../utils/config");
|
|
41
|
+
const logger_1 = require("../utils/logger");
|
|
42
|
+
const inquirer = require('inquirer');
|
|
43
|
+
async function init(options = {}) {
|
|
44
|
+
logger_1.Logger.title('ChalkNotes Setup');
|
|
45
|
+
try {
|
|
46
|
+
// Step 1: Project Detection
|
|
47
|
+
logger_1.Logger.step(1, 4, 'Detecting project configuration...');
|
|
48
|
+
const detector = new detection_1.ProjectDetector();
|
|
49
|
+
const detection = await detector.detect();
|
|
50
|
+
if (!detection.isNextJs) {
|
|
51
|
+
logger_1.Logger.error('ChalkNotes requires a Next.js project. Please run this command in a Next.js project directory.');
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
logger_1.Logger.success(`Next.js project detected (${detection.isAppRouter ? 'App Router' : 'Pages Router'})`);
|
|
55
|
+
logger_1.Logger.info(`CSS Framework: ${getCSSFramework(detection)}`);
|
|
56
|
+
logger_1.Logger.info(`TypeScript: ${detection.hasTypeScript ? 'Yes' : 'No'}`);
|
|
57
|
+
logger_1.Logger.info(`Package Manager: ${detection.packageManager}`);
|
|
58
|
+
// Step 2: Check existing configuration
|
|
59
|
+
logger_1.Logger.step(2, 4, 'Checking existing configuration...');
|
|
60
|
+
const configManager = new config_1.ConfigManager();
|
|
61
|
+
if (configManager.exists() && !options.force) {
|
|
62
|
+
const { overwrite } = await inquirer.prompt([
|
|
63
|
+
{
|
|
64
|
+
type: 'confirm',
|
|
65
|
+
name: 'overwrite',
|
|
66
|
+
message: 'Configuration file already exists. Do you want to overwrite it?',
|
|
67
|
+
default: false
|
|
68
|
+
}
|
|
69
|
+
]);
|
|
70
|
+
if (!overwrite) {
|
|
71
|
+
logger_1.Logger.info('Configuration kept unchanged. Run with --force to overwrite.');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Step 3: Environment setup
|
|
76
|
+
logger_1.Logger.step(3, 4, 'Setting up environment variables...');
|
|
77
|
+
await setupEnvironment();
|
|
78
|
+
// Step 4: Create configuration
|
|
79
|
+
logger_1.Logger.step(4, 4, 'Creating configuration...');
|
|
80
|
+
const config = await createConfiguration(detection);
|
|
81
|
+
await configManager.save(config);
|
|
82
|
+
logger_1.Logger.success('ChalkNotes initialized successfully!');
|
|
83
|
+
logger_1.Logger.section('Next steps:');
|
|
84
|
+
logger_1.Logger.info('1. Add your Notion credentials to .env file');
|
|
85
|
+
logger_1.Logger.info('2. Configure plugins in blog.config.js (optional)');
|
|
86
|
+
logger_1.Logger.info('3. Run "chalknotes scaffold" to generate your blog pages');
|
|
87
|
+
logger_1.Logger.info('4. Start your development server to see your blog');
|
|
88
|
+
logger_1.Logger.section('Built-in plugins available:');
|
|
89
|
+
logger_1.Logger.info('Use {{CommentSection}}, {{TableOfContents}}, {{Share}}, {{ReadingTime}} in your Notion content');
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
logger_1.Logger.error(`Initialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function getCSSFramework(detection) {
|
|
97
|
+
if (detection.hasTailwind)
|
|
98
|
+
return 'Tailwind CSS';
|
|
99
|
+
if (detection.hasStyledComponents)
|
|
100
|
+
return 'Styled Components';
|
|
101
|
+
if (detection.hasCSSModules)
|
|
102
|
+
return 'CSS Modules';
|
|
103
|
+
return 'None detected';
|
|
104
|
+
}
|
|
105
|
+
async function setupEnvironment() {
|
|
106
|
+
const envPath = path.join(process.cwd(), '.env');
|
|
107
|
+
const envExamplePath = path.join(process.cwd(), '.env.example');
|
|
108
|
+
// Check if .env exists
|
|
109
|
+
if (!fs.existsSync(envPath)) {
|
|
110
|
+
const envContent = `# ChalkNotes Configuration
|
|
111
|
+
NOTION_TOKEN=
|
|
112
|
+
NOTION_DATABASE_ID=
|
|
113
|
+
`;
|
|
114
|
+
await fs.promises.writeFile(envPath, envContent);
|
|
115
|
+
logger_1.Logger.success('Created .env file with ChalkNotes variables');
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// Check if ChalkNotes variables exist
|
|
119
|
+
const envContent = await fs.promises.readFile(envPath, 'utf-8');
|
|
120
|
+
let needsUpdate = false;
|
|
121
|
+
let updatedContent = envContent;
|
|
122
|
+
if (!envContent.includes('NOTION_TOKEN=')) {
|
|
123
|
+
updatedContent += '\n# ChalkNotes Configuration\nNOTION_TOKEN=\n';
|
|
124
|
+
needsUpdate = true;
|
|
125
|
+
}
|
|
126
|
+
if (!envContent.includes('NOTION_DATABASE_ID=')) {
|
|
127
|
+
updatedContent += 'NOTION_DATABASE_ID=\n';
|
|
128
|
+
needsUpdate = true;
|
|
129
|
+
}
|
|
130
|
+
if (needsUpdate) {
|
|
131
|
+
await fs.promises.writeFile(envPath, updatedContent);
|
|
132
|
+
logger_1.Logger.success('Added ChalkNotes variables to existing .env file');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Create .env.example if it doesn't exist
|
|
136
|
+
if (!fs.existsSync(envExamplePath)) {
|
|
137
|
+
const exampleContent = `# ChalkNotes Configuration
|
|
138
|
+
NOTION_TOKEN=secret_...
|
|
139
|
+
NOTION_DATABASE_ID=...
|
|
140
|
+
`;
|
|
141
|
+
await fs.promises.writeFile(envExamplePath, exampleContent);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function createConfiguration(detection) {
|
|
145
|
+
const questions = [
|
|
146
|
+
{
|
|
147
|
+
type: 'input',
|
|
148
|
+
name: 'routeBasePath',
|
|
149
|
+
message: 'What should be the base path for your blog?',
|
|
150
|
+
default: '/blog',
|
|
151
|
+
validate: (input) => {
|
|
152
|
+
if (!input.startsWith('/')) {
|
|
153
|
+
return 'Base path must start with /';
|
|
154
|
+
}
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
type: 'list',
|
|
160
|
+
name: 'theme',
|
|
161
|
+
message: 'Choose a theme:',
|
|
162
|
+
choices: [
|
|
163
|
+
{ name: 'Modern - Clean and contemporary design', value: 'modern' },
|
|
164
|
+
{ name: 'Minimal - Simple and focused layout', value: 'minimal' },
|
|
165
|
+
{ name: 'Dev - Developer-focused with code highlighting', value: 'dev' }
|
|
166
|
+
],
|
|
167
|
+
default: 'modern'
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: 'confirm',
|
|
171
|
+
name: 'enableCaching',
|
|
172
|
+
message: 'Enable intelligent caching for better performance?',
|
|
173
|
+
default: true
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
type: 'confirm',
|
|
177
|
+
name: 'enableErrorBoundaries',
|
|
178
|
+
message: 'Enable error boundaries for better reliability?',
|
|
179
|
+
default: true
|
|
180
|
+
}
|
|
181
|
+
];
|
|
182
|
+
const answers = await inquirer.prompt(questions);
|
|
183
|
+
return {
|
|
184
|
+
notionToken: process.env.NOTION_TOKEN || '',
|
|
185
|
+
notionDatabaseId: process.env.NOTION_DATABASE_ID || '',
|
|
186
|
+
routeBasePath: answers.routeBasePath,
|
|
187
|
+
theme: answers.theme,
|
|
188
|
+
plugins: [], // Empty by default, user can add in config file
|
|
189
|
+
caching: {
|
|
190
|
+
enabled: answers.enableCaching,
|
|
191
|
+
ttl: 3600
|
|
192
|
+
},
|
|
193
|
+
errorBoundaries: answers.enableErrorBoundaries
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/commands/scaffold.ts"],"names":[],"mappings":"AASA,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqF3E"}
|