@bytechain.cn/colamd-themes 0.3.0 → 0.3.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.
Files changed (39) hide show
  1. package/.openclaw/skills/colamd-themes/SKILL.md +15 -124
  2. package/.trae/rules/colamd-themes.md +15 -124
  3. package/CHANGELOG.md +142 -3
  4. package/README.md +12 -1
  5. package/README_CN.md +12 -1
  6. package/RELEASENOTE.md +212 -0
  7. package/dist/cli.js +278 -2
  8. package/dist/cli.js.map +1 -1
  9. package/dist/export-cli.d.ts +1 -0
  10. package/dist/export-cli.js +208 -176
  11. package/dist/export-cli.js.map +1 -1
  12. package/dist/extractors/url-extractor.d.ts +6 -0
  13. package/dist/extractors/url-extractor.js +51 -2
  14. package/dist/extractors/url-extractor.js.map +1 -1
  15. package/dist/generator.d.ts +4 -0
  16. package/dist/generator.js +74 -7
  17. package/dist/generator.js.map +1 -1
  18. package/dist/renderer.d.ts +1 -1
  19. package/dist/renderer.js +87 -14
  20. package/dist/renderer.js.map +1 -1
  21. package/dist/theme-store.d.ts +7 -6
  22. package/dist/theme-store.js +84 -34
  23. package/dist/theme-store.js.map +1 -1
  24. package/dist/utils/cli-utils.d.ts +55 -0
  25. package/dist/utils/cli-utils.js +80 -0
  26. package/dist/utils/cli-utils.js.map +1 -0
  27. package/package.json +1 -1
  28. package/skills/colamd-themes/SKILL.md +30 -0
  29. package/src/cli.ts +289 -2
  30. package/src/export-cli.ts +248 -193
  31. package/src/extractors/url-extractor.ts +56 -2
  32. package/src/generator.ts +88 -7
  33. package/src/renderer.ts +96 -14
  34. package/src/theme-store.ts +93 -35
  35. package/src/utils/cli-utils.ts +84 -0
  36. package/.claude/skills/colamd-themes-preview.skill.md +0 -333
  37. package/.claude/skills/colamd-themes.skill.md +0 -155
  38. package/.hermes/skills/tools/colamd-themes/SKILL.md +0 -159
  39. package/.opencode/skills/colamd-themes/SKILL.md +0 -162
@@ -2,13 +2,15 @@
2
2
  * Export CLI commands: set-theme, export-html, export-pdf, export (batch).
3
3
  *
4
4
  * These are registered onto the main Commander program in cli.ts.
5
+ * Uses unified error handling via CLIError and shared utility functions.
5
6
  */
6
- import { existsSync, readFileSync, readdirSync, statSync, mkdirSync } from "node:fs";
7
- import { join, isAbsolute, resolve, basename } from "node:path";
7
+ import { readFileSync, readdirSync, statSync, mkdirSync } from "node:fs";
8
+ import { join, resolve } from "node:path";
8
9
  import chalk from "chalk";
9
10
  import ora from "ora";
10
11
  import { BUILTIN_THEMES, getConfig, setDefaultTheme as storeSetDefault, registerTheme as storeRegister, unregisterTheme as storeUnregister, resolveTheme, } from "./theme-store.js";
11
12
  import { ColamdRenderer } from "./renderer.js";
13
+ import { resolveInputPath, resolveOutputPath, getDocumentTitle, CLIError, ErrorCode, } from "./utils/cli-utils.js";
12
14
  // ── set-theme ──
13
15
  function registerSetTheme(program) {
14
16
  program
@@ -18,50 +20,58 @@ function registerSetTheme(program) {
18
20
  .option("--css <file>", "Register as custom theme using this CSS file")
19
21
  .option("--default", "Set as the default export theme")
20
22
  .option("--remove", "Unregister a custom theme")
21
- .action((name, options) => {
22
- // Remove
23
- if (options.remove) {
24
- if (storeUnregister(name)) {
25
- console.log(chalk.green(`✔ Unregistered custom theme "${name}"`));
23
+ .action(async (name, options) => {
24
+ try {
25
+ // Remove
26
+ if (options.remove) {
27
+ const removed = await storeUnregister(name);
28
+ if (removed) {
29
+ console.log(chalk.green(`✔ Unregistered custom theme "${name}"`));
30
+ }
31
+ else {
32
+ console.log(chalk.yellow(`Theme "${name}" is not registered.`));
33
+ }
34
+ return;
26
35
  }
27
- else {
28
- console.log(chalk.yellow(`Theme "${name}" is not registered.`));
36
+ // Register custom theme
37
+ if (options.css) {
38
+ const cssPath = resolveInputPath(options.css);
39
+ await storeRegister(name, cssPath);
40
+ console.log(chalk.green(`✔ Registered custom theme "${name}" → ${cssPath}`));
41
+ if (options.default) {
42
+ await storeSetDefault(name);
43
+ console.log(chalk.green(`✔ Set "${name}" as default theme`));
44
+ }
45
+ return;
29
46
  }
30
- return;
31
- }
32
- // Register custom theme
33
- if (options.css) {
34
- const cssPath = isAbsolute(options.css) ? options.css : resolve(process.cwd(), options.css);
35
- if (!existsSync(cssPath)) {
36
- console.error(chalk.red(`CSS file not found: ${cssPath}`));
37
- process.exit(1);
47
+ // Set as default (built-in or already registered)
48
+ if (!BUILTIN_THEMES.includes(name)) {
49
+ const config = await getConfig();
50
+ if (!(name in config.themes)) {
51
+ throw new CLIError(`Unknown theme "${name}". ` +
52
+ chalk.dim(`Built-in: ${BUILTIN_THEMES.join(", ")}. `) +
53
+ chalk.dim("Or register a custom theme with --css <file>."), ErrorCode.THEME_ERROR);
54
+ }
38
55
  }
39
- storeRegister(name, cssPath);
40
- console.log(chalk.green(`✔ Registered custom theme "${name}" → ${cssPath}`));
41
- if (options.default) {
42
- storeSetDefault(name);
43
- console.log(chalk.green(`✔ Set "${name}" as default theme`));
56
+ await storeSetDefault(name);
57
+ console.log(chalk.green(`✔ Default theme set to "${name}"`));
58
+ // Show current config
59
+ const config = await getConfig();
60
+ console.log(chalk.dim(`\n Default: ${config.defaultTheme}`));
61
+ const customs = Object.keys(config.themes);
62
+ if (customs.length) {
63
+ console.log(chalk.dim(` Custom themes: ${customs.join(", ")}`));
44
64
  }
45
- return;
46
65
  }
47
- // Set as default (built-in or already registered)
48
- if (!BUILTIN_THEMES.includes(name)) {
49
- const config = getConfig();
50
- if (!(name in config.themes)) {
51
- console.error(chalk.red(`Unknown theme "${name}". `) +
52
- chalk.dim(`Built-in: ${BUILTIN_THEMES.join(", ")}. `) +
53
- chalk.dim("Or register a custom theme with --css <file>."));
54
- process.exit(1);
66
+ catch (err) {
67
+ if (err instanceof CLIError) {
68
+ console.error(chalk.red(err.message));
69
+ process.exit(err.code);
70
+ }
71
+ else {
72
+ console.error(chalk.red(`Unexpected error: ${err.message}`));
73
+ process.exit(ErrorCode.UNKNOWN);
55
74
  }
56
- }
57
- storeSetDefault(name);
58
- console.log(chalk.green(`✔ Default theme set to "${name}"`));
59
- // Show current config
60
- const config = getConfig();
61
- console.log(chalk.dim(`\n Default: ${config.defaultTheme}`));
62
- const customs = Object.keys(config.themes);
63
- if (customs.length) {
64
- console.log(chalk.dim(` Custom themes: ${customs.join(", ")}`));
65
75
  }
66
76
  });
67
77
  }
@@ -74,40 +84,42 @@ function registerExportHTML(program) {
74
84
  .option("-t, --theme <name>", "Theme name (built-in, custom, or CSS file path)")
75
85
  .option("-o, --output <path>", "Output HTML file path")
76
86
  .action(async (input, options) => {
77
- const inputPath = isAbsolute(input) ? input : resolve(process.cwd(), input);
78
- if (!existsSync(inputPath)) {
79
- console.error(chalk.red(`File not found: ${inputPath}`));
80
- process.exit(1);
81
- }
82
- const md = readFileSync(inputPath, "utf-8");
83
- const title = basename(inputPath, ".md");
84
- const outputPath = options.output
85
- ? (isAbsolute(options.output) ? options.output : resolve(process.cwd(), options.output))
86
- : inputPath.replace(/\.md$/i, ".html");
87
- let theme;
88
87
  try {
89
- theme = resolveTheme(options.theme);
90
- }
91
- catch (err) {
92
- console.error(chalk.red(err.message));
93
- process.exit(1);
94
- }
95
- const spinner = ora(`Rendering ${basename(inputPath)} → HTML (${theme.themeName})...`).start();
96
- try {
97
- const { renderMarkdown } = await import("./renderer.js");
98
- const result = await renderMarkdown({
99
- markdown: md,
100
- themeName: theme.themeName,
101
- customCSS: theme.customCSS,
102
- title,
103
- });
104
- const { writeFileSync } = await import("node:fs");
105
- writeFileSync(outputPath, result.html, "utf-8");
106
- spinner.succeed(chalk.green(`Exported: ${outputPath}`));
88
+ // Resolve paths using shared utilities
89
+ const inputPath = resolveInputPath(input);
90
+ const title = getDocumentTitle(inputPath);
91
+ const outputPath = resolveOutputPath(inputPath, options.output, ".html");
92
+ // Read markdown content
93
+ const md = readFileSync(inputPath, "utf-8");
94
+ // Resolve theme with async API
95
+ const theme = await resolveTheme(options.theme);
96
+ // Render with progress indicator
97
+ const spinner = ora(`Rendering ${title} → HTML (${theme.themeName})...`).start();
98
+ try {
99
+ const { renderMarkdown } = await import("./renderer.js");
100
+ const result = await renderMarkdown({
101
+ markdown: md,
102
+ themeName: theme.themeName,
103
+ customCSS: theme.customCSS,
104
+ title,
105
+ });
106
+ const { writeFileSync } = await import("node:fs");
107
+ writeFileSync(outputPath, result.html, "utf-8");
108
+ spinner.succeed(chalk.green(`Exported: ${outputPath}`));
109
+ }
110
+ catch (renderErr) {
111
+ spinner.fail(chalk.red(`Export failed: ${renderErr.message}`));
112
+ throw new CLIError(`HTML rendering failed: ${renderErr.message}`, ErrorCode.RENDER_ERROR, renderErr);
113
+ }
107
114
  }
108
115
  catch (err) {
109
- spinner.fail(chalk.red(`Export failed: ${err.message}`));
110
- process.exit(1);
116
+ if (err instanceof CLIError) {
117
+ process.exit(err.code);
118
+ }
119
+ else {
120
+ console.error(chalk.red(err.message));
121
+ process.exit(ErrorCode.FILE_NOT_FOUND);
122
+ }
111
123
  }
112
124
  });
113
125
  }
@@ -121,40 +133,47 @@ function registerExportPDF(program) {
121
133
  .option("-o, --output <path>", "Output PDF file path")
122
134
  .option("--format <size>", "Page format: A4, Letter, A3", "A4")
123
135
  .action(async (input, options) => {
124
- const inputPath = isAbsolute(input) ? input : resolve(process.cwd(), input);
125
- if (!existsSync(inputPath)) {
126
- console.error(chalk.red(`File not found: ${inputPath}`));
127
- process.exit(1);
128
- }
129
- const md = readFileSync(inputPath, "utf-8");
130
- const title = basename(inputPath, ".md");
131
- const outputPath = options.output
132
- ? (isAbsolute(options.output) ? options.output : resolve(process.cwd(), options.output))
133
- : inputPath.replace(/\.md$/i, ".pdf");
134
- let theme;
135
136
  try {
136
- theme = resolveTheme(options.theme);
137
- }
138
- catch (err) {
139
- console.error(chalk.red(err.message));
140
- process.exit(1);
141
- }
142
- const spinner = ora(`Rendering ${basename(inputPath)} → PDF (${theme.themeName})...`).start();
143
- try {
144
- const { renderPDF } = await import("./renderer.js");
145
- const pdfBuffer = await renderPDF({
146
- markdown: md,
147
- themeName: theme.themeName,
148
- customCSS: theme.customCSS,
149
- title,
150
- }, { format: options.format });
151
- const { writeFileSync } = await import("node:fs");
152
- writeFileSync(outputPath, pdfBuffer);
153
- spinner.succeed(chalk.green(`Exported: ${outputPath}`));
137
+ // Resolve paths using shared utilities
138
+ const inputPath = resolveInputPath(input);
139
+ const title = getDocumentTitle(inputPath);
140
+ const outputPath = resolveOutputPath(inputPath, options.output, ".pdf");
141
+ // Read markdown content
142
+ const md = readFileSync(inputPath, "utf-8");
143
+ // Validate format option
144
+ const validFormats = ["A4", "Letter", "A3"];
145
+ if (!validFormats.includes(options.format ?? "")) {
146
+ throw new CLIError(`Invalid page format: "${options.format}". Valid formats: ${validFormats.join(", ")}`, ErrorCode.INVALID_INPUT);
147
+ }
148
+ // Resolve theme with async API
149
+ const theme = await resolveTheme(options.theme);
150
+ // Render PDF with progress indicator
151
+ const spinner = ora(`Rendering ${title} → PDF (${theme.themeName})...`).start();
152
+ try {
153
+ const { renderPDF } = await import("./renderer.js");
154
+ const pdfBuffer = await renderPDF({
155
+ markdown: md,
156
+ themeName: theme.themeName,
157
+ customCSS: theme.customCSS,
158
+ title,
159
+ }, { format: options.format });
160
+ const { writeFileSync } = await import("node:fs");
161
+ writeFileSync(outputPath, pdfBuffer);
162
+ spinner.succeed(chalk.green(`Exported: ${outputPath}`));
163
+ }
164
+ catch (renderErr) {
165
+ spinner.fail(chalk.red(`Export failed: ${renderErr.message}`));
166
+ throw new CLIError(`PDF rendering failed: ${renderErr.message}`, ErrorCode.RENDER_ERROR, renderErr);
167
+ }
154
168
  }
155
169
  catch (err) {
156
- spinner.fail(chalk.red(`Export failed: ${err.message}`));
157
- process.exit(1);
170
+ if (err instanceof CLIError) {
171
+ process.exit(err.code);
172
+ }
173
+ else {
174
+ console.error(chalk.red(err.message));
175
+ process.exit(ErrorCode.FILE_NOT_FOUND);
176
+ }
158
177
  }
159
178
  });
160
179
  }
@@ -168,90 +187,103 @@ function registerExport(program) {
168
187
  .option("-t, --theme <name>", "Theme name")
169
188
  .option("-d, --output-dir <dir>", "Output directory", ".")
170
189
  .action(async (inputs, options) => {
171
- // Resolve glob inputs (shell usually expands, but handle edge cases)
172
- const files = [];
173
- for (const input of inputs) {
174
- const p = isAbsolute(input) ? input : resolve(process.cwd(), input);
175
- if (existsSync(p)) {
176
- if (statSync(p).isDirectory()) {
177
- // Directory: include all .md files
178
- const dirFiles = readdirSync(p)
179
- .filter((f) => f.endsWith(".md"))
180
- .map((f) => join(p, f));
181
- files.push(...dirFiles);
182
- }
183
- else {
184
- files.push(p);
185
- }
186
- }
187
- else {
188
- console.log(chalk.yellow(`Skipping (not found): ${input}`));
189
- }
190
- }
191
- if (files.length === 0) {
192
- console.error(chalk.red("No valid input files found."));
193
- process.exit(1);
194
- }
195
- let theme;
196
- try {
197
- theme = resolveTheme(options.theme);
198
- }
199
- catch (err) {
200
- console.error(chalk.red(err.message));
201
- process.exit(1);
202
- }
203
- const outDir = isAbsolute(options.outputDir ?? ".")
204
- ? (options.outputDir ?? ".")
205
- : resolve(process.cwd(), options.outputDir ?? ".");
206
- const fmt = options.format ?? "html";
207
- // Ensure output directory exists
208
- if (!existsSync(outDir))
209
- mkdirSync(outDir, { recursive: true });
210
- console.log(chalk.bold(`\nBatch export: ${files.length} file(s) → ${fmt.toUpperCase()}`));
211
- console.log(chalk.dim(` Theme: ${theme.themeName}`));
212
- console.log(chalk.dim(` Output: ${outDir}/\n`));
213
- const renderer = new ColamdRenderer();
214
- let success = 0;
215
- let failed = 0;
216
190
  try {
217
- await renderer.init();
218
- for (const file of files) {
219
- const name = basename(file, ".md");
220
- const md = readFileSync(file, "utf-8");
221
- const outPath = join(outDir, `${name}.${fmt === "pdf" ? "pdf" : "html"}`);
222
- const spinner = ora(` ${name}.md`).start();
191
+ // Resolve glob inputs (shell usually expands, but handle edge cases)
192
+ const files = [];
193
+ for (const input of inputs) {
223
194
  try {
224
- const input = {
225
- markdown: md,
226
- themeName: theme.themeName,
227
- customCSS: theme.customCSS,
228
- title: name,
229
- };
230
- if (fmt === "pdf") {
231
- const pdfBuffer = await renderer.exportPDF(input);
232
- const { writeFileSync } = await import("node:fs");
233
- writeFileSync(outPath, pdfBuffer);
195
+ const p = resolveInputPath(input);
196
+ if (statSync(p).isDirectory()) {
197
+ // Directory: include all .md files
198
+ const dirFiles = readdirSync(p)
199
+ .filter((f) => f.endsWith(".md"))
200
+ .map((f) => join(p, f));
201
+ files.push(...dirFiles);
234
202
  }
235
203
  else {
236
- const result = await renderer.render(input);
237
- const { writeFileSync } = await import("node:fs");
238
- writeFileSync(outPath, result.html, "utf-8");
204
+ files.push(p);
239
205
  }
240
- spinner.succeed(`${name}.${fmt === "pdf" ? "pdf" : "html"}`);
241
- success++;
242
206
  }
243
- catch (err) {
244
- spinner.fail(`${name}.md — ${err.message}`);
245
- failed++;
207
+ catch {
208
+ console.log(chalk.yellow(`Skipping (not found): ${input}`));
209
+ }
210
+ }
211
+ if (files.length === 0) {
212
+ throw new CLIError("No valid input files found.", ErrorCode.FILE_NOT_FOUND);
213
+ }
214
+ // Resolve theme with async API
215
+ const theme = await resolveTheme(options.theme);
216
+ // Setup output directory
217
+ const outDir = resolve(process.cwd(), options.outputDir ?? ".");
218
+ const fmt = options.format ?? "html";
219
+ if (!["html", "pdf"].includes(fmt)) {
220
+ throw new CLIError(`Invalid format: "${fmt}". Supported formats: html, pdf`, ErrorCode.INVALID_INPUT);
221
+ }
222
+ // Ensure output directory exists
223
+ const { existsSync: dirExists } = await import("node:fs");
224
+ if (!dirExists(outDir))
225
+ mkdirSync(outDir, { recursive: true });
226
+ console.log(chalk.bold(`\nBatch export: ${files.length} file(s) → ${fmt.toUpperCase()}`));
227
+ console.log(chalk.dim(` Theme: ${theme.themeName}`));
228
+ console.log(chalk.dim(` Output: ${outDir}/\n`));
229
+ // Initialize renderer for batch processing
230
+ const renderer = new ColamdRenderer();
231
+ let success = 0;
232
+ let failed = 0;
233
+ try {
234
+ await renderer.init();
235
+ for (const file of files) {
236
+ const name = getDocumentTitle(file);
237
+ const md = readFileSync(file, "utf-8");
238
+ const outPath = join(outDir, `${name}.${fmt === "pdf" ? "pdf" : "html"}`);
239
+ const spinner = ora(` ${name}.md`).start();
240
+ try {
241
+ const input = {
242
+ markdown: md,
243
+ themeName: theme.themeName,
244
+ customCSS: theme.customCSS,
245
+ title: name,
246
+ };
247
+ if (fmt === "pdf") {
248
+ const pdfBuffer = await renderer.exportPDF(input);
249
+ const { writeFileSync } = await import("node:fs");
250
+ writeFileSync(outPath, pdfBuffer);
251
+ }
252
+ else {
253
+ const result = await renderer.render(input);
254
+ const { writeFileSync } = await import("node:fs");
255
+ writeFileSync(outPath, result.html, "utf-8");
256
+ }
257
+ spinner.succeed(`${name}.${fmt === "pdf" ? "pdf" : "html"}`);
258
+ success++;
259
+ }
260
+ catch (fileErr) {
261
+ spinner.fail(`${name}.md — ${fileErr.message}`);
262
+ failed++;
263
+ }
246
264
  }
247
265
  }
266
+ finally {
267
+ await renderer.close();
268
+ }
269
+ // Summary
270
+ console.log(chalk.bold(`\nDone: ${chalk.green(`${success} exported`)}`) +
271
+ (failed ? chalk.red(`, ${failed} failed`) : "") +
272
+ "\n");
273
+ if (failed > 0) {
274
+ throw new CLIError(`${failed} file(s) failed to export`, ErrorCode.RENDER_ERROR);
275
+ }
248
276
  }
249
- finally {
250
- await renderer.close();
277
+ catch (err) {
278
+ if (err instanceof CLIError) {
279
+ console.error(chalk.red(err.message));
280
+ process.exit(err.code);
281
+ }
282
+ else {
283
+ console.error(chalk.red(err.message));
284
+ process.exit(ErrorCode.UNKNOWN);
285
+ }
251
286
  }
252
- console.log(chalk.bold(`\nDone: ${chalk.green(`${success} exported`)}`) +
253
- (failed ? chalk.red(`, ${failed} failed`) : "") +
254
- "\n");
255
287
  });
256
288
  }
257
289
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"export-cli.js","sourceRoot":"","sources":["../src/export-cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"export-cli.js","sourceRoot":"","sources":["../src/export-cli.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,12 @@ import type { Extractor } from "./base.js";
19
19
  import { type ThemeStyle } from "../models.js";
20
20
  export declare class UrlExtractor implements Extractor {
21
21
  canHandle(source: string): boolean;
22
+ /**
23
+ * Validate URL to prevent SSRF attacks and ensure security.
24
+ * - Only allows http/https protocols
25
+ * - Blocks private network addresses (localhost, 10.x, 172.16-31.x, 192.168.x, 169.254.x)
26
+ */
27
+ private validateUrl;
22
28
  extract(source: string): Promise<ThemeStyle>;
23
29
  /**
24
30
  * 从页面标题或 URL 推断主题名称
@@ -25,11 +25,60 @@ export class UrlExtractor {
25
25
  canHandle(source) {
26
26
  return /^https?:\/\//i.test(source);
27
27
  }
28
+ /**
29
+ * Validate URL to prevent SSRF attacks and ensure security.
30
+ * - Only allows http/https protocols
31
+ * - Blocks private network addresses (localhost, 10.x, 172.16-31.x, 192.168.x, 169.254.x)
32
+ */
33
+ validateUrl(url) {
34
+ let parsed;
35
+ try {
36
+ parsed = new URL(url);
37
+ }
38
+ catch {
39
+ throw new Error(`Invalid URL format: ${url}`);
40
+ }
41
+ // Protocol whitelist
42
+ if (!["http:", "https:"].includes(parsed.protocol)) {
43
+ throw new Error(`Unsupported protocol "${parsed.protocol}". Only HTTP and HTTPS are allowed.`);
44
+ }
45
+ // Block private network ranges to prevent SSRF
46
+ const hostname = parsed.hostname.toLowerCase();
47
+ const isPrivate = hostname === "localhost" ||
48
+ hostname === "127.0.0.1" ||
49
+ hostname === "::1" ||
50
+ hostname === "[::1]" ||
51
+ hostname.startsWith("10.") ||
52
+ hostname.startsWith("172.16.") ||
53
+ hostname.startsWith("172.17.") ||
54
+ hostname.startsWith("172.18.") ||
55
+ hostname.startsWith("172.19.") ||
56
+ hostname.startsWith("172.20.") ||
57
+ hostname.startsWith("172.21.") ||
58
+ hostname.startsWith("172.22.") ||
59
+ hostname.startsWith("172.23.") ||
60
+ hostname.startsWith("172.24.") ||
61
+ hostname.startsWith("172.25.") ||
62
+ hostname.startsWith("172.26.") ||
63
+ hostname.startsWith("172.27.") ||
64
+ hostname.startsWith("172.28.") ||
65
+ hostname.startsWith("172.29.") ||
66
+ hostname.startsWith("172.30.") ||
67
+ hostname.startsWith("172.31.") ||
68
+ hostname.startsWith("192.168.") ||
69
+ hostname.startsWith("169.254.");
70
+ if (isPrivate) {
71
+ throw new Error(`Private network access denied: ${hostname}. Only public URLs are allowed for security reasons.`);
72
+ }
73
+ }
28
74
  async extract(source) {
75
+ this.validateUrl(source);
29
76
  const response = await axios.get(source, {
30
- headers: { "User-Agent": "ColaMD-Themes/1.0 (Theme Extractor)" },
77
+ headers: { "User-Agent": "Mozilla/5.0 (compatible; ColaMD-Themes/1.0)" },
31
78
  timeout: 15000,
32
- maxRedirects: 5,
79
+ maxRedirects: 3,
80
+ maxContentLength: 10 * 1024 * 1024,
81
+ responseType: "text",
33
82
  });
34
83
  const contentType = String(response.headers["content-type"] || "");
35
84
  if (!contentType.includes("text/html") && !contentType.includes("application/xhtml")) {