@docubook/cli 0.2.1 → 0.2.3

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.1",
3
+ "version": "0.2.3",
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": [
@@ -63,7 +63,7 @@ export function initializeProgram(version) {
63
63
 
64
64
  // Show success message
65
65
  const pmInfo = getPackageManagerInfo(detectedPM);
66
- renderDone(userInput.directoryName, detectedPM, pmInfo.devCmd);
66
+ renderDone(userInput.directoryName, detectedPM, pmInfo.devCmd, userInput.autoInstall !== false);
67
67
  } catch (err) {
68
68
  renderError(err.message || "An unexpected error occurred.");
69
69
  log.error(err.message || "An unexpected error occurred.");
@@ -1,5 +1,6 @@
1
1
  import path from "path";
2
2
  import fs from "fs";
3
+ import { URL } from "url";
3
4
  import ora from "ora";
4
5
  import chalk from "chalk";
5
6
  import { execSync } from "child_process";
@@ -36,9 +37,9 @@ export async function createProject(options) {
36
37
  // 1. Create project directory and get/download template
37
38
  state?.setCurrentStep("Creating directories...");
38
39
  renderScaffolding(state || {});
39
-
40
+
40
41
  const templatePath = await getOrDownloadTemplate(template, state);
41
-
42
+
42
43
  if (!templatePath || !fs.existsSync(templatePath)) {
43
44
  throw new Error(`Template "${template}" could not be found or downloaded.`);
44
45
  }
@@ -93,46 +94,31 @@ async function getOrDownloadTemplate(templateId, state) {
93
94
  // Download from GitHub
94
95
  state?.setCurrentStep("Downloading template...");
95
96
  renderScaffolding(state || {});
96
-
97
+
97
98
  const templateInfo = getTemplate(templateId);
98
- if (!templateInfo || !templateInfo.url) {
99
- throw new Error(`Template "${templateId}" information not available.`);
99
+ if (!templateInfo) {
100
+ throw new Error(`Template "${templateId}" not found.`);
100
101
  }
101
102
 
102
103
  return await downloadTemplateFromGitHub(templateId, templateInfo.url);
103
104
  }
104
105
 
105
106
  /**
106
- * Gets local template path if it exists
107
+ * Gets local template path if it exists (for development)
107
108
  * @param {string} templateId - Template ID
108
109
  * @returns {string|null} Path to local template or null
109
110
  */
110
111
  function getLocalTemplatePath(templateId) {
111
- import("file:///").catch(() => {});
112
-
113
- const distPath = path.join(
114
- new URL(".", import.meta.url).pathname,
115
- "..",
116
- "..",
117
- "dist",
118
- templateId
119
- );
120
-
112
+ const currentDir = new URL(".", import.meta.url).pathname;
113
+
114
+ // Check dist/ folder first (if built)
115
+ const distPath = path.join(currentDir, "..", "..", "dist", templateId);
121
116
  if (fs.existsSync(distPath)) {
122
117
  return distPath;
123
118
  }
124
119
 
125
- const devPath = path.join(
126
- new URL(".", import.meta.url).pathname,
127
- "..",
128
- "..",
129
- "..",
130
- "..",
131
- "packages",
132
- "template",
133
- templateId
134
- );
135
-
120
+ // Check packages/template/ folder (dev environment)
121
+ const devPath = path.join(currentDir, "..", "..", "..", "..", "packages", "template", templateId);
136
122
  if (fs.existsSync(devPath)) {
137
123
  return devPath;
138
124
  }
@@ -143,28 +129,50 @@ function getLocalTemplatePath(templateId) {
143
129
  /**
144
130
  * Downloads template from GitHub repository
145
131
  * @param {string} templateId - Template ID
146
- * @param {string} gitHubUrl - GitHub URL to template
132
+ * @param {string} templateUrl - Template URL from templates.json
147
133
  * @returns {Promise<string>} Path to downloaded template
148
134
  */
149
- async function downloadTemplateFromGitHub(templateId, gitHubUrl) {
135
+ async function downloadTemplateFromGitHub(templateId, templateUrl) {
150
136
  const tempDir = fs.mkdtempSync(path.join("/tmp", "docubook-"));
151
-
137
+
152
138
  try {
153
- // Convert GitHub web URL to archive URL
139
+ // Build archive URL from template URL
154
140
  // https://github.com/DocuBook/docubook/tree/main/packages/template/nextjs-vercel
155
141
  // -> https://github.com/DocuBook/docubook/archive/refs/heads/main.tar.gz
156
- const archiveUrl = "https://github.com/DocuBook/docubook/archive/refs/heads/main.tar.gz";
157
-
158
- // Download archive
142
+ const repoMatch = templateUrl.match(/https:\/\/github\.com\/([^/]+\/[^/]+)\//);
143
+ if (!repoMatch) {
144
+ throw new Error(`Invalid template URL: ${templateUrl}`);
145
+ }
146
+
147
+ const archiveUrl = `https://github.com/${repoMatch[1]}/archive/refs/heads/main.tar.gz`;
159
148
  const archivePath = path.join(tempDir, "repo.tar.gz");
160
- execSync(`curl -L -o "${archivePath}" "${archiveUrl}"`, { stdio: "pipe" });
161
149
 
162
- // Extract archive
163
- execSync(`tar -xzf "${archivePath}" -C "${tempDir}"`, { stdio: "pipe" });
150
+ // Show progress for download
151
+ const downloadSpinner = ora(`Downloading template...`).start();
152
+
153
+ try {
154
+ execSync(`curl -L -o "${archivePath}" "${archiveUrl}"`, { stdio: "pipe" });
155
+ downloadSpinner.succeed("Template downloaded");
156
+ } catch (err) {
157
+ downloadSpinner.fail("Failed to download template");
158
+ throw err;
159
+ }
160
+
161
+ // Show progress for extraction
162
+ const extractSpinner = ora(`Extracting template...`).start();
163
+
164
+ try {
165
+ execSync(`tar -xzf "${archivePath}" -C "${tempDir}"`, { stdio: "pipe" });
166
+ extractSpinner.succeed("Template extracted");
167
+ } catch (err) {
168
+ extractSpinner.fail("Failed to extract template");
169
+ throw err;
170
+ }
164
171
 
165
172
  // Find template in extracted repo
166
- const extractedDir = path.join(tempDir, "docubook-main", "packages", "template", templateId);
167
-
173
+ const repoName = repoMatch[1].split('/')[1];
174
+ const extractedDir = path.join(tempDir, `${repoName}-main`, "packages", "template", templateId);
175
+
168
176
  if (!fs.existsSync(extractedDir)) {
169
177
  throw new Error(`Template "${templateId}" not found in repository.`);
170
178
  }
@@ -1,37 +1,5 @@
1
1
  import chalk from "chalk";
2
2
  import boxen from "boxen";
3
- import cliProgress from "cli-progress";
4
-
5
- /**
6
- * Displays an introduction message for the CLI.
7
- */
8
- export function displayIntro() {
9
- console.log(`\n${chalk.bold.green("🚀 DocuBook Installer")}\n`);
10
- }
11
-
12
- /**
13
- * Displays a progress bar to simulate final setup.
14
- * @returns {Promise<void>} Promise that resolves when simulation completes.
15
- */
16
- export async function simulateInstallation() {
17
- const bar = new cliProgress.SingleBar(
18
- {
19
- format: `Finishing setup... ${chalk.greenBright("{bar}")} | {percentage}%`,
20
- barCompleteChar: "\u2588",
21
- barIncompleteChar: "\u2591",
22
- hideCursor: true,
23
- },
24
- cliProgress.Presets.shades_classic
25
- );
26
-
27
- bar.start(100, 0);
28
- for (let i = 0; i <= 100; i++) {
29
- await new Promise((r) => setTimeout(r, 20)); // Faster simulation
30
- bar.update(i);
31
- }
32
- bar.stop();
33
- console.log("\n");
34
- }
35
3
 
36
4
  /**
37
5
  * Displays manual installation steps if automatic installation fails.
@@ -56,29 +24,4 @@ export function displayManualSteps(projectDirectory, packageManager) {
56
24
  titleAlignment: "center",
57
25
  })
58
26
  );
59
- }
60
-
61
- /**
62
- * Displays next steps after successful installation.
63
- * @param {string} directoryName - Project directory name.
64
- * @param {string} packageManager - Package manager being used.
65
- */
66
- export function displayNextSteps(directoryName, packageManager) {
67
- const steps = `
68
- ${chalk.bold("Next steps:")}
69
-
70
- 1. ${chalk.blueBright(`cd ${directoryName}`)}
71
- 2. ${chalk.blueBright(`${packageManager} run dev`)}
72
- `;
73
-
74
- console.log(
75
- boxen(steps, {
76
- padding: 1,
77
- margin: 1,
78
- borderStyle: "round",
79
- borderColor: "green",
80
- title: "Success!",
81
- titleAlignment: "center",
82
- })
83
- );
84
27
  }
@@ -15,30 +15,30 @@ export function getAvailableTemplates() {
15
15
  const data = JSON.parse(content);
16
16
  return data.templates || [];
17
17
  }
18
- } catch (err) {
18
+ } catch {
19
19
  // Fallback to directory scanning
20
20
  }
21
21
 
22
22
  // Fallback: scan template directories
23
23
  const distPath = path.join(__dirname, '..', '..', 'dist');
24
- const templateDir = fs.existsSync(distPath)
25
- ? distPath
24
+ const templateDir = fs.existsSync(distPath)
25
+ ? distPath
26
26
  : path.join(__dirname, '..', '..', '..', '..', 'packages', 'template');
27
-
27
+
28
28
  if (!fs.existsSync(templateDir)) {
29
29
  return [];
30
30
  }
31
-
31
+
32
32
  const entries = fs.readdirSync(templateDir, { withFileTypes: true });
33
33
  const templates = [];
34
-
34
+
35
35
  for (const entry of entries) {
36
36
  if (!entry.isDirectory()) continue;
37
-
37
+
38
38
  const configPath = path.join(templateDir, entry.name, 'template.config.json');
39
-
39
+
40
40
  if (!fs.existsSync(configPath)) continue;
41
-
41
+
42
42
  try {
43
43
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
44
44
  templates.push({
@@ -51,7 +51,7 @@ export function getAvailableTemplates() {
51
51
  console.error(`Failed to read template config for ${entry.name}`);
52
52
  }
53
53
  }
54
-
54
+
55
55
  return templates;
56
56
  }
57
57