undraw-cli 0.1.1 → 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/dist/index.js CHANGED
@@ -1,127 +1,4 @@
1
1
  #!/usr/bin/env node
2
-
3
- // src/index.ts
4
- import { Command } from "commander";
5
- import fetch from "node-fetch";
6
- import fs from "fs/promises";
7
- import path from "path";
8
- import chalk from "chalk";
9
- import ora from "ora";
10
- var program = new Command();
11
- var DEFAULT_COLOR = "#6c63ff";
12
- var BASE_URL = "https://undraw.co";
13
- var CDN_URL = "https://cdn.undraw.co/illustration";
14
- var INVENTORY_PATH = path.resolve(process.cwd(), "undraw-inventory.json");
15
- async function getBuildId() {
16
- const response = await fetch(BASE_URL);
17
- const html = await response.text();
18
- const match = html.match(/"buildId":"([^"]+)"/);
19
- return match ? match[1] : null;
20
- }
21
- async function fetchIllustrationsPage(buildId, page) {
22
- const url = page === 1 ? `${BASE_URL}/_next/data/${buildId}/illustrations.json` : `${BASE_URL}/_next/data/${buildId}/illustrations/${page}.json?page=${page}`;
23
- const response = await fetch(url);
24
- if (!response.ok) return null;
25
- const data = await response.json();
26
- return data.pageProps.illustrations;
27
- }
28
- async function loadInventory() {
29
- try {
30
- const data = await fs.readFile(INVENTORY_PATH, "utf-8");
31
- return JSON.parse(data);
32
- } catch (_err) {
33
- return null;
34
- }
35
- }
36
- function printIllustrations(illustrations, title) {
37
- if (illustrations.length === 0) {
38
- console.log(chalk.red("No illustrations found."));
39
- return;
40
- }
41
- console.log(chalk.green(`
42
- ${title} (${illustrations.length}):`));
43
- console.log(chalk.gray("\u2500".repeat(50)));
44
- illustrations.forEach((i) => {
45
- console.log(
46
- `${chalk.bold((i.title || "Untitled").padEnd(30))} id: ${chalk.cyan(i.newSlug || i.slug)}`
47
- );
48
- });
49
- console.log(chalk.gray("\u2500".repeat(50)) + "\n");
50
- }
51
- program.name("undraw").description("CLI to search and customize unDraw illustrations").version("0.1.0");
52
- program.command("sync").description("Sync the full unDraw library to a local inventory file").action(async () => {
53
- const spinner = ora("Initializing sync...").start();
54
- try {
55
- const buildId = await getBuildId();
56
- if (!buildId) throw new Error("Could not find buildId");
57
- let allIllustrations = [];
58
- let page = 1;
59
- let hasMore = true;
60
- while (hasMore) {
61
- spinner.text = `Fetching page ${page}... (Total: ${allIllustrations.length})`;
62
- const illustrations = await fetchIllustrationsPage(buildId, page);
63
- if (!illustrations || illustrations.length === 0) {
64
- hasMore = false;
65
- } else {
66
- allIllustrations = [...allIllustrations, ...illustrations];
67
- page++;
68
- }
69
- }
70
- spinner.text = "Saving inventory...";
71
- await fs.writeFile(INVENTORY_PATH, JSON.stringify(allIllustrations, null, 2));
72
- spinner.succeed(
73
- chalk.green(`Synced ${allIllustrations.length} illustrations to ${INVENTORY_PATH}`)
74
- );
75
- } catch (_err) {
76
- spinner.fail(chalk.red(`Sync failed: ${_err.message}`));
77
- }
78
- });
79
- program.command("search").description("Search for illustrations by title").argument("<query>", "search query").action(async (query) => {
80
- const illustrations = await loadInventory();
81
- if (!illustrations) {
82
- console.log(chalk.yellow('Inventory not found. Please run "undraw sync" first.'));
83
- return;
84
- }
85
- const filtered = illustrations.filter(
86
- (i) => (i.title || "").toLowerCase().includes(query.toLowerCase())
87
- );
88
- printIllustrations(filtered, `Found ${filtered.length} matches for "${query}"`);
89
- });
90
- program.command("list").description("List illustrations from local inventory").option("-p, --page <number>", "page number", "1").option("-l, --limit <number>", "items per page", "20").action(async (options) => {
91
- const illustrations = await loadInventory();
92
- if (!illustrations) {
93
- console.log(chalk.yellow('Inventory not found. Please run "undraw sync" first.'));
94
- return;
95
- }
96
- const page = parseInt(options.page, 10);
97
- const limit = parseInt(options.limit, 10);
98
- const start = (page - 1) * limit;
99
- const end = start + limit;
100
- const paginated = illustrations.slice(start, end);
101
- const totalPages = Math.ceil(illustrations.length / limit);
102
- printIllustrations(paginated, `Inventory: Page ${page} of ${totalPages}`);
103
- if (page < totalPages) {
104
- console.log(chalk.gray(`Run 'undraw list --page ${page + 1}' for more...`));
105
- }
106
- });
107
- program.command("download").description("Download an illustration with a custom color").argument("<id>", "illustration id (e.g., astronomy_ied1)").option("-c, --color <hex>", "primary hex color", DEFAULT_COLOR).option("-o, --output <path>", "output file path", ".").action(async (id, options) => {
108
- const spinner = ora(`Downloading ${id}...`).start();
109
- try {
110
- const url = `${CDN_URL}/${id}.svg`;
111
- const response = await fetch(url);
112
- if (!response.ok) throw new Error(`Illustration not found: ${id}`);
113
- let svg = await response.text();
114
- if (options.color !== DEFAULT_COLOR) {
115
- spinner.text = `Applying color ${options.color}...`;
116
- svg = svg.split(DEFAULT_COLOR).join(options.color);
117
- }
118
- const filename = `${id}.svg`;
119
- const outputPath = path.resolve(options.output, filename);
120
- await fs.writeFile(outputPath, svg);
121
- spinner.succeed(chalk.green(`Saved to ${outputPath}`));
122
- } catch (err) {
123
- spinner.fail(chalk.red(`Error: ${err.message}`));
124
- }
125
- });
126
- program.parse();
127
- //# sourceMappingURL=index.js.map
2
+ import{Command as $}from"commander";import p from"node-fetch";import f from"fs/promises";import m from"path";import r from"chalk";import y from"ora";var l=new $,u="#6c63ff",d="https://undraw.co",v="https://cdn.undraw.co/illustration",g=m.resolve(process.cwd(),"undraw-inventory.json");async function I(){let n=(await(await p(d)).text()).match(/"buildId":"([^"]+)"/);return n?n[1]:null}async function b(t,o){let n=o===1?`${d}/_next/data/${t}/illustrations.json`:`${d}/_next/data/${t}/illustrations/${o}.json?page=${o}`,e=await p(n);return e.ok?(await e.json()).pageProps.illustrations:null}async function h(){try{let t=await f.readFile(g,"utf-8");return JSON.parse(t)}catch{return null}}function w(t,o){if(t.length===0){console.log(r.red("No illustrations found."));return}console.log(r.green(`
3
+ ${o} (${t.length}):`)),console.log(r.gray("\u2500".repeat(50))),t.forEach(n=>{console.log(`${r.bold((n[1]||"Untitled").padEnd(30))} id: ${r.cyan(n[0])}`)}),console.log(r.gray("\u2500".repeat(50))+`
4
+ `)}l.name("undraw").description("CLI to search and customize unDraw illustrations").version("0.1.1");l.command("sync").description("Sync the full unDraw library to a local inventory file").action(async()=>{let t=y("Initializing sync...").start();try{let o=await I();if(!o)throw new Error("Could not find buildId");let n=[],e=1,a=!0;for(;a;){t.text=`Fetching page ${e}... (Items: ${n.length})`;let s=await b(o,e);!s||s.length===0?a=!1:(s.forEach(i=>{n.push([i.newSlug,i.title])}),e++)}t.text="Saving inventory...",await f.writeFile(g,JSON.stringify(n)),t.succeed(r.green(`Synced ${n.length} illustrations to ${g}`))}catch(o){t.fail(r.red(`Sync failed: ${o.message}`))}});l.command("search").description("Search for illustrations by title").argument("<query>","search query").action(async t=>{let o=await h();if(!o){console.log(r.yellow('Inventory not found. Please run "undraw sync" first.'));return}let n=o.filter(e=>(e[1]||"").toLowerCase().includes(t.toLowerCase()));w(n,`Found ${n.length} matches for "${t}"`)});l.command("list").description("List illustrations from local inventory").option("-p, --page <number>","page number","1").option("-l, --limit <number>","items per page","20").action(async t=>{let o=await h();if(!o){console.log(r.yellow('Inventory not found. Please run "undraw sync" first.'));return}let n=parseInt(t.page,10),e=parseInt(t.limit,10),a=(n-1)*e,s=a+e,i=o.slice(a,s),c=Math.ceil(o.length/e);w(i,`Inventory: Page ${n} of ${c}`),n<c&&console.log(r.gray(`Run 'undraw list --page ${n+1}' for more...`))});l.command("download").description("Download an illustration with a custom color").argument("<id>","illustration id (e.g., astronomy_ied1)").option("-c, --color <hex>","primary hex color",u).option("-o, --output <path>","output file path",".").action(async(t,o)=>{let n=y(`Downloading ${t}...`).start();try{let e=`${v}/${t}.svg`,a=await p(e);if(!a.ok)throw new Error(`Illustration not found: ${t}`);let s=await a.text();o.color!==u&&(n.text=`Applying color ${o.color}...`,s=s.split(u).join(o.color));let i=`${t}.svg`,c=m.resolve(o.output,i);await f.writeFile(c,s),n.succeed(r.green(`Saved to ${c}`))}catch(e){n.fail(r.red(`Error: ${e.message}`))}});l.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "undraw-cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A CLI to search, customize, and download illustrations from undraw.co",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",