@docubook/cli 0.2.4 → 0.2.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docubook/cli",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "DocuBook CLI tool that helps you initialize, update, and deploy documentation directly from your terminal.",
5
5
  "type": "module",
6
6
  "files": [
@@ -9,6 +9,107 @@ import { detectPackageManager, getPackageManagerInfo, getPackageManagerVersion }
9
9
  import { getAvailableTemplates, getTemplate, getDefaultTemplate } from "../utils/templateDetect.js";
10
10
  import { execSync } from "child_process";
11
11
  import ora from "ora";
12
+ import fs from "fs";
13
+ import os from "os";
14
+ import path from "path";
15
+
16
+ // Helpers to show changelog once per installed version. Stores shown versions under
17
+ // $HOME/.docubook_cli_seen_changelogs.json as a map: { "@docubook/cli": ["1.2.3"] }
18
+ const _CHANGELOG_STORE = path.join(os.homedir(), ".docubook_cli_seen_changelogs.json");
19
+ function _readChangelogStore() {
20
+ try {
21
+ const raw = fs.readFileSync(_CHANGELOG_STORE, "utf8");
22
+ return JSON.parse(raw || "{}");
23
+ } catch {
24
+ return {};
25
+ }
26
+ }
27
+ function _writeChangelogStore(obj) {
28
+ try {
29
+ fs.writeFileSync(_CHANGELOG_STORE, JSON.stringify(obj, null, 2), { mode: 0o600 });
30
+ } catch {
31
+ // non-fatal
32
+ }
33
+ }
34
+
35
+ async function _fetchChangelogFromGitHub(tag) {
36
+ // Try to fetch CHANGELOG.md from the repo tag. Support several tag-name variants
37
+ // (e.g. v1.2.3, 1.2.3, cli-v1.2.3, cli-1.2.3) and common filename variants.
38
+ const repo = "DocuBook/docubook";
39
+
40
+ const bare = tag.replace(/^v/, "");
41
+ const variants = [tag, bare, `cli-${tag}`, `cli-${bare}`].filter(Boolean);
42
+
43
+ const candidates = [];
44
+ for (const v of variants) {
45
+ candidates.push(`https://raw.githubusercontent.com/${repo}/${v}/CHANGELOG.md`);
46
+ candidates.push(`https://raw.githubusercontent.com/${repo}/${v}/CHANGELOG.MD`);
47
+ }
48
+ // final fallback to main branch
49
+ candidates.push(`https://raw.githubusercontent.com/${repo}/main/CHANGELOG.md`);
50
+
51
+ for (const url of candidates) {
52
+ try {
53
+ const res = await fetch(url);
54
+ if (res && res.ok) return await res.text();
55
+ } catch {
56
+ // ignore and try next
57
+ }
58
+ }
59
+ return null;
60
+ }
61
+
62
+ function _extractVersionSection(changelogText, version) {
63
+ if (!changelogText) return null;
64
+ const lines = changelogText.split(/\r?\n/);
65
+ // Look for headings that include the version (e.g. "## v1.2.3" or "## 1.2.3")
66
+ const headerRe = new RegExp(`^#{1,3}\\s*(?:v)?${version.replace(/\./g, "\\.")}(?:\\b|\\D)`, "i");
67
+ let start = -1;
68
+ for (let i = 0; i < lines.length; i++) {
69
+ if (headerRe.test(lines[i])) {
70
+ start = i;
71
+ break;
72
+ }
73
+ }
74
+ if (start === -1) return changelogText.slice(0, 2000); // fallback: return beginning of changelog
75
+
76
+ let end = lines.length;
77
+ for (let j = start + 1; j < lines.length; j++) {
78
+ if (/^#{1,3}\s*/.test(lines[j])) {
79
+ end = j;
80
+ break;
81
+ }
82
+ }
83
+ return lines.slice(start, end).join("\n");
84
+ }
85
+
86
+ async function showChangelogOnce(pkgName, version) {
87
+ try {
88
+ const store = _readChangelogStore();
89
+ const seen = Array.isArray(store[pkgName]) ? store[pkgName] : [];
90
+ if (seen.includes(version)) return;
91
+
92
+ const tag = version.startsWith("v") ? version : `v${version}`;
93
+ const changelog = await _fetchChangelogFromGitHub(tag);
94
+ if (!changelog) return;
95
+
96
+ const section = _extractVersionSection(changelog, version);
97
+ if (!section) return;
98
+
99
+ // Print a concise changelog section
100
+ console.log("\n=== DocuBook CLI changelog (new) ===\n");
101
+ console.log(section.trim());
102
+ console.log("\nFor full changelog, visit:");
103
+ console.log(` https://github.com/DocuBook/docubook/blob/main/CHANGELOG.md\n`);
104
+
105
+ // Mark as shown
106
+ store[pkgName] = Array.from(new Set([...seen, version]));
107
+ _writeChangelogStore(store);
108
+ } catch {
109
+ // silent on any error - changelog is a nicety
110
+ }
111
+ }
112
+
12
113
 
13
114
  /**
14
115
  * Initializes the CLI program
@@ -59,6 +160,12 @@ export function initializeProgram(version) {
59
160
  try {
60
161
  execSync(cmd, { stdio: "inherit" });
61
162
  console.log(`Successfully updated to ${latest}`);
163
+ // Try to show changelog for the newly installed version once
164
+ try {
165
+ await showChangelogOnce(pkgName, latest);
166
+ } catch {
167
+ // non-fatal
168
+ }
62
169
  } catch (installErr) {
63
170
  // If install fails, provide a helpful message
64
171
  console.error(`Update failed: ${installErr.message || installErr}`);
@@ -73,6 +180,16 @@ export function initializeProgram(version) {
73
180
  }
74
181
  });
75
182
 
183
+ // Expose a `version` subcommand: `docubook version`
184
+ program
185
+ .command('version')
186
+ .description('Print the DocuBook CLI version')
187
+ .action(() => {
188
+ console.log(`DocuBook CLI ${version}`);
189
+ console.log("Run 'docubook update' to check for updates.");
190
+ process.exit(0);
191
+ });
192
+
76
193
  // Default behavior (create project)
77
194
  program
78
195
  .argument("[directory]", "The name of the project directory")
package/src/index.js CHANGED
@@ -14,9 +14,9 @@ const packageJsonPath = path.join(__dirname, '..', 'package.json');
14
14
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
15
15
  const VERSION = packageJson.version;
16
16
 
17
- // Handle --version / -V early to print custom output
17
+ // Handle --version / -v early to print custom output
18
18
  const args = process.argv.slice(2);
19
- if (args.includes('--version') || args.includes('-V')) {
19
+ if (args.includes('--version') || args.includes('-v')) {
20
20
  console.log(`DocuBook CLI ${VERSION}`);
21
21
  console.log("Run 'docubook update' to check for updates.");
22
22
  process.exit(0);
package/src/tui/ascii.js CHANGED
@@ -62,7 +62,7 @@ export function createWelcomeBanner(version) {
62
62
  const logoMid = `${colors.cyan}${colors.bright}▌>_▐${colors.reset}`
63
63
  const logoBot = `${colors.cyan}▙▄▄▟${colors.reset}`
64
64
 
65
- const title = `${colors.cyan}${colors.bright}DocuBook${colors.reset} v${version}`
65
+ const title = `${colors.cyan}${colors.bright}DocuBook CLI${colors.reset} v${version}`
66
66
  const subtitle = `${colors.gray}Initialize, build, and deploy docs from terminal.${colors.reset}`
67
67
 
68
68
  const tip = `${colors.gray}Visit our documentation.${colors.reset}`
@@ -103,16 +103,8 @@ export function createBoxedMessage(title, content, color = colors.green) {
103
103
  const reset = "\x1b[0m";
104
104
  const termWidth = process.stdout.columns || 80;
105
105
 
106
- // 1. Tentukan total lebar box (termasuk border)
107
106
  const boxWidth = Math.min(80, termWidth - 4);
108
-
109
- // 2. width adalah panjang garis horizontal (─) di atas dan bawah
110
- // Total lebar box adalah width + 2 (untuk karakter pojok ┌ dan ┐)
111
107
  const width = boxWidth - 2;
112
-
113
- // 3. inner adalah ruang bersih di dalam box untuk teks (tanpa padding spasi)
114
- // Kita beri padding 2 spasi di kiri dan 2 spasi di kanan (total 4)
115
- // Jadi: 1(│) + 2(spasi) + inner + 2(spasi) + 1(│) = width + 2
116
108
  const inner = (width + 2) - 6;
117
109
 
118
110
  const centerTitle = () => {
@@ -126,16 +118,11 @@ export function createBoxedMessage(title, content, color = colors.green) {
126
118
 
127
119
  const pad = (text = "") => {
128
120
  const len = stringWidth(text);
129
- // Tambahkan spasi hingga tepat mengisi 'inner'
130
121
  return text + " ".repeat(Math.max(0, inner - len));
131
122
  };
132
123
 
133
124
  const lines = [];
134
-
135
- // Header
136
125
  lines.push(`${color}┌${centerTitle()}┐${reset}`);
137
-
138
- // Padding atas (opsional)
139
126
  lines.push(`${color}│${reset} ${pad("")} ${color}│${reset}`);
140
127
 
141
128
  const items = typeof content === "string"
@@ -145,15 +132,10 @@ export function createBoxedMessage(title, content, color = colors.green) {
145
132
  for (const line of items) {
146
133
  const wrapped = wrapText(line, inner);
147
134
  wrapped.forEach((w) => {
148
- // Pastikan struktur: │ + spasi(2) + konten + spasi(2) + │
149
135
  lines.push(`${color}│${reset} ${pad(w)} ${color}│${reset}`);
150
136
  });
151
137
  }
152
-
153
- // Padding bawah (opsional)
154
138
  lines.push(`${color}│${reset} ${pad("")} ${color}│${reset}`);
155
-
156
- // Footer
157
139
  lines.push(`${color}└${"─".repeat(width)}┘${reset}`);
158
140
 
159
141
  return "\n" + lines.join("\n") + "\n";
@@ -1,32 +1,6 @@
1
- import { execSync } from "child_process";
2
1
  import fs from "fs";
3
2
  import path from "path";
4
3
 
5
- /**
6
- * Gets the version of the specified package manager
7
- * @param {string} pm - Package manager name
8
- * @returns {string|null} Version string or null if not installed
9
- */
10
- export function getPackageManagerVersion(pm) {
11
- try {
12
- return execSync(`${pm} --version`).toString().trim();
13
- } catch {
14
- return null;
15
- }
16
- }
17
-
18
- /**
19
- * Detects the default package manager from user environment
20
- * @returns {string} Default package manager name
21
- */
22
- export function detectDefaultPackageManager() {
23
- const userAgent = process.env.npm_config_user_agent || "";
24
- if (userAgent.includes("pnpm")) return "pnpm";
25
- if (userAgent.includes("yarn")) return "yarn";
26
- if (userAgent.includes("bun")) return "bun";
27
- return "npm";
28
- }
29
-
30
4
  /**
31
5
  * Updates postcss config file extension for Bun compatibility
32
6
  * @param {string} projectPath - Path to the project directory
package/templates.json CHANGED
@@ -16,6 +16,23 @@
16
16
  ],
17
17
  "url": "https://github.com/DocuBook/docubook/tree/main/packages/template/nextjs-vercel"
18
18
  },
19
+ {
20
+ "id": "nextjs-docker",
21
+ "name": "nextjs-docker",
22
+ "description": "Modern documentation with Next.js standalone and Docker deployment",
23
+ "features": [
24
+ "Next.js 16",
25
+ "React 19",
26
+ "TypeScript",
27
+ "Tailwind CSS",
28
+ "MDX Support",
29
+ "Dark Mode",
30
+ "Search (Algolia)",
31
+ "Responsive Design",
32
+ "Docker Deployment"
33
+ ],
34
+ "url": "https://github.com/DocuBook/docubook/tree/main/packages/template/nextjs-docker"
35
+ },
19
36
  {
20
37
  "id": "react-router",
21
38
  "name": "react-router",