nexo-md-to-pdf-cli 0.1.0 → 0.1.2
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 +57 -4
- package/dist/cli.js +133 -27
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,12 +62,19 @@ Convert several files at once:
|
|
|
62
62
|
nexo a.md b.md c.md --output-dir ./pdfs
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
Use a custom logo:
|
|
65
|
+
Use a one-off custom logo:
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
68
|
nexo release-summary.md --logo ./brand.svg --logo-tone light
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
Save a default logo once and reuse it:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
nexo config set-logo ./brand.svg --logo-tone light
|
|
75
|
+
nexo release-summary.md
|
|
76
|
+
```
|
|
77
|
+
|
|
71
78
|
Target another environment:
|
|
72
79
|
|
|
73
80
|
```bash
|
|
@@ -99,13 +106,16 @@ This keeps metrics and operational visibility clean without splitting rendering
|
|
|
99
106
|
nexo <file.md>
|
|
100
107
|
nexo <file.md> --output <file.pdf>
|
|
101
108
|
nexo <file-a.md> <file-b.md> --output-dir <directory>
|
|
109
|
+
nexo config set-logo <file>
|
|
110
|
+
nexo config clear-logo
|
|
111
|
+
nexo config show
|
|
102
112
|
```
|
|
103
113
|
|
|
104
114
|
### Options
|
|
105
115
|
|
|
106
116
|
- `--output <file>`: write the generated PDF to a specific path for a single Markdown input
|
|
107
117
|
- `--output-dir <directory>`: choose the output directory when converting multiple files
|
|
108
|
-
- `--logo <file>`: provide an optional logo in `png`, `jpg`, `webp`, or `svg
|
|
118
|
+
- `--logo <file>`: provide an optional one-off logo in `png`, `jpg`, `webp`, or `svg`; this overrides the saved default
|
|
109
119
|
- `--logo-tone <dark|light>`: choose the logo header background tone, default is `dark`
|
|
110
120
|
- `--api-base-url <url>`: point the CLI to another NEXO environment such as local development or staging
|
|
111
121
|
- `-h, --help`: show command help
|
|
@@ -117,12 +127,48 @@ nexo <file-a.md> <file-b.md> --output-dir <directory>
|
|
|
117
127
|
- each input file generates one PDF
|
|
118
128
|
- the CLI exits with a non-zero status if one or more conversions fail
|
|
119
129
|
|
|
130
|
+
## Saved default logo
|
|
131
|
+
|
|
132
|
+
If you always use the same brand asset, you can save it once and stop repeating `--logo` in every command.
|
|
133
|
+
|
|
134
|
+
Set the default logo:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
nexo config set-logo ./brand.svg --logo-tone light
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Inspect the saved config:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
nexo config show
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Clear the saved logo:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
nexo config clear-logo
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
After saving a default logo, plain conversions automatically reuse it:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
nexo weekly-report.md
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The CLI stores this configuration locally at:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
~/.nexo/config.json
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
If you pass `--logo` in a conversion command, that explicit file takes precedence over the saved default.
|
|
165
|
+
|
|
120
166
|
## Current scope
|
|
121
167
|
|
|
122
168
|
This first version of the CLI intentionally focuses on the most common command-line workflow:
|
|
123
169
|
|
|
124
170
|
- Markdown input
|
|
125
|
-
- optional custom logo
|
|
171
|
+
- optional custom logo, including a saved default logo
|
|
126
172
|
- hosted conversion through the NEXO API
|
|
127
173
|
|
|
128
174
|
The following are intentionally out of scope for now:
|
|
@@ -167,6 +213,13 @@ Bulk conversion:
|
|
|
167
213
|
nexo docs/release-1.md docs/release-2.md docs/release-3.md --output-dir ./exports
|
|
168
214
|
```
|
|
169
215
|
|
|
216
|
+
Saved default logo:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
nexo config set-logo ./assets/brand.svg --logo-tone light
|
|
220
|
+
nexo docs/release-1.md
|
|
221
|
+
```
|
|
222
|
+
|
|
170
223
|
Local backend:
|
|
171
224
|
|
|
172
225
|
```bash
|
|
@@ -194,7 +247,7 @@ For successful conversions, the CLI prints a line like:
|
|
|
194
247
|
For failed conversions, it prints:
|
|
195
248
|
|
|
196
249
|
```text
|
|
197
|
-
[
|
|
250
|
+
[error] /absolute/input.md -> reason
|
|
198
251
|
```
|
|
199
252
|
|
|
200
253
|
## Development
|
package/dist/cli.js
CHANGED
|
@@ -1,33 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
3
4
|
import { basename, dirname, extname, join, resolve } from "node:path";
|
|
4
5
|
import { parseArgs } from "node:util";
|
|
5
6
|
import { validateFreeConvertRequest } from "./free-convert.js";
|
|
6
7
|
const DEFAULT_API_BASE_URL = "https://nexo.speck-solutions.com.br";
|
|
8
|
+
const DEFAULT_LOGO_TONE = "dark";
|
|
9
|
+
const CONFIG_DIR = join(homedir(), ".nexo");
|
|
10
|
+
const CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
7
11
|
function printHelp() {
|
|
8
12
|
console.log(`nexo
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
nexo
|
|
12
|
-
nexo
|
|
14
|
+
Usage:
|
|
15
|
+
nexo file.md
|
|
16
|
+
nexo file.md --output ./output.pdf
|
|
13
17
|
nexo a.md b.md c.md --output-dir ./pdfs
|
|
14
|
-
nexo
|
|
15
|
-
nexo
|
|
18
|
+
nexo file.md --logo ./logo.svg --logo-tone light
|
|
19
|
+
nexo file.md --api-base-url http://localhost:3000
|
|
20
|
+
nexo config set-logo ./logo.svg --logo-tone light
|
|
21
|
+
nexo config clear-logo
|
|
22
|
+
nexo config show
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
--output <
|
|
19
|
-
--output-dir <
|
|
20
|
-
--logo <
|
|
21
|
-
--logo-tone <dark|light>
|
|
22
|
-
--api-base-url <url>
|
|
23
|
-
--help, -h
|
|
24
|
+
Options:
|
|
25
|
+
--output <file> Write the output PDF to a specific path for one markdown file
|
|
26
|
+
--output-dir <dir> Output directory when converting multiple files
|
|
27
|
+
--logo <file> Optional logo (png, jpg, webp, or svg); overrides the saved default
|
|
28
|
+
--logo-tone <dark|light> Header background tone for the logo (default: dark)
|
|
29
|
+
--api-base-url <url> NEXO API base URL (default: ${DEFAULT_API_BASE_URL})
|
|
30
|
+
--help, -h Show this help message
|
|
24
31
|
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
32
|
+
Rules:
|
|
33
|
+
- Each conversion follows the same free-mode limits as the unauthenticated NEXO flow
|
|
34
|
+
- Each .md file becomes a separate PDF, which makes bulk processing easier
|
|
35
|
+
- Without --output-dir, the PDF is saved next to the original file
|
|
36
|
+
- Usage is tracked by the NEXO backend and marked with CLI as the source
|
|
37
|
+
- A saved default logo can be configured once and reused automatically
|
|
38
|
+
- Attachments are not supported in this CLI version
|
|
31
39
|
`);
|
|
32
40
|
}
|
|
33
41
|
function detectMimeType(filePath) {
|
|
@@ -50,7 +58,7 @@ async function encodeFileAsDataUrl(filePath) {
|
|
|
50
58
|
const absolutePath = resolve(filePath);
|
|
51
59
|
const mimeType = detectMimeType(absolutePath);
|
|
52
60
|
if (!mimeType) {
|
|
53
|
-
throw new Error(`
|
|
61
|
+
throw new Error(`Unsupported file format in ${absolutePath}.`);
|
|
54
62
|
}
|
|
55
63
|
const bytes = await readFile(absolutePath);
|
|
56
64
|
return {
|
|
@@ -72,15 +80,88 @@ function toCliOptions(values) {
|
|
|
72
80
|
output: typeof values.output === "string" ? values.output : undefined,
|
|
73
81
|
outputDir: typeof values["output-dir"] === "string" ? values["output-dir"] : undefined,
|
|
74
82
|
logo: typeof values.logo === "string" ? values.logo : undefined,
|
|
75
|
-
logoTone: values["logo-tone"] === "light"
|
|
83
|
+
logoTone: values["logo-tone"] === "light" || values["logo-tone"] === "dark"
|
|
84
|
+
? values["logo-tone"]
|
|
85
|
+
: undefined,
|
|
76
86
|
apiBaseUrl: typeof values["api-base-url"] === "string" ? values["api-base-url"] : undefined,
|
|
77
87
|
help: Boolean(values.help)
|
|
78
88
|
};
|
|
79
89
|
}
|
|
90
|
+
async function loadCliConfig() {
|
|
91
|
+
try {
|
|
92
|
+
const raw = await readFile(CONFIG_PATH, "utf8");
|
|
93
|
+
const parsed = JSON.parse(raw);
|
|
94
|
+
return {
|
|
95
|
+
defaultLogoPath: typeof parsed.defaultLogoPath === "string" ? parsed.defaultLogoPath : undefined,
|
|
96
|
+
defaultLogoTone: parsed.defaultLogoTone === "light" || parsed.defaultLogoTone === "dark"
|
|
97
|
+
? parsed.defaultLogoTone
|
|
98
|
+
: undefined
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
const code = error instanceof Error && "code" in error ? String(error.code) : "";
|
|
103
|
+
if (code === "ENOENT") {
|
|
104
|
+
return {};
|
|
105
|
+
}
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async function saveCliConfig(config) {
|
|
110
|
+
await mkdir(CONFIG_DIR, { recursive: true });
|
|
111
|
+
await writeFile(CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf8");
|
|
112
|
+
}
|
|
80
113
|
function buildApiUrl(options) {
|
|
81
114
|
const baseUrl = (options.apiBaseUrl || process.env.NEXO_API_BASE_URL || DEFAULT_API_BASE_URL).replace(/\/+$/, "");
|
|
82
115
|
return `${baseUrl}/api/free/convert`;
|
|
83
116
|
}
|
|
117
|
+
async function handleConfigCommand(args, options) {
|
|
118
|
+
const [action, value] = args;
|
|
119
|
+
if (!action || options.help) {
|
|
120
|
+
console.log(`nexo config
|
|
121
|
+
|
|
122
|
+
Usage:
|
|
123
|
+
nexo config set-logo ./logo.svg --logo-tone light
|
|
124
|
+
nexo config clear-logo
|
|
125
|
+
nexo config show
|
|
126
|
+
`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (action === "set-logo") {
|
|
130
|
+
if (!value) {
|
|
131
|
+
throw new Error("Use `nexo config set-logo <file>`.");
|
|
132
|
+
}
|
|
133
|
+
const absoluteLogoPath = resolve(value);
|
|
134
|
+
await encodeFileAsDataUrl(absoluteLogoPath);
|
|
135
|
+
const currentConfig = await loadCliConfig();
|
|
136
|
+
const nextConfig = {
|
|
137
|
+
defaultLogoPath: absoluteLogoPath,
|
|
138
|
+
defaultLogoTone: options.logoTone ?? currentConfig.defaultLogoTone ?? DEFAULT_LOGO_TONE
|
|
139
|
+
};
|
|
140
|
+
await saveCliConfig(nextConfig);
|
|
141
|
+
console.log(`[nexo] Saved default logo: ${absoluteLogoPath}`);
|
|
142
|
+
console.log(`[nexo] Saved default logo tone: ${nextConfig.defaultLogoTone}`);
|
|
143
|
+
console.log(`[nexo] Config path: ${CONFIG_PATH}`);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (action === "clear-logo") {
|
|
147
|
+
await saveCliConfig({});
|
|
148
|
+
console.log("[nexo] Cleared the saved default logo.");
|
|
149
|
+
console.log(`[nexo] Config path: ${CONFIG_PATH}`);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (action === "show") {
|
|
153
|
+
const currentConfig = await loadCliConfig();
|
|
154
|
+
console.log(`[nexo] Config path: ${CONFIG_PATH}`);
|
|
155
|
+
if (!currentConfig.defaultLogoPath) {
|
|
156
|
+
console.log("[nexo] No default logo configured.");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
console.log(`[nexo] Default logo: ${currentConfig.defaultLogoPath}`);
|
|
160
|
+
console.log(`[nexo] Default logo tone: ${currentConfig.defaultLogoTone ?? DEFAULT_LOGO_TONE}`);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
throw new Error(`Unknown config command: ${action}`);
|
|
164
|
+
}
|
|
84
165
|
async function convertMarkdownFile(inputPath, options, customLogoData) {
|
|
85
166
|
const absoluteInputPath = resolve(inputPath);
|
|
86
167
|
const markdown = await readFile(absoluteInputPath, "utf8");
|
|
@@ -115,7 +196,7 @@ async function convertMarkdownFile(inputPath, options, customLogoData) {
|
|
|
115
196
|
const errorBody = await response.json().catch(() => ({}));
|
|
116
197
|
const message = typeof errorBody?.message === "string"
|
|
117
198
|
? errorBody.message
|
|
118
|
-
: `
|
|
199
|
+
: `Conversion failed (${response.status}).`;
|
|
119
200
|
throw new Error(message);
|
|
120
201
|
}
|
|
121
202
|
const pdfBytes = Buffer.from(await response.arrayBuffer());
|
|
@@ -138,26 +219,51 @@ async function main() {
|
|
|
138
219
|
});
|
|
139
220
|
const options = toCliOptions(parsed.values);
|
|
140
221
|
const inputs = parsed.positionals;
|
|
222
|
+
if (inputs[0] === "config") {
|
|
223
|
+
await handleConfigCommand(inputs.slice(1), options);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
141
226
|
if (options.help || inputs.length === 0) {
|
|
142
227
|
printHelp();
|
|
143
228
|
process.exit(inputs.length === 0 && !options.help ? 1 : 0);
|
|
144
229
|
}
|
|
145
230
|
if (options.output && inputs.length > 1) {
|
|
146
|
-
throw new Error("Use --output
|
|
231
|
+
throw new Error("Use --output only when converting a single .md file.");
|
|
147
232
|
}
|
|
148
|
-
const
|
|
233
|
+
const cliConfig = await loadCliConfig();
|
|
234
|
+
const effectiveLogoPath = options.logo ?? cliConfig.defaultLogoPath;
|
|
235
|
+
const effectiveLogoTone = options.logoTone ?? cliConfig.defaultLogoTone ?? DEFAULT_LOGO_TONE;
|
|
236
|
+
const customLogoData = effectiveLogoPath ? await encodeFileAsDataUrl(effectiveLogoPath) : null;
|
|
149
237
|
let failures = 0;
|
|
150
|
-
|
|
238
|
+
const total = inputs.length;
|
|
239
|
+
console.log(`[nexo] Starting ${total} conversion${total === 1 ? "" : "s"} using ${buildApiUrl(options)}`);
|
|
240
|
+
if (effectiveLogoPath) {
|
|
241
|
+
const logoSource = options.logo ? "command line" : "saved config";
|
|
242
|
+
console.log(`[nexo] Using logo from ${logoSource}: ${resolve(effectiveLogoPath)}`);
|
|
243
|
+
console.log(`[nexo] Using logo tone: ${effectiveLogoTone}`);
|
|
244
|
+
}
|
|
245
|
+
for (const [index, inputPath] of inputs.entries()) {
|
|
246
|
+
const absoluteInputPath = resolve(inputPath);
|
|
247
|
+
const outputPath = deriveOutputPath(absoluteInputPath, options);
|
|
151
248
|
try {
|
|
152
|
-
|
|
153
|
-
console.log(`[
|
|
249
|
+
console.log(`[${index + 1}/${total}] Reading ${absoluteInputPath}`);
|
|
250
|
+
console.log(`[${index + 1}/${total}] Sending conversion request...`);
|
|
251
|
+
const writtenOutputPath = await convertMarkdownFile(inputPath, { ...options, logoTone: effectiveLogoTone }, customLogoData);
|
|
252
|
+
console.log(`[ok] ${absoluteInputPath} -> ${writtenOutputPath}`);
|
|
154
253
|
}
|
|
155
254
|
catch (error) {
|
|
156
255
|
failures += 1;
|
|
157
256
|
const reason = error instanceof Error ? error.message : String(error);
|
|
158
|
-
console.error(`[
|
|
257
|
+
console.error(`[error] ${absoluteInputPath} -> ${reason}`);
|
|
258
|
+
console.error(`[${index + 1}/${total}] Expected output path: ${outputPath}`);
|
|
159
259
|
}
|
|
160
260
|
}
|
|
261
|
+
if (failures === 0) {
|
|
262
|
+
console.log(`[nexo] Completed ${total} conversion${total === 1 ? "" : "s"} successfully.`);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
console.error(`[nexo] Finished with ${failures} failure${failures === 1 ? "" : "s"} out of ${total} conversion${total === 1 ? "" : "s"}.`);
|
|
266
|
+
}
|
|
161
267
|
if (failures > 0) {
|
|
162
268
|
process.exitCode = 1;
|
|
163
269
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|