@knowcode/doc-builder 1.9.6 → 1.9.7

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.
@@ -1,4 +1,5 @@
1
1
  module.exports = {
2
+ "configVersion": "1.9.6",
2
3
  "siteName": "@knowcode/doc-builder",
3
4
  "siteDescription": "Beautiful documentation with the least effort possible",
4
5
  "docsDir": "docs",
package/lib/config.js CHANGED
@@ -1,12 +1,16 @@
1
1
  const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
  const chalk = require('chalk');
4
+ const semver = require('semver');
4
5
  const sharedAuth = require('./shared-auth-config');
5
6
 
6
7
  /**
7
8
  * Default configuration
8
9
  */
9
10
  const defaultConfig = {
11
+ // Configuration version - updated when new config options are added
12
+ configVersion: require('../package.json').version,
13
+
10
14
  // Source and output directories
11
15
  docsDir: 'docs',
12
16
  outputDir: 'html',
@@ -214,6 +218,112 @@ const notionInspiredPreset = {
214
218
  }
215
219
  };
216
220
 
221
+ /**
222
+ * Check if config migration is needed
223
+ * @param {object} userConfig - Current user configuration
224
+ * @param {string} packageVersion - Current package version
225
+ * @returns {boolean} - Whether migration is needed
226
+ */
227
+ function needsMigration(userConfig, packageVersion) {
228
+ // If no configVersion in user config, it needs migration
229
+ if (!userConfig.configVersion) {
230
+ return true;
231
+ }
232
+
233
+ try {
234
+ // Use semver to compare versions
235
+ return semver.lt(userConfig.configVersion, packageVersion);
236
+ } catch (error) {
237
+ console.warn(chalk.yellow(`Warning: Invalid version format in config: ${userConfig.configVersion}`));
238
+ return true; // Migrate on version parse errors
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Deep merge objects, preserving user customizations
244
+ * @param {object} target - Target object (defaults)
245
+ * @param {object} source - Source object (user config)
246
+ * @returns {object} - Merged object
247
+ */
248
+ function deepMerge(target, source) {
249
+ const result = { ...target };
250
+
251
+ for (const key in source) {
252
+ if (source.hasOwnProperty(key)) {
253
+ if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
254
+ // Recursively merge objects
255
+ result[key] = deepMerge(target[key] || {}, source[key]);
256
+ } else {
257
+ // Use source value (user customization takes precedence)
258
+ result[key] = source[key];
259
+ }
260
+ }
261
+ }
262
+
263
+ return result;
264
+ }
265
+
266
+ /**
267
+ * Migrate user configuration to current version
268
+ * @param {object} userConfig - Current user configuration
269
+ * @param {string} targetVersion - Target package version
270
+ * @returns {object} - Migrated configuration
271
+ */
272
+ function migrateConfig(userConfig, targetVersion) {
273
+ console.log(chalk.blue(`🔄 Migrating config from ${userConfig.configVersion || 'unknown'} to ${targetVersion}`));
274
+
275
+ // Start with current defaults
276
+ let migratedConfig = { ...defaultConfig };
277
+
278
+ // Deep merge user customizations
279
+ migratedConfig = deepMerge(migratedConfig, userConfig);
280
+
281
+ // Update the config version
282
+ migratedConfig.configVersion = targetVersion;
283
+
284
+ // Log new features added
285
+ const newFeatures = [];
286
+ if (!userConfig.features?.dynamicNavIcons) {
287
+ newFeatures.push('Dynamic navigation icons');
288
+ }
289
+ if (!userConfig.features?.subtleColors) {
290
+ newFeatures.push('Subtle status colors');
291
+ }
292
+ if (!userConfig.features?.phosphorWeight) {
293
+ newFeatures.push('Phosphor icon weight options');
294
+ }
295
+ if (!userConfig.features?.phosphorSize) {
296
+ newFeatures.push('Phosphor icon sizing');
297
+ }
298
+
299
+ if (newFeatures.length > 0) {
300
+ console.log(chalk.green(`✨ Added new features: ${newFeatures.join(', ')}`));
301
+ }
302
+
303
+ return migratedConfig;
304
+ }
305
+
306
+ /**
307
+ * Save configuration to file
308
+ * @param {string} configPath - Path to config file
309
+ * @param {object} config - Configuration object to save
310
+ */
311
+ async function saveConfig(configPath, config) {
312
+ // Create backup of existing config
313
+ if (fs.existsSync(configPath)) {
314
+ const backupPath = `${configPath}.backup.${Date.now()}`;
315
+ await fs.copy(configPath, backupPath);
316
+ console.log(chalk.gray(`💾 Backed up existing config to ${path.basename(backupPath)}`));
317
+ }
318
+
319
+ // Format config as module.exports
320
+ const configContent = `module.exports = ${JSON.stringify(config, null, 2)};
321
+ `;
322
+
323
+ await fs.writeFile(configPath, configContent);
324
+ console.log(chalk.green(`✅ Updated config file: ${path.basename(configPath)}`));
325
+ }
326
+
217
327
  /**
218
328
  * Load configuration
219
329
  */
@@ -230,7 +340,15 @@ async function loadConfig(configPath, options = {}) {
230
340
  if (fs.existsSync(customConfigPath)) {
231
341
  try {
232
342
  const customConfig = require(customConfigPath);
233
- config = { ...config, ...customConfig };
343
+ const packageJson = require('../package.json');
344
+
345
+ // Check if migration is needed
346
+ if (needsMigration(customConfig, packageJson.version)) {
347
+ config = migrateConfig(customConfig, packageJson.version);
348
+ await saveConfig(customConfigPath, config);
349
+ } else {
350
+ config = { ...config, ...customConfig };
351
+ }
234
352
 
235
353
  // Handle alternative config formats
236
354
  if (customConfig.site) {
@@ -358,5 +476,8 @@ module.exports = {
358
476
  defaultConfig,
359
477
  notionInspiredPreset,
360
478
  loadConfig,
361
- createDefaultConfig
479
+ createDefaultConfig,
480
+ needsMigration,
481
+ migrateConfig,
482
+ saveConfig
362
483
  };
@@ -81,6 +81,7 @@ const emojiToPhosphor = {
81
81
  '🧭': '<i class="ph ph-compass" aria-label="navigation"></i>',
82
82
  'đŸ—ēī¸': '<i class="ph ph-map-trifold" aria-label="map"></i>',
83
83
  '🌐': '<i class="ph ph-globe" aria-label="global"></i>',
84
+ '🌍': '<i class="ph ph-globe-hemisphere-west" aria-label="world"></i>',
84
85
 
85
86
  // Communication
86
87
  '📧': '<i class="ph ph-envelope" aria-label="email"></i>',
@@ -250,6 +251,20 @@ const emojiToPhosphor = {
250
251
  '📑': '<i class="ph ph-file-text" aria-label="document"></i>',
251
252
  '💀': '<i class="ph ph-skull" aria-label="skull"></i>',
252
253
  '🔤': '<i class="ph ph-textbox" aria-label="letters"></i>',
254
+ '🧱': '<i class="ph ph-wall" aria-label="brick"></i>',
255
+ 'đŸ–ŧī¸': '<i class="ph ph-image" aria-label="picture"></i>',
256
+ '🎂': '<i class="ph ph-cake" aria-label="birthday"></i>',
257
+ 'â†Šī¸': '<i class="ph ph-arrow-u-left" aria-label="return"></i>',
258
+ '📜': '<i class="ph ph-scroll" aria-label="scroll"></i>',
259
+ 'đŸ•°ī¸': '<i class="ph ph-clock" aria-label="clock"></i>',
260
+ '🧮': '<i class="ph ph-calculator" aria-label="calculator"></i>',
261
+ 'đŸŽĢ': '<i class="ph ph-ticket" aria-label="ticket"></i>',
262
+ 'đŸŒŋ': '<i class="ph ph-leaf" aria-label="leaf"></i>',
263
+ 'đŸĨŠ': '<i class="ph ph-boxing-glove" aria-label="boxing"></i>',
264
+ 'đŸŽ›ī¸': '<i class="ph ph-faders" aria-label="controls"></i>',
265
+ 'đŸ—Ŗī¸': '<i class="ph ph-megaphone-simple" aria-label="speaking"></i>',
266
+ '💝': '<i class="ph ph-gift" aria-label="gift with bow"></i>',
267
+ '🐌': '<i class="ph ph-spiral" aria-label="snail"></i>',
253
268
  };
254
269
 
255
270
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowcode/doc-builder",
3
- "version": "1.9.6",
3
+ "version": "1.9.7",
4
4
  "description": "Reusable documentation builder for markdown-based sites with Vercel deployment support",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -37,7 +37,8 @@
37
37
  "gray-matter": "^4.0.3",
38
38
  "marked": "^15.0.12",
39
39
  "ora": "5.4.1",
40
- "prompts": "^2.4.2"
40
+ "prompts": "^2.4.2",
41
+ "semver": "^7.7.2"
41
42
  },
42
43
  "engines": {
43
44
  "node": ">=14.0.0"