croct 0.16.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +2 -2
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -740,7 +740,7 @@ ${h}`+Qi`
740
740
  `:""),this}appendString(e,r){return this.append(r+e.replace(new RegExp(r,"g"),`\\${r}`)+r)}appendIndentation(){return this.write("",false)}appendName(e,r=true){return this.code+=t.formatName(e,r),this}writeValue(e,r){return this.appendIndentation().appendValue(e,r)}append(e){return this.code+=this.indentCode(e,false),this}appendValue(e,r){let{delimiter:n,stringKeys:i=false}=r;switch(typeof e){case "string":{let s=e.replace(new RegExp(n,"g"),`\\${n}`);return this.append(`${n}${s}${n}`)}case "number":case "boolean":return this.append(`${e}`);case "object":{if(e===null)return this.append("null");if(Array.isArray(e)){if(e.length===0)return this.append("[]");this.append("[").newLine().indent();for(let o=0;o<e.length;o++)this.appendIndentation().appendValue(e[o],r),o<e.length-1&&this.append(", ").newLine();return this.outdent().newLine().write("]",false)}let s=Object.entries(e);if(s.length===0)return this.append("{}");this.append("{").newLine().indent();for(let o=0;o<s.length;o++){let[a,l]=s[o];this.appendIndentation(),i||!(0, Hz.isIdentifier)(a)?this.appendValue(a,r):this.append(a),this.append(": ").appendValue(l,r),o<s.length-1&&this.append(", ").newLine();}return this.outdent().newLine().write("}",false)}default:return this.append("undefined")}}indentCode(e,r=true){let n=" ".repeat(this.indentationLevel*this.indentationSize);return (r?n:"")+e.replace(/\n/g,`
741
741
  ${n}`)}toString(){return this.code}static formatName(e,r=true){let n=e.replace(/[^a-z0-9]/gi,"_");return e.includes("_")?r?n[0].toUpperCase()+n.slice(1):n:n.replace(/(^[a-z_])|_([a-z])/gi,(i,s,o,a)=>r||a>0?(s??o).toUpperCase():(s??o).toLowerCase())}};function _o(t){let e=t.split(/(?<![A-Z])(?=[A-Z])|_/),r=e[0];return [r[0].toUpperCase()+r.slice(1).toLowerCase(),...e.slice(1).map(s=>s.toLowerCase())].join(" ")}function Lr(t){return t.normalize("NFD").toLocaleLowerCase().replace(/(^[^a-z]+|[^a-z0-9_ &-]+)/ig,"").split(/[^a-z0-9]+/i).filter(e=>e!=="").join("-")}function qs(t){return Object.entries(t).sort(([,e],[,r])=>{let n=e.position??Number.MAX_SAFE_INTEGER,i=r.position??Number.MAX_SAFE_INTEGER;return n-i})}var _v=class t{constructor({fileSystem:e,...r}){this.options=r,this.fileSystem=e;}generate(e){let r=this.generateSlotFile(e);return {files:[this.generatePageFile(e,r.path),r]}}generatePageFile(e,r){let n=this.createWriter();return this.writePageSnippet(n,e.definition.title??"Croct example",this.fileSystem.getRelativePath(this.fileSystem.getDirectoryName(this.options.pagePath),r).replace(/\\/g,"/")),{path:this.options.pagePath,language:"html",code:n.toString()}}writePageSnippet(e,r,n){e.write('<html lang="en">').write("<head>").indent().write('<meta charset="UTF-8">').write(`<title>${t.escapeEntities(r)}</title>`).write(`<script type="module" src="${n}"></script>`).outdent().write("</head>").write("<body>").indent().write(`<div id="${this.options.containerId}"></div>`).outdent().write("</body>").write("</html>",false);}generateSlotFile(e){let r=this.createWriter();return this.writeSlotSnippet(r,e),{path:this.options.slotPath,language:this.options.language,code:r.toString()}}writeSlotSnippet(e,r){e.write("import croct from '@croct/plug';"),e.newLine().write(`croct.plug({appId: '${this.options.appId}'});`).newLine(),this.renderListener(e,r);}renderListener(e,r){e.write("document.addEventListener('DOMContentLoaded', async () => {").indent(),e.write("const {content} = ",false).append(`await croct.fetch('${r.id}@${r.version}'`),this.options.fallbackContent!==void 0&&e.append(", {").indent().newLine().write("fallback: ",false).appendValue(this.options.fallbackContent,{delimiter:"'"}).newLine().outdent().write("}",false),e.append(");"),e.newLine(2).write(`document.querySelector('#${this.options.containerId}')`,false),this.options.language==="typescript"&&e.append("!"),e.append(".innerHTML = `").newLine().indent(),this.writeContentSnippet(e,r.definition,"content"),e.outdent().write("`;").outdent().write("});");}writeContentSnippet(e,r,n){switch(r.type){case "text":case "number":e.append(`\${${n}}`);break;case "boolean":r.label!==void 0?e.append(`\${${n} ? `).appendValue(r.label.true??"Yes",{delimiter:"'"}).append(" : ").appendValue(r.label.false??"No",{delimiter:"'"}).append("}"):e.append(`\${${n} ? 'Yes' : 'No'}`);break;case "list":{let i=r.itemLabel!==void 0?Pi(r.itemLabel):"item";e.write("<ol>").indent().write(`\${${n}.map(${i} => \``).indent().write("<li>").indent();let s=t.isInline(r.items);s&&e.appendIndentation(),this.writeContentSnippet(e,r.items,i),s&&e.newLine(),e.outdent().write("</li>").outdent().write("`).join('')}").outdent().write("</ol>");break}case "structure":e.write("<ul>").indent();for(let[i,s]of qs(r.attributes))s.private!==true&&(s.optional===true&&(e.write(`\${${n}.${i} && \``),e.indent()),this.writeAttributeSnippet(e,s,`${n}.${i}`),s.optional===true&&(e.outdent(),e.write("`}")));e.outdent().write("</ul>");break;case "union":for(let[i,s]of Object.entries(r.types))e.write(`\${${n}._type === '${i}' && \``).indent(),this.writeContentSnippet(e,s,n),e.outdent().write("`}");break}}writeAttributeSnippet(e,r,n){let i=r.type,s=r.label!==void 0?t.escapeEntities(r.label).replace(/`/g,"\\`"):_o(n.split(".").pop());switch(i.type){case "boolean":case "text":case "number":{e.write("<li>",false).append(`<strong>${s}:</strong> `),this.writeContentSnippet(e,i,n),e.append("</li>").newLine();break}default:e.write("<li>").indent().write(`<strong>${s}</strong>`),this.writeContentSnippet(e,i,n),e.outdent().write("</li>");break}}static isInline(e){return ["number","text","boolean"].includes(e.type)}static escapeEntities(e){return e.replace(/([&<>])/g,r=>({"&":"&amp;","<":"&lt;",">":"&gt;"})[r]??r)}createWriter(){return new jn(this.options.indentationSize)}};var kv=class t extends Us{constructor({bundlers:e,...r}){super(r),this.bundlers=e;}async createExample(e,r){let{examples:n}=await this.getPaths(r.configuration);return new wi(e.name,t.resolveExampleUrl(n,e.slug))}async generateSlotExampleFiles(e,r){let{configuration:n}=r,[i,s,o]=await Promise.all([this.isTypeScriptProject(),this.detectBundler(),this.workspaceApi.getApplication({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:n.applications.development})]);if(o===null)throw new Mr(`Development application ${n.applications.development} not found.`,{reason:"not_found"});let a=await this.getPaths(n),l=this.fileSystem.joinPaths(a.examples,e.slug),c=new _v({fileSystem:this.fileSystem,language:i?"typescript":"javascript",appId:o.publicId,fallbackContent:s===null?t.extractFallbackContent(e.content[r.configuration.defaultLocale],e.resolvedDefinition):void 0,containerId:"slot",slotPath:this.fileSystem.joinPaths(l,`slot.${i?"ts":"js"}`),pagePath:this.fileSystem.joinPaths(l,"index.html")}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition});return Promise.resolve(c.files)}static extractFallbackContent(e,r){switch(e.type){case "text":case "boolean":case "number":return e.value.type==="static"?e.value.value:e.value.default!==void 0?e.value.default:null;case "list":return e.items.map(n=>t.extractFallbackContent(n,r.items));case "structure":{let n=r,i={};for(let[s,o]of qs(n.attributes)){if(o.private===true)continue;let a=t.extractFallbackContent(e.attributes[s],n.attributes[s].type);(o.optional!==true||a!==null)&&(i[s]=a);}return i}}}async detectBundler(){for(let e of this.bundlers)if(await this.packageManager.hasDirectDependency(e))return Promise.resolve(e);return Promise.resolve(null)}getInstallationPlan(e){return Promise.resolve({tasks:[],dependencies:["@croct/plug"],configuration:e.configuration})}static resolveExampleUrl(e,r){return `/${e}/${r}/index.html`}};var Ai=class t{constructor(e,r){this.fileSystem=e,this.path=r;}getName(){return this.fileSystem.getBaseName(this.path)}exists(){return this.fileSystem.exists(this.path)}async hasVariable(e){let r=await this.read();if(r==="")return false;let n=t.escapeRegex(e);return new RegExp(`^${n}\\s*=`,"m").test(r)}async setVariables(e){let r=await this.read();try{for(let[n,i]of Object.entries(e))await this.setVariable(n,i);}catch(n){throw await this.write(r),n}}async setVariable(e,r){let n=await this.read(),i=t.escapeRegex(e);if(n==="")return this.write(`${e}=${r}`);let s=`${e}=${r}`,o=n.replace(new RegExp(`${i}\\s*=\\s*((?!['"\`]).*$|\`(?:\\.|[^\`])*\`|'(?:\\.|[^'])*'|"(?:\\.|[^"])*")`,"m"),s);return o!==n||o.includes(s)?this.write(o):this.write(`${n}${n.endsWith(`
742
742
  `)?"":`
743
- `}${e}=${r}`)}async write(e){await this.fileSystem.writeTextFile(this.path,e,{overwrite:true});}async read(){return await this.exists()?this.fileSystem.readTextFile(this.path):""}static escapeRegex(e){return e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&")}};var Ju=class t{constructor({fileSystem:e,...r}){this.options=r,this.fileSystem=e;}generate(e){let r=t.replaceVariables(this.options.slotFilePath,e.id),n=t.replaceVariables(this.options.slotComponentName,e.id);return {files:[this.generatePageFile(e,{name:n,path:r,importPath:t.replaceVariables(this.options.slotImportPath,e.id),definition:e}),this.generateSlotFile(e,r,n)]}}generatePageFile(e,r){let n=this.createWriter(),i=t.replaceVariables(this.options.pageFilePath,e.id),s=t.replaceVariables(this.options.pageComponentName,e.id);return this.writePageSnippet(n,s,r),{path:i,language:this.options.language,code:n.toString()}}generateSlotFile(e,r,n){let i=this.createWriter();return this.writeSlotSnippet(i,e,n),{path:r,language:this.options.language,code:i.toString()}}writePageSnippet(e,r,n){this.writePageHeader(e,n),e.newLine(),this.writePageSignature(e,r),e.indent().write("return (").indent(),this.hasSuspenseBoundary()&&e.write('<Suspense fallback="\u2728 Personalizing...">').indent(),this.writeSlotRendering(e,n.name),this.hasSuspenseBoundary()&&e.outdent().write("</Suspense>"),e.outdent().write(");").outdent().write("}",false);}writeSlotRendering(e,r){e.write(`<${r} />`);}writePageSignature(e,r){e.write(this.options.language==="tsx"?`export default function ${r}(): ReactElement {`:`export default function ${r}() {`);}writePageHeader(e,r){switch(this.options.language){case "jsx":this.hasSuspenseBoundary()&&e.write("import {Suspense} from 'react';");break;case "tsx":e.write(this.hasSuspenseBoundary()?"import {type ReactElement, Suspense} from 'react';":"import type {ReactElement} from 'react';");break}e.write(`import ${r.name} from '${r.importPath}';`);}writeSlotSnippet(e,r,n){this.writeSlotHeader(e,r),this.writeSlotSignature(e,r,n),e.indent(),this.writeSlotFetch(e,r),e.write("return (").indent(),t.renderComponentSnippet(e,r.definition,this.options.contentVariable),e.outdent().write(");").outdent().write("};");}writeSlotSignature(e,r,n){e.write(`export default ${this.isSlotFetchAsync()?"async ":""}function ${n}`,false),this.appendSlotParams(e,r),this.options.language==="tsx"&&e.append(`: ${this.isSlotFetchBlocking()?"Promise<ReactElement>":"ReactElement"}`),e.write(" {");}appendSlotParams(e,r){e.append("()");}static renderComponentSnippet(e,r,n){switch(r.type){case "number":case "text":e.append(`{${n}}`);break;case "boolean":r.label!==void 0?e.append(`{${n} ? `).appendValue(r.label.true??"Yes",{delimiter:"'"}).append(" : ").appendValue(r.label.false??"No",{delimiter:"'"}).append("}"):e.append(`{${n} ? 'Yes' : 'No'}`);break;case "list":{let i=r.itemLabel!==void 0?Pi(r.itemLabel):"item";e.write("<ol>").indent().write(`{${n}.map((${i}, index) => (`).indent().write("<li key={index}>").indent();let s=t.isInline(r.items);s&&e.appendIndentation(),t.renderComponentSnippet(e,r.items,i),s&&e.newLine(),e.outdent().write("</li>").outdent().write("))}").outdent().write("</ol>");break}case "structure":e.write("<ul>").indent();for(let[i,s]of qs(r.attributes))s.private!==true&&(s.optional===true&&(e.write(`{${n}.${i} && (`),e.indent()),t.writeAttributeSnippet(e,{name:i,...s},n),s.optional===true&&(e.outdent(),e.write(")}")));e.outdent().write("</ul>");break;case "union":{let i=!n.includes(".");i&&e.write("<>").indent();for(let[s,o]of Object.entries(r.types))e.write(`{${n}._type === '${s}' && (`).indent(),t.renderComponentSnippet(e,o,n),e.outdent().write(")}");i&&e.outdent().write("</>");break}}}static writeAttributeSnippet(e,r,n){let i=r.type,s=t.escapeEntities(r.label??_o(r.name));switch(i.type){case "boolean":case "text":case "number":{e.write("<li>",false).append(`<strong>${s}:</strong> `),t.renderComponentSnippet(e,i,`${n}.${r.name}`),e.append("</li>").newLine();break}default:e.write("<li>").indent().write(`<strong>${s}</strong>`),t.renderComponentSnippet(e,i,`${n}.${r.name}`),e.outdent().write("</li>");break}}static escapeEntities(e){return e.replace(/([&"<>])/g,r=>({"&":"&amp;",'"':"&quot;","<":"&lt;",">":"&gt;"})[r]??r)}createWriter(){return new jn(this.options.indentationSize)}static replaceVariables(e,r){return e.replace(/%name%/g,t.formatName(r,true)).replace(/%slug%/g,Lr(r))}static formatName(e,r=false){return jn.formatName(e,r)}static isInline(e){return ["number","text","boolean"].includes(e.type)}};var cf=class extends Ju{writeSlotHeader(e){switch(this.options.language){case "jsx":e.write("import {useContent} from '@croct/plug-react';");break;case "tsx":e.write("import type {ReactElement} from 'react';"),e.write("import {useContent} from '@croct/plug-react';");break}e.newLine();}writeSlotFetch(e,r){let n=this.options.contentVariable,i=n!=="content"?`content: ${n}`:n;e.write(`const ${i} = useContent('${r.id}@${r.version}');`).newLine();}isSlotFetchAsync(){return false}isSlotFetchBlocking(){return false}hasSuspenseBoundary(){return false}};var Nv=class t extends Us{constructor(e){super(e),this.codemod=e.codemod,this.bundlers=e.bundlers,this.importResolver=e.importResolver;}async generateSlotExampleFiles(e,r){let n=await this.isTypeScriptProject(),i=await this.getPaths(r.configuration),s=this.fileSystem.joinPaths(i.components,`%slug%${n?".tsx":".jsx"}`),o=this.fileSystem.joinPaths(i.examples,`%slug%-example${n?".tsx":".jsx"}`);return new cf({fileSystem:this.fileSystem,language:await this.isTypeScriptProject()?"tsx":"jsx",contentVariable:"content",slotImportPath:await this.importResolver.getImportPath(s,o),slotFilePath:s,slotComponentName:"%name%",pageFilePath:o,pageComponentName:"%name%Example"}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async getInstallationPlan(e){let{configuration:r}=e,n=await this.getProjectInfo();return {dependencies:["@croct/plug-react"],tasks:this.getInstallationTasks({...e,project:n}),configuration:r}}async getProjectInfo(){let r=await this.getEnvVarProperty(),n=this.projectDirectory.get();return {typescript:await this.isTypeScriptProject(),sourceDirectory:"src",provider:{file:await this.locateFile(...["App","main","index"].flatMap(i=>["js","jsx","ts","tsx"].map(s=>`${i}.${s}`)).map(i=>this.fileSystem.joinPaths("src",i)))},env:r===null?void 0:{property:r,productionFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(n,".env.production")),developmentFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(n,".env.development"))}}}getInstallationTasks(e){let r=[],n=e.project.env,{configuration:i}=e,s=null,o=()=>(s===null&&(s=Promise.all([this.workspaceApi.getApplication({organizationSlug:i.organization,workspaceSlug:i.workspace,applicationSlug:i.applications.development}),i.applications.production===void 0?null:this.workspaceApi.getApplication({organizationSlug:i.organization,workspaceSlug:i.workspace,applicationSlug:i.applications.production})]).then(([a,l])=>a===null?Promise.reject(new Mr(`Development application ${i.applications.development} not found`,{reason:"not_found"})):{development:a.publicId,production:l?.publicId})),s);if(n!==void 0){let{developmentFile:a,productionFile:l,property:u}=n,c=u.split(".").pop();r.push({title:"Setup environment variables",task:async p=>{p.update("Setting up environment variables");try{let d=await o();await Promise.all([a.setVariable(c,d.development),d.production===void 0?Promise.resolve():l.setVariable(c,d.production)]),p.confirm("Environment variables updated");}catch(d){p.alert("Failed to update environment variables",V.formatMessage(d));}}});}return r.push({title:"Configure provider",task:async a=>{a.update("Configuring provider");let l=e.project.provider.file,u="Wrap your app's root component with <CroctProvider> from @croct/plug-react.";try{l===null?a.alert("No root component found",u):(await this.installProvider(l,{props:{appId:t.getAppIdProperty(await o(),n?.property)}}),a.confirm("Provider configured"));}catch{a.alert("Failed to install provider",u);}}}),r}async installProvider(e,r){await this.codemod.provider.apply(this.fileSystem.joinPaths(this.projectDirectory.get(),e),r);}async getEnvVarProperty(){for(let e of this.bundlers)if(await this.packageManager.hasDirectDependency(e.package))return `${e.prefix}CROCT_APP_ID`;return null}static getAppIdProperty(e,r){return r!==void 0?{type:"reference",path:r.split(".")}:e.production===void 0?{type:"literal",value:e.development}:{type:"ternary",condition:{operator:"===",left:{type:"reference",path:["process","env","NODE_ENV"]},right:{type:"literal",value:"production"}},consequent:{type:"literal",value:e.production},alternate:{type:"literal",value:e.development}}}};var ho=me(we()),gee=me(Jt());var yee=me(gp());var cr=class t extends V{constructor(e,r={}){super(e,r),Object.setPrototypeOf(this,t.prototype);}},HT=class t extends cr{constructor(e){super(e),Object.setPrototypeOf(this,t.prototype);}};function Ho(t,e,r){try{return (0,yee.parse)(t,{...r,sourceType:"module",plugins:[...e,...r?.plugins??[]]})}catch{throw new HT("The source code contains syntax errors.")}}function bee(t){let e={locales:Array()},r;try{r=Ho(t,["jsx","typescript"]);}catch{return {i18n:e}}return (0, gee.traverse)(r,{ObjectProperty:n=>{if(qj(n.node.key)!=="i18n")return n.skip();let i=n.node.value;if(!ho.isObjectExpression(i))return n.stop();for(let s of i.properties)if(ho.isObjectProperty(s)&&qj(s.key)==="locales"){let o=s.value;if(ho.isArrayExpression(o))for(let a of o.elements)a!==null&&ho.isStringLiteral(a)&&e.locales.push(a.value);}else if(ho.isObjectProperty(s)&&qj(s.key)==="defaultLocale"){let o=s.value;o!==null&&ho.isStringLiteral(o)&&(e.defaultLocale=o.value);}return n.stop()}}),{i18n:e}}function qj(t){return ho.isIdentifier(t)?t.name:ho.isStringLiteral(t)?t.value:null}var KT=class extends Ju{constructor({fileSystem:e,router:r,...n}){super({fileSystem:e,contentVariable:r==="app"?"content":"props",...n}),this.nextOptions={router:r};}writeSlotHeader(e,r){switch(this.options.language){case "jsx":this.nextOptions.router==="app"&&(e.write("import {fetchContent} from '@croct/plug-next/server';"),e.newLine());break;case "tsx":if(e.write("import type {ReactElement} from 'react';"),this.nextOptions.router==="app"&&e.write("import {fetchContent} from '@croct/plug-next/server';"),this.nextOptions.router==="page"){e.write("import type {SlotContent} from '@croct/plug-next';"),e.newLine();let n=jn.formatName(r.id,true);e.write(`export type ${n}Props = SlotContent<'${r.id}@${r.version}'>;`);}e.newLine();break}}writeSlotFetch(e,r){if(this.nextOptions.router==="app"){let n=this.options.contentVariable;e.write(`const {${n}} = await fetchContent('${r.id}@${r.version}');`).newLine();}}writePageHeader(e,r){if(this.nextOptions.router==="app")return super.writePageHeader(e,r);let n=`${r.definition.id}@${r.definition.version}`;switch(this.options.language){case "jsx":e.write("import {fetchContent} from '@croct/plug-next/server';").write(`import ${r.name} from '${r.importPath}';`),e.newLine().write("export async function getServerSideProps(context) {").indent().write("return {").indent().write(`props: await fetchContent('${n}', {`).indent().write("route: context,").outdent().write("}),").outdent().write("}").outdent().write("}");break;case "tsx":e.write("import type {ReactElement} from 'react';"),e.write("import type {GetServerSideProps} from 'next';"),e.write("import {fetchContent} from '@croct/plug-next/server';"),e.write(`import ${r.name}, {type ${r.name}Props} from '${r.importPath}';`),e.newLine().write("type PageProps = {").indent().write(`content: ${r.name}Props,`).outdent().write("};").newLine().write("export const getServerSideProps: ",false).write("GetServerSideProps<PageProps> = async context => ({").indent().write(`props: await fetchContent('${n}', {`).indent().write("route: context,").outdent().write("}),").outdent().write("});");break}}writePageSignature(e,r){switch(this.nextOptions.router){case "app":super.writePageSignature(e,r);break;case "page":{e.write(this.options.language==="tsx"?"export default function Page({content}: PageProps): ReactElement {":"export default function Page({content}) {");break}}}appendSlotParams(e,r){if(this.nextOptions.router!=="page")return super.appendSlotParams(e,r);let n=jn.formatName(r.id,true),i=this.options.contentVariable;if(this.options.language==="jsx"){e.append(`(${i})`);return}e.append(`(${i}: ${n}Props)`);}writeSlotRendering(e,r){switch(this.nextOptions.router){case "app":super.writeSlotRendering(e,r);break;case "page":{e.write(`<${r} {...content} />`);break}}}isSlotFetchAsync(){return this.nextOptions.router==="app"}isSlotFetchBlocking(){return this.nextOptions.router==="app"}hasSuspenseBoundary(){return false}};var zn=class t extends V{constructor(e,r=[],n={}){super(e,{...n,details:n.details??r.map(i=>i.detail??i.title)}),Object.setPrototypeOf(this,t.prototype),this.problems=r;}isErrorType(e){return this.problems.some(r=>r.type===e)}isAccessDenied(e){return this.problems.some(r=>r.type==="https://croct.help/api/admin#access-denied"&&(e===void 0||r.reason===e))}};var Ko=(r=>(r.DEVELOPMENT="DEVELOPMENT",r.PRODUCTION="PRODUCTION",r))(Ko||{});(n=>{function t(i){switch(i){case "DEVELOPMENT":return "Development";case "PRODUCTION":return "Production"}}n.getLabel=t;function e(){return Object.values(n).filter(i=>typeof i=="string")}n.all=e;function r(i){let s=i.toUpperCase();if(!n.all().includes(s))throw new Error(`Invalid environment value "${i}".`);return s}n.fromValue=r;})(Ko||={});var Vi=(n=>(n.READ_RESOURCES="RESOURCE_READ_ACCESS",n.ISSUE_TOKEN="TOKEN_ISSUE",n.EXPORT_DATA="DATA_EXPORT",n))(Vi||{});(n=>{function t(i){switch(i){case "RESOURCE_READ_ACCESS":return "Read resources";case "TOKEN_ISSUE":return "Issue tokens";case "DATA_EXPORT":return "Export data"}}n.getLabel=t;function e(){return Object.values(n).filter(i=>typeof i=="string")}n.all=e;function r(i){let s=i.toUpperCase();if(!n.all().includes(s))throw new Error(`Invalid permission value "${i}".`);return s}n.fromValue=r;})(Vi||={});var JT=class t extends Us{constructor(e){super(e),this.codemod=e.codemod,this.importResolver=e.importResolver,this.userApi=e.userApi,this.applicationApi=e.applicationApi;}async createExample(e,r){return await this.isFallbackMode()?super.createExample(e,r):new wi(e.name,`/${e.slug}`)}async generateSlotExampleFiles(e,r){let[n,i,s]=await Promise.all([this.detectRouter(),this.isTypeScriptProject(),this.isFallbackMode()]),o=await this.getPaths(r.configuration),a=i?".tsx":".jsx",l=this.fileSystem.joinPaths(o.components,`%slug%${a}`),u=s||n==="page"?"index":"page",c=this.fileSystem.joinPaths(o.examples,"%slug%",`${u}${a}`),p=await this.importResolver.getImportPath(l,c),d=i?"tsx":"jsx";return (s?new cf({fileSystem:this.fileSystem,language:d,contentVariable:"content",slotImportPath:p,slotFilePath:l,slotComponentName:"%name%",pageFilePath:c,pageComponentName:"Page"}):new KT({fileSystem:this.fileSystem,router:n==="page"?"page":"app",language:d,slotImportPath:p,slotFilePath:l,slotComponentName:"%name%",pageFilePath:c,pageComponentName:"Page"})).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async getInstallationPlan(e){let{configuration:r,output:n}=e,[{i18n:i},s]=await Promise.all([this.getConfig(),this.getProjectInfo()]);s.fallbackMode&&n.announce({semantics:"warning",title:"Fallback mode",message:"Next.js SDK requires version 13 or newer, so React SDK will be installed instead."});let o=r.locales.filter(u=>i.locales.includes(u)||u===r.defaultLocale),a=o.length>0?o:i.locales,l=i.defaultLocale!==void 0&&a.includes(i.defaultLocale)?i.defaultLocale:r.defaultLocale;return {dependencies:[s.fallbackMode?"@croct/plug-react":"@croct/plug-next"],tasks:this.getInstallationTasks({...e,project:s}),configuration:{...r,locales:a,defaultLocale:l,paths:{...r.paths,examples:s.pageDirectory}}}}async getProjectInfo(){let[e,r,n,i]=await Promise.all([this.isTypeScriptProject(),this.getPageDirectory(),this.isFallbackMode(),this.packageManager.hasDirectDependency("next","<16")]),s={typescript:e,router:await this.detectRouter(r),sourceDirectory:r.startsWith("src")?"src":".",pageDirectory:r},o=i?"middleware":"proxy",[a,l]=await Promise.all([this.locateFile(...[`${o}.js`,`${o}.ts`].map(p=>this.fileSystem.joinPaths(s.sourceDirectory,p))),this.locateFile(...(s.router==="app"?[this.fileSystem.joinPaths("app","layout"),this.fileSystem.joinPaths("app","layout")]:[this.fileSystem.joinPaths("pages","_app"),this.fileSystem.joinPaths("pages","_app")]).flatMap(p=>["js","jsx","ts","tsx"].map(d=>this.fileSystem.joinPaths(s.sourceDirectory,`${p}.${d}`))))]),u=s.typescript?"ts":"js",c=this.projectDirectory.get();return {...s,fallbackMode:n,env:{localFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(c,".env.local")),developmentFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(c,".env.development")),productionFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(c,".env.production"))},proxy:{name:o,file:a??this.fileSystem.joinPaths(s.sourceDirectory,`${o}.${u}`)},provider:{file:l??(s.router==="app"?this.fileSystem.joinPaths(s.sourceDirectory,"app",`layout.${u}x`):this.fileSystem.joinPaths(s.sourceDirectory,"pages",`_app.${u}x`))}}}getInstallationTasks(e){let r=[];if(!e.project.fallbackMode){let n=e.project.proxy.name;r.push({title:`Configure ${n}`,task:async i=>{i.update(`Configuring ${n}`);try{await this.updateCode(this.codemod[n],e.project.proxy.file),i.confirm(`${t.capitalize(n)} configured`);}catch(s){i.alert(`Failed to install ${n}`,V.formatMessage(s));}}});}return r.push({title:"Configure provider",task:async n=>{n.update("Configuring provider");try{await this.installProvider({...e,notifier:n}),n.confirm("Provider configured");}catch(i){n.alert("Failed to install provider",V.formatMessage(i));}}}),r.push({title:"Setup environment variables",task:async n=>{n.update("Setting up environment variables");try{await this.updateEnvVariables({...e,notifier:n}),n.confirm("Environment variables updated");}catch(i){n.alert("Failed to update .env.local",V.formatMessage(i));}}}),r}installProvider(e){return this.updateCode(this.getProviderCodemod(e),e.project.provider.file,{typescript:e.project.typescript})}getProviderCodemod(e){return e.project.fallbackMode?this.codemod.fallbackProvider:e.project.router==="app"?this.codemod.appRouterProvider:this.codemod.pageRouterProvider}async updateCode(e,r,n){await e.apply(this.fileSystem.joinPaths(this.projectDirectory.get(),r),n);}async updateEnvVariables(e){let{project:{env:r},configuration:n,notifier:i}=e;i.update("Loading information");let[s,o]=await Promise.all([this.workspaceApi.getApplication({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:n.applications.development}),n.applications.production===void 0?null:this.workspaceApi.getApplication({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:n.applications.production})]);if(s===null)throw new Mr(`Development application \`${n.applications.development}\` not found.`,{reason:"not_found"});if(!await r.localFile.hasVariable("CROCT_API_KEY")&&e.skipApiKeySetup!==true){let a=await this.userApi.getUser();i.update("Creating API key");let l;try{l=await this.applicationApi.createApiKey({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:s.slug,name:`${a.username} CLI`,permissions:["TOKEN_ISSUE"]});}catch(u){throw u instanceof V?new Mr(u instanceof zn&&u.isAccessDenied()?"Your user does not have permission to create an API key":u.message,u.help):u}await r.localFile.setVariables({CROCT_API_KEY:l.secret});}await Promise.all([r.developmentFile.setVariables({NEXT_PUBLIC_CROCT_APP_ID:s.publicId}),o===null?Promise.resolve():r.productionFile.setVariables({NEXT_PUBLIC_CROCT_APP_ID:o.publicId})]);}async detectRouter(e){return (e??await this.getPageDirectory()).endsWith("pages")?"page":"app"}async getPageDirectory(){return await this.locateFile("app",this.fileSystem.joinPaths("src","app"),"pages",this.fileSystem.joinPaths("src","pages"))??"app"}async getConfig(){let e=["js","mjs","ts","mts"].map(n=>`next.config.${n}`),r=await this.readFile(...e).catch(()=>null);return r===null?{i18n:{locales:[],defaultLocale:""}}:bee(r)}isFallbackMode(){return this.packageManager.hasDirectDependency("next","<=13")}static capitalize(e){return e.charAt(0).toUpperCase()+e.slice(1)}};var dm=class t{constructor(e){this.options=e;}generate(e){let r=t.replaceVariables(this.options.slotFilePath,e.id),n=t.replaceVariables(this.options.slotComponentName,e.id);return {files:[this.generatePageFile(e,{name:n,path:r,importPath:t.replaceVariables(this.options.slotImportPath,e.id),definition:e}),this.generateSlotFile(e,r)]}}getLoadingFlag(){return null}generateSlotFile(e,r){let n=this.createWriter(),i=this.options.contentVariable,s=this.getLoadingFlag();return this.writeSlotScript(n,e),n.newLine(),n.write("<template>").indent(),s!==null?(n.write(`<p v-if="${s}">Loading...</p>`).write("<template v-else>").indent(),this.writeRoot(n,e.definition,i),n.outdent().write("</template>")):this.writeRoot(n,e.definition,i),n.outdent().write("</template>",false),{path:r,language:"vue",code:n.toString()}}generatePageFile(e,r){let n=this.createWriter(),i=t.replaceVariables(this.options.pageFilePath,e.id);return this.writePageScript(n,r),n.toString()!==""&&n.newLine(),n.write("<template>").indent().write(`<${r.name} />`).outdent().write("</template>",false),{path:i,language:"vue",code:n.toString()}}writeScriptOpening(e){e.write(this.options.typescript?'<script setup lang="ts">':"<script setup>");}writeScriptClosing(e){e.write("</script>");}writeRoot(e,r,n){if(r.type==="union"){this.writeUnion(e,r,n);return}e.write(`<ul v-if="${n}">`).indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");}writeFragment(e,r,n){switch(r.type){case "text":case "number":e.append(`{{ ${n} }}`);break;case "boolean":e.append(t.formatBooleanInterpolation(r,n));break;case "list":this.writeList(e,r,n);break;case "structure":e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");break;case "union":this.writeUnion(e,r,n);break}}writeList(e,r,n){let i=r.itemLabel!==void 0?Pi(r.itemLabel):"item";e.write("<ol>").indent().write(`<li v-for="(${i}, index) in ${n}" :key="index">`).indent();let s=t.isInline(r.items);s&&e.appendIndentation(),this.writeFragment(e,r.items,i),s&&e.newLine(),e.outdent().write("</li>").outdent().write("</ol>");}writeStructureAttributes(e,r,n){for(let[i,s]of qs(r.attributes))s.private!==true&&this.writeAttribute(e,{name:i,...s},n);}writeAttribute(e,r,n){let i=`${n}.${r.name}`,s=r.type,o=t.escapeEntities(r.label??_o(r.name)),a=r.optional===true?` v-if="${i}"`:"";switch(s.type){case "boolean":case "text":case "number":{e.write(`<li${a}>`,false).append(`<strong>${o}:</strong> `),this.writeFragment(e,s,i),e.append("</li>").newLine();break}default:e.write(`<li${a}>`).indent().write(`<strong>${o}</strong>`),this.writeFragment(e,s,i),e.outdent().write("</li>");break}}writeUnion(e,r,n){for(let[i,s]of Object.entries(r.types))e.write(`<template v-if="${n}?._type === '${i}'">`).indent(),this.writeFragment(e,s,n),e.outdent().write("</template>");}static formatBooleanInterpolation(e,r){let n=e.label?.true??"Yes",i=e.label?.false??"No";return `{{ ${r} ? '${n.replace(/'/g,"\\'")}' : '${i.replace(/'/g,"\\'")}' }}`}static isInline(e){return ["number","text","boolean"].includes(e.type)}static escapeEntities(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}createWriter(){return new jn(this.options.indentationSize)}static replaceVariables(e,r){return e.replace(/%name%/g,jn.formatName(r,true)).replace(/%slug%/g,Lr(r))}};var YT=class extends dm{writeSlotScript(e,r){let n=this.options.contentVariable,i=n==="data"?n:`data: ${n}`;this.writeScriptOpening(e),e.write("import {useContent} from '@croct/plug-vue';").newLine().write(`const {${i}, isLoading} = useContent('${r.id}@${r.version}');`),this.writeScriptClosing(e);}writePageScript(e,r){this.writeScriptOpening(e),e.write(`import ${r.name} from '${r.importPath}';`),this.writeScriptClosing(e);}getLoadingFlag(){return "isLoading"}};var XT=class t extends Us{constructor(e){super(e),this.codemod=e.codemod,this.bundlers=e.bundlers,this.importResolver=e.importResolver;}async generateSlotExampleFiles(e,r){let n=await this.isTypeScriptProject(),i=await this.getPaths(r.configuration),s=this.fileSystem.joinPaths(i.components,"%slug%.vue"),o=this.fileSystem.joinPaths(i.examples,"%slug%-example.vue");return new YT({typescript:n,contentVariable:"content",slotImportPath:await this.importResolver.getImportPath(s,o),slotFilePath:s,slotComponentName:"%name%",pageFilePath:o}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async getInstallationPlan(e){let{configuration:r}=e,n=await this.getProjectInfo();return {dependencies:["@croct/plug-vue"],tasks:this.getInstallationTasks({...e,project:n}),configuration:r}}async getProjectInfo(){let r=await this.getEnvVarProperty(),n=this.projectDirectory.get();return {typescript:await this.isTypeScriptProject(),sourceDirectory:"src",plugin:{file:await this.locateFile(...["main","index"].flatMap(i=>["ts","js"].map(s=>`${i}.${s}`)).map(i=>this.fileSystem.joinPaths("src",i)))},env:r===null?void 0:{property:r,productionFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(n,".env.production")),developmentFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(n,".env.development"))}}}getInstallationTasks(e){let r=[],n=e.project.env,{configuration:i}=e,s=null,o=()=>(s===null&&(s=Promise.all([this.workspaceApi.getApplication({organizationSlug:i.organization,workspaceSlug:i.workspace,applicationSlug:i.applications.development}),i.applications.production===void 0?null:this.workspaceApi.getApplication({organizationSlug:i.organization,workspaceSlug:i.workspace,applicationSlug:i.applications.production})]).then(([a,l])=>a===null?Promise.reject(new Mr(`Development application ${i.applications.development} not found`,{reason:"not_found"})):{development:a.publicId,production:l?.publicId})),s);if(n!==void 0){let{developmentFile:a,productionFile:l,property:u}=n,c=u.split(".").pop();r.push({title:"Setup environment variables",task:async p=>{p.update("Setting up environment variables");try{let d=await o();await Promise.all([a.setVariable(c,d.development),d.production===void 0?Promise.resolve():l.setVariable(c,d.production)]),p.confirm("Environment variables updated");}catch(d){p.alert("Failed to update environment variables",V.formatMessage(d));}}});}return r.push({title:"Register plugin",task:async a=>{a.update("Registering plugin");let l=e.project.plugin.file;try{l===null?a.alert("No Vue entry file found"):(await this.installPlugin(l,{args:{appId:t.getAppIdProperty(await o(),n?.property)}}),a.confirm("Plugin registered"));}catch{a.alert("Failed to register plugin","Register the Croct plugin in your Vue entry: app.use(createCroct({appId: '<your-app-id>'})) before app.mount().");}}}),r}async installPlugin(e,r){await this.codemod.plugin.apply(this.fileSystem.joinPaths(this.projectDirectory.get(),e),r);}async getEnvVarProperty(){for(let e of this.bundlers)if(await this.packageManager.hasDirectDependency(e.package))return `${e.prefix}CROCT_APP_ID`;return null}static getAppIdProperty(e,r){return r!==void 0?{type:"reference",path:r.split(".")}:e.production===void 0?{type:"literal",value:e.development}:{type:"ternary",condition:{operator:"===",left:{type:"reference",path:["import","meta","env","MODE"]},right:{type:"literal",value:"production"}},consequent:{type:"literal",value:e.production},alternate:{type:"literal",value:e.development}}}};var ZT=class extends dm{writeSlotScript(e,r){this.writeScriptOpening(e),e.write(`const {data} = await useContent('${r.id}@${r.version}');`),this.writeScriptClosing(e);}writePageScript(){}};var QT=class extends Us{constructor(e){super(e),this.codemod=e.codemod,this.userApi=e.userApi,this.applicationApi=e.applicationApi,this.commandExecutor=e.commandExecutor;}createExample(e){return Promise.resolve(new wi(e.name,`/${e.slug}`))}async generateSlotExampleFiles(e,r){let n=await this.isTypeScriptProject(),i=await this.getPaths(r.configuration),s=this.fileSystem.joinPaths(i.components,"%slug%.vue"),o=this.fileSystem.joinPaths(i.examples,"%slug%","index.vue");return new ZT({typescript:n,contentVariable:"data.content",slotImportPath:this.fileSystem.joinPaths("~",i.components,"%slug%.vue"),slotFilePath:s,slotComponentName:"%name%",pageFilePath:o}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async getInstallationPlan(e){let{configuration:r}=e,n=await this.getProjectInfo();return {dependencies:["@croct/plug-nuxt"],tasks:this.getInstallationTasks({...e,project:n}),configuration:{...r,paths:{...r.paths,examples:"pages"}}}}async getProjectInfo(){let[e,r]=await Promise.all([this.isTypeScriptProject(),this.locateNuxtConfig()]),n=this.projectDirectory.get();return {typescript:e,config:{file:r??`nuxt.config.${e?"ts":"js"}`},envFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(n,".env"))}}async locateNuxtConfig(){return this.locateFile(...["ts","js","mjs"].map(e=>`nuxt.config.${e}`))}getInstallationTasks(e){return [{title:"Register module",task:async r=>{r.update("Registering module");try{await this.applyConfigCodemod(e.project.config.file),r.confirm("Module registered");}catch{r.alert("Failed to register module","Add '@croct/plug-nuxt' to the modules array in your nuxt.config.");}}},{title:"Generate Nuxt type aliases",task:async r=>{r.update("Generating Nuxt type aliases");try{await this.generateNuxtTypeAliases(),r.confirm("Nuxt type aliases generated");}catch(n){r.alert("Failed to generate Nuxt type aliases",V.formatMessage(n));}}},{title:"Setup environment variables",task:async r=>{r.update("Setting up environment variables");try{await this.updateEnvVariables({...e,notifier:r}),r.confirm("Environment variables updated");}catch(n){r.alert("Failed to update environment variables",V.formatMessage(n));}}}]}async applyConfigCodemod(e){await this.codemod.config.apply(this.fileSystem.joinPaths(this.projectDirectory.get(),e));}async generateNuxtTypeAliases(){let e=await this.packageManager.getPackageCommand("nuxi",["prepare"]);if(await(await this.commandExecutor.run(e,{workingDirectory:this.projectDirectory.get()})).wait()!==0)throw new V(`Failed to execute command \`${e.name}\`.`)}async updateEnvVariables(e){let{project:{envFile:r},configuration:n,notifier:i}=e;i.update("Loading information");let s=await this.workspaceApi.getApplication({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:n.applications.development});if(s===null)throw new Mr(`Development application \`${n.applications.development}\` not found.`,{reason:"not_found"});if(!await r.hasVariable("NUXT_CROCT_API_KEY")&&e.skipApiKeySetup!==true){let o=await this.userApi.getUser();i.update("Creating API key");let a;try{a=await this.applicationApi.createApiKey({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:s.slug,name:`${o.username} CLI`,permissions:["TOKEN_ISSUE"]});}catch(l){throw l instanceof V?new Mr(l instanceof zn&&l.isAccessDenied()?"Your user does not have permission to create an API key":l.message,l.help):l}await r.setVariables({NUXT_CROCT_API_KEY:a.secret});}await r.setVariables({NUXT_PUBLIC_CROCT_APP_ID:s.publicId});}};var eD=class t{constructor(e){this.configuration=e;}generate(e){let{typescript:r,framework:n,routeFilePath:i,routeComponentName:s,indentationSize:o}=this.configuration,a=Lr(e.id),l=n==="react-router",u=t.replaceVariables(s,e.id),c=new jn(o);c.write("import {fetchContent} from '@croct/plug-hydrogen/server';"),c.write(`import {useLoaderData} from '${l?"react-router":"@remix-run/react"}';`),r&&c.write(l?`import type {Route} from './+types/${a}';`:"import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';"),c.newLine();let p=r?`: ${l?"Route.LoaderArgs":"LoaderFunctionArgs"}`:"";return c.write(`export async function loader({context}${p}) {`).indent().write(`const {content} = await fetchContent('${a}', {scope: context});`).newLine().write("return {content};").outdent().write("}"),c.newLine(),c.write(`export default function ${u}() {`).indent().write(`const {content} = useLoaderData${r?"<typeof loader>":""}();`).newLine().write("return (").indent(),Ju.renderComponentSnippet(c,e.definition,"content"),c.outdent().write(");").outdent().write("}"),{files:[{path:t.replaceVariables(i,e.id),language:r?"tsx":"jsx",code:c.toString()}]}}static replaceVariables(e,r){return e.replace(/%name%/g,jn.formatName(r,true)).replace(/%slug%/g,Lr(r))}};var fm=me(we()),See=me(Jt());function Eee(t,e){let r=typeof t=="string"?Ho(t,["jsx","typescript"]):t,n=null;return (0, See.traverse)(r,{ImportDeclaration:i=>{for(let s of i.node.specifiers)if(Hrt(Grt(s),e))return n=i.node.source.value,i.stop();return i.skip()}}),n}function Grt(t){return fm.isImportDefaultSpecifier(t)?"default":fm.isImportNamespaceSpecifier(t)?"*":fm.isIdentifier(t.imported)?t.imported.name:t.imported.value}function Hrt(t,e){return typeof e=="string"?t===e:e.test(t)}var tD=class extends Us{constructor(e){super(e),this.codemod=e.codemod,this.userApi=e.userApi,this.applicationApi=e.applicationApi,this.importResolver=e.importResolver;}getPaths(e){return Promise.resolve({...e.paths,source:e.paths?.source??"app",utilities:e.paths?.utilities??"app/lib",components:e.paths?.components??"app/components",examples:e.paths?.examples??"app/routes"})}createExample(e){return Promise.resolve(new wi(e.name,`/${e.slug}`))}async generateSlotExampleFiles(e,r){let[n,i]=await Promise.all([this.isTypeScriptProject(),this.detectFramework()]),s=await this.getPaths(r.configuration);return new eD({typescript:n,framework:i,routeFilePath:this.fileSystem.joinPaths(s.examples,`%slug%${n?".tsx":".jsx"}`),routeComponentName:"%name%Route"}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async getInstallationPlan(e){let{configuration:r}=e,n=await this.getProjectInfo();return {dependencies:["@croct/plug-hydrogen"],tasks:this.getInstallationTasks({...e,project:n}),configuration:r}}async getProjectInfo(){let e=this.projectDirectory.get(),[r,n,i,s,o]=await Promise.all([this.detectFramework(),this.locateFile("vite.config.ts","vite.config.mts","vite.config.cts","vite.config.js","vite.config.mjs","vite.config.cjs"),this.locateFile("server.ts","server.js"),this.locateFile("app/root.tsx","app/root.jsx"),this.locateFile("app/entry.server.tsx","app/entry.server.jsx")]),a=await this.locateContext(i);return {framework:r,viteConfig:n,server:i,root:s,context:a,entryServer:o,envFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(e,".env"))}}async detectFramework(){let[e,r]=await Promise.all([this.packageManager.hasDirectDependency("@shopify/hydrogen",">=2025.5.0"),this.packageManager.hasDirectDependency("react-router")]);return e||r?"react-router":"remix"}async locateContext(e){let r=e!==null?await this.followContextImport(e):null;return r!==null?r:this.locateFile("app/lib/context.ts","app/lib/context.tsx","app/lib/context.js","app/lib/context.jsx")}async followContextImport(e){let r=await this.readFile(e);if(r===null)return null;let n=Eee(r,/^create[A-Za-z]*Context$/);return n!==null?this.importResolver.resolveImport(n,e):null}getInstallationTasks(e){let{project:r}=e;return [{title:"Set up environment variables",task:async n=>{n.update("Setting up environment variables");try{await this.updateEnvVariables(e),n.confirm("Environment variables updated");}catch(i){n.alert("Failed to update environment variables",V.formatMessage(i));}}},this.getCodemodTask({title:"Register Vite plugin",confirmation:"Vite plugin registered",codemod:"vite",file:r.viteConfig,instructions:"Add the `croct()` plugin to the `plugins` array in your Vite config."}),r.framework==="react-router"?this.getCodemodTask({title:"Register middleware",confirmation:"Middleware registered",codemod:"middleware",file:r.root,instructions:"Add `createCroctMiddleware()` to the `middleware` array exported from app/root."}):this.getCodemodTask({title:"Expose Croct context",confirmation:"Croct context exposed",codemod:"context",file:r.context,instructions:"Add `croct: await createCroctContext(request, context)` to the load context."}),this.getCodemodTask({title:"Configure Croct cookies",confirmation:"Croct cookies configured",codemod:"cookies",file:r.server,instructions:"Call `writeCroctCookies(response, context)` after the session commits in server.ts."}),this.getCodemodTask({title:"Configure provider",confirmation:"Provider configured",codemod:"provider",file:r.root,instructions:"Wrap your app with `<CroctProvider>` in app/root."}),this.getCodemodTask({title:"Configure content security policy",confirmation:"Content security policy configured",codemod:"csp",file:r.entryServer,instructions:"Add `https://api.croct.io` to `connectSrc` in your content security policy."})]}getCodemodTask(e){let{title:r,confirmation:n,codemod:i,file:s,instructions:o}=e,a=`${r.charAt(0).toLowerCase()}${r.slice(1)}`;return {title:r,task:async l=>{if(l.update(r),s===null){l.alert(`Failed to ${a}`,o);return}try{await this.applyCodemod(this.codemod[i],s),l.confirm(n);}catch{l.alert(`Failed to ${a}`,o);}}}}async applyCodemod(e,r){await e.apply(this.fileSystem.joinPaths(this.projectDirectory.get(),r));}async updateEnvVariables(e){let{project:{envFile:r},configuration:n}=e,i=await this.workspaceApi.getApplication({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:n.applications.development});if(i===null)throw new Mr(`Development application \`${n.applications.development}\` not found.`,{reason:"not_found"});if(!await r.hasVariable("CROCT_API_KEY")&&e.skipApiKeySetup!==true){let s=await this.userApi.getUser(),o;try{o=await this.applicationApi.createApiKey({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:i.slug,name:`${s.username} CLI`,permissions:["TOKEN_ISSUE"]});}catch(a){throw a instanceof V?new Mr(a instanceof zn&&a.isAccessDenied()?"Your user does not have permission to create an API key":a.message,a.help):a}await r.setVariables({CROCT_API_KEY:o.secret});}await r.setVariables({PUBLIC_CROCT_APP_ID:i.publicId});}};var gl=class t{static{this.PHPSTAN_EXTENSION="vendor/croct/plug-php/extension.neon";}constructor(e){this.projectDirectory=e.projectDirectory,this.packageManager=e.packageManager,this.fileSystem=e.fileSystem,this.formatter=e.formatter,this.commandExecutor=e.commandExecutor,this.exampleLauncher=e.exampleLauncher,this.phpstanIncludeCodemod=e.phpstanIncludeCodemod,this.contentLoader=e.contentLoader,this.workspaceApi=e.workspaceApi,this.userApi=e.userApi,this.applicationApi=e.applicationApi;}async setup(e){let{input:r,output:n}=e,i=await this.getInstallationPlan(e),s={...i.configuration,paths:{content:".",...await this.getPaths(e.configuration),...i.configuration.paths}},o={...e,configuration:{...e.configuration,...s,applications:e.configuration.applications}},a=[];a.push({title:"Install dependencies",task:async c=>{c.update("Installing dependencies");let p=new Ci({status:"Installing dependencies",notifier:c});try{await this.packageManager.addDependencies(i.dependencies,{logger:p}),c.confirm("Dependencies installed");}catch(d){c.alert("Failed to install dependencies",V.formatMessage(d));}}}),a.push(...i.tasks);let l=await this.packageManager.hasDependency("phpstan/phpstan"),u=await this.packageManager.hasDependency("phpstan/extension-installer");if(l&&!u&&a.push(this.getPhpstanTask()),await this.packageManager.hasDependency("vimeo/psalm")&&a.push(this.getPsalmTask()),a.push({title:"Set up credentials",task:async c=>{c.update("Setting up credentials");try{await this.setUpCredentials({...o,notifier:c}),c.confirm("Credentials configured");}catch(p){c.alert("Failed to set up credentials",V.formatMessage(p));}}}),a.push({title:"Download content",task:async c=>{c.update("Downloading content");try{await this.contentLoader.downloadContent(o.configuration,!0),c.confirm("Content downloaded");}catch(p){c.alert("Failed to download content",V.formatMessage(p));}}}),a.push({title:"Generate types",task:async c=>{c.update("Generating types");try{await this.updateTypes(o,{clean:!0}),c.confirm("Types generated");}catch(p){c.alert("Failed to generate types",V.formatMessage(p));}}}),r!==void 0){n.break(),n.inform("**Installation plan**");for(let{title:c}of a)n.log(` - ${c}`);if(n.break(),!await r.confirm({message:"Proceed?",default:true}))return n.exit()}return await n.monitor({tasks:a}),s}getPaths(e){let r=e.paths?.source??"src";return Promise.resolve({...e.paths,source:r,utilities:e.paths?.utilities??`${r}/utils`,components:e.paths?.components??`${r}/components`,examples:e.paths?.examples??"examples"})}async update(e,r={}){await this.contentLoader.downloadContent(e.configuration,r.clean===true),await this.updateTypes(e,r);}async updateTypes(e,r){let{configuration:n}=e,i=this.fileSystem.joinPaths(this.projectDirectory.get(),n.paths?.content??".","slots.stub");if(r.clean!==true&&await this.fileSystem.exists(i)||Object.keys(n.slots).length===0&&Object.keys(n.components).length===0)return;let s=await this.contentLoader.loadTypes(n,"PLUG_PHP");await this.fileSystem.createDirectory(this.fileSystem.getDirectoryName(i),{recursive:true}),await this.fileSystem.writeTextFile(i,s,{overwrite:true});}async generateSlotExample(e,r){let n=this.projectDirectory.get(),i=[];for(let s of await this.generateSlotExampleFiles(e,r)){let o=this.fileSystem.joinPaths(n,this.fileSystem.getDirectoryName(s.path));await this.fileSystem.createDirectory(o,{recursive:true}).catch(()=>null);let a=this.fileSystem.joinPaths(n,s.path);await this.fileSystem.writeTextFile(a,s.code,{overwrite:true}),s.language==="php"&&i.push(a);}i.length>0&&await this.formatter.format(i);}async presentExamples(e,r){await this.exampleLauncher.launch({examples:await Promise.all(e.map(n=>this.createExample(n,r))),input:r.input,output:r.output});}getPhpstanTask(){let e=`Add \`${t.PHPSTAN_EXTENSION}\` to your PHPStan \`includes\`.`;return {title:"Enable PHPStan extension",task:async r=>{r.update("Enabling PHPStan extension");let n=await this.findPhpstanConfig()??this.fileSystem.joinPaths(this.projectDirectory.get(),"phpstan.neon");try{let{modified:i}=await this.phpstanIncludeCodemod.apply(n,{key:"includes",value:t.PHPSTAN_EXTENSION});r.confirm(i?"PHPStan extension enabled":"PHPStan extension already enabled");}catch{r.warn("Failed to enable the PHPStan extension",e);}}}}getPsalmTask(){let e="Run `vendor/bin/psalm-plugin enable croct/plug-php` to enable the Croct plugin.";return {title:"Enable Psalm plugin",task:async r=>{r.update("Enabling Psalm plugin");try{let n=await this.packageManager.getPackageCommand("psalm-plugin",["enable","croct/plug-php"]),s=await(await this.commandExecutor.run(n,{workingDirectory:this.projectDirectory.get()})).wait();s===0||s===3?r.confirm("Psalm plugin enabled"):r.warn("Failed to enable the Psalm plugin",e);}catch{r.warn("Failed to enable the Psalm plugin",e);}}}}async findPhpstanConfig(){let e=this.projectDirectory.get(),r=["phpstan.neon","phpstan.neon.dist","phpstan.dist.neon"].map(i=>this.fileSystem.joinPaths(e,i)),n=await Promise.all(r.map(i=>this.fileSystem.exists(i)));for(let i=0;i<n.length;i++)if(n[i])return r[i];return null}async setUpCredentials(e){let{configuration:r,notifier:n}=e;n.update("Loading information");let i=await this.workspaceApi.getApplication({organizationSlug:r.organization,workspaceSlug:r.workspace,applicationSlug:r.applications.development});if(i===null)throw new Mr(`Development application \`${r.applications.development}\` not found.`,{reason:"not_found"});if(!await this.hasApiKey()&&e.skipApiKeySetup!==true){let s=await this.userApi.getUser();n.update("Creating API key");let o;try{o=await this.applicationApi.createApiKey({organizationSlug:r.organization,workspaceSlug:r.workspace,applicationSlug:i.slug,name:`${s.username} CLI`,permissions:["TOKEN_ISSUE"]});}catch(a){throw a instanceof V?new Mr(a instanceof zn&&a.isAccessDenied()?"Your user does not have permission to create an API key":a.message,a.help):a}await this.storeApiKey(o.secret);}await this.storeAppId(i.publicId);}hasApiKey(){return this.getEnvFile().hasVariable("CROCT_API_KEY")}async storeApiKey(e){await this.getEnvFile().setVariables({CROCT_API_KEY:e});}async storeAppId(e){await this.getEnvFile().setVariables({CROCT_APP_ID:e});}getEnvFile(){return new Ai(this.fileSystem,this.fileSystem.joinPaths(this.projectDirectory.get(),".env"))}};var rD=class t{constructor(e){this.options=e;}generate(e){let r=t.replaceVariables(this.options.filePath,e.id),n=new jn(this.options.indentationSize),i=`$${this.options.contentVariable}`,s=t.escapeEntities(t.formatTitle(e.id));return this.writeScript(n,e),n.newLine().write("<!doctype html>").write('<html lang="en">').write("<head>").indent().write('<meta charset="utf-8">').write(`<title>${s}</title>`).outdent().write("</head>").write("<body>").indent(),this.writeRoot(n,e.definition,i),n.newLine(),this.writeHandoff(n),n.outdent().write("</body>").write("</html>",false),{files:[{path:r,language:"php",code:n.toString()}]}}writeHandoff(e){e.write('<script async src="https://cdn.croct.io/js/v1/lib/plug.js"></script>').write("<script>").indent().write("croct.plug(<?= json_encode($croct->getPlugOptions()) ?>);").outdent().write("</script>");}writeRoot(e,r,n){if(r.type==="union"){this.writeUnion(e,r,n);return}e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");}writeStructureAttributes(e,r,n){for(let[i,s]of qs(r.attributes))s.private!==true&&this.writeAttribute(e,{name:i,...s},n);}writeAttribute(e,r,n){let i=`${n}['${r.name}']`,s=r.type,o=t.escapeEntities(r.label??_o(r.name)),a=r.optional===true;switch(a&&e.write(`<?php if (isset(${i})): ?>`).indent(),s.type){case "boolean":case "text":case "number":e.write(`<li><strong>${o}:</strong> `,false),this.writeFragment(e,s,i),e.append("</li>").newLine();break;default:e.write("<li>").indent().write(`<strong>${o}</strong>`),this.writeFragment(e,s,i),e.outdent().write("</li>");break}a&&e.outdent().write("<?php endif; ?>");}writeFragment(e,r,n){switch(r.type){case "text":e.append(`<?= htmlspecialchars(${n}) ?>`);break;case "number":e.append(`<?= ${n} ?>`);break;case "boolean":e.append(t.formatBoolean(r,n));break;case "list":this.writeList(e,r,n);break;case "structure":e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");break;case "union":this.writeUnion(e,r,n);break}}writeList(e,r,n){let s=`$${r.itemLabel!==void 0?Pi(r.itemLabel):"item"}`;e.write("<ol>").indent().write(`<?php foreach (${n} as ${s}): ?>`).indent(),t.isInline(r.items)?(e.write("<li>",false),this.writeFragment(e,r.items,s),e.append("</li>").newLine()):(e.write("<li>").indent(),this.writeFragment(e,r.items,s),e.outdent().write("</li>")),e.outdent().write("<?php endforeach; ?>").outdent().write("</ol>");}writeUnion(e,r,n){for(let[i,s]of Object.entries(r.types))e.write(`<?php if (${n}['_type'] === '${t.escapeString(i)}'): ?>`).indent(),this.writeFragment(e,s,n),e.outdent().write("<?php endif; ?>");}static formatBoolean(e,r){let n=t.escapeString(e.label?.true??"Yes"),i=t.escapeString(e.label?.false??"No");return `<?= ${r} ? '${n}' : '${i}' ?>`}static isInline(e){return ["number","text","boolean"].includes(e.type)}static escapeString(e){return e.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}static escapeEntities(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}static formatTitle(e){return Lr(e).split("-").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join(" ")}static replaceVariables(e,r){return e.replace(/%slug%/g,Lr(r))}};var nD=class t extends rD{constructor(e){super(e),this.autoloadPath=e.autoloadPath;}writeScript(e,r){let n=t.escapeString(r.id),i=this.autoloadPath.replace(/[\\/]?vendor[\\/]autoload\.php$/,"")||".";e.write("<?php").newLine().write("declare(strict_types=1);").newLine().write("use Croct\\Plug\\Croct;").newLine().write(`require __DIR__ . '/${this.autoloadPath}';`).newLine().write(`$croct = Croct::fromDotenv(__DIR__ . '/${i}');`).newLine().write(`$${this.options.contentVariable} = $croct->fetchContent('${n}')->getContent();`).newLine().write("Croct::emitCookies();").newLine().write("?>",false);}};var iD=class t extends gl{getInstallationPlan(e){return Promise.resolve({dependencies:["croct/plug-php","psr/http-client-implementation","psr/http-factory-implementation","psr/http-message-implementation"],tasks:[],configuration:e.configuration})}async generateSlotExampleFiles(e,r){let n=await this.getPaths(r.configuration);return new nD({contentVariable:"content",filePath:this.fileSystem.joinPaths(n.examples,"%slug%.php"),autoloadPath:this.resolveAutoloadPath(n.examples)}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async createExample(e,r){let{examples:n}=await this.getPaths(r.configuration);return new wi(e.name,t.resolveExampleUrl(n,e.slug))}resolveAutoloadPath(e){let r=this.projectDirectory.get(),n=this.fileSystem.joinPaths(r,e),i=this.fileSystem.getRelativePath(n,r);return this.fileSystem.joinPaths(i,"vendor","autoload.php").replace(/\\/g,"/")}static resolveExampleUrl(e,r){return `/${e}/${Lr(r)}.php`}};var sD=class t{constructor(e){this.options=e;}generate(e){let r=t.replaceVariables(this.options.filePath,e.id),n=new jn(this.options.indentationSize),i=`$${this.options.contentVariable}`,s=t.escapeEntities(t.formatTitle(e.id));return n.write("<!doctype html>").write('<html lang="en">').write("<head>").indent().write('<meta charset="utf-8">').write(`<title>${s}</title>`).outdent().write("</head>").write("<body>").indent(),this.writeRoot(n,e.definition,i),n.outdent().write("</body>").write("</html>",false),{files:[{path:r,language:"blade",code:n.toString()}]}}writeRoot(e,r,n){if(r.type==="union"){this.writeUnion(e,r,n);return}e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");}writeStructureAttributes(e,r,n){for(let[i,s]of qs(r.attributes))s.private!==true&&this.writeAttribute(e,{name:i,...s},n);}writeAttribute(e,r,n){let i=`${n}['${r.name}']`,s=r.type,o=t.escapeEntities(r.label??_o(r.name)),a=r.optional===true;switch(a&&e.write(`@isset(${i})`).indent(),s.type){case "boolean":case "text":case "number":e.write(`<li><strong>${o}:</strong> `,false),this.writeFragment(e,s,i),e.append("</li>").newLine();break;default:e.write("<li>").indent().write(`<strong>${o}</strong>`),this.writeFragment(e,s,i),e.outdent().write("</li>");break}a&&e.outdent().write("@endisset");}writeFragment(e,r,n){switch(r.type){case "text":case "number":e.append(`{{ ${n} }}`);break;case "boolean":e.append(t.formatBoolean(r,n));break;case "list":this.writeList(e,r,n);break;case "structure":e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");break;case "union":this.writeUnion(e,r,n);break}}writeList(e,r,n){let s=`$${r.itemLabel!==void 0?Pi(r.itemLabel):"item"}`;e.write("<ol>").indent().write(`@foreach (${n} as ${s})`).indent(),t.isInline(r.items)?(e.write("<li>",false),this.writeFragment(e,r.items,s),e.append("</li>").newLine()):(e.write("<li>").indent(),this.writeFragment(e,r.items,s),e.outdent().write("</li>")),e.outdent().write("@endforeach").outdent().write("</ol>");}writeUnion(e,r,n){for(let[i,s]of Object.entries(r.types))e.write(`@if (${n}['_type'] === '${t.escapeString(i)}')`).indent(),this.writeFragment(e,s,n),e.outdent().write("@endif");}static formatBoolean(e,r){let n=t.escapeString(e.label?.true??"Yes"),i=t.escapeString(e.label?.false??"No");return `{{ ${r} ? '${n}' : '${i}' }}`}static isInline(e){return ["number","text","boolean"].includes(e.type)}static escapeString(e){return e.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}static escapeEntities(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}static formatTitle(e){return Lr(e).split("-").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join(" ")}static replaceVariables(e,r){return e.replace(/%slug%/g,Lr(r))}};var oD=class t extends gl{static{this.VIEWS_DIRECTORY="resources/views";}constructor(e){super(e),this.routeCodemod=e.routeCodemod;}getInstallationPlan(e){return Promise.resolve({dependencies:["croct/plug-laravel"],tasks:[],configuration:e.configuration})}getPaths(e){return Promise.resolve({...e.paths,source:e.paths?.source??"app",utilities:e.paths?.utilities??"app/Support",components:e.paths?.components??"app/View/Components",examples:e.paths?.examples??`${t.VIEWS_DIRECTORY}/croct`})}async generateSlotExampleFiles(e,r){let n=await this.getPaths(r.configuration),i=new sD({contentVariable:"content",filePath:this.fileSystem.joinPaths(n.examples,"%slug%.blade.php")}),{files:s}=i.generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}),o=await this.generateRouteFile(e.slug,this.resolveViewName(n.examples,e.slug));return o!==null?[...s,o]:s}createExample(e){return Promise.resolve(new wi(e.name,t.resolveExampleUrl(e.slug)))}async generateRouteFile(e,r){let n=this.fileSystem.joinPaths("routes","web.php"),i=this.fileSystem.joinPaths(this.projectDirectory.get(),n),s=await this.fileSystem.exists(i)?await this.fileSystem.readTextFile(i):"",{modified:o,result:a}=await this.routeCodemod.apply(s,{slot:e,url:t.resolveExampleUrl(e),view:r});return o?{path:n,code:a,language:"php"}:null}resolveViewName(e,r){let n=this.projectDirectory.get();return [...this.fileSystem.getRelativePath(this.fileSystem.joinPaths(n,t.VIEWS_DIRECTORY),this.fileSystem.joinPaths(n,e)).split(/[\\/]/),Lr(r)].filter(s=>s!==""&&s!==".").join(".")}static resolveExampleUrl(e){return `/${Lr(e)}`}};var mm=class t{constructor(e){this.options=e;}generate(e){let r=t.replaceVariables(this.options.filePath,e.id),n=new jn(this.options.indentationSize),i=this.options.contentVariable;if(this.options.page===false)this.writeRoot(n,e.definition,i);else {let s=t.escapeEntities(t.formatTitle(e.id));n.write("<!doctype html>").write('<html lang="en">').write("<head>").indent().write('<meta charset="utf-8">').write(`<title>${s}</title>`).outdent().write("</head>").write("<body>").indent(),this.writeRoot(n,e.definition,i),n.outdent().write("</body>").write("</html>",false);}return {files:[{path:r,language:"twig",code:n.toString()}]}}writeRoot(e,r,n){if(r.type==="union"){this.writeUnion(e,r,n);return}e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");}writeStructureAttributes(e,r,n){for(let[i,s]of qs(r.attributes))s.private!==true&&this.writeAttribute(e,{name:i,...s},n);}writeAttribute(e,r,n){let i=`${n}.${r.name}`,s=r.type,o=t.escapeEntities(r.label??_o(r.name)),a=r.optional===true;switch(a&&e.write(`{% if ${i} is defined %}`).indent(),s.type){case "boolean":case "text":case "number":e.write(`<li><strong>${o}:</strong> `,false),this.writeFragment(e,s,i),e.append("</li>").newLine();break;default:e.write("<li>").indent().write(`<strong>${o}</strong>`),this.writeFragment(e,s,i),e.outdent().write("</li>");break}a&&e.outdent().write("{% endif %}");}writeFragment(e,r,n){switch(r.type){case "text":case "number":e.append(`{{ ${n} }}`);break;case "boolean":e.append(t.formatBoolean(r,n));break;case "list":this.writeList(e,r,n);break;case "structure":e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");break;case "union":this.writeUnion(e,r,n);break}}writeList(e,r,n){let i=r.itemLabel!==void 0?Pi(r.itemLabel):"item";e.write("<ol>").indent().write(`{% for ${i} in ${n} %}`).indent(),t.isInline(r.items)?(e.write("<li>",false),this.writeFragment(e,r.items,i),e.append("</li>").newLine()):(e.write("<li>").indent(),this.writeFragment(e,r.items,i),e.outdent().write("</li>")),e.outdent().write("{% endfor %}").outdent().write("</ol>");}writeUnion(e,r,n){for(let[i,s]of Object.entries(r.types))e.write(`{% if ${n}._type == '${t.escapeString(i)}' %}`).indent(),this.writeFragment(e,s,n),e.outdent().write("{% endif %}");}static formatBoolean(e,r){let n=t.escapeString(e.label?.true??"Yes"),i=t.escapeString(e.label?.false??"No");return `{{ ${r} ? '${n}' : '${i}' }}`}static isInline(e){return ["number","text","boolean"].includes(e.type)}static escapeString(e){return e.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}static escapeEntities(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}static formatTitle(e){return Lr(e).split("-").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join(" ")}static replaceVariables(e,r){return e.replace(/%slug%/g,Lr(r))}};var aD=class t extends gl{static{this.TEMPLATES_DIRECTORY="templates";}constructor(e){super(e),this.bundleCodemod=e.bundleCodemod,this.configCodemod=e.configCodemod;}getInstallationPlan(e){return Promise.resolve({dependencies:["croct/plug-symfony","symfony/twig-bundle"],tasks:[{title:"Register bundle",task:async r=>{r.update("Registering bundle");try{r.confirm(await this.registerBundle()?"Bundle registered":"Bundle already registered");}catch{r.alert("Failed to register bundle","Add Croct\\Plug\\Symfony\\CroctBundle::class => ['all' => true] to the array in config/bundles.php.");}}},{title:"Configure bundle",task:async r=>{r.update("Configuring bundle");try{r.confirm(await this.configureBundle()?"Bundle configured":"Bundle already configured");}catch(n){r.alert("Failed to configure bundle",V.formatMessage(n));}}}],configuration:e.configuration})}async getPaths(e){return {...await super.getPaths(e),examples:e.paths?.examples??`${t.TEMPLATES_DIRECTORY}/croct`}}async generateSlotExampleFiles(e,r){let n=await this.getPaths(r.configuration);return [...new mm({contentVariable:"content",filePath:this.fileSystem.joinPaths(n.examples,"%slug%.html.twig")}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files,this.generateController(e.slug,n)]}createExample(e){return Promise.resolve(new wi(e.name,t.resolveExampleUrl(e.slug)))}generateController(e,r){let n=Pi(e).replace(/^./,a=>a.toUpperCase()),i=`croct_${Lr(e).replace(/-/g,"_")}`,s=this.resolveTemplateReference(r.examples,e),o=["<?php","","declare(strict_types=1);","","namespace App\\Controller;","","use Croct\\Plug\\Plug;","use Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController;","use Symfony\\Component\\HttpFoundation\\Response;","use Symfony\\Component\\Routing\\Attribute\\Route;","",`final class Croct${n}Controller extends AbstractController`,"{",` #[Route('${t.resolveExampleUrl(e)}', name: '${i}')]`," public function __invoke(Plug $croct): Response"," {",` return $this->render('${s}', [`,` 'content' => $croct->fetchContent('${e}')->getContent(),`," ]);"," }","}",""].join(`
743
+ `}${e}=${r}`)}async write(e){await this.fileSystem.writeTextFile(this.path,e,{overwrite:true});}async read(){return await this.exists()?this.fileSystem.readTextFile(this.path):""}static escapeRegex(e){return e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&")}};var Ju=class t{constructor({fileSystem:e,...r}){this.options=r,this.fileSystem=e;}generate(e){let r=t.replaceVariables(this.options.slotFilePath,e.id),n=t.replaceVariables(this.options.slotComponentName,e.id);return {files:[this.generatePageFile(e,{name:n,path:r,importPath:t.replaceVariables(this.options.slotImportPath,e.id),definition:e}),this.generateSlotFile(e,r,n)]}}generatePageFile(e,r){let n=this.createWriter(),i=t.replaceVariables(this.options.pageFilePath,e.id),s=t.replaceVariables(this.options.pageComponentName,e.id);return this.writePageSnippet(n,s,r),{path:i,language:this.options.language,code:n.toString()}}generateSlotFile(e,r,n){let i=this.createWriter();return this.writeSlotSnippet(i,e,n),{path:r,language:this.options.language,code:i.toString()}}writePageSnippet(e,r,n){this.writePageHeader(e,n),e.newLine(),this.writePageSignature(e,r),e.indent().write("return (").indent(),this.hasSuspenseBoundary()&&e.write('<Suspense fallback="\u2728 Personalizing...">').indent(),this.writeSlotRendering(e,n.name),this.hasSuspenseBoundary()&&e.outdent().write("</Suspense>"),e.outdent().write(");").outdent().write("}",false);}writeSlotRendering(e,r){e.write(`<${r} />`);}writePageSignature(e,r){e.write(this.options.language==="tsx"?`export default function ${r}(): ReactElement {`:`export default function ${r}() {`);}writePageHeader(e,r){switch(this.options.language){case "jsx":this.hasSuspenseBoundary()&&e.write("import {Suspense} from 'react';");break;case "tsx":e.write(this.hasSuspenseBoundary()?"import {type ReactElement, Suspense} from 'react';":"import type {ReactElement} from 'react';");break}e.write(`import ${r.name} from '${r.importPath}';`);}writeSlotSnippet(e,r,n){this.writeSlotHeader(e,r),this.writeSlotSignature(e,r,n),e.indent(),this.writeSlotFetch(e,r),e.write("return (").indent(),t.renderComponentSnippet(e,r.definition,this.options.contentVariable),e.outdent().write(");").outdent().write("};");}writeSlotSignature(e,r,n){e.write(`export default ${this.isSlotFetchAsync()?"async ":""}function ${n}`,false),this.appendSlotParams(e,r),this.options.language==="tsx"&&e.append(`: ${this.isSlotFetchBlocking()?"Promise<ReactElement>":"ReactElement"}`),e.write(" {");}appendSlotParams(e,r){e.append("()");}static renderComponentSnippet(e,r,n){switch(r.type){case "number":case "text":e.append(`{${n}}`);break;case "boolean":r.label!==void 0?e.append(`{${n} ? `).appendValue(r.label.true??"Yes",{delimiter:"'"}).append(" : ").appendValue(r.label.false??"No",{delimiter:"'"}).append("}"):e.append(`{${n} ? 'Yes' : 'No'}`);break;case "list":{let i=r.itemLabel!==void 0?Pi(r.itemLabel):"item";e.write("<ol>").indent().write(`{${n}.map((${i}, index) => (`).indent().write("<li key={index}>").indent();let s=t.isInline(r.items);s&&e.appendIndentation(),t.renderComponentSnippet(e,r.items,i),s&&e.newLine(),e.outdent().write("</li>").outdent().write("))}").outdent().write("</ol>");break}case "structure":e.write("<ul>").indent();for(let[i,s]of qs(r.attributes))s.private!==true&&(s.optional===true&&(e.write(`{${n}.${i} && (`),e.indent()),t.writeAttributeSnippet(e,{name:i,...s},n),s.optional===true&&(e.outdent(),e.write(")}")));e.outdent().write("</ul>");break;case "union":{let i=!n.includes(".");i&&e.write("<>").indent();for(let[s,o]of Object.entries(r.types))e.write(`{${n}._type === '${s}' && (`).indent(),t.renderComponentSnippet(e,o,n),e.outdent().write(")}");i&&e.outdent().write("</>");break}}}static writeAttributeSnippet(e,r,n){let i=r.type,s=t.escapeEntities(r.label??_o(r.name));switch(i.type){case "boolean":case "text":case "number":{e.write("<li>",false).append(`<strong>${s}:</strong> `),t.renderComponentSnippet(e,i,`${n}.${r.name}`),e.append("</li>").newLine();break}default:e.write("<li>").indent().write(`<strong>${s}</strong>`),t.renderComponentSnippet(e,i,`${n}.${r.name}`),e.outdent().write("</li>");break}}static escapeEntities(e){return e.replace(/([&"<>])/g,r=>({"&":"&amp;",'"':"&quot;","<":"&lt;",">":"&gt;"})[r]??r)}createWriter(){return new jn(this.options.indentationSize)}static replaceVariables(e,r){return e.replace(/%name%/g,t.formatName(r,true)).replace(/%slug%/g,Lr(r))}static formatName(e,r=false){return jn.formatName(e,r)}static isInline(e){return ["number","text","boolean"].includes(e.type)}};var cf=class extends Ju{writeSlotHeader(e){switch(this.options.language){case "jsx":e.write("import {useContent} from '@croct/plug-react';");break;case "tsx":e.write("import type {ReactElement} from 'react';"),e.write("import {useContent} from '@croct/plug-react';");break}e.newLine();}writeSlotFetch(e,r){let n=this.options.contentVariable,i=n!=="content"?`content: ${n}`:n;e.write(`const ${i} = useContent('${r.id}@${r.version}');`).newLine();}isSlotFetchAsync(){return false}isSlotFetchBlocking(){return false}hasSuspenseBoundary(){return false}};var Nv=class t extends Us{constructor(e){super(e),this.codemod=e.codemod,this.bundlers=e.bundlers,this.importResolver=e.importResolver;}async generateSlotExampleFiles(e,r){let n=await this.isTypeScriptProject(),i=await this.getPaths(r.configuration),s=this.fileSystem.joinPaths(i.components,`%slug%${n?".tsx":".jsx"}`),o=this.fileSystem.joinPaths(i.examples,`%slug%-example${n?".tsx":".jsx"}`);return new cf({fileSystem:this.fileSystem,language:await this.isTypeScriptProject()?"tsx":"jsx",contentVariable:"content",slotImportPath:await this.importResolver.getImportPath(s,o),slotFilePath:s,slotComponentName:"%name%",pageFilePath:o,pageComponentName:"%name%Example"}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async getInstallationPlan(e){let{configuration:r}=e,n=await this.getProjectInfo();return {dependencies:["@croct/plug-react"],tasks:this.getInstallationTasks({...e,project:n}),configuration:r}}async getProjectInfo(){let r=await this.getEnvVarProperty(),n=this.projectDirectory.get();return {typescript:await this.isTypeScriptProject(),sourceDirectory:"src",provider:{file:await this.locateFile(...["App","main","index"].flatMap(i=>["js","jsx","ts","tsx"].map(s=>`${i}.${s}`)).map(i=>this.fileSystem.joinPaths("src",i)))},env:r===null?void 0:{property:r,productionFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(n,".env.production")),developmentFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(n,".env.development"))}}}getInstallationTasks(e){let r=[],n=e.project.env,{configuration:i}=e,s=null,o=()=>(s===null&&(s=Promise.all([this.workspaceApi.getApplication({organizationSlug:i.organization,workspaceSlug:i.workspace,applicationSlug:i.applications.development}),i.applications.production===void 0?null:this.workspaceApi.getApplication({organizationSlug:i.organization,workspaceSlug:i.workspace,applicationSlug:i.applications.production})]).then(([a,l])=>a===null?Promise.reject(new Mr(`Development application ${i.applications.development} not found`,{reason:"not_found"})):{development:a.publicId,production:l?.publicId})),s);if(n!==void 0){let{developmentFile:a,productionFile:l,property:u}=n,c=u.split(".").pop();r.push({title:"Setup environment variables",task:async p=>{p.update("Setting up environment variables");try{let d=await o();await Promise.all([a.setVariable(c,d.development),d.production===void 0?Promise.resolve():l.setVariable(c,d.production)]),p.confirm("Environment variables updated");}catch(d){p.alert("Failed to update environment variables",V.formatMessage(d));}}});}return r.push({title:"Configure provider",task:async a=>{a.update("Configuring provider");let l=e.project.provider.file,u="Wrap your app's root component with <CroctProvider> from @croct/plug-react.";try{l===null?a.alert("No root component found",u):(await this.installProvider(l,{props:{appId:t.getAppIdProperty(await o(),n?.property)}}),a.confirm("Provider configured"));}catch{a.alert("Failed to install provider",u);}}}),r}async installProvider(e,r){await this.codemod.provider.apply(this.fileSystem.joinPaths(this.projectDirectory.get(),e),r);}async getEnvVarProperty(){for(let e of this.bundlers)if(await this.packageManager.hasDirectDependency(e.package))return `${e.prefix}CROCT_APP_ID`;return null}static getAppIdProperty(e,r){return r!==void 0?{type:"reference",path:r.split(".")}:e.production===void 0?{type:"literal",value:e.development}:{type:"ternary",condition:{operator:"===",left:{type:"reference",path:["process","env","NODE_ENV"]},right:{type:"literal",value:"production"}},consequent:{type:"literal",value:e.production},alternate:{type:"literal",value:e.development}}}};var ho=me(we()),gee=me(Jt());var yee=me(gp());var cr=class t extends V{constructor(e,r={}){super(e,r),Object.setPrototypeOf(this,t.prototype);}},HT=class t extends cr{constructor(e){super(e),Object.setPrototypeOf(this,t.prototype);}};function Ho(t,e,r){try{return (0,yee.parse)(t,{...r,sourceType:"module",plugins:[...e,...r?.plugins??[]]})}catch{throw new HT("The source code contains syntax errors.")}}function bee(t){let e={locales:Array()},r;try{r=Ho(t,["jsx","typescript"]);}catch{return {i18n:e}}return (0, gee.traverse)(r,{ObjectProperty:n=>{if(qj(n.node.key)!=="i18n")return n.skip();let i=n.node.value;if(!ho.isObjectExpression(i))return n.stop();for(let s of i.properties)if(ho.isObjectProperty(s)&&qj(s.key)==="locales"){let o=s.value;if(ho.isArrayExpression(o))for(let a of o.elements)a!==null&&ho.isStringLiteral(a)&&e.locales.push(a.value);}else if(ho.isObjectProperty(s)&&qj(s.key)==="defaultLocale"){let o=s.value;o!==null&&ho.isStringLiteral(o)&&(e.defaultLocale=o.value);}return n.stop()}}),{i18n:e}}function qj(t){return ho.isIdentifier(t)?t.name:ho.isStringLiteral(t)?t.value:null}var KT=class extends Ju{constructor({fileSystem:e,router:r,...n}){super({fileSystem:e,contentVariable:r==="app"?"content":"props",...n}),this.nextOptions={router:r};}writeSlotHeader(e,r){switch(this.options.language){case "jsx":this.nextOptions.router==="app"&&(e.write("import {fetchContent} from '@croct/plug-next/server';"),e.newLine());break;case "tsx":if(e.write("import type {ReactElement} from 'react';"),this.nextOptions.router==="app"&&e.write("import {fetchContent} from '@croct/plug-next/server';"),this.nextOptions.router==="page"){e.write("import type {SlotContent} from '@croct/plug-next';"),e.newLine();let n=jn.formatName(r.id,true);e.write(`export type ${n}Props = SlotContent<'${r.id}@${r.version}'>;`);}e.newLine();break}}writeSlotFetch(e,r){if(this.nextOptions.router==="app"){let n=this.options.contentVariable;e.write(`const {${n}} = await fetchContent('${r.id}@${r.version}');`).newLine();}}writePageHeader(e,r){if(this.nextOptions.router==="app")return super.writePageHeader(e,r);let n=`${r.definition.id}@${r.definition.version}`;switch(this.options.language){case "jsx":e.write("import {fetchContent} from '@croct/plug-next/server';").write(`import ${r.name} from '${r.importPath}';`),e.newLine().write("export async function getServerSideProps(context) {").indent().write("return {").indent().write(`props: await fetchContent('${n}', {`).indent().write("route: context,").outdent().write("}),").outdent().write("}").outdent().write("}");break;case "tsx":e.write("import type {ReactElement} from 'react';"),e.write("import type {GetServerSideProps} from 'next';"),e.write("import {fetchContent} from '@croct/plug-next/server';"),e.write(`import ${r.name}, {type ${r.name}Props} from '${r.importPath}';`),e.newLine().write("type PageProps = {").indent().write(`content: ${r.name}Props,`).outdent().write("};").newLine().write("export const getServerSideProps: ",false).write("GetServerSideProps<PageProps> = async context => ({").indent().write(`props: await fetchContent('${n}', {`).indent().write("route: context,").outdent().write("}),").outdent().write("});");break}}writePageSignature(e,r){switch(this.nextOptions.router){case "app":super.writePageSignature(e,r);break;case "page":{e.write(this.options.language==="tsx"?"export default function Page({content}: PageProps): ReactElement {":"export default function Page({content}) {");break}}}appendSlotParams(e,r){if(this.nextOptions.router!=="page")return super.appendSlotParams(e,r);let n=jn.formatName(r.id,true),i=this.options.contentVariable;if(this.options.language==="jsx"){e.append(`(${i})`);return}e.append(`(${i}: ${n}Props)`);}writeSlotRendering(e,r){switch(this.nextOptions.router){case "app":super.writeSlotRendering(e,r);break;case "page":{e.write(`<${r} {...content} />`);break}}}isSlotFetchAsync(){return this.nextOptions.router==="app"}isSlotFetchBlocking(){return this.nextOptions.router==="app"}hasSuspenseBoundary(){return false}};var zn=class t extends V{constructor(e,r=[],n={}){super(e,{...n,details:n.details??r.map(i=>i.detail??i.title)}),Object.setPrototypeOf(this,t.prototype),this.problems=r;}isErrorType(e){return this.problems.some(r=>r.type===e)}isAccessDenied(e){return this.problems.some(r=>r.type==="https://croct.help/api/admin#access-denied"&&(e===void 0||r.reason===e))}};var Ko=(r=>(r.DEVELOPMENT="DEVELOPMENT",r.PRODUCTION="PRODUCTION",r))(Ko||{});(n=>{function t(i){switch(i){case "DEVELOPMENT":return "Development";case "PRODUCTION":return "Production"}}n.getLabel=t;function e(){return Object.values(n).filter(i=>typeof i=="string")}n.all=e;function r(i){let s=i.toUpperCase();if(!n.all().includes(s))throw new Error(`Invalid environment value "${i}".`);return s}n.fromValue=r;})(Ko||={});var Vi=(n=>(n.READ_RESOURCES="RESOURCE_READ_ACCESS",n.ISSUE_TOKEN="TOKEN_ISSUE",n.EXPORT_DATA="DATA_EXPORT",n))(Vi||{});(n=>{function t(i){switch(i){case "RESOURCE_READ_ACCESS":return "Read resources";case "TOKEN_ISSUE":return "Issue tokens";case "DATA_EXPORT":return "Export data"}}n.getLabel=t;function e(){return Object.values(n).filter(i=>typeof i=="string")}n.all=e;function r(i){let s=i.toUpperCase();if(!n.all().includes(s))throw new Error(`Invalid permission value "${i}".`);return s}n.fromValue=r;})(Vi||={});var JT=class t extends Us{constructor(e){super(e),this.codemod=e.codemod,this.importResolver=e.importResolver,this.userApi=e.userApi,this.applicationApi=e.applicationApi;}async createExample(e,r){return await this.isFallbackMode()?super.createExample(e,r):new wi(e.name,`/${e.slug}`)}async generateSlotExampleFiles(e,r){let[n,i,s]=await Promise.all([this.detectRouter(),this.isTypeScriptProject(),this.isFallbackMode()]),o=await this.getPaths(r.configuration),a=i?".tsx":".jsx",l=this.fileSystem.joinPaths(o.components,`%slug%${a}`),u=s||n==="page"?"index":"page",c=this.fileSystem.joinPaths(o.examples,"%slug%",`${u}${a}`),p=await this.importResolver.getImportPath(l,c),d=i?"tsx":"jsx";return (s?new cf({fileSystem:this.fileSystem,language:d,contentVariable:"content",slotImportPath:p,slotFilePath:l,slotComponentName:"%name%",pageFilePath:c,pageComponentName:"Page"}):new KT({fileSystem:this.fileSystem,router:n==="page"?"page":"app",language:d,slotImportPath:p,slotFilePath:l,slotComponentName:"%name%",pageFilePath:c,pageComponentName:"Page"})).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async getInstallationPlan(e){let{configuration:r,output:n}=e,[{i18n:i},s]=await Promise.all([this.getConfig(),this.getProjectInfo()]);s.fallbackMode&&n.announce({semantics:"warning",title:"Fallback mode",message:"Next.js SDK requires version 13 or newer, so React SDK will be installed instead."});let o=r.locales.filter(u=>i.locales.includes(u)||u===r.defaultLocale),a=o.length>0?o:i.locales,l=i.defaultLocale!==void 0&&a.includes(i.defaultLocale)?i.defaultLocale:r.defaultLocale;return {dependencies:[s.fallbackMode?"@croct/plug-react":"@croct/plug-next"],tasks:this.getInstallationTasks({...e,project:s}),configuration:{...r,locales:a,defaultLocale:l,paths:{...r.paths,examples:s.pageDirectory}}}}async getProjectInfo(){let[e,r,n,i]=await Promise.all([this.isTypeScriptProject(),this.getPageDirectory(),this.isFallbackMode(),this.packageManager.hasDirectDependency("next","<16")]),s={typescript:e,router:await this.detectRouter(r),sourceDirectory:r.startsWith("src")?"src":".",pageDirectory:r},o=i?"middleware":"proxy",[a,l]=await Promise.all([this.locateFile(...[`${o}.js`,`${o}.ts`].map(p=>this.fileSystem.joinPaths(s.sourceDirectory,p))),this.locateFile(...(s.router==="app"?[this.fileSystem.joinPaths("app","layout"),this.fileSystem.joinPaths("app","layout")]:[this.fileSystem.joinPaths("pages","_app"),this.fileSystem.joinPaths("pages","_app")]).flatMap(p=>["js","jsx","ts","tsx"].map(d=>this.fileSystem.joinPaths(s.sourceDirectory,`${p}.${d}`))))]),u=s.typescript?"ts":"js",c=this.projectDirectory.get();return {...s,fallbackMode:n,env:{localFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(c,".env.local")),developmentFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(c,".env.development")),productionFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(c,".env.production"))},proxy:{name:o,file:a??this.fileSystem.joinPaths(s.sourceDirectory,`${o}.${u}`)},provider:{file:l??(s.router==="app"?this.fileSystem.joinPaths(s.sourceDirectory,"app",`layout.${u}x`):this.fileSystem.joinPaths(s.sourceDirectory,"pages",`_app.${u}x`))}}}getInstallationTasks(e){let r=[];if(!e.project.fallbackMode){let n=e.project.proxy.name;r.push({title:`Configure ${n}`,task:async i=>{i.update(`Configuring ${n}`);try{await this.updateCode(this.codemod[n],e.project.proxy.file),i.confirm(`${t.capitalize(n)} configured`);}catch(s){i.alert(`Failed to install ${n}`,V.formatMessage(s));}}});}return r.push({title:"Configure provider",task:async n=>{n.update("Configuring provider");try{await this.installProvider({...e,notifier:n}),n.confirm("Provider configured");}catch(i){n.alert("Failed to install provider",V.formatMessage(i));}}}),r.push({title:"Setup environment variables",task:async n=>{n.update("Setting up environment variables");try{await this.updateEnvVariables({...e,notifier:n}),n.confirm("Environment variables updated");}catch(i){n.alert("Failed to update .env.local",V.formatMessage(i));}}}),r}installProvider(e){return this.updateCode(this.getProviderCodemod(e),e.project.provider.file,{typescript:e.project.typescript})}getProviderCodemod(e){return e.project.fallbackMode?this.codemod.fallbackProvider:e.project.router==="app"?this.codemod.appRouterProvider:this.codemod.pageRouterProvider}async updateCode(e,r,n){await e.apply(this.fileSystem.joinPaths(this.projectDirectory.get(),r),n);}async updateEnvVariables(e){let{project:{env:r},configuration:n,notifier:i}=e;i.update("Loading information");let[s,o]=await Promise.all([this.workspaceApi.getApplication({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:n.applications.development}),n.applications.production===void 0?null:this.workspaceApi.getApplication({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:n.applications.production})]);if(s===null)throw new Mr(`Development application \`${n.applications.development}\` not found.`,{reason:"not_found"});if(!await r.localFile.hasVariable("CROCT_API_KEY")&&e.skipApiKeySetup!==true){let a=await this.userApi.getUser();i.update("Creating API key");let l;try{l=await this.applicationApi.createApiKey({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:s.slug,name:`${a.username} CLI`,permissions:["TOKEN_ISSUE"]});}catch(u){throw u instanceof V?new Mr(u instanceof zn&&u.isAccessDenied()?"Your user does not have permission to create an API key":u.message,u.help):u}await r.localFile.setVariables({CROCT_API_KEY:l.secret});}await Promise.all([r.developmentFile.setVariables({NEXT_PUBLIC_CROCT_APP_ID:s.publicId}),o===null?Promise.resolve():r.productionFile.setVariables({NEXT_PUBLIC_CROCT_APP_ID:o.publicId})]);}async detectRouter(e){return (e??await this.getPageDirectory()).endsWith("pages")?"page":"app"}async getPageDirectory(){return await this.locateFile("app",this.fileSystem.joinPaths("src","app"),"pages",this.fileSystem.joinPaths("src","pages"))??"app"}async getConfig(){let e=["js","mjs","ts","mts"].map(n=>`next.config.${n}`),r=await this.readFile(...e).catch(()=>null);return r===null?{i18n:{locales:[],defaultLocale:""}}:bee(r)}isFallbackMode(){return this.packageManager.hasDirectDependency("next","<=13")}static capitalize(e){return e.charAt(0).toUpperCase()+e.slice(1)}};var dm=class t{constructor(e){this.options=e;}generate(e){let r=t.replaceVariables(this.options.slotFilePath,e.id),n=t.replaceVariables(this.options.slotComponentName,e.id);return {files:[this.generatePageFile(e,{name:n,path:r,importPath:t.replaceVariables(this.options.slotImportPath,e.id),definition:e}),this.generateSlotFile(e,r)]}}getLoadingFlag(){return null}generateSlotFile(e,r){let n=this.createWriter(),i=this.options.contentVariable,s=this.getLoadingFlag();return this.writeSlotScript(n,e),n.newLine(),n.write("<template>").indent(),s!==null?(n.write(`<p v-if="${s}">Loading...</p>`).write("<template v-else>").indent(),this.writeRoot(n,e.definition,i),n.outdent().write("</template>")):this.writeRoot(n,e.definition,i),n.outdent().write("</template>",false),{path:r,language:"vue",code:n.toString()}}generatePageFile(e,r){let n=this.createWriter(),i=t.replaceVariables(this.options.pageFilePath,e.id);return this.writePageScript(n,r),n.toString()!==""&&n.newLine(),n.write("<template>").indent().write(`<${r.name} />`).outdent().write("</template>",false),{path:i,language:"vue",code:n.toString()}}writeScriptOpening(e){e.write(this.options.typescript?'<script setup lang="ts">':"<script setup>");}writeScriptClosing(e){e.write("</script>");}writeRoot(e,r,n){if(r.type==="union"){this.writeUnion(e,r,n);return}e.write(`<ul v-if="${n}">`).indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");}writeFragment(e,r,n){switch(r.type){case "text":case "number":e.append(`{{ ${n} }}`);break;case "boolean":e.append(t.formatBooleanInterpolation(r,n));break;case "list":this.writeList(e,r,n);break;case "structure":e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");break;case "union":this.writeUnion(e,r,n);break}}writeList(e,r,n){let i=r.itemLabel!==void 0?Pi(r.itemLabel):"item";e.write("<ol>").indent().write(`<li v-for="(${i}, index) in ${n}" :key="index">`).indent();let s=t.isInline(r.items);s&&e.appendIndentation(),this.writeFragment(e,r.items,i),s&&e.newLine(),e.outdent().write("</li>").outdent().write("</ol>");}writeStructureAttributes(e,r,n){for(let[i,s]of qs(r.attributes))s.private!==true&&this.writeAttribute(e,{name:i,...s},n);}writeAttribute(e,r,n){let i=`${n}.${r.name}`,s=r.type,o=t.escapeEntities(r.label??_o(r.name)),a=r.optional===true?` v-if="${i}"`:"";switch(s.type){case "boolean":case "text":case "number":{e.write(`<li${a}>`,false).append(`<strong>${o}:</strong> `),this.writeFragment(e,s,i),e.append("</li>").newLine();break}default:e.write(`<li${a}>`).indent().write(`<strong>${o}</strong>`),this.writeFragment(e,s,i),e.outdent().write("</li>");break}}writeUnion(e,r,n){for(let[i,s]of Object.entries(r.types))e.write(`<template v-if="${n}?._type === '${i}'">`).indent(),this.writeFragment(e,s,n),e.outdent().write("</template>");}static formatBooleanInterpolation(e,r){let n=e.label?.true??"Yes",i=e.label?.false??"No";return `{{ ${r} ? '${n.replace(/'/g,"\\'")}' : '${i.replace(/'/g,"\\'")}' }}`}static isInline(e){return ["number","text","boolean"].includes(e.type)}static escapeEntities(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}createWriter(){return new jn(this.options.indentationSize)}static replaceVariables(e,r){return e.replace(/%name%/g,jn.formatName(r,true)).replace(/%slug%/g,Lr(r))}};var YT=class extends dm{writeSlotScript(e,r){let n=this.options.contentVariable,i=n==="data"?n:`data: ${n}`;this.writeScriptOpening(e),e.write("import {useContent} from '@croct/plug-vue';").newLine().write(`const {${i}, isLoading} = useContent('${r.id}@${r.version}');`),this.writeScriptClosing(e);}writePageScript(e,r){this.writeScriptOpening(e),e.write(`import ${r.name} from '${r.importPath}';`),this.writeScriptClosing(e);}getLoadingFlag(){return "isLoading"}};var XT=class t extends Us{constructor(e){super(e),this.codemod=e.codemod,this.bundlers=e.bundlers,this.importResolver=e.importResolver;}async generateSlotExampleFiles(e,r){let n=await this.isTypeScriptProject(),i=await this.getPaths(r.configuration),s=this.fileSystem.joinPaths(i.components,"%slug%.vue"),o=this.fileSystem.joinPaths(i.examples,"%slug%-example.vue");return new YT({typescript:n,contentVariable:"content",slotImportPath:await this.importResolver.getImportPath(s,o),slotFilePath:s,slotComponentName:"%name%",pageFilePath:o}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async getInstallationPlan(e){let{configuration:r}=e,n=await this.getProjectInfo();return {dependencies:["@croct/plug-vue"],tasks:this.getInstallationTasks({...e,project:n}),configuration:r}}async getProjectInfo(){let r=await this.getEnvVarProperty(),n=this.projectDirectory.get();return {typescript:await this.isTypeScriptProject(),sourceDirectory:"src",plugin:{file:await this.locateFile(...["main","index"].flatMap(i=>["ts","js"].map(s=>`${i}.${s}`)).map(i=>this.fileSystem.joinPaths("src",i)))},env:r===null?void 0:{property:r,productionFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(n,".env.production")),developmentFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(n,".env.development"))}}}getInstallationTasks(e){let r=[],n=e.project.env,{configuration:i}=e,s=null,o=()=>(s===null&&(s=Promise.all([this.workspaceApi.getApplication({organizationSlug:i.organization,workspaceSlug:i.workspace,applicationSlug:i.applications.development}),i.applications.production===void 0?null:this.workspaceApi.getApplication({organizationSlug:i.organization,workspaceSlug:i.workspace,applicationSlug:i.applications.production})]).then(([a,l])=>a===null?Promise.reject(new Mr(`Development application ${i.applications.development} not found`,{reason:"not_found"})):{development:a.publicId,production:l?.publicId})),s);if(n!==void 0){let{developmentFile:a,productionFile:l,property:u}=n,c=u.split(".").pop();r.push({title:"Setup environment variables",task:async p=>{p.update("Setting up environment variables");try{let d=await o();await Promise.all([a.setVariable(c,d.development),d.production===void 0?Promise.resolve():l.setVariable(c,d.production)]),p.confirm("Environment variables updated");}catch(d){p.alert("Failed to update environment variables",V.formatMessage(d));}}});}return r.push({title:"Register plugin",task:async a=>{a.update("Registering plugin");let l=e.project.plugin.file;try{l===null?a.alert("No Vue entry file found"):(await this.installPlugin(l,{args:{appId:t.getAppIdProperty(await o(),n?.property)}}),a.confirm("Plugin registered"));}catch{a.alert("Failed to register plugin","Register the Croct plugin in your Vue entry: app.use(createCroct({appId: '<your-app-id>'})) before app.mount().");}}}),r}async installPlugin(e,r){await this.codemod.plugin.apply(this.fileSystem.joinPaths(this.projectDirectory.get(),e),r);}async getEnvVarProperty(){for(let e of this.bundlers)if(await this.packageManager.hasDirectDependency(e.package))return `${e.prefix}CROCT_APP_ID`;return null}static getAppIdProperty(e,r){return r!==void 0?{type:"reference",path:r.split(".")}:e.production===void 0?{type:"literal",value:e.development}:{type:"ternary",condition:{operator:"===",left:{type:"reference",path:["import","meta","env","MODE"]},right:{type:"literal",value:"production"}},consequent:{type:"literal",value:e.production},alternate:{type:"literal",value:e.development}}}};var ZT=class extends dm{writeSlotScript(e,r){this.writeScriptOpening(e),e.write(`const {data} = await useContent('${r.id}@${r.version}');`),this.writeScriptClosing(e);}writePageScript(){}};var QT=class extends Us{constructor(e){super(e),this.codemod=e.codemod,this.userApi=e.userApi,this.applicationApi=e.applicationApi,this.commandExecutor=e.commandExecutor;}createExample(e){return Promise.resolve(new wi(e.name,`/${e.slug}`))}async generateSlotExampleFiles(e,r){let n=await this.isTypeScriptProject(),i=await this.getPaths(r.configuration),s=this.fileSystem.joinPaths(i.components,"%slug%.vue"),o=this.fileSystem.joinPaths(i.examples,"%slug%","index.vue");return new ZT({typescript:n,contentVariable:"data.content",slotImportPath:this.fileSystem.joinPaths("~",i.components,"%slug%.vue"),slotFilePath:s,slotComponentName:"%name%",pageFilePath:o}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async getInstallationPlan(e){let{configuration:r}=e,n=await this.getProjectInfo();return {dependencies:["@croct/plug-nuxt"],tasks:this.getInstallationTasks({...e,project:n}),configuration:{...r,paths:{...r.paths,examples:"pages"}}}}async getProjectInfo(){let[e,r]=await Promise.all([this.isTypeScriptProject(),this.locateNuxtConfig()]),n=this.projectDirectory.get();return {typescript:e,config:{file:r??`nuxt.config.${e?"ts":"js"}`},envFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(n,".env"))}}async locateNuxtConfig(){return this.locateFile(...["ts","js","mjs"].map(e=>`nuxt.config.${e}`))}getInstallationTasks(e){return [{title:"Register module",task:async r=>{r.update("Registering module");try{await this.applyConfigCodemod(e.project.config.file),r.confirm("Module registered");}catch{r.alert("Failed to register module","Add '@croct/plug-nuxt' to the modules array in your nuxt.config.");}}},{title:"Generate Nuxt type aliases",task:async r=>{r.update("Generating Nuxt type aliases");try{await this.generateNuxtTypeAliases(),r.confirm("Nuxt type aliases generated");}catch(n){r.alert("Failed to generate Nuxt type aliases",V.formatMessage(n));}}},{title:"Setup environment variables",task:async r=>{r.update("Setting up environment variables");try{await this.updateEnvVariables({...e,notifier:r}),r.confirm("Environment variables updated");}catch(n){r.alert("Failed to update environment variables",V.formatMessage(n));}}}]}async applyConfigCodemod(e){await this.codemod.config.apply(this.fileSystem.joinPaths(this.projectDirectory.get(),e));}async generateNuxtTypeAliases(){let e=await this.packageManager.getPackageCommand("nuxi",["prepare"]);if(await(await this.commandExecutor.run(e,{workingDirectory:this.projectDirectory.get()})).wait()!==0)throw new V(`Failed to execute command \`${e.name}\`.`)}async updateEnvVariables(e){let{project:{envFile:r},configuration:n,notifier:i}=e;i.update("Loading information");let s=await this.workspaceApi.getApplication({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:n.applications.development});if(s===null)throw new Mr(`Development application \`${n.applications.development}\` not found.`,{reason:"not_found"});if(!await r.hasVariable("NUXT_CROCT_API_KEY")&&e.skipApiKeySetup!==true){let o=await this.userApi.getUser();i.update("Creating API key");let a;try{a=await this.applicationApi.createApiKey({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:s.slug,name:`${o.username} CLI`,permissions:["TOKEN_ISSUE"]});}catch(l){throw l instanceof V?new Mr(l instanceof zn&&l.isAccessDenied()?"Your user does not have permission to create an API key":l.message,l.help):l}await r.setVariables({NUXT_CROCT_API_KEY:a.secret});}await r.setVariables({NUXT_PUBLIC_CROCT_APP_ID:s.publicId});}};var eD=class t{constructor(e){this.configuration=e;}generate(e){let{typescript:r,framework:n,routeFilePath:i,routeComponentName:s,indentationSize:o}=this.configuration,a=Lr(e.id),l=n==="react-router",u=t.replaceVariables(s,e.id),c=new jn(o);c.write("import {fetchContent} from '@croct/plug-hydrogen/server';"),c.write(`import {useLoaderData} from '${l?"react-router":"@remix-run/react"}';`),r&&c.write(l?`import type {Route} from './+types/${a}';`:"import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';"),c.newLine();let p=r?`: ${l?"Route.LoaderArgs":"LoaderFunctionArgs"}`:"";return c.write(`export async function loader({context}${p}) {`).indent().write(`const {content} = await fetchContent('${a}', {scope: context});`).newLine().write("return {content};").outdent().write("}"),c.newLine(),c.write(`export default function ${u}() {`).indent().write(`const {content} = useLoaderData${r?"<typeof loader>":""}();`).newLine().write("return (").indent(),Ju.renderComponentSnippet(c,e.definition,"content"),c.outdent().write(");").outdent().write("}"),{files:[{path:t.replaceVariables(i,e.id),language:r?"tsx":"jsx",code:c.toString()}]}}static replaceVariables(e,r){return e.replace(/%name%/g,jn.formatName(r,true)).replace(/%slug%/g,Lr(r))}};var fm=me(we()),See=me(Jt());function Eee(t,e){let r=typeof t=="string"?Ho(t,["jsx","typescript"]):t,n=null;return (0, See.traverse)(r,{ImportDeclaration:i=>{for(let s of i.node.specifiers)if(Hrt(Grt(s),e))return n=i.node.source.value,i.stop();return i.skip()}}),n}function Grt(t){return fm.isImportDefaultSpecifier(t)?"default":fm.isImportNamespaceSpecifier(t)?"*":fm.isIdentifier(t.imported)?t.imported.name:t.imported.value}function Hrt(t,e){return typeof e=="string"?t===e:e.test(t)}var tD=class extends Us{constructor(e){super(e),this.codemod=e.codemod,this.userApi=e.userApi,this.applicationApi=e.applicationApi,this.importResolver=e.importResolver;}getPaths(e){return Promise.resolve({...e.paths,source:e.paths?.source??"app",utilities:e.paths?.utilities??"app/lib",components:e.paths?.components??"app/components",examples:e.paths?.examples??"app/routes"})}createExample(e){return Promise.resolve(new wi(e.name,`/${e.slug}`))}async generateSlotExampleFiles(e,r){let[n,i]=await Promise.all([this.isTypeScriptProject(),this.detectFramework()]),s=await this.getPaths(r.configuration);return new eD({typescript:n,framework:i,routeFilePath:this.fileSystem.joinPaths(s.examples,`%slug%${n?".tsx":".jsx"}`),routeComponentName:"%name%Route"}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async getInstallationPlan(e){let{configuration:r}=e,n=await this.getProjectInfo();return {dependencies:["@croct/plug-hydrogen"],tasks:this.getInstallationTasks({...e,project:n}),configuration:r}}async getProjectInfo(){let e=this.projectDirectory.get(),[r,n,i,s,o]=await Promise.all([this.detectFramework(),this.locateFile("vite.config.ts","vite.config.mts","vite.config.cts","vite.config.js","vite.config.mjs","vite.config.cjs"),this.locateFile("server.ts","server.js"),this.locateFile("app/root.tsx","app/root.jsx"),this.locateFile("app/entry.server.tsx","app/entry.server.jsx")]),a=await this.locateContext(i);return {framework:r,viteConfig:n,server:i,root:s,context:a,entryServer:o,envFile:new Ai(this.fileSystem,this.fileSystem.joinPaths(e,".env"))}}async detectFramework(){let[e,r]=await Promise.all([this.packageManager.hasDirectDependency("@shopify/hydrogen",">=2025.5.0"),this.packageManager.hasDirectDependency("react-router")]);return e||r?"react-router":"remix"}async locateContext(e){let r=e!==null?await this.followContextImport(e):null;return r!==null?r:this.locateFile("app/lib/context.ts","app/lib/context.tsx","app/lib/context.js","app/lib/context.jsx")}async followContextImport(e){let r=await this.readFile(e);if(r===null)return null;let n=Eee(r,/^create[A-Za-z]*Context$/);return n!==null?this.importResolver.resolveImport(n,e):null}getInstallationTasks(e){let{project:r}=e;return [{title:"Set up environment variables",task:async n=>{n.update("Setting up environment variables");try{await this.updateEnvVariables(e),n.confirm("Environment variables updated");}catch(i){n.alert("Failed to update environment variables",V.formatMessage(i));}}},this.getCodemodTask({title:"Register Vite plugin",confirmation:"Vite plugin registered",codemod:"vite",file:r.viteConfig,instructions:"Add the `croct()` plugin to the `plugins` array in your Vite config."}),r.framework==="react-router"?this.getCodemodTask({title:"Register middleware",confirmation:"Middleware registered",codemod:"middleware",file:r.root,instructions:"Add `createCroctMiddleware()` to the `middleware` array exported from app/root."}):this.getCodemodTask({title:"Expose Croct context",confirmation:"Croct context exposed",codemod:"context",file:r.context,instructions:"Add `croct: await createCroctContext(request, context)` to the load context."}),this.getCodemodTask({title:"Configure Croct cookies",confirmation:"Croct cookies configured",codemod:"cookies",file:r.server,instructions:"Call `writeCroctCookies(response, context)` after the session commits in server.ts."}),this.getCodemodTask({title:"Configure provider",confirmation:"Provider configured",codemod:"provider",file:r.root,instructions:"Wrap your app with `<CroctProvider>` in app/root."}),this.getCodemodTask({title:"Configure content security policy",confirmation:"Content security policy configured",codemod:"csp",file:r.entryServer,instructions:"Add `https://api.croct.io` to `connectSrc` in your content security policy."})]}getCodemodTask(e){let{title:r,confirmation:n,codemod:i,file:s,instructions:o}=e,a=`${r.charAt(0).toLowerCase()}${r.slice(1)}`;return {title:r,task:async l=>{if(l.update(r),s===null){l.alert(`Failed to ${a}`,o);return}try{await this.applyCodemod(this.codemod[i],s),l.confirm(n);}catch{l.alert(`Failed to ${a}`,o);}}}}async applyCodemod(e,r){await e.apply(this.fileSystem.joinPaths(this.projectDirectory.get(),r));}async updateEnvVariables(e){let{project:{envFile:r},configuration:n}=e,i=await this.workspaceApi.getApplication({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:n.applications.development});if(i===null)throw new Mr(`Development application \`${n.applications.development}\` not found.`,{reason:"not_found"});if(!await r.hasVariable("CROCT_API_KEY")&&e.skipApiKeySetup!==true){let s=await this.userApi.getUser(),o;try{o=await this.applicationApi.createApiKey({organizationSlug:n.organization,workspaceSlug:n.workspace,applicationSlug:i.slug,name:`${s.username} CLI`,permissions:["TOKEN_ISSUE"]});}catch(a){throw a instanceof V?new Mr(a instanceof zn&&a.isAccessDenied()?"Your user does not have permission to create an API key":a.message,a.help):a}await r.setVariables({CROCT_API_KEY:o.secret});}await r.setVariables({PUBLIC_CROCT_APP_ID:i.publicId});}};var gl=class t{static{this.PHPSTAN_EXTENSION="vendor/croct/plug-php/extension.neon";}static{this.INTEGRATIONS=[{detect:"storyblok/php-content-api-client",install:"croct/plug-storyblok"}];}constructor(e){this.projectDirectory=e.projectDirectory,this.packageManager=e.packageManager,this.fileSystem=e.fileSystem,this.formatter=e.formatter,this.commandExecutor=e.commandExecutor,this.exampleLauncher=e.exampleLauncher,this.phpstanIncludeCodemod=e.phpstanIncludeCodemod,this.contentLoader=e.contentLoader,this.workspaceApi=e.workspaceApi,this.userApi=e.userApi,this.applicationApi=e.applicationApi;}async setup(e){let{input:r,output:n}=e,i=await this.getInstallationPlan(e),s=[...i.dependencies,...await this.getIntegrationDependencies()],o={...i.configuration,paths:{content:".",...await this.getPaths(e.configuration),...i.configuration.paths}},a={...e,configuration:{...e.configuration,...o,applications:e.configuration.applications}},l=[];l.push({title:"Install dependencies",task:async p=>{p.update("Installing dependencies");let d=new Ci({status:"Installing dependencies",notifier:p});try{await this.packageManager.addDependencies(s,{logger:d}),p.confirm("Dependencies installed");}catch(f){p.alert("Failed to install dependencies",V.formatMessage(f));}}}),l.push(...i.tasks);let u=await this.packageManager.hasDependency("phpstan/phpstan"),c=await this.packageManager.hasDependency("phpstan/extension-installer");if(u&&!c&&l.push(this.getPhpstanTask()),await this.packageManager.hasDependency("vimeo/psalm")&&l.push(this.getPsalmTask()),l.push({title:"Set up credentials",task:async p=>{p.update("Setting up credentials");try{await this.setUpCredentials({...a,notifier:p}),p.confirm("Credentials configured");}catch(d){p.alert("Failed to set up credentials",V.formatMessage(d));}}}),l.push({title:"Download content",task:async p=>{p.update("Downloading content");try{await this.contentLoader.downloadContent(a.configuration,!0),p.confirm("Content downloaded");}catch(d){p.alert("Failed to download content",V.formatMessage(d));}}}),l.push({title:"Generate types",task:async p=>{p.update("Generating types");try{await this.updateTypes(a,{clean:!0}),p.confirm("Types generated");}catch(d){p.alert("Failed to generate types",V.formatMessage(d));}}}),r!==void 0){n.break(),n.inform("**Installation plan**");for(let{title:p}of l)n.log(` - ${p}`);if(n.break(),!await r.confirm({message:"Proceed?",default:true}))return n.exit()}return await n.monitor({tasks:l}),o}getPaths(e){let r=e.paths?.source??"src";return Promise.resolve({...e.paths,source:r,utilities:e.paths?.utilities??`${r}/utils`,components:e.paths?.components??`${r}/components`,examples:e.paths?.examples??"examples"})}async update(e,r={}){await this.contentLoader.downloadContent(e.configuration,r.clean===true),await this.updateTypes(e,r);}async updateTypes(e,r){let{configuration:n}=e,i=this.fileSystem.joinPaths(this.projectDirectory.get(),n.paths?.content??".","slots.stub");if(r.clean!==true&&await this.fileSystem.exists(i)||Object.keys(n.slots).length===0&&Object.keys(n.components).length===0)return;let s=await this.contentLoader.loadTypes(n,"PLUG_PHP");await this.fileSystem.createDirectory(this.fileSystem.getDirectoryName(i),{recursive:true}),await this.fileSystem.writeTextFile(i,s,{overwrite:true});}async generateSlotExample(e,r){let n=this.projectDirectory.get(),i=[];for(let s of await this.generateSlotExampleFiles(e,r)){let o=this.fileSystem.joinPaths(n,this.fileSystem.getDirectoryName(s.path));await this.fileSystem.createDirectory(o,{recursive:true}).catch(()=>null);let a=this.fileSystem.joinPaths(n,s.path);await this.fileSystem.writeTextFile(a,s.code,{overwrite:true}),s.language==="php"&&i.push(a);}i.length>0&&await this.formatter.format(i);}async presentExamples(e,r){await this.exampleLauncher.launch({examples:await Promise.all(e.map(n=>this.createExample(n,r))),input:r.input,output:r.output});}async getIntegrationDependencies(){let e=await Promise.all(t.INTEGRATIONS.map(r=>this.packageManager.hasDependency(r.detect)));return t.INTEGRATIONS.filter((r,n)=>e[n]).map(r=>r.install)}getPhpstanTask(){let e=`Add \`${t.PHPSTAN_EXTENSION}\` to your PHPStan \`includes\`.`;return {title:"Enable PHPStan extension",task:async r=>{r.update("Enabling PHPStan extension");let n=await this.findPhpstanConfig()??this.fileSystem.joinPaths(this.projectDirectory.get(),"phpstan.neon");try{let{modified:i}=await this.phpstanIncludeCodemod.apply(n,{key:"includes",value:t.PHPSTAN_EXTENSION});r.confirm(i?"PHPStan extension enabled":"PHPStan extension already enabled");}catch{r.warn("Failed to enable the PHPStan extension",e);}}}}getPsalmTask(){let e="Run `vendor/bin/psalm-plugin enable croct/plug-php` to enable the Croct plugin.";return {title:"Enable Psalm plugin",task:async r=>{r.update("Enabling Psalm plugin");try{let n=await this.packageManager.getPackageCommand("psalm-plugin",["enable","croct/plug-php"]),s=await(await this.commandExecutor.run(n,{workingDirectory:this.projectDirectory.get()})).wait();s===0||s===3?r.confirm("Psalm plugin enabled"):r.warn("Failed to enable the Psalm plugin",e);}catch{r.warn("Failed to enable the Psalm plugin",e);}}}}async findPhpstanConfig(){let e=this.projectDirectory.get(),r=["phpstan.neon","phpstan.neon.dist","phpstan.dist.neon"].map(i=>this.fileSystem.joinPaths(e,i)),n=await Promise.all(r.map(i=>this.fileSystem.exists(i)));for(let i=0;i<n.length;i++)if(n[i])return r[i];return null}async setUpCredentials(e){let{configuration:r,notifier:n}=e;n.update("Loading information");let i=await this.workspaceApi.getApplication({organizationSlug:r.organization,workspaceSlug:r.workspace,applicationSlug:r.applications.development});if(i===null)throw new Mr(`Development application \`${r.applications.development}\` not found.`,{reason:"not_found"});if(!await this.hasApiKey()&&e.skipApiKeySetup!==true){let s=await this.userApi.getUser();n.update("Creating API key");let o;try{o=await this.applicationApi.createApiKey({organizationSlug:r.organization,workspaceSlug:r.workspace,applicationSlug:i.slug,name:`${s.username} CLI`,permissions:["TOKEN_ISSUE"]});}catch(a){throw a instanceof V?new Mr(a instanceof zn&&a.isAccessDenied()?"Your user does not have permission to create an API key":a.message,a.help):a}await this.storeApiKey(o.secret);}await this.storeAppId(i.publicId);}hasApiKey(){return this.getEnvFile().hasVariable("CROCT_API_KEY")}async storeApiKey(e){await this.getEnvFile().setVariables({CROCT_API_KEY:e});}async storeAppId(e){await this.getEnvFile().setVariables({CROCT_APP_ID:e});}getEnvFile(){return new Ai(this.fileSystem,this.fileSystem.joinPaths(this.projectDirectory.get(),".env"))}};var rD=class t{constructor(e){this.options=e;}generate(e){let r=t.replaceVariables(this.options.filePath,e.id),n=new jn(this.options.indentationSize),i=`$${this.options.contentVariable}`,s=t.escapeEntities(t.formatTitle(e.id));return this.writeScript(n,e),n.newLine().write("<!doctype html>").write('<html lang="en">').write("<head>").indent().write('<meta charset="utf-8">').write(`<title>${s}</title>`).outdent().write("</head>").write("<body>").indent(),this.writeRoot(n,e.definition,i),n.newLine(),this.writeHandoff(n),n.outdent().write("</body>").write("</html>",false),{files:[{path:r,language:"php",code:n.toString()}]}}writeHandoff(e){e.write('<script src="https://cdn.croct.io/js/v1/lib/plug.js"></script>').write("<script>").indent().write("croct.plug(<?= json_encode($croct->getPlugOptions()) ?>);").outdent().write("</script>");}writeRoot(e,r,n){if(r.type==="union"){this.writeUnion(e,r,n);return}e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");}writeStructureAttributes(e,r,n){for(let[i,s]of qs(r.attributes))s.private!==true&&this.writeAttribute(e,{name:i,...s},n);}writeAttribute(e,r,n){let i=`${n}['${r.name}']`,s=r.type,o=t.escapeEntities(r.label??_o(r.name)),a=r.optional===true;switch(a&&e.write(`<?php if (isset(${i})): ?>`).indent(),s.type){case "boolean":case "text":case "number":e.write(`<li><strong>${o}:</strong> `,false),this.writeFragment(e,s,i),e.append("</li>").newLine();break;default:e.write("<li>").indent().write(`<strong>${o}</strong>`),this.writeFragment(e,s,i),e.outdent().write("</li>");break}a&&e.outdent().write("<?php endif; ?>");}writeFragment(e,r,n){switch(r.type){case "text":e.append(`<?= htmlspecialchars(${n}) ?>`);break;case "number":e.append(`<?= ${n} ?>`);break;case "boolean":e.append(t.formatBoolean(r,n));break;case "list":this.writeList(e,r,n);break;case "structure":e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");break;case "union":this.writeUnion(e,r,n);break}}writeList(e,r,n){let s=`$${r.itemLabel!==void 0?Pi(r.itemLabel):"item"}`;e.write("<ol>").indent().write(`<?php foreach (${n} as ${s}): ?>`).indent(),t.isInline(r.items)?(e.write("<li>",false),this.writeFragment(e,r.items,s),e.append("</li>").newLine()):(e.write("<li>").indent(),this.writeFragment(e,r.items,s),e.outdent().write("</li>")),e.outdent().write("<?php endforeach; ?>").outdent().write("</ol>");}writeUnion(e,r,n){for(let[i,s]of Object.entries(r.types))e.write(`<?php if (${n}['_type'] === '${t.escapeString(i)}'): ?>`).indent(),this.writeFragment(e,s,n),e.outdent().write("<?php endif; ?>");}static formatBoolean(e,r){let n=t.escapeString(e.label?.true??"Yes"),i=t.escapeString(e.label?.false??"No");return `<?= ${r} ? '${n}' : '${i}' ?>`}static isInline(e){return ["number","text","boolean"].includes(e.type)}static escapeString(e){return e.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}static escapeEntities(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}static formatTitle(e){return Lr(e).split("-").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join(" ")}static replaceVariables(e,r){return e.replace(/%slug%/g,Lr(r))}};var nD=class t extends rD{constructor(e){super(e),this.autoloadPath=e.autoloadPath;}writeScript(e,r){let n=t.escapeString(r.id),i=this.autoloadPath.replace(/[\\/]?vendor[\\/]autoload\.php$/,"")||".";e.write("<?php").newLine().write("declare(strict_types=1);").newLine().write("use Croct\\Plug\\Croct;").newLine().write(`require __DIR__ . '/${this.autoloadPath}';`).newLine().write(`$croct = Croct::fromDotenv(__DIR__ . '/${i}');`).newLine().write(`$${this.options.contentVariable} = $croct->fetchContent('${n}')->getContent();`).newLine().write("Croct::emitCookies();").newLine().write("?>",false);}};var iD=class t extends gl{getInstallationPlan(e){return Promise.resolve({dependencies:["croct/plug-php","psr/http-client-implementation","psr/http-factory-implementation","psr/http-message-implementation"],tasks:[],configuration:e.configuration})}getIntegrationDependencies(){return Promise.resolve([])}async generateSlotExampleFiles(e,r){let n=await this.getPaths(r.configuration);return new nD({contentVariable:"content",filePath:this.fileSystem.joinPaths(n.examples,"%slug%.php"),autoloadPath:this.resolveAutoloadPath(n.examples)}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files}async createExample(e,r){let{examples:n}=await this.getPaths(r.configuration);return new wi(e.name,t.resolveExampleUrl(n,e.slug))}resolveAutoloadPath(e){let r=this.projectDirectory.get(),n=this.fileSystem.joinPaths(r,e),i=this.fileSystem.getRelativePath(n,r);return this.fileSystem.joinPaths(i,"vendor","autoload.php").replace(/\\/g,"/")}static resolveExampleUrl(e,r){return `/${e}/${Lr(r)}.php`}};var sD=class t{constructor(e){this.options=e;}generate(e){let r=t.replaceVariables(this.options.filePath,e.id),n=new jn(this.options.indentationSize),i=`$${this.options.contentVariable}`,s=t.escapeEntities(t.formatTitle(e.id));return n.write("<!doctype html>").write('<html lang="en">').write("<head>").indent().write('<meta charset="utf-8">').write(`<title>${s}</title>`).outdent().write("</head>").write("<body>").indent(),this.writeRoot(n,e.definition,i),n.outdent().write("</body>").write("</html>",false),{files:[{path:r,language:"blade",code:n.toString()}]}}writeRoot(e,r,n){if(r.type==="union"){this.writeUnion(e,r,n);return}e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");}writeStructureAttributes(e,r,n){for(let[i,s]of qs(r.attributes))s.private!==true&&this.writeAttribute(e,{name:i,...s},n);}writeAttribute(e,r,n){let i=`${n}['${r.name}']`,s=r.type,o=t.escapeEntities(r.label??_o(r.name)),a=r.optional===true;switch(a&&e.write(`@isset(${i})`).indent(),s.type){case "boolean":case "text":case "number":e.write(`<li><strong>${o}:</strong> `,false),this.writeFragment(e,s,i),e.append("</li>").newLine();break;default:e.write("<li>").indent().write(`<strong>${o}</strong>`),this.writeFragment(e,s,i),e.outdent().write("</li>");break}a&&e.outdent().write("@endisset");}writeFragment(e,r,n){switch(r.type){case "text":case "number":e.append(`{{ ${n} }}`);break;case "boolean":e.append(t.formatBoolean(r,n));break;case "list":this.writeList(e,r,n);break;case "structure":e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");break;case "union":this.writeUnion(e,r,n);break}}writeList(e,r,n){let s=`$${r.itemLabel!==void 0?Pi(r.itemLabel):"item"}`;e.write("<ol>").indent().write(`@foreach (${n} as ${s})`).indent(),t.isInline(r.items)?(e.write("<li>",false),this.writeFragment(e,r.items,s),e.append("</li>").newLine()):(e.write("<li>").indent(),this.writeFragment(e,r.items,s),e.outdent().write("</li>")),e.outdent().write("@endforeach").outdent().write("</ol>");}writeUnion(e,r,n){for(let[i,s]of Object.entries(r.types))e.write(`@if (${n}['_type'] === '${t.escapeString(i)}')`).indent(),this.writeFragment(e,s,n),e.outdent().write("@endif");}static formatBoolean(e,r){let n=t.escapeString(e.label?.true??"Yes"),i=t.escapeString(e.label?.false??"No");return `{{ ${r} ? '${n}' : '${i}' }}`}static isInline(e){return ["number","text","boolean"].includes(e.type)}static escapeString(e){return e.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}static escapeEntities(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}static formatTitle(e){return Lr(e).split("-").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join(" ")}static replaceVariables(e,r){return e.replace(/%slug%/g,Lr(r))}};var oD=class t extends gl{static{this.VIEWS_DIRECTORY="resources/views";}constructor(e){super(e),this.routeCodemod=e.routeCodemod;}getInstallationPlan(e){return Promise.resolve({dependencies:["croct/plug-laravel"],tasks:[],configuration:e.configuration})}getPaths(e){return Promise.resolve({...e.paths,source:e.paths?.source??"app",utilities:e.paths?.utilities??"app/Support",components:e.paths?.components??"app/View/Components",examples:e.paths?.examples??`${t.VIEWS_DIRECTORY}/croct`})}async generateSlotExampleFiles(e,r){let n=await this.getPaths(r.configuration),i=new sD({contentVariable:"content",filePath:this.fileSystem.joinPaths(n.examples,"%slug%.blade.php")}),{files:s}=i.generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}),o=await this.generateRouteFile(e.slug,this.resolveViewName(n.examples,e.slug));return o!==null?[...s,o]:s}createExample(e){return Promise.resolve(new wi(e.name,t.resolveExampleUrl(e.slug)))}async generateRouteFile(e,r){let n=this.fileSystem.joinPaths("routes","web.php"),i=this.fileSystem.joinPaths(this.projectDirectory.get(),n),s=await this.fileSystem.exists(i)?await this.fileSystem.readTextFile(i):"",{modified:o,result:a}=await this.routeCodemod.apply(s,{slot:e,url:t.resolveExampleUrl(e),view:r});return o?{path:n,code:a,language:"php"}:null}resolveViewName(e,r){let n=this.projectDirectory.get();return [...this.fileSystem.getRelativePath(this.fileSystem.joinPaths(n,t.VIEWS_DIRECTORY),this.fileSystem.joinPaths(n,e)).split(/[\\/]/),Lr(r)].filter(s=>s!==""&&s!==".").join(".")}static resolveExampleUrl(e){return `/${Lr(e)}`}};var mm=class t{constructor(e){this.options=e;}generate(e){let r=t.replaceVariables(this.options.filePath,e.id),n=new jn(this.options.indentationSize),i=this.options.contentVariable;if(this.options.page===false)this.writeRoot(n,e.definition,i);else {let s=t.escapeEntities(t.formatTitle(e.id));n.write("<!doctype html>").write('<html lang="en">').write("<head>").indent().write('<meta charset="utf-8">').write(`<title>${s}</title>`).outdent().write("</head>").write("<body>").indent(),this.writeRoot(n,e.definition,i),n.outdent().write("</body>").write("</html>",false);}return {files:[{path:r,language:"twig",code:n.toString()}]}}writeRoot(e,r,n){if(r.type==="union"){this.writeUnion(e,r,n);return}e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");}writeStructureAttributes(e,r,n){for(let[i,s]of qs(r.attributes))s.private!==true&&this.writeAttribute(e,{name:i,...s},n);}writeAttribute(e,r,n){let i=`${n}.${r.name}`,s=r.type,o=t.escapeEntities(r.label??_o(r.name)),a=r.optional===true;switch(a&&e.write(`{% if ${i} is defined %}`).indent(),s.type){case "boolean":case "text":case "number":e.write(`<li><strong>${o}:</strong> `,false),this.writeFragment(e,s,i),e.append("</li>").newLine();break;default:e.write("<li>").indent().write(`<strong>${o}</strong>`),this.writeFragment(e,s,i),e.outdent().write("</li>");break}a&&e.outdent().write("{% endif %}");}writeFragment(e,r,n){switch(r.type){case "text":case "number":e.append(`{{ ${n} }}`);break;case "boolean":e.append(t.formatBoolean(r,n));break;case "list":this.writeList(e,r,n);break;case "structure":e.write("<ul>").indent(),this.writeStructureAttributes(e,r,n),e.outdent().write("</ul>");break;case "union":this.writeUnion(e,r,n);break}}writeList(e,r,n){let i=r.itemLabel!==void 0?Pi(r.itemLabel):"item";e.write("<ol>").indent().write(`{% for ${i} in ${n} %}`).indent(),t.isInline(r.items)?(e.write("<li>",false),this.writeFragment(e,r.items,i),e.append("</li>").newLine()):(e.write("<li>").indent(),this.writeFragment(e,r.items,i),e.outdent().write("</li>")),e.outdent().write("{% endfor %}").outdent().write("</ol>");}writeUnion(e,r,n){for(let[i,s]of Object.entries(r.types))e.write(`{% if ${n}._type == '${t.escapeString(i)}' %}`).indent(),this.writeFragment(e,s,n),e.outdent().write("{% endif %}");}static formatBoolean(e,r){let n=t.escapeString(e.label?.true??"Yes"),i=t.escapeString(e.label?.false??"No");return `{{ ${r} ? '${n}' : '${i}' }}`}static isInline(e){return ["number","text","boolean"].includes(e.type)}static escapeString(e){return e.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}static escapeEntities(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}static formatTitle(e){return Lr(e).split("-").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join(" ")}static replaceVariables(e,r){return e.replace(/%slug%/g,Lr(r))}};var aD=class t extends gl{static{this.TEMPLATES_DIRECTORY="templates";}constructor(e){super(e),this.bundleCodemod=e.bundleCodemod,this.configCodemod=e.configCodemod;}getInstallationPlan(e){return Promise.resolve({dependencies:["croct/plug-symfony","symfony/twig-bundle"],tasks:[{title:"Register bundle",task:async r=>{r.update("Registering bundle");try{r.confirm(await this.registerBundle()?"Bundle registered":"Bundle already registered");}catch{r.alert("Failed to register bundle","Add Croct\\Plug\\Symfony\\CroctBundle::class => ['all' => true] to the array in config/bundles.php.");}}},{title:"Configure bundle",task:async r=>{r.update("Configuring bundle");try{r.confirm(await this.configureBundle()?"Bundle configured":"Bundle already configured");}catch(n){r.alert("Failed to configure bundle",V.formatMessage(n));}}}],configuration:e.configuration})}async getPaths(e){return {...await super.getPaths(e),examples:e.paths?.examples??`${t.TEMPLATES_DIRECTORY}/croct`}}async generateSlotExampleFiles(e,r){let n=await this.getPaths(r.configuration);return [...new mm({contentVariable:"content",filePath:this.fileSystem.joinPaths(n.examples,"%slug%.html.twig")}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files,this.generateController(e.slug,n)]}createExample(e){return Promise.resolve(new wi(e.name,t.resolveExampleUrl(e.slug)))}generateController(e,r){let n=Pi(e).replace(/^./,a=>a.toUpperCase()),i=`croct_${Lr(e).replace(/-/g,"_")}`,s=this.resolveTemplateReference(r.examples,e),o=["<?php","","declare(strict_types=1);","","namespace App\\Controller;","","use Croct\\Plug\\Plug;","use Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController;","use Symfony\\Component\\HttpFoundation\\Response;","use Symfony\\Component\\Routing\\Attribute\\Route;","",`final class Croct${n}Controller extends AbstractController`,"{",` #[Route('${t.resolveExampleUrl(e)}', name: '${i}')]`," public function __invoke(Plug $croct): Response"," {",` return $this->render('${s}', [`,` 'content' => $croct->fetchContent('${e}')->getContent(),`," ]);"," }","}",""].join(`
744
744
  `);return {path:this.fileSystem.joinPaths(r.source,"Controller",`Croct${n}Controller.php`),language:"php",code:o}}resolveTemplateReference(e,r){let n=this.projectDirectory.get();return [...this.fileSystem.getRelativePath(this.fileSystem.joinPaths(n,t.TEMPLATES_DIRECTORY),this.fileSystem.joinPaths(n,e)).split(/[\\/]/),`${Lr(r)}.html.twig`].filter(s=>s!==""&&s!==".").join("/")}async registerBundle(){let e=this.fileSystem.joinPaths(this.projectDirectory.get(),"config","bundles.php");return (await this.bundleCodemod.apply(e)).modified}async configureBundle(){let e=this.fileSystem.joinPaths(this.projectDirectory.get(),"config","packages","croct.yaml");return (await this.configCodemod.apply(e,{key:"croct",entries:{app_id:"'%env(CROCT_APP_ID)%'",api_key:"'%env(CROCT_API_KEY)%'"}})).modified}static resolveExampleUrl(e){return `/${Lr(e)}`}};var _g=class t extends gl{static{this.MODULE_NAME="croct_example";}static{this.LOCAL_SETTINGS_FILE="settings.local.php";}static{this.SETTINGS={APP_ID:"croct.app_id",API_KEY:"croct.api_key"};}constructor(e){super(e),this.localSettingsFileCodemod=e.localSettingsFileCodemod;}getInstallationPlan(e){let r=[this.getModuleTask(),this.getLocalSettingsTask()];return Promise.resolve({dependencies:["croct/plug-drupal"],tasks:r,configuration:e.configuration})}getModuleTask(){return {title:"Enable the Croct module (`drush en croct`)",task:async e=>{e.update("Enabling the Croct module with `drush en croct`"),await this.enableModule()?e.confirm("Croct module enabled"):e.warn("Could not enable the Croct module","Run `drush en croct` to enable it manually.");}}}getLocalSettingsTask(){let e="Add the `settings.local.php` include to `settings.php` so Croct can read the credentials.";return {title:"Include settings.local.php in settings.php",task:async r=>{switch(r.update("Adding the `settings.local.php` include to `settings.php`"),await this.includeLocalSettings()){case "included":return r.confirm("Added the `settings.local.php` include to `settings.php`");case "unchanged":return r.confirm("`settings.php` already includes `settings.local.php`");case "failed":return r.alert("Could not include the local settings",e);default:return r.warn("Could not include the local settings",e)}}}}async getPaths(e){let r=await this.resolveModulesDirectory();return {...e.paths,source:e.paths?.source??r,utilities:e.paths?.utilities??r,components:e.paths?.components??r,examples:e.paths?.examples??this.fileSystem.joinPaths(r,t.MODULE_NAME)}}async generateSlotExampleFiles(e,r){let n=(await this.getPaths(r.configuration)).examples;return [this.generateModuleInfo(n),this.generateInstallHook(n),this.generateBlock(e,n)]}async presentExamples(e,r){let{input:n,output:i}=r;if(n===void 0){t.printExampleSteps(i);return}if(!await n.confirm({message:"Enable the Croct example module now? It places the example block(s) in the Content region.",default:true})){t.printExampleSteps(i);return}let o=i.notify("Enabling the Croct example module");if(!await this.enableExampleModule()){o.stop(),i.warn("Could not enable the Croct example module."),t.printExampleSteps(i);return}o.confirm("Croct example module enabled"),await this.exampleLauncher.launch({examples:[await this.createExample(e[0])],input:n,output:i});}createExample(e){return Promise.resolve(new wi(e.name,"/"))}async setUpCredentials(e){await super.setUpCredentials(e),e.notifier.update("Rebuilding the Drupal cache to apply the credentials"),await this.rebuildCache()||e.notifier.warn("Could not rebuild the Drupal cache","Run `drush cr` to apply the Croct credentials.");}async hasApiKey(){let e=await this.resolveLocalSettingsFile();return e===null||!await this.fileSystem.exists(e)?false:(await this.fileSystem.readTextFile(e)).includes(`$settings['${t.SETTINGS.API_KEY}']`)}async storeApiKey(e){await this.writeSetting(t.SETTINGS.API_KEY,e);}async storeAppId(e){await this.writeSetting(t.SETTINGS.APP_ID,e);}generateModuleInfo(e){return {path:this.fileSystem.joinPaths(e,`${t.MODULE_NAME}.info.yml`),language:"yaml",code:["name: 'Croct Example'","type: module","description: 'Example blocks rendering Croct slots.'","package: Croct","core_version_requirement: ^10 || ^11","dependencies:"," - 'croct:croct'",""].join(`
745
745
  `)}}generateInstallHook(e){let r=t.MODULE_NAME;return {path:this.fileSystem.joinPaths(e,`${r}.install`),language:"php",code:["<?php","","declare(strict_types=1);","","use Drupal\\block\\Entity\\Block;","","/**"," * Implements hook_install()."," *"," * Places the example blocks in the default theme's content region."," */",`function ${r}_install(): void`,"{"," $theme = \\Drupal::config('system.theme')->get('default');"," $manager = \\Drupal::service('plugin.manager.block');",""," foreach ($manager->getDefinitions() as $id => $definition) {",` if (($definition['provider'] ?? '') !== '${r}') {`," continue;"," }",""," $blockId = $theme . '_' . $id;",""," if (Block::load($blockId) !== null) {"," continue;"," }",""," Block::create(["," 'id' => $blockId,"," 'plugin' => $id,"," 'region' => 'content',"," 'theme' => $theme,"," 'weight' => -50,"," 'settings' => ["," 'id' => $id,"," 'label' => (string) $definition['admin_label'],"," 'label_display' => '0',",` 'provider' => '${r}',`," ],"," ])->save();"," }","}",""].join(`
746
746
  `)}}generateBlock(e,r){let n=Pi(e.slug).replace(/^./,u=>u.toUpperCase()),i=`croct_${Lr(e.slug).replace(/-/g,"_")}`,s=t.formatTitle(e.slug).replace(/\\/g,"\\\\").replace(/'/g,"\\'"),a=new mm({contentVariable:"content",filePath:"",page:false}).generate({id:e.slug,version:e.version.major,definition:e.resolvedDefinition}).files[0].code.trimEnd().split(`
@@ -2541,4 +2541,4 @@ tell application "System Events" to get value of property list item "CFBundleNam
2541
2541
  `);return new V(`${e.message}
2542
2542
 
2543
2543
  \u25B6\uFE0F **Trace**
2544
- ${r}`,e.help)}break;case e instanceof Fa:return new V(e.message,{...e.help,suggestions:["Run `init` to create a new configuration."]})}return e}static getSourceLocation(e){return e.url.protocol==="file:"?`${e.url}:${e.start.line}:${e.start.column}`:e.url.hostname==="github.com"?`${e.url}#L${e.start.line}-L${e.end.line}`:`${e.url}#${e.start.line}:${e.start.column}-${e.end.line}:${e.end.column}`}};var B8={version:"0.16.0"};function bfe(t){let e=new lq().name("croct").description("Manage your Croct projects").enablePositionalOptions().option("--cwd <path>","The working directory.",v=>{try{return realpathSync(v)}catch{throw new ua("The path does not exist.")}}).addOption(new vi("--api-key <key>","The API key to use for authentication.").env("CROCT_API_KEY").argParser(v=>{try{return cq.parse(v)}catch{throw new ua("The API key is malformed.")}}).conflicts("token")).addOption(new vi("--token <token>","The JWT-formatted token to use for authentication.").env("CROCT_TOKEN").argParser(v=>{let T;try{T=Hc.parse(v);}catch{throw new ua("The token is malformed.")}if(!T.isValidNow())throw new ua("The token is expired.");return T})).option("--registry <url>","The template registry.",v=>{if(!URL.canParse(v))throw new ua("Malformed URL.");return v}).option("--no-interaction","Run the CLI in non-interactive mode.").option("--config <path>","Path to the configuration file.").addOption(new vi("--stateless","Run the CLI without saving any state locally.").env("CROCT_STATELESS").default(false)).addOption(new vi("--dnd","Run the CLI with minimal interaction and interruption.").env("CROCT_DND").default(false)).addOption(new vi("-q, --quiet","Disable output messages.").default(false).implies({interaction:false})).option("--debug","Enable debug mode.").version(B8.version,"-v, --version","Display the version number.").helpOption("-h, --help","Display help for a command.").helpCommand("help [command]","Display help for a command.");e.command("open <url>").description("Open a deep link.").action(async v=>{await t.cli?.open({url:v});});let r=e.command("login").description("Authenticate your user."),n=new vi("-u, --username <username>","The email."),i=new vi("-p, --password <password>","The password.");r.command("credentials",{isDefault:true}).description("Authenticate using credentials.").addOption(t.interactive?n:n.makeOptionMandatory()).addOption(t.interactive?i:i.makeOptionMandatory()).action(async v=>{await t.cli?.login({method:"credentials",username:v.username,password:v.password});}),e.command("logout").description("Logout the current user.").action(async()=>{await t.cli?.logout();}),e.command("admin").argument("[page...]","The name of the page or path to open.").description("Log in and open the admin panel.").action(async v=>{await t.cli?.admin({page:v!==void 0?v.join(" "):t.interactive?void 0:"/"});});let s=new vi("--wor <workspace-slug>","The workspace slug."),o=new vi("--org <organization-slug>","The organization slug."),a=new vi("--dev-app <application-slug>","The development application slug."),l=new vi("--prod-app <application-slug>","The production application slug.");e.command("init").description("Configure the project.").option("-o, --override","Override any existing configuration.").addOption(new vi("-n, --new <resource>","The resources to create.").choices(["organization","org","workspace","wor","application","app"])).addOption(new vi("-s, --sdk <platform>","The SDK to use.").choices(["javascript","react","next"])).addOption(new vi("--skip-api-key-setup","Opt-out of API key setup.").default(false).env("CROCT_SKIP_API_KEY_SETUP")).addOption(t.interactive?o:o.makeOptionMandatory()).addOption(t.interactive?s:s.makeOptionMandatory()).addOption(t.interactive?a:a.makeOptionMandatory()).addOption(l).action(async v=>{await t.cli?.init({override:v.override,new:(()=>{switch(v.new){case "organization":case "org":return "organization";case "workspace":case "wor":return "workspace";case "application":case "app":return "application";default:return}})(),sdk:v.sdk,organization:v.org,workspace:v.wor,devApplication:v.devApp,prodApplication:v.prodApp,skipApiKeySetup:v.skipApiKeySetup});}),e.command("install").description("Install content and types.").action(async()=>{await t.cli?.install({});}),e.command("update").description("Update content and types.").action(async()=>{await t.cli?.install({clean:true});}),e.command("upgrade").description("Upgrade components and slots to the latest version.").option("-s, --slots <slots...>","The slots to upgrade.").option("-c, --components <components...>","The components to upgrade.").action(async v=>{await t.cli?.upgrade({slots:v.slots??(v.components!==void 0?[]:void 0),components:v.components??(v.slots!==void 0?[]:void 0)});});let u=e.command("add").description("Add a resource to your project.");u.command("slot").description("Add a slot to your project.").argument(t.interactive?"[slots...]":"<slots...>").option("-e, --example","Generate an implementation example.").action(async(v,T)=>{await t.cli?.addSlot({slots:v,example:T.example});}),u.command("component").description("Add a component to your project.").argument(t.interactive?"[components...]":"<components...>").action(async v=>{await t.cli?.addComponent({components:v});});let c=e.command("remove").description("Remove a resource from your project.");c.command("slot").description("Remove a slot from your project.").argument(t.interactive?"[slots...]":"<slots...>").action(async v=>{await t.cli?.removeSlot({slots:v});}),c.command("component").description("Remove a component from your project.").argument(t.interactive?"[components...]":"<components...>").action(async v=>{await t.cli?.removeComponent({components:v});});let p=e.command("create").description("Create a resource in your project.");p.command("template").description("Create a template from your project.").addArgument(new uq("<path>","The path to the file.").argOptional()).option("-e, --empty","Create an empty template.").action(async(v,T)=>{await t.cli?.createTemplate({file:v,empty:T.empty});});let d=new vi("--permissions <permissions...>","The permissions of the API key.").argParser(v=>v.split(",").map(T=>{try{return Vi.fromValue(T)}catch{throw new ua(`Unknown permission "${T}".`)}})),f=new vi("--env <environment>","The environment of the API key.").choices(["prod","dev"]).argParser(v=>v==="prod"?"PRODUCTION":"DEVELOPMENT");p.command("api-key").description("Create an API key.").option("--name <name>","The name of the API key.").addOption(t.interactive?d:d.makeOptionMandatory()).addOption(t.interactive?f:f.makeOptionMandatory()).option("-c, --copy","Copy the API key to the clipboard.").action(async v=>{await t.cli?.createApiKey({name:v.name,permissions:v.permissions,environment:v.env,copy:v.copy});});let h={},m=e.command("use").description("Use a template.").argument("template","The path to the template.").passThroughOptions(t.cli===void 0).allowUnknownOption(t.cli===void 0||t.template===null).action(async(v,T)=>{await t.cli?.useTemplate({template:v,options:Object.fromEntries(Object.entries(T).map(([D,C])=>[h[D],C]))});});for(let[v,T]of Object.entries(t.template??{})){let D=`--${v}${T.type!=="boolean"?" <value>":""}`,C=new vi(D,T.description).makeOptionMandatory(T.required===true);switch(T.type){case "string":T.choices!==void 0&&T.choices.length>0&&C.choices(T.choices);break;case "number":C.argParser(L=>{let R=Number.parseFloat(L);if(Number.isNaN(R))throw new ua("The value must be a number.");return R});break;case "array":C.argParser(L=>{let R;try{R=JSON.parse(L);}catch{}if(R===void 0||!Array.isArray(R))throw new ua("The value must be a JSON array.");return R});break;case "object":C.argParser(L=>{let R;try{R=JSON.parse(L);}catch{throw new ua("The JSON is malformed.")}if(typeof R!="object"||R===null)throw new ua("The value must be a JSON object.")});break}h[C.attributeName()]=v,m.addOption(C);}return e.command("enable").description("Enable a feature.").command("deep-link").description("Enable deep link support.").action(async()=>{await t.cli?.deepLink({operation:"enable"});}),e.command("disable").description("Disable a feature.").command("deep-link").description("Disable deep link support.").action(async()=>{await t.cli?.deepLink({operation:"disable"});}),e}function _xt(t){let e=["use","help use"];for(let r of e){let n=r.split(" ").length;if(t.length>n&&t.slice(0,n).join(" ")===r&&(t[n]??"")!=="")return t[n]}return null}function kxt(t){return t.length>=2&&["enable","disable"].includes(t[0])&&t[1]==="deep-link"}async function $8(t=process.argv,e=true){let r=bfe({interactive:true}).parse(t),n=r.opts(),i=oO.fromDefaults({program:l=>$8(r.args.slice(0,2).concat(l)),version:B8.version,quiet:n.quiet,debug:n.debug,interactive:n.interaction?void 0:false,stateless:n.stateless,apiKey:n.apiKey,token:n.token,dnd:n.dnd,templateRegistryUrl:n.registry===void 0?void 0:new URL(n.registry),configurationFile:n.config}),s=_xt(r.args),o=s!==null?await i.getTemplateOptions(s).catch(()=>null):void 0,a=bfe({cli:i,interactive:n.interaction,template:o});e&&await i.welcome({skipDeepLinkCheck:kxt(r.args)}),await a.parseAsync(t);}$8();
2544
+ ${r}`,e.help)}break;case e instanceof Fa:return new V(e.message,{...e.help,suggestions:["Run `init` to create a new configuration."]})}return e}static getSourceLocation(e){return e.url.protocol==="file:"?`${e.url}:${e.start.line}:${e.start.column}`:e.url.hostname==="github.com"?`${e.url}#L${e.start.line}-L${e.end.line}`:`${e.url}#${e.start.line}:${e.start.column}-${e.end.line}:${e.end.column}`}};var B8={version:"0.16.1"};function bfe(t){let e=new lq().name("croct").description("Manage your Croct projects").enablePositionalOptions().option("--cwd <path>","The working directory.",v=>{try{return realpathSync(v)}catch{throw new ua("The path does not exist.")}}).addOption(new vi("--api-key <key>","The API key to use for authentication.").env("CROCT_API_KEY").argParser(v=>{try{return cq.parse(v)}catch{throw new ua("The API key is malformed.")}}).conflicts("token")).addOption(new vi("--token <token>","The JWT-formatted token to use for authentication.").env("CROCT_TOKEN").argParser(v=>{let T;try{T=Hc.parse(v);}catch{throw new ua("The token is malformed.")}if(!T.isValidNow())throw new ua("The token is expired.");return T})).option("--registry <url>","The template registry.",v=>{if(!URL.canParse(v))throw new ua("Malformed URL.");return v}).option("--no-interaction","Run the CLI in non-interactive mode.").option("--config <path>","Path to the configuration file.").addOption(new vi("--stateless","Run the CLI without saving any state locally.").env("CROCT_STATELESS").default(false)).addOption(new vi("--dnd","Run the CLI with minimal interaction and interruption.").env("CROCT_DND").default(false)).addOption(new vi("-q, --quiet","Disable output messages.").default(false).implies({interaction:false})).option("--debug","Enable debug mode.").version(B8.version,"-v, --version","Display the version number.").helpOption("-h, --help","Display help for a command.").helpCommand("help [command]","Display help for a command.");e.command("open <url>").description("Open a deep link.").action(async v=>{await t.cli?.open({url:v});});let r=e.command("login").description("Authenticate your user."),n=new vi("-u, --username <username>","The email."),i=new vi("-p, --password <password>","The password.");r.command("credentials",{isDefault:true}).description("Authenticate using credentials.").addOption(t.interactive?n:n.makeOptionMandatory()).addOption(t.interactive?i:i.makeOptionMandatory()).action(async v=>{await t.cli?.login({method:"credentials",username:v.username,password:v.password});}),e.command("logout").description("Logout the current user.").action(async()=>{await t.cli?.logout();}),e.command("admin").argument("[page...]","The name of the page or path to open.").description("Log in and open the admin panel.").action(async v=>{await t.cli?.admin({page:v!==void 0?v.join(" "):t.interactive?void 0:"/"});});let s=new vi("--wor <workspace-slug>","The workspace slug."),o=new vi("--org <organization-slug>","The organization slug."),a=new vi("--dev-app <application-slug>","The development application slug."),l=new vi("--prod-app <application-slug>","The production application slug.");e.command("init").description("Configure the project.").option("-o, --override","Override any existing configuration.").addOption(new vi("-n, --new <resource>","The resources to create.").choices(["organization","org","workspace","wor","application","app"])).addOption(new vi("-s, --sdk <platform>","The SDK to use.").choices(["javascript","react","next"])).addOption(new vi("--skip-api-key-setup","Opt-out of API key setup.").default(false).env("CROCT_SKIP_API_KEY_SETUP")).addOption(t.interactive?o:o.makeOptionMandatory()).addOption(t.interactive?s:s.makeOptionMandatory()).addOption(t.interactive?a:a.makeOptionMandatory()).addOption(l).action(async v=>{await t.cli?.init({override:v.override,new:(()=>{switch(v.new){case "organization":case "org":return "organization";case "workspace":case "wor":return "workspace";case "application":case "app":return "application";default:return}})(),sdk:v.sdk,organization:v.org,workspace:v.wor,devApplication:v.devApp,prodApplication:v.prodApp,skipApiKeySetup:v.skipApiKeySetup});}),e.command("install").description("Install content and types.").action(async()=>{await t.cli?.install({});}),e.command("update").description("Update content and types.").action(async()=>{await t.cli?.install({clean:true});}),e.command("upgrade").description("Upgrade components and slots to the latest version.").option("-s, --slots <slots...>","The slots to upgrade.").option("-c, --components <components...>","The components to upgrade.").action(async v=>{await t.cli?.upgrade({slots:v.slots??(v.components!==void 0?[]:void 0),components:v.components??(v.slots!==void 0?[]:void 0)});});let u=e.command("add").description("Add a resource to your project.");u.command("slot").description("Add a slot to your project.").argument(t.interactive?"[slots...]":"<slots...>").option("-e, --example","Generate an implementation example.").action(async(v,T)=>{await t.cli?.addSlot({slots:v,example:T.example});}),u.command("component").description("Add a component to your project.").argument(t.interactive?"[components...]":"<components...>").action(async v=>{await t.cli?.addComponent({components:v});});let c=e.command("remove").description("Remove a resource from your project.");c.command("slot").description("Remove a slot from your project.").argument(t.interactive?"[slots...]":"<slots...>").action(async v=>{await t.cli?.removeSlot({slots:v});}),c.command("component").description("Remove a component from your project.").argument(t.interactive?"[components...]":"<components...>").action(async v=>{await t.cli?.removeComponent({components:v});});let p=e.command("create").description("Create a resource in your project.");p.command("template").description("Create a template from your project.").addArgument(new uq("<path>","The path to the file.").argOptional()).option("-e, --empty","Create an empty template.").action(async(v,T)=>{await t.cli?.createTemplate({file:v,empty:T.empty});});let d=new vi("--permissions <permissions...>","The permissions of the API key.").argParser(v=>v.split(",").map(T=>{try{return Vi.fromValue(T)}catch{throw new ua(`Unknown permission "${T}".`)}})),f=new vi("--env <environment>","The environment of the API key.").choices(["prod","dev"]).argParser(v=>v==="prod"?"PRODUCTION":"DEVELOPMENT");p.command("api-key").description("Create an API key.").option("--name <name>","The name of the API key.").addOption(t.interactive?d:d.makeOptionMandatory()).addOption(t.interactive?f:f.makeOptionMandatory()).option("-c, --copy","Copy the API key to the clipboard.").action(async v=>{await t.cli?.createApiKey({name:v.name,permissions:v.permissions,environment:v.env,copy:v.copy});});let h={},m=e.command("use").description("Use a template.").argument("template","The path to the template.").passThroughOptions(t.cli===void 0).allowUnknownOption(t.cli===void 0||t.template===null).action(async(v,T)=>{await t.cli?.useTemplate({template:v,options:Object.fromEntries(Object.entries(T).map(([D,C])=>[h[D],C]))});});for(let[v,T]of Object.entries(t.template??{})){let D=`--${v}${T.type!=="boolean"?" <value>":""}`,C=new vi(D,T.description).makeOptionMandatory(T.required===true);switch(T.type){case "string":T.choices!==void 0&&T.choices.length>0&&C.choices(T.choices);break;case "number":C.argParser(L=>{let R=Number.parseFloat(L);if(Number.isNaN(R))throw new ua("The value must be a number.");return R});break;case "array":C.argParser(L=>{let R;try{R=JSON.parse(L);}catch{}if(R===void 0||!Array.isArray(R))throw new ua("The value must be a JSON array.");return R});break;case "object":C.argParser(L=>{let R;try{R=JSON.parse(L);}catch{throw new ua("The JSON is malformed.")}if(typeof R!="object"||R===null)throw new ua("The value must be a JSON object.")});break}h[C.attributeName()]=v,m.addOption(C);}return e.command("enable").description("Enable a feature.").command("deep-link").description("Enable deep link support.").action(async()=>{await t.cli?.deepLink({operation:"enable"});}),e.command("disable").description("Disable a feature.").command("deep-link").description("Disable deep link support.").action(async()=>{await t.cli?.deepLink({operation:"disable"});}),e}function _xt(t){let e=["use","help use"];for(let r of e){let n=r.split(" ").length;if(t.length>n&&t.slice(0,n).join(" ")===r&&(t[n]??"")!=="")return t[n]}return null}function kxt(t){return t.length>=2&&["enable","disable"].includes(t[0])&&t[1]==="deep-link"}async function $8(t=process.argv,e=true){let r=bfe({interactive:true}).parse(t),n=r.opts(),i=oO.fromDefaults({program:l=>$8(r.args.slice(0,2).concat(l)),version:B8.version,quiet:n.quiet,debug:n.debug,interactive:n.interaction?void 0:false,stateless:n.stateless,apiKey:n.apiKey,token:n.token,dnd:n.dnd,templateRegistryUrl:n.registry===void 0?void 0:new URL(n.registry),configurationFile:n.config}),s=_xt(r.args),o=s!==null?await i.getTemplateOptions(s).catch(()=>null):void 0,a=bfe({cli:i,interactive:n.interaction,template:o});e&&await i.welcome({skipDeepLinkCheck:kxt(r.args)}),await a.parseAsync(t);}$8();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "croct",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "description": "A command-line interface (CLI) for managing projects using Croct.",
5
5
  "author": {
6
6
  "name": "Croct",