@iconia/react 0.1.0-dev.52c1e49 → 0.1.0-dev.f643e57

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 (2) hide show
  1. package/dist/cli/index.js +11 -11
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{Command as eo}from"commander";import{Command as Ro}from"commander";import T from"fs";import Uo from"path";import z from"picocolors";var Lo=`import type { IconiaConfig } from 'iconia';
2
+ import{Command as Zo}from"commander";import{Command as Ro}from"commander";import T from"fs";import Uo from"path";import q from"picocolors";var Lo=`import type { IconiaConfig } from '@iconia/react';
3
3
 
4
4
  const config: IconiaConfig = {
5
5
  apiKey: process.env.ICONIA_API_KEY ?? '',
@@ -7,18 +7,18 @@ const config: IconiaConfig = {
7
7
  };
8
8
 
9
9
  export default config;
10
- `,X=new Ro("init").description("Create an iconia.config.ts file in the current directory").action(()=>{let o=Uo.resolve(process.cwd(),"iconia.config.ts");if(T.existsSync(o)){console.log(z.yellow("iconia.config.ts already exists. Skipping."));return}T.writeFileSync(o,Lo),console.log(z.green("✓ Created iconia.config.ts")),console.log(`
11
- Next steps:`),console.log(` 1. Set ${z.cyan("ICONIA_API_KEY")} in your environment`),console.log(` 2. Edit ${z.cyan("iconia.config.ts")} to add your collections`),console.log(` 3. Run ${z.cyan("npx iconia pull")} to fetch icons`),console.log(`
12
- Import icons: ${z.cyan("import { MyIcon } from 'iconia/my-collection'")}`)});import{Command as qo}from"commander";import H from"picocolors";import zo from"ora";import{z as Q}from"zod";import N from"path";var Co=Q.object({apiKey:Q.string().min(1,"apiKey is required"),collections:Q.array(Q.string()).min(1,"At least one collection is required")}),Eo="https://api.iconia.io";async function E(){let o=N.resolve(process.cwd(),"iconia.config.ts"),i=N.resolve(process.cwd(),"iconia.config.js"),r;try{let c=await import(o);r=c.default??c}catch{try{let c=await import(i);r=c.default??c}catch{throw Error("Could not find iconia.config.ts or iconia.config.js\nRun `npx iconia init` to create one.")}}let n=Co.safeParse(r);if(!n.success){let c=n.error.issues.map((t)=>` - ${t.path.join(".")}: ${t.message}`).join(`
10
+ `,X=new Ro("init").description("Create an iconia.config.ts file in the current directory").action(()=>{let o=Uo.resolve(process.cwd(),"iconia.config.ts");if(T.existsSync(o)){console.log(q.yellow("iconia.config.ts already exists. Skipping."));return}T.writeFileSync(o,Lo),console.log(q.green("✓ Created iconia.config.ts")),console.log(`
11
+ Next steps:`),console.log(` 1. Set ${q.cyan("ICONIA_API_KEY")} in your environment`),console.log(` 2. Edit ${q.cyan("iconia.config.ts")} to add your collections`),console.log(` 3. Run ${q.cyan("npx iconia pull")} to fetch icons`),console.log(`
12
+ Import icons: ${q.cyan("import { MyIcon } from '@iconia/react/my-collection'")}`)});import{Command as eo}from"commander";import b from"picocolors";import qo from"ora";import{z as p}from"zod";import N from"path";var Co=p.object({apiKey:p.string().min(1,"apiKey is required"),collections:p.array(p.string()).min(1,"At least one collection is required")}),Eo="https://api.iconia.io";async function E(){let o=N.resolve(process.cwd(),"iconia.config.ts"),i=N.resolve(process.cwd(),"iconia.config.js"),r;try{let c=await import(o);r=c.default??c}catch{try{let c=await import(i);r=c.default??c}catch{throw Error("Could not find iconia.config.ts or iconia.config.js\nRun `npx @iconia/react init` to create one.")}}let n=Co.safeParse(r);if(!n.success){let c=n.error.issues.map((t)=>` - ${t.path.join(".")}: ${t.message}`).join(`
13
13
  `);throw Error(`Invalid iconia config:
14
- ${c}`)}return{...n.data,apiUrl:Eo}}function h(o){return{Authorization:`ApiKey ${o.apiKey}`,"Content-Type":"application/json"}}async function D(o){let i=await fetch(new URL("/v1/collections",o.apiUrl).toString(),{headers:h(o)});if(!i.ok){let n=await i.json().catch(()=>({}));throw Error(`API error ${i.status}: ${n.error??i.statusText}`)}return(await i.json()).collections}async function J(o,i){let r=new URL("/v1/collections/icons",o.apiUrl);r.searchParams.set("collections",i.join(","));let n=await fetch(r.toString(),{headers:h(o)});if(!n.ok){let t=await n.json().catch(()=>({}));throw Error(`API error ${n.status}: ${t.error??n.statusText}`)}return(await n.json()).icons}async function l(o,i){let r=await fetch(new URL("/v1/icons",o.apiUrl).toString(),{method:"POST",headers:h(o),body:JSON.stringify(i)});if(!r.ok){let c=await r.json().catch(()=>({}));throw Error(c.error??r.statusText)}return(await r.json()).icon}import u from"fs";import q from"path";import{fileURLToPath as Ko}from"url";import _o from"picocolors";import{optimize as so}from"svgo";function uo(o){return so(o,{plugins:["removeDoctype","removeXMLProcInst","removeComments","removeMetadata","removeTitle","removeDesc"]}).data.replace(/<svg([^>]*)>/i,(r,n)=>`<svg${n.replace(/\s+(width|height)=['"][^'"]*['"]/gi,"")}>`)}function x(o){let i={},r=/([\w:-]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/g,n;while((n=r.exec(o))!==null){let c=n[1].replace(/^xlink:/,"").replace(/-([a-z])/g,(t,a)=>a.toUpperCase());i[c]=n[2]??n[3]??""}return i}function g(o){let i=[],r=0;while(r<o.length){let n=o.indexOf("<",r);if(n===-1)break;let c=o[n+1];if(c==="/"||c==="!"||c==="?"){let j=o.indexOf(">",n);r=j===-1?o.length:j+1;continue}let t=n+1,a=!1,m="";while(t<o.length){let j=o[t];if(a){if(j===m)a=!1}else if(j==='"'||j==="'")a=!0,m=j;else if(j===">")break;t++}if(t>=o.length)break;let I=o.slice(n+1,t),f=I.trimEnd().endsWith("/"),w=f?I.slice(0,I.lastIndexOf("/")).trim():I.trim(),y=w.search(/\s/),$=y===-1?w:w.slice(0,y);if(!$){r=t+1;continue}let L=y===-1?"":w.slice(y+1),O=x(L);if(r=t+1,f)i.push([$,O]);else{let j=`<${$}`,V=`</${$}>`,F=1,R=r;while(F>0&&R<o.length){let C=o.indexOf(j,R),d=o.indexOf(V,R);if(d===-1)break;if(C!==-1&&C<d)F++,R=C+j.length;else if(F--,F===0){let jo=o.slice(r,d),G=g(jo),Fo=G.length>0?[$,O,G]:[$,O];i.push(Fo),r=d+V.length}else R=d+V.length}if(F>0)i.push([$,O])}}return i}function oo(o){let i=uo(o),r=i.match(/<svg([^>]*)>/i),n=x(r?.[1]??"");delete n.xmlns,delete n.xmlnsXlink;let{viewBox:c}=n,t=c?{viewBox:c}:{},m=i.match(/<svg[^>]*>([\s\S]*)<\/svg>/i)?.[1]?.trim()??"";return{iconNode:g(m),svgAttrs:t}}function v(o){return o.replace(/[-_\s]+(.)/g,(i,r)=>r.toUpperCase()).replace(/^(.)/,(i,r)=>r.toUpperCase())}function io(o){if(o.length===0)return"";let i=["import { forwardRef, createElement } from 'react';","","const _r = (n) => n.map(([t, a, c], i) => createElement(t, { key: i, ...a }, ...(c ? _r(c) : [])));",""];for(let{name:r,iconNode:n,svgAttrs:c}of o){let t=v(r),a={viewBox:"0 0 24 24",...c},m=JSON.stringify(n),I=JSON.stringify(a);i.push(`export const ${t} = /*#__PURE__*/forwardRef(({ children, ...props }, ref) =>`,` createElement('svg', { ref, xmlns: 'http://www.w3.org/2000/svg', ...${I}, ...props },`,` ..._r(${m}),`," children"," )",");",`${t}.displayName = '${t}';`,"")}return i.join(`
15
- `)}function ro(o){let i=["import type { ForwardRefExoticComponent, SVGProps, RefAttributes } from 'react';","","type IconComponent = ForwardRefExoticComponent<SVGProps<SVGSVGElement> & RefAttributes<SVGSVGElement>>;",""];for(let r of o)i.push(`export declare const ${v(r)}: IconComponent;`);return i.push(""),i.join(`
16
- `)}function B(){return q.resolve(q.dirname(Ko(import.meta.url)),"..")}function Y(o,i){let r=[];for(let c of i)try{let{iconNode:t,svgAttrs:a}=oo(c.svgContent);r.push({name:c.name,iconNode:t,svgAttrs:a})}catch(t){console.warn(_o.yellow(` ⚠ Skipped ${c.name}: ${t.message}`))}if(r.length===0)return 0;let n=B();return u.writeFileSync(q.join(n,`${o}.js`),io(r),"utf-8"),u.writeFileSync(q.join(n,`${o}.d.ts`),ro(r.map((c)=>c.name)),"utf-8"),r.length}function Z(){let o=q.join(B(),"..","package.json");try{let i=JSON.parse(u.readFileSync(o,"utf-8")),r=i.exports??{};if(r["./*"]?.import?.startsWith("./dist/"))return;i.exports={".":r["."]??{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/index.cjs"},"./*":{import:"./dist/*.js",types:"./dist/*.d.ts"}},u.writeFileSync(o,JSON.stringify(i,null,2)+`
17
- `,"utf-8")}catch{}}function no(o){let i=B(),r=q.join(i,`${o}.js`),n=q.join(i,`${o}.d.ts`);if(u.existsSync(r))u.unlinkSync(r);if(u.existsSync(n))u.unlinkSync(n)}import co from"fs";import Oo from"path";var Vo=".iconia-lock.json";function to(){return Oo.resolve(process.cwd(),Vo)}function K(){try{let o=co.readFileSync(to(),"utf-8");return JSON.parse(o)}catch{return{version:1,collections:{}}}}function _(o){co.writeFileSync(to(),JSON.stringify(o,null,2),"utf-8")}function A(o,i,r){return{...o,collections:{...o.collections,[i]:{icons:Object.fromEntries(r.map((n)=>[n.slug,n.fingerprint]))}}}}function fo(o,i){let{[i]:r,...n}=o.collections;return{...o,collections:n}}var mo=new qo("pull").description("Fetch icons and regenerate all collection files (replaces existing)").option("-c, --collection <slug>","Pull only this collection").action(async(o)=>{let i=zo("Loading config...").start(),r;try{r=await E()}catch(f){i.fail(H.red(f.message)),process.exit(1)}let n=o.collection?[o.collection]:r.collections;if(o.collection&&!r.collections.includes(o.collection))i.fail(H.red(`Collection '${o.collection}' is not in your config.`)),process.exit(1);i.text=`Fetching icons for ${n.join(", ")}...`;let c;try{c=await J(r,n)}catch(f){i.fail(H.red(`Failed to fetch icons: ${f.message}`)),process.exit(1)}if(c.length===0){i.warn(H.yellow("No icons found."));return}i.text=`Generating ${c.length} icon${c.length!==1?"s":""}...`;let t=new Map;for(let f of c){let w=t.get(f.collectionSlug)??[];w.push(f),t.set(f.collectionSlug,w)}let a=K(),m=0,I=[];for(let[f,w]of t){let y=Y(f,w);if(y===0)continue;m+=y,I.push(f),a=A(a,f,w.map(($)=>({slug:$.slug,fingerprint:$.fingerprint})))}if(_(a),Z(),i.succeed(H.green(`Generated ${m} icon${m!==1?"s":""} across ${I.length} collection${I.length!==1?"s":""}`)),I.length>0){let f=I[0]??"",w=v(t.get(f)?.[0]?.name??"MyIcon");console.log(`
14
+ ${c}`)}return{...n.data,apiUrl:Eo}}function h(o){return{Authorization:`ApiKey ${o.apiKey}`,"Content-Type":"application/json"}}async function D(o){let i=await fetch(new URL("/v1/collections",o.apiUrl).toString(),{headers:h(o)});if(!i.ok){let n=await i.json().catch(()=>({}));throw Error(`API error ${i.status}: ${n.error??i.statusText}`)}return(await i.json()).collections}async function z(o,i){let r=new URL("/v1/collections/icons",o.apiUrl);r.searchParams.set("collections",i.join(","));let n=await fetch(r.toString(),{headers:h(o)});if(!n.ok){let t=await n.json().catch(()=>({}));throw Error(`API error ${n.status}: ${t.error??n.statusText}`)}return(await n.json()).icons}async function l(o,i){let r=await fetch(new URL("/v1/icons",o.apiUrl).toString(),{method:"POST",headers:h(o),body:JSON.stringify(i)});if(!r.ok){let c=await r.json().catch(()=>({}));throw Error(c.error??r.statusText)}return(await r.json()).icon}import u from"fs";import e from"path";import{fileURLToPath as Ko}from"url";import _o from"picocolors";import{optimize as so}from"svgo";function uo(o){return so(o,{plugins:["removeDoctype","removeXMLProcInst","removeComments","removeMetadata","removeTitle","removeDesc"]}).data.replace(/<svg([^>]*)>/i,(r,n)=>`<svg${n.replace(/\s+(width|height)=['"][^'"]*['"]/gi,"")}>`)}function x(o){let i={},r=/([\w:-]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/g,n;while((n=r.exec(o))!==null){let c=n[1].replace(/^xlink:/,"").replace(/-([a-z])/g,(t,a)=>a.toUpperCase());i[c]=n[2]??n[3]??""}return i}function g(o){let i=[],r=0;while(r<o.length){let n=o.indexOf("<",r);if(n===-1)break;let c=o[n+1];if(c==="/"||c==="!"||c==="?"){let j=o.indexOf(">",n);r=j===-1?o.length:j+1;continue}let t=n+1,a=!1,m="";while(t<o.length){let j=o[t];if(a){if(j===m)a=!1}else if(j==='"'||j==="'")a=!0,m=j;else if(j===">")break;t++}if(t>=o.length)break;let I=o.slice(n+1,t),f=I.trimEnd().endsWith("/"),w=f?I.slice(0,I.lastIndexOf("/")).trim():I.trim(),y=w.search(/\s/),$=y===-1?w:w.slice(0,y);if(!$){r=t+1;continue}let L=y===-1?"":w.slice(y+1),O=x(L);if(r=t+1,f)i.push([$,O]);else{let j=`<${$}`,V=`</${$}>`,F=1,R=r;while(F>0&&R<o.length){let C=o.indexOf(j,R),d=o.indexOf(V,R);if(d===-1)break;if(C!==-1&&C<d)F++,R=C+j.length;else if(F--,F===0){let jo=o.slice(r,d),G=g(jo),Fo=G.length>0?[$,O,G]:[$,O];i.push(Fo),r=d+V.length}else R=d+V.length}if(F>0)i.push([$,O])}}return i}function oo(o){let i=uo(o),r=i.match(/<svg([^>]*)>/i),n=x(r?.[1]??"");delete n.xmlns,delete n.xmlnsXlink;let{viewBox:c}=n,t=c?{viewBox:c}:{},m=i.match(/<svg[^>]*>([\s\S]*)<\/svg>/i)?.[1]?.trim()??"";return{iconNode:g(m),svgAttrs:t}}function J(o){return o.replace(/[-_\s]+(.)/g,(i,r)=>r.toUpperCase()).replace(/^(.)/,(i,r)=>r.toUpperCase())}function io(o){if(o.length===0)return"";let i=["import { forwardRef, createElement } from 'react';","","const _r = (n) => n.map(([t, a, c], i) => createElement(t, { key: i, ...a }, ...(c ? _r(c) : [])));",""];for(let{name:r,iconNode:n,svgAttrs:c}of o){let t=J(r),a={viewBox:"0 0 24 24",...c},m=JSON.stringify(n),I=JSON.stringify(a);i.push(`export const ${t} = /*#__PURE__*/forwardRef(({ children, ...props }, ref) =>`,` createElement('svg', { ref, xmlns: 'http://www.w3.org/2000/svg', ...${I}, ...props },`,` ..._r(${m}),`," children"," )",");",`${t}.displayName = '${t}';`,"")}return i.join(`
15
+ `)}function ro(o){let i=["import type { ForwardRefExoticComponent, SVGProps, RefAttributes } from 'react';","","type IconComponent = ForwardRefExoticComponent<SVGProps<SVGSVGElement> & RefAttributes<SVGSVGElement>>;",""];for(let r of o)i.push(`export declare const ${J(r)}: IconComponent;`);return i.push(""),i.join(`
16
+ `)}function B(){return e.resolve(e.dirname(Ko(import.meta.url)),"..")}function v(o,i){let r=[];for(let c of i)try{let{iconNode:t,svgAttrs:a}=oo(c.svgContent);r.push({name:c.name,iconNode:t,svgAttrs:a})}catch(t){console.warn(_o.yellow(` ⚠ Skipped ${c.name}: ${t.message}`))}if(r.length===0)return 0;let n=B();return u.writeFileSync(e.join(n,`${o}.js`),io(r),"utf-8"),u.writeFileSync(e.join(n,`${o}.d.ts`),ro(r.map((c)=>c.name)),"utf-8"),r.length}function Q(){let o=e.join(B(),"..","package.json");try{let i=JSON.parse(u.readFileSync(o,"utf-8")),r=i.exports??{};if(r["./*"]?.import?.startsWith("./dist/"))return;i.exports={".":r["."]??{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/index.cjs"},"./*":{import:"./dist/*.js",types:"./dist/*.d.ts"}},u.writeFileSync(o,JSON.stringify(i,null,2)+`
17
+ `,"utf-8")}catch{}}function no(o){let i=B(),r=e.join(i,`${o}.js`),n=e.join(i,`${o}.d.ts`);if(u.existsSync(r))u.unlinkSync(r);if(u.existsSync(n))u.unlinkSync(n)}import co from"fs";import Oo from"path";var Vo=".iconia-lock.json";function to(){return Oo.resolve(process.cwd(),Vo)}function K(){try{let o=co.readFileSync(to(),"utf-8");return JSON.parse(o)}catch{return{version:1,collections:{}}}}function _(o){co.writeFileSync(to(),JSON.stringify(o,null,2),"utf-8")}function Y(o,i,r){return{...o,collections:{...o.collections,[i]:{icons:Object.fromEntries(r.map((n)=>[n.slug,n.fingerprint]))}}}}function fo(o,i){let{[i]:r,...n}=o.collections;return{...o,collections:n}}var mo=new eo("pull").description("Fetch icons and regenerate all collection files (replaces existing)").option("-c, --collection <slug>","Pull only this collection").action(async(o)=>{let i=qo("Loading config...").start(),r;try{r=await E()}catch(f){i.fail(b.red(f.message)),process.exit(1)}let n=o.collection?[o.collection]:r.collections;if(o.collection&&!r.collections.includes(o.collection))i.fail(b.red(`Collection '${o.collection}' is not in your config.`)),process.exit(1);i.text=`Fetching icons for ${n.join(", ")}...`;let c;try{c=await z(r,n)}catch(f){i.fail(b.red(`Failed to fetch icons: ${f.message}`)),process.exit(1)}if(c.length===0){i.warn(b.yellow("No icons found."));return}i.text=`Generating ${c.length} icon${c.length!==1?"s":""}...`;let t=new Map;for(let f of c){let w=t.get(f.collectionSlug)??[];w.push(f),t.set(f.collectionSlug,w)}let a=K(),m=0,I=[];for(let[f,w]of t){let y=v(f,w);if(y===0)continue;m+=y,I.push(f),a=Y(a,f,w.map(($)=>({slug:$.slug,fingerprint:$.fingerprint})))}if(_(a),Q(),i.succeed(b.green(`Generated ${m} icon${m!==1?"s":""} across ${I.length} collection${I.length!==1?"s":""}`)),I.length>0){let f=I[0]??"",w=J(t.get(f)?.[0]?.name??"MyIcon");console.log(`
18
18
  Import icons:
19
- ${H.cyan(`import { ${w} } from 'iconia/${f}'`)}`)}});import{Command as Jo}from"commander";import s from"picocolors";import vo from"ora";import p from"fs";import ao from"path";function e(){let o=ao.resolve(process.cwd(),"iconia.config.ts"),i=ao.resolve(process.cwd(),"iconia.config.js");if(p.existsSync(o))return o;if(p.existsSync(i))return i;return null}function S(o){let n=p.readFileSync(o,"utf-8").match(/collections:\s*\[([\s\S]*?)\]/)?.[1];if(!n)return null;let c=[],t=/['"]([^'"]+)['"]/g,a;while((a=t.exec(n))!==null){let m=a[1];if(m)c.push(m)}return c}function W(o,i){let r=p.readFileSync(o,"utf-8"),n=i.length===0?"[]":`[
19
+ ${b.cyan(`import { ${w} } from '@iconia/react/${f}'`)}`)}});import{Command as zo}from"commander";import s from"picocolors";import Jo from"ora";import P from"fs";import ao from"path";function Z(){let o=ao.resolve(process.cwd(),"iconia.config.ts"),i=ao.resolve(process.cwd(),"iconia.config.js");if(P.existsSync(o))return o;if(P.existsSync(i))return i;return null}function S(o){let n=P.readFileSync(o,"utf-8").match(/collections:\s*\[([\s\S]*?)\]/)?.[1];if(!n)return null;let c=[],t=/['"]([^'"]+)['"]/g,a;while((a=t.exec(n))!==null){let m=a[1];if(m)c.push(m)}return c}function W(o,i){let r=P.readFileSync(o,"utf-8"),n=i.length===0?"[]":`[
20
20
  ${i.map((t)=>` '${t}'`).join(`,
21
21
  `)},
22
- ]`,c=r.replace(/collections:\s*\[[\s\S]*?\]/,`collections: ${n}`);if(c===r)return!1;return p.writeFileSync(o,c,"utf-8"),!0}var yo=new Jo("add").description("Add a collection to your project (updates config and downloads icons)").argument("<slug>","Collection slug").action(async(o)=>{let i=vo("Loading config...").start(),r;try{r=await E()}catch(m){i.fail(s.red(m.message)),process.exit(1)}if(r.collections.includes(o))i.info(s.yellow(`Collection '${o}' is already in your config. Running pull...`));else{i.text="Verifying collection...";let m;try{m=await D(r)}catch(L){i.fail(s.red(`Failed to fetch collections: ${L.message}`)),process.exit(1)}if(!m.find((L)=>L.slug===o))i.fail(s.red(`Collection '${o}' not found. Available: ${m.map((L)=>L.slug).join(", ")||"none"}`)),process.exit(1);let f=e();if(!f)i.fail(s.red("Config file not found. Run `npx iconia init` first.")),process.exit(1);let y=[...S(f)??r.collections,o];if(!W(f,y))i.warn(s.yellow(`Could not update config automatically. Add '${o}' to collections in iconia.config.ts manually.`));else i.text=`Added '${o}' to config. Fetching icons...`}i.text=`Fetching icons for '${o}'...`;let n;try{n=await J(r,[o])}catch(m){i.fail(s.red(`Failed to fetch icons: ${m.message}`)),process.exit(1)}if(n.length===0){i.warn(s.yellow(`No icons in collection '${o}'.`));return}i.text=`Generating ${n.length} icon${n.length!==1?"s":""}...`;let c=Y(o,n),t=K();t=A(t,o,n.map((m)=>({slug:m.slug,fingerprint:m.fingerprint}))),_(t),i.succeed(s.green(`Added '${o}' — ${c} icon${c!==1?"s":""} generated`));let a=v(n[0]?.name??"Icon");console.log(`
22
+ ]`,c=r.replace(/collections:\s*\[[\s\S]*?\]/,`collections: ${n}`);if(c===r)return!1;return P.writeFileSync(o,c,"utf-8"),!0}var yo=new zo("add").description("Add a collection to your project (updates config and downloads icons)").argument("<slug>","Collection slug").action(async(o)=>{let i=Jo("Loading config...").start(),r;try{r=await E()}catch(m){i.fail(s.red(m.message)),process.exit(1)}if(r.collections.includes(o))i.info(s.yellow(`Collection '${o}' is already in your config. Running pull...`));else{i.text="Verifying collection...";let m;try{m=await D(r)}catch(L){i.fail(s.red(`Failed to fetch collections: ${L.message}`)),process.exit(1)}if(!m.find((L)=>L.slug===o))i.fail(s.red(`Collection '${o}' not found. Available: ${m.map((L)=>L.slug).join(", ")||"none"}`)),process.exit(1);let f=Z();if(!f)i.fail(s.red("Config file not found. Run `npx @iconia/react init` first.")),process.exit(1);let y=[...S(f)??r.collections,o];if(!W(f,y))i.warn(s.yellow(`Could not update config automatically. Add '${o}' to collections in iconia.config.ts manually.`));else i.text=`Added '${o}' to config. Fetching icons...`}i.text=`Fetching icons for '${o}'...`;let n;try{n=await z(r,[o])}catch(m){i.fail(s.red(`Failed to fetch icons: ${m.message}`)),process.exit(1)}if(n.length===0){i.warn(s.yellow(`No icons in collection '${o}'.`));return}i.text=`Generating ${n.length} icon${n.length!==1?"s":""}...`;let c=v(o,n),t=K();t=Y(t,o,n.map((m)=>({slug:m.slug,fingerprint:m.fingerprint}))),_(t),i.succeed(s.green(`Added '${o}' — ${c} icon${c!==1?"s":""} generated`));let a=J(n[0]?.name??"Icon");console.log(`
23
23
  Import icons:
24
- ${s.cyan(`import { ${a} } from 'iconia/${o}'`)}`)});import{Command as Yo}from"commander";import M from"picocolors";var wo=new Yo("remove").description("Remove a collection from your project (updates config and deletes generated files)").argument("<slug>","Collection slug").action(async(o)=>{let i;try{i=await E()}catch(n){console.error(M.red(n.message)),process.exit(1)}if(!i.collections.includes(o))console.warn(M.yellow(`Collection '${o}' is not in your config.`));else{let n=e();if(n){let t=(S(n)??i.collections).filter((m)=>m!==o);if(!W(n,t))console.warn(M.yellow(`Could not update config automatically. Remove '${o}' from collections in iconia.config.ts manually.`))}}no(o);let r=K();r=fo(r,o),_(r),console.log(M.green(`✓ Removed collection '${o}'`))});import{Command as Ao}from"commander";import U from"picocolors";import Ho from"ora";var $o=new Ao("sync").description("Sync icons: add new, update changed, remove deleted — without full re-fetch").option("-c, --collection <slug>","Sync only this collection").action(async(o)=>{let i=Ho("Loading config...").start(),r;try{r=await E()}catch(y){i.fail(U.red(y.message)),process.exit(1)}let n=o.collection?[o.collection]:r.collections;if(o.collection&&!r.collections.includes(o.collection))i.fail(U.red(`Collection '${o.collection}' is not in your config.`)),process.exit(1);i.text=`Fetching icons for ${n.join(", ")}...`;let c;try{c=await J(r,n)}catch(y){i.fail(U.red(`Failed to fetch icons: ${y.message}`)),process.exit(1)}let t=new Map;for(let y of c){let $=t.get(y.collectionSlug)??[];$.push(y),t.set(y.collectionSlug,$)}let a=K(),m=0,I=0,f=0,w=0;for(let y of n){let $=t.get(y)??[],L=a.collections[y]?.icons??{},O=new Map($.map((d)=>[d.slug,d])),j=new Set(Object.keys(L)),V=new Set(O.keys()),F=[...V].filter((d)=>!j.has(d)),R=[...j].filter((d)=>!V.has(d)),C=[...V].filter((d)=>j.has(d)&&L[d]!==O.get(d).fingerprint);if(F.length===0&&R.length===0&&C.length===0){console.log(U.dim(` ${y}: up to date`));continue}if(F.length>0)console.log(U.green(` ${y}: +${F.length} added`)+U.dim(` (${F.slice(0,5).join(", ")}${F.length>5?"…":""})`));if(C.length>0)console.log(U.blue(` ${y}: ~${C.length} updated`)+U.dim(` (${C.slice(0,5).join(", ")}${C.length>5?"…":""})`));if(R.length>0)console.log(U.red(` ${y}: -${R.length} removed`)+U.dim(` (${R.slice(0,5).join(", ")}${R.length>5?"…":""})`));if($.length>0)Y(y,$);a=A(a,y,$.map((d)=>({slug:d.slug,fingerprint:d.fingerprint}))),m+=F.length,I+=C.length,f+=R.length,w++}if(_(a),w>0)Z();if(w===0)i.succeed(U.green("Everything is up to date."));else i.succeed(U.green(`Sync complete: ${m} added, ${I} updated, ${f} removed across ${w} collection${w!==1?"s":""}`))});import{Command as Po}from"commander";import k from"fs";import b from"path";import P from"picocolors";import bo from"ora";function po(o){return b.basename(o,b.extname(o)).toLowerCase().replace(/\s+/g,"-").replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}function Qo(o){return o.split("-").map((i)=>i.charAt(0).toUpperCase()+i.slice(1)).join(" ")}function Zo(o){let i=k.statSync(o);if(i.isFile()){if(!o.endsWith(".svg"))throw Error(`File '${o}' is not an SVG.`);return[o]}if(i.isDirectory())return k.readdirSync(o).filter((r)=>r.endsWith(".svg")).map((r)=>b.join(o,r));throw Error(`'${o}' is not a file or directory.`)}var Io=new Po("upload").description("Upload SVG file(s) to an Iconia collection").argument("<path>","SVG file or directory of SVGs").requiredOption("-c, --collection <slug>","Target collection slug").option("--tags <tags>","Comma-separated tags to apply to all uploaded icons").action(async(o,i)=>{let r=bo("Loading config...").start(),n;try{n=await E()}catch(f){r.fail(P.red(f.message)),process.exit(1)}let c;try{c=Zo(b.resolve(process.cwd(),o))}catch(f){r.fail(P.red(f.message)),process.exit(1)}if(c.length===0){r.warn(P.yellow("No SVG files found."));return}let t=i.tags?i.tags.split(",").map((f)=>f.trim()).filter(Boolean):[];r.text=`Uploading ${c.length} file${c.length!==1?"s":""} to '${i.collection}'...`;let a=0,m=0,I=[];for(let f of c){let w=po(f);if(!w){I.push(`${b.basename(f)}: could not derive a valid slug`),m++;continue}let y=k.readFileSync(f,"utf-8");try{await l(n,{collectionSlug:i.collection,name:Qo(w),slug:w,svgContent:y,tags:t}),a++,r.text=`Uploading... (${a}/${c.length})`}catch($){I.push(`${b.basename(f)}: ${$.message}`),m++}}if(m===0)r.succeed(P.green(`Uploaded ${a} icon${a!==1?"s":""} to '${i.collection}'`));else{r.warn(P.yellow(`Uploaded ${a}, failed ${m}`));for(let f of I)console.log(P.dim(` ✗ ${f}`))}});var So=new eo("iconia").version("0.1.0").description("CLI for fetching and generating React icon components from Iconia").addCommand(X).addCommand(yo).addCommand(wo).addCommand(mo).addCommand($o).addCommand(Io);So.parse(process.argv);
24
+ ${s.cyan(`import { ${a} } from '@iconia/react/${o}'`)}`)});import{Command as vo}from"commander";import M from"picocolors";var wo=new vo("remove").description("Remove a collection from your project (updates config and deletes generated files)").argument("<slug>","Collection slug").action(async(o)=>{let i;try{i=await E()}catch(n){console.error(M.red(n.message)),process.exit(1)}if(!i.collections.includes(o))console.warn(M.yellow(`Collection '${o}' is not in your config.`));else{let n=Z();if(n){let t=(S(n)??i.collections).filter((m)=>m!==o);if(!W(n,t))console.warn(M.yellow(`Could not update config automatically. Remove '${o}' from collections in iconia.config.ts manually.`))}}no(o);let r=K();r=fo(r,o),_(r),console.log(M.green(`✓ Removed collection '${o}'`))});import{Command as Yo}from"commander";import U from"picocolors";import bo from"ora";var $o=new Yo("sync").description("Sync icons: add new, update changed, remove deleted — without full re-fetch").option("-c, --collection <slug>","Sync only this collection").action(async(o)=>{let i=bo("Loading config...").start(),r;try{r=await E()}catch(y){i.fail(U.red(y.message)),process.exit(1)}let n=o.collection?[o.collection]:r.collections;if(o.collection&&!r.collections.includes(o.collection))i.fail(U.red(`Collection '${o.collection}' is not in your config.`)),process.exit(1);i.text=`Fetching icons for ${n.join(", ")}...`;let c;try{c=await z(r,n)}catch(y){i.fail(U.red(`Failed to fetch icons: ${y.message}`)),process.exit(1)}let t=new Map;for(let y of c){let $=t.get(y.collectionSlug)??[];$.push(y),t.set(y.collectionSlug,$)}let a=K(),m=0,I=0,f=0,w=0;for(let y of n){let $=t.get(y)??[],L=a.collections[y]?.icons??{},O=new Map($.map((d)=>[d.slug,d])),j=new Set(Object.keys(L)),V=new Set(O.keys()),F=[...V].filter((d)=>!j.has(d)),R=[...j].filter((d)=>!V.has(d)),C=[...V].filter((d)=>j.has(d)&&L[d]!==O.get(d).fingerprint);if(F.length===0&&R.length===0&&C.length===0){console.log(U.dim(` ${y}: up to date`));continue}if(F.length>0)console.log(U.green(` ${y}: +${F.length} added`)+U.dim(` (${F.slice(0,5).join(", ")}${F.length>5?"…":""})`));if(C.length>0)console.log(U.blue(` ${y}: ~${C.length} updated`)+U.dim(` (${C.slice(0,5).join(", ")}${C.length>5?"…":""})`));if(R.length>0)console.log(U.red(` ${y}: -${R.length} removed`)+U.dim(` (${R.slice(0,5).join(", ")}${R.length>5?"…":""})`));if($.length>0)v(y,$);a=Y(a,y,$.map((d)=>({slug:d.slug,fingerprint:d.fingerprint}))),m+=F.length,I+=C.length,f+=R.length,w++}if(_(a),w>0)Q();if(w===0)i.succeed(U.green("Everything is up to date."));else i.succeed(U.green(`Sync complete: ${m} added, ${I} updated, ${f} removed across ${w} collection${w!==1?"s":""}`))});import{Command as Ao}from"commander";import k from"fs";import H from"path";import A from"picocolors";import Ho from"ora";function Po(o){return H.basename(o,H.extname(o)).toLowerCase().replace(/\s+/g,"-").replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}function po(o){return o.split("-").map((i)=>i.charAt(0).toUpperCase()+i.slice(1)).join(" ")}function Qo(o){let i=k.statSync(o);if(i.isFile()){if(!o.endsWith(".svg"))throw Error(`File '${o}' is not an SVG.`);return[o]}if(i.isDirectory())return k.readdirSync(o).filter((r)=>r.endsWith(".svg")).map((r)=>H.join(o,r));throw Error(`'${o}' is not a file or directory.`)}var Io=new Ao("upload").description("Upload SVG file(s) to an Iconia collection").argument("<path>","SVG file or directory of SVGs").requiredOption("-c, --collection <slug>","Target collection slug").option("--tags <tags>","Comma-separated tags to apply to all uploaded icons").action(async(o,i)=>{let r=Ho("Loading config...").start(),n;try{n=await E()}catch(f){r.fail(A.red(f.message)),process.exit(1)}let c;try{c=Qo(H.resolve(process.cwd(),o))}catch(f){r.fail(A.red(f.message)),process.exit(1)}if(c.length===0){r.warn(A.yellow("No SVG files found."));return}let t=i.tags?i.tags.split(",").map((f)=>f.trim()).filter(Boolean):[];r.text=`Uploading ${c.length} file${c.length!==1?"s":""} to '${i.collection}'...`;let a=0,m=0,I=[];for(let f of c){let w=Po(f);if(!w){I.push(`${H.basename(f)}: could not derive a valid slug`),m++;continue}let y=k.readFileSync(f,"utf-8");try{await l(n,{collectionSlug:i.collection,name:po(w),slug:w,svgContent:y,tags:t}),a++,r.text=`Uploading... (${a}/${c.length})`}catch($){I.push(`${H.basename(f)}: ${$.message}`),m++}}if(m===0)r.succeed(A.green(`Uploaded ${a} icon${a!==1?"s":""} to '${i.collection}'`));else{r.warn(A.yellow(`Uploaded ${a}, failed ${m}`));for(let f of I)console.log(A.dim(` ✗ ${f}`))}});var So=new Zo("iconia").version("0.1.0").description("CLI for fetching and generating React icon components from Iconia").addCommand(X).addCommand(yo).addCommand(wo).addCommand(mo).addCommand($o).addCommand(Io);So.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iconia/react",
3
- "version": "0.1.0-dev.52c1e49",
3
+ "version": "0.1.0-dev.f643e57",
4
4
  "description": "Fetch and generate React icon components from your Iconia collections",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",