@proofkit/cli 2.0.0-beta.24 → 2.0.0-beta.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/add-h15IdCWp.js +57 -0
- package/dist/add-h15IdCWp.js.map +1 -0
- package/dist/{addPackageDependency-BGZl7xc5.js → addPackageDependency-BUJ8tT5i.js} +2 -2
- package/dist/{addPackageDependency-BGZl7xc5.js.map → addPackageDependency-BUJ8tT5i.js.map} +1 -1
- package/dist/{consts-BZnOMxpW.js → consts-CE9CE6Fo.js} +4 -4
- package/dist/{consts-BZnOMxpW.js.map → consts-CE9CE6Fo.js.map} +1 -1
- package/dist/{deploy-D25sPO7K.js → deploy-BJryOaec.js} +3 -3
- package/dist/{deploy-D25sPO7K.js.map → deploy-BJryOaec.js.map} +1 -1
- package/dist/errors-DxuuVXoQ.js +2 -0
- package/dist/errors-DxuuVXoQ.js.map +1 -0
- package/dist/{fmdapi-BO4QL0F8.js → fmdapi-D4f7TrLy.js} +2 -2
- package/dist/{fmdapi-BO4QL0F8.js.map → fmdapi-D4f7TrLy.js.map} +1 -1
- package/dist/{fmdapi-DyRYZWzI.js → fmdapi-H4o2qGE2.js} +3 -3
- package/dist/{fmdapi-DyRYZWzI.js.map → fmdapi-H4o2qGE2.js.map} +1 -1
- package/dist/{getUserPkgManager-Cph_6l1P.js → getUserPkgManager-CZwrE7fs.js} +1 -1
- package/dist/{getUserPkgManager-Cph_6l1P.js.map → getUserPkgManager-CZwrE7fs.js.map} +1 -1
- package/dist/{globalOptions-CkqEi9uC.js → globalOptions-C6fknjPB.js} +1 -1
- package/dist/{globalOptions-CkqEi9uC.js.map → globalOptions-C6fknjPB.js.map} +1 -1
- package/dist/{index-DALPpGd1.d.ts → index-D9Y-xAF1.d.ts} +124 -42
- package/dist/index-D9Y-xAF1.d.ts.map +1 -0
- package/dist/index.js +10 -7
- package/dist/index.js.map +1 -1
- package/dist/{logger-DCEXcH26.js → logger-DxbfijxS.js} +1 -1
- package/dist/{logger-DCEXcH26.js.map → logger-DxbfijxS.js.map} +1 -1
- package/dist/{parseSettings-DJ2m9sgJ.js → parseSettings-xU5Rw3Ne.js} +1 -1
- package/dist/{parseSettings-DJ2m9sgJ.js.map → parseSettings-xU5Rw3Ne.js.map} +1 -1
- package/dist/{proofkit-webviewer-73IB1OBU.js → proofkit-webviewer-Baa93FAx.js} +2 -2
- package/dist/{proofkit-webviewer-73IB1OBU.js.map → proofkit-webviewer-Baa93FAx.js.map} +1 -1
- package/dist/remove-COo1Ju8v.js +2 -0
- package/dist/remove-COo1Ju8v.js.map +1 -0
- package/dist/typegen-DrfVmQfx.js +2 -0
- package/dist/{typegen-DyXaif5O.js.map → typegen-DrfVmQfx.js.map} +1 -1
- package/dist/update-Cpyhj57Y.js +7 -0
- package/dist/{update-FX71y5b3.js.map → update-Cpyhj57Y.js.map} +1 -1
- package/dist/utils-DGwyHkvO.js +3 -0
- package/dist/{utils-DymV7zmv.js.map → utils-DGwyHkvO.js.map} +1 -1
- package/package.json +3 -3
- package/template/nextjs-mantine/package.json +2 -1
- package/template/nextjs-shadcn/package.json +2 -0
- package/template/vite-wv/package.json +2 -2
- package/dist/add-DrcID6d6.js +0 -57
- package/dist/add-DrcID6d6.js.map +0 -1
- package/dist/index-DALPpGd1.d.ts.map +0 -1
- package/dist/remove-BOCU6In3.js +0 -2
- package/dist/remove-BOCU6In3.js.map +0 -1
- package/dist/typegen-DyXaif5O.js +0 -2
- package/dist/update-FX71y5b3.js +0 -7
- package/dist/utils-DymV7zmv.js +0 -3
package/dist/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as e,i as t,n,o as r,s as
|
|
3
|
-
`);s
|
|
4
|
-
`}
|
|
5
|
-
`)
|
|
6
|
-
`)}function $e(e){return e.filter(e=>Je.has(e)?!1:e===`.gitignore`?!0:!e.startsWith(`.`))}const et=e=>S.gen(function*(){let t=yield*j,n=yield*A,r=yield*O,i=yield*k;if(!(yield*S.promise(()=>t.exists(e.targetDir)))||$e(yield*S.promise(()=>t.readdir(e.targetDir))).length===0)return;if(e.request.force){yield*S.promise(()=>t.emptyDir(e.targetDir));return}if(r.nonInteractive)throw Error(`${e.request.appDir} already exists and isn't empty. Remove the existing files or choose a different directory.`);let a=yield*S.promise(()=>i.select({message:`${e.request.appDir} already exists and isn't empty. How would you like to proceed?`,options:[{value:`abort`,label:`Abort installation`},{value:`clear`,label:`Clear the directory and continue`},{value:`overwrite`,label:`Continue and overwrite conflicting files`}]}));if(a===`abort`)throw new P;if(a===`clear`){if(!(yield*S.promise(()=>i.confirm({message:`Are you sure you want to clear the directory?`,initialValue:!1}))))throw new P;yield*S.promise(()=>t.emptyDir(e.targetDir));return}n.warn(`Continuing in ${e.request.appDir} and overwriting conflicting files when needed.`)}),tt=e=>S.gen(function*(){let t=yield*O,n=yield*j,r=yield*A,i=yield*ke,o=yield*N,s=yield*De,l=yield*Oe,u=yield*Ae,d=yield*M,f=[];yield*et(e),r.info(`Scaffolding in ${e.targetDir}`),yield*S.promise(()=>n.copyDir(e.templateDir,e.targetDir,{overwrite:!0}));let p=c.join(e.targetDir,`_gitignore`),m=c.join(e.targetDir,`.gitignore`);(yield*S.promise(()=>n.exists(p)))&&((yield*S.promise(()=>n.exists(m)))?yield*S.promise(()=>n.remove(p)):yield*S.promise(()=>n.rename(p,m)));let h=c.join(e.targetDir,`package.json`),g=se(qe(yield*S.promise(()=>n.readJson(h)),e.packageJson));yield*S.promise(()=>n.writeJson(h,g)),yield*S.promise(()=>i.writeSettings(e.targetDir,e.settings)),yield*S.promise(()=>n.writeFile(e.envFile.path,e.envFile.content));for(let t of e.writes)yield*S.promise(()=>n.writeFile(t.path,t.content));yield*S.promise(()=>I(n,e.targetDir,`__PNPM_COMMAND__`,e.packageManagerCommand)),yield*S.promise(()=>I(n,e.targetDir,`__PACKAGE_MANAGER__`,e.request.packageManager)),yield*S.promise(()=>I(n,e.targetDir,`__AGENT_INSTRUCTIONS__`,a)),e.request.importAlias!==`~/`&&(yield*S.promise(()=>I(n,e.targetDir,`~/`,Le(e.request.importAlias))),yield*S.promise(()=>I(n,e.targetDir,`@/`,e.request.importAlias.replace(Ye,``).replace(Xe,`/`))));let _=e.settings;if(e.tasks.bootstrapFileMaker&&e.request.fileMaker){let t=e.request.fileMaker;_=yield*S.promise(()=>o.bootstrap(e.targetDir,_,t,e.request.appType)),yield*S.promise(()=>i.writeSettings(e.targetDir,_))}if(e.tasks.checkWebViewerAddon&&(yield*S.promise(async()=>{try{let{checkForWebViewerLayouts:n,getWebViewerAddonMessages:i}=await import(`./proofkit-webviewer-73IB1OBU.js`),a=i(await n(e.targetDir));for(let e of a.warn)r.warn(e);for(let e of a.info)r.info(e);t.nonInteractive&&f.push(...a.nextSteps)}catch(e){let t=e instanceof Error?e.message:String(e);r.warn(`Could not inspect the ProofKit WebViewer add-on (${t}).`)}})),e.tasks.runInstall){let t=[`install`];e.request.packageManager===`yarn`&&(t=[]),yield*S.promise(()=>s.run(e.request.packageManager,t,{cwd:e.targetDir,stdout:`pipe`,stderr:`pipe`}))}e.tasks.runInitialCodegen&&(yield*S.promise(()=>u.runInitial(e.targetDir,e.request.packageManager))),e.tasks.initializeGit&&(yield*S.promise(()=>l.initialize(e.targetDir)));let v=yield*S.promise(()=>d.getVersion(e.request.packageManager,e.targetDir));return r.success(`Created ${e.request.scopedAppName} in ${e.targetDir}${v?` using ${e.request.packageManager}@${v}`:``}`),r.info(L.bold(`Next steps:`)),r.info(Qe(e,Array.from(new Set(f)))),e}),nt=/\/+$/,rt=/\\/g,it=/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;function at(e){return e.replace(rt,`/`)}function ot(e){return at(e).replace(nt,``)}function st(e){let t=ot(e).split(`/`),n=t.at(-1)??``;n===`.`&&(n=c.basename(c.resolve(process.cwd())));let r=t.findIndex(e=>e.startsWith(`@`));r!==-1&&(n=t.slice(r).join(`/`));let i=t.filter(e=>!e.startsWith(`@`)).join(`/`);return[n,i]}function ct(e){let t=ot(e);if(t===`.`){let e=c.basename(c.resolve(process.cwd()));return it.test(e)?void 0:`Name must consist of only lowercase alphanumeric characters, '-', and '_'`}let n=t.split(`/`),r=n.findIndex(e=>e.startsWith(`@`)),i=n.at(-1);if(r!==-1&&(i=n.slice(r).join(`/`)),!it.test(i??``))return`Name must consist of only lowercase alphanumeric characters, '-', and '_'`}const lt={noGit:!1,noInstall:!1,force:!1,default:!1,CI:!1,importAlias:`~/`};function ut(e,t){let n=e.split(`.`).map(e=>Number.parseInt(e,10)||0),r=t.split(`.`).map(e=>Number.parseInt(e,10)||0);for(let e=0;e<Math.max(n.length,r.length);e+=1){let t=n[e]??0,i=r[e]??0;if(t>i)return 1;if(t<i)return-1}return 0}function dt(e){if(!!e.layoutName!=!!e.schemaName)throw Error(`Both --layout-name and --schema-name must be provided together.`)}async function ft({prompt:e,fileMakerService:t,flags:n,nonInteractive:r}){if(dt(n),!n.server&&r)throw Error(`Missing required hosted FileMaker inputs in non-interactive mode: --server, --file-name, and --data-api-key.`);let i=n.server??await e.text({message:`What is the URL of your FileMaker Server?`,validate:e=>{try{let t=e.startsWith(`http`)?e:`https://${e}`;new URL(t);return}catch{return`Please enter a valid URL`}}}),{normalizedUrl:a,versions:o}=await t.validateHostedServerUrl(i),s=new URL(a),c=n.fileName,l=n.dataApiKey,u=n.layoutName,d=n.schemaName,f,p=[],m=()=>{if(!f)throw Error(`OttoFMS authentication is required for hosted setup.`);return f};if(!(c&&l)){if(!(n.adminApiKey||o.ottoVersion&&ut(o.ottoVersion,`4.7.0`)>=0))throw Error(`OttoFMS 4.7.0 or later is required to auto-login. Upgrade OttoFMS or pass --admin-api-key for hosted setup.`);f=n.adminApiKey??(await t.getOttoFMSToken({url:s})).token}if(!c){if(r)throw Error(`Missing required FileMaker inputs in non-interactive mode: --file-name, --data-api-key.`);p=await t.listFiles({url:s,token:m()}),c=await e.searchSelect({message:`Which file would you like to connect to?`,options:[{value:`$deploy-demo`,label:`Deploy NEW ProofKit Demo File`,hint:`Use OttoFMS to deploy a new file for testing`,keywords:[`demo`,`proofkit`]},...p.slice().sort((e,t)=>e.filename.localeCompare(t.filename)).map(e=>({value:e.filename,label:e.filename,hint:e.status,keywords:[e.filename]}))]})}if(!c)throw Error(`No FileMaker file was selected.`);if(c===`$deploy-demo`){p.length===0&&(p=await t.listFiles({url:s,token:m()}));let n=p.some(e=>e.filename===`ProofKitDemo.fmp12`),i=n&&!r?await e.confirm({message:`The demo file already exists. Do you want to replace it with a fresh copy?`,initialValue:!1}):n,a=await t.deployDemoFile({url:s,token:m(),operation:i?`replace`:`install`});c=a.filename,l=a.apiKey,u??=`API_Contacts`,d??=`Contacts`}if(!l&&r)throw Error(`Missing required FileMaker inputs in non-interactive mode: --data-api-key.`);if(!l){let n=(await t.listAPIKeys({url:s,token:m()})).filter(e=>e.database===c),r=n.length===0?`create`:await e.searchSelect({message:`Which OttoFMS Data API key would you like to use?`,options:[...n.map(e=>({value:e.key,label:`${e.label} - ${e.user}`,hint:`${e.key.slice(0,5)}...${e.key.slice(-4)}`,keywords:[e.label,e.user,e.database]})),{value:`create`,label:`Create a new API key`,hint:`Requires FileMaker credentials for this file`,keywords:[`create`,`new`]}]});if(r===`create`){let n=await e.text({message:`Enter the account name for ${c}`,validate:e=>e?void 0:`An account name is required`}),r=await e.password({message:`Enter the password for ${n}`,validate:e=>e?void 0:`A password is required`});l=(await t.createDataAPIKeyWithCredentials({url:s,filename:c,username:n,password:r})).apiKey}else l=r}if(!l)throw Error(`No FileMaker Data API key was selected.`);let h=await t.listLayouts({dataApiKey:l,fmFile:c,server:s.origin});if(u&&!h.includes(u))throw Error(`Layout "${u}" was not found in ${c}.`);return r||u||d||await e.confirm({message:`Do you want to configure an initial layout for type generation now?`,initialValue:!1})&&(u=await e.searchSelect({message:`Select a layout to read data from`,options:h.map(e=>({value:e,label:e,keywords:[e]}))}),d=await e.text({message:`What should the generated schema be called?`,defaultValue:Pe(u),validate:e=>e?void 0:`A schema name is required`})),{mode:`hosted-otto`,dataSourceName:`filemaker`,envNames:Fe(`filemaker`),server:s.origin,fileName:c,dataApiKey:l,layoutName:u,schemaName:d,adminApiKey:n.adminApiKey,fmsVersion:o.fmsVersion,ottoVersion:o.ottoVersion}}async function pt({prompt:e,fileMakerService:t,flags:n,appType:r,nonInteractive:i}){if(n.dataSource!==`filemaker`)return{fileMaker:void 0,skipFileMakerSetup:!1};if(dt(n),r===`webviewer`&&!n.server)for(;;){let r=await t.detectLocalFmMcp();if(r.healthy&&r.connectedFiles[0])return{fileMaker:{mode:`local-fm-mcp`,dataSourceName:`filemaker`,envNames:Fe(`filemaker`),fmMcpBaseUrl:r.baseUrl,fileName:r.connectedFiles[0],layoutName:n.layoutName,schemaName:n.schemaName},skipFileMakerSetup:!1};if(i)throw r.healthy?Error(`ProofKit MCP Server was detected, but no FileMaker files are open. Open a file in FileMaker and rerun, or pass --server.`):Error(`ProofKit MCP Server was not detected and no FileMaker server was provided. Start the ProofKit MCP Server locally or rerun with --server.`);let a=await e.select({message:r.healthy?`I noticed you have the ProofKit MCP Server installed, but no files are open. How would you like to continue?`:`ProofKit MCP Server was not detected. How would you like to continue?`,options:[{value:`retry`,label:`Try again`,hint:r.healthy?`Open a FileMaker file, then retry detection`:`Retry ProofKit MCP Server detection`},{value:`hosted`,label:`Continue with hosted setup`,hint:`Use OttoFMS and a hosted FileMaker server`},{value:`skip`,label:`Skip for now`,hint:`Create the project and configure FileMaker later`}]});if(a!==`retry`){if(a===`skip`)return{fileMaker:void 0,skipFileMakerSetup:!0};break}}return{fileMaker:await ft({prompt:e,fileMakerService:t,flags:n,nonInteractive:i}),skipFileMakerSetup:!1}}const mt=(e,t)=>S.gen(function*(){let r={...lt,...t},i=yield*k,a=yield*N,o=yield*O,s=o.nonInteractive||r.CI||r.nonInteractive===!0,c=e;if(!c){if(s)return yield*S.fail(Error(`Project name is required in non-interactive mode.`));c=yield*S.promise(()=>i.text({message:`What will your project be called?`,defaultValue:n,validate:ct}))}if(!c)return yield*S.fail(Error(`Project name is required.`));let l=ct(c);if(l)return yield*S.fail(Error(l));let u=r.appType??`browser`;r.appType||s||(u=yield*S.promise(()=>i.select({message:`What kind of app do you want to build?`,options:[{value:`browser`,label:`Web App for Browsers`,hint:`Uses Next.js and hosted deployment`},{value:`webviewer`,label:`FileMaker Web Viewer`,hint:`Uses Vite for FileMaker web viewers`}]})).pipe(S.map(e=>e)));let d=!!(r.server||r.adminApiKey||r.dataApiKey||r.fileName||r.layoutName||r.schemaName),f=`none`;if(r.dataSource?f=r.dataSource:u===`webviewer`&&(f=d||!(s&&!r.server)?`filemaker`:`none`),!(s||r.dataSource)&&u!==`webviewer`&&(f=yield*S.promise(()=>i.select({message:`Do you want to connect to a FileMaker Database now?`,options:[{value:`filemaker`,label:`Yes`,hint:`Set up env, datasource config, and typegen now`},{value:`none`,label:`No`,hint:`You can add a data source later`}]})).pipe(S.map(e=>e))),s&&!r.dataSource&&d||s&&f!==`filemaker`&&d)return yield*S.fail(Error(`FileMaker flags require --data-source filemaker in non-interactive mode.`));let{fileMaker:p,skipFileMakerSetup:m}=yield*S.promise(()=>pt({prompt:i,fileMakerService:a,flags:{...r,dataSource:f},appType:u,nonInteractive:s})),[h,g]=st(c);return{projectName:c,scopedAppName:h,appDir:g,appType:u,ui:r.ui??`shadcn`,dataSource:f,packageManager:o.packageManager,noInstall:r.noInstall,noGit:r.noGit,force:r.force,cwd:o.cwd,importAlias:r.importAlias,nonInteractive:s,debug:o.debug,fileMaker:p,skipFileMakerSetup:m,hasExplicitFileMakerInputs:d}});async function ht(e){try{await fe(e)}catch{}}function B(){return new pe.Agent({rejectUnauthorized:process.env.PROOFKIT_ALLOW_INSECURE_TLS!==`1`})}async function V(e,t){return await D.get(e,{headers:t?.headers,httpsAgent:B(),timeout:t?.timeout??1e4,validateStatus:null})}async function gt(e,t,n){return await D.post(e,t,{headers:n?.headers,httpsAgent:B(),timeout:n?.timeout??1e4,validateStatus:null})}async function _t(e,t){return await D.delete(e,{headers:t?.headers,httpsAgent:B(),timeout:t?.timeout??1e4,validateStatus:null})}function vt(){let e=process.env.npm_config_user_agent;return e?e.startsWith(`yarn`)?`yarn`:e.startsWith(`pnpm`)?`pnpm`:e.startsWith(`bun`)?`bun`:`npm`:`npm`}const yt=Symbol.for(`@proofkit/new/prompt-cancelled`),bt=me,H=ge,xt=_e,St=ve;function Ct(e){return e instanceof Error&&e.name===`ExitPromptError`}function U(e){return e().catch(e=>{if(Ct(e))return yt;throw e})}function wt(e){return e===yt||he(e)}function Tt(e){if(e)return t=>e(t)??!0}function Et(e,t){return[e.label,e.hint??``,...e.keywords??[]].join(` `).toLowerCase().includes(t.trim().toLowerCase())}function W(e){return typeof e==`string`?e:e?!0:void 0}function Dt(e,t){let n=t?.trim();return n?e.filter(e=>Et(e,n)):e}function Ot(e){return U(()=>xe({message:e.message,default:e.defaultValue,validate:Tt(e.validate)}))}function kt(e){return U(()=>Se({message:e.message,validate:Tt(e.validate)}))}function At(e){return U(()=>be({message:e.message,default:e.initialValue}))}function jt(e){return U(()=>we({message:e.message,pageSize:10,choices:e.options.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:W(e.disabled)}))}))}function Mt(e){return U(()=>Ce({message:e.message,pageSize:10,source:t=>{let n=Dt(e.options,t);return n.length===0?[{value:`__no_matches__`,name:e.emptyMessage??`No matches found. Keep typing to refine your search.`,disabled:e.emptyMessage??`No matches found`}]:n.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:W(e.disabled)}))}}))}function Nt(e){return U(()=>ye({message:e.message,pageSize:10,required:e.required,choices:e.options.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:W(e.disabled)}))}))}function G(e){if(wt(e))throw new P;return e}function Pt(e){return e.startsWith(`https://`)?e:e.startsWith(`http://`)?e.replace(`http://`,`https://`):`https://${e}`}function Ft(e){let t=e=>e.isFolder===!0?(Array.isArray(e.folderLayoutNames)?e.folderLayoutNames:[]).flatMap(e=>t(e)):typeof e.name==`string`?[e.name]:[];return e.flatMap(t).sort((e,t)=>e.localeCompare(t))}const It={text:async e=>G(await Ot({message:e.message,defaultValue:e.defaultValue,validate:e.validate})).toString(),password:async e=>G(await kt({message:e.message,validate:e.validate})).toString(),select:async e=>G(await jt({message:e.message,options:e.options})),searchSelect:async e=>G(await Mt(e)),multiSearchSelect:async e=>G(await Nt(e)),confirm:async e=>G(await At({message:e.message,initialValue:e.initialValue}))},Lt={info:e=>H.info(e),warn:e=>H.warn(e),error:e=>H.error(e),success:e=>H.success(e),note:(e,t)=>xt(e,t)},K={exists:async e=>E.pathExists(e),readdir:async e=>E.readdir(e),emptyDir:async e=>E.emptyDir(e),copyDir:async(e,t,n)=>E.copy(e,t,{overwrite:n?.overwrite??!0}),rename:async(e,t)=>E.rename(e,t),remove:async e=>E.remove(e),readJson:async e=>E.readJson(e),writeJson:async(e,t)=>E.writeJson(e,t,{spaces:2}),writeFile:async(e,t)=>E.writeFile(e,t,`utf8`),readFile:async e=>E.readFile(e,`utf8`)},Rt={getTemplateDir:(t,n)=>t===`webviewer`?c.join(e,`vite-wv`):n===`mantine`?c.join(e,`nextjs-mantine`):c.join(e,`nextjs-shadcn`)},zt={getVersion:async(e,t)=>{if(e===`bun`)return;let{stdout:n}=await T(e,[`-v`],{cwd:t});return n.trim()}},Bt={run:async(e,t,n)=>{let r=await T(e,t,{cwd:n.cwd,stdout:n.stdout??`pipe`,stderr:n.stderr??`pipe`});return{stdout:r.stdout??``,stderr:r.stderr??``}}},Vt={initialize:async e=>{await T(`git`,[`init`],{cwd:e}),await T(`git`,[`add`,`.`],{cwd:e}),await T(`git`,[`commit`,`-m`,`Initial commit`],{cwd:e})}},Ht={writeSettings:async(e,t)=>E.writeJson(c.join(e,`proofkit.json`),t,{spaces:2}),appendEnvVars:async(e,t)=>{let n=c.join(e,`.env`),r=await E.pathExists(n)?await E.readFile(n,`utf8`):``,i=Object.entries(t).map(([e,t])=>`${e}=${t}`).join(`
|
|
2
|
+
import{a as e,c as t,i as n,n as r,o as i,s as a,t as o}from"./consts-CE9CE6Fo.js";import{a as s,c,i as l,l as u,n as d,o as f,r as p,s as m,t as h}from"./errors-DxuuVXoQ.js";import{readFileSync as g,realpathSync as _}from"node:fs";import v from"node:path";import{fileURLToPath as y}from"node:url";import{optional as b,text as x,withDescription as S}from"@effect/cli/Args";import{make as C,run as ee,withDescription as w,withSubcommands as te}from"@effect/cli/Command";import{boolean as T,choice as ne,optional as re,text as ie,withAlias as ae,withDescription as E}from"@effect/cli/Options";import{isValidationError as oe}from"@effect/cli/ValidationError";import{layer as se}from"@effect/platform-node/NodeContext";import{Cause as D,Context as O,Effect as k,Exit as ce,Layer as A}from"effect";import{getOrUndefined as j}from"effect/Option";import{parse as le}from"dotenv";import{applyEdits as ue,modify as de,parse as fe}from"jsonc-parser";import{Chalk as pe}from"chalk";import me from"sort-package-json";import{randomUUID as he}from"node:crypto";import{execa as M}from"execa";import N from"fs-extra";import ge from"open";import _e from"node:https";import ve from"axios";import{intro as ye,isCancel as be,log as xe,note as Se,spinner as Ce}from"@clack/prompts";import{checkbox as we,confirm as Te,input as Ee,password as De,search as Oe,select as ke}from"@inquirer/prompts";import Ae from"gradient-string";const P=O.GenericTag(`@proofkit/cli/CliContext`),je=O.GenericTag(`@proofkit/cli/PromptService`),F=O.GenericTag(`@proofkit/cli/ConsoleService`),I=O.GenericTag(`@proofkit/cli/FileSystemService`),Me=O.GenericTag(`@proofkit/cli/TemplateService`),Ne=O.GenericTag(`@proofkit/cli/PackageManagerService`),Pe=O.GenericTag(`@proofkit/cli/ProcessService`),Fe=O.GenericTag(`@proofkit/cli/GitService`),Ie=O.GenericTag(`@proofkit/cli/SettingsService`),Le=O.GenericTag(`@proofkit/cli/FileMakerService`),Re=O.GenericTag(`@proofkit/cli/CodegenService`);function L(e,t){t&&!e.includes(t)&&e.push(t)}function ze(e){return typeof e==`object`&&!!e&&`config`in e}const Be=k.gen(function*(){let e=yield*P,t=yield*I,r=yield*F,i=e.cwd,a=e=>t.readJson(e).pipe(k.match({onFailure:()=>void 0,onSuccess:e=>e})),o=e=>t.readFile(e).pipe(k.match({onFailure:()=>void 0,onSuccess:e=>e})),s=v.join(i,`proofkit.json`);if(!(yield*t.exists(s))){r.note([`No ProofKit project found in this directory.`,``,`Next steps:`,"- Run `proofkit init` to create a new project",`- Docs: ${n}/docs/cli`].join(`
|
|
3
|
+
`),`Doctor`);return}let c=[],l;l=yield*a(s),l?c.push({level:`ok`,message:"Found `proofkit.json`."}):c.push({level:`error`,message:"Could not read `proofkit.json`."});let u=v.join(i,`package.json`);if(yield*t.exists(u)){let e=yield*a(u);e?({...e.dependencies??{},...e.devDependencies??{}}[`@proofkit/typegen`]?c.push({level:`ok`,message:"Found `@proofkit/typegen`."}):c.push({level:`warn`,message:"Missing `@proofkit/typegen` dependency."}),e.scripts?.typegen?c.push({level:`ok`,message:"Found `typegen` script."}):c.push({level:`warn`,message:"Missing `typegen` script in `package.json`."}),e.scripts?.[`typegen:ui`]&&c.push({level:`ok`,message:"Found `typegen:ui` script."})):c.push({level:`error`,message:"Could not read `package.json`."})}else c.push({level:`error`,message:"Missing `package.json`."});let d=v.join(i,`proofkit-typegen.config.jsonc`),f;if(yield*t.exists(d)){let e=yield*o(d);if(e){let n=fe(e);if(ze(n)){f=n,c.push({level:`ok`,message:`Typegen config is present and valid.`});let e=Array.isArray(n.config)?n.config:[n.config];for(let n of e){let e=v.join(i,n.path??`schema`);(yield*t.exists(e))?c.push({level:`ok`,message:`Generated path exists: \`${n.path??`schema`}\`.`}):c.push({level:`warn`,message:`Generated path missing: \`${n.path??`schema`}\`. Run \`npx @proofkit/typegen\`.`}),n.type===`fmdapi`&&(n.layouts?.length??0)===0&&c.push({level:`warn`,message:"Typegen config has no layouts yet. Use `npx @proofkit/typegen ui`."}),n.type===`fmodata`&&(n.tables?.length??0)===0&&c.push({level:`warn`,message:"Typegen config has no tables yet. Use `npx @proofkit/typegen ui`."}),n.type===`fmdapi`&&n.fmMcp?.enabled&&!n.fmMcp.connectedFileName&&c.push({level:`warn`,message:`FM MCP is enabled but no connected file is pinned yet.`})}}else c.push({level:`error`,message:"Typegen config exists but is invalid. Open `npx @proofkit/typegen ui` or fix the JSONC file."})}else c.push({level:`error`,message:"Could not read `proofkit-typegen.config.jsonc`."})}else c.push({level:`warn`,message:"Missing `proofkit-typegen.config.jsonc`. Run `npx @proofkit/typegen init`."});let p=[l?.envFile?v.join(i,l.envFile):void 0,v.join(i,`.env.local`),v.join(i,`.env`)].filter(e=>!!e),m;for(let e of p)if(yield*t.exists(e)){m=e;break}let h=[];for(let e of l?.dataSources??[])e.type===`fm`&&(L(h,e.envNames?.server),L(h,e.envNames?.database),L(h,e.envNames?.apiKey));let g=[];f&&(g=Array.isArray(f.config)?f.config:[f.config]);for(let e of g)L(h,e.envNames?.server),L(h,e.envNames?.db),L(h,e.envNames?.auth?.apiKey),L(h,e.envNames?.auth?.username),L(h,e.envNames?.auth?.password);if(h.length>0)if(m){let e=yield*o(m);if(e){let t=le(e),n=h.filter(e=>!(e in t));n.length>0?c.push({level:`warn`,message:`Missing env vars in \`${v.basename(m)}\`: ${n.join(`, `)}.`}):c.push({level:`ok`,message:`Expected env vars found in \`${v.basename(m)}\`.`})}else c.push({level:`error`,message:`Could not read env file \`${v.basename(m)}\`.`})}else c.push({level:`warn`,message:`No env file found. Expected vars: ${h.join(`, `)}.`});let _=c.filter(e=>e.level===`error`),y=c.filter(e=>e.level===`warn`),b=[`Checks: ${c.filter(e=>e.level===`ok`).length} ok, ${y.length} warn, ${_.length} error`,``,...c.map(e=>{let t=`ERR`;return e.level===`ok`?t=`OK`:e.level===`warn`&&(t=`WARN`),`- [${t}] ${e.message}`}),``,`Next steps:`,"- Run `npx @proofkit/typegen init` if typegen config is missing","- Run `npx @proofkit/typegen ui` to edit typegen config","- Run `npx @proofkit/typegen` to regenerate generated files",`- Docs: ${n}/docs/typegen`];l?.appType===`webviewer`&&b.splice(b.length-1,0,`- For webviewer projects, make sure local FM MCP is running before typegen`),r.note(b.join(`
|
|
4
|
+
`),`Doctor`)}),Ve=[`API_`,`API `,`dapi_`,`dapi`],He=/[^/]$/,Ue=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.json`,`.jsonc`,`.md`,`.css`,`.scss`,`.html`,`.mjs`,`.cjs`]);function We(e){let t=e.replace(/[-\s]/g,`_`);for(let e of Ve)t.startsWith(e)&&(t=t.replace(e,``));return t}function Ge(e){if(e===`filemaker`)return{database:`FM_DATABASE`,server:`FM_SERVER`,apiKey:`OTTO_API_KEY`};let t=e.toUpperCase();return{database:`${t}_FM_DATABASE`,server:`${t}_FM_SERVER`,apiKey:`${t}_OTTO_API_KEY`}}function R(e,t){return[`npm`,`bun`].includes(e)?`${e} run ${t}`:`${e} ${t}`}function Ke(e){return e===`npm`?`npm run`:e}function qe(e){return e.replace(/\*/g,``).replace(He,`$&/`)}async function z(e,t,n,r){let i=await e.readdir(t);for(let a of i){let i=v.join(t,a);if(await e.readdir(i).catch(e=>{if((typeof e==`object`&&e&&`code`in e&&typeof e.code==`string`?e.code:void 0)!==`ENOTDIR`)throw e})){await z(e,i,n,r);continue}let o=v.extname(a);if(!Ue.has(o))continue;let s=await e.readFile(i).catch(()=>void 0);s?.includes(n)&&await e.writeFile(i,s.replaceAll(n,r))}}async function Je(e,t,n){let r=v.join(t,`src/lib/env.ts`);if(!await e.exists(r))return;let i=await e.readFile(r),a=i.indexOf(` server: {`);if(a===-1)return;let o=i.indexOf(` },`,a);if(o===-1)return;let s=n.filter(e=>!i.includes(`${e.name}:`)).map(e=>` ${e.name}: ${e.zodSchema},`).join(`
|
|
5
|
+
`);s&&(i=`${i.slice(0,o)}${s}\n${i.slice(o)}`,await e.writeFile(r,i))}async function Ye(e,t,n){let r=v.join(t,`proofkit-typegen.config.jsonc`),i=`./src/config/schemas/${n.dataSourceName}`,a={type:`fmdapi`,layouts:[],path:i,clearOldFiles:!0,clientSuffix:`Layout`};n.envNames&&(a.envNames={server:n.envNames.server,db:n.envNames.database,auth:{apiKey:n.envNames.apiKey}}),n.appType===`webviewer`&&(a.webviewerScriptName=`ExecuteDataApi`),n.fmMcpBaseUrl&&(a.fmMcp={enabled:!0,baseUrl:n.fmMcpBaseUrl,...n.connectedFileName?{connectedFileName:n.connectedFileName}:{}});let o=n.layoutName&&n.schemaName?{layoutName:n.layoutName,schemaName:n.schemaName,valueLists:`allowEmpty`}:void 0;if(o&&(a.layouts=[o]),!await e.exists(r)){let t={$schema:`https://proofkit.dev/typegen-config-schema.json`,config:[a]};await e.writeFile(r,`${JSON.stringify(t,null,2)}\n`);return}let s=await e.readFile(r),c=fe(s),l=Array.isArray(c.config)?c.config:[c.config],u=l.findIndex(e=>e.path===i);if(u===-1)l.push(a);else{let e=l[u]??{},t=Array.isArray(e.layouts)?e.layouts:[],n=t;o&&!t.some(e=>e?.layoutName===o.layoutName)&&(n=[...t,o]),l[u]={...e,...a,layouts:n}}let d=de(s,[`config`],Array.isArray(c.config)?l:l[0]??a,{formattingOptions:{insertSpaces:!0,tabSize:2,eol:`
|
|
6
|
+
`}});await e.writeFile(r,ue(s,d))}function Xe(){let t=[v.resolve(e,`package.json`),v.resolve(e,`../cli/package.json`)];for(let e of t)try{let t=JSON.parse(g(e,`utf8`));if(t.version&&t.version!==`0.0.0-private`)return t.version}catch{}return`0.0.0-private`}function Ze(){return`beta`}function Qe(){return process.versions.node.split(`.`)[0]??`22`}function $e(e){return{ui:e.ui,appType:e.appType,envFile:`.env`,dataSources:[],replacedMainPage:!1,registryTemplates:[]}}function et(){return[`# When adding additional environment variables, update the schema alongside this file.`,``].join(`
|
|
7
|
+
`)}const tt={"@radix-ui/react-slot":`^1.2.3`,"class-variance-authority":`^0.7.1`,clsx:`^2.1.1`,"lucide-react":`^0.577.0`,"tailwind-merge":`^3.5.0`,tailwindcss:`^4.1.10`,"tw-animate-css":`^1.4.0`};function nt(e,t){let n=v.resolve(e.cwd,e.appDir),r=Ze(),i=$e(e),a=Ke(e.packageManager),o={name:e.scopedAppName,packageManager:t.packageManagerVersion?`${e.packageManager}@${t.packageManagerVersion}`:void 0,proofkitMetadata:{initVersion:Xe(),scaffoldPackage:`@proofkit/cli`},dependencies:{},devDependencies:{"@proofkit/cli":r,"@types/node":`^${Qe()}`}};return e.appType===`browser`&&(Object.assign(o.dependencies,tt),o.dependencies[`@tailwindcss/postcss`]=`^4.1.10`,o.dependencies[`next-themes`]=`^0.4.6`),e.appType===`webviewer`&&(Object.assign(o.dependencies,tt),o.dependencies[`@proofkit/fmdapi`]=r,o.dependencies[`@proofkit/webviewer`]=r,o.dependencies[`@tanstack/react-query`]=`^5.90.21`,o.dependencies[`@tanstack/react-router`]=`^1.167.4`,o.dependencies.zod=`^4`,o.devDependencies[`@proofkit/typegen`]=r,o.devDependencies[`@tailwindcss/vite`]=`^4.2.1`,o.devDependencies.ultracite=`7.0.8`),{request:e,targetDir:n,templateDir:t.templateDir,packageManagerCommand:a,packageJson:o,settings:i,envFile:{path:v.join(n,`.env`),content:et()},writes:[],commands:[...e.noInstall?[]:[{type:`install`}],...e.dataSource===`filemaker`&&!e.skipFileMakerSetup&&!(e.appType===`webviewer`&&e.nonInteractive&&!e.hasExplicitFileMakerInputs)?[{type:`codegen`}]:[],...e.noGit?[]:[{type:`git-init`}]],tasks:{bootstrapFileMaker:e.dataSource===`filemaker`&&!e.skipFileMakerSetup,checkWebViewerAddon:e.appType===`webviewer`,runInstall:!e.noInstall,runInitialCodegen:e.dataSource===`filemaker`&&!e.skipFileMakerSetup&&!(e.appType===`webviewer`&&e.nonInteractive&&!e.hasExplicitFileMakerInputs),initializeGit:!e.noGit},nextSteps:[`cd ${e.appDir}`,...e.noInstall?[e.packageManager===`yarn`?`yarn`:`${e.packageManager} install`]:[],`npx @tanstack/intent@latest install`,R(e.packageManager,`dev`),...e.appType===`webviewer`?[R(e.packageManager,`typegen`),R(e.packageManager,`launch-fm`)]:[],R(e.packageManager,`proofkit`)]}}function rt(e,t,n=!0){e.name=t.name,e.proofkitMetadata=t.proofkitMetadata,t.packageManager&&(e.packageManager=t.packageManager),e.dependencies||={},e.devDependencies||={};let r=(e,t)=>{for(let[r,i]of Object.entries(t))(n||!(r in e))&&(e[r]=i)};return r(e.dependencies,t.dependencies),r(e.devDependencies,t.devDependencies),e}const it=new Set([`.agents`,`.claude`,`.clawed`,`.clinerules`,`.cursor`,`.windsurf`]),at=/\*/g,ot=/\/?$/,st=new pe({level:1}),B=e=>st.cyan(e),V=e=>st.bold(e),ct=e=>st.yellow(e);function lt(e,t=[]){let n=[`${V(`Project root:`)} ${B(`cd ${ct(e.request.appDir)}`)}`,``,V(`Agent setup:`),`Have your agent run this in the new project and complete the interactive prompt so it can load the right skills:`,` ${B(`npx @tanstack/intent@latest install`)}`];return e.request.noInstall&&n.push(``,V(`Install dependencies:`),` ${B(e.request.packageManager===`yarn`?`yarn`:`${e.request.packageManager} install`)}`),n.push(``,V(`Start the app:`),` ${B(`${e.packageManagerCommand} dev`)}`),e.request.appType===`webviewer`&&(n.push(``,V(`When your FileMaker file is ready:`),` ${B(`${e.packageManagerCommand} typegen`)}`,` ${B(`${e.packageManagerCommand} launch-fm`)}`),t.length>0&&n.push(...t.map(e=>` ${B(e)}`))),n.push(``,V(`More ProofKit commands:`),` ${B(`${e.packageManagerCommand} proofkit`)}`),n.join(`
|
|
8
|
+
`)}function ut(e){return e.filter(e=>it.has(e)?!1:e===`.gitignore`?!0:!e.startsWith(`.`))}function dt(e,t){return k.tryPromise({try:t,catch:t=>u(t)?t:new d({message:e,path:``})})}const ft=e=>k.gen(function*(){let t=yield*I,n=yield*F,r=yield*P,i=yield*je;if(!(yield*t.exists(e.targetDir))||ut(yield*t.readdir(e.targetDir)).length===0)return;if(e.request.force){yield*t.emptyDir(e.targetDir);return}if(r.nonInteractive)return yield*k.fail(new d({message:`${e.request.appDir} already exists and isn't empty. Remove the existing files or choose a different directory.`,path:e.targetDir}));let a=yield*dt(`Unable to choose how to handle the existing directory.`,()=>i.select({message:`${e.request.appDir} already exists and isn't empty. How would you like to proceed?`,options:[{value:`abort`,label:`Abort installation`},{value:`clear`,label:`Clear the directory and continue`},{value:`overwrite`,label:`Continue and overwrite conflicting files`}]}));if(a===`abort`)return yield*k.fail(new m({message:`User aborted the operation`}));if(a===`clear`){if(!(yield*dt(`Unable to confirm directory clearing.`,()=>i.confirm({message:`Are you sure you want to clear the directory?`,initialValue:!1}))))return yield*k.fail(new m({message:`User aborted the operation`}));yield*t.emptyDir(e.targetDir);return}n.warn(`Continuing in ${e.request.appDir} and overwriting conflicting files when needed.`)}),pt=e=>k.gen(function*(){let t=yield*P,n=yield*I,r=yield*F,i=yield*Ie,a=yield*Le,c=yield*Pe,l=yield*Fe,u=yield*Re,d=yield*Ne,f=[],p=async e=>{let t=await k.runPromiseExit(e);if(ce.isSuccess(t))return t.value;let n=j(D.failureOption(t.cause));throw n&&typeof n==`object`&&n&&`cause`in n?n.cause:n??D.squash(t.cause)},m={readdir:e=>p(n.readdir(e)),readFile:e=>p(n.readFile(e)),writeFile:(e,t)=>p(n.writeFile(e,t))};yield*ft(e),r.info(`Scaffolding in ${e.targetDir}`),yield*n.copyDir(e.templateDir,e.targetDir,{overwrite:!0});let h=v.join(e.targetDir,`_gitignore`),g=v.join(e.targetDir,`.gitignore`);(yield*n.exists(h))&&((yield*n.exists(g))?yield*n.remove(h):yield*n.rename(h,g));let _=v.join(e.targetDir,`package.json`),y=me(rt(yield*n.readJson(_),e.packageJson));yield*n.writeJson(_,y),yield*i.writeSettings(e.targetDir,e.settings),yield*n.writeFile(e.envFile.path,e.envFile.content);for(let t of e.writes)yield*n.writeFile(t.path,t.content);yield*k.tryPromise({try:()=>z(m,e.targetDir,`__PNPM_COMMAND__`,e.packageManagerCommand),catch:t=>new s({message:`Unable to rewrite scaffold placeholders.`,operation:`replaceTextInFiles`,path:e.targetDir,cause:t})}),yield*k.tryPromise({try:()=>z(m,e.targetDir,`__PACKAGE_MANAGER__`,e.request.packageManager),catch:t=>new s({message:`Unable to rewrite scaffold placeholders.`,operation:`replaceTextInFiles`,path:e.targetDir,cause:t})}),yield*k.tryPromise({try:()=>z(m,e.targetDir,`__AGENT_INSTRUCTIONS__`,o),catch:t=>new s({message:`Unable to rewrite scaffold placeholders.`,operation:`replaceTextInFiles`,path:e.targetDir,cause:t})}),e.request.importAlias!==`~/`&&(yield*k.tryPromise({try:()=>z(m,e.targetDir,`~/`,qe(e.request.importAlias)),catch:t=>new s({message:`Unable to rewrite scaffold import aliases.`,operation:`replaceTextInFiles`,path:e.targetDir,cause:t})}),yield*k.tryPromise({try:()=>z(m,e.targetDir,`@/`,e.request.importAlias.replace(at,``).replace(ot,`/`)),catch:t=>new s({message:`Unable to rewrite scaffold import aliases.`,operation:`replaceTextInFiles`,path:e.targetDir,cause:t})}));let b=e.settings;if(e.tasks.bootstrapFileMaker&&e.request.fileMaker){let t=e.request.fileMaker;b=yield*a.bootstrap(e.targetDir,b,t,e.request.appType),yield*i.writeSettings(e.targetDir,b)}if(e.tasks.checkWebViewerAddon&&(yield*k.promise(async()=>{try{let{checkForWebViewerLayouts:n,getWebViewerAddonMessages:i}=await import(`./proofkit-webviewer-Baa93FAx.js`),a=i(await n(e.targetDir));for(let e of a.warn)r.warn(e);for(let e of a.info)r.info(e);t.nonInteractive&&f.push(...a.nextSteps)}catch(e){let t=e instanceof Error?e.message:String(e);r.warn(`Could not inspect the ProofKit WebViewer add-on (${t}).`)}})),e.tasks.runInstall){let t=[`install`];e.request.packageManager===`yarn`&&(t=[]),yield*c.run(e.request.packageManager,t,{cwd:e.targetDir,stdout:`pipe`,stderr:`pipe`})}e.tasks.runInitialCodegen&&(yield*u.runInitial(e.targetDir,e.request.packageManager)),e.tasks.initializeGit&&(yield*l.initialize(e.targetDir));let x=yield*d.getVersion(e.request.packageManager,e.targetDir);return r.success(`Created ${e.request.scopedAppName} in ${e.targetDir}${x?` using ${e.request.packageManager}@${x}`:``}`),r.info(st.bold(`Next steps:`)),r.info(lt(e,Array.from(new Set(f)))),e}),mt=k.gen(function*(){(yield*F).note([`Agent-ready prompts are coming soon.`,``,`This command will become the stable entrypoint for docs-linked AI workflows.`,`For now, use package-native tools directly and check docs: ${n}/docs/cli`].join(`
|
|
9
|
+
`),`Coming soon`)}),ht=/\/+$/,gt=/\\/g,_t=/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;function vt(e){return e.replace(gt,`/`)}function yt(e){return vt(e).replace(ht,``)}function bt(e){let t=yt(e).split(`/`),n=t.at(-1)??``;n===`.`&&(n=v.basename(v.resolve(process.cwd())));let r=t.findIndex(e=>e.startsWith(`@`));r!==-1&&(n=t.slice(r).join(`/`));let i=t.filter(e=>!e.startsWith(`@`)).join(`/`);return[n,i]}function xt(e){let t=yt(e);if(t===`.`){let e=v.basename(v.resolve(process.cwd()));return _t.test(e)?void 0:`Name must consist of only lowercase alphanumeric characters, '-', and '_'`}let n=t.split(`/`),r=n.findIndex(e=>e.startsWith(`@`)),i=n.at(-1);if(r!==-1&&(i=n.slice(r).join(`/`)),!_t.test(i??``))return`Name must consist of only lowercase alphanumeric characters, '-', and '_'`}const St={noGit:!1,noInstall:!1,force:!1,default:!1,CI:!1,importAlias:`~/`};function Ct(e,t){let n=e.split(`.`).map(e=>Number.parseInt(e,10)||0),r=t.split(`.`).map(e=>Number.parseInt(e,10)||0);for(let e=0;e<Math.max(n.length,r.length);e+=1){let t=n[e]??0,i=r[e]??0;if(t>i)return 1;if(t<i)return-1}return 0}function wt(e){return!!e.layoutName==!!e.schemaName?k.void:k.fail(new h({message:`Both --layout-name and --schema-name must be provided together.`}))}function H(e,t){return k.tryPromise({try:t,catch:t=>u(t)?t:new h({message:e,cause:t})})}function Tt(e){return e.filter(([,e])=>!e).map(([e])=>e)}function Et(e,t){return`Missing required ${e} inputs in non-interactive mode: ${t.join(`, `)}.`}function Dt({prompt:e,fileMakerService:t,flags:n,nonInteractive:r}){return k.gen(function*(){if(yield*wt(n),!n.server&&r)return yield*k.fail(new f({message:Et(`hosted FileMaker`,Tt([[`--server`,n.server],[`--file-name`,n.fileName],[`--data-api-key`,n.dataApiKey]]))}));let i=n.server??(yield*H(`Unable to read FileMaker Server URL.`,()=>e.text({message:`What is the URL of your FileMaker Server?`,validate:e=>{try{let t=e.startsWith(`http`)?e:`https://${e}`;new URL(t);return}catch{return`Please enter a valid URL`}}}))),{normalizedUrl:a,versions:o}=yield*t.validateHostedServerUrl(i),s=new URL(a),c=n.fileName,u=n.dataApiKey,d=n.layoutName,p=n.schemaName,m,h=[],g=()=>m?k.succeed(m):k.fail(new l({message:`OttoFMS authentication is required for hosted setup.`}));if(!(c&&u)){if(!(n.adminApiKey||o.ottoVersion&&Ct(o.ottoVersion,`4.7.0`)>=0))return yield*k.fail(new l({message:`OttoFMS 4.7.0 or later is required to auto-login. Upgrade OttoFMS or pass --admin-api-key for hosted setup.`}));m=n.adminApiKey??(yield*t.getOttoFMSToken({url:s})).token}if(!c){if(r)return yield*k.fail(new f({message:Et(`FileMaker`,Tt([[`--file-name`,c],[`--data-api-key`,u]]))}));h=yield*t.listFiles({url:s,token:yield*g()}),c=yield*H(`Unable to choose a FileMaker file.`,()=>e.searchSelect({message:`Which file would you like to connect to?`,options:[{value:`$deploy-demo`,label:`Deploy NEW ProofKit Demo File`,hint:`Use OttoFMS to deploy a new file for testing`,keywords:[`demo`,`proofkit`]},...h.slice().sort((e,t)=>e.filename.localeCompare(t.filename)).map(e=>({value:e.filename,label:e.filename,hint:e.status,keywords:[e.filename]}))]}))}if(!c)return yield*k.fail(new l({message:`No FileMaker file was selected.`}));if(c===`$deploy-demo`){h.length===0&&(h=yield*t.listFiles({url:s,token:yield*g()}));let n=h.some(e=>e.filename===`ProofKitDemo.fmp12`),i=n&&!r?yield*H(`Unable to confirm ProofKit Demo replacement.`,()=>e.confirm({message:`The demo file already exists. Do you want to replace it with a fresh copy?`,initialValue:!1})):n,a=yield*t.deployDemoFile({url:s,token:yield*g(),operation:i?`replace`:`install`});c=a.filename,u=a.apiKey,d??=`API_Contacts`,p??=`Contacts`}if(!u&&r)return yield*k.fail(new f({message:Et(`FileMaker`,Tt([[`--data-api-key`,u]]))}));if(!u){let n=(yield*t.listAPIKeys({url:s,token:yield*g()})).filter(e=>e.database===c),r=n.length===0?`create`:yield*H(`Unable to choose an OttoFMS Data API key.`,()=>e.searchSelect({message:`Which OttoFMS Data API key would you like to use?`,options:[...n.map(e=>({value:e.key,label:`${e.label} - ${e.user}`,hint:`${e.key.slice(0,5)}...${e.key.slice(-4)}`,keywords:[e.label,e.user,e.database]})),{value:`create`,label:`Create a new API key`,hint:`Requires FileMaker credentials for this file`,keywords:[`create`,`new`]}]}));if(r===`create`){let n=yield*H(`Unable to read FileMaker account name.`,()=>e.text({message:`Enter the account name for ${c}`,validate:e=>e?void 0:`An account name is required`})),r=yield*H(`Unable to read FileMaker account password.`,()=>e.password({message:`Enter the password for ${n}`,validate:e=>e?void 0:`A password is required`}));if(!c)return yield*k.fail(new l({message:`No FileMaker file was selected.`}));u=(yield*t.createDataAPIKeyWithCredentials({url:s,filename:c,username:n,password:r})).apiKey}else u=r}if(!u)return yield*k.fail(new l({message:`No FileMaker Data API key was selected.`}));let _=c;if(!_)return yield*k.fail(new l({message:`No FileMaker file was selected.`}));let v=yield*t.listLayouts({dataApiKey:u,fmFile:_,server:s.origin});if(d&&!v.includes(d))return yield*k.fail(new l({message:`Layout "${d}" was not found in ${_}.`}));if(!(r||d||p)&&(yield*H(`Unable to confirm initial layout setup.`,()=>e.confirm({message:`Do you want to configure an initial layout for type generation now?`,initialValue:!1})))){d=yield*H(`Unable to choose a FileMaker layout.`,()=>e.searchSelect({message:`Select a layout to read data from`,options:v.map(e=>({value:e,label:e,keywords:[e]}))}));let t=d;if(!t)return yield*k.fail(new l({message:`No FileMaker layout was selected.`}));p=yield*H(`Unable to read generated schema name.`,()=>e.text({message:`What should the generated schema be called?`,defaultValue:We(t),validate:e=>e?void 0:`A schema name is required`}))}return c?u?{mode:`hosted-otto`,dataSourceName:`filemaker`,envNames:Ge(`filemaker`),server:s.origin,fileName:c,dataApiKey:u,layoutName:d,schemaName:p,adminApiKey:n.adminApiKey,fmsVersion:o.fmsVersion,ottoVersion:o.ottoVersion}:yield*k.fail(new l({message:`No FileMaker Data API key was selected.`})):yield*k.fail(new l({message:`No FileMaker file was selected.`}))})}function Ot({prompt:e,console:t,fileMakerService:n,flags:r,appType:i,nonInteractive:a}){return k.gen(function*(){if(r.dataSource!==`filemaker`)return{fileMaker:void 0,skipFileMakerSetup:!1};if(yield*wt(r),i===`webviewer`&&!r.server){let i=t=>k.gen(function*(){let n=t.filter(Boolean);if(n.length!==0)return r.fileName?n.includes(r.fileName)?r.fileName:yield*k.fail(new l({message:`FileMaker file "${r.fileName}" is not currently connected to the local ProofKit MCP Server. Connected files: ${n.join(`, `)}.`})):n.length===1?n[0]:a?yield*k.fail(new f({message:`Multiple FileMaker files are connected to the local ProofKit MCP Server. Pass --file-name with one of: ${n.join(`, `)}.`})):yield*H(`Unable to choose a local FileMaker file.`,()=>e.searchSelect({message:`Multiple FileMaker files are open. Which file should ProofKit use?`,options:n.map(e=>({value:e,label:e,hint:`Connected via local ProofKit MCP Server`,keywords:[e]}))}))});for(;;){let o=yield*n.detectLocalFmMcp(),s=o.healthy?yield*i(o.connectedFiles):void 0;if(o.healthy&&s)return t.info(`Using local ProofKit MCP file: ${s}`),{fileMaker:{mode:`local-fm-mcp`,dataSourceName:`filemaker`,envNames:Ge(`filemaker`),fmMcpBaseUrl:o.baseUrl,fileName:s,layoutName:r.layoutName,schemaName:r.schemaName},skipFileMakerSetup:!1};if(a)return o.healthy?yield*k.fail(new f({message:`ProofKit MCP Server was detected, but no FileMaker files are open. Open a file in FileMaker and rerun, or pass --server.`})):yield*k.fail(new f({message:`ProofKit MCP Server was not detected and no FileMaker server was provided. Start the ProofKit MCP Server locally or rerun with --server.`}));let c=yield*H(`Unable to choose FileMaker setup fallback.`,()=>e.select({message:o.healthy?`ProofKit MCP Server is running, but no FileMaker file is open yet. Open one, then choose how to continue.`:`ProofKit MCP Server was not detected. How would you like to continue?`,options:[{value:`retry`,label:`Try again`,hint:o.healthy?`Check again after opening a FileMaker file`:`Retry ProofKit MCP Server detection`},{value:`hosted`,label:`Continue with hosted setup`,hint:`Use OttoFMS and a hosted FileMaker server`},{value:`skip`,label:`Skip for now`,hint:`Create the project and configure FileMaker later`}]}));if(c!==`retry`){if(c===`skip`)return{fileMaker:void 0,skipFileMakerSetup:!0};break}}}return{fileMaker:yield*Dt({prompt:e,fileMakerService:n,flags:r,nonInteractive:a}),skipFileMakerSetup:!1}})}const kt=(e,t)=>k.gen(function*(){let n={...St,...t},i=yield*je,a=yield*F,o=yield*Le,s=yield*P,c=s.nonInteractive||n.CI||n.nonInteractive===!0,l=e;if(!l){if(c)return yield*k.fail(new f({message:`Project name is required in non-interactive mode.`}));l=yield*H(`Unable to read project name.`,()=>i.text({message:`What will your project be called?`,defaultValue:r,validate:xt}))}if(!l)return yield*k.fail(new h({message:`Project name is required.`}));let u=xt(l);if(u)return yield*k.fail(new h({message:u}));let d=n.appType??`browser`;n.appType||c||(d=yield*H(`Unable to choose app type.`,()=>i.select({message:`What kind of app do you want to build?`,options:[{value:`browser`,label:`Web App for Browsers`,hint:`Uses Next.js and hosted deployment`},{value:`webviewer`,label:`FileMaker Web Viewer`,hint:`Uses Vite for FileMaker web viewers`}]})));let p=!!(n.server||n.adminApiKey||n.dataApiKey||n.fileName||n.layoutName||n.schemaName),m=`none`;if(n.dataSource?m=n.dataSource:d===`webviewer`&&(m=p||!(c&&!n.server)?`filemaker`:`none`),!(c||n.dataSource)&&d!==`webviewer`&&(m=yield*H(`Unable to choose data source setup.`,()=>i.select({message:`Do you want to connect to a FileMaker Database now?`,options:[{value:`filemaker`,label:`Yes`,hint:`Set up env, datasource config, and typegen now`},{value:`none`,label:`No`,hint:`You can add a data source later`}]}))),c&&!n.dataSource&&p||c&&m!==`filemaker`&&p)return yield*k.fail(new f({message:`FileMaker flags require --data-source filemaker in non-interactive mode.`}));let{fileMaker:g,skipFileMakerSetup:_}=yield*Ot({prompt:i,console:a,fileMakerService:o,flags:{...n,dataSource:m},appType:d,nonInteractive:c}),[v,y]=bt(l);return{projectName:l,scopedAppName:v,appDir:y,appType:d,ui:n.ui??`shadcn`,dataSource:m,packageManager:s.packageManager,noInstall:n.noInstall,noGit:n.noGit,force:n.force,cwd:s.cwd,importAlias:n.importAlias,nonInteractive:c,debug:s.debug,fileMaker:g,skipFileMakerSetup:_,hasExplicitFileMakerInputs:p}});async function At(e){try{await ge(e)}catch{}}function jt(){return new _e.Agent({rejectUnauthorized:process.env.PROOFKIT_ALLOW_INSECURE_TLS!==`1`})}async function U(e,t){return await ve.get(e,{headers:t?.headers,httpsAgent:jt(),timeout:t?.timeout??1e4,validateStatus:null})}async function Mt(e,t,n){return await ve.post(e,t,{headers:n?.headers,httpsAgent:jt(),timeout:n?.timeout??1e4,validateStatus:null})}async function Nt(e,t){return await ve.delete(e,{headers:t?.headers,httpsAgent:jt(),timeout:t?.timeout??1e4,validateStatus:null})}function Pt(){let e=process.env.npm_config_user_agent;return e?e.startsWith(`yarn`)?`yarn`:e.startsWith(`pnpm`)?`pnpm`:e.startsWith(`bun`)?`bun`:`npm`:`npm`}const Ft=Symbol.for(`@proofkit/new/prompt-cancelled`),It=ye,W=xe,Lt=Se,Rt=Ce;function zt(e){return e instanceof Error&&e.name===`ExitPromptError`}function G(e){return e().catch(e=>{if(zt(e))return Ft;throw e})}function Bt(e){return e===Ft||be(e)}function Vt(e){if(e)return t=>e(t)??!0}function Ht(e,t){return[e.label,e.hint??``,...e.keywords??[]].join(` `).toLowerCase().includes(t.trim().toLowerCase())}function Ut(e){return typeof e==`string`?e:e?!0:void 0}function Wt(e,t){let n=t?.trim();return n?e.filter(e=>Ht(e,n)):e}function Gt(e){return G(()=>Ee({message:e.message,default:e.defaultValue,validate:Vt(e.validate)}))}function Kt(e){return G(()=>De({message:e.message,validate:Vt(e.validate)}))}function qt(e){return G(()=>Te({message:e.message,default:e.initialValue}))}function Jt(e){return G(()=>ke({message:e.message,pageSize:10,choices:e.options.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:Ut(e.disabled)}))}))}function Yt(e){return G(()=>Oe({message:e.message,pageSize:10,source:t=>{let n=Wt(e.options,t);return n.length===0?[{value:`__no_matches__`,name:e.emptyMessage??`No matches found. Keep typing to refine your search.`,disabled:e.emptyMessage??`No matches found`}]:n.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:Ut(e.disabled)}))}}))}function Xt(e){return G(()=>we({message:e.message,pageSize:10,required:e.required,choices:e.options.map(e=>({value:e.value,name:e.label,description:e.hint,disabled:Ut(e.disabled)}))}))}function K(e){if(Bt(e))throw new m({message:`User aborted the operation`});return e}function Zt(e){return e.startsWith(`https://`)?e:e.startsWith(`http://`)?e.replace(`http://`,`https://`):`https://${e}`}function Qt(e){let t=e=>e.isFolder===!0?(Array.isArray(e.folderLayoutNames)?e.folderLayoutNames:[]).flatMap(e=>t(e)):typeof e.name==`string`?[e.name]:[];return e.flatMap(t).sort((e,t)=>e.localeCompare(t))}function q(e,t,n){return k.tryPromise({try:n,catch:n=>new s({message:`File system ${e} failed for ${t}.`,operation:e,path:t,cause:n})})}function J(e,t,n,r,i){return k.tryPromise({try:r,catch:r=>new p({message:i??`Command failed: ${[e,...t].join(` `)}`,command:e,args:t,cwd:n,cause:r})})}function Y(e,t){return k.tryPromise({try:t,catch:t=>new l({message:e,cause:t})})}const $t={text:async e=>K(await Gt({message:e.message,defaultValue:e.defaultValue,validate:e.validate})).toString(),password:async e=>K(await Kt({message:e.message,validate:e.validate})).toString(),select:async e=>K(await Jt({message:e.message,options:e.options})),searchSelect:async e=>K(await Yt(e)),multiSearchSelect:async e=>K(await Xt(e)),confirm:async e=>K(await qt({message:e.message,initialValue:e.initialValue}))},en={info:e=>W.info(e),warn:e=>W.warn(e),error:e=>W.error(e),success:e=>W.success(e),note:(e,t)=>Lt(e,t)},tn={exists:e=>q(`exists`,e,()=>N.pathExists(e)),readdir:e=>q(`readdir`,e,()=>N.readdir(e)),emptyDir:e=>q(`emptyDir`,e,()=>N.emptyDir(e)),copyDir:(e,t,n)=>q(`copyDir`,`${e} -> ${t}`,()=>N.copy(e,t,{overwrite:n?.overwrite??!0})),rename:(e,t)=>q(`rename`,`${e} -> ${t}`,()=>N.rename(e,t)),remove:e=>q(`remove`,e,()=>N.remove(e)),readJson:e=>q(`readJson`,e,()=>N.readJson(e)),writeJson:(e,t)=>q(`writeJson`,e,()=>N.writeJson(e,t,{spaces:2})),writeFile:(e,t)=>q(`writeFile`,e,()=>N.writeFile(e,t,`utf8`)),readFile:e=>q(`readFile`,e,()=>N.readFile(e,`utf8`))},nn={getTemplateDir:(e,t)=>e===`webviewer`?v.join(i,`vite-wv`):t===`mantine`?v.join(i,`nextjs-mantine`):v.join(i,`nextjs-shadcn`)},rn={getVersion:(e,t)=>e===`bun`?k.succeed(void 0):J(e,[`-v`],t,async()=>{let{stdout:n}=await M(e,[`-v`],{cwd:t});return n.trim()})},an={run:(e,t,n)=>J(e,t,n.cwd,async()=>{let r=await M(e,t,{cwd:n.cwd,stdout:n.stdout??`pipe`,stderr:n.stderr??`pipe`});return{stdout:r.stdout??``,stderr:r.stderr??``}})},on={initialize:e=>k.gen(function*(){yield*J(`git`,[`init`],e,()=>M(`git`,[`init`],{cwd:e})),yield*J(`git`,[`add`,`.`],e,()=>M(`git`,[`add`,`.`],{cwd:e})),yield*J(`git`,[`commit`,`-m`,`Initial commit`],e,()=>M(`git`,[`commit`,`-m`,`Initial commit`],{cwd:e}))})},sn={writeSettings:(e,t)=>q(`writeSettings`,v.join(e,`proofkit.json`),()=>N.writeJson(v.join(e,`proofkit.json`),t,{spaces:2})),appendEnvVars:(e,t)=>q(`appendEnvVars`,v.join(e,`.env`),async()=>{let n=v.join(e,`.env`),r=await N.pathExists(n)?await N.readFile(n,`utf8`):``,i=Object.entries(t).map(([e,t])=>`${e}=${t}`).join(`
|
|
7
10
|
`),a=[r.trimEnd(),i].filter(Boolean).join(`
|
|
8
11
|
`).concat(`
|
|
9
|
-
`);await
|
|
10
|
-
`),`Project commands`);return}
|
|
12
|
+
`);await N.writeFile(n,a,`utf8`)})};function cn(e){return{type:`fm`,name:e,envNames:Ge(e)}}function ln(e,t,n){let r=cn(t.dataSourceName),i={...e,dataSources:e.dataSources.some(e=>e.name===r.name)?e.dataSources:[...e.dataSources,r]};return t.mode===`local-fm-mcp`?Promise.resolve({settings:i,envVars:{},envSchemaEntries:[],typegenConfig:{mode:t.mode,dataSourceName:t.dataSourceName,fmMcpBaseUrl:t.fmMcpBaseUrl,connectedFileName:t.fileName,layoutName:t.layoutName,schemaName:t.schemaName,appType:n}}):Promise.resolve({settings:i,envVars:{[t.envNames.database]:t.fileName,[t.envNames.server]:t.server,[t.envNames.apiKey]:t.dataApiKey},envSchemaEntries:[{name:t.envNames.database,zodSchema:`z.string().endsWith(".fmp12")`,defaultValue:t.fileName},{name:t.envNames.server,zodSchema:`z.string().url()`,defaultValue:t.server},{name:t.envNames.apiKey,zodSchema:`z.string().startsWith("dk_")`,defaultValue:t.dataApiKey}],typegenConfig:{mode:t.mode,dataSourceName:t.dataSourceName,envNames:t.envNames,layoutName:t.layoutName,schemaName:t.schemaName,appType:n}})}const X={detectLocalFmMcp:(e=process.env.FM_MCP_BASE_URL??`http://127.0.0.1:1365`)=>k.tryPromise({try:async()=>{try{if(!(await fetch(`${e}/health`,{signal:AbortSignal.timeout(3e3)})).ok)return{baseUrl:e,healthy:!1,connectedFiles:[]};let t=await fetch(`${e}/connectedFiles`,{signal:AbortSignal.timeout(3e3)}).then(async e=>e.ok?await e.json():[]).catch(()=>[]);return{baseUrl:e,healthy:!0,connectedFiles:Array.isArray(t)?t.filter(e=>typeof e==`string`):[]}}catch{return{baseUrl:e,healthy:!1,connectedFiles:[]}}},catch:e=>new l({message:`Unable to detect local ProofKit MCP Server.`,cause:e})}),validateHostedServerUrl:(e,t)=>k.gen(function*(){let n=Zt(e),r=new URL(`/fmws/serverinfo`,n).toString(),i=(yield*Y(`Unable to validate FileMaker Server URL: ${n}`,()=>U(r))).data?.data?.ServerVersion?.split(` `)[0];if(!i)return yield*k.fail(new l({message:`Invalid FileMaker Server URL: ${n}`}));let a=null;if(a=(yield*Y(`Unable to query OttoFMS version.`,()=>U(new URL(`/otto/api/info`,n).toString())).pipe(k.catchAll(()=>k.succeed(void 0))))?.data?.response?.Otto?.version??null,!a){let e=new URL(n);e.port=t?String(t):`3030`,e.pathname=`/api/otto/info`,a=(yield*Y(`Unable to query OttoFMS v3 version.`,()=>U(e.toString())).pipe(k.catchAll(()=>k.succeed(void 0))))?.data?.Otto?.version??null}return{normalizedUrl:new URL(n).origin,versions:{fmsVersion:i,ottoVersion:a}}}),getOttoFMSToken:({url:e})=>k.gen(function*(){let t=he().replaceAll(`-`,``).slice(0,18),n=new URL(`/otto/wizard/${t}`,e.origin);W.info(`If the browser window didn't open automatically, use this Otto login URL:\n${n.toString()}`),yield*Y(`Unable to open OttoFMS login URL.`,()=>At(n.toString()));let r=Rt();r.start(`Waiting for OttoFMS login`);let i=Date.now()+18e4;for(;Date.now()<i;){let n=(yield*Y(`Unable to poll OttoFMS login status.`,()=>U(`${e.origin}/otto/api/cli/checkHash/${t}`,{headers:{"Accept-Encoding":`deflate`},timeout:5e3})).pipe(k.catchAll(()=>k.succeed(void 0))))?.data?.response?.token;if(n)return r.stop(`Login complete`),yield*Y(`Unable to clean up OttoFMS login state.`,()=>Nt(`${e.origin}/otto/api/cli/checkHash/${t}`,{headers:{"Accept-Encoding":`deflate`}})).pipe(k.catchAll(()=>k.void)),{token:n};yield*k.promise(()=>new Promise(e=>setTimeout(e,500)))}return r.stop(`Login timed out`),yield*k.fail(new l({message:`OttoFMS login timed out after 3 minutes.`}))}),listFiles:({url:e,token:t})=>k.gen(function*(){let n=yield*Y(`Unable to list FileMaker files from OttoFMS.`,()=>U(`${e.origin}/otto/fmi/admin/api/v2/databases`,{headers:{Authorization:`Bearer ${t}`}}));return(Array.isArray(n.data?.response?.databases)?n.data.response.databases:[]).filter(e=>typeof e.filename==`string`).map(e=>({filename:e.filename,status:e.status??`unknown`}))}),listAPIKeys:({url:e,token:t})=>k.gen(function*(){let n=yield*Y(`Unable to list OttoFMS Data API keys.`,()=>U(`${e.origin}/otto/api/api-key`,{headers:{Authorization:`Bearer ${t}`}}));return(Array.isArray(n.data?.response?.[`api-keys`])?n.data.response[`api-keys`]:[]).filter(e=>typeof e.key==`string`&&typeof e.user==`string`&&typeof e.database==`string`&&typeof e.label==`string`).map(e=>({key:e.key,user:e.user,database:e.database,label:e.label}))}),createDataAPIKeyWithCredentials:({url:e,filename:t,username:n,password:r})=>k.gen(function*(){let i=(yield*Y(`Unable to create a Data API key for ${t}.`,()=>Mt(`${e.origin}/otto/api/api-key/create-only`,{database:t,label:`For FM Web App`,user:n,pass:r}))).data?.response?.key;return i?{apiKey:i}:yield*k.fail(new l({message:`Failed to create a Data API key for ${t}.`}))}),startDeployment:({payload:e,url:t,token:n})=>Y(`Unable to start ProofKit Demo deployment.`,()=>Mt(`${t.origin}/otto/api/deployment`,e,{headers:{Authorization:`Bearer ${n}`}})),getDeploymentStatus:({url:e,token:t,deploymentId:n})=>Y(`Unable to fetch deployment status for ${n}.`,()=>U(`${e.origin}/otto/api/deployment/${n}`,{headers:{Authorization:`Bearer ${t}`}})),deployDemoFile:({url:e,token:t,operation:n})=>k.gen(function*(){let r=`ProofKitDemo.fmp12`,i=Rt();i.start(`Deploying ProofKit Demo file`);let a={scheduled:!1,label:`Install ProofKit Demo`,deployments:[{name:`Install ProofKit Demo`,source:{type:`url`,url:`https://proofkit.dev/proofkit-demo/manifest.json`},fileOperations:[{target:{fileName:r},operation:n,source:{fileName:r},location:{folder:`default`,subFolder:``}}],concurrency:1,options:{closeFilesAfterBuild:!1,keepFilesClosedAfterComplete:!1,transferContainerData:!1}}],abortRemaining:!1},o=(yield*X.startDeployment({payload:a,url:e,token:t})).data?.response?.subDeploymentIds?.[0];if(!o)return i.stop(`Demo deployment failed`),yield*k.fail(new l({message:`No deployment ID was returned when deploying the demo file.`}));let s=Date.now()+3e5,c=!1;for(;Date.now()<s;){yield*k.promise(()=>new Promise(e=>setTimeout(e,2500)));let n=yield*X.getDeploymentStatus({url:e,token:t,deploymentId:o});if(!n.data?.response?.running){if(n.data?.response?.status!==`complete`)return i.stop(`Demo deployment failed`),yield*k.fail(new l({message:`ProofKit Demo deployment did not complete successfully.`}));c=!0;break}}if(!c)return i.stop(`Demo deployment timed out`),yield*k.fail(new l({message:`ProofKit Demo deployment timed out after 5 minutes.`}));let u=yield*X.createDataAPIKeyWithCredentials({url:e,filename:r,username:`admin`,password:`admin`});return i.stop(`Demo file deployed`),{apiKey:u.apiKey,filename:r}}),listLayouts:({dataApiKey:e,fmFile:t,server:n})=>k.gen(function*(){let r=yield*Y(`Unable to list layouts for ${t}.`,()=>U(`${n}/otto/fmi/data/vLatest/databases/${encodeURIComponent(t)}/layouts`,{headers:{Authorization:`Bearer ${e}`}}));return Qt(Array.isArray(r.data?.response?.layouts)?r.data.response.layouts:[])}),createFileMakerBootstrapArtifacts:(e,t,n)=>Y(`Unable to prepare FileMaker bootstrap artifacts.`,()=>ln(e,t,n)),bootstrap:(e,t,n,r)=>k.gen(function*(){let i=yield*X.createFileMakerBootstrapArtifacts(t,n,r),a={exists:e=>k.runPromise(tn.exists(e)),readFile:e=>k.runPromise(tn.readFile(e)),writeFile:(e,t)=>k.runPromise(tn.writeFile(e,t))};return Object.keys(i.envVars).length>0&&(yield*sn.appendEnvVars(e,i.envVars),yield*Y(`Unable to update env schema for FileMaker bootstrap.`,()=>Je(a,e,i.envSchemaEntries))),yield*Y(`Unable to update typegen config for FileMaker bootstrap.`,()=>Ye(a,e,{appType:i.typegenConfig.appType,dataSourceName:i.typegenConfig.dataSourceName,envNames:i.typegenConfig.envNames,fmMcpBaseUrl:i.typegenConfig.fmMcpBaseUrl,connectedFileName:i.typegenConfig.connectedFileName,layoutName:i.typegenConfig.layoutName,schemaName:i.typegenConfig.schemaName})),i.settings})},un={runInitial:(e,t)=>{let n;n=t===`npm`?[`npm`,`run`,`typegen`]:t===`bun`?[`bun`,`run`,`typegen`]:[t,`typegen`];let r=n[0];if(!r)return k.fail(new p({message:`Unable to resolve the codegen command`,command:t,args:n.slice(1),cwd:e}));let i=n.slice(1);return J(r,i,e,async()=>{await M(r,i,{cwd:e})},`Initial codegen failed`)}};function Z(e){let t={cwd:e.cwd,debug:e.debug,nonInteractive:e.nonInteractive,packageManager:Pt()},n=A.mergeAll(A.succeed(P,t),A.succeed(je,$t),A.succeed(F,en),A.succeed(I,tn),A.succeed(Me,nn),A.succeed(Ne,rn),A.succeed(Pe,an),A.succeed(Fe,on),A.succeed(Ie,sn),A.succeed(Le,X),A.succeed(Re,un));return e=>k.provide(e,n)}const dn=[`CI`,`GITHUB_ACTIONS`,`CODEX`,`OPENAI_CODEX`,`CLAUDE_CODE`,`JENKINS_URL`,`BUILDKITE`];function fn(e){let t=e?.env??process.env,n=e?.stdinIsTTY===!0&&e?.stdoutIsTTY===!0,r=dn.some(e=>!!t[e]),i=t.TERM===`dumb`;return!n||r||i}function pn(e){return e?.nonInteractive===!0||e?.CI===!0?!0:fn(e)}const mn=Ae(Object.values({purple:`#89216B`,lightPurple:`#D15ABB`,orange:`#FF595E`}));function hn(e=`0.0.0-private`){let n=Pt();(n===`yarn`||n===`pnpm`)&&console.log(``),console.log(mn.multiline(t(e)))}const gn={noGit:!1,noInstall:!1,force:!1,default:!1,CI:!1,importAlias:`~/`};function _n(){try{let e=new URL(`../package.json`,import.meta.url);return JSON.parse(g(y(e),`utf8`)).version??`0.0.0-private`}catch{return`0.0.0-private`}}const vn=(e,t)=>k.gen(function*(){let n=yield*Me,r=yield*Ne,i=yield*kt(e,{...gn,...t}),a=nt(i,{templateDir:n.getTemplateDir(i.appType,i.ui),packageManagerVersion:yield*r.getVersion(i.packageManager,i.cwd)});return yield*pt(a),{request:i,plan:a}}),yn=e=>k.gen(function*(){let t=yield*P,n=yield*I,r=yield*F,i={...gn,...e},a=v.join(t.cwd,`proofkit.json`);if(yield*n.exists(a)){It(`Found ${mn(`ProofKit`)} project`),r.note([`ProofKit now focuses on project bootstrap, diagnostics, and agent entrypoints.`,"Use an explicit command such as `proofkit doctor`, `proofkit prompt`, or `proofkit init`."].join(`
|
|
13
|
+
`),`Project commands`);return}if(t.nonInteractive||i.CI||i.nonInteractive)return yield*k.fail(new f({message:"The default command is interactive-only in non-interactive mode. Run an explicit command such as `proofkit init <name> --non-interactive`."}));It(`No ${mn(`ProofKit`)} project found, running \`init\``),yield*vn(void 0,{...i,default:!0})}),bn=b(x({name:`dir`})).pipe(S(`The project name or target directory`));function Q(e,t){return re(ie(e).pipe(E(t)))}function xn(e,t,n){return re(ne(e,t).pipe(E(n)))}function Sn(){return{stdinIsTTY:process.stdin?.isTTY,stdoutIsTTY:process.stdout?.isTTY}}function $(e,t){let n=pn({nonInteractive:t?.nonInteractive,...Sn()});return Z({cwd:process.cwd(),debug:t?.debug===!0,nonInteractive:n})(k.promise(e))}function Cn(){return C(`init`,{dir:bn,appType:xn(`app-type`,[`browser`,`webviewer`],`The type of app to create`),ui:xn(`ui`,[`shadcn`,`mantine`],`The UI scaffold to create`),server:Q(`server`,`The URL of your FileMaker Server`),adminApiKey:Q(`admin-api-key`,`Admin API key for OttoFMS`),fileName:Q(`file-name`,`The FileMaker file name to use, including selecting a local connected file`),layoutName:Q(`layout-name`,`The FileMaker layout name to scaffold`),schemaName:Q(`schema-name`,`The generated schema name`),dataApiKey:Q(`data-api-key`,`The Otto Data API key to use`),dataSource:xn(`data-source`,[`filemaker`,`none`],`The data source to use`),noGit:T(`no-git`).pipe(E(`Skip git initialization`)),noInstall:T(`no-install`).pipe(E(`Skip package installation`)),force:T(`force`).pipe(ae(`f`),E(`Force overwrite target directory when it already contains files`)),CI:T(`ci`).pipe(E(`Deprecated alias for --non-interactive`)),nonInteractive:T(`non-interactive`).pipe(E(`Never prompt for input; fail when required values are missing`)),debug:T(`debug`).pipe(E(`Run in debug mode`))},({dir:e,...t})=>{let n=pn({CI:t.CI,nonInteractive:t.nonInteractive,...Sn()}),r={...gn,appType:j(t.appType),ui:j(t.ui),server:j(t.server),adminApiKey:j(t.adminApiKey),fileName:j(t.fileName),layoutName:j(t.layoutName),schemaName:j(t.schemaName),dataApiKey:j(t.dataApiKey),dataSource:j(t.dataSource),noGit:t.noGit,noInstall:t.noInstall,force:t.force,CI:t.CI,nonInteractive:t.nonInteractive,debug:t.debug};return Z({cwd:process.cwd(),debug:r.debug===!0,nonInteractive:n})(vn(j(e),r))}).pipe(w(`Create a new project with ProofKit`))}function wn(){return C(`add`,{name:b(x({name:`name`})).pipe(S(`Component or registry item to add`)),target:b(x({name:`target`})).pipe(S(`Optional add target`)),noInstall:T(`no-install`).pipe(E(`Skip package installation`)),CI:T(`ci`).pipe(E(`Deprecated alias for --non-interactive`)),nonInteractive:T(`non-interactive`).pipe(E(`Never prompt for input; fail when required values are missing`)),debug:T(`debug`).pipe(E(`Run in debug mode`))},({name:e,target:t,noInstall:n,CI:r,nonInteractive:i,debug:a})=>$(async()=>{let[{runAdd:o},{initProgramState:s,state:c}]=await Promise.all([import(`./add-h15IdCWp.js`),import(`./state-BVEcvFT3.js`).then(e=>e.i)]);s({noInstall:n,ci:r,nonInteractive:i,debug:a}),c.baseCommand=`add`,c.projectDir=process.cwd(),await o(j(e),{noInstall:n,target:j(t)})},{nonInteractive:r||i,debug:a})).pipe(w(`Legacy command. Prefer package-native tools, agents, or shadcn.`))}function Tn(){return C(`remove`,{name:b(x({name:`name`})).pipe(S(`Component type to remove`)),CI:T(`ci`).pipe(E(`Deprecated alias for --non-interactive`)),nonInteractive:T(`non-interactive`).pipe(E(`Never prompt for input; fail when required values are missing`)),debug:T(`debug`).pipe(E(`Run in debug mode`))},({name:e,CI:t,nonInteractive:n,debug:r})=>$(async()=>{let[{runRemove:i},{initProgramState:a,state:o}]=await Promise.all([import(`./remove-COo1Ju8v.js`),import(`./state-BVEcvFT3.js`).then(e=>e.i)]);a({ci:t,nonInteractive:n,debug:r}),o.baseCommand=`remove`,o.projectDir=process.cwd(),await i(j(e))},{nonInteractive:t||n,debug:r})).pipe(w(`Legacy command. Prefer direct code edits or package-native tools.`))}function En(){return C(`typegen`,{debug:T(`debug`).pipe(E(`Run in debug mode`))},({debug:e})=>$(async()=>{let[{runTypegen:e},{state:t}]=await Promise.all([import(`./typegen-DrfVmQfx.js`),import(`./state-BVEcvFT3.js`).then(e=>e.i)]);t.projectDir=process.cwd(),await e({settings:(await import(`./parseSettings-xU5Rw3Ne.js`).then(e=>e.i)).getSettings()})},{debug:e})).pipe(w("Legacy alias. Prefer `npx @proofkit/typegen`."))}function Dn(){return C(`deploy`,{debug:T(`debug`).pipe(E(`Run in debug mode`))},({debug:e})=>$(async()=>{let[{runDeploy:t},{initProgramState:n,state:r}]=await Promise.all([import(`./deploy-BJryOaec.js`),import(`./state-BVEcvFT3.js`).then(e=>e.i)]);n({debug:e}),r.baseCommand=`deploy`,r.projectDir=process.cwd(),await t()},{debug:e})).pipe(w(`Deploy your app`))}function On(){return C(`upgrade`,{CI:T(`ci`).pipe(E(`Deprecated alias for --non-interactive`)),nonInteractive:T(`non-interactive`).pipe(E(`Never prompt for input; fail when required values are missing`)),debug:T(`debug`).pipe(E(`Run in debug mode`))},({CI:e,nonInteractive:t,debug:n})=>$(async()=>{let[{runUpgrade:r},{initProgramState:i,state:a}]=await Promise.all([import(`./update-Cpyhj57Y.js`),import(`./state-BVEcvFT3.js`).then(e=>e.i)]);i({ci:e,nonInteractive:t,debug:n}),a.baseCommand=`upgrade`,a.projectDir=process.cwd(),await r()},{nonInteractive:e||t,debug:n})).pipe(w(`Legacy command.`))}function kn(){return C(`doctor`,{debug:T(`debug`).pipe(E(`Run in debug mode`))},({debug:e})=>Z({cwd:process.cwd(),debug:e===!0,nonInteractive:!0})(Be)).pipe(w(`Inspect project health and suggest exact next steps`))}function An(){return C(`prompt`,{debug:T(`debug`).pipe(E(`Run in debug mode`))},({debug:e})=>Z({cwd:process.cwd(),debug:e===!0,nonInteractive:!0})(mt)).pipe(w(`Agent workflow entrypoint placeholder`))}const jn=ee(C(a,{CI:T(`ci`).pipe(E(`Deprecated alias for --non-interactive`)),nonInteractive:T(`non-interactive`).pipe(E(`Never prompt for input; fail when required values are missing`)),debug:T(`debug`).pipe(E(`Run in debug mode`))},e=>Z({cwd:process.cwd(),debug:e.debug===!0,nonInteractive:pn({CI:e.CI,nonInteractive:e.nonInteractive,...Sn()})})(yn({...gn,CI:e.CI,nonInteractive:e.nonInteractive,debug:e.debug}))).pipe(w(`Interactive CLI to scaffold and manage ProofKit projects`),te([Cn(),kn(),An(),wn(),Tn(),En(),Dn(),On()])),{name:`ProofKit`,version:_n()});function Mn(e,t){if(!e)return!1;let n=y(t);try{return _(e)===_(n)}catch{return v.resolve(e)===v.resolve(n)}}const Nn=Mn(process.argv[1],import.meta.url),Pn=new Set([`--debug`]);function Fn(e){return e.some(e=>Pn.has(e))}function In(e,t){let n=j(D.failureOption(e));if(n&&oe(n)){t&&console.error(`\n[debug] ${D.pretty(e)}`);return}if(n&&u(n))console.error(c(n));else{let t=D.squash(e);console.error(t instanceof Error?t.message:String(t))}t&&console.error(`\n[debug] ${D.pretty(e)}`)}async function Ln(e){let t=Fn(e),n=await k.runPromiseExit(k.provide(jn(e),se));ce.isFailure(n)&&(In(n.cause,t),process.exitCode=1)}Nn&&(hn(_n()),Ln(process.argv).catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1}));export{jn as cli,In as renderFailure,yn as runDefaultCommand,vn as runInit};
|
|
11
14
|
//# sourceMappingURL=index.js.map
|