Comparing version 0.4.1 to 0.5.0
#!/usr/bin/env node | ||
import{existsSync as _,promises as le}from"fs";import D from"path";import J from"path";import{createMatchPath as be}from"tsconfig-paths";async function O(t,e){return be(e.absoluteBaseUrl,e.paths)(t,void 0,()=>!0,[".ts",".tsx"])}import{cosmiconfig as Pe}from"cosmiconfig";import{loadConfig as ke}from"tsconfig-paths";import*as f from"zod";var K="@/components",H="@/lib/utils",X="app/globals.css",q="tailwind.config.js";var Ee=Pe("components",{searchPlaces:["components.json"]}),b=f.object({$schema:f.string().optional(),style:f.string(),rsc:f.coerce.boolean().default(!1),tsx:f.coerce.boolean().default(!0),tailwind:f.object({config:f.string(),css:f.string(),baseColor:f.string(),cssVariables:f.boolean().default(!0)}),aliases:f.object({components:f.string(),utils:f.string()})}).strict(),je=b.extend({resolvedPaths:f.object({tailwindConfig:f.string(),tailwindCss:f.string(),utils:f.string(),components:f.string()})});async function x(t){let e=await $e(t);return e?await N(t,e):null}async function N(t,e){let o=await ke(t);if(o.resultType==="failed")throw new Error(`Failed to load tsconfig.json. ${o.message??""}`.trim());return je.parse({...e,resolvedPaths:{tailwindConfig:J.resolve(t,e.tailwind.config),tailwindCss:J.resolve(t,e.tailwind.css),utils:await O(e.aliases.utils,o),components:await O(e.aliases.components,o)}})}async function $e(t){try{let e=await Ee.search(t);return e?b.parse(e.config):null}catch{throw new Error(`Invalid configuration found in ${t}/components.json.`)}}import{detect as Fe}from"@antfu/ni";async function P(t){let e=await Fe({programmatic:!0,cwd:t});return e==="yarn@berry"?"yarn":e==="pnpm@6"?"pnpm":e==="bun"?"bun":e??"npm"}import k from"chalk";var l={error(...t){console.log(k.red(...t))},warn(...t){console.log(k.yellow(...t))},info(...t){console.log(k.cyan(...t))},success(...t){console.log(k.green(...t))},break(){console.log("")}};function C(t){typeof t=="string"&&(l.error(t),process.exit(1)),t instanceof Error&&(l.error(t.message),process.exit(1)),l.error("Something went wrong. Please try again."),process.exit(1)}import Ae from"path";import*as s from"zod";var Y=s.object({name:s.string(),dependencies:s.array(s.string()).optional(),registryDependencies:s.array(s.string()).optional(),files:s.array(s.string()),type:s.enum(["components:ui","components:component","components:example"])}),Z=s.array(Y),Le=Y.extend({files:s.array(s.object({name:s.string(),content:s.string()}))}),Q=s.array(Le),ee=s.array(s.object({name:s.string(),label:s.string()})),te=s.object({inlineColors:s.object({light:s.record(s.string(),s.string()),dark:s.record(s.string(),s.string())}),cssVars:s.object({light:s.record(s.string(),s.string()),dark:s.record(s.string(),s.string())}),inlineColorsTemplate:s.string(),cssVarsTemplate:s.string()});import{HttpsProxyAgent as De}from"https-proxy-agent";import Re from"node-fetch";var oe=process.env.COMPONENTS_REGISTRY_URL??"https://ui.shadcn.com",Oe=process.env.https_proxy?new De(process.env.https_proxy):void 0;async function E(){try{let[t]=await F(["index.json"]);return Z.parse(t)}catch{throw new Error("Failed to fetch components from registry.")}}async function re(){try{let[t]=await F(["styles/index.json"]);return ee.parse(t)}catch{throw new Error("Failed to fetch styles from registry.")}}async function ne(){return[{name:"slate",label:"Slate"},{name:"gray",label:"Gray"},{name:"zinc",label:"Zinc"},{name:"neutral",label:"Neutral"},{name:"stone",label:"Stone"}]}async function v(t){try{let[e]=await F([`colors/${t}.json`]);return te.parse(e)}catch{throw new Error("Failed to fetch base color from registry.")}}async function W(t,e){let o=[];for(let r of e){let n=t.find(i=>i.name===r);if(n&&(o.push(n),n.registryDependencies)){let i=await W(t,n.registryDependencies);o.push(...i)}}return o.filter((r,n,i)=>i.findIndex(a=>a.name===r.name)===n)}async function j(t,e){try{let o=e.map(n=>`styles/${t}/${n.name}.json`),r=await F(o);return Q.parse(r)}catch{throw new Error("Failed to fetch tree from registry.")}}async function $(t,e,o){if(o&&e.type!=="components:ui")return o;let[r,n]=e.type.split(":");return r in t.resolvedPaths?Ae.join(t.resolvedPaths[r],n):null}async function F(t){try{return await Promise.all(t.map(async o=>await(await Re(`${oe}/registry/${o}`,{agent:Oe})).json()))}catch(e){throw console.log(e),new Error(`Failed to fetch registry from ${oe}.`)}}import{promises as Ke}from"fs";import{tmpdir as He}from"os";import pe from"path";import{SyntaxKind as Ne}from"ts-morph";var se=async({sourceFile:t,config:e,baseColor:o})=>(e.tailwind?.cssVariables||!o?.inlineColors||t.getDescendantsOfKind(Ne.StringLiteral).forEach(r=>{let n=r.getText();if(n){let i=Ue(n.replace(/"/g,""),o.inlineColors);r.replaceWithText(`"${i.trim()}"`)}}),t);function We(t){if(!t.includes("/")&&!t.includes(":"))return[null,t,null];let e=[],[o,r]=t.split("/");if(!o.includes(":"))return[null,o,r];let n=o.split(":"),i=n.pop(),a=n.join(":");return e.push(a??null,i??null,r??null),e}var _e=["bg-","text-","border-","ring-offset-","ring-"];function Ue(t,e){t.includes(" border ")&&(t=t.replace(" border "," border border-border "));let o=t.split(" "),r=new Set,n=new Set;for(let i of o){let[a,d,m]=We(i),g=_e.find(p=>d?.startsWith(p));if(!g){r.has(i)||r.add(i);continue}let c=d?.replace(g,"");if(c&&c in e.light){r.add([a,`${g}${e.light[c]}`].filter(Boolean).join(":")+(m?`/${m}`:"")),n.add(["dark",a,`${g}${e.dark[c]}`].filter(Boolean).join(":")+(m?`/${m}`:""));continue}r.has(i)||r.add(i)}return[...Array.from(r),...Array.from(n)].join(" ").trim()}var ie=async({sourceFile:t,config:e})=>{let o=t.getImportDeclarations();for(let r of o){let n=r.getModuleSpecifierValue();n.startsWith("@/registry/")&&r.setModuleSpecifier(n.replace(/^@\/registry\/[^/]+/,e.aliases.components)),n=="@/lib/utils"&&r.getNamedImports().find(d=>d.getName()==="cn")&&r.setModuleSpecifier(n.replace(/^@\/lib\/utils/,e.aliases.utils))}return t};import{transformFromAstSync as Me}from"@babel/core";import{parse as Be}from"@babel/parser";import Ve from"@babel/plugin-transform-typescript";import*as L from"recast";var Ge={sourceType:"module",allowImportExportEverywhere:!0,allowReturnOutsideFunction:!0,startLine:1,tokens:!0,plugins:["asyncGenerators","bigInt","classPrivateMethods","classPrivateProperties","classProperties","classStaticBlock","decimal","decorators-legacy","doExpressions","dynamicImport","exportDefaultFrom","exportNamespaceFrom","functionBind","functionSent","importAssertions","importMeta","nullishCoalescingOperator","numericSeparator","objectRestSpread","optionalCatchBinding","optionalChaining",["pipelineOperator",{proposal:"minimal"}],["recordAndTuple",{syntaxType:"hash"}],"throwExpressions","topLevelAwait","v8intrinsic","typescript","jsx"]},ae=async({sourceFile:t,config:e})=>{let o=t.getFullText();if(e.tsx)return o;let r=L.parse(o,{parser:{parse:i=>Be(i,Ge)}}),n=Me(r,o,{cloneInputAst:!1,code:!1,ast:!0,plugins:[Ve],configFile:!1});if(!n||!n.ast)throw new Error("Failed to transform JSX");return L.print(n.ast).code};import{SyntaxKind as Je}from"ts-morph";var ce=async({sourceFile:t,config:e})=>{if(e.rsc)return t;let o=t.getFirstChildByKind(Je.ExpressionStatement);return o?.getText()==='"use client"'&&o.remove(),t};import{Project as Xe,ScriptKind as qe}from"ts-morph";var Ye=[ie,ce,se],Ze=new Xe({compilerOptions:{}});async function Qe(t){let e=await Ke.mkdtemp(pe.join(He(),"shadcn-"));return pe.join(e,t)}async function A(t){let e=await Qe(t.filename),o=Ze.createSourceFile(e,t.raw,{scriptKind:qe.TSX});for(let r of Ye)r({sourceFile:o,...t});return await ae({sourceFile:o,...t})}import me from"chalk";import{Command as et}from"commander";import{execa as tt}from"execa";import ot from"ora";import U from"prompts";import*as h from"zod";var rt=h.object({components:h.array(h.string()).optional(),yes:h.boolean(),overwrite:h.boolean(),cwd:h.string(),all:h.boolean(),path:h.string().optional()}),fe=new et().name("add").description("add a component to your project").argument("[components...]","the components to add").option("-y, --yes","skip confirmation prompt.",!0).option("-o, --overwrite","overwrite existing files.",!1).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).option("-a, --all","add all available components",!1).option("-p, --path <path>","the path to add the component to.").action(async(t,e)=>{try{let o=rt.parse({components:t,...e}),r=D.resolve(o.cwd);_(r)||(l.error(`The path ${r} does not exist. Please try again.`),process.exit(1));let n=await x(r);n||(l.warn(`Configuration is missing. Please run ${me.green("init")} to create a components.json file.`),process.exit(1));let i=await E(),a=o.all?i.map(p=>p.name):o.components;if(!o.components?.length&&!o.all){let{components:p}=await U({type:"multiselect",name:"components",message:"Which components would you like to add?",hint:"Space to select. A to toggle all. Enter to submit.",instructions:!1,choices:i.map(u=>({title:u.name,value:u.name,selected:o.all?!0:o.components?.includes(u.name)}))});a=p}a?.length||(l.warn("No components selected. Exiting."),process.exit(0));let d=await W(i,a),m=await j(n.style,d),g=await v(n.tailwind.baseColor);if(m.length||(l.warn("Selected components not found. Exiting."),process.exit(0)),!o.yes){let{proceed:p}=await U({type:"confirm",name:"proceed",message:"Ready to install components and dependencies. Proceed?",initial:!0});p||process.exit(0)}let c=ot("Installing components...").start();for(let p of m){c.text=`Installing ${p.name}...`;let u=await $(n,p,o.path?D.resolve(r,o.path):void 0);if(!u)continue;if(_(u)||await le.mkdir(u,{recursive:!0}),p.files.filter(y=>_(D.resolve(u,y.name))).length&&!o.overwrite)if(a.includes(p.name)){c.stop();let{overwrite:y}=await U({type:"confirm",name:"overwrite",message:`Component ${p.name} already exists. Would you like to overwrite?`,initial:!1});if(!y){l.info(`Skipped ${p.name}. To overwrite, run with the ${me.green("--overwrite")} flag.`);continue}c.start(`Installing ${p.name}...`)}else continue;for(let y of p.files){let z=D.resolve(u,y.name),Ie=await A({filename:y.name,raw:y.content,config:n,baseColor:g});n.tsx||(z=z.replace(/\.tsx$/,".jsx"),z=z.replace(/\.ts$/,".js")),await le.writeFile(z,Ie)}if(p.dependencies?.length){let y=await P(r);await tt(y,[y==="npm"?"install":"add",...p.dependencies],{cwd:r})}}c.succeed("Done.")}catch(o){C(o)}});import{existsSync as M,promises as nt}from"fs";import B from"path";import T from"chalk";import{Command as st}from"commander";import{diffLines as it}from"diff";import*as w from"zod";var at=w.object({component:w.string().optional(),yes:w.boolean(),cwd:w.string(),path:w.string().optional()}),ge=new st().name("diff").description("check for updates against the registry").argument("[component]","the component name").option("-y, --yes","skip confirmation prompt.",!1).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).action(async(t,e)=>{try{let o=at.parse({component:t,...e}),r=B.resolve(o.cwd);M(r)||(l.error(`The path ${r} does not exist. Please try again.`),process.exit(1));let n=await x(r);n||(l.warn(`Configuration is missing. Please run ${T.green("init")} to create a components.json file.`),process.exit(1));let i=await E();if(!o.component){let m=n.resolvedPaths.components,g=i.filter(p=>{for(let u of p.files){let G=B.resolve(m,u);if(M(G))return!0}return!1}),c=[];for(let p of g){let u=await de(p,n);u.length&&c.push({name:p.name,changes:u})}c.length||(l.info("No updates found."),process.exit(0)),l.info("The following components have updates available:");for(let p of c){l.info(`- ${p.name}`);for(let u of p.changes)l.info(` - ${u.filePath}`)}l.break(),l.info(`Run ${T.green("diff <component>")} to see the changes.`),process.exit(0)}let a=i.find(m=>m.name===o.component);a||(l.error(`The component ${T.green(o.component)} does not exist.`),process.exit(1));let d=await de(a,n);d.length||(l.info(`No updates found for ${o.component}.`),process.exit(0));for(let m of d)l.info(`- ${m.filePath}`),await ct(m.patch),l.info("")}catch(o){C(o)}});async function de(t,e){let o=await j(e.style,[t]),r=await v(e.tailwind.baseColor),n=[];for(let i of o){let a=await $(e,i);if(a)for(let d of i.files){let m=B.resolve(a,d.name);if(!M(m))continue;let g=await nt.readFile(m,"utf8"),c=await A({filename:d.name,raw:d.content,config:e,baseColor:r}),p=it(c,g);p.length>1&&n.push({file:d.name,filePath:m,patch:p})}}return n}async function ct(t){t.forEach(e=>{if(e)return e.added?process.stdout.write(T.green(e.value)):e.removed?process.stdout.write(T.red(e.value)):process.stdout.write(e.value)})}import{existsSync as ve,promises as I}from"fs";import R from"path";var ue=`import { type ClassValue, clsx } from "clsx" | ||
import{existsSync as B,promises as ue}from"fs";import W from"path";import q from"path";import{createMatchPath as Le}from"tsconfig-paths";async function _(t,e){return Le(e.absoluteBaseUrl,e.paths)(t,void 0,()=>!0,[".ts",".tsx"])}import{cosmiconfig as De}from"cosmiconfig";import{loadConfig as Fe}from"tsconfig-paths";import*as d from"zod";var X="@/components",Y="@/lib/utils",Z="app/globals.css",Q="tailwind.config.js";var je=De("components",{searchPlaces:["components.json"]}),$=d.object({$schema:d.string().optional(),style:d.string(),rsc:d.coerce.boolean().default(!1),tsx:d.coerce.boolean().default(!0),tailwind:d.object({config:d.string(),css:d.string(),baseColor:d.string(),cssVariables:d.boolean().default(!0),prefix:d.string().default("").optional()}),aliases:d.object({components:d.string(),utils:d.string()})}).strict(),Ne=$.extend({resolvedPaths:d.object({tailwindConfig:d.string(),tailwindCss:d.string(),utils:d.string(),components:d.string()})});async function C(t){let e=await Oe(t);return e?await R(t,e):null}async function R(t,e){let o=await Fe(t);if(o.resultType==="failed")throw new Error(`Failed to load ${e.tsx?"tsconfig":"jsconfig"}.json. ${o.message??""}`.trim());return Ne.parse({...e,resolvedPaths:{tailwindConfig:q.resolve(t,e.tailwind.config),tailwindCss:q.resolve(t,e.tailwind.css),utils:await _(e.aliases.utils,o),components:await _(e.aliases.components,o)}})}async function Oe(t){try{let e=await je.search(t);return e?$.parse(e.config):null}catch{throw new Error(`Invalid configuration found in ${t}/components.json.`)}}import{detect as We}from"@antfu/ni";async function A(t){let e=await We({programmatic:!0,cwd:t});return e==="yarn@berry"?"yarn":e==="pnpm@6"?"pnpm":e==="bun"?"bun":e??"npm"}import k from"chalk";var l={error(...t){console.log(k.red(...t))},warn(...t){console.log(k.yellow(...t))},info(...t){console.log(k.cyan(...t))},success(...t){console.log(k.green(...t))},break(){console.log("")}};function T(t){typeof t=="string"&&(l.error(t),process.exit(1)),t instanceof Error&&(l.error(t.message),process.exit(1)),l.error("Something went wrong. Please try again."),process.exit(1)}import Re from"path";import*as a from"zod";var ee=a.object({name:a.string(),dependencies:a.array(a.string()).optional(),registryDependencies:a.array(a.string()).optional(),files:a.array(a.string()),type:a.enum(["components:ui","components:component","components:example"])}),te=a.array(ee),_e=ee.extend({files:a.array(a.object({name:a.string(),content:a.string()}))}),re=a.array(_e),oe=a.array(a.object({name:a.string(),label:a.string()})),ne=a.object({inlineColors:a.object({light:a.record(a.string(),a.string()),dark:a.record(a.string(),a.string())}),cssVars:a.object({light:a.record(a.string(),a.string()),dark:a.record(a.string(),a.string())}),inlineColorsTemplate:a.string(),cssVarsTemplate:a.string()});import{HttpsProxyAgent as Ue}from"https-proxy-agent";import Ke from"node-fetch";var ie=process.env.COMPONENTS_REGISTRY_URL??"https://ui.shadcn.com",Be=process.env.https_proxy?new Ue(process.env.https_proxy):void 0;async function L(){try{let[t]=await j(["index.json"]);return te.parse(t)}catch{throw new Error("Failed to fetch components from registry.")}}async function se(){try{let[t]=await j(["styles/index.json"]);return oe.parse(t)}catch{throw new Error("Failed to fetch styles from registry.")}}async function ae(){return[{name:"slate",label:"Slate"},{name:"gray",label:"Gray"},{name:"zinc",label:"Zinc"},{name:"neutral",label:"Neutral"},{name:"stone",label:"Stone"}]}async function S(t){try{let[e]=await j([`colors/${t}.json`]);return ne.parse(e)}catch{throw new Error("Failed to fetch base color from registry.")}}async function U(t,e){let o=[];for(let r of e){let n=t.find(i=>i.name===r);if(n&&(o.push(n),n.registryDependencies)){let i=await U(t,n.registryDependencies);o.push(...i)}}return o.filter((r,n,i)=>i.findIndex(s=>s.name===r.name)===n)}async function D(t,e){try{let o=e.map(n=>`styles/${t}/${n.name}.json`),r=await j(o);return re.parse(r)}catch{throw new Error("Failed to fetch tree from registry.")}}async function F(t,e,o){if(o&&e.type!=="components:ui")return o;let[r,n]=e.type.split(":");return r in t.resolvedPaths?Re.join(t.resolvedPaths[r],n):null}async function j(t){try{return await Promise.all(t.map(async o=>await(await Ke(`${ie}/registry/${o}`,{agent:Be})).json()))}catch(e){throw console.log(e),new Error(`Failed to fetch registry from ${ie}.`)}}import{promises as Ze}from"fs";import{tmpdir as Qe}from"os";import ge from"path";import{SyntaxKind as Me}from"ts-morph";var ce=async({sourceFile:t,config:e,baseColor:o})=>(e.tailwind?.cssVariables||!o?.inlineColors||t.getDescendantsOfKind(Me.StringLiteral).forEach(r=>{let n=r.getText();if(n){let i=Ge(n.replace(/"/g,""),o.inlineColors);r.replaceWithText(`"${i.trim()}"`)}}),t);function K(t){if(!t.includes("/")&&!t.includes(":"))return[null,t,null];let e=[],[o,r]=t.split("/");if(!o.includes(":"))return[null,o,r];let n=o.split(":"),i=n.pop(),s=n.join(":");return e.push(s??null,i??null,r??null),e}var Ve=["bg-","text-","border-","ring-offset-","ring-"];function Ge(t,e){t.includes(" border ")&&(t=t.replace(" border "," border border-border "));let o=t.split(" "),r=new Set,n=new Set;for(let i of o){let[s,m,f]=K(i),h=Ve.find(c=>m?.startsWith(c));if(!h){r.has(i)||r.add(i);continue}let p=m?.replace(h,"");if(p&&p in e.light){r.add([s,`${h}${e.light[p]}`].filter(Boolean).join(":")+(f?`/${f}`:"")),n.add(["dark",s,`${h}${e.dark[p]}`].filter(Boolean).join(":")+(f?`/${f}`:""));continue}r.has(i)||r.add(i)}return[...Array.from(r),...Array.from(n)].join(" ").trim()}var le=async({sourceFile:t,config:e})=>{let o=t.getImportDeclarations();for(let r of o){let n=r.getModuleSpecifierValue();n.startsWith("@/registry/")&&r.setModuleSpecifier(n.replace(/^@\/registry\/[^/]+/,e.aliases.components)),n=="@/lib/utils"&&r.getNamedImports().find(m=>m.getName()==="cn")&&r.setModuleSpecifier(n.replace(/^@\/lib\/utils/,e.aliases.utils))}return t};import{transformFromAstSync as Je}from"@babel/core";import{parse as He}from"@babel/parser";import qe from"@babel/plugin-transform-typescript";import*as N from"recast";var Xe={sourceType:"module",allowImportExportEverywhere:!0,allowReturnOutsideFunction:!0,startLine:1,tokens:!0,plugins:["asyncGenerators","bigInt","classPrivateMethods","classPrivateProperties","classProperties","classStaticBlock","decimal","decorators-legacy","doExpressions","dynamicImport","exportDefaultFrom","exportNamespaceFrom","functionBind","functionSent","importAssertions","importMeta","nullishCoalescingOperator","numericSeparator","objectRestSpread","optionalCatchBinding","optionalChaining",["pipelineOperator",{proposal:"minimal"}],["recordAndTuple",{syntaxType:"hash"}],"throwExpressions","topLevelAwait","v8intrinsic","typescript","jsx"]},pe=async({sourceFile:t,config:e})=>{let o=t.getFullText();if(e.tsx)return o;let r=N.parse(o,{parser:{parse:i=>He(i,Xe)}}),n=Je(r,o,{cloneInputAst:!1,code:!1,ast:!0,plugins:[qe],configFile:!1});if(!n||!n.ast)throw new Error("Failed to transform JSX");return N.print(n.ast).code};import{SyntaxKind as Ye}from"ts-morph";var me=async({sourceFile:t,config:e})=>{if(e.rsc)return t;let o=t.getFirstChildByKind(Ye.ExpressionStatement);return o?.getText()==='"use client"'&&o.remove(),t};import{Project as et,ScriptKind as tt}from"ts-morph";import{SyntaxKind as g}from"ts-morph";var fe=async({sourceFile:t,config:e})=>(e.tailwind?.prefix&&(t.getDescendantsOfKind(g.CallExpression).filter(o=>o.getExpression().getText()==="cva").forEach(o=>{if(o.getArguments()[0]?.isKind(g.StringLiteral)){let r=o.getArguments()[0];r&&r.replaceWithText(`"${w(r.getText()?.replace(/"/g,""),e.tailwind.prefix)}"`)}o.getArguments()[1]?.isKind(g.ObjectLiteralExpression)&&o.getArguments()[1]?.getDescendantsOfKind(g.PropertyAssignment).find(r=>r.getName()==="variants")?.getDescendantsOfKind(g.PropertyAssignment).forEach(r=>{r.getDescendantsOfKind(g.PropertyAssignment).forEach(n=>{let i=n.getInitializerIfKind(g.StringLiteral);i&&i?.replaceWithText(`"${w(i.getText()?.replace(/"/g,""),e.tailwind.prefix)}"`)})})}),t.getDescendantsOfKind(g.JsxAttribute).forEach(o=>{if(o.getName()==="className"){if(o.getInitializer()?.isKind(g.StringLiteral)){let r=o.getInitializer();r&&r.replaceWithText(`"${w(r.getText()?.replace(/"/g,""),e.tailwind.prefix)}"`)}if(o.getInitializer()?.isKind(g.JsxExpression)){let r=o.getInitializer()?.getDescendantsOfKind(g.CallExpression).find(n=>n.getExpression().getText()==="cn");r&&r.getArguments().forEach(n=>{(n.isKind(g.ConditionalExpression)||n.isKind(g.BinaryExpression))&&n.getChildrenOfKind(g.StringLiteral).forEach(i=>{i.replaceWithText(`"${w(i.getText()?.replace(/"/g,""),e.tailwind.prefix)}"`)}),n.isKind(g.StringLiteral)&&n.replaceWithText(`"${w(n.getText()?.replace(/"/g,""),e.tailwind.prefix)}"`)})}}o.getName()==="classNames"&&o.getInitializer()?.isKind(g.JsxExpression)&&o.getDescendantsOfKind(g.PropertyAssignment).forEach(r=>{if(r.getInitializer()?.isKind(g.CallExpression)){let n=r.getInitializerIfKind(g.CallExpression);n&&n.getArguments().forEach(i=>{i.isKind(g.ConditionalExpression)&&i.getChildrenOfKind(g.StringLiteral).forEach(s=>{s.replaceWithText(`"${w(s.getText()?.replace(/"/g,""),e.tailwind.prefix)}"`)}),i.isKind(g.StringLiteral)&&i.replaceWithText(`"${w(i.getText()?.replace(/"/g,""),e.tailwind.prefix)}"`)})}if(r.getInitializer()?.isKind(g.StringLiteral)&&r.getName()!=="variant"){let n=r.getInitializer();n&&n.replaceWithText(`"${w(n.getText()?.replace(/"/g,""),e.tailwind.prefix)}"`)}})})),t);function w(t,e=""){let o=t.split(" "),r=[];for(let n of o){let[i,s,m]=K(n);i?m?r.push(`${i}:${e}${s}/${m}`):r.push(`${i}:${e}${s}`):m?r.push(`${e}${s}/${m}`):r.push(`${e}${s}`)}return r.join(" ")}function de(t,e){let o=t.split(` | ||
`);for(let r of o)if(r.includes("@apply")){let n=r.replace("@apply","").trim(),i=w(n,e);t=t.replace(n,i)}return t}var rt=[le,me,ce,fe],ot=new et({compilerOptions:{}});async function nt(t){let e=await Ze.mkdtemp(ge.join(Qe(),"shadcn-"));return ge.join(e,t)}async function O(t){let e=await nt(t.filename),o=ot.createSourceFile(e,t.raw,{scriptKind:tt.TSX});for(let r of rt)r({sourceFile:o,...t});return await pe({sourceFile:o,...t})}import he from"chalk";import{Command as it}from"commander";import{execa as st}from"execa";import at from"ora";import M from"prompts";import*as x from"zod";var ct=x.object({components:x.array(x.string()).optional(),yes:x.boolean(),overwrite:x.boolean(),cwd:x.string(),all:x.boolean(),path:x.string().optional()}),xe=new it().name("add").description("add a component to your project").argument("[components...]","the components to add").option("-y, --yes","skip confirmation prompt.",!0).option("-o, --overwrite","overwrite existing files.",!1).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).option("-a, --all","add all available components",!1).option("-p, --path <path>","the path to add the component to.").action(async(t,e)=>{try{let o=ct.parse({components:t,...e}),r=W.resolve(o.cwd);B(r)||(l.error(`The path ${r} does not exist. Please try again.`),process.exit(1));let n=await C(r);n||(l.warn(`Configuration is missing. Please run ${he.green("init")} to create a components.json file.`),process.exit(1));let i=await L(),s=o.all?i.map(c=>c.name):o.components;if(!o.components?.length&&!o.all){let{components:c}=await M({type:"multiselect",name:"components",message:"Which components would you like to add?",hint:"Space to select. A to toggle all. Enter to submit.",instructions:!1,choices:i.map(u=>({title:u.name,value:u.name,selected:o.all?!0:o.components?.includes(u.name)}))});s=c}s?.length||(l.warn("No components selected. Exiting."),process.exit(0));let m=await U(i,s),f=await D(n.style,m),h=await S(n.tailwind.baseColor);if(f.length||(l.warn("Selected components not found. Exiting."),process.exit(0)),!o.yes){let{proceed:c}=await M({type:"confirm",name:"proceed",message:"Ready to install components and dependencies. Proceed?",initial:!0});c||process.exit(0)}let p=at("Installing components...").start();for(let c of f){p.text=`Installing ${c.name}...`;let u=await F(n,c,o.path?W.resolve(r,o.path):void 0);if(!u)continue;if(B(u)||await ue.mkdir(u,{recursive:!0}),c.files.filter(y=>B(W.resolve(u,y.name))).length&&!o.overwrite)if(s.includes(c.name)){p.stop();let{overwrite:y}=await M({type:"confirm",name:"overwrite",message:`Component ${c.name} already exists. Would you like to overwrite?`,initial:!1});if(!y){l.info(`Skipped ${c.name}. To overwrite, run with the ${he.green("--overwrite")} flag.`);continue}p.start(`Installing ${c.name}...`)}else continue;for(let y of c.files){let z=W.resolve(u,y.name),ke=await O({filename:y.name,raw:y.content,config:n,baseColor:h});n.tsx||(z=z.replace(/\.tsx$/,".jsx"),z=z.replace(/\.ts$/,".js")),await ue.writeFile(z,ke)}if(c.dependencies?.length){let y=await A(r);await st(y,[y==="npm"?"install":"add",...c.dependencies],{cwd:r})}}p.succeed("Done.")}catch(o){T(o)}});import{existsSync as V,promises as lt}from"fs";import G from"path";import b from"chalk";import{Command as pt}from"commander";import{diffLines as mt}from"diff";import*as v from"zod";var ft=v.object({component:v.string().optional(),yes:v.boolean(),cwd:v.string(),path:v.string().optional()}),we=new pt().name("diff").description("check for updates against the registry").argument("[component]","the component name").option("-y, --yes","skip confirmation prompt.",!1).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).action(async(t,e)=>{try{let o=ft.parse({component:t,...e}),r=G.resolve(o.cwd);V(r)||(l.error(`The path ${r} does not exist. Please try again.`),process.exit(1));let n=await C(r);n||(l.warn(`Configuration is missing. Please run ${b.green("init")} to create a components.json file.`),process.exit(1));let i=await L();if(!o.component){let f=n.resolvedPaths.components,h=i.filter(c=>{for(let u of c.files){let H=G.resolve(f,u);if(V(H))return!0}return!1}),p=[];for(let c of h){let u=await ye(c,n);u.length&&p.push({name:c.name,changes:u})}p.length||(l.info("No updates found."),process.exit(0)),l.info("The following components have updates available:");for(let c of p){l.info(`- ${c.name}`);for(let u of c.changes)l.info(` - ${u.filePath}`)}l.break(),l.info(`Run ${b.green("diff <component>")} to see the changes.`),process.exit(0)}let s=i.find(f=>f.name===o.component);s||(l.error(`The component ${b.green(o.component)} does not exist.`),process.exit(1));let m=await ye(s,n);m.length||(l.info(`No updates found for ${o.component}.`),process.exit(0));for(let f of m)l.info(`- ${f.filePath}`),await dt(f.patch),l.info("")}catch(o){T(o)}});async function ye(t,e){let o=await D(e.style,[t]),r=await S(e.tailwind.baseColor),n=[];for(let i of o){let s=await F(e,i);if(s)for(let m of i.files){let f=G.resolve(s,m.name);if(!V(f))continue;let h=await lt.readFile(f,"utf8"),p=await O({filename:m.name,raw:m.content,config:e,baseColor:r}),c=mt(p,h);c.length>1&&n.push({file:m.name,filePath:f,patch:c})}}return n}async function dt(t){t.forEach(e=>{if(e)return e.added?process.stdout.write(b.green(e.value)):e.removed?process.stdout.write(b.red(e.value)):process.stdout.write(e.value)})}import{existsSync as Ee,promises as E}from"fs";import P from"path";var ve=`import { type ClassValue, clsx } from "clsx" | ||
import { twMerge } from "tailwind-merge" | ||
export function cn(...inputs: ClassValue[]) { | ||
return twMerge(clsx(inputs)) | ||
} | ||
`,he=`import { clsx } from "clsx" | ||
`,Ce=`import { clsx } from "clsx" | ||
import { twMerge } from "tailwind-merge" | ||
export function cn(...inputs) { | ||
return twMerge(clsx(inputs)) | ||
} | ||
`,ye=`/** @type {import('tailwindcss').Config} */ | ||
`,Te=`/** @type {import('tailwindcss').Config} */ | ||
module.exports = { | ||
@@ -22,3 +23,4 @@ darkMode: ["class"], | ||
'./src/**/*.{<%- extension %>,<%- extension %>x}', | ||
], | ||
], | ||
prefix: "<%- prefix %>", | ||
theme: { | ||
@@ -35,3 +37,3 @@ container: { | ||
"accordion-down": { | ||
from: { height: 0 }, | ||
from: { height: "0" }, | ||
to: { height: "var(--radix-accordion-content-height)" }, | ||
@@ -41,3 +43,3 @@ }, | ||
from: { height: "var(--radix-accordion-content-height)" }, | ||
to: { height: 0 }, | ||
to: { height: "0" }, | ||
}, | ||
@@ -52,3 +54,3 @@ }, | ||
plugins: [require("tailwindcss-animate")], | ||
}`,we=`/** @type {import('tailwindcss').Config} */ | ||
}`,Se=`/** @type {import('tailwindcss').Config} */ | ||
module.exports = { | ||
@@ -61,3 +63,120 @@ darkMode: ["class"], | ||
'./src/**/*.{<%- extension %>,<%- extension %>x}', | ||
], | ||
prefix: "<%- prefix %>", | ||
theme: { | ||
container: { | ||
center: true, | ||
padding: "2rem", | ||
screens: { | ||
"2xl": "1400px", | ||
}, | ||
}, | ||
extend: { | ||
colors: { | ||
border: "hsl(var(--border))", | ||
input: "hsl(var(--input))", | ||
ring: "hsl(var(--ring))", | ||
background: "hsl(var(--background))", | ||
foreground: "hsl(var(--foreground))", | ||
primary: { | ||
DEFAULT: "hsl(var(--primary))", | ||
foreground: "hsl(var(--primary-foreground))", | ||
}, | ||
secondary: { | ||
DEFAULT: "hsl(var(--secondary))", | ||
foreground: "hsl(var(--secondary-foreground))", | ||
}, | ||
destructive: { | ||
DEFAULT: "hsl(var(--destructive))", | ||
foreground: "hsl(var(--destructive-foreground))", | ||
}, | ||
muted: { | ||
DEFAULT: "hsl(var(--muted))", | ||
foreground: "hsl(var(--muted-foreground))", | ||
}, | ||
accent: { | ||
DEFAULT: "hsl(var(--accent))", | ||
foreground: "hsl(var(--accent-foreground))", | ||
}, | ||
popover: { | ||
DEFAULT: "hsl(var(--popover))", | ||
foreground: "hsl(var(--popover-foreground))", | ||
}, | ||
card: { | ||
DEFAULT: "hsl(var(--card))", | ||
foreground: "hsl(var(--card-foreground))", | ||
}, | ||
}, | ||
borderRadius: { | ||
lg: "var(--radius)", | ||
md: "calc(var(--radius) - 2px)", | ||
sm: "calc(var(--radius) - 4px)", | ||
}, | ||
keyframes: { | ||
"accordion-down": { | ||
from: { height: "0" }, | ||
to: { height: "var(--radix-accordion-content-height)" }, | ||
}, | ||
"accordion-up": { | ||
from: { height: "var(--radix-accordion-content-height)" }, | ||
to: { height: "0" }, | ||
}, | ||
}, | ||
animation: { | ||
"accordion-down": "accordion-down 0.2s ease-out", | ||
"accordion-up": "accordion-up 0.2s ease-out", | ||
}, | ||
}, | ||
}, | ||
plugins: [require("tailwindcss-animate")], | ||
}`,Ie=`import type { Config } from "tailwindcss" | ||
const config = { | ||
darkMode: ["class"], | ||
content: [ | ||
'./pages/**/*.{<%- extension %>,<%- extension %>x}', | ||
'./components/**/*.{<%- extension %>,<%- extension %>x}', | ||
'./app/**/*.{<%- extension %>,<%- extension %>x}', | ||
'./src/**/*.{<%- extension %>,<%- extension %>x}', | ||
], | ||
prefix: "<%- prefix %>", | ||
theme: { | ||
container: { | ||
center: true, | ||
padding: "2rem", | ||
screens: { | ||
"2xl": "1400px", | ||
}, | ||
}, | ||
extend: { | ||
keyframes: { | ||
"accordion-down": { | ||
from: { height: "0" }, | ||
to: { height: "var(--radix-accordion-content-height)" }, | ||
}, | ||
"accordion-up": { | ||
from: { height: "var(--radix-accordion-content-height)" }, | ||
to: { height: "0" }, | ||
}, | ||
}, | ||
animation: { | ||
"accordion-down": "accordion-down 0.2s ease-out", | ||
"accordion-up": "accordion-up 0.2s ease-out", | ||
}, | ||
}, | ||
}, | ||
plugins: [require("tailwindcss-animate")], | ||
} satisfies Config | ||
export default config`,ze=`import type { Config } from "tailwindcss" | ||
const config = { | ||
darkMode: ["class"], | ||
content: [ | ||
'./pages/**/*.{<%- extension %>,<%- extension %>x}', | ||
'./components/**/*.{<%- extension %>,<%- extension %>x}', | ||
'./app/**/*.{<%- extension %>,<%- extension %>x}', | ||
'./src/**/*.{<%- extension %>,<%- extension %>x}', | ||
], | ||
prefix: "<%- prefix %>", | ||
theme: { | ||
@@ -114,3 +233,3 @@ container: { | ||
"accordion-down": { | ||
from: { height: 0 }, | ||
from: { height: "0" }, | ||
to: { height: "var(--radix-accordion-content-height)" }, | ||
@@ -120,3 +239,3 @@ }, | ||
from: { height: "var(--radix-accordion-content-height)" }, | ||
to: { height: 0 }, | ||
to: { height: "0" }, | ||
}, | ||
@@ -131,3 +250,5 @@ }, | ||
plugins: [require("tailwindcss-animate")], | ||
}`;import Se from"chalk";import{Command as lt}from"commander";import{execa as mt}from"execa";import xe from"lodash.template";import V from"ora";import Ce from"prompts";import*as S from"zod";var ft=["tailwindcss-animate","class-variance-authority","clsx","tailwind-merge"],dt=S.object({cwd:S.string(),yes:S.boolean()}),ze=new lt().name("init").description("initialize your project and install dependencies").option("-y, --yes","skip confirmation prompt.",!1).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).action(async t=>{try{let e=dt.parse(t),o=R.resolve(e.cwd);ve(o)||(l.error(`The path ${o} does not exist. Please try again.`),process.exit(1));let r=await x(o),n=await gt(o,r,e.yes);await ut(o,n),l.info(""),l.info(`${Se.green("Success!")} Project initialization completed.`),l.info("")}catch(e){C(e)}});async function gt(t,e=null,o=!1){let r=c=>Se.cyan(c),n=await re(),i=await ne(),a=await Ce([{type:"toggle",name:"typescript",message:`Would you like to use ${r("TypeScript")} (recommended)?`,initial:e?.tsx??!0,active:"yes",inactive:"no"},{type:"select",name:"style",message:`Which ${r("style")} would you like to use?`,choices:n.map(c=>({title:c.label,value:c.name}))},{type:"select",name:"tailwindBaseColor",message:`Which color would you like to use as ${r("base color")}?`,choices:i.map(c=>({title:c.label,value:c.name}))},{type:"text",name:"tailwindCss",message:`Where is your ${r("global CSS")} file?`,initial:e?.tailwind.css??X},{type:"toggle",name:"tailwindCssVariables",message:`Would you like to use ${r("CSS variables")} for colors?`,initial:e?.tailwind.cssVariables??!0,active:"yes",inactive:"no"},{type:"text",name:"tailwindConfig",message:`Where is your ${r("tailwind.config.js")} located?`,initial:e?.tailwind.config??q},{type:"text",name:"components",message:`Configure the import alias for ${r("components")}:`,initial:e?.aliases.components??K},{type:"text",name:"utils",message:`Configure the import alias for ${r("utils")}:`,initial:e?.aliases.utils??H},{type:"toggle",name:"rsc",message:`Are you using ${r("React Server Components")}?`,initial:e?.rsc??!0,active:"yes",inactive:"no"}]),d=b.parse({$schema:"https://ui.shadcn.com/schema.json",style:a.style,tailwind:{config:a.tailwindConfig,css:a.tailwindCss,baseColor:a.tailwindBaseColor,cssVariables:a.tailwindCssVariables},rsc:a.rsc,tsx:a.typescript,aliases:{utils:a.utils,components:a.components}});if(!o){let{proceed:c}=await Ce({type:"confirm",name:"proceed",message:`Write configuration to ${r("components.json")}. Proceed?`,initial:!0});c||process.exit(0)}l.info("");let m=V("Writing components.json...").start(),g=R.resolve(t,"components.json");return await I.writeFile(g,JSON.stringify(d,null,2),"utf8"),m.succeed(),await N(t,d)}async function ut(t,e){let o=V("Initializing project...")?.start();for(let[m,g]of Object.entries(e.resolvedPaths)){let c=R.extname(g)?R.dirname(g):g;m==="utils"&&g.endsWith("/utils")&&(c=c.replace(/\/utils$/,"")),ve(c)||await I.mkdir(c,{recursive:!0})}let r=e.tsx?"ts":"js";await I.writeFile(e.resolvedPaths.tailwindConfig,e.tailwind.cssVariables?xe(we)({extension:r}):xe(ye)({extension:r}),"utf8");let n=await v(e.tailwind.baseColor);n&&await I.writeFile(e.resolvedPaths.tailwindCss,e.tailwind.cssVariables?n.cssVarsTemplate:n.inlineColorsTemplate,"utf8"),await I.writeFile(`${e.resolvedPaths.utils}.${r}`,r==="ts"?ue:he,"utf8"),o?.succeed();let i=V("Installing dependencies...")?.start(),a=await P(t),d=[...ft,e.style==="new-york"?"@radix-ui/react-icons":"lucide-react"];await mt(a,[a==="npm"?"install":"add",...d],{cwd:t}),i?.succeed()}import{Command as wt}from"commander";import ht from"path";import yt from"fs-extra";function Te(){let t=ht.join("package.json");return yt.readJSONSync(t)}process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function xt(){let t=await Te(),e=new wt().name("shadcn-ui").description("add components and dependencies to your project").version(t.version||"1.0.0","-v, --version","display the version number");e.addCommand(ze).addCommand(fe).addCommand(ge),e.parse()}xt(); | ||
} satisfies Config | ||
export default config`;import Pe from"chalk";import{Command as ut}from"commander";import{execa as ht}from"execa";import xt from"lodash.template";import J from"ora";import be from"prompts";import*as I from"zod";var yt=["tailwindcss-animate","class-variance-authority","clsx","tailwind-merge"],wt=I.object({cwd:I.string(),yes:I.boolean()}),$e=new ut().name("init").description("initialize your project and install dependencies").option("-y, --yes","skip confirmation prompt.",!1).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).action(async t=>{try{let e=wt.parse(t),o=P.resolve(e.cwd);Ee(o)||(l.error(`The path ${o} does not exist. Please try again.`),process.exit(1));let r=await C(o),n=await vt(o,r,e.yes);await Ct(o,n),l.info(""),l.info(`${Pe.green("Success!")} Project initialization completed.`),l.info("")}catch(e){T(e)}});async function vt(t,e=null,o=!1){let r=p=>Pe.cyan(p),n=await se(),i=await ae(),s=await be([{type:"toggle",name:"typescript",message:`Would you like to use ${r("TypeScript")} (recommended)?`,initial:e?.tsx??!0,active:"yes",inactive:"no"},{type:"select",name:"style",message:`Which ${r("style")} would you like to use?`,choices:n.map(p=>({title:p.label,value:p.name}))},{type:"select",name:"tailwindBaseColor",message:`Which color would you like to use as ${r("base color")}?`,choices:i.map(p=>({title:p.label,value:p.name}))},{type:"text",name:"tailwindCss",message:`Where is your ${r("global CSS")} file?`,initial:e?.tailwind.css??Z},{type:"toggle",name:"tailwindCssVariables",message:`Would you like to use ${r("CSS variables")} for colors?`,initial:e?.tailwind.cssVariables??!0,active:"yes",inactive:"no"},{type:"text",name:"tailwindPrefix",message:`Are you using a custom ${r("tailwind prefix eg. tw-")}? (Leave blank if not)`,initial:""},{type:"text",name:"tailwindConfig",message:`Where is your ${r("tailwind.config.js")} located?`,initial:e?.tailwind.config??Q},{type:"text",name:"components",message:`Configure the import alias for ${r("components")}:`,initial:e?.aliases.components??X},{type:"text",name:"utils",message:`Configure the import alias for ${r("utils")}:`,initial:e?.aliases.utils??Y},{type:"toggle",name:"rsc",message:`Are you using ${r("React Server Components")}?`,initial:e?.rsc??!0,active:"yes",inactive:"no"}]),m=$.parse({$schema:"https://ui.shadcn.com/schema.json",style:s.style,tailwind:{config:s.tailwindConfig,css:s.tailwindCss,baseColor:s.tailwindBaseColor,cssVariables:s.tailwindCssVariables,prefix:s.tailwindPrefix},rsc:s.rsc,tsx:s.typescript,aliases:{utils:s.utils,components:s.components}});if(!o){let{proceed:p}=await be({type:"confirm",name:"proceed",message:`Write configuration to ${r("components.json")}. Proceed?`,initial:!0});p||process.exit(0)}l.info("");let f=J("Writing components.json...").start(),h=P.resolve(t,"components.json");return await E.writeFile(h,JSON.stringify(m,null,2),"utf8"),f.succeed(),await R(t,m)}async function Ct(t,e){let o=J("Initializing project...")?.start();for(let[p,c]of Object.entries(e.resolvedPaths)){let u=P.extname(c)?P.dirname(c):c;p==="utils"&&c.endsWith("/utils")&&(u=u.replace(/\/utils$/,"")),Ee(u)||await E.mkdir(u,{recursive:!0})}let r=e.tsx?"ts":"js",n=P.extname(e.resolvedPaths.tailwindConfig),i;n===".ts"?i=e.tailwind.cssVariables?ze:Ie:i=e.tailwind.cssVariables?Se:Te,await E.writeFile(e.resolvedPaths.tailwindConfig,xt(i)({extension:r,prefix:e.tailwind.prefix}),"utf8");let s=await S(e.tailwind.baseColor);s&&await E.writeFile(e.resolvedPaths.tailwindCss,e.tailwind.cssVariables?e.tailwind.prefix?de(s.cssVarsTemplate,e.tailwind.prefix):s.cssVarsTemplate:s.inlineColorsTemplate,"utf8"),await E.writeFile(`${e.resolvedPaths.utils}.${r}`,r==="ts"?ve:Ce,"utf8"),o?.succeed();let m=J("Installing dependencies...")?.start(),f=await A(t),h=[...yt,e.style==="new-york"?"@radix-ui/react-icons":"lucide-react"];await ht(f,[f==="npm"?"install":"add",...h],{cwd:t}),m?.succeed()}import{Command as It}from"commander";import Tt from"path";import St from"fs-extra";function Ae(){let t=Tt.join("package.json");return St.readJSONSync(t)}process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function zt(){let t=await Ae(),e=new It().name("shadcn-ui").description("add components and dependencies to your project").version(t.version||"1.0.0","-v, --version","display the version number");e.addCommand($e).addCommand(xe).addCommand(we),e.parse()}zt(); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "shadcn-ui", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"description": "Add components to your apps.", | ||
@@ -5,0 +5,0 @@ "publishConfig": { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
115043
312