jsrepo 2.2.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {h,g,f,j,z as z$1,c,w,m,o,p,x as x$1,y,a,v,u,b,B,A,l}from'./chunk-GJE55QJV.js';import {Command,Option,program,Argument,InvalidArgumentError}from'commander';import de from'node:fs';import {outro,confirm,isCancel,cancel,multiselect,text,select,log,spinner,password,intro}from'@clack/prompts';import N from'chalk';import {resolveCommand}from'package-manager-detector/commands';import {detect}from'package-manager-detector/detect';import Z from'pathe';import*as $ from'valibot';import mi from'is-unicode-supported';import {stripVTControlCharacters}from'node:util';import {builtinModules}from'node:module';import {createPathsMatcher,getTsconfig}from'get-tsconfig';import Pn from'validate-npm-package-name';import yi from'node:os';import ts from'escape-string-regexp';import {detect as detect$1,resolveCommand as resolveCommand$1}from'package-manager-detector';import {x}from'tinyexec';import qo from'boxen';import {diffLines,diffChars}from'diff';import Vo from'semver';import {cursor,erase}from'sisteransi';import xi from'@anthropic-ai/sdk';import ji from'ollama';import Pi from'openai';import $i from'conf';import Di from'make-fetch-happen';import {Biome,Distribution}from'@biomejs/js-api';import*as rn from'css-dependency';import*as on from'prettier';import*as sn from'parse5';import ls from'oxc-parser';import {walk}from'estree-walker';import*as wn from'svelte/compiler';import*as xn from'vue/compiler-sfc';import Ys from'node-machine-id';import ta from'ignore';import {Server}from'@modelcontextprotocol/sdk/server/index.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {CallToolRequestSchema,ListToolsRequestSchema}from'@modelcontextprotocol/sdk/types.js';import*as oi from'tar';var Ot={name:"jsrepo",description:"A CLI to add shared code from remote repositories.",version:"2.2.
|
|
2
|
+
import {h,g,f,j,z as z$1,c,w,m,o,p,x as x$1,y,a,v,u,b,B,A,l}from'./chunk-GJE55QJV.js';import {Command,Option,program,Argument,InvalidArgumentError}from'commander';import de from'node:fs';import {outro,confirm,isCancel,cancel,multiselect,text,select,log,spinner,password,intro}from'@clack/prompts';import N from'chalk';import {resolveCommand}from'package-manager-detector/commands';import {detect}from'package-manager-detector/detect';import Z from'pathe';import*as $ from'valibot';import mi from'is-unicode-supported';import {stripVTControlCharacters}from'node:util';import {builtinModules}from'node:module';import {createPathsMatcher,getTsconfig}from'get-tsconfig';import Pn from'validate-npm-package-name';import yi from'node:os';import ts from'escape-string-regexp';import {detect as detect$1,resolveCommand as resolveCommand$1}from'package-manager-detector';import {x}from'tinyexec';import qo from'boxen';import {diffLines,diffChars}from'diff';import Vo from'semver';import {cursor,erase}from'sisteransi';import xi from'@anthropic-ai/sdk';import ji from'ollama';import Pi from'openai';import $i from'conf';import Di from'make-fetch-happen';import {Biome,Distribution}from'@biomejs/js-api';import*as rn from'css-dependency';import*as on from'prettier';import*as sn from'parse5';import ls from'oxc-parser';import {walk}from'estree-walker';import*as wn from'svelte/compiler';import*as xn from'vue/compiler-sfc';import Ys from'node-machine-id';import ta from'ignore';import {Server}from'@modelcontextprotocol/sdk/server/index.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {CallToolRequestSchema,ListToolsRequestSchema}from'@modelcontextprotocol/sdk/types.js';import*as oi from'tar';var Ot={name:"jsrepo",description:"A CLI to add shared code from remote repositories.",version:"2.2.1"};var ui=mi(),le=(e,t)=>ui?e:t,Ro=le("\u25C6","*"),So=le("\u25C6","*"),jo=le("\u25A0","x"),D=N.gray(le("\u2502","|")),qt=N.gray(le("\u2500","-")),Po=N.gray(le("\u2510","+")),Eo=N.gray(le("\u2518","+")),Ht=N.gray(le("\u251C","+")),Io=N.gray(le("\u252C","+"));N.gray(le("\u250C","T"));var Oo=N.gray(le("\u2514","-")),ue=N.bgRgb(245,149,66).black(" WARN "),Pe=N.bgBlueBright.white(" INFO "),Kt=N.bgRedBright.white(" ERROR "),Qe=N.hex("#f7df1e")("jsrepo"),We=N.hex("#f7df1e").bold("jsrepo.com");function fr(e,t){let r=[];for(let[o,n]of e)r.push(t(o,n));return r}function To(e,t){let r=0;for(let o of e)r=r+t(o);return r}function Do(e){let t=0;for(let r of e){let o=stripVTControlCharacters(r);o.length>t&&(t=o.length);}return t}function Yt(e,t,r=" "){let o=stripVTControlCharacters(e).length;if(o>t)throw new Error("String length is greater than the length provided.");return r.repeat(t-o)+e}function Ao(e,t,r=" "){let o=stripVTControlCharacters(e).length;if(o>t)throw new Error("String length is greater than the length provided.");return e+r.repeat(t-o)}var vi=/\n|\r\n/g;function U(e){return e.split(vi)}function z(e,{lineNumbers:t=false,prefix:r}={}){let o=e;if(t){let n=e.length.toString().length+1;o=o.map((i,s)=>`${Yt(`${s+1}`,n)} ${i}`);}return r!==void 0&&(o=o.map((n,i)=>`${r(i,e.length)}${n}`)),o.join(yi.EOL)}var wi={"no-workspace":"--no-workspace","install-as-dev-dependency":"-D"},bi={"install-as-dev-dependency":"-D"},ki={"no-workspace":"--workspaces=false","install-as-dev-dependency":"-D"},Fo={"no-workspace":"--ignore-workspace","install-as-dev-dependency":"-D"},Lo={"no-workspace":"--focus","install-as-dev-dependency":"-D"},Ar={bun:wi,npm:ki,pnpm:Fo,deno:bi,yarn:Lo,"yarn@berry":Lo,"pnpm@6":Fo};function Ve(){return new $i({projectName:"jsrepo"})}var Fr="http-registries-w-tokens",pe=class{#e;constructor(t){this.#e=t??Ve();}getKey(t){return `${t}-token`.toLowerCase()}get(t){let r=this.getKey(t),o=this.#e.get(r,void 0);return t==="jsrepo"?o??process.env.JSREPO_TOKEN:o}set(t,r){if(t.startsWith("http")){let n=this.getHttpRegistriesWithTokens(),i=t.slice(5);n||(n=[]),n.includes(i)||n.push(i),this.#e.set(Fr,n);}let o=this.getKey(t);this.#e.set(o,r);}delete(t){if(t.startsWith("http")){let o=this.getHttpRegistriesWithTokens(),n=t.slice(5),i=o.indexOf(n);i!==-1&&(o=[...o.slice(0,i),...o.slice(i+1)]),this.#e.set(Fr,o);}let r=this.getKey(t);this.#e.delete(r);}getHttpRegistriesWithTokens(){let t=this.#e.get(Fr);return t||[]}};var _r={"Claude 3.7 Sonnet":{updateFile:async({originalFile:e,newFile:t,loading:r,verbose:o,additionalInstructions:n,messages:i})=>{let s=await Bo("Anthropic");o||r.start("Asking Claude 3.7 Sonnet");let a=Lr({originalFile:e,newFile:t,additionalInstructions:n,rePrompt:i!==void 0&&i.length>0});o?.(`Prompting Claude 3.7 Sonnet with:
|
|
3
3
|
${JSON.stringify(a,null," ")}`);let c=await Ii({model:"claude-3-7-sonnet-latest",prompt:a,apiKey:s,messages:i,maxTokens:(e.content.length+t.content.length)*2});return o||r.stop("Claude 3.7 Sonnet updated the file"),c?{content:Br(c),prompt:a.message}:{content:t.content,prompt:a.message}}},"OpenAI o3-mini":{updateFile:async({originalFile:e,newFile:t,loading:r,verbose:o,additionalInstructions:n,messages:i})=>{let s=await Bo("OpenAI");o||r.start("Asking OpenAI o3-mini");let a=Lr({originalFile:e,newFile:t,additionalInstructions:n,rePrompt:i!==void 0&&i.length>0});o?.(`Prompting OpenAI o3-mini with:
|
|
4
4
|
${JSON.stringify(a,null," ")}`);let c=await Ei({model:"o3-mini",prompt:a,apiKey:s,messages:i,maxTokens:(e.content.length+t.content.length)*2});return o||r.stop("OpenAI o3-mini updated the file"),c?{content:Br(c),prompt:a.message}:{content:t.content,prompt:a.message}}},Phi4:{updateFile:async({originalFile:e,newFile:t,loading:r,verbose:o,additionalInstructions:n,messages:i})=>{o||r.start("Asking Phi4");let s=Lr({originalFile:e,newFile:t,additionalInstructions:n,rePrompt:i!==void 0&&i.length>0});o?.(`Prompting Phi4 with:
|
|
5
5
|
${JSON.stringify(s,null," ")}`);let a=await Oi({model:"phi4",prompt:s,messages:i});return o||r.stop("Phi4 updated the file"),a?{content:Br(a),prompt:s.message}:{content:t.content,prompt:s.message}}}};async function Ei({prompt:e,maxTokens:t,model:r,apiKey:o,messages:n}){let a=(await new Pi({apiKey:o}).chat.completions.create({model:r,max_completion_tokens:t,messages:[{role:"system",content:e.system},...n??[],{role:"user",content:e.message}]})).choices[0];return a.message.content===null?null:a.message.content}async function Ii({prompt:e,messages:t,maxTokens:r,model:o,apiKey:n}){let i=new xi({apiKey:n}),s=[];if(t)for(let l of t)s.push({role:l.role,content:[{type:"text",text:l.content}]});s.push({role:"user",content:[{type:"text",text:e.message}]});let c=(await i.messages.create({model:o,max_tokens:Math.min(r,8192),temperature:.5,system:e.system,messages:s})).content[0];return c.type!=="text"?null:c.text}async function Oi({prompt:e,messages:t,model:r}){return (await ji.chat({model:r,messages:[{role:"system",content:e.system},...t??[],{role:"user",content:e.message}]})).message.content}function Lr({originalFile:e,newFile:t,additionalInstructions:r,rePrompt:o}){return {system:"You will merge two files provided by the user. You will respond only with the resulting code. DO NOT format the code with markdown, DO NOT put the code inside of triple quotes, only return the code as a raw string. DO NOT make unnecessary changes.",message:o?r??"":`
|
|
@@ -93,7 +93,7 @@ ${e.meta.authors.map(i=>`- ${N.blue(i)}`).join(`
|
|
|
93
93
|
${Object.entries(e.tags).map(([i,s])=>`${N.blue(i)}: ${s}`).join(`
|
|
94
94
|
`)}
|
|
95
95
|
|
|
96
|
-
`,t}var $a=$.object({repos:$.optional($.array($.string())),watermark:$.boolean(),tests:$.optional($.boolean()),formatter:$.optional(zr),paths:$.optional($.record($.string(),$.string())),configFiles:$.optional($.record($.string(),$.string())),project:$.optional($.boolean()),registry:$.optional($.boolean()),buildScript:$.string(),publishScript:$.string(),expand:$.boolean(),maxUnchanged:$.number(),yes:$.boolean(),cache:$.boolean(),cwd:$.string()}),lo=new Command("init").description("Initializes your project with a configuration file.").argument("[registries...]","Registries to install the blocks from.",[]).option("--repos [repos...]","Repository to install the blocks from. (DEPRECATED)").option("--no-watermark","Will not add a watermark to each file upon adding it to your project.").option("--tests","Will include tests with the blocks.").addOption(new Option("--formatter <formatter>","What formatter to use when adding or updating blocks.").choices(["prettier","biome"])).addOption(new Option("--paths <category=path>,<category=path>","The paths to install the blocks to.").argParser(nr).default({})).addOption(new Option("--config-files <configFile=path>,<configFile=path>","The paths to install the config files to.").argParser(nr).default({})).option("-P, --project","Takes you through the steps to initialize a project.").option("-R, --registry","Takes you through the steps to initialize a registry.").option("--build-script <name>","The name of the build script. (For Registry setup)","build:registry").option("--publish-script <name>","The name of the publish script. (For Registry setup)","release:registry").option("-E, --expand","Expands the diff so you see the entire file.",false).option("--max-unchanged <number>","Maximum unchanged lines that will show without being collapsed.",e=>Number.parseInt(e),3).option("-y, --yes","Skip confirmation prompt.",false).option("--no-cache","Disable caching of resolved git urls.").option("--cwd <path>","The current working directory.",process.cwd()).action(async(e,t)=>{let r=$.parse($a,t);if(await ie(),r.registry!==void 0&&r.project!==void 0&&program.error(N.red(`You cannot provide both ${N.bold("--project")} and ${N.bold("--registry")} at the same time.`)),r.repos!==void 0&&log.warn(`The ${N.gray("`--repos`")} flag is deprecated! Instead supply registries as arguments. ${N.cyan(`\`jsrepo init ${r.repos.join(" ")}\``)}`),r.registry===void 0&&r.project===void 0&&e.length===0){let o=await select({message:"Initialize a project or registry?",options:[{value:"project",label:"project"},{value:"registry",label:"registry"}],initialValue:"project"});isCancel(o)&&(cancel("Canceled!"),process.exit(0)),r.project=o==="project";}r.project||e.length>0?await xa(e,r):await Ra(r),outro(N.green("All done!"));}),xa=async(e,t)=>{let r=Te(t.cwd),o=spinner(),n,i={},s=Nt(t.cwd).unwrapOr(null),a=t.paths?.["*"]??(r.isOk()?r.unwrap().paths["*"]:void 0);if(t.yes&&a===void 0&&program.error(N.red("You must provide a default path to install the blocks when using --yes.")),a===void 0){let R=await text({message:"Please enter a default path to install the blocks",validate(d){if(d.trim()==="")return "Please provide a value";if(!d.startsWith("./")){let w="Invalid path alias! If you are intending to use a relative path make sure it starts with `./`";if(s===null)return w;let x=createPathsMatcher(s);if(x&&x(d).length===0)return w}},placeholder:"./src/blocks",initialValue:a});isCancel(R)&&(cancel("Canceled!"),process.exit(0)),a=R;}if(r.isOk()?(n={...r.unwrap().paths,"*":a},i=r.unwrap().configFiles??{}):n={"*":a},n={...n,...t.paths},!t.formatter){let R=r.isErr()?"none":r.unwrap().formatter??"none";de.existsSync(Z.join(t.cwd,".prettierrc"))&&(R="prettier"),de.existsSync(Z.join(t.cwd,"biome.json"))&&(R="biome");let d=await select({message:"Which formatter would you like to use?",options:["Prettier","Biome","None"].map(w=>({value:w.toLowerCase(),label:w})),initialValue:R});isCancel(d)&&(cancel("Canceled!"),process.exit(0)),d!=="none"&&(t.formatter=d);}let c=Array.from(new Set([...e,...t.repos??[],...r.isOk()?r.unwrap().repos:[]])),l=new Set,f=new Set,m=async R=>{let d=await Ca({url:R,paths:n,configFiles:i,options:t,formatter:t.formatter});for(let w of d.dependencies)l.add(w);for(let w of d.devDependencies)f.add(w);n=d.paths,i=d.configFiles;};if(c.length>0)for(let R of c){if(!e.find(d=>d===R)&&r.isOk()&&r.unwrap().repos.find(d=>d===R)){let d=await confirm({message:`Initialize ${R}?`,initialValue:t.yes});if(isCancel(d)&&(cancel("Canceled!"),process.exit(0)),!d)continue}log.info(`Initializing ${N.cyan(R)}`),await m(R);}for(;!t.yes;){{let d=await confirm({message:c.length>0?"Add another repo?":"Add a repo?",initialValue:c.length===0});if(isCancel(d)&&(cancel("Canceled!"),process.exit(0)),!d)break}let R=await text({message:"Where should we download the blocks from?",placeholder:"github/ieedan/std",validate:d=>{if(d.trim().length===0)return "Please provide a value";if(!z$1(d))return `Invalid provider! Valid providers (${y.map(w=>w.name).join(", ")})`}});isCancel(R)&&(cancel("Canceled!"),process.exit(0)),await m(R),c.push(R);}let h={$schema:`https://unpkg.com/jsrepo@${Fe.version}/schemas/project-config.json`,repos:c,includeTests:r.isOk()&&t.tests===void 0?r.unwrap().includeTests:t.tests??false,watermark:t.watermark,formatter:t.formatter,configFiles:i,paths:n};o.start(`Writing config to \`${yt}\``);let{prettierOptions:b,biomeOptions:p}=await Ct({formatter:h.formatter,cwd:t.cwd}),g=Z.join(t.cwd,yt),v=await br.format(JSON.stringify(h,null," "),{biomeOptions:p,prettierOptions:b,filePath:g,formatter:h.formatter});de.existsSync(t.cwd)||de.mkdirSync(t.cwd,{recursive:true}),de.writeFileSync(g,v),o.stop(`Wrote config to \`${yt}\`.`);let u=(await detect$1({cwd:t.cwd}))?.agent??"npm",S=await Ze(l,f,{yes:t.yes,cwd:t.cwd,pm:u});if(S.dependencies.size>0||S.devDependencies.size>0){let R=[];if(!S.installed){if(l.size>0){let w=resolveCommand$1(u,"add",[...l]);R.push(`Install dependencies \`${N.cyan(`${w?.command} ${w?.args.join(" ")}`)}\``);}if(f.size>0){let w=resolveCommand$1(u,"add",[...f,"-D"]);R.push(`Install dev dependencies \`${N.cyan(`${w?.command} ${w?.args.join(" ")}`)}\``);}}R=R.map((w,x)=>`${x+1}. ${w}`),S.installed||R.push(""),R.push(`Add blocks with ${N.cyan("jsrepo add")}!`);let d=ft(R);process.stdout.write(d);}};async function Ca({url:e,paths:t,configFiles:r,formatter:o,options:n}){let i=spinner(),s=new pe,a=z$1(e);a||program.error(N.red(`Invalid provider! Valid providers (${y.map(p=>p.name).join(", ")})`));let c$1=a.name;if(a.name===u.name){let p=u.parse(e,{fullyQualified:false});c$1=`http-${new URL(p.url).origin}`;}if(!s.get(c$1)&&!n.yes){let p=await confirm({message:"Would you like to add an auth token?",initialValue:false});if(isCancel(p)&&(cancel("Canceled!"),process.exit(0)),p){let g=await password({message:"Paste your token",validate(v){if(v.trim()==="")return "Please provide a value"}});isCancel(g)&&(cancel("Canceled!"),process.exit(0)),s.set(c$1,g);}}i.start(`Fetching manifest from ${N.cyan(e)}`);let f=(await lt(e,{noCache:!n.cache})).match(p=>p,p=>program.error(N.red(p))),m=(await Ft(f)).match(p=>p,p=>program.error(N.red(p)));i.stop(`Fetched manifest from ${N.cyan(e)}`),Mt(f,m,n.cwd);let h=[],b=[];if(m.configFiles){let{prettierOptions:p,biomeOptions:g}=await Ct({formatter:o,cwd:n.cwd});for(let v of m.configFiles){if(v.optional&&!n.yes){let x=await confirm({message:`Would you like to add the ${v.name} file?`,initialValue:true});if(isCancel(x)&&(cancel("Canceled!"),process.exit(0)),!x)continue}if(h.push(...v.dependencies??[]),b.push(...v.devDependencies??[]),!r[v.name])if(n.configFiles?.[v.name])r[v.name]=n.configFiles[v.name];else if(n.yes)v.expectedPath||program.error(N.red(`You must provide a path for ${v.name} when using --yes!`)),r[v.name]=v.expectedPath;else {let x=await text({message:`Where is your ${v.name} file?`,defaultValue:v.expectedPath,initialValue:v.expectedPath,placeholder:v.expectedPath,validate(C){if(C.trim()==="")return "Please provide a value"}});isCancel(x)&&(cancel("Canceled!"),process.exit(0)),r[v.name]=x;}let u=Z.join(n.cwd,r[v.name]),S;if(de.existsSync(u))S=de.readFileSync(u).toString();else {let x=Z.dirname(u);if(de.existsSync(x)){let C=tn(u);if(C){S=de.readFileSync(C).toString();let j=Z.relative(n.cwd,C);log.warn(`Located ${N.bold(r[v.name])} at ${N.bold(j)}`),r[v.name]=j,u=Z.join(n.cwd,j);}}}i.start(`Fetching the ${N.cyan(v.name)} from ${N.cyan(e)}`);let R=(await Ge(f,v.path)).match(x=>x,x=>program.error(N.red(x))),d=await yr({file:{content:R,destPath:u},biomeOptions:g,prettierOptions:p,formatter:o});i.stop(`Fetched the ${N.cyan(v.name)} from ${N.cyan(e)}`);let w=n.yes||S===void 0;if(S){if(!n.yes){let x=c(f.url,v.name),C=await Dt({config:{biomeOptions:g,prettierOptions:p,formatter:o},current:{content:S,path:u},incoming:{content:d,path:x},options:{...n,loading:i,no:false}});C.applyChanges&&(w=true,S=C.updatedContent);}}else {let x=Z.dirname(u);de.existsSync(x)||de.mkdirSync(x,{recursive:true}),S=d;}w&&S&&(i.start(`Writing ${N.cyan(v.name)} to ${N.cyan(u)}`),de.writeFileSync(u,S),i.stop(`Wrote ${N.cyan(v.name)} to ${N.cyan(u)}`));}}if(!n.yes){let p=await multiselect({message:"Which category paths would you like to configure?",options:m.categories.map(g=>({label:g.name,value:g.name})),required:false});if(isCancel(p)&&(cancel("Canceled!"),process.exit(0)),p.length>0)for(let g of p){let v=t[g],u=await text({message:`Where should ${g} be added in your project?`,validate(S){if(S.trim()==="")return "Please provide a value"},placeholder:v||`./src/${g}`,defaultValue:v,initialValue:v});isCancel(u)&&(cancel("Canceled!"),process.exit(0)),t[g]=u;}}return {paths:t,configFiles:r,dependencies:h,devDependencies:b}}var Ra=async e=>{let t=spinner(),r=Z.join(e.cwd,"package.json");de.existsSync(r)||program.error(N.red(`Couldn't find your ${N.bold("package.json")}!`));let o=At(e.cwd).match(p=>p,p=>program.error(N.red(p)));for(o||(o={$schema:"",name:void 0,version:void 0,readme:"README.md",dirs:[],doNotListBlocks:[],doNotListCategories:[],listBlocks:[],listCategories:[],excludeDeps:[],includeBlocks:[],includeCategories:[],excludeBlocks:[],excludeCategories:[],preview:false}),o.$schema=`https://unpkg.com/jsrepo@${Fe.version}/schemas/registry-config.json`;;){if(o.dirs.length>0){let g=await confirm({message:"Add another blocks directory?",initialValue:false});if(isCancel(g)&&(cancel("Canceled!"),process.exit(0)),!g)break}let p=await text({message:"Where are your blocks located?",placeholder:"./src",defaultValue:"./src",initialValue:"./src",validate:g=>{if(g.trim().length===0)return "Please provide a value!"}});isCancel(p)&&(cancel("Canceled!"),process.exit(0)),o.dirs.push(p);}let n=JSON.parse(de.readFileSync(r).toString()),i=!e.yes;if(!e.yes){let p=await confirm({message:`Configure to publish to ${We}?`,initialValue:true});isCancel(p)&&(cancel("Canceled!"),process.exit(0)),i=p;}if(i){if(!o.name){let p=await text({message:"What's the name of your registry?",placeholder:"@ieedan/std",validate:g=>{if(g.trim().length===0)return "Please provide a value!"}});isCancel(p)&&(cancel("Canceled!"),process.exit(0)),o.name=p;}o.version||(o.version="0.0.1"),e.publishScript=await Zn(e.publishScript,n,e,"release:registry");}else e.buildScript=await Zn(e.buildScript,n,e,"build:registry");let s=n.devDependencies&&n.devDependencies.jsrepo!==void 0,a=(await detect$1({cwd:"cwd"}))?.agent??"npm",c="jsrepo build",l="jsrepo publish";n.scripts===void 0&&(n.scripts={}),i?n.scripts[e.publishScript]=l:n.scripts[e.buildScript]=c;let f=[];f.push({loadingMessage:"Adding script to package.json",completedMessage:"Added script to package.json",run:async()=>{try{de.writeFileSync(r,JSON.stringify(n,null," "));}catch(p){program.error(N.red(`Error writing to \`${N.bold(r)}\`. Error: ${p}`));}}}),f.push({loadingMessage:`Writing config to \`${N.cyan(vt)}\``,completedMessage:`Wrote config to \`${N.cyan(vt)}\``,run:async()=>{let p=Z.join(e.cwd,vt);try{de.writeFileSync(Z.join(p),JSON.stringify(o,null," "));}catch(g){program.error(N.red(`Error writing to \`${N.bold(p)}\`. Error: ${g}`));}}}),await Ho(f,{loading:t});let m=s;s||(m=(await Ze(new Set,new Set(["jsrepo"]),{cwd:e.cwd,pm:a,yes:e.yes})).installed);let h=[];if(!m){let p=resolveCommand$1(a,"add",["jsrepo","-D"]);h.push(`Install ${Qe} as a dev dependency \`${N.cyan(`${p?.command} ${p?.args.join(" ")}`)}\``);}if(h.push(`Add categories to \`${N.cyan(o.dirs.join(", "))}\`.`),i){let p=resolveCommand$1(a,"run",[e.publishScript]);h.push(`Run \`${N.cyan(`${p?.command} ${p?.args.join(" ")}`)}\` to publish the registry.`);}else {let p=resolveCommand$1(a,"run",[e.buildScript]);h.push(`Run \`${N.cyan(`${p?.command} ${p?.args.join(" ")}`)}\` to build the registry.`);}h=h.map((p,g)=>`${g+1}. ${p}`);let b=ft(h);process.stdout.write(b);};async function Zn(e,t,r,o){let n=e;for(;!r.yes&&t.scripts&&t.scripts[n];){let i=await confirm({message:`The \`${N.cyan(n)}\` already exists overwrite?`,initialValue:false});if(isCancel(i)&&(cancel("Canceled!"),process.exit(0)),i)break;{let s=await text({message:"What would you like to call the script?",placeholder:o,validate:a=>{if(a.trim().length===0)return "Please provide a value!"}});isCancel(s)&&(cancel("Canceled!"),process.exit(0)),n=s;}}return n}var Ia={name:"list-components",description:"Lists all available components/utilities for the provided registries.",inputSchema:{type:"object",properties:{registries:{type:"array",description:"Registries from the user's jsrepo.json `repos` key or any well-known jsrepo registry.",items:{type:"string"}}},required:["registries"]}};async function Oa(e){let t=(await ze(e)).match(o=>o,o=>{throw new Error(`Error getting registry state for ${o.repo}: ${o.message}`)}),r=(await bt(t)).match(o=>o,o=>{throw new Error(`Error getting components for ${o.repo}: ${o.message}`)});return {components:fr(r,(o,n)=>n).map(o=>{let n=`${o.category}/${o.name}`,i=c(o.sourceRepo.url,n);return {fullName:n,...o,sourceRepo:void 0,commands:{add:`jsrepo add ${i} -y -A`,update:`jsrepo update ${i} -y -A`}}})}}var Ta={name:"get-component-code",description:"Returns the associated code files for the provided component.",inputSchema:{type:"object",properties:{component:{type:"string",description:"The component to get the code for. Format: <registry>/<category>/<block>"},includeTests:{type:"boolean",description:"Should tests be included with the component code.",default:false}},required:["component"]}};async function Da({component:e,includeTests:t=false}){let r=z$1(e);if(!r)throw new Error(`${e} is not valid! Expected a category and block proceeded by the registry url i.e. @ieedan/std/<category>/<block>`);let{url:o,specifier:n}=r.parse(e,{fullyQualified:true});if(!n)throw new Error(`${e} is not valid! Expected a category and block proceeded by the registry url i.e. @ieedan/std/<category>/<block>`);let i=(await lt(o)).match(m=>m,m=>{throw new Error(`Error getting state for ${o}: ${m}`)}),s=(await Bt([i])).match(m=>m,m=>{throw new Error(`Error getting manifest for ${o}: ${m}`)}),c$1=Lt(s).get(c(o,n));if(!c$1)throw new Error(`${n} does not exist in ${o}`);let l=_t([c$1],{includeTests:t}),f=(await Promise.all(l.map(m=>m.files))).flatMap(m=>[...m.map(h=>({name:h.name,content:h.content.unwrapOr("<FETCH ERROR>")}))]);return {registry:o,component:n,files:f,commands:{add:`jsrepo add ${e} -y -A`,update:`jsrepo update ${e} -y -A`}}}var Na={name:"get-config-files",description:"Lists the config files for this registry. These are files that are either necessary for the registry to work or optional as marked by the `optional` boolean on each file.",inputSchema:{type:"object",properties:{registry:{type:"string",description:"Registry to list components from. (If not provided will return all for the current config file.)",examples:["@ieedan/std","github/ieedan/std","gitlab/ieedan/std","bitbucket/ieedan/std","azure/ieedan/std/std","https://example.com/r"]},requiredOnly:{type:"boolean",description:"When true only returns the config files required for the registry to work properly."}},required:["registry"]}};async function Aa({registry:e,requiredOnly:t=false}){let r=(await lt(e)).match(i=>i,i=>{throw new Error(`Error getting state for ${e}: ${i}`)}),o=(await Ft(r)).match(i=>i,i=>{throw new Error(`Error getting manifest for ${e}: ${i}`)});return !o.configFiles||o.configFiles.length===0?[]:{configFiles:await Promise.all(o.configFiles.filter(i=>!t||!i.optional).map(async i=>{let s=(await Ge(r,i.path)).unwrapOr("<FETCH ERROR>");return {...i,content:s}}))}}var Fa={name:"discover-registries",description:"Searches jsrepo.com for registries that could include components the user needs in their project.",inputSchema:{type:"object",properties:{primaryLanguage:{type:"string",description:"File extension of the primary language of the registry. i.e. TypeScript -> ts, React -> tsx/jsx"}},required:["primaryLanguage"]}};async function La({primaryLanguage:e}){let t=await ke(`${w}/api/registries?lang=${e}`);if(!t.ok)return [];let{data:r}=await t.json();return {registries:r.map(o=>{let n=`@${o.scope.name}/${o.name}`;return {name:n,description:o.metaDescription,repository:o.metaRepository,keywords:o.metaTags,homepage:o.metaHomepage,rating:o.rating,primaryLanguage:o.metaPrimaryLanguage,monthlyDownloads:o.monthlyFetches,latestVersion:o.latestVersion,access:o.access,commands:{init:`jsrepo init ${n}`}}})}}var Ba={name:"cli-reference",description:"A reference for the usage of the jsrepo CLI.",inputSchema:{type:"object"}};function _a(){return {name:Et.name(),description:Et.description(),version:Et.version(),commands:Et.commands.map(e=>({name:e.name(),description:e.description(),usage:e.usage(),options:e.options.map(t=>({flags:t.flags,description:t.description,defaultValue:t.defaultValue}))}))}}async function ri(){let e=new Server({name:"jsrepo",version:Fe.version},{capabilities:{tools:{},resources:{}}});e.setRequestHandler(CallToolRequestSchema,async r=>{console.error(`Received CallToolRequest calling: ${N.bold(r.params.name)}`);try{switch(r.params.name){case "list-components":{let o=r.params.arguments,n=await Oa(o.registries);return {content:[{type:"text",text:JSON.stringify(n)}]}}case "get-component-code":{let o=r.params.arguments,n=await Da(o);return {content:[{type:"text",text:JSON.stringify(n)}]}}case "get-config-files":{let o=r.params.arguments,n=await Aa(o);return {content:[{type:"text",text:JSON.stringify(n)}]}}case "discover-registries":{let o=r.params.arguments,n=await La(o);return {content:[{type:"text",text:JSON.stringify(n)}]}}case "cli-reference":{let o=_a();return {content:[{type:"text",text:JSON.stringify(o)}]}}}throw new Error(`Invalid tool ${r.params.name}`)}catch(o){return console.error(N.red(`Error executing tool ${N.bold(r.params.name)}: ${o}`)),{content:[{type:"text",text:JSON.stringify({error:o instanceof Error?o.message:String(o)})}]}}}),e.setRequestHandler(ListToolsRequestSchema,async()=>(console.error("Received ListToolsRequest"),{tools:[Ia,Ta,Na,Fa,Ba]}));let t=new StdioServerTransport;console.error("Connecting server to transport..."),await e.connect(t),console.error("Server connected");}var fo=new Command("mcp").description("Interact with jsrepo through an MCP server.").option("--cwd <path>","The current working directory.",process.cwd()).action(async()=>{await ri().catch(e=>{console.error(e),process.exit(1);});});var Ga=$.object({private:$.boolean(),dryRun:$.boolean(),name:$.optional($.string()),ver:$.optional($.string()),dirs:$.optional($.array($.string())),includeBlocks:$.optional($.array($.string())),includeCategories:$.optional($.array($.string())),excludeBlocks:$.optional($.array($.string())),excludeCategories:$.optional($.array($.string())),excludeDeps:$.optional($.array($.string())),listBlocks:$.optional($.array($.string())),listCategories:$.optional($.array($.string())),doNotListBlocks:$.optional($.array($.string())),doNotListCategories:$.optional($.array($.string())),allowSubdirectories:$.optional($.boolean()),verbose:$.boolean(),cwd:$.string()}),mo=new Command("publish").description("Publish a registry to jsrepo.com.").option("--private","When publishing the first version of the registry make it private.",false).option("--dry-run","Test the publish but don't list on jsrepo.com.",false).option("--name <name>","The name of the registry. i.e. @ieedan/std").option("--ver <version>","The version of the registry. i.e. 0.0.1").option("--dirs [dirs...]","The directories containing the blocks.").option("--include-blocks [blockNames...]","Include only the blocks with these names.").option("--include-categories [categoryNames...]","Include only the categories with these names.").option("--exclude-blocks [blockNames...]","Do not include the blocks with these names.").option("--exclude-categories [categoryNames...]","Do not include the categories with these names.").option("--list-blocks [blockNames...]","List only the blocks with these names.").option("--list-categories [categoryNames...]","List only the categories with these names.").option("--do-not-list-blocks [blockNames...]","Do not list the blocks with these names.").option("--do-not-list-categories [categoryNames...]","Do not list the categories with these names.").option("--exclude-deps [deps...]","Dependencies that should not be added.").option("--allow-subdirectories","Allow subdirectories to be built.").option("--verbose","Include debug logs.",false).option("--cwd <path>","The current working directory.",process.cwd()).action(async e=>{let t=$.parse(Ga,e);await ie(),await za(t),outro(N.green("All done!"));});async function za(e){let t=d=>{e.verbose&&console.info(`${Pe} ${d}`);},r=he({verbose:e.verbose?t:void 0}),o=At(e.cwd).match(d=>{if(d===null)return {$schema:"",access:"public",readme:"README.md",dirs:e.dirs??[],doNotListBlocks:e.doNotListBlocks??[],doNotListCategories:e.doNotListCategories??[],listBlocks:e.listBlocks??[],listCategories:e.listCategories??[],excludeDeps:e.excludeDeps??[],includeBlocks:e.includeBlocks??[],includeCategories:e.includeCategories??[],excludeBlocks:e.excludeBlocks??[],excludeCategories:e.excludeCategories??[],allowSubdirectories:e.allowSubdirectories};let w=d;return e.private&&(w.access="private"),e.name&&(w.name=e.name),e.ver&&(w.version=e.ver),e.dirs&&(w.dirs=e.dirs),e.doNotListBlocks&&(w.doNotListBlocks=e.doNotListBlocks),e.doNotListCategories&&(w.doNotListCategories=e.doNotListCategories),e.listBlocks&&(w.listBlocks=e.listBlocks),e.listCategories&&(w.listCategories=e.listCategories),e.includeBlocks&&(w.includeBlocks=e.includeBlocks),e.includeCategories&&(w.includeCategories=e.includeCategories),e.excludeBlocks&&(w.excludeBlocks=e.excludeBlocks),e.excludeCategories&&(w.excludeCategories=e.excludeCategories),e.excludeDeps&&(w.excludeDeps=e.excludeDeps),e.allowSubdirectories!==void 0&&(w.allowSubdirectories=e.allowSubdirectories),w.rules={...Zt,...w.rules},w},d=>program.error(N.red(d)));if(e.dryRun&&log.warn(N.bgYellow.black(" DRY RUN ")),o.name!==void 0)try{let[d,w,...x]=o.name.split("/");if(x.length>0)throw new Error;if(!d.startsWith("@"))throw new Error;if(!d.slice(1).match(v))throw new Error;if(!w.match(v))throw new Error}catch{program.error(N.red(`\`${o.name}\` is not a valid name. The name should be provided as \`@<scope>/<registry>\``));}else program.error(N.red(`To publish to ${N.bold("jsrepo.com")} you need to provide the \`name\` field in the \`jsrepo-build-config.json\``));if(o.version!==void 0){if(o.version==="package"){let w=Z.join(e.cwd,"package.json");de.existsSync(w)||program.error(N.red(`Couldn't find your ${N.bold("package.json")}!`));let{version:x}=JSON.parse(de.readFileSync(w).toString());o.version=x;}Vo.valid(o.version)||program.error(`\`${o.version}\` is not a valid semver version.`);}else program.error(N.red(`To publish to ${N.bold("jsrepo.com")} you need to provide the \`version\` field in the \`jsrepo-build-config.json\``));let n=new pe().get("jsrepo");n===void 0&&program.error(N.red(`Please authenticate with ${N.cyan("jsrepo auth")} to publish to ${We}.`));let i=[],s=ta();try{let d=de.readFileSync(Z.join(e.cwd,".gitignore")).toString();s.add(d);}catch{}s.add(Er);for(let d of o.dirs){let w=Z.join(e.cwd,d);r.start(`Building ${N.cyan(w)}`);let x=Cr(w,{cwd:e.cwd,ignore:s,config:o});for(let C of x){if(i.find(j=>j.name===C.name)!==void 0){console.warn(`${D} ${ue} Skipped adding \`${N.cyan(`${d}/${C.name}`)}\` because a category with the same name already exists!`);continue}i.push(C);}r.stop(`Built ${N.cyan(w)}`);}let a=Rr(o,{cwd:e.cwd}),c=p(i,a,o);r.start("Checking manifest");let{warnings:l,errors:f}=xr(c,o,e.cwd,o.rules);r.stop("Completed checking manifest."),(l.length>0||f.length>0)&&console.log(D);for(let d of l)console.log(d);if(f.length>0){for(let d of f)console.log(d);program.error(N.red(`Completed checking manifest with ${N.bold(`${f.length} error(s)`)} and ${N.bold(`${l.length} warning(s)`)}`));}let[m,h]=Sr(c.categories);c.categories=m,h>0&&log.step(`Removed ${h} unused block${h>1?"s":""}.`),r.start(`Packaging ${N.cyan(c.name)}...`);let b=Z.resolve(e.cwd,`jsrepo-publish-temp-${Date.now()}`);t(`Creating temp dir: ${b}`),de.mkdirSync(b,{recursive:true}),t("Writing manifest to temp dir"),de.writeFileSync(Z.resolve(b,"jsrepo-manifest.json"),JSON.stringify(c));let p$1=Z.resolve(e.cwd,o.readme);try{t("Attempting to copy readme"),de.copyFileSync(p$1,Z.join(b,"README.md")),t("Copied readme");}catch{t("No readme found.");}if(c.configFiles){t("Copying config files");for(let d of c.configFiles){let w=Z.join(e.cwd,d.path),x=Z.join(b,d.path),C=Z.join(x,"../");de.existsSync(C)||de.mkdirSync(C,{recursive:true}),de.copyFileSync(w,x);}t("Copied config files");}t("Copying registry files");for(let d of c.categories)for(let w of d.blocks){let x=Z.join(e.cwd,w.directory),C=Z.join(b,w.directory);for(let j of w.files){let X=Z.join(C,j,"../");de.existsSync(X)||de.mkdirSync(X,{recursive:true}),de.copyFileSync(Z.join(x,j),Z.join(C,j));}}t("Copied registry files");let g=Z.resolve(e.cwd,`${o.name.replace("/","_")}-package.tar.gz`),v$1=de.readdirSync(b);t("Creating archive file"),await oi.create({z:true,cwd:b,file:g},v$1),t("Created archive file"),t("Removing temp directory"),de.rmSync(b,{force:true,recursive:true}),t("Removed temp directory"),r.stop(`Created package ${N.cyan(g)}...`);let u=o.access??"public";log.info(`Publishing to jsrepo with the access set to ${N.cyan(u)}`),r.start(`Publishing ${N.bold(c.name)} to ${We}...`);let S=de.readFileSync(g);t("Removing archive file"),de.rmSync(g,{force:true,recursive:true}),t("Removed archive file"),t(`Publishing to ${`${w}/api/publish`}`);let R=await ke(`${w}/api/publish`,{body:S,headers:{"content-type":"application/gzip","content-encoding":"gzip","x-api-key":n,"x-dry-run":e.dryRun?"1":"0","x-access":u},method:"POST"});if(r.stop(`Got response from ${We}.`),R.ok){let d=await R.json();d.status==="dry-run"?log.success(`${N.hex("#f7df1e").bold("[jsrepo.com]")} Completed dry run!`):log.success(`${N.hex("#f7df1e").bold("[jsrepo.com]")} published ${N.greenBright(`@${d.scope}`)}/${d.registry}${N.greenBright(`@${d.version}`)}!`);}else {let d=await R.json();program.error(N.red(`${N.bold("[jsrepo.com]")} ${N.bold(R.status)} ${d.message}`));}}var nc=$.object({repo:$.optional($.string()),allow:$.boolean(),debug:$.boolean(),cache:$.boolean(),verbose:$.boolean(),cwd:$.string()}),uo=new Command("test").description("Tests local blocks against most recent remote tests.").addArgument(new Argument("[blocks...]","The blocks you want to test.").default([])).option("--repo <repo>","Repository to download the blocks from.").option("-A, --allow","Allow jsrepo to download code from the provided repo.",false).option("--debug","Leaves the temp test file around for debugging upon failure.",false).option("--no-cache","Disable caching of resolved git urls.").option("--verbose","Include debug logs.",false).option("--cwd <path>","The current working directory.",process.cwd()).action(async(e,t)=>{let r=$.parse(nc,t);await ie(),await ic(e,r),outro(N.green("All done!"));});async function ic(e,t){let r=u=>{t.verbose&&console.info(`${Pe} ${u}`);};r(`Attempting to test ${JSON.stringify(e)}`);let o=Te(t.cwd).match(u=>u,u=>program.error(N.red(u))),n=he({verbose:t.verbose?r:void 0}),i=o.repos;if(t.repo&&(i=[t.repo]),!t.allow&&t.repo){let u=await confirm({message:`Allow ${N.cyan("jsrepo")} to download and run code from ${N.cyan(t.repo)}?`,initialValue:true});(isCancel(u)||!u)&&(cancel("Canceled!"),process.exit(0));}t.verbose||n.start(`Fetching blocks from ${N.cyan(i.join(", "))}`);let s=(await ze(i,{noCache:!t.cache})).match(u=>u,({repo:u,message:S})=>{n.stop(`Failed to get info for ${N.cyan(u)}`),program.error(N.red(S));});r(`Resolved ${N.cyan(i.join(", "))}`),r(`Fetching blocks from ${N.cyan(i.join(", "))}`);let a=(await bt(s,{verbose:t.verbose?r:void 0})).match(u=>u,({repo:u,message:S})=>{n.stop(`Failed fetching blocks from ${N.cyan(u)}`),program.error(N.red(S));});r(`Retrieved blocks from ${N.cyan(i.join(", "))}`),t.verbose||n.stop(`Retrieved blocks from ${N.cyan(i.join(", "))}`);let c$1=Z.resolve(Z.join(t.cwd,`blocks-tests-temp-${Date.now()}`));r(`Trying to create the temp directory ${N.bold(c$1)}.`),de.mkdirSync(c$1,{recursive:true});let l=()=>{de.rmSync(c$1,{recursive:true,force:true});},f=xt(a,o,t.cwd).map(u=>u.specifier),m=e;e.length===0&&(m=f),m.length===0&&(l(),program.error(N.red("There were no blocks found in your project!")));let h=[];for(let u of m){let S,R=z$1(u);if(R){let{url:d}=R.parse(u,{fullyQualified:true}),w=(await lt(d)).match(C=>C,C=>program.error(N.red(C))),x=(await bt([w])).match(C=>C,C=>program.error(N.red(C)));for(let[C,j]of x)a.set(C,j);S=a.get(u);}else for(let d of i){let w=z$1(d);if(!w)continue;let{url:x,specifier:C}=w.parse(c(d,u),{fullyQualified:true}),j=a.get(c(x,C));if(j!==void 0){S=j;break}}S||program.error(N.red(`Invalid block! ${N.bold(u)} does not exist!`)),h.push({name:u,block:S});}let b=Ue(o.paths,t.cwd).match(u=>u,u=>program.error(N.red(u)));for(let{block:u}of h){let S=u.sourceRepo,R=c(u.sourceRepo.url,u.category,u.name);if(t.verbose||n.start(`Setting up test file for ${N.cyan(R)}`),!u.tests){n.stop(`No tests found for ${N.cyan(R)}`);continue}let d=tr(u,b,t.cwd);d=Z.relative(c$1,d);let w=async C=>{let j=await Ge(S,C);return j.isErr()&&(n.stop(N.red(`Error fetching ${N.bold(C)}`)),program.error(N.red(`There was an error trying to get ${R}`))),j.unwrap()};r(`Downloading and copying test files for ${R}`);let x=[];for(let C of u.files.filter(j=>ct(j))){let j=await w(Z.join(u.directory,C)),X=Z.join(c$1,C);de.writeFileSync(X,j),x.push(X);}for(let C of x){r(`Opening test file ${C}`);let j=de.readFileSync(C).toString(),X=ls.parseSync(C,j);for(let oe of X.module.staticImports){let Y=oe.moduleRequest.value,k;if(Y.startsWith(".")&&(u.subdirectory?k=Z.join(d,u.name,Y):k=Z.join(d,Y)),k){let A=new RegExp(`(['"])${ts(Y)}\\1`,"g");j=j.replaceAll(A,`$1${k}$1`);}}de.writeFileSync(C,j);}r(`Completed ${N.cyan.bold(R)} test file`),t.verbose||n.stop(`Completed setup for ${N.bold(R)}`);}r("Beginning testing");let p=await detect({cwd:t.cwd});p==null&&program.error(N.red("Could not detect package manager"));let g=resolveCommand(p.agent,"execute",["vitest","run",c$1]);g==null&&program.error(N.red(`Could not resolve add command for '${p.agent}'.`));let v=`${g.command} ${g.args.join(" ")}`;r(`Running ${N.cyan(v)} on ${N.cyan(t.cwd)}`);try{let u=x(g.command,g.args,{nodeOptions:{cwd:t.cwd}});for await(let S of u)process.stdout.write(`${S}
|
|
96
|
+
`,t}var $a=$.object({repos:$.optional($.array($.string())),watermark:$.boolean(),tests:$.optional($.boolean()),formatter:$.optional(zr),paths:$.optional($.record($.string(),$.string())),configFiles:$.optional($.record($.string(),$.string())),project:$.optional($.boolean()),registry:$.optional($.boolean()),buildScript:$.string(),publishScript:$.string(),expand:$.boolean(),maxUnchanged:$.number(),yes:$.boolean(),cache:$.boolean(),cwd:$.string()}),lo=new Command("init").description("Initializes your project with a configuration file.").argument("[registries...]","Registries to install the blocks from.",[]).option("--repos [repos...]","Repository to install the blocks from. (DEPRECATED)").option("--no-watermark","Will not add a watermark to each file upon adding it to your project.").option("--tests","Will include tests with the blocks.").addOption(new Option("--formatter <formatter>","What formatter to use when adding or updating blocks.").choices(["prettier","biome"])).addOption(new Option("--paths <category=path>,<category=path>","The paths to install the blocks to.").argParser(nr).default({})).addOption(new Option("--config-files <configFile=path>,<configFile=path>","The paths to install the config files to.").argParser(nr).default({})).option("-P, --project","Takes you through the steps to initialize a project.").option("-R, --registry","Takes you through the steps to initialize a registry.").option("--build-script <name>","The name of the build script. (For Registry setup)","build:registry").option("--publish-script <name>","The name of the publish script. (For Registry setup)","release:registry").option("-E, --expand","Expands the diff so you see the entire file.",false).option("--max-unchanged <number>","Maximum unchanged lines that will show without being collapsed.",e=>Number.parseInt(e),3).option("-y, --yes","Skip confirmation prompt.",false).option("--no-cache","Disable caching of resolved git urls.").option("--cwd <path>","The current working directory.",process.cwd()).action(async(e,t)=>{let r=$.parse($a,t);if(await ie(),r.registry!==void 0&&r.project!==void 0&&program.error(N.red(`You cannot provide both ${N.bold("--project")} and ${N.bold("--registry")} at the same time.`)),r.repos!==void 0&&log.warn(`The ${N.gray("`--repos`")} flag is deprecated! Instead supply registries as arguments. ${N.cyan(`\`jsrepo init ${r.repos.join(" ")}\``)}`),r.registry===void 0&&r.project===void 0&&e.length===0){let o=await select({message:"Initialize a project or registry?",options:[{value:"project",label:"project"},{value:"registry",label:"registry"}],initialValue:"project"});isCancel(o)&&(cancel("Canceled!"),process.exit(0)),r.project=o==="project";}r.project||e.length>0?await xa(e,r):await Ra(r),outro(N.green("All done!"));}),xa=async(e,t)=>{let r=Te(t.cwd),o=spinner(),n,i={},s=Nt(t.cwd).unwrapOr(null),a=t.paths?.["*"]??(r.isOk()?r.unwrap().paths["*"]:void 0);if(t.yes&&a===void 0&&program.error(N.red("You must provide a default path to install the blocks when using --yes.")),a===void 0){let R=await text({message:"Please enter a default path to install the blocks",validate(d){if(d.trim()==="")return "Please provide a value";if(!d.startsWith("./")){let w="Invalid path alias! If you are intending to use a relative path make sure it starts with `./`";if(s===null)return w;let x=createPathsMatcher(s);if(x&&x(d).length===0)return w}},placeholder:"./src/blocks",initialValue:a});isCancel(R)&&(cancel("Canceled!"),process.exit(0)),a=R;}if(r.isOk()?(n={...r.unwrap().paths,"*":a},i=r.unwrap().configFiles??{}):n={"*":a},n={...n,...t.paths},!t.formatter){let R=r.isErr()?"none":r.unwrap().formatter??"none";de.existsSync(Z.join(t.cwd,".prettierrc"))&&(R="prettier"),de.existsSync(Z.join(t.cwd,"biome.json"))&&(R="biome");let d=await select({message:"Which formatter would you like to use?",options:["Prettier","Biome","None"].map(w=>({value:w.toLowerCase(),label:w})),initialValue:R});isCancel(d)&&(cancel("Canceled!"),process.exit(0)),d!=="none"&&(t.formatter=d);}let c=Array.from(new Set([...e,...t.repos??[],...r.isOk()?r.unwrap().repos:[]])),l=new Set,f=new Set,m=async R=>{let d=await Ca({url:R,paths:n,configFiles:i,options:t,formatter:t.formatter});for(let w of d.dependencies)l.add(w);for(let w of d.devDependencies)f.add(w);n=d.paths,i=d.configFiles;};if(c.length>0)for(let R of c){if(!e.find(d=>d===R)&&r.isOk()&&r.unwrap().repos.find(d=>d===R)){let d=await confirm({message:`Initialize ${R}?`,initialValue:t.yes});if(isCancel(d)&&(cancel("Canceled!"),process.exit(0)),!d)continue}log.info(`Initializing ${N.cyan(R)}`),await m(R);}for(;!t.yes;){{let d=await confirm({message:c.length>0?"Add another repo?":"Add a repo?",initialValue:c.length===0});if(isCancel(d)&&(cancel("Canceled!"),process.exit(0)),!d)break}let R=await text({message:"Where should we download the blocks from?",placeholder:"github/ieedan/std",validate:d=>{if(d.trim().length===0)return "Please provide a value";if(!z$1(d))return `Invalid provider! Valid providers (${y.map(w=>w.name).join(", ")})`}});isCancel(R)&&(cancel("Canceled!"),process.exit(0)),await m(R),c.push(R);}let h={$schema:`https://unpkg.com/jsrepo@${Fe.version}/schemas/project-config.json`,repos:c,includeTests:r.isOk()&&t.tests===void 0?r.unwrap().includeTests:t.tests??false,watermark:t.watermark,formatter:t.formatter,configFiles:i,paths:n};o.start(`Writing config to \`${yt}\``);let{prettierOptions:b,biomeOptions:p}=await Ct({formatter:h.formatter,cwd:t.cwd}),g=Z.join(t.cwd,yt),v=await br.format(JSON.stringify(h,null," "),{biomeOptions:p,prettierOptions:b,filePath:g,formatter:h.formatter});de.existsSync(t.cwd)||de.mkdirSync(t.cwd,{recursive:true}),de.writeFileSync(g,v),o.stop(`Wrote config to \`${yt}\`.`);let u=(await detect$1({cwd:t.cwd}))?.agent??"npm",S=await Ze(l,f,{yes:t.yes,cwd:t.cwd,pm:u});if(S.dependencies.size>0||S.devDependencies.size>0){let R=[];if(!S.installed){if(l.size>0){let w=resolveCommand$1(u,"add",[...l]);R.push(`Install dependencies \`${N.cyan(`${w?.command} ${w?.args.join(" ")}`)}\``);}if(f.size>0){let w=resolveCommand$1(u,"add",[...f,"-D"]);R.push(`Install dev dependencies \`${N.cyan(`${w?.command} ${w?.args.join(" ")}`)}\``);}}R=R.map((w,x)=>`${x+1}. ${w}`),S.installed||R.push(""),R.push(`Add blocks with ${N.cyan("jsrepo add")}!`);let d=ft(R);process.stdout.write(d);}};async function Ca({url:e,paths:t,configFiles:r,formatter:o,options:n}){let i=spinner(),s=new pe,a=z$1(e);a||program.error(N.red(`Invalid provider! Valid providers (${y.map(p=>p.name).join(", ")})`));let c$1=a.name;if(a.name===u.name){let p=u.parse(e,{fullyQualified:false});c$1=`http-${new URL(p.url).origin}`;}if(!s.get(c$1)&&!n.yes){let p=await confirm({message:"Would you like to add an auth token?",initialValue:false});if(isCancel(p)&&(cancel("Canceled!"),process.exit(0)),p){let g=await password({message:"Paste your token",validate(v){if(v.trim()==="")return "Please provide a value"}});isCancel(g)&&(cancel("Canceled!"),process.exit(0)),s.set(c$1,g);}}i.start(`Fetching manifest from ${N.cyan(e)}`);let f=(await lt(e,{noCache:!n.cache})).match(p=>p,p=>program.error(N.red(p))),m=(await Ft(f)).match(p=>p,p=>program.error(N.red(p)));i.stop(`Fetched manifest from ${N.cyan(e)}`),Mt(f,m,n.cwd);let h=[],b=[];if(m.configFiles){let{prettierOptions:p,biomeOptions:g}=await Ct({formatter:o,cwd:n.cwd});for(let v of m.configFiles){if(v.optional&&!n.yes){let x=await confirm({message:`Would you like to add the ${v.name} file?`,initialValue:true});if(isCancel(x)&&(cancel("Canceled!"),process.exit(0)),!x)continue}if(h.push(...v.dependencies??[]),b.push(...v.devDependencies??[]),!r[v.name])if(n.configFiles?.[v.name])r[v.name]=n.configFiles[v.name];else if(n.yes)v.expectedPath||program.error(N.red(`You must provide a path for ${v.name} when using --yes!`)),r[v.name]=v.expectedPath;else {let x=await text({message:`Where is your ${v.name} file?`,defaultValue:v.expectedPath,initialValue:v.expectedPath,placeholder:v.expectedPath,validate(C){if(C.trim()==="")return "Please provide a value"}});isCancel(x)&&(cancel("Canceled!"),process.exit(0)),r[v.name]=x;}let u=Z.join(n.cwd,r[v.name]),S;if(de.existsSync(u))S=de.readFileSync(u).toString();else {let x=Z.dirname(u);if(de.existsSync(x)){let C=tn(u);if(C){S=de.readFileSync(C).toString();let j=Z.relative(n.cwd,C);log.warn(`Located ${N.bold(r[v.name])} at ${N.bold(j)}`),r[v.name]=j,u=Z.join(n.cwd,j);}}}i.start(`Fetching the ${N.cyan(v.name)} from ${N.cyan(e)}`);let R=(await Ge(f,v.path)).match(x=>x,x=>program.error(N.red(x))),d=await yr({file:{content:R,destPath:u},biomeOptions:g,prettierOptions:p,formatter:o});i.stop(`Fetched the ${N.cyan(v.name)} from ${N.cyan(e)}`);let w=n.yes||S===void 0;if(S){if(!n.yes){let x=c(f.url,v.name),C=await Dt({config:{biomeOptions:g,prettierOptions:p,formatter:o},current:{content:S,path:u},incoming:{content:d,path:x},options:{...n,loading:i,no:false}});C.applyChanges&&(w=true,S=C.updatedContent);}}else {let x=Z.dirname(u);de.existsSync(x)||de.mkdirSync(x,{recursive:true}),S=d;}w&&S&&(i.start(`Writing ${N.cyan(v.name)} to ${N.cyan(u)}`),de.writeFileSync(u,S),i.stop(`Wrote ${N.cyan(v.name)} to ${N.cyan(u)}`));}}if(!n.yes){let p=await multiselect({message:"Which category paths would you like to configure?",options:m.categories.map(g=>({label:g.name,value:g.name})),required:false});if(isCancel(p)&&(cancel("Canceled!"),process.exit(0)),p.length>0)for(let g of p){let v=t[g],u=await text({message:`Where should ${g} be added in your project?`,validate(S){if(S.trim()==="")return "Please provide a value"},placeholder:v||`./src/${g}`,defaultValue:v,initialValue:v});isCancel(u)&&(cancel("Canceled!"),process.exit(0)),t[g]=u;}}return {paths:t,configFiles:r,dependencies:h,devDependencies:b}}var Ra=async e=>{let t=spinner(),r=Z.join(e.cwd,"package.json");de.existsSync(r)||program.error(N.red(`Couldn't find your ${N.bold("package.json")}!`));let o=At(e.cwd).match(p=>p,p=>program.error(N.red(p)));for(o||(o={$schema:"",name:void 0,version:void 0,readme:"README.md",dirs:[],doNotListBlocks:[],doNotListCategories:[],listBlocks:[],listCategories:[],excludeDeps:[],includeBlocks:[],includeCategories:[],excludeBlocks:[],excludeCategories:[],preview:false}),o.$schema=`https://unpkg.com/jsrepo@${Fe.version}/schemas/registry-config.json`;;){if(o.dirs.length>0){let g=await confirm({message:"Add another blocks directory?",initialValue:false});if(isCancel(g)&&(cancel("Canceled!"),process.exit(0)),!g)break}let p=await text({message:"Where are your blocks located?",placeholder:"./src",defaultValue:"./src",initialValue:"./src",validate:g=>{if(g.trim().length===0)return "Please provide a value!"}});isCancel(p)&&(cancel("Canceled!"),process.exit(0)),o.dirs.push(p);}let n=JSON.parse(de.readFileSync(r).toString()),i=!e.yes;if(!e.yes){let p=await confirm({message:`Configure to publish to ${We}?`,initialValue:true});isCancel(p)&&(cancel("Canceled!"),process.exit(0)),i=p;}if(i){if(!o.name){let p=await text({message:"What's the name of your registry?",placeholder:"@ieedan/std",validate:g=>{if(g.trim().length===0)return "Please provide a value!"}});isCancel(p)&&(cancel("Canceled!"),process.exit(0)),o.name=p;}o.version||(o.version="0.0.1"),e.publishScript=await Zn(e.publishScript,n,e,"release:registry");}else e.buildScript=await Zn(e.buildScript,n,e,"build:registry");let s=n.devDependencies&&n.devDependencies.jsrepo!==void 0,a=(await detect$1({cwd:"cwd"}))?.agent??"npm",c="jsrepo build",l="jsrepo publish";n.scripts===void 0&&(n.scripts={}),i?n.scripts[e.publishScript]=l:n.scripts[e.buildScript]=c;let f=[];f.push({loadingMessage:"Adding script to package.json",completedMessage:"Added script to package.json",run:async()=>{try{de.writeFileSync(r,JSON.stringify(n,null," "));}catch(p){program.error(N.red(`Error writing to \`${N.bold(r)}\`. Error: ${p}`));}}}),f.push({loadingMessage:`Writing config to \`${N.cyan(vt)}\``,completedMessage:`Wrote config to \`${N.cyan(vt)}\``,run:async()=>{let p=Z.join(e.cwd,vt);try{de.writeFileSync(Z.join(p),JSON.stringify(o,null," "));}catch(g){program.error(N.red(`Error writing to \`${N.bold(p)}\`. Error: ${g}`));}}}),await Ho(f,{loading:t});let m=s;s||(m=(await Ze(new Set,new Set(["jsrepo"]),{cwd:e.cwd,pm:a,yes:e.yes})).installed);let h=[];if(!m){let p=resolveCommand$1(a,"add",["jsrepo","-D"]);h.push(`Install ${Qe} as a dev dependency \`${N.cyan(`${p?.command} ${p?.args.join(" ")}`)}\``);}if(h.push(`Add categories to \`${N.cyan(o.dirs.join(", "))}\`.`),i){let p=resolveCommand$1(a,"run",[e.publishScript]);h.push(`Run \`${N.cyan(`${p?.command} ${p?.args.join(" ")}`)}\` to publish the registry.`);}else {let p=resolveCommand$1(a,"run",[e.buildScript]);h.push(`Run \`${N.cyan(`${p?.command} ${p?.args.join(" ")}`)}\` to build the registry.`);}h=h.map((p,g)=>`${g+1}. ${p}`);let b=ft(h);process.stdout.write(b);};async function Zn(e,t,r,o){let n=e;for(;!r.yes&&t.scripts&&t.scripts[n];){let i=await confirm({message:`The \`${N.cyan(n)}\` already exists overwrite?`,initialValue:false});if(isCancel(i)&&(cancel("Canceled!"),process.exit(0)),i)break;{let s=await text({message:"What would you like to call the script?",placeholder:o,validate:a=>{if(a.trim().length===0)return "Please provide a value!"}});isCancel(s)&&(cancel("Canceled!"),process.exit(0)),n=s;}}return n}var Ia={name:"list-components",description:"Lists all available components/utilities for the provided registries.",inputSchema:{type:"object",properties:{registries:{type:"array",description:"Registries from the user's jsrepo.json `repos` key or any well-known jsrepo registry.",items:{type:"string"}}},required:["registries"]}};async function Oa(e){let t=(await ze(e)).match(o=>o,o=>{throw new Error(`Error getting registry state for ${o.repo}: ${o.message}`)}),r=(await bt(t)).match(o=>o,o=>{throw new Error(`Error getting components for ${o.repo}: ${o.message}`)});return {components:fr(r,(o,n)=>n).map(o=>{let n=`${o.category}/${o.name}`,i=c(o.sourceRepo.url,n);return {fullName:n,...o,sourceRepo:void 0,commands:{add:`jsrepo add ${i} -y -A`,update:`jsrepo update ${i} -y -A`}}})}}var Ta={name:"get-component-code",description:"Returns the associated code files for the provided component.",inputSchema:{type:"object",properties:{component:{type:"string",description:"The component to get the code for. Format: <registry>/<category>/<block>"},includeTests:{type:"boolean",description:"Should tests be included with the component code.",default:false}},required:["component"]}};async function Da({component:e,includeTests:t=false}){let r=z$1(e);if(!r)throw new Error(`${e} is not valid! Expected a category and block proceeded by the registry url i.e. @ieedan/std/<category>/<block>`);let{url:o,specifier:n}=r.parse(e,{fullyQualified:true});if(!n)throw new Error(`${e} is not valid! Expected a category and block proceeded by the registry url i.e. @ieedan/std/<category>/<block>`);let i=(await lt(o)).match(m=>m,m=>{throw new Error(`Error getting state for ${o}: ${m}`)}),s=(await Bt([i])).match(m=>m,m=>{throw new Error(`Error getting manifest for ${o}: ${m}`)}),c$1=Lt(s).get(c(o,n));if(!c$1)throw new Error(`${n} does not exist in ${o}`);let l=_t([c$1],{includeTests:t}),f=(await Promise.all(l.map(m=>m.files))).flatMap(m=>[...m.map(h=>({name:h.name,content:h.content.unwrapOr("<FETCH ERROR>")}))]);return {registry:o,component:n,files:f,commands:{add:`jsrepo add ${e} -y -A`,update:`jsrepo update ${e} -y -A`}}}var Na={name:"get-config-files",description:"Lists the config files for this registry. These are files that are either necessary for the registry to work or optional as marked by the `optional` boolean on each file.",inputSchema:{type:"object",properties:{registry:{type:"string",description:"Registry to list components from. (If not provided will return all for the current config file.)",examples:["@ieedan/std","github/ieedan/std","gitlab/ieedan/std","bitbucket/ieedan/std","azure/ieedan/std/std","https://example.com/r"]},requiredOnly:{type:"boolean",description:"When true only returns the config files required for the registry to work properly."}},required:["registry"]}};async function Aa({registry:e,requiredOnly:t=false}){let r=(await lt(e)).match(i=>i,i=>{throw new Error(`Error getting state for ${e}: ${i}`)}),o=(await Ft(r)).match(i=>i,i=>{throw new Error(`Error getting manifest for ${e}: ${i}`)});return !o.configFiles||o.configFiles.length===0?[]:{configFiles:await Promise.all(o.configFiles.filter(i=>!t||!i.optional).map(async i=>{let s=(await Ge(r,i.path)).unwrapOr("<FETCH ERROR>");return {...i,content:s}}))}}var Fa={name:"discover-registries",description:"Searches jsrepo.com for registries that could include components the user needs in their project.",inputSchema:{type:"object",properties:{primaryLanguage:{type:"string",description:"File extension of the primary language of the registry. i.e. TypeScript -> ts, React -> tsx/jsx"}},required:["primaryLanguage"]}};async function La({primaryLanguage:e}){let t=await ke(`${w}/api/registries?lang=${e}`);if(!t.ok)return [];let{data:r}=await t.json();return {registries:r.map(o=>{let n=`@${o.scope.name}/${o.name}`;return {name:n,description:o.metaDescription,repository:o.metaRepository,keywords:o.metaTags,homepage:o.metaHomepage,rating:o.rating,primaryLanguage:o.metaPrimaryLanguage,monthlyDownloads:o.monthlyFetches,latestVersion:o.latestVersion,access:o.access,commands:{init:`jsrepo init ${n}`}}})}}var Ba={name:"cli-reference",description:"A reference for the usage of the jsrepo CLI.",inputSchema:{type:"object"}};function _a(){return {name:Et.name(),description:Et.description(),version:Et.version(),commands:Et.commands.map(e=>({name:e.name(),description:e.description(),usage:e.usage(),options:e.options.map(t=>({flags:t.flags,description:t.description,defaultValue:t.defaultValue}))}))}}async function ri(){let e=new Server({name:"jsrepo",version:Fe.version},{capabilities:{tools:{}}});e.setRequestHandler(CallToolRequestSchema,async r=>{console.error(`Received CallToolRequest calling: ${N.bold(r.params.name)}`);try{switch(r.params.name){case "list-components":{let o=r.params.arguments,n=await Oa(o.registries);return {content:[{type:"text",text:JSON.stringify(n)}]}}case "get-component-code":{let o=r.params.arguments,n=await Da(o);return {content:[{type:"text",text:JSON.stringify(n)}]}}case "get-config-files":{let o=r.params.arguments,n=await Aa(o);return {content:[{type:"text",text:JSON.stringify(n)}]}}case "discover-registries":{let o=r.params.arguments,n=await La(o);return {content:[{type:"text",text:JSON.stringify(n)}]}}case "cli-reference":{let o=_a();return {content:[{type:"text",text:JSON.stringify(o)}]}}}throw new Error(`Invalid tool ${r.params.name}`)}catch(o){return console.error(N.red(`Error executing tool ${N.bold(r.params.name)}: ${o}`)),{content:[{type:"text",text:JSON.stringify({error:o instanceof Error?o.message:String(o)})}]}}}),e.setRequestHandler(ListToolsRequestSchema,async()=>(console.error("Received ListToolsRequest"),{tools:[Ia,Ta,Na,Fa,Ba]}));let t=new StdioServerTransport;console.error("Connecting server to transport..."),await e.connect(t),console.error("Server connected");}var fo=new Command("mcp").description("Interact with jsrepo through an MCP server.").option("--cwd <path>","The current working directory.",process.cwd()).action(async()=>{await ri().catch(e=>{console.error(e),process.exit(1);});});var Ga=$.object({private:$.boolean(),dryRun:$.boolean(),name:$.optional($.string()),ver:$.optional($.string()),dirs:$.optional($.array($.string())),includeBlocks:$.optional($.array($.string())),includeCategories:$.optional($.array($.string())),excludeBlocks:$.optional($.array($.string())),excludeCategories:$.optional($.array($.string())),excludeDeps:$.optional($.array($.string())),listBlocks:$.optional($.array($.string())),listCategories:$.optional($.array($.string())),doNotListBlocks:$.optional($.array($.string())),doNotListCategories:$.optional($.array($.string())),allowSubdirectories:$.optional($.boolean()),verbose:$.boolean(),cwd:$.string()}),mo=new Command("publish").description("Publish a registry to jsrepo.com.").option("--private","When publishing the first version of the registry make it private.",false).option("--dry-run","Test the publish but don't list on jsrepo.com.",false).option("--name <name>","The name of the registry. i.e. @ieedan/std").option("--ver <version>","The version of the registry. i.e. 0.0.1").option("--dirs [dirs...]","The directories containing the blocks.").option("--include-blocks [blockNames...]","Include only the blocks with these names.").option("--include-categories [categoryNames...]","Include only the categories with these names.").option("--exclude-blocks [blockNames...]","Do not include the blocks with these names.").option("--exclude-categories [categoryNames...]","Do not include the categories with these names.").option("--list-blocks [blockNames...]","List only the blocks with these names.").option("--list-categories [categoryNames...]","List only the categories with these names.").option("--do-not-list-blocks [blockNames...]","Do not list the blocks with these names.").option("--do-not-list-categories [categoryNames...]","Do not list the categories with these names.").option("--exclude-deps [deps...]","Dependencies that should not be added.").option("--allow-subdirectories","Allow subdirectories to be built.").option("--verbose","Include debug logs.",false).option("--cwd <path>","The current working directory.",process.cwd()).action(async e=>{let t=$.parse(Ga,e);await ie(),await za(t),outro(N.green("All done!"));});async function za(e){let t=d=>{e.verbose&&console.info(`${Pe} ${d}`);},r=he({verbose:e.verbose?t:void 0}),o=At(e.cwd).match(d=>{if(d===null)return {$schema:"",access:"public",readme:"README.md",dirs:e.dirs??[],doNotListBlocks:e.doNotListBlocks??[],doNotListCategories:e.doNotListCategories??[],listBlocks:e.listBlocks??[],listCategories:e.listCategories??[],excludeDeps:e.excludeDeps??[],includeBlocks:e.includeBlocks??[],includeCategories:e.includeCategories??[],excludeBlocks:e.excludeBlocks??[],excludeCategories:e.excludeCategories??[],allowSubdirectories:e.allowSubdirectories};let w=d;return e.private&&(w.access="private"),e.name&&(w.name=e.name),e.ver&&(w.version=e.ver),e.dirs&&(w.dirs=e.dirs),e.doNotListBlocks&&(w.doNotListBlocks=e.doNotListBlocks),e.doNotListCategories&&(w.doNotListCategories=e.doNotListCategories),e.listBlocks&&(w.listBlocks=e.listBlocks),e.listCategories&&(w.listCategories=e.listCategories),e.includeBlocks&&(w.includeBlocks=e.includeBlocks),e.includeCategories&&(w.includeCategories=e.includeCategories),e.excludeBlocks&&(w.excludeBlocks=e.excludeBlocks),e.excludeCategories&&(w.excludeCategories=e.excludeCategories),e.excludeDeps&&(w.excludeDeps=e.excludeDeps),e.allowSubdirectories!==void 0&&(w.allowSubdirectories=e.allowSubdirectories),w.rules={...Zt,...w.rules},w},d=>program.error(N.red(d)));if(e.dryRun&&log.warn(N.bgYellow.black(" DRY RUN ")),o.name!==void 0)try{let[d,w,...x]=o.name.split("/");if(x.length>0)throw new Error;if(!d.startsWith("@"))throw new Error;if(!d.slice(1).match(v))throw new Error;if(!w.match(v))throw new Error}catch{program.error(N.red(`\`${o.name}\` is not a valid name. The name should be provided as \`@<scope>/<registry>\``));}else program.error(N.red(`To publish to ${N.bold("jsrepo.com")} you need to provide the \`name\` field in the \`jsrepo-build-config.json\``));if(o.version!==void 0){if(o.version==="package"){let w=Z.join(e.cwd,"package.json");de.existsSync(w)||program.error(N.red(`Couldn't find your ${N.bold("package.json")}!`));let{version:x}=JSON.parse(de.readFileSync(w).toString());o.version=x;}Vo.valid(o.version)||program.error(`\`${o.version}\` is not a valid semver version.`);}else program.error(N.red(`To publish to ${N.bold("jsrepo.com")} you need to provide the \`version\` field in the \`jsrepo-build-config.json\``));let n=new pe().get("jsrepo");n===void 0&&program.error(N.red(`Please authenticate with ${N.cyan("jsrepo auth")} to publish to ${We}.`));let i=[],s=ta();try{let d=de.readFileSync(Z.join(e.cwd,".gitignore")).toString();s.add(d);}catch{}s.add(Er);for(let d of o.dirs){let w=Z.join(e.cwd,d);r.start(`Building ${N.cyan(w)}`);let x=Cr(w,{cwd:e.cwd,ignore:s,config:o});for(let C of x){if(i.find(j=>j.name===C.name)!==void 0){console.warn(`${D} ${ue} Skipped adding \`${N.cyan(`${d}/${C.name}`)}\` because a category with the same name already exists!`);continue}i.push(C);}r.stop(`Built ${N.cyan(w)}`);}let a=Rr(o,{cwd:e.cwd}),c=p(i,a,o);r.start("Checking manifest");let{warnings:l,errors:f}=xr(c,o,e.cwd,o.rules);r.stop("Completed checking manifest."),(l.length>0||f.length>0)&&console.log(D);for(let d of l)console.log(d);if(f.length>0){for(let d of f)console.log(d);program.error(N.red(`Completed checking manifest with ${N.bold(`${f.length} error(s)`)} and ${N.bold(`${l.length} warning(s)`)}`));}let[m,h]=Sr(c.categories);c.categories=m,h>0&&log.step(`Removed ${h} unused block${h>1?"s":""}.`),r.start(`Packaging ${N.cyan(c.name)}...`);let b=Z.resolve(e.cwd,`jsrepo-publish-temp-${Date.now()}`);t(`Creating temp dir: ${b}`),de.mkdirSync(b,{recursive:true}),t("Writing manifest to temp dir"),de.writeFileSync(Z.resolve(b,"jsrepo-manifest.json"),JSON.stringify(c));let p$1=Z.resolve(e.cwd,o.readme);try{t("Attempting to copy readme"),de.copyFileSync(p$1,Z.join(b,"README.md")),t("Copied readme");}catch{t("No readme found.");}if(c.configFiles){t("Copying config files");for(let d of c.configFiles){let w=Z.join(e.cwd,d.path),x=Z.join(b,d.path),C=Z.join(x,"../");de.existsSync(C)||de.mkdirSync(C,{recursive:true}),de.copyFileSync(w,x);}t("Copied config files");}t("Copying registry files");for(let d of c.categories)for(let w of d.blocks){let x=Z.join(e.cwd,w.directory),C=Z.join(b,w.directory);for(let j of w.files){let X=Z.join(C,j,"../");de.existsSync(X)||de.mkdirSync(X,{recursive:true}),de.copyFileSync(Z.join(x,j),Z.join(C,j));}}t("Copied registry files");let g=Z.resolve(e.cwd,`${o.name.replace("/","_")}-package.tar.gz`),v$1=de.readdirSync(b);t("Creating archive file"),await oi.create({z:true,cwd:b,file:g},v$1),t("Created archive file"),t("Removing temp directory"),de.rmSync(b,{force:true,recursive:true}),t("Removed temp directory"),r.stop(`Created package ${N.cyan(g)}...`);let u=o.access??"public";log.info(`Publishing to jsrepo with the access set to ${N.cyan(u)}`),r.start(`Publishing ${N.bold(c.name)} to ${We}...`);let S=de.readFileSync(g);t("Removing archive file"),de.rmSync(g,{force:true,recursive:true}),t("Removed archive file"),t(`Publishing to ${`${w}/api/publish`}`);let R=await ke(`${w}/api/publish`,{body:S,headers:{"content-type":"application/gzip","content-encoding":"gzip","x-api-key":n,"x-dry-run":e.dryRun?"1":"0","x-access":u},method:"POST"});if(r.stop(`Got response from ${We}.`),R.ok){let d=await R.json();d.status==="dry-run"?log.success(`${N.hex("#f7df1e").bold("[jsrepo.com]")} Completed dry run!`):log.success(`${N.hex("#f7df1e").bold("[jsrepo.com]")} published ${N.greenBright(`@${d.scope}`)}/${d.registry}${N.greenBright(`@${d.version}`)}!`);}else {let d=await R.json();program.error(N.red(`${N.bold("[jsrepo.com]")} ${N.bold(R.status)} ${d.message}`));}}var nc=$.object({repo:$.optional($.string()),allow:$.boolean(),debug:$.boolean(),cache:$.boolean(),verbose:$.boolean(),cwd:$.string()}),uo=new Command("test").description("Tests local blocks against most recent remote tests.").addArgument(new Argument("[blocks...]","The blocks you want to test.").default([])).option("--repo <repo>","Repository to download the blocks from.").option("-A, --allow","Allow jsrepo to download code from the provided repo.",false).option("--debug","Leaves the temp test file around for debugging upon failure.",false).option("--no-cache","Disable caching of resolved git urls.").option("--verbose","Include debug logs.",false).option("--cwd <path>","The current working directory.",process.cwd()).action(async(e,t)=>{let r=$.parse(nc,t);await ie(),await ic(e,r),outro(N.green("All done!"));});async function ic(e,t){let r=u=>{t.verbose&&console.info(`${Pe} ${u}`);};r(`Attempting to test ${JSON.stringify(e)}`);let o=Te(t.cwd).match(u=>u,u=>program.error(N.red(u))),n=he({verbose:t.verbose?r:void 0}),i=o.repos;if(t.repo&&(i=[t.repo]),!t.allow&&t.repo){let u=await confirm({message:`Allow ${N.cyan("jsrepo")} to download and run code from ${N.cyan(t.repo)}?`,initialValue:true});(isCancel(u)||!u)&&(cancel("Canceled!"),process.exit(0));}t.verbose||n.start(`Fetching blocks from ${N.cyan(i.join(", "))}`);let s=(await ze(i,{noCache:!t.cache})).match(u=>u,({repo:u,message:S})=>{n.stop(`Failed to get info for ${N.cyan(u)}`),program.error(N.red(S));});r(`Resolved ${N.cyan(i.join(", "))}`),r(`Fetching blocks from ${N.cyan(i.join(", "))}`);let a=(await bt(s,{verbose:t.verbose?r:void 0})).match(u=>u,({repo:u,message:S})=>{n.stop(`Failed fetching blocks from ${N.cyan(u)}`),program.error(N.red(S));});r(`Retrieved blocks from ${N.cyan(i.join(", "))}`),t.verbose||n.stop(`Retrieved blocks from ${N.cyan(i.join(", "))}`);let c$1=Z.resolve(Z.join(t.cwd,`blocks-tests-temp-${Date.now()}`));r(`Trying to create the temp directory ${N.bold(c$1)}.`),de.mkdirSync(c$1,{recursive:true});let l=()=>{de.rmSync(c$1,{recursive:true,force:true});},f=xt(a,o,t.cwd).map(u=>u.specifier),m=e;e.length===0&&(m=f),m.length===0&&(l(),program.error(N.red("There were no blocks found in your project!")));let h=[];for(let u of m){let S,R=z$1(u);if(R){let{url:d}=R.parse(u,{fullyQualified:true}),w=(await lt(d)).match(C=>C,C=>program.error(N.red(C))),x=(await bt([w])).match(C=>C,C=>program.error(N.red(C)));for(let[C,j]of x)a.set(C,j);S=a.get(u);}else for(let d of i){let w=z$1(d);if(!w)continue;let{url:x,specifier:C}=w.parse(c(d,u),{fullyQualified:true}),j=a.get(c(x,C));if(j!==void 0){S=j;break}}S||program.error(N.red(`Invalid block! ${N.bold(u)} does not exist!`)),h.push({name:u,block:S});}let b=Ue(o.paths,t.cwd).match(u=>u,u=>program.error(N.red(u)));for(let{block:u}of h){let S=u.sourceRepo,R=c(u.sourceRepo.url,u.category,u.name);if(t.verbose||n.start(`Setting up test file for ${N.cyan(R)}`),!u.tests){n.stop(`No tests found for ${N.cyan(R)}`);continue}let d=tr(u,b,t.cwd);d=Z.relative(c$1,d);let w=async C=>{let j=await Ge(S,C);return j.isErr()&&(n.stop(N.red(`Error fetching ${N.bold(C)}`)),program.error(N.red(`There was an error trying to get ${R}`))),j.unwrap()};r(`Downloading and copying test files for ${R}`);let x=[];for(let C of u.files.filter(j=>ct(j))){let j=await w(Z.join(u.directory,C)),X=Z.join(c$1,C);de.writeFileSync(X,j),x.push(X);}for(let C of x){r(`Opening test file ${C}`);let j=de.readFileSync(C).toString(),X=ls.parseSync(C,j);for(let oe of X.module.staticImports){let Y=oe.moduleRequest.value,k;if(Y.startsWith(".")&&(u.subdirectory?k=Z.join(d,u.name,Y):k=Z.join(d,Y)),k){let A=new RegExp(`(['"])${ts(Y)}\\1`,"g");j=j.replaceAll(A,`$1${k}$1`);}}de.writeFileSync(C,j);}r(`Completed ${N.cyan.bold(R)} test file`),t.verbose||n.stop(`Completed setup for ${N.bold(R)}`);}r("Beginning testing");let p=await detect({cwd:t.cwd});p==null&&program.error(N.red("Could not detect package manager"));let g=resolveCommand(p.agent,"execute",["vitest","run",c$1]);g==null&&program.error(N.red(`Could not resolve add command for '${p.agent}'.`));let v=`${g.command} ${g.args.join(" ")}`;r(`Running ${N.cyan(v)} on ${N.cyan(t.cwd)}`);try{let u=x(g.command,g.args,{nodeOptions:{cwd:t.cwd}});for await(let S of u)process.stdout.write(`${S}
|
|
97
97
|
`);l();}catch(u){t.debug?console.info(`${N.bold("--debug")} flag provided. Skipping cleanup. Run '${N.bold(v)}' to retry tests.
|
|
98
98
|
`):l(),program.error(N.red(`Tests failed! Error ${u}`));}}var dc=$.object({token:$.optional($.string()),logout:$.boolean(),cwd:$.string()}),Gt=["Anthropic","Azure","BitBucket","GitHub","GitLab","OpenAI","http"].sort(),go=new Command("tokens").description("Provide a token for access to private repositories.").addArgument(new Argument("service","The service you want to authenticate to.").choices(Gt.map(e=>e.toLowerCase())).argOptional()).option("--logout","Execute the logout flow.",false).option("--token <token>","The token to use for authenticating to this service.").option("--cwd <path>","The current working directory.",process.cwd()).action(async(e,t)=>{let r=$.parse(dc,t);await ie(),await fc(e,r),outro(N.green("All done!"));});async function fc(e,t){let r=Te(t.cwd).match(s=>s.repos.filter(u.matches),()=>[]),o=Gt.find(s=>s.toLowerCase()===e?.toLowerCase()),n=new pe;if(t.logout){if(o!==void 0){if(o==="http"){await ii(n);return}n.delete(o),log.success(`Logged out of ${o}.`);return}for(let s of Gt){if(s==="http"){await ii(n);continue}if(n.get(s)===void 0){log.step(N.gray(`Already logged out of ${N.bold(s)}.`));continue}let a=await confirm({message:`Logout of ${N.bold(s)}?`,initialValue:true});isCancel(a)&&(cancel("Canceled!"),process.exit(0)),a&&n.delete(s);}return}if(o===void 0){let s=await select({message:"Which service do you want to authenticate to?",options:Gt.map(a=>({label:a,value:a})),initialValue:Gt[0]});if(isCancel(s)&&(cancel("Canceled!"),process.exit(0)),o=s,o==="http"){let a="Other";if(r.length>0){r.push("Other");let c=await select({message:"Which registry do you want to authenticate to?",options:r.map(l=>({label:l,value:l})),initialValue:Gt[0]});isCancel(c)&&(cancel("Canceled!"),process.exit(0)),a=new URL(c).origin;}if(a==="Other"){let c=await text({message:"Please enter the registry url you want to authenticate to:",placeholder:"https://example.com",validate(l){if(l.trim()==="")return "Please provide a value";try{new URL(l);}catch{return "Please provide a valid url"}}});isCancel(c)&&(cancel("Canceled!"),process.exit(0)),a=new URL(c).origin;}o=`http-${a}`;}}let i=o;if(i.startsWith("http")&&(i=i.slice(5)),t.token===void 0){let s=await password({message:`Paste your token for ${N.bold(i)}:`,validate(a){if(a.trim()==="")return "Please provide a value"}});(isCancel(s)||!s)&&(cancel("Canceled!"),process.exit(0)),t.token=s;}n.set(o,t.token),log.success(`Logged into ${N.bold(i)}.`);}async function ii(e){let t=e.getHttpRegistriesWithTokens();t.length===0&&log.step(N.gray(`Already logged out of ${N.bold("http")}.`));for(let r of t){let o;try{o=new URL(r);}catch{continue}let n=await confirm({message:`Logout of ${N.bold(o.origin)}?`,initialValue:true});isCancel(n)&&(cancel("Canceled!"),process.exit(0)),n&&e.delete(`http-${o.origin}`);}}var vc=$.object({all:$.boolean(),expand:$.boolean(),maxUnchanged:$.number(),no:$.boolean(),repo:$.optional($.string()),allow:$.boolean(),yes:$.boolean(),cache:$.boolean(),verbose:$.boolean(),cwd:$.string()}),yo=new Command("update").description("Update blocks to the code in the remote repository.").argument("[blocks...]","Names of the blocks you want to update. ex: (utils/math)").option("--all","Update all installed components.",false).option("-E, --expand","Expands the diff so you see the entire file.",false).option("--max-unchanged <number>","Maximum unchanged lines that will show without being collapsed.",e=>Number.parseInt(e),3).option("-n, --no","Do update any blocks.",false).option("--repo <repo>","Repository to download the blocks from.").option("-A, --allow","Allow jsrepo to download code from the provided repo.",false).option("-y, --yes","Skip confirmation prompt.",false).option("--no-cache","Disable caching of resolved git urls.").option("--verbose","Include debug logs.",false).option("--cwd <path>","The current working directory.",process.cwd()).action(async(e,t)=>{let r=$.parse(vc,t);await ie(),await wc(e,r),outro(N.green("All done!"));});async function wc(e,t){let r=d=>{t.verbose&&console.info(`${Pe} ${d}`);};r(`Attempting to update ${JSON.stringify(e)}`);let o=he({verbose:t.verbose?r:void 0}),n=Te(t.cwd).match(d=>d,d=>program.error(N.red(d))),i=n.repos;t.repo&&(i=[t.repo]);for(let d of e)y.find(w=>d.startsWith(w.name))&&program.error(N.red(`Invalid value provided for block names \`${N.bold(d)}\`. Block names are expected to be provided in the format of \`${N.bold("<category>/<name>")}\``));if(!t.allow&&t.repo){let d=await confirm({message:`Allow ${N.cyan("jsrepo")} to download and run code from ${N.cyan(t.repo)}?`,initialValue:true});(isCancel(d)||!d)&&(cancel("Canceled!"),process.exit(0));}r(`Resolving ${N.cyan(i.join(", "))}`),t.verbose||o.start(`Fetching blocks from ${N.cyan(i.join(", "))}`);let s=(await ze(i,{noCache:!t.cache})).match(d=>d,({repo:d,message:w})=>{o.stop(`Failed to get info for ${N.cyan(d)}`),program.error(N.red(w));});r(`Resolved ${N.cyan(i.join(", "))}`),r(`Fetching blocks from ${N.cyan(i.join(", "))}`);let a=(await Bt(s)).match(d=>d,({repo:d,message:w})=>{o.stop(`Failed fetching blocks from ${N.cyan(d)}`),program.error(N.red(w));}),c$1=Lt(a);t.verbose||o.stop(`Retrieved blocks from ${N.cyan(i.join(", "))}`),r(`Retrieved blocks from ${N.cyan(i.join(", "))}`);for(let d of a)Mt(d.state,d.manifest,t.cwd);let l=xt(c$1,n,t.cwd);l.length===0&&program.error(N.red(`You haven't installed any blocks yet. Did you mean to \`${N.bold("add")}\`?`));let f=e;if(t.all&&(f=l.map(d=>d.specifier)),f.length===0){let d=await multiselect({message:`Which blocks would you like to ${t.no?"diff":"update"}?`,options:l.filter(w=>w.block.list).map(w=>({label:`${N.cyan(w.block.category)}/${w.block.name}`,value:w.specifier})),required:true});isCancel(d)&&(cancel("Canceled!"),process.exit(0)),f=d;}r(`Preparing to update ${N.cyan(f.join(", "))}`);let m=(await $t(f,c$1,s)).match(d=>d,program.error),h=new Set,b=new Set,{prettierOptions:p,biomeOptions:g}=await Ct({formatter:n.formatter,cwd:t.cwd}),v=Ue(n.paths,t.cwd).match(d=>d,d=>program.error(N.red(d))),u=_t(m,n);for(let d of u){let w=c(d.block.sourceRepo.url,d.block.category,d.block.name),x=ir(d.block.sourceRepo.url);r(`Attempting to update ${w}`),n.includeTests&&d.block.tests&&(r("Trying to include tests"),h.add("vitest"));for(let j of d.block.devDependencies)h.add(j);for(let j of d.block.dependencies)b.add(j);let C=await d.files;process.stdout.write(`${D}
|
|
99
99
|
`),process.stdout.write(`${D} ${w}
|