@solar-icons/codemod 2.0.0-beta.4 → 2.0.0

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/README.md CHANGED
@@ -7,18 +7,18 @@ Conservative, opt-in migrations for Solar Icons v2.
7
7
  Use the interactive assistant when running the migration by hand. It detects supported frameworks, asks for the React and Vue strategy when relevant, and requires confirmation before it writes files.
8
8
 
9
9
  ```bash
10
- npx @solar-icons/codemod@beta --interactive
10
+ npx @solar-icons/codemod --interactive
11
11
  ```
12
12
 
13
13
  Use arguments for scripts, CI, or repeatable migrations. The command previews changes unless `--write` is passed.
14
14
 
15
15
  ```bash
16
- npx @solar-icons/codemod@beta --react-v1-mode static
17
- npx @solar-icons/codemod@beta ./apps/web --react-v1-mode static --write
18
- npx @solar-icons/codemod@beta --json > solar-icons-migration.json
16
+ npx @solar-icons/codemod --react-v1-mode static
17
+ npx @solar-icons/codemod ./apps/web --react-v1-mode static --write
18
+ npx @solar-icons/codemod --json > solar-icons-migration.json
19
19
  ```
20
20
 
21
- Run `npx @solar-icons/codemod@beta --help` for every option. `--cwd <path>` remains available for existing scripts, but a directory argument is shorter.
21
+ Run `npx @solar-icons/codemod --help` for every option. `--cwd <path>` remains available for existing scripts, but a directory argument is shorter.
22
22
 
23
23
  ## React v1 strategy
24
24
 
package/dist/cli.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{detectFrameworks as e}from"./detect.mjs";import{transformPackageJson as t}from"./package-json.mjs";import{collectAngularSelectorRenames as n,transformAngular as r,transformAngularTemplate as i}from"./transforms/angular.mjs";import{transformNuxt as a}from"./transforms/nuxt.mjs";import{transformReactNative as o}from"./transforms/react-native.mjs";import{transformReactPerf as s}from"./transforms/react-perf.mjs";import{transformReact as c}from"./transforms/react.mjs";import{transformSolid as l}from"./transforms/solid.mjs";import{transformSvelte as u}from"./transforms/svelte.mjs";import{transformVue as d}from"./transforms/vue.mjs";import{readFile as f,readdir as p,writeFile as m}from"node:fs/promises";import{extname as h,join as g,resolve as _}from"node:path";import{realpathSync as v}from"node:fs";import{pathToFileURL as y}from"node:url";import*as b from"@clack/prompts";import{Command as x,InvalidArgumentError as S}from"commander";import C from"picocolors";const w=new Set([`.html`,`.js`,`.jsx`,`.mjs`,`.ts`,`.tsx`,`.svelte`,`.vue`]),T=new Set([`.git`,`.next`,`.nuxt`,`.svelte-kit`,`coverage`,`dist`,`node_modules`]);async function E(e){let t=await p(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let n=g(e,t.name);return t.isDirectory()?T.has(t.name)?[]:E(n):t.isFile()&&w.has(h(t.name))?[n]:[]}))).flat()}async function D({cwd:p,reactV1Mode:h=`static`,targetVersion:_,vueV1Mode:v=`static`,write:y=!1}){let b=await e(p),x=await E(p),S=new Map(await Promise.all(x.map(async e=>[e,await f(e,`utf8`)]))),C=new Map;for(let[e,t]of S)for(let[r,i]of n(t,e))C.set(r,i);let w=new Set(x),T=[],D=[];for(let e of x){let t=s(S.get(e),e),n=c(t.code,e,h),f=o(n.code,e),p=d(f.code,e,v),g=a(p.code,e),_=u(g.code,e),b=l(_.code,e),x=r(b.code,e,w),E=i(x.code,C);D.push(...t.diagnostics,...n.diagnostics,...f.diagnostics,...p.diagnostics,...g.diagnostics,..._.diagnostics,...b.diagnostics,...x.diagnostics,...E.diagnostics),!(!t.changed&&!n.changed&&!f.changed&&!p.changed&&!g.changed&&!_.changed&&!b.changed&&!x.changed&&!E.changed)&&(T.push(e),y&&await m(e,E.code))}let O=g(p,`package.json`),k=t(await f(O,`utf8`),_);return k.changed&&(T.push(O),y&&await m(O,k.code)),{changedFiles:T,diagnostics:D,detectedFrameworks:b}}function O(e){if(e===`static`||e===`dynamic`)return e;throw new S(`Expected either "static" or "dynamic".`)}function k(e){let t=e.file&&e.line?`${e.file}:${e.line}:${e.column??1}`:e.file,n=e.severity===`error`?C.red(`error`):C.yellow(`warning`);return`${C.dim(t??`solar-icons`)} ${n} ${C.bold(`[${e.code}]`)} ${e.message}`}function A(e,t){console.info(`${C.cyan(`Detected frameworks:`)} ${e.detectedFrameworks.join(`, `)||`none`}`),console.info(`${t?C.green(`Migrated`):C.cyan(`Would migrate`)} ${C.bold(String(e.changedFiles.length))} file(s).`);for(let t of e.diagnostics)console.warn(k(t));!t&&e.changedFiles.length>0&&console.info(C.dim(`Run again with --write to apply these changes.`))}async function j(e){let t=await b.select({message:`${e} migration strategy`,options:[{value:`static`,label:`Static (recommended)`,hint:`one style per import and the smallest bundle`},{value:`dynamic`,label:`Dynamic`,hint:`preserve runtime style switching`}]});if(!b.isCancel(t))return t}async function M(t){b.intro(C.bgCyan(C.black(` Solar Icons v2 migration `)));let n=await e(t);b.log.info(`Detected: ${n.join(`, `)||`no supported framework`}`);let r=n.includes(`react`)?await j(`React`):void 0;if(n.includes(`react`)&&!r){b.cancel(`Migration cancelled.`);return}let i=n.includes(`vue`)?await j(`Vue`):void 0;if(n.includes(`vue`)&&!i){b.cancel(`Migration cancelled.`);return}let a=await b.select({message:`Choose an action`,options:[{value:`preview`,label:`Preview changes`,hint:`does not modify files`},{value:`write`,label:`Apply changes`,hint:`writes the migration to disk`}]});if(b.isCancel(a)){b.cancel(`Migration cancelled.`);return}let o=a===`write`;if(o){let e=await b.confirm({message:`Write the migration to this project?`,initialValue:!1});if(b.isCancel(e)||!e){b.cancel(`Migration cancelled.`);return}}return{reactV1Mode:r,vueV1Mode:i,write:o}}async function N(){let e=new x().name(`solar-icons-migrate`).description(`Migrate a Solar Icons project from the pre-v2 API to v2.`).argument(`[directory]`,`project directory, defaults to the current directory`).option(`-C, --cwd <path>`,`project directory, kept for backwards compatibility`).option(`-i, --interactive`,`guide the migration with prompts`).option(`-w, --write`,`apply changes instead of previewing them`).option(`--react-v1-mode <mode>`,`React strategy: static or dynamic`,O).option(`--vue-v1-mode <mode>`,`Vue strategy: static or dynamic`,O).option(`--target-version <version>`,`Solar Icons v2 version to add to package.json`).option(`--json`,`write a machine-readable report to stdout`).showHelpAfterError().showSuggestionAfterError();e.action(async(t,n)=>{t&&n.cwd&&e.error(`Use either [directory] or --cwd, not both.`,{exitCode:2}),n.interactive&&n.json&&e.error(`--interactive cannot be combined with --json.`,{exitCode:2});let r=_(n.cwd??t??process.cwd()),i=n.interactive?await M(r):void 0;if(n.interactive&&!i)return;let a={cwd:r,reactV1Mode:i?.reactV1Mode??n.reactV1Mode,targetVersion:n.targetVersion,vueV1Mode:i?.vueV1Mode??n.vueV1Mode,write:i?.write??n.write},o=await D(a);n.json?console.info(JSON.stringify(o,null,2)):A(o,!!a.write),n.interactive&&b.outro(`Migration complete.`)}),await e.parseAsync()}const P=process.argv[1]?v(process.argv[1]):void 0;P&&import.meta.url===y(P).href&&N();export{D as runMigration};
2
+ import{detectFrameworks as e}from"./detect.mjs";import{transformPackageJson as t}from"./package-json.mjs";import{collectAngularSelectorRenames as n,transformAngular as r,transformAngularTemplate as i}from"./transforms/angular.mjs";import{transformNuxt as a}from"./transforms/nuxt.mjs";import{transformReactNative as o}from"./transforms/react-native.mjs";import{transformReactPerf as s}from"./transforms/react-perf.mjs";import{transformReact as c}from"./transforms/react.mjs";import{transformSolid as l}from"./transforms/solid.mjs";import{transformSvelte as u}from"./transforms/svelte.mjs";import{transformVue as d}from"./transforms/vue.mjs";import{readFile as f,readdir as p,writeFile as m}from"node:fs/promises";import{extname as h,join as g,resolve as _}from"node:path";import{realpathSync as v}from"node:fs";import{pathToFileURL as y}from"node:url";import*as b from"@clack/prompts";import{Command as x,InvalidArgumentError as S}from"commander";import C from"picocolors";const w=new Set([`.html`,`.js`,`.jsx`,`.mjs`,`.ts`,`.tsx`,`.svelte`,`.vue`]),T=new Set([`.git`,`.next`,`.nuxt`,`.svelte-kit`,`coverage`,`dist`,`node_modules`]);async function E(e){let t=await p(e,{withFileTypes:!0});return(await Promise.all(t.map(async t=>{let n=g(e,t.name);return t.isDirectory()?T.has(t.name)?[]:E(n):t.isFile()&&w.has(h(t.name))?[n]:[]}))).flat()}async function D({cwd:p,reactV1Mode:h=`static`,targetVersion:_,vueV1Mode:v=`static`,write:y=!1}){let b=await e(p),x=await E(p),S=new Map(await Promise.all(x.map(async e=>[e,await f(e,`utf8`)]))),C=new Map;for(let[e,t]of S)for(let[r,i]of n(t,e))C.set(r,i);let w=new Set(x),T=[],D=[];for(let e of x){let t=S.get(e),n=s(t,e),f=c(n.code,e,h),p=o(f.code,e),g=d(p.code,e,v),_=a(g.code,e),b=u(_.code,e),x=l(b.code,e),E=r(x.code,e,w),O=i(E.code,C);D.push(...n.diagnostics,...f.diagnostics,...p.diagnostics,...g.diagnostics,..._.diagnostics,...b.diagnostics,...x.diagnostics,...E.diagnostics,...O.diagnostics),!(!n.changed&&!f.changed&&!p.changed&&!g.changed&&!_.changed&&!b.changed&&!x.changed&&!E.changed&&!O.changed)&&(T.push(e),y&&await m(e,O.code))}let O=g(p,`package.json`),k=t(await f(O,`utf8`),_);return k.changed&&(T.push(O),y&&await m(O,k.code)),{changedFiles:T,diagnostics:D,detectedFrameworks:b}}function O(e){if(e===`static`||e===`dynamic`)return e;throw new S(`Expected either "static" or "dynamic".`)}function k(e){let t=e.file&&e.line?`${e.file}:${e.line}:${e.column??1}`:e.file,n=e.severity===`error`?C.red(`error`):C.yellow(`warning`);return`${C.dim(t??`solar-icons`)} ${n} ${C.bold(`[${e.code}]`)} ${e.message}`}function A(e,t){console.info(`${C.cyan(`Detected frameworks:`)} ${e.detectedFrameworks.join(`, `)||`none`}`),console.info(`${t?C.green(`Migrated`):C.cyan(`Would migrate`)} ${C.bold(String(e.changedFiles.length))} file(s).`);for(let t of e.diagnostics)console.warn(k(t));!t&&e.changedFiles.length>0&&console.info(C.dim(`Run again with --write to apply these changes.`))}async function j(e){let t=await b.select({message:`${e} migration strategy`,options:[{value:`static`,label:`Static (recommended)`,hint:`one style per import and the smallest bundle`},{value:`dynamic`,label:`Dynamic`,hint:`preserve runtime style switching`}]});if(!b.isCancel(t))return t}async function M(t){b.intro(C.bgCyan(C.black(` Solar Icons v2 migration `)));let n=await e(t);b.log.info(`Detected: ${n.join(`, `)||`no supported framework`}`);let r=n.includes(`react`)?await j(`React`):void 0;if(n.includes(`react`)&&!r){b.cancel(`Migration cancelled.`);return}let i=n.includes(`vue`)?await j(`Vue`):void 0;if(n.includes(`vue`)&&!i){b.cancel(`Migration cancelled.`);return}let a=await b.select({message:`Choose an action`,options:[{value:`preview`,label:`Preview changes`,hint:`does not modify files`},{value:`write`,label:`Apply changes`,hint:`writes the migration to disk`}]});if(b.isCancel(a)){b.cancel(`Migration cancelled.`);return}let o=a===`write`;if(o){let e=await b.confirm({message:`Write the migration to this project?`,initialValue:!1});if(b.isCancel(e)||!e){b.cancel(`Migration cancelled.`);return}}return{reactV1Mode:r,vueV1Mode:i,write:o}}async function N(){let e=new x().name(`solar-icons-migrate`).description(`Migrate a Solar Icons project from the pre-v2 API to v2.`).argument(`[directory]`,`project directory, defaults to the current directory`).option(`-C, --cwd <path>`,`project directory, kept for backwards compatibility`).option(`-i, --interactive`,`guide the migration with prompts`).option(`-w, --write`,`apply changes instead of previewing them`).option(`--react-v1-mode <mode>`,`React strategy: static or dynamic`,O).option(`--vue-v1-mode <mode>`,`Vue strategy: static or dynamic`,O).option(`--target-version <version>`,`Solar Icons v2 version to add to package.json`).option(`--json`,`write a machine-readable report to stdout`).showHelpAfterError().showSuggestionAfterError();e.action(async(t,n)=>{t&&n.cwd&&e.error(`Use either [directory] or --cwd, not both.`,{exitCode:2}),n.interactive&&n.json&&e.error(`--interactive cannot be combined with --json.`,{exitCode:2});let r=_(n.cwd??t??process.cwd()),i=n.interactive?await M(r):void 0;if(n.interactive&&!i)return;let a={cwd:r,reactV1Mode:i?.reactV1Mode??n.reactV1Mode,targetVersion:n.targetVersion,vueV1Mode:i?.vueV1Mode??n.vueV1Mode,write:i?.write??n.write},o=await D(a);n.json?console.info(JSON.stringify(o,null,2)):A(o,!!a.write),n.interactive&&b.outro(`Migration complete.`)}),await e.parseAsync()}const P=process.argv[1]?v(process.argv[1]):void 0;P&&import.meta.url===y(P).href&&N();export{D as runMigration};
@@ -1 +1 @@
1
- const e=[`dependencies`,`devDependencies`,`peerDependencies`];function t(t,n=`^2.0.0`){let r=JSON.parse(t),i=!1;for(let t of e){let e=r[t];if(!e)continue;if(`@solar-icons/react-perf`in e){delete e[`@solar-icons/react-perf`],e[`@solar-icons/react`]=n,i=!0;continue}let a=e[`@solar-icons/react`];(a?.startsWith(`1.`)||a?.startsWith(`^1.`)||a?.startsWith(`~1.`))&&(e[`@solar-icons/react`]=n,i=!0);let o=e[`@solar-icons/react-native`];(o?.startsWith(`1.`)||o?.startsWith(`^1.`)||o?.startsWith(`~1.`))&&(e[`@solar-icons/react-native`]=n,i=!0);for(let t of[`@solar-icons/vue`,`@solar-icons/nuxt`,`@solar-icons/svelte`,`@solar-icons/solid`,`@solar-icons/angular`]){let r=e[t];(r?.startsWith(`1.`)||r?.startsWith(`^1.`)||r?.startsWith(`~1.`))&&(e[t]=n,i=!0)}}return{code:i?`${JSON.stringify(r,null,4)}\n`:t,changed:i,diagnostics:[]}}export{t as transformPackageJson};
1
+ const e=[`dependencies`,`devDependencies`,`peerDependencies`];function t(t,n=`^2.0.0`){let r=JSON.parse(t),i=!1;for(let t of e){let e=r[t];if(!e)continue;`@solar-icons/react-perf`in e&&(delete e[`@solar-icons/react-perf`],e[`@solar-icons/react`]=n,i=!0);let a=e[`@solar-icons/react`];(a?.startsWith(`1.`)||a?.startsWith(`^1.`)||a?.startsWith(`~1.`))&&(e[`@solar-icons/react`]=n,i=!0);let o=e[`@solar-icons/react-native`];(o?.startsWith(`1.`)||o?.startsWith(`^1.`)||o?.startsWith(`~1.`))&&(e[`@solar-icons/react-native`]=n,i=!0);for(let t of[`@solar-icons/vue`,`@solar-icons/nuxt`,`@solar-icons/svelte`,`@solar-icons/solid`,`@solar-icons/angular`]){let r=e[t];(r?.startsWith(`1.`)||r?.startsWith(`^1.`)||r?.startsWith(`~1.`))&&(e[t]=n,i=!0)}}return{code:i?`${JSON.stringify(r,null,4)}\n`:t,changed:i,diagnostics:[]}}export{t as transformPackageJson};
@@ -1 +1 @@
1
- import{renameIcon as e}from"../icon-renames.mjs";import{renameImportedBindingReferences as t}from"../import-bindings.mjs";import n from"typescript";const r={bold:`bold`,boldduotone:`bold-duotone`,broken:`broken`,linear:`linear`,lineduotone:`line-duotone`,outline:`outline`},i=new Set([`Icon`,`IconProps`]);function a(e){return e.endsWith(`Icon`)?e:`${e}Icon`}function o(e){let t=e.split(`/`).at(-1)?.replace(/[-_]/g,``).toLowerCase();return t?r[t]:void 0}function s(t,n){let i=Object.entries(r).find(([,e])=>e===n)?.[0];return a(e(i&&t.toLowerCase().endsWith(i)?t.slice(0,-i.length):t))}function c(t){let n=[`BoldDuotone`,`LineDuotone`,`Outline`,`Broken`,`Linear`,`Bold`].find(e=>t.endsWith(e));return a(n?`${e(t.slice(0,-n.length))}${n}`:e(t))}function l(e){return(e.propertyName??e.name).text}function u(e,t){return t.sort((e,t)=>t.start-e.start).reduce((e,t)=>e.slice(0,t.start)+t.text+e.slice(t.end),e)}function d(e,t){let n=e.getLineAndCharacterOfPosition(t.getStart(e));return{column:n.character+1,line:n.line+1}}function f(e,r=`source.tsx`){let a=n.createSourceFile(r,e,n.ScriptTarget.Latest,!0),f=[],p=[],m=new Map;for(let e of a.statements){if(!n.isImportDeclaration(e)||!n.isStringLiteral(e.moduleSpecifier))continue;let t=e.moduleSpecifier.text;if(!t.startsWith(`@solar-icons/react-perf`))continue;let u=t.slice(23),h=u?o(t):void 0;if(u===`/lib/types`){let o=e.importClause?.namedBindings;if(!o||!n.isNamedImports(o)){p.push({code:`UNSUPPORTED_REACT_PERF_IMPORT`,...d(a,e.moduleSpecifier),message:`Skipped non-named import from ${t}.`,file:r});continue}let s=o.elements.find(e=>!i.has(l(e)));if(s){p.push({code:`UNSUPPORTED_REACT_PERF_TYPE_EXPORT`,...d(a,s),message:`Skipped unsupported react-perf type export: ${l(s)}.`,file:r});continue}f.push({start:e.moduleSpecifier.getStart(a)+1,end:e.moduleSpecifier.getEnd()-1,text:`@solar-icons/react/lib/index`});continue}if(u&&!h){p.push({code:`UNSUPPORTED_REACT_PERF_SUBPATH`,...d(a,e.moduleSpecifier),message:`Skipped unsupported react-perf subpath: ${t}.`,file:r});continue}let g=e.importClause?.namedBindings;if(!g||!n.isNamedImports(g)){p.push({code:`UNSUPPORTED_REACT_PERF_IMPORT`,...d(a,e.moduleSpecifier),message:`Skipped non-named import from ${t}.`,file:r});continue}f.push({start:e.moduleSpecifier.getStart(a)+1,end:e.moduleSpecifier.getEnd()-1,text:h?`@solar-icons/react/${h}`:`@solar-icons/react`});for(let e of g.elements){let t=l(e),n=h?s(t,h):c(t),r=e.name.text,i=!!e.propertyName,o=i?r:n;!i&&r!==n&&m.set(r,n),f.push({start:e.getStart(a),end:e.getEnd(),text:o===n?n:`${n} as ${o}`})}let _=new Set(g.elements.map(e=>e.name.text)),v=e=>{if(n.isJsxOpeningLikeElement(e)&&n.isIdentifier(e.tagName)&&_.has(e.tagName.text))for(let t of e.attributes.properties)!n.isJsxAttribute(t)||t.name.getText()!==`mirrored`||p.push({code:`REACT_MIRRORED_REQUIRES_MANUAL_MIGRATION`,file:r,...d(a,t),message:`${e.tagName.text} uses the removed mirrored prop. Replace it with style={{ transform: 'scaleX(-1)' }}.`,severity:`warning`});n.forEachChild(e,v)};n.forEachChild(a,v)}let h=e=>{n.isStringLiteral(e)&&e.text===`@solar-icons/react-perf`&&!n.isImportDeclaration(e.parent)&&f.push({start:e.getStart(a)+1,end:e.getEnd()-1,text:`@solar-icons/react`}),n.forEachChild(e,h)};n.forEachChild(a,h),f.push(...t(e,r,m));let g=u(e,f);return{code:g,changed:g!==e,diagnostics:p}}export{f as transformReactPerf};
1
+ import{renameIcon as e}from"../icon-renames.mjs";import{renameImportedBindingReferences as t}from"../import-bindings.mjs";import n from"typescript";const r={bold:`bold`,boldduotone:`bold-duotone`,broken:`broken`,linear:`linear`,lineduotone:`line-duotone`,outline:`outline`},i=new Set([`Icon`,`IconProps`]);function a(e){return e.endsWith(`Icon`)?e:`${e}Icon`}function o(e){let t=e.split(`/`).at(-1)?.replace(/[-_]/g,``).toLowerCase();return t?r[t]:void 0}function s(t,n){let i=Object.entries(r).find(([,e])=>e===n)?.[0],o=i&&t.toLowerCase().endsWith(i)?t.slice(0,-i.length):t;return a(e(o))}function c(t){let n=[`BoldDuotone`,`LineDuotone`,`Outline`,`Broken`,`Linear`,`Bold`].find(e=>t.endsWith(e));return a(n?`${e(t.slice(0,-n.length))}${n}`:e(t))}function l(e){return(e.propertyName??e.name).text}function u(e,t){return t.sort((e,t)=>t.start-e.start).reduce((e,t)=>e.slice(0,t.start)+t.text+e.slice(t.end),e)}function d(e,t){let n=e.getLineAndCharacterOfPosition(t.getStart(e));return{column:n.character+1,line:n.line+1}}function f(e,r=`source.tsx`){let a=n.createSourceFile(r,e,n.ScriptTarget.Latest,!0),f=[],p=[],m=new Map;for(let e of a.statements){if(!n.isImportDeclaration(e)||!n.isStringLiteral(e.moduleSpecifier))continue;let t=e.moduleSpecifier.text;if(!t.startsWith(`@solar-icons/react-perf`))continue;let u=t.slice(23),h=u?o(t):void 0;if(u===`/lib/types`){let o=e.importClause?.namedBindings;if(!o||!n.isNamedImports(o)){p.push({code:`UNSUPPORTED_REACT_PERF_IMPORT`,...d(a,e.moduleSpecifier),message:`Skipped non-named import from ${t}.`,file:r});continue}let s=o.elements.find(e=>!i.has(l(e)));if(s){p.push({code:`UNSUPPORTED_REACT_PERF_TYPE_EXPORT`,...d(a,s),message:`Skipped unsupported react-perf type export: ${l(s)}.`,file:r});continue}f.push({start:e.moduleSpecifier.getStart(a)+1,end:e.moduleSpecifier.getEnd()-1,text:`@solar-icons/react/lib/index`});continue}if(u&&!h){p.push({code:`UNSUPPORTED_REACT_PERF_SUBPATH`,...d(a,e.moduleSpecifier),message:`Skipped unsupported react-perf subpath: ${t}.`,file:r});continue}let g=e.importClause?.namedBindings;if(!g||!n.isNamedImports(g)){p.push({code:`UNSUPPORTED_REACT_PERF_IMPORT`,...d(a,e.moduleSpecifier),message:`Skipped non-named import from ${t}.`,file:r});continue}f.push({start:e.moduleSpecifier.getStart(a)+1,end:e.moduleSpecifier.getEnd()-1,text:h?`@solar-icons/react/${h}`:`@solar-icons/react`});for(let e of g.elements){let t=l(e),n=h?s(t,h):c(t),r=e.name.text,i=!!e.propertyName,o=i?r:n;!i&&r!==n&&m.set(r,n),f.push({start:e.getStart(a),end:e.getEnd(),text:o===n?n:`${n} as ${o}`})}let _=new Set(g.elements.map(e=>e.name.text)),v=e=>{if(n.isJsxOpeningLikeElement(e)&&n.isIdentifier(e.tagName)&&_.has(e.tagName.text))for(let t of e.attributes.properties)!n.isJsxAttribute(t)||t.name.getText()!==`mirrored`||p.push({code:`REACT_MIRRORED_REQUIRES_MANUAL_MIGRATION`,file:r,...d(a,t),message:`${e.tagName.text} uses the removed mirrored prop. Replace it with style={{ transform: 'scaleX(-1)' }}.`,severity:`warning`});n.forEachChild(e,v)};n.forEachChild(a,v)}let h=e=>{n.isStringLiteral(e)&&e.text===`@solar-icons/react-perf`&&!n.isImportDeclaration(e.parent)&&f.push({start:e.getStart(a)+1,end:e.getEnd()-1,text:`@solar-icons/react`}),n.forEachChild(e,h)};n.forEachChild(a,h),f.push(...t(e,r,m));let g=u(e,f);return{code:g,changed:g!==e,diagnostics:p}}export{f as transformReactPerf};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solar-icons/codemod",
3
- "version": "2.0.0-beta.4",
3
+ "version": "2.0.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -32,21 +32,21 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@clack/prompts": "^1.7.0",
35
- "@vue/compiler-sfc": "^3.5.39",
35
+ "@vue/compiler-sfc": "^3.5.41",
36
36
  "commander": "^15.0.0",
37
37
  "picocolors": "^1.1.1",
38
- "svelte": "^5.56.4",
38
+ "svelte": "^5.56.8",
39
39
  "typescript": "^6.0.3"
40
40
  },
41
41
  "devDependencies": {
42
- "@tala-tools/eslint": "0.1.4",
42
+ "@tala-tools/eslint": "0.1.5",
43
43
  "@tala-tools/prettier": "0.0.3",
44
- "@tala-tools/tsconfig": "0.0.1",
45
- "@types/node": "^26.1.1",
46
- "prettier": "^3.9.4",
44
+ "@tala-tools/tsconfig": "0.0.2",
45
+ "@types/node": "^26.1.2",
46
+ "prettier": "^3.9.6",
47
47
  "rimraf": "^6.1.3",
48
- "tsdown": "^0.22.4",
49
- "tsx": "^4.23.0",
48
+ "tsdown": "^0.22.14",
49
+ "tsx": "^4.23.8",
50
50
  "vitest": "^4.1.10"
51
51
  },
52
52
  "engines": {