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 +3 -126
- package/package.json +1 -1
- package/undraw-inventory.json +1 -9902
- package/dist/index.js.map +0 -1
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport fetch from 'node-fetch';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport chalk from 'chalk';\nimport ora from 'ora';\n\nconst program = new Command();\n\nconst DEFAULT_COLOR = '#6c63ff';\nconst BASE_URL = 'https://undraw.co';\nconst CDN_URL = 'https://cdn.undraw.co/illustration';\nconst INVENTORY_PATH = path.resolve(process.cwd(), 'undraw-inventory.json');\n\nasync function getBuildId() {\n const response = await fetch(BASE_URL);\n const html = await response.text();\n const match = html.match(/\"buildId\":\"([^\"]+)\"/);\n return match ? match[1] : null;\n}\n\nasync function fetchIllustrationsPage(buildId: string, page: number) {\n // Pattern discovered:\n // Page 1: https://undraw.co/_next/data/[BUILD_ID]/illustrations.json\n // Page 2+: https://undraw.co/_next/data/[BUILD_ID]/illustrations/[PAGE].json?page=[PAGE]\n const url =\n page === 1\n ? `${BASE_URL}/_next/data/${buildId}/illustrations.json`\n : `${BASE_URL}/_next/data/${buildId}/illustrations/${page}.json?page=${page}`;\n const response = await fetch(url);\n if (!response.ok) return null;\n const data = (await response.json()) as any;\n return data.pageProps.illustrations;\n}\n\nasync function loadInventory() {\n try {\n const data = await fs.readFile(INVENTORY_PATH, 'utf-8');\n return JSON.parse(data);\n } catch (_err) {\n return null;\n }\n}\n\nfunction printIllustrations(illustrations: any[], title: string) {\n if (illustrations.length === 0) {\n console.log(chalk.red('No illustrations found.'));\n return;\n }\n\n console.log(chalk.green(`\\n${title} (${illustrations.length}):`));\n console.log(chalk.gray('─'.repeat(50)));\n illustrations.forEach((i: any) => {\n console.log(\n `${chalk.bold((i.title || 'Untitled').padEnd(30))} id: ${chalk.cyan(i.newSlug || i.slug)}`\n );\n });\n console.log(chalk.gray('─'.repeat(50)) + '\\n');\n}\n\nprogram\n .name('undraw')\n .description('CLI to search and customize unDraw illustrations')\n .version('0.1.0');\n\nprogram\n .command('sync')\n .description('Sync the full unDraw library to a local inventory file')\n .action(async () => {\n const spinner = ora('Initializing sync...').start();\n try {\n const buildId = await getBuildId();\n if (!buildId) throw new Error('Could not find buildId');\n\n let allIllustrations: any[] = [];\n let page = 1;\n let hasMore = true;\n\n while (hasMore) {\n spinner.text = `Fetching page ${page}... (Total: ${allIllustrations.length})`;\n const illustrations = await fetchIllustrationsPage(buildId, page);\n\n if (!illustrations || illustrations.length === 0) {\n hasMore = false;\n } else {\n allIllustrations = [...allIllustrations, ...illustrations];\n page++;\n }\n }\n\n spinner.text = 'Saving inventory...';\n await fs.writeFile(INVENTORY_PATH, JSON.stringify(allIllustrations, null, 2));\n spinner.succeed(\n chalk.green(`Synced ${allIllustrations.length} illustrations to ${INVENTORY_PATH}`)\n );\n } catch (_err: any) {\n spinner.fail(chalk.red(`Sync failed: ${_err.message}`));\n }\n });\n\nprogram\n .command('search')\n .description('Search for illustrations by title')\n .argument('<query>', 'search query')\n .action(async (query: string) => {\n const illustrations = await loadInventory();\n if (!illustrations) {\n console.log(chalk.yellow('Inventory not found. Please run \"undraw sync\" first.'));\n return;\n }\n\n const filtered = illustrations.filter((i: any) =>\n (i.title || '').toLowerCase().includes(query.toLowerCase())\n );\n\n printIllustrations(filtered, `Found ${filtered.length} matches for \"${query}\"`);\n });\n\nprogram\n .command('list')\n .description('List illustrations from local inventory')\n .option('-p, --page <number>', 'page number', '1')\n .option('-l, --limit <number>', 'items per page', '20')\n .action(async (options) => {\n const illustrations = await loadInventory();\n if (!illustrations) {\n console.log(chalk.yellow('Inventory not found. Please run \"undraw sync\" first.'));\n return;\n }\n\n const page = parseInt(options.page, 10);\n const limit = parseInt(options.limit, 10);\n const start = (page - 1) * limit;\n const end = start + limit;\n const paginated = illustrations.slice(start, end);\n const totalPages = Math.ceil(illustrations.length / limit);\n\n printIllustrations(paginated, `Inventory: Page ${page} of ${totalPages}`);\n\n if (page < totalPages) {\n console.log(chalk.gray(`Run 'undraw list --page ${page + 1}' for more...`));\n }\n });\n\nprogram\n .command('download')\n .description('Download an illustration with a custom color')\n .argument('<id>', 'illustration id (e.g., astronomy_ied1)')\n .option('-c, --color <hex>', 'primary hex color', DEFAULT_COLOR)\n .option('-o, --output <path>', 'output file path', '.')\n .action(async (id, options) => {\n const spinner = ora(`Downloading ${id}...`).start();\n try {\n const url = `${CDN_URL}/${id}.svg`;\n const response = await fetch(url);\n if (!response.ok) throw new Error(`Illustration not found: ${id}`);\n\n let svg = await response.text();\n\n if (options.color !== DEFAULT_COLOR) {\n spinner.text = `Applying color ${options.color}...`;\n svg = svg.split(DEFAULT_COLOR).join(options.color);\n }\n\n const filename = `${id}.svg`;\n const outputPath = path.resolve(options.output, filename);\n\n await fs.writeFile(outputPath, svg);\n spinner.succeed(chalk.green(`Saved to ${outputPath}`));\n } catch (err: any) {\n spinner.fail(chalk.red(`Error: ${err.message}`));\n }\n });\n\nprogram.parse();\n"],"mappings":"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","names":[]}
|