@tiptap/cli 1.1.10
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/LICENSE +21 -0
- package/README.md +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/package.json +81 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Tiptap
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Tiptap CLI
|
|
2
|
+
|
|
3
|
+
The Tiptap CLI helps you scaffold [editors](https://tiptap.dev/docs/ui-components/templates/simple-editor), install [UI components](https://tiptap.dev/docs/ui-components/components/overview) or primitives, and configure Tiptap faster. It removes much of the manual work so you can start building editor features faster.
|
|
4
|
+
|
|
5
|
+
To use it, head over to the [documentation](https://tiptap.dev/docs/ui-components/getting-started/cli).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import rn from"path";import{Command as nn}from"commander";import{z as Z}from"zod";import{createPrompt as Ut,useState as Re,useKeypress as Dt,usePrefix as Lt,usePagination as zt,useRef as We,useMemo as Te,useEffect as Vt,isBackspaceKey as Wt,isEnterKey as Gt,isUpKey as Ie,isDownKey as Ge,isNumberKey as Kt,Separator as ie,ValidationError as Bt,makeTheme as Yt}from"@inquirer/core";import Ke from"yoctocolors-cjs";import Jt from"@inquirer/figures";import Ht from"ansi-escapes";import{Separator as Bn}from"@inquirer/core";var qt={icon:{cursor:Jt.pointer},style:{disabled:e=>Ke.dim(`- ${e}`),description:e=>Ke.cyan(e)},helpMode:"auto",indexMode:"hidden"};function H(e){return!ie.isSeparator(e)&&!e.disabled}function Xt(e){return e.map(t=>{if(ie.isSeparator(t))return t;if(typeof t=="string")return{value:t,name:t,short:t,disabled:!1};let r=t.name??String(t.value),n={value:t.value,name:r,short:t.short??r,disabled:t.disabled??!1};return t.description&&(n.description=t.description),n})}var te=Ut((e,t)=>{let{loop:r=!0,pageSize:n=7,instructions:s}=e,o=We(!0),a=Yt(qt,e.theme),[i,l]=Re("idle"),u=Lt({status:i,theme:a}),m=We(),[x,k]=Re(!0),v=Te(()=>Xt(e.choices),[e.choices]),$=Te(()=>{let w=v.findIndex(H),T=v.findLastIndex(H);if(w===-1)throw new Bt("[select prompt] No selectable choices. All choices are disabled.");return{first:w,last:T}},[v]),y=Te(()=>"default"in e?v.findIndex(w=>H(w)&&w.value===e.default):-1,[e.default,v]),[j,W]=Re(y===-1?$.first:y),O=v[j];Dt((w,T)=>{if(clearTimeout(m.current),k(!1),Gt(w))l("done"),t(O.value);else if(Ie(w)||Ge(w)){if(T.clearLine(0),r||Ie(w)&&j!==$.first||Ge(w)&&j!==$.last){let _=Ie(w)?-1:1,I=j;do I=(I+_+v.length)%v.length;while(!H(v[I]));W(I)}}else if(Kt(w)&&!Number.isNaN(Number(T.line))){let _=Number(T.line)-1,I=v[_];I!=null&&H(I)&&W(_),m.current=setTimeout(()=>{T.clearLine(0)},700)}else if(Wt(w))T.clearLine(0);else{let _=T.line.toLowerCase(),I=v.findIndex(ee=>ie.isSeparator(ee)||!H(ee)?!1:ee.name.toLowerCase().startsWith(_));I!==-1&&W(I),m.current=setTimeout(()=>{T.clearLine(0)},700)}}),Vt(()=>()=>{clearTimeout(m.current)},[]);let G=a.style.message(e.message,i),K="",J="";(a.helpMode==="always"||a.helpMode==="auto"&&x&&(s===void 0||s))&&(typeof s=="string"?K=s:K=` (${[`${a.style.key("\u2191\u2193")} to navigate`,`${a.style.key("enter")} to select`,a.indexMode==="number"?`${a.style.key("1-9")} to jump`:"","type to filter"].filter(T=>T!=="").join(", ")})`,v.length>n&&(a.helpMode==="always"||a.helpMode==="auto"&&o.current)&&(J=`
|
|
3
|
+
${a.style.help("(Use arrow keys to reveal more choices)")}`,o.current=!1));let B=zt({items:v,active:j,renderItem({item:w,isActive:T,index:_}){if(ie.isSeparator(w))return` ${w.separator}`;let I=a.indexMode==="number"?`${_+1}. `:"";if(w.disabled){let be=typeof w.disabled=="string"?w.disabled:"(disabled)";return a.style.disabled(`${I}${w.name} ${be}`)}let ee=T?a.style.highlight:be=>be,Mt=T?a.icon.cursor:" ";return ee(`${Mt} ${I}${w.name}`)},pageSize:n,loop:r});if(i==="done")return`${u} ${G} ${a.style.answer(O.short)}`;let _t=O.description?`
|
|
4
|
+
${a.style.description(O.description)}`:"";return`${[u,G,K].filter(Boolean).join(" ")}
|
|
5
|
+
${B}${J}${_t}${Ht.cursorHide}`});import{checkbox as sn,Separator as bt}from"@inquirer/prompts";import gr from"path";var M="1";var Ce="6",Be="7";import R from"path";import{createMatchPath as Zt}from"tsconfig-paths";async function P(e,t){return Zt(t.absoluteBaseUrl,t.paths)(e,void 0,()=>!0,[".ts",".tsx"])}import{cosmiconfig as sr}from"cosmiconfig";import or from"fast-glob";import{loadConfig as ir}from"tsconfig-paths";import{z as g}from"zod";import Je from"path";var A={"next-app":{name:"next-app",label:"Next.js",links:{installation:"https://example.com/docs/installation/next"}},"next-pages":{name:"next-pages",label:"Next.js",links:{installation:"https://example.com/docs/installation/next"}},remix:{name:"remix",label:"Remix",links:{installation:"https://example.com/docs/installation/remix"}},"react-router":{name:"react-router",label:"React Router",links:{installation:"https://example.com/docs/installation/react-router"}},vite:{name:"vite",label:"Vite",links:{installation:"https://example.com/docs/installation/vite"}},astro:{name:"astro",label:"Astro",links:{installation:"https://example.com/docs/installation/astro"}},laravel:{name:"laravel",label:"Laravel",links:{installation:"https://example.com/docs/installation/laravel"}},"tanstack-start":{name:"tanstack-start",label:"TanStack Start",links:{installation:"https://example.com/docs/installation/tanstack"}},gatsby:{name:"gatsby",label:"Gatsby",links:{installation:"https://example.com/docs/installation/gatsby"}},manual:{name:"manual",label:"Manual",links:{installation:"https://example.com/docs/installation/manual"}}};import Qt from"path";import er from"fs-extra";function Ye(e="",t=!0){let r=Qt.join(e,"package.json");return er.readJSONSync(r,{throws:t})}import qe from"fast-glob";import He from"fs-extra";import{loadConfig as tr}from"tsconfig-paths";var Xe=["**/node_modules/**",".next","public","dist","build"];async function b(e){let[t,r,n,s,o]=await Promise.all([qe.glob("**/{next,vite,astro,app}.config.*|gatsby-config.*|composer.json|react-router.config.*",{cwd:e,deep:3,ignore:Xe}),He.pathExists(Je.resolve(e,"src")),nr(e),rr(e),Ye(e,!1)]),a=await He.pathExists(Je.resolve(e,`${r?"src/":""}app`)),i={framework:A.manual,isSrcDir:r,isRSC:!1,isTsx:n,aliasPrefix:s};return t.find(l=>l.startsWith("next.config."))?.length?(i.framework=a?A["next-app"]:A["next-pages"],i.isRSC=a,i):t.find(l=>l.startsWith("astro.config."))?.length?(i.framework=A.astro,i):t.find(l=>l.startsWith("gatsby-config."))?.length?(i.framework=A.gatsby,i):t.find(l=>l.startsWith("composer.json"))?.length?(i.framework=A.laravel,i):Object.keys(o?.dependencies??{}).find(l=>l.startsWith("@remix-run/"))?(i.framework=A.remix,i):t.find(l=>l.startsWith("app.config."))?.length&&[...Object.keys(o?.dependencies??{}),...Object.keys(o?.devDependencies??{})].find(l=>l.startsWith("@tanstack/start"))?(i.framework=A["tanstack-start"],i):t.find(l=>l.startsWith("react-router.config."))?.length?(i.framework=A["react-router"],i):(t.find(l=>l.startsWith("vite.config."))?.length&&(i.framework=A.vite),i)}async function rr(e){let t=await tr(e);if(t?.resultType==="failed"||!Object.entries(t?.paths).length)return null;for(let[r,n]of Object.entries(t.paths))if(n.includes("./*")||n.includes("./src/*")||n.includes("./app/*")||n.includes("./resources/js/*"))return r.replace(/\/\*$/,"")??null;return Object.keys(t?.paths)?.[0].replace(/\/\*$/,"")??null}async function nr(e){return(await qe.glob("tsconfig.*",{cwd:e,deep:1,ignore:Xe})).length>0}async function Ze(e,t=null){let[r,n]=await Promise.all([N(e),t?Promise.resolve(t):b(e)]);if(r)return r;if(!n)return null;let s={rsc:n.isRSC,tsx:n.isTsx,aliases:{components:`${n.aliasPrefix}/components`,contexts:`${n.aliasPrefix}/contexts`,hooks:`${n.aliasPrefix}/hooks`,tiptapIcons:`${n.aliasPrefix}/components/tiptap-icons`,lib:`${n.aliasPrefix}/lib`,tiptapExtensions:`${n.aliasPrefix}/components/tiptap-extensions`,tiptapNodes:`${n.aliasPrefix}/components/tiptap-nodes`,tiptapUi:`${n.aliasPrefix}/components/tiptap-ui`,tiptapUiPrimitives:`${n.aliasPrefix}/components/tiptap-ui-primitives`,styles:`${n.aliasPrefix}/styles`}};return await re(e,s)}var pe="@/components",ce="@/contexts",le="@/hooks",me="@/components/tiptap-icons",ne="@/lib",fe="@/components/tiptap-extension",ue="@/components/tiptap-node",ge="@/components/tiptap-ui",de="@/components/tiptap-ui-primitive",he="@/styles",ar=sr("components",{searchPlaces:["components.json"]}),q=g.object({rsc:g.coerce.boolean().default(!1),tsx:g.coerce.boolean().default(!0),aliases:g.object({components:g.string(),contexts:g.string().optional(),hooks:g.string().optional(),tiptapIcons:g.string().optional(),lib:g.string().optional(),tiptapExtensions:g.string().optional(),tiptapNodes:g.string().optional(),tiptapUi:g.string().optional(),tiptapUiPrimitives:g.string().optional(),styles:g.string().optional()})}),Qe=q.extend({resolvedPaths:g.object({cwd:g.string(),components:g.string(),contexts:g.string(),hooks:g.string(),tiptapIcons:g.string(),lib:g.string(),tiptapExtensions:g.string(),tiptapNodes:g.string(),tiptapUi:g.string(),tiptapUiPrimitives:g.string(),styles:g.string()})}),pr=g.record(Qe);async function N(e){let t=await ar.search(e),r;if(t)r=q.parse(t.config),r.aliases={components:r.aliases.components??pe,contexts:r.aliases.contexts??ce,hooks:r.aliases.hooks??le,tiptapIcons:r.aliases.tiptapIcons??me,lib:r.aliases.lib??ne,tiptapExtensions:r.aliases.tiptapExtensions??fe,tiptapNodes:r.aliases.tiptapNodes??ue,tiptapUi:r.aliases.tiptapUi??ge,tiptapUiPrimitives:r.aliases.tiptapUiPrimitives??de,styles:r.aliases.styles??he};else{let n=await b(e);r=q.parse({rsc:n?.isRSC??!1,tsx:n?.isTsx??!0,aliases:{components:pe,contexts:ce,hooks:le,tiptapIcons:me,lib:ne,tiptapExtensions:fe,tiptapNodes:ue,tiptapUi:ge,tiptapUiPrimitives:de,styles:he}})}return await re(e,r)}async function re(e,t){let r=await ir(e);if(r.resultType==="failed")throw new Error(`Failed to load ${t.tsx?"tsconfig":"jsconfig"}.json. ${r.message??""}`.trim());return Qe.parse({...t,resolvedPaths:{cwd:e,components:await P(t.aliases.components,r),contexts:t.aliases.contexts?await P(t.aliases.contexts,r):R.resolve(await P(t.aliases.components,r)??e,"..","contexts"),hooks:t.aliases.hooks?await P(t.aliases.hooks,r):R.resolve(await P(t.aliases.components,r)??e,"..","hooks"),tiptapIcons:t.aliases.tiptapIcons?await P(t.aliases.tiptapIcons,r):R.resolve(await P(t.aliases.components,r)??e,"tiptap-icons"),lib:t.aliases.lib?await P(t.aliases.lib,r):R.resolve(await P(ne,r)??e,".."),tiptapExtensions:t.aliases.tiptapExtensions?await P(t.aliases.tiptapExtensions,r):R.resolve(await P(t.aliases.components,r)??e,"tiptap-extension"),tiptapNodes:t.aliases.tiptapNodes?await P(t.aliases.tiptapNodes,r):R.resolve(await P(t.aliases.components,r)??e,"tiptap-node"),tiptapUi:t.aliases.tiptapUi?await P(t.aliases.tiptapUi,r):R.resolve(await P(t.aliases.components,r)??e,"tiptap-ui"),tiptapUiPrimitives:t.aliases.tiptapUiPrimitives?await P(t.aliases.tiptapUiPrimitives,r):R.resolve(await P(t.aliases.components,r)??e,"tiptap-ui-primitive"),styles:t.aliases.styles?await P(t.aliases.styles,r):R.resolve(e,"styles")}})}async function et(e){let t={};for(let n of Object.keys(e.aliases)){if(!cr(n,e))continue;let s=e.resolvedPaths[n],o=await Ee(e.resolvedPaths.cwd,s);if(!o){t[n]=e;continue}t[n]=await N(o)}let r=pr.safeParse(t);return r.success?r.data:null}async function Ee(e,t){let r=je(e,t),n=R.relative(r,t),o=(await or.glob("**/package.json",{cwd:r,deep:3,ignore:["**/node_modules/**","**/dist/**","**/build/**","**/public/**"]})).map(a=>R.dirname(a)).find(a=>n.startsWith(a));return o?R.join(r,o):null}function cr(e,t){return Object.keys(t.resolvedPaths).includes(e)}function je(e,t){let r=e.split(R.sep),n=t.split(R.sep),s=[];for(let o=0;o<Math.min(r.length,n.length)&&r[o]===n[o];o++)s.push(r[o]);return s.join(R.sep)}import{cyan as lr,green as mr,red as fr,yellow as ur}from"kleur/colors";var f={error:fr,warn:ur,info:lr,success:mr};var p={error(...e){console.log(f.error(e.join(" ")))},warn(...e){console.log(f.warn(e.join(" ")))},info(...e){console.log(f.info(e.join(" ")))},success(...e){console.log(f.success(e.join(" ")))},log(...e){console.log(e.join(" "))},break(){console.log("")}};import tt from"fs-extra";async function rt(e){let t={};if(!tt.existsSync(e.cwd)||!tt.existsSync(gr.resolve(e.cwd,"package.json")))return t[M]=!0,{errors:t,config:null};try{let r=await N(e.cwd);return{errors:t,config:r}}catch(r){console.log("[preFlightAdd] - ",r),p.break(),p.error(`An invalid ${f.info("components.json")} file was found at ${f.info(e.cwd)}.
|
|
6
|
+
Before you can add components, you must create a valid ${f.info("components.json")} file by running the ${f.info("init")} command.`),p.error(`Learn more at ${f.info("link-here")}.`),p.break(),process.exit(0)}}import X from"path";import{z as dr}from"zod";function S(e){if(p.error("Something went wrong. Please check the error below for more details."),p.error("If the problem persists, please open an issue on GitHub."),p.error(""),typeof e=="string"&&(p.error(e),p.break(),process.exit(0)),e instanceof dr.ZodError){p.error("Validation failed:");for(let[t,r]of Object.entries(e.flatten().fieldErrors))p.error(`- ${f.info(t)}: ${r}`);p.break(),process.exit(0)}e instanceof Error&&(p.error(e.message),p.break(),process.exit(0)),p.break(),process.exit(0)}import{z as d}from"zod";var nt=d.enum(["registry:context","registry:extension","registry:hook","registry:icon","registry:lib","registry:node","registry:template","registry:ui-primitive","registry:ui","registry:page","registry:component","registry:style","registry:asset"]),hr=d.enum(["free","paid"]).default("free"),st=d.object({path:d.string(),content:d.string().optional(),type:nt,target:d.string().optional()}),U=d.object({name:d.string(),type:nt,description:d.string().optional(),dependencies:d.array(d.string()).optional(),devDependencies:d.array(d.string()).optional(),registryDependencies:d.array(d.string()).optional(),files:d.array(st).optional(),meta:d.record(d.string(),d.any()).optional(),plan:hr.optional(),hidden:d.boolean().default(!0)}),$s=d.array(U),ot=d.array(U.extend({files:d.array(d.union([d.string(),st])).optional()})),it=U.pick({dependencies:!0,devDependencies:!0,files:!0});import ye from"fs-extra";import at from"path";import wr from"os";import{execa as xr}from"execa";import Vs from"node-fetch";import{HttpsProxyAgent as vr}from"https-proxy-agent";import yr from"ora";function h(e,t){return yr({text:e,isSilent:t?.silent})}import Ys from"yaml";var kr=process.env.REGISTRY_URL||"https://template.tiptap.dev",Js=`${kr}/api/auth`;var Pr="//registry.tiptap.dev/:_authToken";var Hs=process.env.https_proxy?new vr(process.env.https_proxy):void 0;async function pt(e,t){try{let r=await Sr(t);return r||(e==="npm"?await br(t):await Rr())}catch{return null}}async function Sr(e){let t=at.join(e,".npmrc");if(ye.existsSync(t)){let r=await ye.readFile(t,"utf8");return ct(r)}return null}async function br(e){let{stdout:t}=await xr("npm",["config","get",Pr],{cwd:e});return t&&t!=="undefined"?t.trim():null}async function Rr(){let e=at.join(wr.homedir(),".npmrc");if(ye.existsSync(e)){let t=await ye.readFile(e,"utf8");return ct(t)}return null}function ct(e){let t=e.split(`
|
|
7
|
+
`).filter(n=>n.startsWith("//registry.tiptap.dev/:_authToken="));return t.length===0?null:t[0].split("=")[1]?.trim()||null}import{detect as Tr}from"@antfu/ni";async function D(e,{withFallback:t}={withFallback:!1}){let r=await Tr({programmatic:!0,cwd:e});if(r==="deno"&&(r=void 0),r==="yarn@berry")return"yarn";if(r==="pnpm@6")return"pnpm";if(r==="bun")return"bun";if(!t)return r??"npm";let n=process.env.npm_config_user_agent||"";return n.startsWith("yarn")?"yarn":n.startsWith("pnpm")?"pnpm":n.startsWith("bun")?"bun":"npm"}import Oe from"deepmerge";import{HttpsProxyAgent as Ir}from"https-proxy-agent";import lt from"node-fetch";import{z as Cr}from"zod";var se=process.env.REGISTRY_URL||"https://template.tiptap.dev",mt=process.env.https_proxy?new Ir(process.env.https_proxy):void 0;async function Ae(e){try{let[t]=await oe(["index.json"],e);return ot.parse(t)}catch(t){p.error(`
|
|
8
|
+
`),S(t)}}async function ft(){try{let e=`${se}/api/registry/free`,t=await lt(e,{agent:mt});if(!t.ok)throw new Error(`Failed to fetch from ${f.info(e)}.
|
|
9
|
+
${t.statusText}`);return await t.json()}catch(e){p.error(`
|
|
10
|
+
`),S(e)}}async function oe(e,t){try{let r=null;if(t){let s=await D(t.resolvedPaths.cwd);r=await pt(s,t.resolvedPaths.cwd)}return await Promise.all(e.map(async s=>{let o=gt(s),a={};r&&(a.Authorization=`Bearer ${r}`);let i=await lt(o,{agent:mt,headers:a});if(!i.ok){let l={400:"Bad request",401:"Unauthorized",403:"Forbidden",404:"Not found",500:"Internal server error"};if(i.status===401)throw new Error(`You are not authorized to access the component at ${f.info(o)}.
|
|
11
|
+
Please run 'tiptap auth login' to authenticate with the registry, or make sure your token is valid.`);if(i.status===404)throw new Error(`The component at ${f.info(o)} was not found.
|
|
12
|
+
It may not exist at the registry. Please make sure it is a valid component.`);if(i.status===403)throw new Error(`You do not have access to the component at ${f.info(o)}.
|
|
13
|
+
Your account may not have the required subscription plan for this component.
|
|
14
|
+
Please upgrade your subscription or use a component available in your current plan.`);let u=await i.json(),m=u&&typeof u=="object"&&"error"in u?u.error:i.statusText||l[i.status];throw new Error(`Failed to fetch from ${f.info(o)}.
|
|
15
|
+
${m}`)}return i.json()}))}catch(r){return p.error(`
|
|
16
|
+
`),S(r),[]}}async function ut(e,t){try{if(!await Ae(t))return null;e.includes("index")&&e.unshift("index");let n=await $e(e,t),s=await oe(n,t),o=Cr.array(U).parse(s);if(!o)return null;let i=(await b(t.resolvedPaths.cwd))?.framework.name,l=Oe.all(o.map(x=>x.dependencies??[])),u=Oe.all(o.map(x=>x.devDependencies??[])),m=jr(u,i);return it.parse({dependencies:l,devDependencies:m,files:Oe.all(o.map(x=>x.files??[]))})}catch(r){return S(r),null}}async function Er(e,t){let r=new Set,n=[];async function s(o){let a=gt(dt(o)?o:`components/${o}.json`);if(!r.has(a)){r.add(a);try{let[i]=await oe([a],t),l=U.parse(i);if(n.push(a),l.registryDependencies)for(let u of l.registryDependencies)await s(u)}catch(i){console.error(`Error fetching or parsing registry item at ${o}:`,i)}}}return await s(e),Array.from(new Set(n))}async function $e(e,t){let r=[];for(let n of e){let s=await Er(n,t);r.push(...s)}return Array.from(new Set(r))}function gt(e){if(dt(e))return new URL(e).toString();if(!se)throw new Error("No registry URL found");if(e==="index.json")return`${se}/r/${e}`;if(e.startsWith("components/")){let t=e.replace("components/","").replace(".json","");return`${se}/api/registry/components/${t}`}return`${se}/${e}`}function dt(e){try{return new URL(e),!0}catch{return!1}}function ht(){return new Map([["registry:ui","tiptapUi"],["registry:ui-primitive","tiptapUiPrimitives"],["registry:extension","tiptapExtensions"],["registry:node","tiptapNodes"],["registry:context","contexts"],["registry:hook","hooks"],["registry:lib","lib"],["registry:context","components"],["registry:template","tiptapTemplates"],["registry:component","components"],["registry:icon","titpapIcons"],["registry:style","styles"]])}function yt(e){let t=new Map;return e.forEach(r=>{r.registryDependencies&&r.registryDependencies.forEach(n=>{t.set(n,r)})}),t}function jr(e,t){let r=Array.isArray(e)?e:[];if(!r.length)return[];let n=r.map(a=>String(a)),s=n.includes("sass"),o=n.includes("sass-embedded");if(s&&o){let a=[...n];return t&&(t==="vite"?a=a.filter(i=>i!=="sass"):(t==="next-app"||t==="next-pages")&&(a=a.filter(i=>i!=="sass-embedded"))),a}return n}import{execa as Or}from"execa";import Y from"chalk";var c={cyan:Y.hex("#46caff"),gray:Y.hex("#898989"),magenta:Y.hex("#f64d90"),white:Y.white,yellow:Y.yellow,green:Y.green,red:Y.red};async function Ne(e,t,r){if(e=Array.from(new Set(e)),!e?.length)return;r={silent:!1,...r};let n=h("Installing dependencies.",{silent:r.silent}).start(),s=await D(t.resolvedPaths.cwd);await Or(s,[s==="npm"?"install":"add",...s==="npm"?["--save"]:[],...e],{cwd:t.resolvedPaths.cwd}),n.stopAndPersist({symbol:c.cyan("\u2714")})}import{existsSync as kt,promises as Fe}from"fs";import E,{basename as Kr}from"path";import{promises as Dr}from"fs";import{tmpdir as Lr}from"os";import xt from"path";var we=async({sourceFile:e,config:t})=>{let r=e.getImportDeclarations();for(let n of r){let s=Ar(n.getModuleSpecifierValue(),t);s&&n.setModuleSpecifier(s)}return e};function Ar(e,t){if(!e.startsWith("@/registry/")){let r=t.aliases.components.split("/")[0];return e.replace(/^@\//,`${r}/`)}return e.match(/@\/registry\/tiptap-templates\/([^/]+)\/components\//)?e.replace(/@\/registry\/tiptap-templates\/([^/]+)\/components\//,`${t.aliases.components}/tiptap-templates/$1/`):e.match(/@\/registry\/tiptap-templates\/([^/]+)\/(?!components\/)/)?e.replace(/@\/registry\/tiptap-templates\/([^/]+)\//,`${t.aliases.components}/tiptap-templates/$1/`):t.aliases.components&&e.match(/@\/registry\/components/)?e.replace(/@\/registry\/components/,t.aliases.components):t.aliases.contexts&&e.match(/@\/registry\/contexts/)?e.replace(/@\/registry\/contexts/,t.aliases.contexts):t.aliases.tiptapExtensions&&e.match(/@\/registry\/tiptap-extension/)?e.replace(/@\/registry\/tiptap-extension/,t.aliases.tiptapExtensions):t.aliases.hooks&&e.match(/@\/registry\/hooks/)?e.replace(/@\/registry\/hooks/,t.aliases.hooks):t.aliases.tiptapIcons&&e.match(/@\/registry\/tiptap-icons/)?e.replace(/@\/registry\/tiptap-icons/,t.aliases.tiptapIcons):t.aliases.lib&&e.match(/@\/registry\/lib/)?e.replace(/@\/registry\/lib/,t.aliases.lib):t.aliases.tiptapNodes&&e.match(/@\/registry\/tiptap-node/)?e.replace(/@\/registry\/tiptap-node/,t.aliases.tiptapNodes):t.aliases.tiptapUiPrimitives&&e.match(/@\/registry\/tiptap-ui-primitive/)?e.replace(/@\/registry\/tiptap-ui-primitive/,t.aliases.tiptapUiPrimitives):t.aliases.tiptapUi&&e.match(/@\/registry\/tiptap-ui/)?e.replace(/@\/registry\/tiptap-ui/,t.aliases.tiptapUi):t.aliases.styles&&e.match(/@\/registry\/styles/)?e.replace(/@\/registry\/styles/,t.aliases.styles):e.replace(/^@\/registry\/[^/]+(?:\/.*\/)?/,t.aliases.components+"/")}import{transformFromAstSync as $r}from"@babel/core";import{parse as Nr}from"@babel/parser";import Fr from"@babel/plugin-transform-typescript";import*as xe from"recast";var _r={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"]},wt=async({sourceFile:e,config:t})=>{let r=e.getFullText();if(t.tsx)return r;let n=xe.parse(r,{parser:{parse:o=>Nr(o,_r)}}),s=$r(n,r,{cloneInputAst:!1,code:!1,ast:!0,plugins:[Fr],configFile:!1});if(!s||!s.ast)throw new Error("Failed to transform JSX");return xe.print(s.ast).code};import{SyntaxKind as Mr}from"ts-morph";var Ur=/^["']use client["']$/g,ve=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let r=e.getFirstChildByKind(Mr.ExpressionStatement);return r&&Ur.test(r.getText())&&r.remove(),e};var ke=async({sourceFile:e,config:t})=>{if((await b(t.resolvedPaths.cwd))?.framework.name==="vite"){let n=e.getFullText();n=n.replace(/process\.env\.NEXT_PUBLIC_([A-Za-z0-9_]+)/g,"import.meta.env.VITE_$1"),n=n.replace(/process\.env\.([A-Za-z0-9_]+)/g,"import.meta.env.$1"),e.replaceWithText(n)}return e};import{Project as zr,ScriptKind as Vr}from"ts-morph";var Wr=new zr({compilerOptions:{}});async function Gr(e){let t=await Dr.mkdtemp(xt.join(Lr(),"tiptap-"));return xt.join(t,e)}async function vt(e,t=[we,ve,ke]){let r=await Gr(e.filename),n=Wr.createSourceFile(r,e.raw,{scriptKind:Vr.TSX});for(let s of t)await s({sourceFile:n,...e});return e.transformJsx?await wt({sourceFile:n,...e}):n.getText()}import{confirm as Br}from"@inquirer/prompts";import _e from"chalk";async function Me(e,t,r){if(!e?.length)return{filesCreated:[],filesUpdated:[],filesSkipped:[]};r={overwrite:!1,force:!1,silent:!1,...r};let n=h("Updating files.",{silent:r.silent})?.start(),[s]=await Promise.all([b(t.resolvedPaths.cwd)]),o=[],a=[],i=[];for(let u of e){if(!u.content)continue;let m=Xr(u,t,{isSrcDir:s?.isSrcDir,framework:s?.framework.name,commonRoot:Jr(e.map(y=>y.path),u.path)});if(!m)continue;let x=Kr(u.path),k=E.dirname(m);t.tsx||(m=m.replace(/\.tsx?$/,y=>y===".tsx"?".jsx":".js"));let v=kt(m),$=await vt({filename:u.path,raw:u.content,config:t,transformJsx:!t.tsx},[we,ve,ke]);if(v){let y=await Fe.readFile(m,"utf-8"),[j,W]=await Promise.all([Pt(y),Pt($)]);if(j===W){i.push(E.relative(t.resolvedPaths.cwd,m));continue}}if(v&&!r.overwrite){if(n.stop(),r.rootSpinner&&r.rootSpinner.stop(),!await Br({message:_e.white(`The file ${f.info(x)} already exists. Would you like to overwrite?`),theme:{prefix:_e.hex("#46caff")("?"),style:{answer:j=>_e.white(j)}}})){i.push(E.relative(t.resolvedPaths.cwd,m)),r.rootSpinner&&r.rootSpinner.start();continue}n?.start(),r.rootSpinner&&r.rootSpinner.start()}kt(k)||await Fe.mkdir(k,{recursive:!0}),await Fe.writeFile(m,$,"utf-8"),v?a.push(E.relative(t.resolvedPaths.cwd,m)):o.push(E.relative(t.resolvedPaths.cwd,m))}if(!(o.length||a.length)&&!i.length&&n?.info("No files updated."),o.length){if(n?.succeed(`Created ${o.length} ${o.length===1?"file":"files"}:`),!r.silent)for(let u of o)p.log(` - ${u}`)}else n?.stop();if(a.length&&(h(`Updated ${a.length} ${a.length===1?"file":"files"}:`,{silent:r.silent})?.info(),!r.silent))for(let u of a)p.log(` - ${u}`);if(i.length&&(h(`Skipped ${i.length} ${a.length===1?"file":"files"}: (use --overwrite to overwrite)`,{silent:r.silent})?.info(),!r.silent))for(let u of i)p.log(` - ${u}`);return r.silent||p.break(),{filesCreated:o,filesUpdated:a,filesSkipped:i}}function Yr(e,t,r){return r||(e.type==="registry:ui"?t.resolvedPaths.tiptapUi:e.type==="registry:ui-primitive"?t.resolvedPaths.tiptapUiPrimitives:e.type==="registry:extension"?t.resolvedPaths.tiptapExtensions:e.type==="registry:node"?t.resolvedPaths.tiptapNodes:e.type==="registry:icon"?t.resolvedPaths.tiptapIcons:e.type==="registry:hook"?t.resolvedPaths.hooks:e.type==="registry:lib"?t.resolvedPaths.lib:e.type==="registry:context"?t.resolvedPaths.contexts:e.type==="registry:template"||e.type==="registry:component"?t.resolvedPaths.components:e.type==="registry:style"?t.resolvedPaths.styles:t.resolvedPaths.components)}function Jr(e,t){let r=e.map(a=>a.replace(/^\//,"")),n=t.replace(/^\//,""),s=n.split("/").slice(0,-1).join("/");if(!s)return"";let o=s.split("/");for(let a=o.length;a>0;a--){let i=o.slice(0,a).join("/");if(r.some(u=>u!==n&&u.startsWith(i+"/")))return"/"+i}return"/"+s}async function Pt(e){return e.replace(/\r\n/g,`
|
|
17
|
+
`).trim()}function Hr(e,t){if(!t)return"";if(t==="next-app")return e;if(t==="next-pages"){let r=e.replace(/^app\//,"pages/");return r=r.replace(/\/page(\.[jt]sx?)$/,"$1"),r}if(t==="react-router"){let r=e.replace(/^app\//,"app/routes/");return r=r.replace(/\/page(\.[jt]sx?)$/,"$1"),r}if(t==="laravel"){let r=e.replace(/^app\//,"resources/js/pages/");return r=r.replace(/\/page(\.[jt]sx?)$/,"$1"),r}return""}function qr(e,t){let r=e.replace(/^\/|\/$/g,""),n=t.replace(/^\/|\/$/g,""),s=r.split("/"),o=n.split("/"),a=o[o.length-1],i=s.findIndex(l=>l===a);return i===-1?s[s.length-1]:s.slice(i+1).join("/")}function Xr(e,t,r){if(!e.target&&e.path.includes("tiptap-templates/")&&e.type!=="registry:page"){let o=e.path.match(/tiptap-templates\/([^/]+)\/(.*)/);if(o){let[,a,i]=o;if(i.startsWith("components/")){let l=i.replace("components/","");return E.join(t.resolvedPaths.components,"tiptap-templates",a,l)}return E.join(t.resolvedPaths.components,"tiptap-templates",a,i)}}if(e.target&&e.path.includes("tiptap-templates/")&&e.target.includes("/data/")){let o=e.path.match(/tiptap-templates\/([^/]+)\//);if(o){let a=o[1],i=e.target.split("/data/")[1];return E.join(t.resolvedPaths.components,"tiptap-templates",a,"data",i)}}if(e.target){if(e.target.startsWith("~/"))return E.join(t.resolvedPaths.cwd,e.target.replace("~/",""));let o=e.target;return e.type==="registry:page"&&(o=Hr(o,r.framework),!o)?"":r.isSrcDir?E.join(t.resolvedPaths.cwd,"src",o.replace("src/","")):E.join(t.resolvedPaths.cwd,o.replace("src/",""))}let n=Yr(e,t),s=qr(e.path,n);return E.join(n,s)}import{z as Qr}from"zod";import{execa as Zr}from"execa";async function St(e,t,r){if(e=Array.from(new Set(e)),!e?.length)return;r={silent:!1,...r};let n=h("Installing development dependencies.",{silent:r.silent})?.start(),s=await D(t.resolvedPaths.cwd);n?.start(),await Zr(s,[s==="npm"?"install":"add",s==="npm"?"--save-dev":"-D",...e],{cwd:t.resolvedPaths.cwd}),n?.stopAndPersist({symbol:c.cyan("\u2714")})}async function Pe(e,t,r){r={overwrite:!1,silent:!1,isNewProject:!1,...r};let n=await et(t);return n&&n.tiptapUi&&n.tiptapUi.resolvedPaths.cwd!==t.resolvedPaths.cwd?await tn(e,t,n,{...r}):await en(e,t,r)}async function en(e,t,r){let n=h("Checking registry.",{silent:r.silent}).start(),s=await ut(e,t);return s?(n.stopAndPersist({symbol:c.cyan("\u2714")}),await Ne(s.dependencies,t,{silent:r.silent}),await St(s.devDependencies,t,{silent:r.silent}),await Me(s.files,t,{overwrite:r.overwrite,silent:r.silent})):(n?.fail(),S(new Error("Failed to fetch components from registry.")))}async function tn(e,t,r,n){let s=h("Checking registry.",{silent:n.silent}).start(),o=await $e(e,t),a=await oe(o,t),i=Qr.array(U).parse(a);if(!i.length)return s?.fail(),S(new Error("Failed to fetch components from registry."));s.stopAndPersist({symbol:c.cyan("\u2714")});let l=yt(i),u=ht(),m=[],x=[],k=[],v=h("Installing components.")?.start();for(let y of i){let j=u.get(y.type),W=l.get(y.name);if(!j)continue;let O=(y.type==="registry:ui"||W?.type==="registry:ui")&&r.tiptapUi||t;if(!O.resolvedPaths.tiptapUi)continue;let G=je(t.resolvedPaths.cwd,O.resolvedPaths.tiptapUi),K=await Ee(G,O.resolvedPaths.cwd)??O.resolvedPaths.cwd;await Ne(y.dependencies||[],O,{silent:!0});let J=await Me(y.files||[],O,{overwrite:n.overwrite,silent:!0,rootSpinner:v});m.push(...J.filesCreated.map(B=>X.relative(G,X.join(K,B)))),x.push(...J.filesUpdated.map(B=>X.relative(G,X.join(K,B)))),k.push(...J.filesSkipped.map(B=>X.relative(G,X.join(K,B))))}if(v.stopAndPersist({symbol:c.cyan("\u2714")}),m.sort(),x.sort(),k.sort(),!(m.length||x.length)&&!k.length&&h("No files updated.",{silent:n.silent})?.info(),m.length){h(`Created ${m.length} ${m.length===1?"file":"files"}:`,{silent:n.silent})?.stopAndPersist({symbol:c.cyan("\u2714")});for(let y of m)p.log(` - ${y}`)}if(x.length){h(`Updated ${x.length} ${x.length===1?"file":"files"}:`,{silent:n.silent})?.info();for(let y of x)p.log(` - ${y}`)}if(k.length){h(`Skipped ${k.length} ${k.length===1?"file":"files"}: (use --overwrite to overwrite)`,{silent:n.silent})?.info();for(let y of k)p.log(` - ${y}`)}return{filesCreated:m,filesUpdated:x,filesSkipped:k}}function Ue(e){return e.split(/[-_]/).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}var on=Z.object({components:Z.array(Z.string()).optional(),cwd:Z.string(),path:Z.string().optional(),silent:Z.boolean()}),Rt={free:"Free",paid:"Paid"},Tt=1e3,L={divider:c.gray("-----------------------------------------"),warning:c.magenta(" Some components (marked as Paid) require an active subscription!"),emptyRegistry:c.red(" No components or templates found"),operationCancelled:c.red(" Operation cancelled"),missingDirectory:c.red(" Missing directory or empty project. Please create a new project first.")},Se={icon:{cursor:c.cyan("\u276F"),checked:"\u25CF"},style:{highlight:e=>c.cyan(e),answer:e=>c.white(e)},prefix:{done:c.cyan("\u2714"),idle:c.white("?")},helpMode:"always"},an={...Se,icon:{...Se.icon,checked:"\u25CF",cursor:" "}};function pn(e,t){return t?e.filter(r=>t.includes(r.name)):e}var De=e=>`
|
|
18
|
+
${c.gray(e)}
|
|
19
|
+
`;function Le(e){for(let t=0;t<e;t++)process.stdout.write("\x1B[1A"),process.stdout.write("\x1B[2K")}var cn=e=>({templates:e.filter(t=>t.type==="registry:template"),ui:e.filter(t=>t.type==="registry:ui"),primitives:e.filter(t=>t.type==="registry:ui-primitive"),nodes:e.filter(t=>t.type==="registry:node")});async function ln(e){let t=c.white("What would you like to integrate:"),r=De(" Use arrow-keys \u25B2\u25BC / [Return] to submit"),n=[],s=e.ui.length===0&&e.nodes.length===0;if(e.templates.length===0||n.push({name:"Templates",value:"templates"}),s||n.push({name:"Components",value:"components"}),n.length===0)return p.break(),console.log(L.emptyRegistry),null;try{console.log(L.divider);let a=await te({message:t,instructions:r,pageSize:Tt,theme:Se,choices:n});return console.log(L.divider),a}catch{return Le(4),console.log(L.operationCancelled),null}}async function mn(e,t){let r=[];if(!t)return r;let n=(s,o)=>{let a=s.filter(i=>t.includes(i.name));a.length>0&&(r.push(new bt(c.gray(` ${o}`))),a.forEach(i=>{let l=Rt[i.plan||"free"];r.push({name:`${Ue(i.name)} (${l})`,value:i.name})}),r.push(new bt(" ")))};return n(e.ui,"UI COMPONENTS"),n(e.nodes,"NODE COMPONENTS"),n(e.primitives,"PRIMITIVES"),r}async function fn(e,t){let r=De(`${L.warning}
|
|
20
|
+
[Space] to select / [A] to toggle all / [I] to invert / [Return] to submit`),n=await mn(e,t);if(n.length===0)return[];try{let s=await sn({message:c.white("Select the components you want to add:"),instructions:r,required:!0,pageSize:20,choices:n,theme:an});return console.log(""),s}catch{return Le(25),console.log(L.operationCancelled),[]}}async function un(e){try{let t=De(" Use arrow-keys \u25B2\u25BC / [Return] to submit"),r=e.map(n=>{let s=Rt[n.plan||"free"],o=n.description?` - ${n.description}`:"";return{name:`${Ue(n.name)}${o} (${s})`,value:n.name}});return await te({message:c.white("Select the template you want to add:"),instructions:t,pageSize:Tt,choices:r,theme:Se})}catch{return Le(4),console.log(L.operationCancelled),""}}async function ze(e){if(e.components?.length)return e.components;let t=await Ae();if(!t)return p.break(),S(new Error("[prompts] - Failed to fetch registry index.")),[];let r=t.filter(Boolean),n=cn(r),s=await ln(n);if(!s)return[];let o=await ft();if(!o)return p.break(),S(new Error("[prompts] - Failed to fetch free components.")),[];switch(s){case"components":return await fn(n,o)||[];case"templates":{let a=pn(n.templates,o),i=await un(a);return i?[i]:[]}default:return[]}}var It=new nn().name("add").description("add Tiptap components and templates to your project").argument("[components...]","the components to add").option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).option("-p, --path <path>","the path to add the component to.").option("-s, --silent","mute output.",!1).action(async(e,t)=>{try{let r=on.parse({components:e,cwd:rn.resolve(t.cwd),...t});if(r.components?.length||(r.components=await ze(r)),!r.components?.length)return;let{errors:n,config:s}=await rt(r);if(n[M]&&(p.warn(`
|
|
21
|
+
${L.missingDirectory}`),process.exit(0)),!s)throw new Error(`Failed to read config at ${f.info(r.cwd)}.`);await Pe(r.components,s,r)}catch(r){p.break(),S(r)}});import{Command as gn}from"commander";var Ct=new gn().name("info").description("get information about your project").option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).action(async e=>{p.info("> project info"),console.log(await b(e.cwd)),p.break(),p.info("> config"),console.log(await N(e.cwd))});import $t from"path";import{Command as On}from"commander";import{confirm as An}from"@inquirer/prompts";import{z as V}from"zod";import dn from"path";import Et from"fs-extra";async function jt(e){let t={};if(!Et.existsSync(e.cwd)||!Et.existsSync(dn.resolve(e.cwd,"package.json")))return t[M]=!0,{errors:t,projectInfo:null};let r=h("Verifying framework.",{silent:e.silent}).start(),n=await b(e.cwd);(!n||n?.framework.name==="manual")&&(t[Be]=!0,r?.fail(),p.break(),n?.framework.links.installation&&p.error(`We could not detect a supported framework at ${f.info(e.cwd)}.
|
|
22
|
+
Visit ${f.info(n?.framework.links.installation)} to manually configure your project.
|
|
23
|
+
Once configured, you can use the cli to add components.`),p.break(),process.exit(0)),r?.succeed(`Verifying framework. Found ${f.info(n.framework.label)}.`);let s=h("Validating import alias.",{silent:e.silent}).start();return n?.aliasPrefix?s?.succeed():(t[Ce]=!0,s?.fail()),Object.keys(t).length>0&&(t[Ce]&&(p.break(),p.error("No import alias found in your tsconfig.json file."),n?.framework.links.installation&&p.error(`Visit ${f.info(n?.framework.links.installation)} to learn how to set an import alias.`)),p.break(),process.exit(0)),{errors:t,projectInfo:n}}import hn from"os";import z from"path";import C from"fs-extra";import{execa as F}from"execa";import{parse as yn}from"jsonc-parser";import{input as wn}from"@inquirer/prompts";var xn="https://codeload.github.com/shadcn-ui/ui/tar.gz/main",Q={next:"next",vite:"vite","next-monorepo":"next-monorepo"},vn=(e,t="")=>wn({message:c.white(e),default:t,required:!0,validate:r=>r.length>128?"Name should be less than 128 characters.":!0,theme:{prefix:{done:c.cyan("\u2714"),idle:c.white("?")},style:{answer:r=>c.white(r)}}}),kn=async(e,t)=>{let r=`
|
|
24
|
+
${c.gray(" Use arrow-keys \u25B2\u25BC / [Return] to submit")}
|
|
25
|
+
`;return te({message:c.white(e),instructions:r,theme:{icon:{cursor:c.cyan("\u276F")},style:{highlight:n=>c.cyan(n),answer:n=>c.white(n)},prefix:{done:c.cyan("\u2714"),idle:c.white("?")},helpMode:"always"},choices:t})};async function Ot(e){let t={srcDir:!1,...e},r=t.framework&&Q[t.framework]?t.framework:"next",n="my-app",s="latest";if(!t.framework){let i=`The path ${c.cyan(t.cwd)} does not contain a package.json file.
|
|
26
|
+
Would you like to start a new project?`;r=await kn(i,[{name:"Next.js",value:"next"},{name:"Vite + React + TypeScript",value:"vite"}])}n=await vn("What is your project named?",n);let o=await D(t.cwd,{withFallback:!0}),a=z.join(t.cwd,n);return await Pn(t.cwd,n),r===Q.next?await Sn(a,{version:s,cwd:t.cwd,packageManager:o,srcDir:!!t.srcDir}):r===Q.vite?await bn(a,{cwd:t.cwd,packageManager:o,projectName:n}):r===Q["next-monorepo"]&&await Cn(a,{packageManager:o}),{projectPath:a,projectName:n,framework:r}}async function Pn(e,t){try{await C.access(e,C.constants.W_OK)}catch{p.break(),p.error(`The path ${f.info(e)} is not writable.`),p.error(`It is likely you do not have write permissions for this folder or the path ${f.info(e)} does not exist.`),p.break(),process.exit(0)}C.existsSync(z.resolve(e,t,"package.json"))&&(p.break(),p.error(`A project with the name ${f.info(t)} already exists.`),p.error("Please choose a different name and try again."),p.break(),process.exit(0))}async function Sn(e,t){let r=h("Creating a new Next.js project. This may take a few minutes.").start(),n=["--tailwind","--eslint","--typescript","--app",t.srcDir?"--src-dir":"--no-src-dir","--no-import-alias",`--use-${t.packageManager}`];(t.version.startsWith("15")||t.version.startsWith("latest")||t.version.startsWith("canary"))&&n.push("--turbopack");try{await F("npx",[`create-next-app@${t.version}`,e,"--silent",...n],{cwd:t.cwd}),await At(e),r.stopAndPersist({symbol:c.cyan("\u2714")})}catch{r?.fail("Something went wrong creating a new Next.js project."),p.break(),p.error("Something went wrong creating a new Next.js project. Please try again."),process.exit(0)}}async function bn(e,t){let r=h("Creating a new Vite + React + TypeScript project. This may take a few minutes.").start();try{await F("npm",["create","vite@latest",t.projectName,"--","--template","react-ts"],{cwd:t.cwd}),await F(t.packageManager,["install"],{cwd:e}),await Rn(e),await At(e),r.stopAndPersist({symbol:c.cyan("\u2714")})}catch(n){r?.fail("Something went wrong creating a new Vite project."),S(n)}}async function Rn(e){try{await Tn(e),await In(e)}catch{p.warn("Failed to set up TypeScript path aliases, but project creation succeeded")}}async function Tn(e){let t=async r=>{let n=z.join(e,r);if(!await C.pathExists(n))return;let s=await C.readFile(n,"utf-8"),o=yn(s);o.compilerOptions={...o.compilerOptions,baseUrl:".",paths:{...o.compilerOptions?.paths||{},"@/*":["./src/*"]}};let a=JSON.stringify(o,null,2);await C.writeFile(n,a)};await t("tsconfig.json"),await t("tsconfig.app.json")}async function In(e){let t=z.join(e,"vite.config.ts"),n=(await C.readFile(t,"utf-8")).replace("import { defineConfig } from 'vite'",`import { defineConfig } from 'vite'
|
|
27
|
+
import path from 'path'`).replace("plugins: [react()]",`plugins: [react()],
|
|
28
|
+
resolve: {
|
|
29
|
+
alias: {
|
|
30
|
+
'@': path.resolve(__dirname, './src')
|
|
31
|
+
}
|
|
32
|
+
}`);await C.writeFile(t,n)}async function Cn(e,t){let r=h("Creating a new Next.js monorepo. This may take a few minutes.").start();try{await En(e),await F(t.packageManager,["install"],{cwd:e}),await jn(e),r?.succeed("Creating a new Next.js monorepo.")}catch(n){r?.fail("Something went wrong creating a new Next.js monorepo."),S(n)}}async function En(e){let t=z.join(hn.tmpdir(),`tiptap-framework-${Date.now()}`);await C.ensureDir(t);let r=await fetch(xn);if(!r.ok)throw new Error(`Failed to download framework: ${r.statusText}`);let n=z.resolve(t,"framework.tar.gz");await C.writeFile(n,Buffer.from(await r.arrayBuffer())),await F("tar",["-xzf",n,"-C",t,"--strip-components=2","ui-main/templates/monorepo-next"]);let s=z.resolve(t,"monorepo-next");await C.move(s,e),await C.remove(t)}async function jn(e){let t=process.cwd();try{await F("git",["--version"],{cwd:e}),await F("git",["init"],{cwd:e}),await F("git",["add","-A"],{cwd:e}),await F("git",["commit","-m","Initial commit"],{cwd:e}),await F("cd",[t])}catch{p.warn("Failed to initialize git repository, but project creation succeeded")}}async function At(e){let t=z.join(e,"README.md"),r=`# Tiptap Editor Project
|
|
33
|
+
|
|
34
|
+
Thank you for installing the Tiptap Simple Editor template via the Tiptap CLI! This README will help you get started quickly.
|
|
35
|
+
|
|
36
|
+
## Getting Started
|
|
37
|
+
Before running the project, make sure to install the required Tiptap packages:
|
|
38
|
+
|
|
39
|
+
\`\`\`bash
|
|
40
|
+
npm i @tiptap/react @tiptap/starter-kit @tiptap/extension-image @tiptap/extension-task-item @tiptap/extension-task-list @tiptap/extension-text-align @tiptap/extension-typography
|
|
41
|
+
\`\`\`
|
|
42
|
+
|
|
43
|
+
### Run the project
|
|
44
|
+
Install dependencies (if you haven't already):
|
|
45
|
+
|
|
46
|
+
\`\`\`bash
|
|
47
|
+
npm install
|
|
48
|
+
\`\`\`
|
|
49
|
+
or use yarn or pnpm.
|
|
50
|
+
|
|
51
|
+
### Start the development server
|
|
52
|
+
|
|
53
|
+
\`\`\`bash
|
|
54
|
+
npm run dev
|
|
55
|
+
\`\`\`
|
|
56
|
+
or yarn or pnpm.
|
|
57
|
+
|
|
58
|
+
### Include Global Styles
|
|
59
|
+
To apply the correct styles to the editor, manually import these files into your main CSS/SCSS entry point:
|
|
60
|
+
|
|
61
|
+
\`\`\`jsx
|
|
62
|
+
@import 'path-to/_variables.scss';
|
|
63
|
+
@import 'path-to/_keyframes-animations.scss';
|
|
64
|
+
\`\`\`
|
|
65
|
+
|
|
66
|
+
Make sure the path matches your project structure.
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
### Access the template
|
|
70
|
+
Once the server is running, you can access the Tiptap Simple Editor template by visiting the /simple route in your application.
|
|
71
|
+
|
|
72
|
+
http://localhost:3000/simple
|
|
73
|
+
|
|
74
|
+
## Documentation
|
|
75
|
+
To learn more about the Tiptap Simple Editor and how to customize it, visit the official documentation:
|
|
76
|
+
[Tiptap Simple Editor Documentation](https://tiptap.dev/docs/ui-components/templates/simple-editor)
|
|
77
|
+
`;try{await C.writeFile(t,r,"utf-8"),console.log(`Updated README.md in ${e}`)}catch(n){console.error(`Error updating README.md: ${n}`)}}var $n=V.object({cwd:V.string(),components:V.array(V.string()).optional(),silent:V.boolean(),isNewProject:V.boolean(),srcDir:V.boolean().optional(),framework:V.string().optional().refine(e=>!e||Q[e],{message:"Invalid framework. Please use 'next' or 'vite'."})}),Ve=(e,t=!0)=>An({message:c.white(e),default:t,theme:{prefix:{done:c.cyan("\u2714"),idle:c.white("?")},style:{answer:r=>c.white(r),message:r=>c.white(r)}}}),Nt=new On().name("init").description("initialize your project and install dependencies").argument("[components...]","the components to add").option("-f, --framework <framework>","the framework to use. (next, vite)").option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",process.cwd()).option("-s, --silent","mute output.",!1).option("--src-dir","use the src directory when creating a new project (specific to next).",!1).action(async(e,t)=>{try{let r=$n.parse({cwd:$t.resolve(t.cwd),isNewProject:!1,components:e,...t});await Nn(r),p.log(`${f.success("Success!")} Project initialization completed.`),p.break()}catch(r){p.break(),S(r)}});async function Nn(e){let{cwd:t,skipPreflight:r,components:n,silent:s}=e,o,a,i={...e};if(r)o=await b(t);else{let k=await jt(e);if(k.errors[M]){let{projectPath:$,framework:y}=await Ot(e);$||process.exit(0),i={...i,cwd:$,isNewProject:!0},a=y}o=k.projectInfo}if(a==="next-monorepo"){let k=$t.resolve(i.cwd,"apps/web");return await N(k)}let l=await Ze(i.cwd,o),u=l?await _n(l):await Fn(await N(i.cwd)),m=n||[];m.length||(await Ve("Would you like to add a template or UI components to your project?")||(p.info(""),process.exit(0)),m=await ze(i),m.length||(p.info(""),process.exit(0)));let x=await re(i.cwd,u);return await Pe(m,x,{overwrite:!0,silent:s,isNewProject:i.isNewProject||o?.framework.name==="next-app"}),x}async function Fn(e=null){p.info("");let t=await Ve(`Would you like to use ${c.cyan("TypeScript")} (recommended)?`,e?.tsx??!0),r=await Ve(`Are you using ${c.cyan("React Server Components")}?`,e?.rsc??!0);return q.parse({rsc:r,tsx:t,aliases:{components:pe,contexts:ce,hooks:le,tiptapIcons:me,lib:ne,tiptapExtensions:fe,tiptapNodes:ue,tiptapUi:ge,tiptapUiPrimitives:de,styles:he}})}async function _n(e){return q.parse({rsc:e?.rsc,tsx:e?.tsx,aliases:e?.aliases})}import{Command as Un}from"commander";var Ft={name:"tiptap-cli",version:"1.1.10",description:"Tiptap CLI",publishConfig:{access:"public"},author:{name:"tiptap",url:"https://github.com/ueberdosis/tiptap"},files:["dist"],keywords:["cli","components","nextjs","react","templates","tiptap","tiptap-cli","ui"],type:"module",exports:{".":{types:"./dist/index.d.ts",default:"./dist/index.js"}},bin:"./dist/index.js",scripts:{dev:"tsup --watch",build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist","start:dev":"cross-env REGISTRY_URL=http://localhost:3000 node dist/index.js","start:prod":"cross-env REGISTRY_URL=https://template.tiptap.dev node dist/index.js",start:"node dist/index.js","pub:beta":"pnpm build && pnpm publish --no-git-checks --access public --tag beta","pub:release":"pnpm build && pnpm publish --access public"},dependencies:{"@antfu/ni":"^23.3.1","@babel/core":"^7.26.10","@babel/parser":"^7.27.0","@babel/plugin-transform-typescript":"^7.27.0","@inquirer/core":"^10.1.10","@inquirer/figures":"^1.0.11","@inquirer/prompts":"^7.4.1","@inquirer/type":"^3.0.6","ansi-escapes":"^7.0.0",chalk:"^5.4.1",commander:"^13.1.0",cosmiconfig:"^9.0.0",deepmerge:"^4.3.1",execa:"^9.5.2","fast-glob":"^3.3.3","fs-extra":"^11.3.0","https-proxy-agent":"^7.0.6","jsonc-parser":"^3.3.1",kleur:"^4.1.5","node-fetch":"^3.3.2",ora:"^8.2.0",recast:"^0.23.11","ts-morph":"^25.0.1","tsconfig-paths":"^4.2.0",yaml:"^2.7.1","yoctocolors-cjs":"^2.1.2",zod:"^3.24.2"},devDependencies:{"@babel/plugin-transform-typescript":"^7.26.5","@types/babel__core":"^7.20.5","@types/fs-extra":"^11.0.4","@types/prompts":"^2.4.9",tsup:"^8.4.0","type-fest":"^4.39.1"}};process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function Dn(){let e=new Un().name("tiptap").description("add components and dependencies to your project").version(Ft.version||"1.0.0","-v, --version","display the version number");e.addCommand(Nt).addCommand(It).addCommand(Ct),e.parse()}Dn();
|
|
78
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/add.ts","../src/inquirer/select.ts","../src/preflights/preflight-add.ts","../src/utils/errors.ts","../src/utils/get-config.ts","../src/utils/resolve-import.ts","../src/utils/get-project-info.ts","../src/utils/frameworks.ts","../src/utils/get-package-info.ts","../src/utils/highlighter.ts","../src/utils/logger.ts","../src/utils/add-components.ts","../src/utils/handle-error.ts","../src/utils/registry/schema.ts","../src/utils/auth.ts","../src/utils/spinner.ts","../src/utils/get-package-manager.ts","../src/utils/registry/index.ts","../src/utils/updaters/update-dependencies.ts","../src/utils/colors.ts","../src/utils/updaters/update-files.ts","../src/utils/transformers/index.ts","../src/utils/transformers/transform-import.ts","../src/utils/transformers/transform-jsx.ts","../src/utils/transformers/transform-rsc.ts","../src/utils/transformers/transform-env-vars.ts","../src/utils/updaters/update-dev-dependencies.ts","../src/utils/common.ts","../src/commands/info.ts","../src/commands/init.ts","../src/preflights/preflight-init.ts","../src/utils/create-project.ts","../src/index.ts","../package.json"],"sourcesContent":["import path from \"path\"\nimport { Command } from \"commander\"\nimport { z } from \"zod\"\nimport select from \"@/src/inquirer/select\"\nimport { checkbox, Separator } from \"@inquirer/prompts\"\nimport { preFlightAdd } from \"@/src/preflights/preflight-add\"\nimport { addComponents } from \"@/src/utils/add-components\"\nimport * as ERRORS from \"@/src/utils/errors\"\nimport { handleError } from \"@/src/utils/handle-error\"\nimport { highlighter } from \"@/src/utils/highlighter\"\nimport { logger } from \"@/src/utils/logger\"\nimport { fetchFreeRegistry, getRegistryIndex } from \"@/src/utils/registry\"\nimport { colors } from \"@/src/utils/colors\"\nimport type { RegistryItemIndexSchema } from \"@/src/utils/registry/schema\"\nimport { toReadableName } from \"@/src/utils/common\"\n\nexport const addOptionsSchema = z.object({\n components: z.array(z.string()).optional(),\n cwd: z.string(),\n path: z.string().optional(),\n silent: z.boolean(),\n})\n\ntype AddOptions = z.infer<typeof addOptionsSchema>\n\ninterface CategoryMap {\n templates: RegistryItemIndexSchema\n ui: RegistryItemIndexSchema\n primitives: RegistryItemIndexSchema\n nodes: RegistryItemIndexSchema\n}\n\nconst PLANS = {\n free: \"Free\",\n paid: \"Paid\",\n // Future plans:\n // start: \"Start\",\n // plus: \"Plus\",\n // growth: \"Growth\",\n // enterprise: \"Enterprise\",\n}\n\nconst PROMPT_PAGE_SIZE = 1_000 // Large size to avoid help tip\n\nconst UI = {\n divider: colors.gray(\"-----------------------------------------\"),\n warning: colors.magenta(\n \" Some components (marked as Paid) require an active subscription!\"\n ),\n emptyRegistry: colors.red(\" No components or templates found\"),\n operationCancelled: colors.red(\" Operation cancelled\"),\n missingDirectory: colors.red(\n \" Missing directory or empty project. Please create a new project first.\"\n ),\n}\n\nconst PROMPT_THEME = {\n icon: {\n cursor: colors.cyan(\"❯\"),\n checked: \"●\",\n },\n style: {\n highlight: (text: string) => colors.cyan(text),\n answer: (text: string) => colors.white(text),\n },\n prefix: {\n done: colors.cyan(\"✔\"),\n idle: colors.white(\"?\"),\n },\n helpMode: \"always\" as const,\n}\n\nconst CHECKBOX_THEME = {\n ...PROMPT_THEME,\n icon: {\n ...PROMPT_THEME.icon,\n checked: \"●\",\n cursor: \" \",\n },\n}\n\n/**\n * Filters templates to only include free ones based on registry data\n */\nfunction filterFreeTemplates(\n templates: RegistryItemIndexSchema,\n freeComponents: string[] | null\n): RegistryItemIndexSchema {\n if (!freeComponents) {\n return templates\n }\n\n return templates.filter((template) => freeComponents.includes(template.name))\n}\n\n/**\n * Creates instruction text for prompts\n */\nconst createInstruction = (text: string): string => {\n return `\\n${colors.gray(text)}\\n`\n}\n\n/**\n * Clears specified number of lines from console\n */\nfunction clearPromptLines(lines: number) {\n for (let i = 0; i < lines; i++) {\n process.stdout.write(\"\\x1B[1A\") // Move cursor up\n process.stdout.write(\"\\x1B[2K\") // Clear line\n }\n}\n\n/**\n * Categorizes registry items by type\n */\nconst categorizeRegistryItems = (\n registryIndex: RegistryItemIndexSchema\n): CategoryMap => {\n return {\n templates: registryIndex.filter(\n (entry) => entry.type === \"registry:template\"\n ),\n ui: registryIndex.filter((entry) => entry.type === \"registry:ui\"),\n primitives: registryIndex.filter(\n (entry) => entry.type === \"registry:ui-primitive\"\n ),\n nodes: registryIndex.filter((entry) => entry.type === \"registry:node\"),\n }\n}\n\n/**\n * Prompts user to select between components and templates\n */\nasync function promptForInitialSelection(\n categories: CategoryMap\n): Promise<\"components\" | \"templates\" | null> {\n const message = colors.white(\"What would you like to integrate:\")\n const instructions = createInstruction(\n \" Use arrow-keys ▲▼ / [Return] to submit\"\n )\n\n const choices = []\n const isComponentEmpty =\n categories.ui.length === 0 && categories.nodes.length === 0\n const isTemplateEmpty = categories.templates.length === 0\n\n if (!isTemplateEmpty) {\n choices.push({ name: \"Templates\", value: \"templates\" })\n }\n\n if (!isComponentEmpty) {\n choices.push({ name: \"Components\", value: \"components\" })\n }\n\n if (choices.length === 0) {\n logger.break()\n console.log(UI.emptyRegistry)\n return null\n }\n\n try {\n console.log(UI.divider)\n const selection = await select({\n message,\n instructions,\n pageSize: PROMPT_PAGE_SIZE,\n theme: PROMPT_THEME,\n choices,\n })\n console.log(UI.divider)\n return selection as \"templates\" | \"components\"\n } catch (error) {\n clearPromptLines(4)\n console.log(UI.operationCancelled)\n return null\n }\n}\n\n/**\n * Creates choices for component menu with appropriate sections\n */\nasync function createComponentChoices(\n categories: CategoryMap,\n freeComponents: string[] | null\n): Promise<Array<{ name: string; value: string } | Separator>> {\n const choices: Array<{ name: string; value: string } | Separator> = []\n\n if (!freeComponents) {\n return choices\n }\n\n const addCategorySection = (\n items: RegistryItemIndexSchema,\n title: string\n ) => {\n const freeItems = items.filter((item) => freeComponents.includes(item.name))\n\n if (freeItems.length > 0) {\n choices.push(new Separator(colors.gray(` ${title}`)))\n\n freeItems.forEach((item) => {\n const planLabel = PLANS[item.plan || \"free\"]\n choices.push({\n name: `${toReadableName(item.name)} (${planLabel})`,\n value: item.name,\n })\n })\n\n choices.push(new Separator(\" \"))\n }\n }\n\n addCategorySection(categories.ui, \"UI COMPONENTS\")\n addCategorySection(categories.nodes, \"NODE COMPONENTS\")\n addCategorySection(categories.primitives, \"PRIMITIVES\")\n\n return choices\n}\n\n/**\n * Shows menu for selecting components\n */\nasync function componentMenu(\n categories: CategoryMap,\n freeComponents: string[] | null\n): Promise<string[]> {\n const instructions = createInstruction(\n `${UI.warning}\\n [Space] to select / [A] to toggle all / [I] to invert / [Return] to submit`\n )\n\n const choices = await createComponentChoices(categories, freeComponents)\n\n if (choices.length === 0) {\n return []\n }\n\n try {\n const selectedComponents = await checkbox({\n message: colors.white(\"Select the components you want to add:\"),\n instructions,\n required: true,\n pageSize: 20,\n choices,\n theme: CHECKBOX_THEME,\n })\n\n console.log(\"\")\n return selectedComponents\n } catch (error) {\n clearPromptLines(25) // 20 for menu + 5 for console\n console.log(UI.operationCancelled)\n return []\n }\n}\n\n/**\n * Shows menu for selecting templates\n */\nasync function templateMenu(\n templates: RegistryItemIndexSchema\n): Promise<string> {\n try {\n const instructions = createInstruction(\n \" Use arrow-keys ▲▼ / [Return] to submit\"\n )\n\n const choices = templates.map((template) => {\n const planLabel = PLANS[template.plan || \"free\"]\n const description = template.description\n ? ` - ${template.description}`\n : \"\"\n\n return {\n name: `${toReadableName(template.name)}${description} (${planLabel})`,\n value: template.name,\n }\n })\n\n return await select({\n message: colors.white(\"Select the template you want to add:\"),\n instructions,\n pageSize: PROMPT_PAGE_SIZE,\n choices,\n theme: PROMPT_THEME,\n })\n } catch (error) {\n clearPromptLines(4)\n console.log(UI.operationCancelled)\n return \"\"\n }\n}\n\n/**\n * Main function to prompt for registry components\n */\nexport async function promptForRegistryComponents(\n options: AddOptions\n): Promise<string[]> {\n if (options.components?.length) {\n return options.components\n }\n\n const registryIndex = await getRegistryIndex()\n\n if (!registryIndex) {\n logger.break()\n handleError(new Error(\"[prompts] - Failed to fetch registry index.\"))\n return []\n }\n\n // Filter out hidden components from the registry\n const visibleRegistryItems = registryIndex.filter(Boolean)\n const categories = categorizeRegistryItems(visibleRegistryItems)\n\n const selection = await promptForInitialSelection(categories)\n\n if (!selection) {\n return []\n }\n\n const freeComponents = await fetchFreeRegistry()\n\n if (!freeComponents) {\n logger.break()\n handleError(new Error(\"[prompts] - Failed to fetch free components.\"))\n return []\n }\n\n switch (selection) {\n case \"components\":\n return (await componentMenu(categories, freeComponents)) || []\n case \"templates\": {\n const filteredTemplates = filterFreeTemplates(\n categories.templates,\n freeComponents\n )\n const templateResult = await templateMenu(filteredTemplates)\n return templateResult ? [templateResult] : []\n }\n default:\n return []\n }\n}\n\nexport const add = new Command()\n .name(\"add\")\n .description(\"add Tiptap components and templates to your project\")\n .argument(\"[components...]\", \"the components to add\")\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd()\n )\n .option(\"-p, --path <path>\", \"the path to add the component to.\")\n .option(\"-s, --silent\", \"mute output.\", false)\n .action(async (components, opts) => {\n try {\n const options = addOptionsSchema.parse({\n components,\n cwd: path.resolve(opts.cwd),\n ...opts,\n })\n\n if (!options.components?.length) {\n options.components = await promptForRegistryComponents(options)\n }\n\n // No components selected\n if (!options.components?.length) {\n return\n }\n\n const { errors, config } = await preFlightAdd(options)\n\n if (errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT]) {\n logger.warn(`\\n${UI.missingDirectory}`)\n process.exit(0)\n }\n\n if (!config) {\n throw new Error(\n `Failed to read config at ${highlighter.info(options.cwd)}.`\n )\n }\n\n await addComponents(options.components, config, options)\n } catch (error) {\n logger.break()\n handleError(error)\n }\n })\n","import {\n createPrompt,\n useState,\n useKeypress,\n usePrefix,\n usePagination,\n useRef,\n useMemo,\n useEffect,\n isBackspaceKey,\n isEnterKey,\n isUpKey,\n isDownKey,\n isNumberKey,\n Separator,\n ValidationError,\n makeTheme,\n type Theme,\n type Status,\n} from \"@inquirer/core\"\nimport type { PartialDeep } from \"@inquirer/type\"\nimport colors from \"yoctocolors-cjs\"\nimport figures from \"@inquirer/figures\"\nimport ansiEscapes from \"ansi-escapes\"\n\ntype SelectTheme = {\n icon: { cursor: string }\n style: {\n disabled: (text: string) => string\n description: (text: string) => string\n }\n helpMode: \"always\" | \"never\" | \"auto\"\n indexMode: \"hidden\" | \"number\"\n}\n\nconst selectTheme: SelectTheme = {\n icon: { cursor: figures.pointer },\n style: {\n disabled: (text: string) => colors.dim(`- ${text}`),\n description: (text: string) => colors.cyan(text),\n },\n helpMode: \"auto\",\n indexMode: \"hidden\",\n}\n\ntype Choice<Value> = {\n value: Value\n name?: string\n description?: string\n short?: string\n disabled?: boolean | string\n type?: never\n}\n\ntype NormalizedChoice<Value> = {\n value: Value\n name: string\n description?: string\n short: string\n disabled: boolean | string\n}\n\ntype SelectConfig<\n Value,\n ChoicesObject =\n | ReadonlyArray<string | Separator>\n | ReadonlyArray<Choice<Value> | Separator>,\n> = {\n message: string\n choices: ChoicesObject extends ReadonlyArray<string | Separator>\n ? ChoicesObject\n : ReadonlyArray<Choice<Value> | Separator>\n pageSize?: number\n loop?: boolean\n default?: unknown\n instructions?: string | boolean\n theme?: PartialDeep<Theme<SelectTheme>>\n}\n\nfunction isSelectable<Value>(\n item: NormalizedChoice<Value> | Separator\n): item is NormalizedChoice<Value> {\n return !Separator.isSeparator(item) && !item.disabled\n}\n\nfunction normalizeChoices<Value>(\n choices:\n | ReadonlyArray<string | Separator>\n | ReadonlyArray<Choice<Value> | Separator>\n): Array<NormalizedChoice<Value> | Separator> {\n return choices.map((choice) => {\n if (Separator.isSeparator(choice)) return choice\n\n if (typeof choice === \"string\") {\n return {\n value: choice as Value,\n name: choice,\n short: choice,\n disabled: false,\n }\n }\n\n const name = choice.name ?? String(choice.value)\n const normalizedChoice: NormalizedChoice<Value> = {\n value: choice.value,\n name,\n short: choice.short ?? name,\n disabled: choice.disabled ?? false,\n }\n\n if (choice.description) {\n normalizedChoice.description = choice.description\n }\n\n return normalizedChoice\n })\n}\n\nexport default createPrompt(\n <Value>(config: SelectConfig<Value>, done: (value: Value) => void) => {\n const { loop = true, pageSize = 7, instructions } = config\n const firstRender = useRef(true)\n const theme = makeTheme<SelectTheme>(selectTheme, config.theme)\n const [status, setStatus] = useState<Status>(\"idle\")\n const prefix = usePrefix({ status, theme })\n const searchTimeoutRef = useRef<ReturnType<typeof setTimeout>>()\n const [showHelpTip, setShowHelpTip] = useState(true)\n\n const items = useMemo(\n () => normalizeChoices(config.choices),\n [config.choices]\n )\n\n const bounds = useMemo(() => {\n const first = items.findIndex(isSelectable)\n const last = items.findLastIndex(isSelectable)\n\n if (first === -1) {\n throw new ValidationError(\n \"[select prompt] No selectable choices. All choices are disabled.\"\n )\n }\n\n return { first, last }\n }, [items])\n\n const defaultItemIndex = useMemo(() => {\n if (!(\"default\" in config)) return -1\n return items.findIndex(\n (item) => isSelectable(item) && item.value === config.default\n )\n }, [config.default, items])\n\n const [active, setActive] = useState(\n defaultItemIndex === -1 ? bounds.first : defaultItemIndex\n )\n\n // Safe to assume the cursor position always point to a Choice.\n const selectedChoice = items[active] as NormalizedChoice<Value>\n\n useKeypress((key, rl) => {\n clearTimeout(searchTimeoutRef.current)\n setShowHelpTip(false)\n\n if (isEnterKey(key)) {\n setStatus(\"done\")\n done(selectedChoice.value)\n } else if (isUpKey(key) || isDownKey(key)) {\n rl.clearLine(0)\n if (\n loop ||\n (isUpKey(key) && active !== bounds.first) ||\n (isDownKey(key) && active !== bounds.last)\n ) {\n const offset = isUpKey(key) ? -1 : 1\n let next = active\n do {\n next = (next + offset + items.length) % items.length\n } while (!isSelectable(items[next]!))\n setActive(next)\n }\n } else if (isNumberKey(key) && !Number.isNaN(Number(rl.line))) {\n const position = Number(rl.line) - 1\n const item = items[position]\n if (item != null && isSelectable(item)) {\n setActive(position)\n }\n\n searchTimeoutRef.current = setTimeout(() => {\n rl.clearLine(0)\n }, 700)\n } else if (isBackspaceKey(key)) {\n rl.clearLine(0)\n } else {\n // Default to search\n const searchTerm = rl.line.toLowerCase()\n const matchIndex = items.findIndex((item) => {\n if (Separator.isSeparator(item) || !isSelectable(item)) return false\n\n return item.name.toLowerCase().startsWith(searchTerm)\n })\n\n if (matchIndex !== -1) {\n setActive(matchIndex)\n }\n\n searchTimeoutRef.current = setTimeout(() => {\n rl.clearLine(0)\n }, 700)\n }\n })\n\n useEffect(\n () => () => {\n clearTimeout(searchTimeoutRef.current)\n },\n []\n )\n\n const message = theme.style.message(config.message, status)\n\n let helpTipTop = \"\"\n let helpTipBottom = \"\"\n if (\n theme.helpMode === \"always\" ||\n (theme.helpMode === \"auto\" &&\n showHelpTip &&\n (instructions === undefined || instructions))\n ) {\n if (typeof instructions === \"string\") {\n helpTipTop = instructions\n } else {\n const keys = [\n `${theme.style.key(\"↑↓\")} to navigate`,\n `${theme.style.key(\"enter\")} to select`,\n theme.indexMode === \"number\"\n ? `${theme.style.key(\"1-9\")} to jump`\n : \"\",\n `type to filter`,\n ]\n helpTipTop = ` (${keys.filter((key) => key !== \"\").join(\", \")})`\n }\n\n if (\n items.length > pageSize &&\n (theme.helpMode === \"always\" ||\n (theme.helpMode === \"auto\" && firstRender.current))\n ) {\n helpTipBottom = `\\n${theme.style.help(\"(Use arrow keys to reveal more choices)\")}`\n firstRender.current = false\n }\n }\n\n const page = usePagination({\n items,\n active,\n renderItem({ item, isActive, index }) {\n if (Separator.isSeparator(item)) {\n return ` ${item.separator}`\n }\n\n const indexLabel = theme.indexMode === \"number\" ? `${index + 1}. ` : \"\"\n if (item.disabled) {\n const disabledLabel =\n typeof item.disabled === \"string\" ? item.disabled : \"(disabled)\"\n return theme.style.disabled(\n `${indexLabel}${item.name} ${disabledLabel}`\n )\n }\n\n const color = isActive ? theme.style.highlight : (x: string) => x\n const cursor = isActive ? theme.icon.cursor : ` `\n return color(`${cursor} ${indexLabel}${item.name}`)\n },\n pageSize,\n loop,\n })\n\n if (status === \"done\") {\n return `${prefix} ${message} ${theme.style.answer(selectedChoice.short)}`\n }\n\n const choiceDescription = selectedChoice.description\n ? `\\n${theme.style.description(selectedChoice.description)}`\n : ``\n\n return `${[prefix, message, helpTipTop].filter(Boolean).join(\" \")}\\n${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`\n }\n)\n\nexport { Separator } from \"@inquirer/core\"\n","import path from \"path\"\nimport { addOptionsSchema } from \"@/src/commands/add\"\nimport * as ERRORS from \"@/src/utils/errors\"\nimport { getConfig } from \"@/src/utils/get-config\"\nimport { highlighter } from \"@/src/utils/highlighter\"\nimport { logger } from \"@/src/utils/logger\"\nimport fs from \"fs-extra\"\nimport { z } from \"zod\"\n\nexport async function preFlightAdd(options: z.infer<typeof addOptionsSchema>) {\n const errors: Record<string, boolean> = {}\n\n if (\n !fs.existsSync(options.cwd) ||\n !fs.existsSync(path.resolve(options.cwd, \"package.json\"))\n ) {\n errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT] = true\n return {\n errors,\n config: null,\n }\n }\n\n try {\n const config = await getConfig(options.cwd)\n\n return {\n errors,\n config: config!,\n }\n } catch (error) {\n console.log(\"[preFlightAdd] - \", error)\n\n logger.break()\n logger.error(\n `An invalid ${highlighter.info(\n \"components.json\"\n )} file was found at ${highlighter.info(\n options.cwd\n )}.\\nBefore you can add components, you must create a valid ${highlighter.info(\n \"components.json\"\n )} file by running the ${highlighter.info(\"init\")} command.`\n )\n logger.error(`Learn more at ${highlighter.info(\"link-here\")}.`)\n logger.break()\n process.exit(0)\n }\n}\n","export const MISSING_DIR_OR_EMPTY_PROJECT = \"1\"\nexport const EXISTING_CONFIG = \"2\"\nexport const MISSING_CONFIG = \"3\"\nexport const FAILED_CONFIG_READ = \"4\"\nexport const IMPORT_ALIAS_MISSING = \"6\"\nexport const UNSUPPORTED_FRAMEWORK = \"7\"\nexport const COMPONENT_URL_NOT_FOUND = \"8\"\nexport const COMPONENT_URL_UNAUTHORIZED = \"9\"\nexport const COMPONENT_URL_FORBIDDEN = \"10\"\nexport const COMPONENT_URL_BAD_REQUEST = \"11\"\nexport const COMPONENT_URL_INTERNAL_SERVER_ERROR = \"12\"\n","import path from \"path\"\nimport { resolveImport } from \"@/src/utils/resolve-import\"\nimport { cosmiconfig } from \"cosmiconfig\"\nimport fg from \"fast-glob\"\nimport { loadConfig } from \"tsconfig-paths\"\nimport { z } from \"zod\"\nimport { getProjectInfo } from \"./get-project-info\"\n\nexport const DEFAULT_COMPONENTS = \"@/components\"\nexport const DEFAULT_CONTEXTS = \"@/contexts\"\nexport const DEFAULT_HOOKS = \"@/hooks\"\nexport const DEFAULT_TIPTAP_ICONS = \"@/components/tiptap-icons\"\nexport const DEFAULT_LIB = \"@/lib\"\nexport const DEFAULT_TIPTAP_EXTENSIONS = \"@/components/tiptap-extension\"\nexport const DEFAULT_TIPTAP_NODES = \"@/components/tiptap-node\"\nexport const DEFAULT_TIPTAP_UI = \"@/components/tiptap-ui\"\nexport const DEFAULT_TIPTAP_UI_PRIMITIVES = \"@/components/tiptap-ui-primitive\"\nexport const DEFAULT_STYLES = \"@/styles\"\n\nconst explorer = cosmiconfig(\"components\", {\n searchPlaces: [\"components.json\"],\n})\n\nexport const rawConfigSchema = z.object({\n rsc: z.coerce.boolean().default(false),\n tsx: z.coerce.boolean().default(true),\n aliases: z.object({\n components: z.string(),\n contexts: z.string().optional(),\n hooks: z.string().optional(),\n tiptapIcons: z.string().optional(),\n lib: z.string().optional(),\n tiptapExtensions: z.string().optional(),\n tiptapNodes: z.string().optional(),\n tiptapUi: z.string().optional(),\n tiptapUiPrimitives: z.string().optional(),\n styles: z.string().optional(),\n }),\n})\n\nexport const configSchema = rawConfigSchema.extend({\n resolvedPaths: z.object({\n cwd: z.string(),\n components: z.string(),\n contexts: z.string(),\n hooks: z.string(),\n tiptapIcons: z.string(),\n lib: z.string(),\n tiptapExtensions: z.string(),\n tiptapNodes: z.string(),\n tiptapUi: z.string(),\n tiptapUiPrimitives: z.string(),\n styles: z.string(),\n }),\n})\n\nexport const workspaceConfigSchema = z.record(configSchema)\n\nexport type RawConfig = z.infer<typeof rawConfigSchema>\n\nexport type Config = z.infer<typeof configSchema>\n\nexport async function getConfig(cwd: string) {\n const res = await explorer.search(cwd)\n let config: RawConfig\n\n if (!res) {\n const projectInfo = await getProjectInfo(cwd)\n config = rawConfigSchema.parse({\n rsc: projectInfo?.isRSC ?? false,\n tsx: projectInfo?.isTsx ?? true,\n aliases: {\n components: DEFAULT_COMPONENTS,\n contexts: DEFAULT_CONTEXTS,\n hooks: DEFAULT_HOOKS,\n tiptapIcons: DEFAULT_TIPTAP_ICONS,\n lib: DEFAULT_LIB,\n tiptapExtensions: DEFAULT_TIPTAP_EXTENSIONS,\n tiptapNodes: DEFAULT_TIPTAP_NODES,\n tiptapUi: DEFAULT_TIPTAP_UI,\n tiptapUiPrimitives: DEFAULT_TIPTAP_UI_PRIMITIVES,\n styles: DEFAULT_STYLES,\n },\n })\n } else {\n config = rawConfigSchema.parse(res.config)\n\n config.aliases = {\n components: config.aliases.components ?? DEFAULT_COMPONENTS,\n contexts: config.aliases.contexts ?? DEFAULT_CONTEXTS,\n hooks: config.aliases.hooks ?? DEFAULT_HOOKS,\n tiptapIcons: config.aliases.tiptapIcons ?? DEFAULT_TIPTAP_ICONS,\n lib: config.aliases.lib ?? DEFAULT_LIB,\n tiptapExtensions:\n config.aliases.tiptapExtensions ?? DEFAULT_TIPTAP_EXTENSIONS,\n tiptapNodes: config.aliases.tiptapNodes ?? DEFAULT_TIPTAP_NODES,\n tiptapUi: config.aliases.tiptapUi ?? DEFAULT_TIPTAP_UI,\n tiptapUiPrimitives:\n config.aliases.tiptapUiPrimitives ?? DEFAULT_TIPTAP_UI_PRIMITIVES,\n styles: config.aliases.styles ?? DEFAULT_STYLES,\n }\n }\n\n return await resolveConfigPaths(cwd, config)\n}\n\nexport async function resolveConfigPaths(cwd: string, config: RawConfig) {\n // Read tsconfig.json.\n const tsConfig = await loadConfig(cwd)\n\n if (tsConfig.resultType === \"failed\") {\n throw new Error(\n `Failed to load ${config.tsx ? \"tsconfig\" : \"jsconfig\"}.json. ${\n tsConfig.message ?? \"\"\n }`.trim()\n )\n }\n\n return configSchema.parse({\n ...config,\n resolvedPaths: {\n cwd,\n components: await resolveImport(config.aliases.components, tsConfig),\n contexts: config.aliases.contexts\n ? await resolveImport(config.aliases.contexts, tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases.components, tsConfig)) ?? cwd,\n \"..\",\n \"contexts\"\n ),\n hooks: config.aliases.hooks\n ? await resolveImport(config.aliases.hooks, tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases.components, tsConfig)) ?? cwd,\n \"..\",\n \"hooks\"\n ),\n tiptapIcons: config.aliases.tiptapIcons\n ? await resolveImport(config.aliases.tiptapIcons, tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases.components, tsConfig)) ?? cwd,\n \"tiptap-icons\"\n ),\n lib: config.aliases.lib\n ? await resolveImport(config.aliases.lib, tsConfig)\n : path.resolve(\n (await resolveImport(DEFAULT_LIB, tsConfig)) ?? cwd,\n \"..\"\n ),\n tiptapExtensions: config.aliases.tiptapExtensions\n ? await resolveImport(config.aliases.tiptapExtensions, tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases.components, tsConfig)) ?? cwd,\n \"tiptap-extension\"\n ),\n tiptapNodes: config.aliases.tiptapNodes\n ? await resolveImport(config.aliases.tiptapNodes, tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases.components, tsConfig)) ?? cwd,\n \"tiptap-node\"\n ),\n tiptapUi: config.aliases.tiptapUi\n ? await resolveImport(config.aliases.tiptapUi, tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases.components, tsConfig)) ?? cwd,\n \"tiptap-ui\"\n ),\n tiptapUiPrimitives: config.aliases.tiptapUiPrimitives\n ? await resolveImport(config.aliases.tiptapUiPrimitives, tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases.components, tsConfig)) ?? cwd,\n \"tiptap-ui-primitive\"\n ),\n styles: config.aliases.styles\n ? await resolveImport(config.aliases.styles, tsConfig)\n : path.resolve(cwd, \"styles\"),\n },\n })\n}\n\n// Note: we can check for -workspace.yaml or \"workspace\" in package.json.\n// Since cwd is not necessarily the root of the project.\n// We'll instead check if ui aliases resolve to a different root.\nexport async function getWorkspaceConfig(config: Config) {\n const resolvedAliases: Record<string, Config> = {}\n\n for (const key of Object.keys(config.aliases)) {\n if (!isAliasKey(key, config)) {\n continue\n }\n\n const resolvedPath = config.resolvedPaths[key]\n const packageRoot = await findPackageRoot(\n config.resolvedPaths.cwd,\n resolvedPath\n )\n\n if (!packageRoot) {\n resolvedAliases[key] = config\n continue\n }\n\n resolvedAliases[key] = await getConfig(packageRoot)\n }\n\n const result = workspaceConfigSchema.safeParse(resolvedAliases)\n if (!result.success) {\n return null\n }\n\n return result.data\n}\n\nexport async function findPackageRoot(cwd: string, resolvedPath: string) {\n const commonRoot = findCommonRoot(cwd, resolvedPath)\n const relativePath = path.relative(commonRoot, resolvedPath)\n\n const packageRoots = await fg.glob(\"**/package.json\", {\n cwd: commonRoot,\n deep: 3,\n ignore: [\"**/node_modules/**\", \"**/dist/**\", \"**/build/**\", \"**/public/**\"],\n })\n\n const matchingPackageRoot = packageRoots\n .map((pkgPath) => path.dirname(pkgPath))\n .find((pkgDir) => relativePath.startsWith(pkgDir))\n\n return matchingPackageRoot ? path.join(commonRoot, matchingPackageRoot) : null\n}\n\nfunction isAliasKey(\n key: string,\n config: Config\n): key is keyof Config[\"aliases\"] {\n return Object.keys(config.resolvedPaths).includes(key)\n}\n\nexport function findCommonRoot(cwd: string, resolvedPath: string) {\n const parts1 = cwd.split(path.sep)\n const parts2 = resolvedPath.split(path.sep)\n const commonParts = []\n\n for (let i = 0; i < Math.min(parts1.length, parts2.length); i++) {\n if (parts1[i] !== parts2[i]) {\n break\n }\n commonParts.push(parts1[i])\n }\n\n return commonParts.join(path.sep)\n}\n","import { createMatchPath, type ConfigLoaderSuccessResult } from \"tsconfig-paths\"\n\nexport async function resolveImport(\n importPath: string,\n config: Pick<ConfigLoaderSuccessResult, \"absoluteBaseUrl\" | \"paths\">\n) {\n return createMatchPath(config.absoluteBaseUrl, config.paths)(\n importPath,\n undefined,\n () => true,\n [\".ts\", \".tsx\"]\n )\n}\n","import path from \"path\"\nimport { FRAMEWORKS, Framework } from \"@/src/utils/frameworks\"\nimport { getPackageInfo } from \"@/src/utils/get-package-info\"\nimport fg from \"fast-glob\"\nimport fs from \"fs-extra\"\nimport { loadConfig } from \"tsconfig-paths\"\nimport {\n Config,\n RawConfig,\n getConfig,\n resolveConfigPaths,\n} from \"@/src/utils/get-config\"\n\nexport type ProjectInfo = {\n framework: Framework\n isSrcDir: boolean\n isRSC: boolean\n isTsx: boolean\n aliasPrefix: string | null\n}\n\nconst PROJECT_SHARED_IGNORE = [\n \"**/node_modules/**\",\n \".next\",\n \"public\",\n \"dist\",\n \"build\",\n]\n\nexport async function getProjectInfo(cwd: string): Promise<ProjectInfo | null> {\n const [configFiles, isSrcDir, isTsx, aliasPrefix, packageJson] =\n await Promise.all([\n fg.glob(\n \"**/{next,vite,astro,app}.config.*|gatsby-config.*|composer.json|react-router.config.*\",\n {\n cwd,\n deep: 3,\n ignore: PROJECT_SHARED_IGNORE,\n }\n ),\n fs.pathExists(path.resolve(cwd, \"src\")),\n isTypeScriptProject(cwd),\n getTsConfigAliasPrefix(cwd),\n getPackageInfo(cwd, false),\n ])\n\n const isUsingAppDir = await fs.pathExists(\n path.resolve(cwd, `${isSrcDir ? \"src/\" : \"\"}app`)\n )\n\n const type: ProjectInfo = {\n framework: FRAMEWORKS[\"manual\"],\n isSrcDir,\n isRSC: false,\n isTsx,\n aliasPrefix,\n }\n\n // Next.js.\n if (configFiles.find((file) => file.startsWith(\"next.config.\"))?.length) {\n type.framework = isUsingAppDir\n ? FRAMEWORKS[\"next-app\"]\n : FRAMEWORKS[\"next-pages\"]\n type.isRSC = isUsingAppDir\n return type\n }\n\n // Astro.\n if (configFiles.find((file) => file.startsWith(\"astro.config.\"))?.length) {\n type.framework = FRAMEWORKS[\"astro\"]\n return type\n }\n\n // Gatsby.\n if (configFiles.find((file) => file.startsWith(\"gatsby-config.\"))?.length) {\n type.framework = FRAMEWORKS[\"gatsby\"]\n return type\n }\n\n // Laravel.\n if (configFiles.find((file) => file.startsWith(\"composer.json\"))?.length) {\n type.framework = FRAMEWORKS[\"laravel\"]\n return type\n }\n\n // Remix.\n if (\n Object.keys(packageJson?.dependencies ?? {}).find((dep) =>\n dep.startsWith(\"@remix-run/\")\n )\n ) {\n type.framework = FRAMEWORKS[\"remix\"]\n return type\n }\n\n // TanStack Start.\n if (\n configFiles.find((file) => file.startsWith(\"app.config.\"))?.length &&\n [\n ...Object.keys(packageJson?.dependencies ?? {}),\n ...Object.keys(packageJson?.devDependencies ?? {}),\n ].find((dep) => dep.startsWith(\"@tanstack/start\"))\n ) {\n type.framework = FRAMEWORKS[\"tanstack-start\"]\n return type\n }\n\n // React Router.\n if (\n configFiles.find((file) => file.startsWith(\"react-router.config.\"))?.length\n ) {\n type.framework = FRAMEWORKS[\"react-router\"]\n return type\n }\n\n // Vite.\n // Some Remix templates also have a vite.config.* file.\n // We'll assume that it got caught by the Remix check above.\n if (configFiles.find((file) => file.startsWith(\"vite.config.\"))?.length) {\n type.framework = FRAMEWORKS[\"vite\"]\n return type\n }\n\n return type\n}\n\nexport async function getTsConfigAliasPrefix(cwd: string) {\n const tsConfig = await loadConfig(cwd)\n\n if (\n tsConfig?.resultType === \"failed\" ||\n !Object.entries(tsConfig?.paths).length\n ) {\n return null\n }\n\n // This assume that the first alias is the prefix.\n for (const [alias, paths] of Object.entries(tsConfig.paths)) {\n if (\n paths.includes(\"./*\") ||\n paths.includes(\"./src/*\") ||\n paths.includes(\"./app/*\") ||\n paths.includes(\"./resources/js/*\") // Laravel.\n ) {\n return alias.replace(/\\/\\*$/, \"\") ?? null\n }\n }\n\n // Use the first alias as the prefix.\n return Object.keys(tsConfig?.paths)?.[0].replace(/\\/\\*$/, \"\") ?? null\n}\n\nexport async function isTypeScriptProject(cwd: string) {\n const files = await fg.glob(\"tsconfig.*\", {\n cwd,\n deep: 1,\n ignore: PROJECT_SHARED_IGNORE,\n })\n\n return files.length > 0\n}\n\nexport async function getProjectConfig(\n cwd: string,\n defaultProjectInfo: ProjectInfo | null = null\n): Promise<Config | null> {\n const [existingConfig, projectInfo] = await Promise.all([\n getConfig(cwd),\n !defaultProjectInfo\n ? getProjectInfo(cwd)\n : Promise.resolve(defaultProjectInfo),\n ])\n\n if (existingConfig) {\n return existingConfig\n }\n\n if (!projectInfo) {\n return null\n }\n\n const config: RawConfig = {\n rsc: projectInfo.isRSC,\n tsx: projectInfo.isTsx,\n aliases: {\n components: `${projectInfo.aliasPrefix}/components`,\n contexts: `${projectInfo.aliasPrefix}/contexts`,\n hooks: `${projectInfo.aliasPrefix}/hooks`,\n tiptapIcons: `${projectInfo.aliasPrefix}/components/tiptap-icons`,\n lib: `${projectInfo.aliasPrefix}/lib`,\n tiptapExtensions: `${projectInfo.aliasPrefix}/components/tiptap-extensions`,\n tiptapNodes: `${projectInfo.aliasPrefix}/components/tiptap-nodes`,\n tiptapUi: `${projectInfo.aliasPrefix}/components/tiptap-ui`,\n tiptapUiPrimitives: `${projectInfo.aliasPrefix}/components/tiptap-ui-primitives`,\n styles: `${projectInfo.aliasPrefix}/styles`,\n },\n }\n\n return await resolveConfigPaths(cwd, config)\n}\n","export const FRAMEWORKS = {\n \"next-app\": {\n name: \"next-app\",\n label: \"Next.js\",\n links: {\n installation: \"https://example.com/docs/installation/next\",\n },\n },\n \"next-pages\": {\n name: \"next-pages\",\n label: \"Next.js\",\n links: {\n installation: \"https://example.com/docs/installation/next\",\n },\n },\n remix: {\n name: \"remix\",\n label: \"Remix\",\n links: {\n installation: \"https://example.com/docs/installation/remix\",\n },\n },\n \"react-router\": {\n name: \"react-router\",\n label: \"React Router\",\n links: {\n installation: \"https://example.com/docs/installation/react-router\",\n },\n },\n vite: {\n name: \"vite\",\n label: \"Vite\",\n links: {\n installation: \"https://example.com/docs/installation/vite\",\n },\n },\n astro: {\n name: \"astro\",\n label: \"Astro\",\n links: {\n installation: \"https://example.com/docs/installation/astro\",\n },\n },\n laravel: {\n name: \"laravel\",\n label: \"Laravel\",\n links: {\n installation: \"https://example.com/docs/installation/laravel\",\n },\n },\n \"tanstack-start\": {\n name: \"tanstack-start\",\n label: \"TanStack Start\",\n links: {\n installation: \"https://example.com/docs/installation/tanstack\",\n },\n },\n gatsby: {\n name: \"gatsby\",\n label: \"Gatsby\",\n links: {\n installation: \"https://example.com/docs/installation/gatsby\",\n },\n },\n manual: {\n name: \"manual\",\n label: \"Manual\",\n links: {\n installation: \"https://example.com/docs/installation/manual\",\n },\n },\n} as const\n\nexport type Framework = (typeof FRAMEWORKS)[keyof typeof FRAMEWORKS]\n","import path from \"path\"\nimport fs from \"fs-extra\"\nimport { type PackageJson } from \"type-fest\"\n\nexport function getPackageInfo(\n cwd: string = \"\",\n shouldThrow: boolean = true\n): PackageJson | null {\n const packageJsonPath = path.join(cwd, \"package.json\")\n\n return fs.readJSONSync(packageJsonPath, {\n throws: shouldThrow,\n }) as PackageJson\n}\n","import { cyan, green, red, yellow } from \"kleur/colors\"\n\nexport const highlighter = {\n error: red,\n warn: yellow,\n info: cyan,\n success: green,\n}\n","import { highlighter } from \"@/src/utils/highlighter\"\n\nexport const logger = {\n error(...args: unknown[]) {\n console.log(highlighter.error(args.join(\" \")))\n },\n warn(...args: unknown[]) {\n console.log(highlighter.warn(args.join(\" \")))\n },\n info(...args: unknown[]) {\n console.log(highlighter.info(args.join(\" \")))\n },\n success(...args: unknown[]) {\n console.log(highlighter.success(args.join(\" \")))\n },\n log(...args: unknown[]) {\n console.log(args.join(\" \"))\n },\n break() {\n console.log(\"\")\n },\n}\n","import path from \"path\"\nimport {\n configSchema,\n findCommonRoot,\n findPackageRoot,\n getWorkspaceConfig,\n workspaceConfigSchema,\n type Config,\n} from \"@/src/utils/get-config\"\nimport { handleError } from \"@/src/utils/handle-error\"\nimport { logger } from \"@/src/utils/logger\"\nimport {\n fetchRegistry,\n getRegistryParentMap,\n getRegistryTypeAliasMap,\n registryResolveItemsTree,\n resolveRegistryItems,\n} from \"@/src/utils/registry\"\nimport { registryItemSchema } from \"@/src/utils/registry/schema\"\nimport { spinner } from \"@/src/utils/spinner\"\nimport { updateDependencies } from \"@/src/utils/updaters/update-dependencies\"\nimport { updateFiles } from \"@/src/utils/updaters/update-files\"\nimport { z } from \"zod\"\nimport { colors } from \"@/src/utils/colors\"\nimport { updateDevDependencies } from \"@/src/utils/updaters/update-dev-dependencies\"\n\nexport async function addComponents(\n components: string[],\n config: Config,\n options: {\n overwrite?: boolean\n silent?: boolean\n isNewProject?: boolean\n }\n) {\n options = {\n overwrite: false,\n silent: false,\n isNewProject: false,\n ...options,\n }\n\n const workspaceConfig = await getWorkspaceConfig(config)\n\n if (\n workspaceConfig &&\n workspaceConfig.tiptapUi &&\n workspaceConfig.tiptapUi.resolvedPaths.cwd !== config.resolvedPaths.cwd\n ) {\n return await addWorkspaceComponents(components, config, workspaceConfig, {\n ...options,\n })\n }\n\n return await addProjectComponents(components, config, options)\n}\n\nasync function addProjectComponents(\n components: string[],\n config: z.infer<typeof configSchema>,\n options: {\n overwrite?: boolean\n silent?: boolean\n isNewProject?: boolean\n }\n) {\n const registrySpinner = spinner(`Checking registry.`, {\n silent: options.silent,\n }).start()\n const tree = await registryResolveItemsTree(components, config)\n if (!tree) {\n registrySpinner?.fail()\n return handleError(new Error(\"Failed to fetch components from registry.\"))\n }\n\n registrySpinner.stopAndPersist({\n symbol: colors.cyan(\"✔\"),\n })\n\n await updateDependencies(tree.dependencies, config, {\n silent: options.silent,\n })\n\n await updateDevDependencies(tree.devDependencies, config, {\n silent: options.silent,\n })\n\n return await updateFiles(tree.files, config, {\n overwrite: options.overwrite,\n silent: options.silent,\n })\n}\n\nasync function addWorkspaceComponents(\n components: string[],\n config: z.infer<typeof configSchema>,\n workspaceConfig: z.infer<typeof workspaceConfigSchema>,\n options: {\n overwrite?: boolean\n silent?: boolean\n isNewProject?: boolean\n }\n) {\n const registrySpinner = spinner(`Checking registry.`, {\n silent: options.silent,\n }).start()\n const registryItems = await resolveRegistryItems(components, config)\n const result = await fetchRegistry(registryItems, config)\n\n const payload = z.array(registryItemSchema).parse(result)\n if (!payload.length) {\n registrySpinner?.fail()\n return handleError(new Error(\"Failed to fetch components from registry.\"))\n }\n registrySpinner.stopAndPersist({\n symbol: colors.cyan(\"✔\"),\n })\n\n const registryParentMap = getRegistryParentMap(payload)\n const registryTypeAliasMap = getRegistryTypeAliasMap()\n\n const filesCreated: string[] = []\n const filesUpdated: string[] = []\n const filesSkipped: string[] = []\n\n const rootSpinner = spinner(`Installing components.`)?.start()\n\n for (const component of payload) {\n const alias = registryTypeAliasMap.get(component.type)\n const registryParent = registryParentMap.get(component.name)\n\n // We don't support this type of component.\n if (!alias) {\n continue\n }\n\n // A good start is ui for now.\n const targetConfig =\n component.type === \"registry:ui\" || registryParent?.type === \"registry:ui\"\n ? workspaceConfig.tiptapUi || config\n : config\n\n if (!targetConfig.resolvedPaths.tiptapUi) {\n continue\n }\n\n const workspaceRoot = findCommonRoot(\n config.resolvedPaths.cwd,\n targetConfig.resolvedPaths.tiptapUi\n )\n const packageRoot =\n (await findPackageRoot(workspaceRoot, targetConfig.resolvedPaths.cwd)) ??\n targetConfig.resolvedPaths.cwd\n\n // 3. Update dependencies.\n await updateDependencies(component.dependencies || [], targetConfig, {\n silent: true,\n })\n\n // 4. Update files.\n const files = await updateFiles(component.files || [], targetConfig, {\n overwrite: options.overwrite,\n silent: true,\n rootSpinner,\n })\n\n filesCreated.push(\n ...files.filesCreated.map((file) =>\n path.relative(workspaceRoot, path.join(packageRoot, file))\n )\n )\n filesUpdated.push(\n ...files.filesUpdated.map((file) =>\n path.relative(workspaceRoot, path.join(packageRoot, file))\n )\n )\n filesSkipped.push(\n ...files.filesSkipped.map((file) =>\n path.relative(workspaceRoot, path.join(packageRoot, file))\n )\n )\n }\n\n rootSpinner.stopAndPersist({\n symbol: colors.cyan(\"✔\"),\n })\n\n // Sort files.\n filesCreated.sort()\n filesUpdated.sort()\n filesSkipped.sort()\n\n const hasUpdatedFiles = filesCreated.length || filesUpdated.length\n if (!hasUpdatedFiles && !filesSkipped.length) {\n spinner(`No files updated.`, {\n silent: options.silent,\n })?.info()\n }\n\n if (filesCreated.length) {\n spinner(\n `Created ${filesCreated.length} ${\n filesCreated.length === 1 ? \"file\" : \"files\"\n }:`,\n {\n silent: options.silent,\n }\n )?.stopAndPersist({\n symbol: colors.cyan(\"✔\"),\n })\n for (const file of filesCreated) {\n logger.log(` - ${file}`)\n }\n }\n\n if (filesUpdated.length) {\n spinner(\n `Updated ${filesUpdated.length} ${\n filesUpdated.length === 1 ? \"file\" : \"files\"\n }:`,\n {\n silent: options.silent,\n }\n )?.info()\n for (const file of filesUpdated) {\n logger.log(` - ${file}`)\n }\n }\n\n if (filesSkipped.length) {\n spinner(\n `Skipped ${filesSkipped.length} ${\n filesSkipped.length === 1 ? \"file\" : \"files\"\n }: (use --overwrite to overwrite)`,\n {\n silent: options.silent,\n }\n )?.info()\n for (const file of filesSkipped) {\n logger.log(` - ${file}`)\n }\n }\n\n return {\n filesCreated,\n filesUpdated,\n filesSkipped,\n }\n}\n","import { highlighter } from \"@/src/utils/highlighter\"\nimport { logger } from \"@/src/utils/logger\"\nimport { z } from \"zod\"\n\nexport function handleError(error: unknown) {\n logger.error(\n `Something went wrong. Please check the error below for more details.`\n )\n logger.error(`If the problem persists, please open an issue on GitHub.`)\n logger.error(\"\")\n if (typeof error === \"string\") {\n logger.error(error)\n logger.break()\n process.exit(0)\n }\n\n if (error instanceof z.ZodError) {\n logger.error(\"Validation failed:\")\n for (const [key, value] of Object.entries(error.flatten().fieldErrors)) {\n logger.error(`- ${highlighter.info(key)}: ${value}`)\n }\n logger.break()\n process.exit(0)\n }\n\n if (error instanceof Error) {\n logger.error(error.message)\n logger.break()\n process.exit(0)\n }\n\n logger.break()\n process.exit(0)\n}\n","import { z } from \"zod\"\n\nexport const registryItemTypeSchema = z.enum([\n \"registry:context\",\n \"registry:extension\",\n \"registry:hook\",\n \"registry:icon\",\n \"registry:lib\",\n \"registry:node\",\n \"registry:template\",\n \"registry:ui-primitive\",\n \"registry:ui\",\n \"registry:page\",\n \"registry:component\",\n \"registry:style\",\n \"registry:asset\",\n])\n\n// TODO: next release\n// export const planSchema = z\n// .enum([\"free\", \"start\", \"plus\", \"growth\", \"enterprise\"])\n// .default(\"free\")\n\nexport const planSchema = z.enum([\"free\", \"paid\"]).default(\"free\")\n\nexport const registryItemFileSchema = z.object({\n path: z.string(),\n content: z.string().optional(),\n type: registryItemTypeSchema,\n target: z.string().optional(),\n})\n\nexport const registryItemSchema = z.object({\n name: z.string(),\n type: registryItemTypeSchema,\n description: z.string().optional(),\n dependencies: z.array(z.string()).optional(),\n devDependencies: z.array(z.string()).optional(),\n registryDependencies: z.array(z.string()).optional(),\n files: z.array(registryItemFileSchema).optional(),\n meta: z.record(z.string(), z.any()).optional(),\n plan: planSchema.optional(),\n hidden: z.boolean().default(true),\n})\n\nexport const registrySchema = z.array(registryItemSchema)\n\nexport type Registry = z.infer<typeof registrySchema>\n\nexport const registryIndexSchema = z.array(\n registryItemSchema.extend({\n files: z.array(z.union([z.string(), registryItemFileSchema])).optional(),\n })\n)\n\nexport const registryResolvedItemsTreeSchema = registryItemSchema.pick({\n dependencies: true,\n devDependencies: true,\n files: true,\n})\n\nexport type RegistryItem = z.infer<typeof registryItemSchema>\nexport type RegistryItemIndexSchema = z.infer<typeof registryIndexSchema>\n","import fs from \"fs-extra\"\nimport path from \"path\"\nimport os from \"os\"\nimport { execa } from \"execa\"\nimport fetch from \"node-fetch\"\nimport { HttpsProxyAgent } from \"https-proxy-agent\"\nimport { logger } from \"@/src/utils/logger\"\nimport { spinner } from \"@/src/utils/spinner\"\nimport yaml from \"yaml\"\n\nconst REGISTRY_URL = process.env.REGISTRY_URL || \"https://template.tiptap.dev\"\nconst AUTH_API_URL = `${REGISTRY_URL}/api/auth`\nconst TIPTAP_REGISTRY = \"https://registry.tiptap.dev/\"\nconst AUTH_TOKEN_KEY = \"//registry.tiptap.dev/:_authToken\"\nconst SCOPE_REGISTRY_KEY = \"@tiptap-pro:registry\"\n\ntype PackageManager = \"npm\" | \"yarn\" | \"pnpm\" | \"bun\"\ntype AuthResult = {\n success: boolean\n token?: string\n error?: string\n}\ntype AuthStatus = {\n authenticated: boolean\n user?: string\n plan?: string\n expires?: string\n token?: string\n}\n\nconst httpAgent = process.env.https_proxy\n ? new HttpsProxyAgent(process.env.https_proxy)\n : undefined\n\n/**\n * Authenticate a user with the Tiptap registry\n */\nexport async function authenticateUser({\n email,\n password,\n packageManager,\n writeConfig = true,\n cwd,\n}: {\n email?: string\n password?: string\n packageManager: PackageManager\n writeConfig?: boolean\n cwd: string\n}): Promise<AuthResult> {\n const loginSpinner = spinner(\n \"Authenticating with Tiptap registry...\"\n )?.start()\n\n try {\n if (!email || !password) {\n loginSpinner?.fail(\"Authentication failed\")\n return { success: false, error: \"Invalid credentials\" }\n }\n\n const token = await requestAuthToken(email, password)\n\n if (writeConfig) {\n const success = await saveAuthToken(token, packageManager, cwd)\n if (!success) {\n loginSpinner?.fail(\"Failed to save authentication token\")\n return { success: false, error: \"Could not save authentication token\" }\n }\n }\n\n loginSpinner?.succeed(\"Authentication successful\")\n return { success: true, token }\n } catch (error) {\n loginSpinner?.fail(\"Authentication failed\")\n return {\n success: false,\n error:\n error instanceof Error\n ? error.message\n : \"Unknown error during authentication\",\n }\n }\n}\n\n/**\n * Request an authentication token from the API\n */\nasync function requestAuthToken(\n email: string,\n password: string\n): Promise<string> {\n const response = await fetch(`${AUTH_API_URL}/login`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email, password }),\n agent: httpAgent,\n })\n\n if (!response.ok) {\n throw new Error(`Error ${response.status}: ${response.statusText}`)\n }\n\n const data = (await response.json()) as { token: string }\n return data.token\n}\n\n/**\n * Check if user is authenticated with Tiptap registry\n */\nexport async function checkAuthStatus(\n packageManager: PackageManager,\n cwd: string\n): Promise<AuthStatus> {\n try {\n const token = await getAuthToken(packageManager, cwd)\n\n if (!token) {\n return { authenticated: false }\n }\n\n const response = await fetch(`${AUTH_API_URL}/verify`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n },\n agent: httpAgent,\n })\n\n if (!response.ok) {\n return { authenticated: false }\n }\n\n const data = (await response.json()) as {\n email?: string\n username?: string\n plan?: string\n expires?: string\n }\n\n return {\n authenticated: true,\n user: data.email || data.username,\n plan: data.plan,\n expires: data.expires,\n token,\n }\n } catch (error) {\n logger.error(\n `Auth status check error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n )\n return { authenticated: false }\n }\n}\n\n/**\n * Save authentication token to package manager config\n */\nasync function saveAuthToken(\n token: string,\n packageManager: PackageManager,\n cwd: string\n): Promise<boolean> {\n try {\n switch (packageManager) {\n case \"npm\":\n await saveNpmToken(token, cwd)\n break\n case \"yarn\":\n await saveYarnToken(token, cwd)\n break\n case \"pnpm\":\n case \"bun\":\n await saveToNpmrc(path.join(cwd, \".npmrc\"), token)\n break\n }\n return true\n } catch (error) {\n logger.error(\n `Error saving auth token: ${error instanceof Error ? error.message : \"Unknown error\"}`\n )\n return false\n }\n}\n\n/**\n * Save token for npm\n */\nasync function saveNpmToken(token: string, cwd: string): Promise<void> {\n await execa(\"npm\", [\"config\", \"set\", SCOPE_REGISTRY_KEY, TIPTAP_REGISTRY], {\n cwd,\n })\n await execa(\"npm\", [\"config\", \"set\", AUTH_TOKEN_KEY, token], { cwd })\n}\n\n/**\n * Save token for yarn (handles v1 and v2+)\n */\nasync function saveYarnToken(token: string, cwd: string): Promise<void> {\n try {\n const { stdout: yarnVersion } = await execa(\"yarn\", [\"--version\"], { cwd })\n const isYarnV1 = yarnVersion.startsWith(\"1.\")\n\n if (isYarnV1) {\n // For Yarn 1.x\n await execa(\n \"yarn\",\n [\"config\", \"set\", SCOPE_REGISTRY_KEY, TIPTAP_REGISTRY],\n { cwd }\n )\n await execa(\"yarn\", [\"config\", \"set\", AUTH_TOKEN_KEY, token], { cwd })\n } else {\n // For Yarn 2+ (Berry)\n await saveYarnBerryToken(token, cwd)\n }\n } catch (error) {\n // Fallback to .npmrc for yarn\n await saveToNpmrc(path.join(cwd, \".npmrc\"), token)\n }\n}\n\n/**\n * Save token for Yarn Berry (v2+)\n */\nasync function saveYarnBerryToken(token: string, cwd: string): Promise<void> {\n const yarnrcPath = path.join(cwd, \".yarnrc.yml\")\n let yamlObj: Record<string, unknown> = {}\n\n // Read existing config if it exists\n if (fs.existsSync(yarnrcPath)) {\n const yarnrcContent = await fs.readFile(yarnrcPath, \"utf8\")\n try {\n yamlObj = yaml.parse(yarnrcContent) || {}\n } catch (e) {\n // If parsing fails, start with empty object\n }\n }\n\n // Ensure the structure exists\n if (!yamlObj.npmScopes) {\n yamlObj.npmScopes = {}\n }\n\n // Set or update the tiptap-pro scope\n ;(yamlObj.npmScopes as Record<string, unknown>)[\"tiptap-pro\"] = {\n npmRegistryServer: TIPTAP_REGISTRY,\n npmAuthToken: token,\n }\n\n // Write back to file\n await fs.writeFile(yarnrcPath, yaml.stringify(yamlObj))\n}\n\n/**\n * Update .npmrc file with token\n */\nasync function saveToNpmrc(npmrcPath: string, token: string): Promise<void> {\n let npmrcContent = \"\"\n\n // Read existing file if it exists\n if (fs.existsSync(npmrcPath)) {\n npmrcContent = await fs.readFile(npmrcPath, \"utf8\")\n }\n\n // Parse .npmrc content\n const { lines, processedKeys } = parseNpmrc(npmrcContent, token)\n\n // Add missing keys\n if (!processedKeys.has(SCOPE_REGISTRY_KEY)) {\n lines.push(`${SCOPE_REGISTRY_KEY}=${TIPTAP_REGISTRY}`)\n }\n\n if (!processedKeys.has(AUTH_TOKEN_KEY)) {\n lines.push(`${AUTH_TOKEN_KEY}=${token}`)\n }\n\n // Ensure file ends with a newline\n if (lines.length > 0 && lines[lines.length - 1] !== \"\") {\n lines.push(\"\")\n }\n\n // Write the updated content back to the file\n await fs.writeFile(npmrcPath, lines.join(\"\\n\"))\n}\n\n/**\n * Parse .npmrc content\n */\nfunction parseNpmrc(\n npmrcContent: string,\n token: string\n): {\n lines: string[]\n processedKeys: Set<string>\n} {\n const lines: string[] = []\n const processedKeys = new Set<string>()\n\n // Split content into lines\n const contentLines = npmrcContent.split(\"\\n\")\n\n // Process each line\n for (const line of contentLines) {\n const trimmedLine = line.trim()\n\n // Skip empty lines or add them as-is\n if (!trimmedLine) {\n lines.push(line)\n continue\n }\n\n // Preserve comments\n if (trimmedLine.startsWith(\"#\")) {\n lines.push(line)\n continue\n }\n\n // Process key-value pairs\n const index = line.indexOf(\"=\")\n if (index !== -1) {\n const key = line.substring(0, index).trim()\n\n // Update specific keys\n if (key === SCOPE_REGISTRY_KEY) {\n lines.push(`${SCOPE_REGISTRY_KEY}=${TIPTAP_REGISTRY}`)\n processedKeys.add(key)\n } else if (key === AUTH_TOKEN_KEY) {\n lines.push(`${AUTH_TOKEN_KEY}=${token}`)\n processedKeys.add(key)\n } else {\n // Keep other keys unchanged\n lines.push(line)\n }\n } else {\n // Keep lines that aren't key-value pairs\n lines.push(line)\n }\n }\n\n return { lines, processedKeys }\n}\n\n/**\n * Get auth token from package manager config\n */\nexport async function getAuthToken(\n packageManager: PackageManager,\n cwd: string\n): Promise<string | null> {\n try {\n // First check project .npmrc\n const projectToken = await checkProjectNpmrc(cwd)\n if (projectToken) {\n return projectToken\n }\n\n // Then check package manager specific methods\n if (packageManager === \"npm\") {\n return await getNpmAuthToken(cwd)\n }\n\n // For other package managers, check global .npmrc\n return await checkGlobalNpmrc()\n } catch (error) {\n // logger.error(\n // `Error getting auth token: ${error instanceof Error ? error.message : 'Unknown error'}`\n // )\n return null\n }\n}\n\n/**\n * Check project .npmrc for auth token\n */\nasync function checkProjectNpmrc(cwd: string): Promise<string | null> {\n const projectNpmrcPath = path.join(cwd, \".npmrc\")\n if (fs.existsSync(projectNpmrcPath)) {\n const content = await fs.readFile(projectNpmrcPath, \"utf8\")\n return extractAuthToken(content)\n }\n return null\n}\n\n/**\n * Get npm auth token using npm config command\n */\nasync function getNpmAuthToken(cwd: string): Promise<string | null> {\n const { stdout } = await execa(\"npm\", [\"config\", \"get\", AUTH_TOKEN_KEY], {\n cwd,\n })\n\n return stdout && stdout !== \"undefined\" ? stdout.trim() : null\n}\n\n/**\n * Check global .npmrc file for auth token\n */\nasync function checkGlobalNpmrc(): Promise<string | null> {\n const globalNpmrcPath = path.join(os.homedir(), \".npmrc\")\n\n if (fs.existsSync(globalNpmrcPath)) {\n const content = await fs.readFile(globalNpmrcPath, \"utf8\")\n return extractAuthToken(content)\n }\n\n return null\n}\n\n/**\n * Extract auth token from config string\n */\nexport function extractAuthToken(configString: string): string | null {\n // Split into lines and filter for registry.tiptap.dev\n const lines = configString\n .split(\"\\n\")\n .filter((line) => line.startsWith(\"//registry.tiptap.dev/:_authToken=\"))\n\n if (lines.length === 0) {\n return null\n }\n\n // Extract the token after the \"=\" sign\n const token = lines[0].split(\"=\")[1]?.trim()\n return token || null\n}\n","import ora, { type Options } from \"ora\"\n\nexport function spinner(\n text: Options[\"text\"],\n options?: {\n silent?: boolean\n }\n) {\n return ora({\n text,\n isSilent: options?.silent,\n })\n}\n","import { detect } from \"@antfu/ni\"\n\nexport async function getPackageManager(\n targetDir: string,\n { withFallback }: { withFallback?: boolean } = {\n withFallback: false,\n }\n): Promise<\"yarn\" | \"pnpm\" | \"bun\" | \"npm\"> {\n let packageManager = await detect({ programmatic: true, cwd: targetDir })\n if (packageManager === \"deno\") packageManager = undefined\n\n if (packageManager === \"yarn@berry\") return \"yarn\"\n if (packageManager === \"pnpm@6\") return \"pnpm\"\n if (packageManager === \"bun\") return \"bun\"\n\n if (!withFallback) {\n return packageManager ?? \"npm\"\n }\n\n // Fallback to user agent if not detected.\n const userAgent = process.env.npm_config_user_agent || \"\"\n\n if (userAgent.startsWith(\"yarn\")) {\n return \"yarn\"\n }\n\n if (userAgent.startsWith(\"pnpm\")) {\n return \"pnpm\"\n }\n\n if (userAgent.startsWith(\"bun\")) {\n return \"bun\"\n }\n\n return \"npm\"\n}\n\nexport async function getPackageRunner(cwd: string) {\n const packageManager = await getPackageManager(cwd)\n\n if (packageManager === \"pnpm\") return \"pnpm dlx\"\n\n if (packageManager === \"bun\") return \"bunx\"\n\n return \"npx\"\n}\n","import { Config, configSchema } from \"@/src/utils/get-config\"\nimport { handleError } from \"@/src/utils/handle-error\"\nimport { highlighter } from \"@/src/utils/highlighter\"\nimport { logger } from \"@/src/utils/logger\"\nimport {\n registryIndexSchema,\n registryItemSchema,\n registryResolvedItemsTreeSchema,\n} from \"@/src/utils/registry/schema\"\nimport { getAuthToken } from \"@/src/utils/auth\"\nimport { getPackageManager } from \"@/src/utils/get-package-manager\"\nimport deepmerge from \"deepmerge\"\nimport { HttpsProxyAgent } from \"https-proxy-agent\"\nimport fetch from \"node-fetch\"\nimport { z } from \"zod\"\nimport { getProjectInfo } from \"@/src/utils/get-project-info\"\n\nconst REGISTRY_URL = process.env.REGISTRY_URL || \"https://template.tiptap.dev\"\n\nconst agent = process.env.https_proxy\n ? new HttpsProxyAgent(process.env.https_proxy)\n : undefined\n\nexport async function getRegistryIndex(config?: Config) {\n try {\n const [result] = await fetchRegistry([\"index.json\"], config)\n\n return registryIndexSchema.parse(result)\n } catch (error) {\n logger.error(\"\\n\")\n handleError(error)\n }\n}\n\nexport async function fetchFreeRegistry() {\n try {\n const url = `${REGISTRY_URL}/api/registry/free`\n const response = await fetch(url, {\n agent,\n })\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch from ${highlighter.info(url)}.\\n${response.statusText}`\n )\n }\n\n const result = (await response.json()) as string[]\n return result\n } catch (error) {\n logger.error(\"\\n\")\n handleError(error)\n }\n}\n\nexport async function fetchRegistry(paths: string[], config?: Config) {\n try {\n let authToken = null\n if (config) {\n const packageManager = await getPackageManager(config.resolvedPaths.cwd)\n authToken = await getAuthToken(packageManager, config.resolvedPaths.cwd)\n }\n\n const results = await Promise.all(\n paths.map(async (path) => {\n const url = getRegistryUrl(path)\n\n // Setup headers with auth token if available\n const headers: Record<string, string> = {}\n if (authToken) {\n headers[\"Authorization\"] = `Bearer ${authToken}`\n }\n\n const response = await fetch(url, {\n agent,\n headers,\n })\n\n if (!response.ok) {\n const errorMessages: { [key: number]: string } = {\n 400: \"Bad request\",\n 401: \"Unauthorized\",\n 403: \"Forbidden\",\n 404: \"Not found\",\n 500: \"Internal server error\",\n }\n\n if (response.status === 401) {\n throw new Error(\n `You are not authorized to access the component at ${highlighter.info(\n url\n )}.\\nPlease run 'tiptap auth login' to authenticate with the registry, or make sure your token is valid.`\n )\n }\n\n if (response.status === 404) {\n throw new Error(\n `The component at ${highlighter.info(\n url\n )} was not found.\\nIt may not exist at the registry. Please make sure it is a valid component.`\n )\n }\n\n if (response.status === 403) {\n throw new Error(\n `You do not have access to the component at ${highlighter.info(\n url\n )}.\\nYour account may not have the required subscription plan for this component.\\nPlease upgrade your subscription or use a component available in your current plan.`\n )\n }\n\n const result = await response.json()\n const message =\n result && typeof result === \"object\" && \"error\" in result\n ? result.error\n : response.statusText || errorMessages[response.status]\n throw new Error(\n `Failed to fetch from ${highlighter.info(url)}.\\n${message}`\n )\n }\n\n return response.json()\n })\n )\n\n return results\n } catch (error) {\n logger.error(\"\\n\")\n handleError(error)\n return []\n }\n}\n\nexport async function registryResolveItemsTree(\n names: z.infer<typeof registryItemSchema>[\"name\"][],\n config: z.infer<typeof configSchema>\n) {\n try {\n const index = await getRegistryIndex(config)\n if (!index) {\n return null\n }\n\n // If we're resolving the index, we want it to go first.\n if (names.includes(\"index\")) {\n names.unshift(\"index\")\n }\n\n const registryItems = await resolveRegistryItems(names, config)\n const result = await fetchRegistry(registryItems, config)\n const payload = z.array(registryItemSchema).parse(result)\n\n if (!payload) {\n return null\n }\n\n const projectInfo = await getProjectInfo(config.resolvedPaths.cwd)\n const framework = projectInfo?.framework.name\n\n const allDependencies = deepmerge.all(\n payload.map((item) => item.dependencies ?? [])\n )\n\n const allDevDependencies = deepmerge.all(\n payload.map((item) => item.devDependencies ?? [])\n )\n\n const filteredDevDependencies = filterDevDependenciesByFramework(\n allDevDependencies,\n framework\n )\n\n return registryResolvedItemsTreeSchema.parse({\n dependencies: allDependencies,\n devDependencies: filteredDevDependencies,\n files: deepmerge.all(payload.map((item) => item.files ?? [])),\n })\n } catch (error) {\n handleError(error)\n return null\n }\n}\n\nasync function resolveRegistryDependencies(\n url: string,\n config: Config\n): Promise<string[]> {\n const visited = new Set<string>()\n const payload: string[] = []\n\n async function resolveDependencies(itemUrl: string) {\n const url = getRegistryUrl(\n isUrl(itemUrl) ? itemUrl : `components/${itemUrl}.json`\n )\n\n if (visited.has(url)) {\n return\n }\n\n visited.add(url)\n\n try {\n const [result] = await fetchRegistry([url], config)\n const item = registryItemSchema.parse(result)\n payload.push(url)\n\n if (item.registryDependencies) {\n for (const dependency of item.registryDependencies) {\n await resolveDependencies(dependency)\n }\n }\n } catch (error) {\n console.error(\n `Error fetching or parsing registry item at ${itemUrl}:`,\n error\n )\n }\n }\n\n await resolveDependencies(url)\n return Array.from(new Set(payload))\n}\n\n// TODO: We're double-fetching here. Use a cache.\nexport async function resolveRegistryItems(names: string[], config: Config) {\n const registryDependencies: string[] = []\n for (const name of names) {\n const itemRegistryDependencies = await resolveRegistryDependencies(\n name,\n config\n )\n registryDependencies.push(...itemRegistryDependencies)\n }\n\n return Array.from(new Set(registryDependencies))\n}\n\nfunction getRegistryUrl(path: string) {\n if (isUrl(path)) {\n const url = new URL(path)\n return url.toString()\n }\n\n if (!REGISTRY_URL) {\n throw new Error(\"No registry URL found\")\n }\n\n // Keep the index.json path as is (public)\n if (path === \"index.json\") {\n return `${REGISTRY_URL}/r/${path}`\n }\n\n // Only redirect component paths to the API\n if (path.startsWith(\"components/\")) {\n const componentName = path.replace(\"components/\", \"\").replace(\".json\", \"\")\n return `${REGISTRY_URL}/api/registry/components/${componentName}`\n }\n\n return `${REGISTRY_URL}/${path}`\n}\n\nfunction isUrl(path: string) {\n try {\n new URL(path)\n return true\n } catch (error) {\n return false\n }\n}\n\nexport function getRegistryTypeAliasMap() {\n return new Map<string, string>([\n [\"registry:ui\", \"tiptapUi\"],\n [\"registry:ui-primitive\", \"tiptapUiPrimitives\"],\n [\"registry:extension\", \"tiptapExtensions\"],\n [\"registry:node\", \"tiptapNodes\"],\n [\"registry:context\", \"contexts\"],\n [\"registry:hook\", \"hooks\"],\n [\"registry:lib\", \"lib\"],\n [\"registry:context\", \"components\"],\n [\"registry:template\", \"tiptapTemplates\"],\n [\"registry:component\", \"components\"],\n [\"registry:icon\", \"titpapIcons\"],\n [\"registry:style\", \"styles\"],\n ])\n}\n\n// Track a dependency and its parent.\nexport function getRegistryParentMap(\n registryItems: z.infer<typeof registryItemSchema>[]\n) {\n const map = new Map<string, z.infer<typeof registryItemSchema>>()\n\n registryItems.forEach((item) => {\n if (!item.registryDependencies) {\n return\n }\n\n item.registryDependencies.forEach((dependency) => {\n map.set(dependency, item)\n })\n })\n\n return map\n}\n\n/**\n * Filter development dependencies based on framework requirements\n * @param devDependencies Array of development dependencies\n * @param framework Framework name\n * @returns Filtered array of development dependencies\n */\nfunction filterDevDependenciesByFramework(\n devDependencies: unknown,\n framework: string | undefined\n): string[] {\n // Ensure we have a proper string array\n const depsArray = Array.isArray(devDependencies) ? devDependencies : []\n\n if (!depsArray.length) {\n return []\n }\n\n const stringDeps = depsArray.map((dep) => String(dep))\n\n const hasSass = stringDeps.includes(\"sass\")\n const hasSassEmbedded = stringDeps.includes(\"sass-embedded\")\n\n if (hasSass && hasSassEmbedded) {\n let filteredDeps = [...stringDeps]\n\n if (framework) {\n if (framework === \"vite\") {\n // Vite prefers sass-embedded\n filteredDeps = filteredDeps.filter((dep) => dep !== \"sass\")\n } else if (framework === \"next-app\" || framework === \"next-pages\") {\n // Next.js prefers sass\n filteredDeps = filteredDeps.filter((dep) => dep !== \"sass-embedded\")\n }\n }\n\n return filteredDeps\n }\n\n return stringDeps\n}\n","import { Config } from \"@/src/utils/get-config\"\nimport { getPackageManager } from \"@/src/utils/get-package-manager\"\nimport { RegistryItem } from \"@/src/utils/registry/schema\"\nimport { spinner } from \"@/src/utils/spinner\"\nimport { execa } from \"execa\"\nimport { colors } from \"@/src/utils/colors\"\n\nexport async function updateDependencies(\n dependencies: RegistryItem[\"dependencies\"],\n config: Config,\n options: {\n silent?: boolean\n }\n) {\n dependencies = Array.from(new Set(dependencies))\n if (!dependencies?.length) {\n return\n }\n\n options = {\n silent: false,\n ...options,\n }\n\n const dependenciesSpinner = spinner(`Installing dependencies.`, {\n silent: options.silent,\n }).start()\n const packageManager = await getPackageManager(config.resolvedPaths.cwd)\n\n await execa(\n packageManager,\n [\n packageManager === \"npm\" ? \"install\" : \"add\",\n ...(packageManager === \"npm\" ? [\"--save\"] : []),\n ...dependencies,\n ],\n {\n cwd: config.resolvedPaths.cwd,\n }\n )\n\n dependenciesSpinner.stopAndPersist({\n symbol: colors.cyan(\"✔\"),\n })\n}\n","import chalk from \"chalk\"\n\nexport const colors = {\n cyan: chalk.hex(\"#46caff\"),\n gray: chalk.hex(\"#898989\"),\n magenta: chalk.hex(\"#f64d90\"),\n white: chalk.white,\n yellow: chalk.yellow,\n green: chalk.green,\n red: chalk.red,\n}\n","import { existsSync, promises as fs } from \"fs\"\nimport path, { basename } from \"path\"\nimport { Config } from \"@/src/utils/get-config\"\nimport { getProjectInfo, ProjectInfo } from \"@/src/utils/get-project-info\"\nimport { highlighter } from \"@/src/utils/highlighter\"\nimport { logger } from \"@/src/utils/logger\"\nimport {\n RegistryItem,\n registryItemFileSchema,\n} from \"@/src/utils/registry/schema\"\nimport { spinner } from \"@/src/utils/spinner\"\nimport { transform } from \"@/src/utils/transformers\"\nimport { transformImport } from \"@/src/utils/transformers/transform-import\"\nimport { transformRsc } from \"@/src/utils/transformers/transform-rsc\"\nimport { transformEnvVars } from \"@/src/utils/transformers/transform-env-vars\"\nimport { z } from \"zod\"\nimport { confirm } from \"@inquirer/prompts\"\nimport chalk from \"chalk\"\n\nexport async function updateFiles(\n files: RegistryItem[\"files\"],\n config: Config,\n options: {\n overwrite?: boolean\n force?: boolean\n silent?: boolean\n rootSpinner?: ReturnType<typeof spinner>\n }\n) {\n if (!files?.length) {\n return {\n filesCreated: [],\n filesUpdated: [],\n filesSkipped: [],\n }\n }\n options = {\n overwrite: false,\n force: false,\n silent: false,\n ...options,\n }\n const filesCreatedSpinner = spinner(`Updating files.`, {\n silent: options.silent,\n })?.start()\n\n const [projectInfo] = await Promise.all([\n getProjectInfo(config.resolvedPaths.cwd),\n ])\n\n const filesCreated = []\n const filesUpdated = []\n const filesSkipped = []\n\n for (const file of files) {\n if (!file.content) {\n continue\n }\n\n let filePath = resolveFilePath(file, config, {\n isSrcDir: projectInfo?.isSrcDir,\n framework: projectInfo?.framework.name,\n commonRoot: findCommonRoot(\n files.map((f) => f.path),\n file.path\n ),\n })\n\n if (!filePath) {\n continue\n }\n\n const fileName = basename(file.path)\n const targetDir = path.dirname(filePath)\n\n if (!config.tsx) {\n filePath = filePath.replace(/\\.tsx?$/, (match) =>\n match === \".tsx\" ? \".jsx\" : \".js\"\n )\n }\n\n const existingFile = existsSync(filePath)\n\n // Run our transformers.\n const content = await transform(\n {\n filename: file.path,\n raw: file.content,\n config,\n transformJsx: !config.tsx,\n },\n [transformImport, transformRsc, transformEnvVars]\n )\n\n if (existingFile) {\n const existingFileContent = await fs.readFile(filePath, \"utf-8\")\n const [normalizedExisting, normalizedNew] = await Promise.all([\n getNormalizedFileContent(existingFileContent),\n getNormalizedFileContent(content),\n ])\n if (normalizedExisting === normalizedNew) {\n filesSkipped.push(path.relative(config.resolvedPaths.cwd, filePath))\n continue\n }\n }\n\n if (existingFile && !options.overwrite) {\n filesCreatedSpinner.stop()\n if (options.rootSpinner) {\n options.rootSpinner.stop()\n }\n\n const overwrite = await confirm({\n message: chalk.white(\n `The file ${highlighter.info(\n fileName\n )} already exists. Would you like to overwrite?`\n ),\n theme: {\n prefix: chalk.hex(\"#46caff\")(\"?\"),\n style: {\n answer: (text: string) => chalk.white(text),\n },\n },\n })\n\n if (!overwrite) {\n filesSkipped.push(path.relative(config.resolvedPaths.cwd, filePath))\n if (options.rootSpinner) {\n options.rootSpinner.start()\n }\n continue\n }\n filesCreatedSpinner?.start()\n if (options.rootSpinner) {\n options.rootSpinner.start()\n }\n }\n\n // Create the target directory if it doesn't exist.\n if (!existsSync(targetDir)) {\n await fs.mkdir(targetDir, { recursive: true })\n }\n\n await fs.writeFile(filePath, content, \"utf-8\")\n existingFile\n ? filesUpdated.push(path.relative(config.resolvedPaths.cwd, filePath))\n : filesCreated.push(path.relative(config.resolvedPaths.cwd, filePath))\n }\n\n const hasUpdatedFiles = filesCreated.length || filesUpdated.length\n if (!hasUpdatedFiles && !filesSkipped.length) {\n filesCreatedSpinner?.info(\"No files updated.\")\n }\n\n if (filesCreated.length) {\n filesCreatedSpinner?.succeed(\n `Created ${filesCreated.length} ${\n filesCreated.length === 1 ? \"file\" : \"files\"\n }:`\n )\n if (!options.silent) {\n for (const file of filesCreated) {\n logger.log(` - ${file}`)\n }\n }\n } else {\n filesCreatedSpinner?.stop()\n }\n\n if (filesUpdated.length) {\n spinner(\n `Updated ${filesUpdated.length} ${\n filesUpdated.length === 1 ? \"file\" : \"files\"\n }:`,\n {\n silent: options.silent,\n }\n )?.info()\n if (!options.silent) {\n for (const file of filesUpdated) {\n logger.log(` - ${file}`)\n }\n }\n }\n\n if (filesSkipped.length) {\n spinner(\n `Skipped ${filesSkipped.length} ${\n filesUpdated.length === 1 ? \"file\" : \"files\"\n }: (use --overwrite to overwrite)`,\n {\n silent: options.silent,\n }\n )?.info()\n if (!options.silent) {\n for (const file of filesSkipped) {\n logger.log(` - ${file}`)\n }\n }\n }\n\n if (!options.silent) {\n logger.break()\n }\n\n return {\n filesCreated,\n filesUpdated,\n filesSkipped,\n }\n}\n\nexport function resolveFileTargetDirectory(\n file: z.infer<typeof registryItemFileSchema>,\n config: Config,\n override?: string\n) {\n if (override) {\n return override\n }\n\n if (file.type === \"registry:ui\") {\n return config.resolvedPaths.tiptapUi\n }\n\n if (file.type === \"registry:ui-primitive\") {\n return config.resolvedPaths.tiptapUiPrimitives\n }\n\n if (file.type === \"registry:extension\") {\n return config.resolvedPaths.tiptapExtensions\n }\n\n if (file.type === \"registry:node\") {\n return config.resolvedPaths.tiptapNodes\n }\n\n if (file.type === \"registry:icon\") {\n return config.resolvedPaths.tiptapIcons\n }\n\n if (file.type === \"registry:hook\") {\n return config.resolvedPaths.hooks\n }\n\n if (file.type === \"registry:lib\") {\n return config.resolvedPaths.lib\n }\n\n if (file.type === \"registry:context\") {\n return config.resolvedPaths.contexts\n }\n\n if (file.type === \"registry:template\" || file.type === \"registry:component\") {\n return config.resolvedPaths.components\n }\n\n if (file.type === \"registry:style\") {\n return config.resolvedPaths.styles\n }\n\n return config.resolvedPaths.components\n}\n\nexport function findCommonRoot(paths: string[], needle: string): string {\n // Remove leading slashes for consistent handling\n const normalizedPaths = paths.map((p) => p.replace(/^\\//, \"\"))\n const normalizedNeedle = needle.replace(/^\\//, \"\")\n\n // Get the directory path of the needle by removing the file name\n const needleDir = normalizedNeedle.split(\"/\").slice(0, -1).join(\"/\")\n\n // If needle is at root level, return empty string\n if (!needleDir) {\n return \"\"\n }\n\n // Split the needle directory into segments\n const needleSegments = needleDir.split(\"/\")\n\n // Start from the full path and work backwards\n for (let i = needleSegments.length; i > 0; i--) {\n const testPath = needleSegments.slice(0, i).join(\"/\")\n // Check if this is a common root by verifying if any other paths start with it\n const hasRelatedPaths = normalizedPaths.some(\n (path) => path !== normalizedNeedle && path.startsWith(testPath + \"/\")\n )\n if (hasRelatedPaths) {\n return \"/\" + testPath // Add leading slash back for the result\n }\n }\n\n // If no common root found with other files, return the parent directory of the needle\n return \"/\" + needleDir // Add leading slash back for the result\n}\n\nexport async function getNormalizedFileContent(content: string) {\n return content.replace(/\\r\\n/g, \"\\n\").trim()\n}\n\nexport function resolvePageTarget(\n target: string,\n framework?: ProjectInfo[\"framework\"][\"name\"]\n) {\n if (!framework) {\n return \"\"\n }\n\n if (framework === \"next-app\") {\n return target\n }\n\n if (framework === \"next-pages\") {\n let result = target.replace(/^app\\//, \"pages/\")\n result = result.replace(/\\/page(\\.[jt]sx?)$/, \"$1\")\n\n return result\n }\n\n if (framework === \"react-router\") {\n let result = target.replace(/^app\\//, \"app/routes/\")\n result = result.replace(/\\/page(\\.[jt]sx?)$/, \"$1\")\n\n return result\n }\n\n if (framework === \"laravel\") {\n let result = target.replace(/^app\\//, \"resources/js/pages/\")\n result = result.replace(/\\/page(\\.[jt]sx?)$/, \"$1\")\n\n return result\n }\n\n return \"\"\n}\n\nexport function resolveNestedFilePath(\n filePath: string,\n targetDir: string\n): string {\n // Normalize paths by removing leading/trailing slashes\n const normalizedFilePath = filePath.replace(/^\\/|\\/$/g, \"\")\n const normalizedTargetDir = targetDir.replace(/^\\/|\\/$/g, \"\")\n\n // Split paths into segments\n const fileSegments = normalizedFilePath.split(\"/\")\n const targetSegments = normalizedTargetDir.split(\"/\")\n\n // Find the last matching segment from targetDir in filePath\n const lastTargetSegment = targetSegments[targetSegments.length - 1]\n const commonDirIndex = fileSegments.findIndex(\n (segment) => segment === lastTargetSegment\n )\n\n if (commonDirIndex === -1) {\n // Return just the filename if no common directory is found\n return fileSegments[fileSegments.length - 1]\n }\n\n // Return everything after the common directory\n return fileSegments.slice(commonDirIndex + 1).join(\"/\")\n}\n\nexport function resolveFilePath(\n file: z.infer<typeof registryItemFileSchema>,\n config: Config,\n options: {\n isSrcDir?: boolean\n commonRoot?: string\n framework?: ProjectInfo[\"framework\"][\"name\"]\n }\n) {\n // if (file.type === \"registry:asset\") {\n // if (file.target) {\n // // replace assets/ and public/ with the public directory\n // const targetDir = file.target.replace(/^assets\\//, \"\")\n // const targetDirPublic = targetDir.replace(/^public\\//, \"\")\n // const targetDirPublicPath = path.join(\n // config.resolvedPaths.cwd,\n // \"public\",\n // targetDirPublic\n // )\n\n // return targetDirPublicPath\n // }\n // }\n\n // Special handling for template files without targets\n if (\n !file.target &&\n file.path.includes(\"tiptap-templates/\") &&\n file.type !== \"registry:page\"\n ) {\n const match = file.path.match(/tiptap-templates\\/([^/]+)\\/(.*)/)\n if (match) {\n const [, templateName, relativePath] = match\n\n // If it's a component file in the components directory, adjust the path\n if (relativePath.startsWith(\"components/\")) {\n const finalPath = relativePath.replace(\"components/\", \"\")\n return path.join(\n config.resolvedPaths.components,\n \"tiptap-templates\",\n templateName,\n finalPath\n )\n }\n\n // For data and other files\n return path.join(\n config.resolvedPaths.components,\n \"tiptap-templates\",\n templateName,\n relativePath\n )\n }\n }\n\n // Special handling for data files with targets in templates\n if (\n file.target &&\n file.path.includes(\"tiptap-templates/\") &&\n file.target.includes(\"/data/\")\n ) {\n const templateMatch = file.path.match(/tiptap-templates\\/([^/]+)\\//)\n if (templateMatch) {\n const templateName = templateMatch[1]\n const dataPath = file.target.split(\"/data/\")[1]\n return path.join(\n config.resolvedPaths.components,\n \"tiptap-templates\",\n templateName,\n \"data\",\n dataPath\n )\n }\n }\n\n // Original logic for files with explicit targets\n if (file.target) {\n if (file.target.startsWith(\"~/\")) {\n return path.join(config.resolvedPaths.cwd, file.target.replace(\"~/\", \"\"))\n }\n\n let target = file.target\n\n if (file.type === \"registry:page\") {\n target = resolvePageTarget(target, options.framework)\n if (!target) {\n return \"\"\n }\n }\n\n return options.isSrcDir\n ? path.join(config.resolvedPaths.cwd, \"src\", target.replace(\"src/\", \"\"))\n : path.join(config.resolvedPaths.cwd, target.replace(\"src/\", \"\"))\n }\n\n // Original logic for non-template files\n const targetDir = resolveFileTargetDirectory(file, config)\n const relativePath = resolveNestedFilePath(file.path, targetDir)\n return path.join(targetDir, relativePath)\n}\n","import { promises as fs } from \"fs\"\nimport { tmpdir } from \"os\"\nimport path from \"path\"\nimport { Config } from \"@/src/utils/get-config\"\nimport { transformImport } from \"@/src/utils/transformers/transform-import\"\nimport { transformJsx } from \"@/src/utils/transformers/transform-jsx\"\nimport { transformRsc } from \"@/src/utils/transformers/transform-rsc\"\nimport { transformEnvVars } from \"@/src/utils/transformers/transform-env-vars\"\nimport { Project, ScriptKind, type SourceFile } from \"ts-morph\"\n\nexport type TransformOpts = {\n filename: string\n raw: string\n config: Config\n transformJsx?: boolean\n}\n\nexport type Transformer<Output = SourceFile> = (\n opts: TransformOpts & {\n sourceFile: SourceFile\n }\n) => Promise<Output>\n\nconst project = new Project({\n compilerOptions: {},\n})\n\nasync function createTempSourceFile(filename: string) {\n const dir = await fs.mkdtemp(path.join(tmpdir(), \"tiptap-\"))\n return path.join(dir, filename)\n}\n\nexport async function transform(\n opts: TransformOpts,\n transformers: Transformer[] = [\n transformImport,\n transformRsc,\n transformEnvVars,\n ]\n) {\n const tempFile = await createTempSourceFile(opts.filename)\n const sourceFile = project.createSourceFile(tempFile, opts.raw, {\n scriptKind: ScriptKind.TSX,\n })\n\n for (const transformer of transformers) {\n await transformer({ sourceFile, ...opts })\n }\n\n if (opts.transformJsx) {\n return await transformJsx({\n sourceFile,\n ...opts,\n })\n }\n\n return sourceFile.getText()\n}\n","import { Config } from \"@/src/utils/get-config\"\nimport { Transformer } from \"@/src/utils/transformers\"\n\nexport const transformImport: Transformer = async ({ sourceFile, config }) => {\n const importDeclarations = sourceFile.getImportDeclarations()\n\n for (const importDeclaration of importDeclarations) {\n const moduleSpecifier = updateImportAliases(\n importDeclaration.getModuleSpecifierValue(),\n config\n )\n\n if (moduleSpecifier) {\n importDeclaration.setModuleSpecifier(moduleSpecifier)\n }\n }\n\n return sourceFile\n}\n\nfunction updateImportAliases(moduleSpecifier: string, config: Config): string {\n // Remove \"/registry/\" from the module specifier\n if (!moduleSpecifier.startsWith(\"@/registry/\")) {\n // We fix the alias and return.\n const alias = config.aliases.components.split(\"/\")[0]\n return moduleSpecifier.replace(/^@\\//, `${alias}/`)\n }\n\n // Handle template imports specifically to preserve the template structure\n if (\n moduleSpecifier.match(\n /@\\/registry\\/tiptap-templates\\/([^/]+)\\/components\\//\n )\n ) {\n return moduleSpecifier.replace(\n /@\\/registry\\/tiptap-templates\\/([^/]+)\\/components\\//,\n `${config.aliases.components}/tiptap-templates/$1/`\n )\n }\n\n // Handle template imports without the components part\n if (\n moduleSpecifier.match(\n /@\\/registry\\/tiptap-templates\\/([^/]+)\\/(?!components\\/)/\n )\n ) {\n return moduleSpecifier.replace(\n /@\\/registry\\/tiptap-templates\\/([^/]+)\\//,\n `${config.aliases.components}/tiptap-templates/$1/`\n )\n }\n\n if (\n config.aliases.components &&\n moduleSpecifier.match(/@\\/registry\\/components/)\n ) {\n return moduleSpecifier.replace(\n /@\\/registry\\/components/,\n config.aliases.components\n )\n }\n\n if (\n config.aliases.contexts &&\n moduleSpecifier.match(/@\\/registry\\/contexts/)\n ) {\n return moduleSpecifier.replace(\n /@\\/registry\\/contexts/,\n config.aliases.contexts\n )\n }\n\n if (\n config.aliases.tiptapExtensions &&\n moduleSpecifier.match(/@\\/registry\\/tiptap-extension/)\n ) {\n return moduleSpecifier.replace(\n /@\\/registry\\/tiptap-extension/,\n config.aliases.tiptapExtensions\n )\n }\n\n if (config.aliases.hooks && moduleSpecifier.match(/@\\/registry\\/hooks/)) {\n return moduleSpecifier.replace(/@\\/registry\\/hooks/, config.aliases.hooks)\n }\n\n if (\n config.aliases.tiptapIcons &&\n moduleSpecifier.match(/@\\/registry\\/tiptap-icons/)\n ) {\n return moduleSpecifier.replace(\n /@\\/registry\\/tiptap-icons/,\n config.aliases.tiptapIcons\n )\n }\n\n if (config.aliases.lib && moduleSpecifier.match(/@\\/registry\\/lib/)) {\n return moduleSpecifier.replace(/@\\/registry\\/lib/, config.aliases.lib)\n }\n\n if (\n config.aliases.tiptapNodes &&\n moduleSpecifier.match(/@\\/registry\\/tiptap-node/)\n ) {\n return moduleSpecifier.replace(\n /@\\/registry\\/tiptap-node/,\n config.aliases.tiptapNodes\n )\n }\n\n if (\n config.aliases.tiptapUiPrimitives &&\n moduleSpecifier.match(/@\\/registry\\/tiptap-ui-primitive/)\n ) {\n return moduleSpecifier.replace(\n /@\\/registry\\/tiptap-ui-primitive/,\n config.aliases.tiptapUiPrimitives\n )\n }\n\n if (\n config.aliases.tiptapUi &&\n moduleSpecifier.match(/@\\/registry\\/tiptap-ui/)\n ) {\n return moduleSpecifier.replace(\n /@\\/registry\\/tiptap-ui/,\n config.aliases.tiptapUi\n )\n }\n\n if (config.aliases.styles && moduleSpecifier.match(/@\\/registry\\/styles/)) {\n return moduleSpecifier.replace(/@\\/registry\\/styles/, config.aliases.styles)\n }\n\n // Default case - preserve all other imports\n return moduleSpecifier.replace(\n /^@\\/registry\\/[^/]+(?:\\/.*\\/)?/,\n config.aliases.components + \"/\"\n )\n}\n","import { type Transformer } from \"@/src/utils/transformers\"\nimport { transformFromAstSync } from \"@babel/core\"\nimport { ParserOptions, parse } from \"@babel/parser\"\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error\nimport transformTypescript from \"@babel/plugin-transform-typescript\"\nimport * as recast from \"recast\"\n\n// TODO.\n// I'm using recast for the AST here.\n// Figure out if ts-morph AST is compatible with Babel.\n\n// This is a copy of the babel options from recast/parser.\n// The goal here is to tolerate as much syntax as possible.\n// We want to be able to parse any valid tsx code.\n// See https://github.com/benjamn/recast/blob/master/parsers/_babel_options.ts.\nconst PARSE_OPTIONS: ParserOptions = {\n sourceType: \"module\",\n allowImportExportEverywhere: true,\n allowReturnOutsideFunction: true,\n startLine: 1,\n tokens: true,\n plugins: [\n \"asyncGenerators\",\n \"bigInt\",\n \"classPrivateMethods\",\n \"classPrivateProperties\",\n \"classProperties\",\n \"classStaticBlock\",\n \"decimal\",\n \"decorators-legacy\",\n \"doExpressions\",\n \"dynamicImport\",\n \"exportDefaultFrom\",\n \"exportNamespaceFrom\",\n \"functionBind\",\n \"functionSent\",\n \"importAssertions\",\n \"importMeta\",\n \"nullishCoalescingOperator\",\n \"numericSeparator\",\n \"objectRestSpread\",\n \"optionalCatchBinding\",\n \"optionalChaining\",\n [\n \"pipelineOperator\",\n {\n proposal: \"minimal\",\n },\n ],\n [\n \"recordAndTuple\",\n {\n syntaxType: \"hash\",\n },\n ],\n \"throwExpressions\",\n \"topLevelAwait\",\n \"v8intrinsic\",\n \"typescript\",\n \"jsx\",\n ],\n}\n\nexport const transformJsx: Transformer<string> = async ({\n sourceFile,\n config,\n}) => {\n const output = sourceFile.getFullText()\n\n if (config.tsx) {\n return output\n }\n\n const ast = recast.parse(output, {\n parser: {\n parse: (code: string) => {\n return parse(code, PARSE_OPTIONS)\n },\n },\n })\n\n const result = transformFromAstSync(ast, output, {\n cloneInputAst: false,\n code: false,\n ast: true,\n plugins: [transformTypescript],\n configFile: false,\n })\n\n if (!result || !result.ast) {\n throw new Error(\"Failed to transform JSX\")\n }\n\n return recast.print(result.ast).code\n}\n","import { Transformer } from \"@/src/utils/transformers\"\nimport { SyntaxKind } from \"ts-morph\"\n\nconst directiveRegex = /^[\"']use client[\"']$/g\n\nexport const transformRsc: Transformer = async ({ sourceFile, config }) => {\n if (config.rsc) {\n return sourceFile\n }\n\n // Remove \"use client\" from the top of the file.\n const first = sourceFile.getFirstChildByKind(SyntaxKind.ExpressionStatement)\n if (first && directiveRegex.test(first.getText())) {\n first.remove()\n }\n\n return sourceFile\n}\n","import { Transformer } from \"@/src/utils/transformers\"\nimport { getProjectInfo } from \"@/src/utils/get-project-info\"\n\nexport const transformEnvVars: Transformer = async ({ sourceFile, config }) => {\n // First check if this is a Vite project\n const projectInfo = await getProjectInfo(config.resolvedPaths.cwd)\n\n if (projectInfo?.framework.name === \"vite\") {\n // Replace process.env with import.meta.env\n // This is a simple replacement method - for more complex cases you might\n // want to use ts-morph's API to modify specific nodes\n let fileContent = sourceFile.getFullText()\n\n // Replace process.env.NEXT_PUBLIC_X with import.meta.env.VITE_X\n fileContent = fileContent.replace(\n /process\\.env\\.NEXT_PUBLIC_([A-Za-z0-9_]+)/g,\n \"import.meta.env.VITE_$1\"\n )\n\n // Replace other process.env.X with import.meta.env.X\n fileContent = fileContent.replace(\n /process\\.env\\.([A-Za-z0-9_]+)/g,\n \"import.meta.env.$1\"\n )\n\n // Update the source file content\n sourceFile.replaceWithText(fileContent)\n }\n\n return sourceFile\n}\n","import { Config } from \"@/src/utils/get-config\"\nimport { getPackageManager } from \"@/src/utils/get-package-manager\"\nimport { RegistryItem } from \"@/src/utils/registry/schema\"\nimport { spinner } from \"@/src/utils/spinner\"\nimport { execa } from \"execa\"\nimport { colors } from \"@/src/utils/colors\"\n\n/**\n * Installs development dependencies for a component\n *\n * @param devDependencies List of development dependencies to install\n * @param config Configuration object with project paths\n * @param options Additional options\n */\nexport async function updateDevDependencies(\n devDependencies: RegistryItem[\"devDependencies\"],\n config: Config,\n options: {\n silent?: boolean\n }\n) {\n devDependencies = Array.from(new Set(devDependencies))\n if (!devDependencies?.length) {\n return\n }\n\n options = {\n silent: false,\n ...options,\n }\n\n const devDependenciesSpinner = spinner(\n `Installing development dependencies.`,\n {\n silent: options.silent,\n }\n )?.start()\n const packageManager = await getPackageManager(config.resolvedPaths.cwd)\n\n devDependenciesSpinner?.start()\n\n // Different package managers have different flags for dev dependencies\n const devFlag = packageManager === \"npm\" ? \"--save-dev\" : \"-D\"\n\n await execa(\n packageManager,\n [packageManager === \"npm\" ? \"install\" : \"add\", devFlag, ...devDependencies],\n {\n cwd: config.resolvedPaths.cwd,\n }\n )\n\n devDependenciesSpinner?.stopAndPersist({\n symbol: colors.cyan(\"✔\"),\n })\n}\n","/**\n * Converts kebab-case or snake_case to Title Case\n */\nexport function toReadableName(input: string): string {\n return input\n .split(/[-_]/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \")\n}\n","import { getConfig } from \"@/src/utils/get-config\"\nimport { getProjectInfo } from \"@/src/utils/get-project-info\"\nimport { logger } from \"@/src/utils/logger\"\nimport { Command } from \"commander\"\n\nexport const info = new Command()\n .name(\"info\")\n .description(\"get information about your project\")\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd()\n )\n .action(async (opts) => {\n logger.info(\"> project info\")\n console.log(await getProjectInfo(opts.cwd))\n logger.break()\n logger.info(\"> config\")\n console.log(await getConfig(opts.cwd))\n })\n","import path from \"path\"\nimport { Command } from \"commander\"\nimport { confirm } from \"@inquirer/prompts\"\nimport { z } from \"zod\"\n\nimport { preFlightInit } from \"@/src/preflights/preflight-init\"\nimport { promptForRegistryComponents } from \"@/src/commands/add\"\nimport { FRAMEWORKS, createProject } from \"@/src/utils/create-project\"\nimport * as ERRORS from \"@/src/utils/errors\"\nimport { colors } from \"@/src/utils/colors\"\nimport { handleError } from \"@/src/utils/handle-error\"\nimport { highlighter } from \"@/src/utils/highlighter\"\nimport { logger } from \"@/src/utils/logger\"\nimport { addComponents } from \"@/src/utils/add-components\"\nimport { getProjectConfig, getProjectInfo } from \"@/src/utils/get-project-info\"\nimport {\n DEFAULT_COMPONENTS,\n DEFAULT_CONTEXTS,\n DEFAULT_HOOKS,\n DEFAULT_TIPTAP_ICONS,\n DEFAULT_LIB,\n DEFAULT_STYLES,\n DEFAULT_TIPTAP_EXTENSIONS,\n DEFAULT_TIPTAP_NODES,\n DEFAULT_TIPTAP_UI,\n DEFAULT_TIPTAP_UI_PRIMITIVES,\n getConfig,\n rawConfigSchema,\n resolveConfigPaths,\n type Config,\n} from \"@/src/utils/get-config\"\n\nexport const initOptionsSchema = z.object({\n cwd: z.string(),\n components: z.array(z.string()).optional(),\n silent: z.boolean(),\n isNewProject: z.boolean(),\n srcDir: z.boolean().optional(),\n framework: z\n .string()\n .optional()\n .refine((val) => !val || FRAMEWORKS[val as keyof typeof FRAMEWORKS], {\n message: \"Invalid framework. Please use 'next' or 'vite'.\",\n }),\n})\n\ntype InitOptions = z.infer<typeof initOptionsSchema> & {\n skipPreflight?: boolean\n}\n\n/**\n * Creates a themed confirmation prompt with consistent styling\n */\nconst createThemedConfirm = (message: string, defaultValue: boolean = true) => {\n return confirm({\n message: colors.white(message),\n default: defaultValue,\n theme: {\n prefix: {\n done: colors.cyan(\"✔\"),\n idle: colors.white(\"?\"),\n },\n style: {\n answer: (text: string) => colors.white(text),\n message: (text: string) => colors.white(text),\n },\n },\n })\n}\n\n/**\n * Initialize the CLI command\n */\nexport const init = new Command()\n .name(\"init\")\n .description(\"initialize your project and install dependencies\")\n .argument(\"[components...]\", \"the components to add\")\n .option(\"-f, --framework <framework>\", \"the framework to use. (next, vite)\")\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd()\n )\n .option(\"-s, --silent\", \"mute output.\", false)\n .option(\n \"--src-dir\",\n \"use the src directory when creating a new project (specific to next).\",\n false\n )\n .action(async (components, opts) => {\n try {\n const options = initOptionsSchema.parse({\n cwd: path.resolve(opts.cwd),\n isNewProject: false,\n components,\n ...opts,\n })\n await runInit(options)\n logger.log(\n `${highlighter.success(\"Success!\")} Project initialization completed.`\n )\n logger.break()\n } catch (error) {\n logger.break()\n handleError(error)\n }\n })\n\n/**\n * Main initialization function\n */\nexport async function runInit(options: InitOptions) {\n const { cwd, skipPreflight, components, silent } = options\n let projectInfo\n let newProjectFramework\n let updatedOptions = { ...options }\n\n // Handle preflight checks and possible project creation\n if (!skipPreflight) {\n const preflight = await preFlightInit(options)\n const isMissingDirOrEmptyProject =\n preflight.errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT]\n\n if (isMissingDirOrEmptyProject) {\n const { projectPath, framework } = await createProject(options)\n if (!projectPath) {\n process.exit(0)\n }\n\n updatedOptions = {\n ...updatedOptions,\n cwd: projectPath,\n isNewProject: true,\n }\n newProjectFramework = framework\n }\n projectInfo = preflight.projectInfo\n } else {\n projectInfo = await getProjectInfo(cwd)\n }\n\n // Handle monorepo special case\n if (newProjectFramework === \"next-monorepo\") {\n const monorepoWebPath = path.resolve(updatedOptions.cwd, \"apps/web\")\n return await getConfig(monorepoWebPath)\n }\n\n // Get or create configuration\n const projectConfig = await getProjectConfig(updatedOptions.cwd, projectInfo)\n const config = projectConfig\n ? await promptForMinimalConfig(projectConfig)\n : await promptForConfig(await getConfig(updatedOptions.cwd))\n\n // Handle component selection if none specified\n let selectedComponents = components || []\n if (!selectedComponents.length) {\n const shouldAddComponents = await createThemedConfirm(\n \"Would you like to add a template or UI components to your project?\"\n )\n\n if (!shouldAddComponents) {\n logger.info(\"\")\n process.exit(0)\n }\n\n selectedComponents = await promptForRegistryComponents(updatedOptions)\n\n // Exit if still no components selected\n if (!selectedComponents.length) {\n logger.info(\"\")\n process.exit(0)\n }\n }\n\n // Add components\n const fullConfig = await resolveConfigPaths(updatedOptions.cwd, config)\n await addComponents(selectedComponents, fullConfig, {\n // Init will always overwrite files.\n overwrite: true,\n silent,\n isNewProject:\n updatedOptions.isNewProject || projectInfo?.framework.name === \"next-app\",\n })\n\n return fullConfig\n}\n\n/**\n * Prompt for full configuration\n */\nasync function promptForConfig(defaultConfig: Config | null = null) {\n logger.info(\"\")\n\n const tsx = await createThemedConfirm(\n `Would you like to use ${colors.cyan(\"TypeScript\")} (recommended)?`,\n defaultConfig?.tsx ?? true\n )\n\n const rsc = await createThemedConfirm(\n `Are you using ${colors.cyan(\"React Server Components\")}?`,\n defaultConfig?.rsc ?? true\n )\n\n return rawConfigSchema.parse({\n rsc,\n tsx,\n aliases: {\n components: DEFAULT_COMPONENTS,\n contexts: DEFAULT_CONTEXTS,\n hooks: DEFAULT_HOOKS,\n tiptapIcons: DEFAULT_TIPTAP_ICONS,\n lib: DEFAULT_LIB,\n tiptapExtensions: DEFAULT_TIPTAP_EXTENSIONS,\n tiptapNodes: DEFAULT_TIPTAP_NODES,\n tiptapUi: DEFAULT_TIPTAP_UI,\n tiptapUiPrimitives: DEFAULT_TIPTAP_UI_PRIMITIVES,\n styles: DEFAULT_STYLES,\n },\n })\n}\n\n/**\n * Prompt for minimal configuration from existing config\n */\nasync function promptForMinimalConfig(defaultConfig: Config) {\n return rawConfigSchema.parse({\n rsc: defaultConfig?.rsc,\n tsx: defaultConfig?.tsx,\n aliases: defaultConfig?.aliases,\n })\n}\n","import path from \"path\"\nimport { initOptionsSchema } from \"@/src/commands/init\"\nimport * as ERRORS from \"@/src/utils/errors\"\nimport { getProjectInfo } from \"@/src/utils/get-project-info\"\nimport { highlighter } from \"@/src/utils/highlighter\"\nimport { logger } from \"@/src/utils/logger\"\nimport { spinner } from \"@/src/utils/spinner\"\nimport fs from \"fs-extra\"\nimport { z } from \"zod\"\n\nexport async function preFlightInit(\n options: z.infer<typeof initOptionsSchema>\n) {\n const errors: Record<string, boolean> = {}\n\n // Ensure target directory exists.\n // Check for empty project. We assume if no package.json exists, the project is empty.\n if (\n !fs.existsSync(options.cwd) ||\n !fs.existsSync(path.resolve(options.cwd, \"package.json\"))\n ) {\n errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT] = true\n return {\n errors,\n projectInfo: null,\n }\n }\n\n const frameworkSpinner = spinner(`Verifying framework.`, {\n silent: options.silent,\n }).start()\n const projectInfo = await getProjectInfo(options.cwd)\n if (!projectInfo || projectInfo?.framework.name === \"manual\") {\n errors[ERRORS.UNSUPPORTED_FRAMEWORK] = true\n frameworkSpinner?.fail()\n logger.break()\n if (projectInfo?.framework.links.installation) {\n logger.error(\n `We could not detect a supported framework at ${highlighter.info(\n options.cwd\n )}.\\n` +\n `Visit ${highlighter.info(\n projectInfo?.framework.links.installation\n )} to manually configure your project.\\nOnce configured, you can use the cli to add components.`\n )\n }\n logger.break()\n process.exit(0)\n }\n frameworkSpinner?.succeed(\n `Verifying framework. Found ${highlighter.info(\n projectInfo.framework.label\n )}.`\n )\n\n const tsConfigSpinner = spinner(`Validating import alias.`, {\n silent: options.silent,\n }).start()\n if (!projectInfo?.aliasPrefix) {\n errors[ERRORS.IMPORT_ALIAS_MISSING] = true\n tsConfigSpinner?.fail()\n } else {\n tsConfigSpinner?.succeed()\n }\n\n if (Object.keys(errors).length > 0) {\n if (errors[ERRORS.IMPORT_ALIAS_MISSING]) {\n logger.break()\n logger.error(`No import alias found in your tsconfig.json file.`)\n if (projectInfo?.framework.links.installation) {\n logger.error(\n `Visit ${highlighter.info(\n projectInfo?.framework.links.installation\n )} to learn how to set an import alias.`\n )\n }\n }\n\n logger.break()\n process.exit(0)\n }\n\n return {\n errors,\n projectInfo,\n }\n}\n","import os from \"os\"\nimport path from \"path\"\nimport fs from \"fs-extra\"\nimport { execa } from \"execa\"\nimport { z } from \"zod\"\nimport { parse as parseJsonc } from \"jsonc-parser\"\nimport { input } from \"@inquirer/prompts\"\n\nimport { initOptionsSchema } from \"@/src/commands/init\"\nimport select from \"@/src/inquirer/select\"\nimport { colors } from \"@/src/utils/colors\"\nimport { getPackageManager } from \"@/src/utils/get-package-manager\"\nimport { handleError } from \"@/src/utils/handle-error\"\nimport { highlighter } from \"@/src/utils/highlighter\"\nimport { logger } from \"@/src/utils/logger\"\nimport { spinner } from \"@/src/utils/spinner\"\n\nconst MONOREPO_FRAMEWORK_URL =\n \"https://codeload.github.com/shadcn-ui/ui/tar.gz/main\"\n\nexport const FRAMEWORKS = {\n next: \"next\",\n vite: \"vite\",\n \"next-monorepo\": \"next-monorepo\",\n} as const\n\ntype Framework = keyof typeof FRAMEWORKS\ntype ProjectOptions = Pick<\n z.infer<typeof initOptionsSchema>,\n \"cwd\" | \"srcDir\" | \"components\" | \"framework\"\n>\ntype CreateNextOptions = {\n version: string\n cwd: string\n packageManager: string\n srcDir: boolean\n}\ntype CreateViteOptions = {\n cwd: string\n packageManager: string\n projectName: string\n}\ntype CreateMonorepoOptions = {\n packageManager: string\n}\n\n/**\n * Creates a themed input prompt with consistent styling\n */\nconst createThemedInput = (message: string, defaultValue: string = \"\") => {\n return input({\n message: colors.white(message),\n default: defaultValue,\n required: true,\n validate: (value: string) =>\n value.length > 128 ? `Name should be less than 128 characters.` : true,\n theme: {\n prefix: {\n done: colors.cyan(\"✔\"),\n idle: colors.white(\"?\"),\n },\n style: {\n answer: (text: string) => colors.white(text),\n },\n },\n })\n}\n\n/**\n * Creates a themed select prompt with consistent styling\n */\nconst createThemedSelect = async (\n message: string,\n choices: Array<{ name: string; value: string }>\n) => {\n const instructions = `\\n${colors.gray(\" Use arrow-keys ▲▼ / [Return] to submit\")}\\n`\n\n return select({\n message: colors.white(message),\n instructions,\n theme: {\n icon: {\n cursor: colors.cyan(\"❯\"),\n },\n style: {\n highlight: (text: string) => colors.cyan(text),\n answer: (text: string) => colors.white(text),\n },\n prefix: {\n done: colors.cyan(\"✔\"),\n idle: colors.white(\"?\"),\n },\n helpMode: \"always\" as const,\n },\n choices,\n })\n}\n\n/**\n * Creates a new project based on the specified framework\n */\nexport async function createProject(options: ProjectOptions) {\n const normalizedOptions = {\n srcDir: false,\n ...options,\n }\n\n let framework: Framework =\n normalizedOptions.framework &&\n FRAMEWORKS[normalizedOptions.framework as Framework]\n ? (normalizedOptions.framework as Framework)\n : \"next\"\n\n let projectName = \"my-app\"\n const nextVersion = \"latest\"\n\n // Only prompt for framework if not already specified\n if (!normalizedOptions.framework) {\n const frameworkPromptMessage = `The path ${colors.cyan(normalizedOptions.cwd)} does not contain a package.json file.\\n Would you like to start a new project?`\n\n const selectedFramework = await createThemedSelect(frameworkPromptMessage, [\n { name: \"Next.js\", value: \"next\" },\n { name: \"Vite + React + TypeScript\", value: \"vite\" },\n // { name: 'Next.js (Monorepo)', value: 'next-monorepo' }\n ])\n\n framework = selectedFramework as Framework\n }\n\n // Prompt for project name\n projectName = await createThemedInput(\n \"What is your project named?\",\n projectName\n )\n\n // Get the package manager for the project\n const packageManager = await getPackageManager(normalizedOptions.cwd, {\n withFallback: true,\n })\n\n const projectPath = path.join(normalizedOptions.cwd, projectName)\n\n // Validate path is writable\n await validateProjectPath(normalizedOptions.cwd, projectName)\n\n // Create the project based on framework\n if (framework === FRAMEWORKS.next) {\n await createNextProject(projectPath, {\n version: nextVersion,\n cwd: normalizedOptions.cwd,\n packageManager,\n srcDir: !!normalizedOptions.srcDir,\n })\n } else if (framework === FRAMEWORKS.vite) {\n await createViteProject(projectPath, {\n cwd: normalizedOptions.cwd,\n packageManager,\n projectName,\n })\n } else if (framework === FRAMEWORKS[\"next-monorepo\"]) {\n await createMonorepoProject(projectPath, {\n packageManager,\n })\n }\n\n return {\n projectPath,\n projectName,\n framework,\n }\n}\n\n/**\n * Validates that the project path is writable and doesn't already exist\n */\nasync function validateProjectPath(cwd: string, projectName: string) {\n // Check if path is writable\n try {\n await fs.access(cwd, fs.constants.W_OK)\n } catch (error) {\n logger.break()\n logger.error(`The path ${highlighter.info(cwd)} is not writable.`)\n logger.error(\n `It is likely you do not have write permissions for this folder or the path ${highlighter.info(cwd)} does not exist.`\n )\n logger.break()\n process.exit(0)\n }\n\n // Check if project already exists\n if (fs.existsSync(path.resolve(cwd, projectName, \"package.json\"))) {\n logger.break()\n logger.error(\n `A project with the name ${highlighter.info(projectName)} already exists.`\n )\n logger.error(`Please choose a different name and try again.`)\n logger.break()\n process.exit(0)\n }\n}\n\n/**\n * Creates a new Next.js project\n */\nasync function createNextProject(\n projectPath: string,\n options: CreateNextOptions\n) {\n const createSpinner = spinner(\n \"Creating a new Next.js project. This may take a few minutes.\"\n ).start()\n\n // Note: pnpm fails here. Fallback to npx with --use-PACKAGE-MANAGER.\n const args = [\n \"--tailwind\",\n \"--eslint\",\n \"--typescript\",\n \"--app\",\n options.srcDir ? \"--src-dir\" : \"--no-src-dir\",\n \"--no-import-alias\",\n `--use-${options.packageManager}`,\n ]\n\n // Add turbopack for Next.js 15+ or canary/latest\n if (\n options.version.startsWith(\"15\") ||\n options.version.startsWith(\"latest\") ||\n options.version.startsWith(\"canary\")\n ) {\n args.push(\"--turbopack\")\n }\n\n try {\n await execa(\n \"npx\",\n [`create-next-app@${options.version}`, projectPath, \"--silent\", ...args],\n { cwd: options.cwd }\n )\n\n await updateReadmeFile(projectPath)\n\n createSpinner.stopAndPersist({\n symbol: colors.cyan(\"✔\"),\n })\n } catch (error) {\n createSpinner?.fail(\"Something went wrong creating a new Next.js project.\")\n logger.break()\n logger.error(\n `Something went wrong creating a new Next.js project. Please try again.`\n )\n process.exit(0)\n }\n}\n\n/**\n * Creates a new Vite + React + TypeScript project\n */\nasync function createViteProject(\n projectPath: string,\n options: CreateViteOptions\n) {\n const createSpinner = spinner(\n `Creating a new Vite + React + TypeScript project. This may take a few minutes.`\n ).start()\n\n try {\n await execa(\n \"npm\",\n [\n \"create\",\n \"vite@latest\",\n options.projectName,\n \"--\",\n \"--template\",\n \"react-ts\",\n ],\n { cwd: options.cwd }\n )\n\n // Install dependencies\n await execa(options.packageManager, [\"install\"], {\n cwd: projectPath,\n })\n\n await setupViteTsConfig(projectPath)\n\n await updateReadmeFile(projectPath)\n\n createSpinner.stopAndPersist({\n symbol: colors.cyan(\"✔\"),\n })\n } catch (error) {\n createSpinner?.fail(\"Something went wrong creating a new Vite project.\")\n handleError(error)\n }\n}\n\n/**\n * Configures TypeScript and path aliases for a Vite project\n */\nasync function setupViteTsConfig(projectPath: string) {\n try {\n await setupTsConfigPathAliases(projectPath)\n await setupViteConfigPathAliases(projectPath)\n } catch (error) {\n logger.warn(\n \"Failed to set up TypeScript path aliases, but project creation succeeded\"\n )\n }\n}\n\n/**\n * Sets up TypeScript configuration files with path aliases\n */\nasync function setupTsConfigPathAliases(projectPath: string) {\n const addAliasToTsConfig = async (tsconfigFile: string) => {\n const tsconfigPath = path.join(projectPath, tsconfigFile)\n if (!(await fs.pathExists(tsconfigPath))) return\n\n const jsonContent = await fs.readFile(tsconfigPath, \"utf-8\")\n const jsonObj = parseJsonc(jsonContent)\n\n jsonObj.compilerOptions = {\n ...jsonObj.compilerOptions,\n baseUrl: \".\",\n paths: {\n ...(jsonObj.compilerOptions?.paths || {}),\n \"@/*\": [\"./src/*\"],\n },\n }\n\n const updatedJson = JSON.stringify(jsonObj, null, 2)\n await fs.writeFile(tsconfigPath, updatedJson)\n }\n\n await addAliasToTsConfig(\"tsconfig.json\")\n await addAliasToTsConfig(\"tsconfig.app.json\")\n}\n\n/**\n * Sets up Vite configuration with path aliases\n */\nasync function setupViteConfigPathAliases(projectPath: string) {\n const viteConfigPath = path.join(projectPath, \"vite.config.ts\")\n const viteConfigContent = await fs.readFile(viteConfigPath, \"utf-8\")\n\n const updatedViteConfig = viteConfigContent\n .replace(\n \"import { defineConfig } from 'vite'\",\n \"import { defineConfig } from 'vite'\\nimport path from 'path'\"\n )\n .replace(\n \"plugins: [react()]\",\n `plugins: [react()],\n resolve: {\n alias: {\n '@': path.resolve(__dirname, './src')\n }\n }`\n )\n\n await fs.writeFile(viteConfigPath, updatedViteConfig)\n}\n\n/**\n * Creates a new Next.js monorepo project\n */\nasync function createMonorepoProject(\n projectPath: string,\n options: CreateMonorepoOptions\n) {\n const createSpinner = spinner(\n `Creating a new Next.js monorepo. This may take a few minutes.`\n ).start()\n\n try {\n await downloadAndExtractFramework(projectPath)\n\n // Run install\n await execa(options.packageManager, [\"install\"], {\n cwd: projectPath,\n })\n\n // Initialize git repository\n await initializeGitRepository(projectPath)\n\n createSpinner?.succeed(\"Creating a new Next.js monorepo.\")\n } catch (error) {\n createSpinner?.fail(\"Something went wrong creating a new Next.js monorepo.\")\n handleError(error)\n }\n}\n\n/**\n * Downloads and extracts the monorepo framework\n */\nasync function downloadAndExtractFramework(projectPath: string) {\n // Create temporary directory\n const frameworkPath = path.join(os.tmpdir(), `tiptap-framework-${Date.now()}`)\n await fs.ensureDir(frameworkPath)\n\n // Download framework\n const response = await fetch(MONOREPO_FRAMEWORK_URL)\n if (!response.ok) {\n throw new Error(`Failed to download framework: ${response.statusText}`)\n }\n\n // Write the tar file\n const tarPath = path.resolve(frameworkPath, \"framework.tar.gz\")\n await fs.writeFile(tarPath, Buffer.from(await response.arrayBuffer()))\n\n // Extract framework\n await execa(\"tar\", [\n \"-xzf\",\n tarPath,\n \"-C\",\n frameworkPath,\n \"--strip-components=2\",\n \"ui-main/templates/monorepo-next\",\n ])\n\n // Move to project path and cleanup\n const extractedPath = path.resolve(frameworkPath, \"monorepo-next\")\n await fs.move(extractedPath, projectPath)\n await fs.remove(frameworkPath)\n}\n\n/**\n * Initializes a git repository in the project directory\n */\nasync function initializeGitRepository(projectPath: string) {\n const cwd = process.cwd()\n\n try {\n await execa(\"git\", [\"--version\"], { cwd: projectPath })\n await execa(\"git\", [\"init\"], { cwd: projectPath })\n await execa(\"git\", [\"add\", \"-A\"], { cwd: projectPath })\n await execa(\"git\", [\"commit\", \"-m\", \"Initial commit\"], {\n cwd: projectPath,\n })\n await execa(\"cd\", [cwd])\n } catch (error) {\n logger.warn(\n \"Failed to initialize git repository, but project creation succeeded\"\n )\n }\n}\n\nasync function updateReadmeFile(projectPath: string) {\n const readmePath = path.join(projectPath, \"README.md\")\n\n const readmeContent = `# Tiptap Editor Project\n\nThank you for installing the Tiptap Simple Editor template via the Tiptap CLI! This README will help you get started quickly.\n\n## Getting Started\nBefore running the project, make sure to install the required Tiptap packages:\n\n\\`\\`\\`bash\nnpm i @tiptap/react @tiptap/starter-kit @tiptap/extension-image @tiptap/extension-task-item @tiptap/extension-task-list @tiptap/extension-text-align @tiptap/extension-typography\n\\`\\`\\`\n\n### Run the project\nInstall dependencies (if you haven't already):\n\n\\`\\`\\`bash\nnpm install\n\\`\\`\\`\nor use yarn or pnpm.\n\n### Start the development server\n\n\\`\\`\\`bash\nnpm run dev\n\\`\\`\\`\nor yarn or pnpm.\n\n### Include Global Styles\nTo apply the correct styles to the editor, manually import these files into your main CSS/SCSS entry point:\n\n\\`\\`\\`jsx\n@import 'path-to/_variables.scss';\n@import 'path-to/_keyframes-animations.scss';\n\\`\\`\\`\n\nMake sure the path matches your project structure.\n\n\n### Access the template\nOnce the server is running, you can access the Tiptap Simple Editor template by visiting the /simple route in your application.\n\nhttp://localhost:3000/simple\n\n## Documentation\nTo learn more about the Tiptap Simple Editor and how to customize it, visit the official documentation:\n[Tiptap Simple Editor Documentation](https://tiptap.dev/docs/ui-components/templates/simple-editor)\n`\n\n try {\n await fs.writeFile(readmePath, readmeContent, \"utf-8\")\n console.log(`Updated README.md in ${projectPath}`)\n } catch (error) {\n console.error(`Error updating README.md: ${error}`)\n }\n}\n","#!/usr/bin/env node\nimport { add } from \"@/src/commands/add\"\nimport { info } from \"@/src/commands/info\"\nimport { init } from \"@/src/commands/init\"\n// import { login, status } from \"@/src/commands/auth\"\nimport { Command } from \"commander\"\n\nimport packageJson from \"../package.json\"\n\nprocess.on(\"SIGINT\", () => process.exit(0))\nprocess.on(\"SIGTERM\", () => process.exit(0))\n\nasync function main() {\n const program = new Command()\n .name(\"tiptap\")\n .description(\"add components and dependencies to your project\")\n .version(\n packageJson.version || \"1.0.0\",\n \"-v, --version\",\n \"display the version number\"\n )\n\n program.addCommand(init).addCommand(add).addCommand(info)\n // .addCommand(login)\n // .addCommand(status)\n\n program.parse()\n}\n\nmain()\n","{\n \"name\": \"tiptap-cli\",\n \"version\": \"1.1.10\",\n \"description\": \"Tiptap CLI\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"author\": {\n \"name\": \"tiptap\",\n \"url\": \"https://github.com/ueberdosis/tiptap\"\n },\n \"files\": [\n \"dist\"\n ],\n \"keywords\": [\n \"cli\",\n \"components\",\n \"nextjs\",\n \"react\",\n \"templates\",\n \"tiptap\",\n \"tiptap-cli\",\n \"ui\"\n ],\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"bin\": \"./dist/index.js\",\n \"scripts\": {\n \"dev\": \"tsup --watch\",\n \"build\": \"tsup\",\n \"typecheck\": \"tsc --noEmit\",\n \"clean\": \"rm -rf dist\",\n \"start:dev\": \"cross-env REGISTRY_URL=http://localhost:3000 node dist/index.js\",\n \"start:prod\": \"cross-env REGISTRY_URL=https://template.tiptap.dev node dist/index.js\",\n \"start\": \"node dist/index.js\",\n \"pub:beta\": \"pnpm build && pnpm publish --no-git-checks --access public --tag beta\",\n \"pub:release\": \"pnpm build && pnpm publish --access public\"\n },\n \"dependencies\": {\n \"@antfu/ni\": \"^23.3.1\",\n \"@babel/core\": \"^7.26.10\",\n \"@babel/parser\": \"^7.27.0\",\n \"@babel/plugin-transform-typescript\": \"^7.27.0\",\n \"@inquirer/core\": \"^10.1.10\",\n \"@inquirer/figures\": \"^1.0.11\",\n \"@inquirer/prompts\": \"^7.4.1\",\n \"@inquirer/type\": \"^3.0.6\",\n \"ansi-escapes\": \"^7.0.0\",\n \"chalk\": \"^5.4.1\",\n \"commander\": \"^13.1.0\",\n \"cosmiconfig\": \"^9.0.0\",\n \"deepmerge\": \"^4.3.1\",\n \"execa\": \"^9.5.2\",\n \"fast-glob\": \"^3.3.3\",\n \"fs-extra\": \"^11.3.0\",\n \"https-proxy-agent\": \"^7.0.6\",\n \"jsonc-parser\": \"^3.3.1\",\n \"kleur\": \"^4.1.5\",\n \"node-fetch\": \"^3.3.2\",\n \"ora\": \"^8.2.0\",\n \"recast\": \"^0.23.11\",\n \"ts-morph\": \"^25.0.1\",\n \"tsconfig-paths\": \"^4.2.0\",\n \"yaml\": \"^2.7.1\",\n \"yoctocolors-cjs\": \"^2.1.2\",\n \"zod\": \"^3.24.2\"\n },\n \"devDependencies\": {\n \"@babel/plugin-transform-typescript\": \"^7.26.5\",\n \"@types/babel__core\": \"^7.20.5\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/prompts\": \"^2.4.9\",\n \"tsup\": \"^8.4.0\",\n \"type-fest\": \"^4.39.1\"\n }\n}\n"],"mappings":"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","names":["path","Command","z","createPrompt","useState","useKeypress","usePrefix","usePagination","useRef","useMemo","useEffect","isBackspaceKey","isEnterKey","isUpKey","isDownKey","isNumberKey","Separator","ValidationError","makeTheme","colors","figures","ansiEscapes","selectTheme","text","isSelectable","item","normalizeChoices","choices","choice","name","normalizedChoice","select_default","config","done","loop","pageSize","instructions","firstRender","theme","status","setStatus","prefix","searchTimeoutRef","showHelpTip","setShowHelpTip","items","bounds","first","last","defaultItemIndex","active","setActive","selectedChoice","key","rl","offset","next","position","searchTerm","matchIndex","message","helpTipTop","helpTipBottom","page","isActive","index","indexLabel","disabledLabel","color","x","cursor","choiceDescription","checkbox","Separator","path","MISSING_DIR_OR_EMPTY_PROJECT","IMPORT_ALIAS_MISSING","UNSUPPORTED_FRAMEWORK","path","createMatchPath","resolveImport","importPath","config","cosmiconfig","fg","loadConfig","z","path","FRAMEWORKS","path","fs","getPackageInfo","cwd","shouldThrow","packageJsonPath","fg","fs","loadConfig","PROJECT_SHARED_IGNORE","getProjectInfo","cwd","configFiles","isSrcDir","isTsx","aliasPrefix","packageJson","fg","fs","path","isTypeScriptProject","getTsConfigAliasPrefix","getPackageInfo","isUsingAppDir","type","FRAMEWORKS","file","dep","tsConfig","loadConfig","alias","paths","getProjectConfig","defaultProjectInfo","existingConfig","projectInfo","getConfig","config","resolveConfigPaths","DEFAULT_COMPONENTS","DEFAULT_CONTEXTS","DEFAULT_HOOKS","DEFAULT_TIPTAP_ICONS","DEFAULT_LIB","DEFAULT_TIPTAP_EXTENSIONS","DEFAULT_TIPTAP_NODES","DEFAULT_TIPTAP_UI","DEFAULT_TIPTAP_UI_PRIMITIVES","DEFAULT_STYLES","explorer","cosmiconfig","rawConfigSchema","z","configSchema","workspaceConfigSchema","getConfig","cwd","res","config","projectInfo","getProjectInfo","resolveConfigPaths","tsConfig","loadConfig","resolveImport","path","getWorkspaceConfig","resolvedAliases","key","isAliasKey","resolvedPath","packageRoot","findPackageRoot","result","commonRoot","findCommonRoot","relativePath","matchingPackageRoot","fg","pkgPath","pkgDir","parts1","parts2","commonParts","i","cyan","green","red","yellow","highlighter","logger","args","highlighter","fs","preFlightAdd","options","errors","path","MISSING_DIR_OR_EMPTY_PROJECT","config","getConfig","error","logger","highlighter","path","z","handleError","error","logger","key","value","highlighter","z","registryItemTypeSchema","planSchema","registryItemFileSchema","registryItemSchema","registrySchema","registryIndexSchema","registryResolvedItemsTreeSchema","fs","path","os","execa","fetch","HttpsProxyAgent","ora","spinner","text","options","yaml","REGISTRY_URL","AUTH_API_URL","AUTH_TOKEN_KEY","httpAgent","HttpsProxyAgent","getAuthToken","packageManager","cwd","projectToken","checkProjectNpmrc","getNpmAuthToken","checkGlobalNpmrc","projectNpmrcPath","path","fs","content","extractAuthToken","stdout","execa","AUTH_TOKEN_KEY","globalNpmrcPath","os","configString","lines","line","detect","getPackageManager","targetDir","withFallback","packageManager","userAgent","deepmerge","HttpsProxyAgent","fetch","z","REGISTRY_URL","agent","HttpsProxyAgent","getRegistryIndex","config","result","fetchRegistry","registryIndexSchema","error","logger","handleError","fetchFreeRegistry","url","response","fetch","highlighter","paths","authToken","packageManager","getPackageManager","getAuthToken","path","getRegistryUrl","headers","errorMessages","message","registryResolveItemsTree","names","registryItems","resolveRegistryItems","payload","z","registryItemSchema","framework","getProjectInfo","allDependencies","deepmerge","item","allDevDependencies","filteredDevDependencies","filterDevDependenciesByFramework","registryResolvedItemsTreeSchema","resolveRegistryDependencies","visited","resolveDependencies","itemUrl","isUrl","dependency","registryDependencies","name","itemRegistryDependencies","componentName","getRegistryTypeAliasMap","getRegistryParentMap","map","devDependencies","depsArray","stringDeps","dep","hasSass","hasSassEmbedded","filteredDeps","execa","chalk","colors","updateDependencies","dependencies","config","options","dependenciesSpinner","spinner","packageManager","getPackageManager","execa","colors","existsSync","fs","path","basename","fs","tmpdir","path","transformImport","sourceFile","config","importDeclarations","importDeclaration","moduleSpecifier","updateImportAliases","alias","transformFromAstSync","parse","transformTypescript","recast","PARSE_OPTIONS","transformJsx","sourceFile","config","output","ast","code","result","SyntaxKind","directiveRegex","transformRsc","sourceFile","config","first","transformEnvVars","sourceFile","config","getProjectInfo","fileContent","Project","ScriptKind","project","createTempSourceFile","filename","dir","fs","path","tmpdir","transform","opts","transformers","transformImport","transformRsc","transformEnvVars","tempFile","sourceFile","transformer","transformJsx","confirm","chalk","updateFiles","files","config","options","filesCreatedSpinner","spinner","projectInfo","getProjectInfo","filesCreated","filesUpdated","filesSkipped","file","filePath","resolveFilePath","findCommonRoot","f","fileName","basename","targetDir","path","match","existingFile","existsSync","content","transform","transformImport","transformRsc","transformEnvVars","existingFileContent","fs","normalizedExisting","normalizedNew","getNormalizedFileContent","highlighter","text","logger","resolveFileTargetDirectory","override","paths","needle","normalizedPaths","p","normalizedNeedle","needleDir","needleSegments","i","testPath","resolvePageTarget","target","framework","result","resolveNestedFilePath","normalizedFilePath","normalizedTargetDir","fileSegments","targetSegments","lastTargetSegment","commonDirIndex","segment","templateName","relativePath","finalPath","templateMatch","dataPath","z","execa","updateDevDependencies","devDependencies","config","options","devDependenciesSpinner","spinner","packageManager","getPackageManager","execa","colors","addComponents","components","config","options","workspaceConfig","getWorkspaceConfig","addWorkspaceComponents","addProjectComponents","registrySpinner","spinner","tree","registryResolveItemsTree","colors","updateDependencies","updateDevDependencies","updateFiles","handleError","registryItems","resolveRegistryItems","result","fetchRegistry","payload","z","registryItemSchema","registryParentMap","getRegistryParentMap","registryTypeAliasMap","getRegistryTypeAliasMap","filesCreated","filesUpdated","filesSkipped","rootSpinner","component","alias","registryParent","targetConfig","workspaceRoot","findCommonRoot","packageRoot","findPackageRoot","files","file","path","logger","toReadableName","input","word","addOptionsSchema","z","PLANS","PROMPT_PAGE_SIZE","UI","colors","PROMPT_THEME","text","CHECKBOX_THEME","filterFreeTemplates","templates","freeComponents","template","createInstruction","clearPromptLines","lines","i","categorizeRegistryItems","registryIndex","entry","promptForInitialSelection","categories","message","instructions","choices","isComponentEmpty","logger","selection","select_default","createComponentChoices","addCategorySection","items","title","freeItems","item","Separator","planLabel","toReadableName","componentMenu","selectedComponents","checkbox","templateMenu","description","promptForRegistryComponents","options","getRegistryIndex","handleError","visibleRegistryItems","fetchFreeRegistry","filteredTemplates","templateResult","add","Command","components","opts","path","errors","config","preFlightAdd","MISSING_DIR_OR_EMPTY_PROJECT","highlighter","addComponents","error","Command","info","opts","logger","getProjectInfo","getConfig","path","Command","confirm","z","path","fs","preFlightInit","options","errors","path","MISSING_DIR_OR_EMPTY_PROJECT","frameworkSpinner","spinner","projectInfo","getProjectInfo","UNSUPPORTED_FRAMEWORK","logger","highlighter","tsConfigSpinner","IMPORT_ALIAS_MISSING","os","path","fs","execa","parseJsonc","input","MONOREPO_FRAMEWORK_URL","FRAMEWORKS","createThemedInput","message","defaultValue","input","colors","value","text","createThemedSelect","choices","instructions","select_default","createProject","options","normalizedOptions","framework","projectName","nextVersion","frameworkPromptMessage","packageManager","getPackageManager","projectPath","path","validateProjectPath","createNextProject","createViteProject","createMonorepoProject","cwd","fs","logger","highlighter","createSpinner","spinner","args","execa","updateReadmeFile","setupViteTsConfig","error","handleError","setupTsConfigPathAliases","setupViteConfigPathAliases","addAliasToTsConfig","tsconfigFile","tsconfigPath","jsonContent","jsonObj","parseJsonc","updatedJson","viteConfigPath","updatedViteConfig","downloadAndExtractFramework","initializeGitRepository","frameworkPath","os","response","tarPath","extractedPath","readmePath","readmeContent","initOptionsSchema","z","val","FRAMEWORKS","createThemedConfirm","message","defaultValue","confirm","colors","text","init","Command","components","opts","options","path","runInit","logger","highlighter","error","handleError","cwd","skipPreflight","silent","projectInfo","newProjectFramework","updatedOptions","getProjectInfo","preflight","preFlightInit","MISSING_DIR_OR_EMPTY_PROJECT","projectPath","framework","createProject","monorepoWebPath","getConfig","projectConfig","getProjectConfig","config","promptForMinimalConfig","promptForConfig","selectedComponents","promptForRegistryComponents","fullConfig","resolveConfigPaths","addComponents","defaultConfig","tsx","rsc","rawConfigSchema","DEFAULT_COMPONENTS","DEFAULT_CONTEXTS","DEFAULT_HOOKS","DEFAULT_TIPTAP_ICONS","DEFAULT_LIB","DEFAULT_TIPTAP_EXTENSIONS","DEFAULT_TIPTAP_NODES","DEFAULT_TIPTAP_UI","DEFAULT_TIPTAP_UI_PRIMITIVES","DEFAULT_STYLES","Command","package_default","main","program","Command","package_default","init","add","info"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tiptap/cli",
|
|
3
|
+
"version": "1.1.10",
|
|
4
|
+
"description": "Tiptap CLI",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "tiptap",
|
|
10
|
+
"url": "https://github.com/ueberdosis/tiptap"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"cli",
|
|
17
|
+
"components",
|
|
18
|
+
"nextjs",
|
|
19
|
+
"react",
|
|
20
|
+
"templates",
|
|
21
|
+
"tiptap",
|
|
22
|
+
"tiptap-cli",
|
|
23
|
+
"ui"
|
|
24
|
+
],
|
|
25
|
+
"type": "module",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"default": "./dist/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"bin": "./dist/index.js",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@antfu/ni": "^23.3.1",
|
|
35
|
+
"@babel/core": "^7.26.10",
|
|
36
|
+
"@babel/parser": "^7.27.0",
|
|
37
|
+
"@babel/plugin-transform-typescript": "^7.27.0",
|
|
38
|
+
"@inquirer/core": "^10.1.10",
|
|
39
|
+
"@inquirer/figures": "^1.0.11",
|
|
40
|
+
"@inquirer/prompts": "^7.4.1",
|
|
41
|
+
"@inquirer/type": "^3.0.6",
|
|
42
|
+
"ansi-escapes": "^7.0.0",
|
|
43
|
+
"chalk": "^5.4.1",
|
|
44
|
+
"commander": "^13.1.0",
|
|
45
|
+
"cosmiconfig": "^9.0.0",
|
|
46
|
+
"deepmerge": "^4.3.1",
|
|
47
|
+
"execa": "^9.5.2",
|
|
48
|
+
"fast-glob": "^3.3.3",
|
|
49
|
+
"fs-extra": "^11.3.0",
|
|
50
|
+
"https-proxy-agent": "^7.0.6",
|
|
51
|
+
"jsonc-parser": "^3.3.1",
|
|
52
|
+
"kleur": "^4.1.5",
|
|
53
|
+
"node-fetch": "^3.3.2",
|
|
54
|
+
"ora": "^8.2.0",
|
|
55
|
+
"recast": "^0.23.11",
|
|
56
|
+
"ts-morph": "^25.0.1",
|
|
57
|
+
"tsconfig-paths": "^4.2.0",
|
|
58
|
+
"yaml": "^2.7.1",
|
|
59
|
+
"yoctocolors-cjs": "^2.1.2",
|
|
60
|
+
"zod": "^3.24.2"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@babel/plugin-transform-typescript": "^7.26.5",
|
|
64
|
+
"@types/babel__core": "^7.20.5",
|
|
65
|
+
"@types/fs-extra": "^11.0.4",
|
|
66
|
+
"@types/prompts": "^2.4.9",
|
|
67
|
+
"tsup": "^8.4.0",
|
|
68
|
+
"type-fest": "^4.39.1"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"dev": "tsup --watch",
|
|
72
|
+
"build": "tsup",
|
|
73
|
+
"typecheck": "tsc --noEmit",
|
|
74
|
+
"clean": "rm -rf dist",
|
|
75
|
+
"start:dev": "cross-env REGISTRY_URL=http://localhost:3000 node dist/index.js",
|
|
76
|
+
"start:prod": "cross-env REGISTRY_URL=https://template.tiptap.dev node dist/index.js",
|
|
77
|
+
"start": "node dist/index.js",
|
|
78
|
+
"pub:beta": "pnpm build && pnpm publish --no-git-checks --access public --tag beta",
|
|
79
|
+
"pub:release": "pnpm build && pnpm publish --access public"
|
|
80
|
+
}
|
|
81
|
+
}
|