Skip to content

Repository files navigation

🎨 VectorStock CLI

Sanitize SVGs, auto-generate AI metadata, and export ready-to-upload packages for microstock marketplaces — from your terminal.

Test VectorStock CLI npm version License: MIT Node.js 20+

VectorStock CLI is a Node.js/TypeScript command-line tool for designers and developers who sell vector assets on Adobe Stock, Freepik, and Shutterstock. It sanitizes your SVGs to a marketplace-ready standard (flattens nested transforms, strips editor cruft, guarantees a valid viewBox), uses AI — local via Ollama, or OpenAI/Anthropic — to generate commercial titles and 30-50 SEO tags per asset, and exports the ZIP + CSV files each marketplace expects for bulk upload.

$ vector-stock run ./my-svgs --zip

→ Sanitizing SVGs from "./my-svgs" -> "./vectorstock-output/sanitized"
done  coffee-cup.svg (44% smaller, viewBox added)
done  mountain-icon.svg (61% smaller, viewBox added)
info  Manifest written (2 sanitized asset(s), 0 failed).
→ Generating AI metadata via "ollama" for 2 asset(s)
done  coffee-cup.svg: "Hand-drawn coffee cup with steam, flat vector icon" (32 tags)
done  mountain-icon.svg: "Minimalist mountain range line icon" (35 tags)
→ Exporting CSV metadata for: adobe-stock, shutterstock, freepik
done  Wrote ./vectorstock-output/adobe-stock.csv
done  Wrote ./vectorstock-output/shutterstock.csv
done  Wrote ./vectorstock-output/freepik.csv
→ Packaging 2 asset(s) into "./vectorstock-output/vectorstock-package.zip"
done  Wrote ./vectorstock-output/vectorstock-package.zip
done  Pipeline complete.

Why use it

  • From 2 hours to 10 seconds. Tagging 100 SVGs by hand for three different marketplaces is the single most tedious part of selling vector assets. One command replaces it.
  • Real sanitization, not a linter. Built on SVGO with a preset tuned for stock submissions: nested <g transform> chains collapse to a single, minimal transform (or disappear entirely when possible), editor metadata/comments are stripped, and a missing viewBox is safely derived from width/height rather than silently dropped.
  • AI tagging with a local-first option. Point it at a local Ollama model and generate metadata with zero API cost and no data leaving your machine — or use OpenAI/Anthropic when you want a stronger model.
  • Never blocks on AI. If Ollama isn't running or an API key is missing, tagging degrades to deterministic, structure-derived metadata (filename, detected shapes, color palette, aspect ratio) instead of failing your whole batch — you still get a usable result, clearly flagged as a fallback.
  • The exact CSV shape each marketplace expects. Adobe Stock, Shutterstock, and Freepik each require different column layouts — VectorStock CLI ships one exporter per marketplace instead of a generic "keywords" dump.
  • Solid error handling. Malformed SVGs, unreachable AI providers, missing config keys, and empty batches all fail with a specific, actionable message — never a silent no-op or a stack trace.

Install & quick start

No install needed — run it directly with npx:

npx vector-stock-cli init                 # writes .stockrc.json in the current directory
npx vector-stock-cli sanitize ./my-svgs   # clean + validate SVGs
npx vector-stock-cli tag                  # AI-generate titles & tags
npx vector-stock-cli export               # write CSVs for your configured marketplaces
npx vector-stock-cli package              # bundle everything into a ZIP

Or run the whole pipeline in one command:

npx vector-stock-cli run ./my-svgs --zip --marketplaces adobe-stock,shutterstock

Prefer a local install? npm install --save-dev vector-stock-cli and use the vector-stock bin the same way.

Commands

Command Description
vector-stock init [--force] Writes a .stockrc.json config file in the current directory.
vector-stock sanitize <input> Cleans and validates SVGs, writing sanitized copies + a manifest.
vector-stock tag [--force] Generates AI titles/tags for the manifest's assets (--force re-tags assets that already have metadata).
vector-stock export [-m <list>] Writes marketplace CSV(s) from the manifest.
vector-stock package Bundles sanitized assets (+ any matching .eps/.png sidecar files) into a ZIP.
vector-stock run <input> [--zip] [-m <list>] Runs sanitize → tag → export → (optionally) package in one command.

Every command accepts -c, --config <path> to use a config file other than ./.stockrc.json.

Configuration (.stockrc.json)

{
  "aiProvider": "ollama",
  "ollama": { "host": "http://localhost:11434", "model": "llama3.1", "timeoutMs": 30000 },
  "openai": { "model": "gpt-4o-mini", "apiKeyEnvVar": "OPENAI_API_KEY", "timeoutMs": 30000 },
  "anthropic": { "model": "claude-3-5-haiku-latest", "apiKeyEnvVar": "ANTHROPIC_API_KEY", "timeoutMs": 30000 },
  "tags": { "min": 30, "max": 50 },
  "title": { "maxLength": 200 },
  "marketplaces": ["adobe-stock", "shutterstock", "freepik"],
  "output": {
    "sanitizedDir": "./vectorstock-output/sanitized",
    "manifestFile": "./vectorstock-output/manifest.json",
    "zipFile": "./vectorstock-output/vectorstock-package.zip",
    "csvDir": "./vectorstock-output"
  },
  "sanitizer": { "precision": 3, "removeTextElements": false }
}

Switch aiProvider to "openai" or "anthropic" to use a hosted model instead of Ollama — set the corresponding API key in the environment variable named by apiKeyEnvVar (OPENAI_API_KEY / ANTHROPIC_API_KEY by default).

Supported marketplaces

Marketplace CSV columns
Adobe Stock Filename, Title, Keywords, Category, Releases
Shutterstock Filename, Description, Keywords, Categories, Editorial, Mature content, Illustration
Freepik File name, Title, Keywords

Column layouts follow each marketplace's publicly documented contributor bulk-metadata CSV template at the time of writing. Marketplaces occasionally revise their required columns — always verify against the current template in your contributor dashboard before a large bulk upload.

How sanitization works

  1. Optimize — runs SVGO with convertTransform + collapseGroups to collapse nested transform chains into a single, minimal transform (or eliminate it entirely for single-child groups), strips comments/metadata/editor namespaces, and rounds path precision without visibly degrading curves.
  2. Validate the viewBox — a missing viewBox is derived from width/height when both are present; when neither is usable, sanitization fails loudly for that file rather than guessing.
  3. Flag what it can't safely auto-fix — embedded raster <image> data and live <text> elements are flagged as warnings (most marketplaces require text outlined to paths, which needs a font-aware vector editor, not a CLI heuristic). Set sanitizer.removeTextElements: true to strip <text> automatically instead of just flagging it.

How AI tagging works

VectorStock CLI does not perform computer vision on your artwork. Instead, it extracts a structural fingerprint directly from the sanitized SVG's markup — shape composition (circle×3, path×12, ...), the dominant colors actually used in fill/stroke, viewBox aspect ratio, gradient presence, and overall complexity — combines it with a filename-derived hint, and sends that structured summary to your configured LLM with a prompt asking for a commercial title and a 30-50 keyword list. This is honest about what it is: a strong, real signal for inferring subject matter without requiring a vision model or any GPU, while staying fast and free to run locally via Ollama.

Contributing

Issues and pull requests are welcome. Before opening a PR:

npm install
npm run typecheck   # tsc --noEmit
npm test            # vitest run — unit tests for the sanitizer, structural analyzer, tagger, and CSV exporters
npm run build       # compiles src/ to dist/

Please add or update a test for any behavior change — the sanitizer, structural analyzer, and CSV exporters are all covered by real fixtures (actual SVG markup, actual parsed output), not mocks, and new marketplace exporters or sanitizer rules should follow that pattern.

Project layout

vector-stock-cli/
├── bin/vector-stock.js          # Stable CLI entry point (requires dist/cli.js)
├── src/
│   ├── cli.ts                   # Commander command definitions
│   ├── types.ts                 # Shared types
│   ├── config/                  # .stockrc.json loading + validation
│   ├── sanitizer/svg.ts         # SVGO-based cleanup, viewBox repair, warnings
│   ├── analyzer/structural.ts   # Structural fingerprint extraction (shapes, colors, complexity)
│   ├── ai/tagger.ts             # Ollama / OpenAI / Anthropic metadata generation + fallback
│   ├── exporters/csv.ts         # Per-marketplace CSV templates
│   ├── packager/zip.ts          # ZIP packaging (+ .eps/.png sidecar bundling)
│   └── utils/                   # Logging, manifest read/write
├── tests/                       # vitest unit tests
├── .stockrc.json.example
└── .github/workflows/test.yml   # Typecheck, test, build, and an end-to-end CLI smoke test

License

MIT

About

Sanitize SVGs, auto-generate AI metadata (Ollama/OpenAI/Anthropic), and export ready-to-upload ZIP+CSV packages for Adobe Stock, Freepik, and Shutterstock.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages