@tailorkit/cli 0.1.0-beta.22 → 0.1.0-beta.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -190,4 +190,4 @@ export const greeting = tk.query
|
|
|
190
190
|
<path d="M3 6h6v6H3z" style="fill:#262626" transform="matrix(1.5 0 0 1.5 10.5 -9)"/>
|
|
191
191
|
<path d="M2 6v12h12v-6H8V6z" style="fill:#262626" transform="matrix(1.5 0 0 1.5 -3 -3)"/>
|
|
192
192
|
</svg>
|
|
193
|
-
`,$r=new fe({strictVariables:!0}),ei=(e,t)=>$r.parseAndRender(e,t),ti=e=>g(e,{recursive:!0}).then(()=>{}),ni=async(e,t,n)=>{if(!n&&le(e))throw Error(`${e} already exists. Use --force to overwrite it.`);await C(e,t,`utf-8`)},ri=async e=>{let{targetDirectory:t,force:n,formatting:r,hostUrl:i,schema:a,linting:o,packageName:s,packageVersions:c,useWorkspaceDependencies:l}=e,u=Object.keys(a.slots??{}).sort(),d=Object.keys(a.views??{}).sort().find(e=>u.some(t=>a.slots?.[t]?.views.includes(e)));if(d===void 0)throw Error(`The host schema has no views supported by a slot. Add a view and slot before running tailorkit init.`);let f=u.find(e=>a.slots?.[e]?.views.includes(d)),p=a.components?.Box,m=p?.children===!0&&!p.fields?.required?.length,h=E.join(t,`src`,`tailorkit.gen.ts`);if(!n&&le(h))throw Error(`${h} already exists. Use --force to overwrite it.`);let g=l?`workspace:*`:c.tailorkit,_=[],v=[];o&&(_.push(`pnpm run lint`),v.push(`pnpm run lint:fix`)),r&&(_.push(`pnpm run format`),v.push(`pnpm run format:fix`));let y={viewPath:JSON.stringify(d),slotName:JSON.stringify(f),multiple:a.slots?.[f]?.multiple===!0,useBox:m,checkScript:_.join(` && `),fixScript:v.join(` && `),formatting:r,hostUrl:i,linting:o,oxfmtVersion:c.oxfmt,oxlintVersion:c.oxlint,packageName:s,preactVersion:c.preact,tailorkitVersion:g,typescriptVersion:c.typescript,zodVersion:c.zod??`^4.0.0`,drizzleKitVersion:c.drizzleKit??`1.0.0-rc.4-5d5b77c`,drizzleOrmVersion:c.drizzleOrm??`1.0.0-rc.4-5d5b77c`};await ti(E.join(t,`src`,`views`)),await ti(E.join(t,`src`,`functions`));let b=[{template:Br,dest:`package.json`},{template:Vr,dest:`tsconfig.json`},{template:Hr,dest:`tailorkit.config.ts`},{template:Zr,dest:`logo-dark.svg`},{template:Qr,dest:`logo-light.svg`},{template:Ur,dest:`.gitignore`},{template:Wr,dest:`oxlint.config.ts`,condition:o},{template:Gr,dest:`oxfmt.config.ts`,condition:r},{template:Kr,dest:E.join(`src`,`client.ts`)},{template:qr,dest:E.join(`src`,`views`,`default.tsx`)},{template:Jr,dest:E.join(`src`,`server.ts`)},{template:Yr,dest:E.join(`src`,`schema.ts`)},{template:Xr,dest:E.join(`src`,`functions`,`greeting.ts`)}];await Promise.all(b.filter(e=>e.condition!==!1).map(async({template:e,dest:r})=>{let i=await ei(e,y);await ni(E.join(t,r),i,n)})),await Mr({cwd:t,schema:a})},ii=[`pnpm`,`yarn`,`npm`,`bun`],ai=e=>ii.includes(e),oi=e=>e.trim().toLowerCase().replaceAll(/[^a-z0-9._/-]+/gu,`-`).replaceAll(/^-+|-+$/gu,``),Z=e=>(s(e)&&(i(`Init cancelled.`),process.exit(0)),e),si=(e,t)=>E.resolve(t,e??`.`),ci=async(e,t)=>{let n=oi(E.basename(t))||`tailorkit-app`;return oi(e===void 0?Z(await f({defaultValue:n,message:`Package name`,placeholder:n,validate:e=>oi(e??``).length===0?`Enter a package name.`:void 0})):e)},li=async e=>{if(e!==void 0){if(ai(e))return e;throw Error(`--package-manager must be one of: ${ii.join(`, `)}.`)}return Z(await u({initialValue:`pnpm`,message:`Package manager`,options:ii.map(e=>({label:e,value:e}))}))},ui=async e=>e===void 0?Z(await a({initialValue:!0,message:`Add linting with oxlint?`})):e,di=async e=>e===void 0?Z(await a({initialValue:!0,message:`Add formatting with oxfmt?`})):e,fi=e=>{try{gn(e??``);return}catch{return`Enter a valid host URL.`}},pi=async e=>{if(e!==void 0){let t=fi(e);if(t!==void 0)throw Error(t);return gn(e)}let t=`https://example.com/api/tailorkit`;return gn(Z(await f({defaultValue:t,message:`Host URL`,placeholder:t,validate:fi})))},mi=async e=>e===void 0?Z(await a({initialValue:!0,message:`Install dependencies?`})):e,hi=async(e,t)=>t||!le(e)?t:Z(await a({initialValue:!1,message:`${m.cyan(e)} already exists. Overwrite matching files?`})),gi=(e,t,n)=>new Promise((r,i)=>{let a=ce(e,t,{cwd:n,stdio:`inherit`});a.on(`close`,r),a.on(`error`,i)}),_i=async(e,t)=>{let n=d();n.start(`Installing dependencies with ${t}`);let r=await gi(t,[`install`],e);if(r!==0)throw n.stop(`Install failed.`),Error(`${t} install exited with code ${r}.`);n.stop(`Installed dependencies.`)},vi=async(e,t)=>{let n=d();n.start(`Formatting project`);let r=await gi(t,[`run`,`format:fix`],e);if(r!==0)throw n.stop(`Formatting failed.`),Error(`${t} run format:fix exited with code ${r}.`);n.stop(`Formatted project.`)},yi=async e=>{let t=si(e.directory,e.cwd),n=await ci(e.name,t),r=E.join(t,n),i=await hi(r,e.force??!1),a=await li(e.packageManager),o=await pi(e.host),s=await ui(e.linting),c=await di(e.formatting),l=await mi(e.install),u=d();u.start(`Fetching host schema`);let f;try{f=await jr(o),u.stop(`Fetched host schema.`)}catch(e){throw u.stop(`Unable to fetch host schema.`),e}u.start(`Resolving package versions`);let p=await zr();return u.stop(`Resolved package versions.`),await g(r,{recursive:!0}),await ri({force:i,formatting:c,hostUrl:o,linting:s,packageName:n,packageVersions:p,schema:f,targetDirectory:r}),l&&(await _i(r,a),c&&await vi(r,a)),r},bi=262144,xi={".css":`text/css; charset=utf-8`,".html":`text/html; charset=utf-8`,".js":`text/javascript; charset=utf-8`,".json":`application/json; charset=utf-8`,".map":`application/json; charset=utf-8`},Q=e=>e instanceof Error?e.message:String(e),Si=e=>typeof e==`object`&&!!e&&`code`in e&&e.code===`UNAUTHORIZED`&&`message`in e&&typeof e.message==`string`&&/Preview session is unavailable|Preview developer reconnect grace expired|Preview CLI token is unavailable/u.test(e.message);async function Ci(e){let t=await b(e),n=(await y(t,{recursive:!0,withFileTypes:!0})).filter(e=>e.isFile()).toSorted((e,t)=>E.join(e.parentPath,e.name).localeCompare(E.join(t.parentPath,t.name)));if(n.length>100)throw Error(`Preview build exceeds 100 files.`);let r=[],i={files:[]},a=0;for(let e of n){let n=await b(E.join(e.parentPath,e.name)),o=E.relative(t,n).replaceAll(E.sep,`/`);if(!o||o.startsWith(`../`)||E.isAbsolute(o))throw Error(`Preview file escapes the build output.`);let s=await v(n);if(s.length>1048576)throw Error(`Preview file ${o} exceeds 1 MiB.`);if(a+=s.length,a>10485760)throw Error(`Preview build exceeds 10 MiB.`);o===`views.json`&&(i.views=Ot.shape.views.unwrap().parse(JSON.parse(s.toString(`utf8`)))),r.push(s),i.files.push({path:o,contentType:xi[E.extname(o)]??`application/octet-stream`,size:s.length,chunks:Math.ceil(s.length/bi),sha256:oe(`sha256`).update(s).digest(`hex`)})}if(!i.files.some(e=>e.path===`client.js`))throw Error(`Preview build is missing client.js.`);return{files:r,manifest:i,fingerprint:oe(`sha256`).update(JSON.stringify(i)).digest(`hex`)}}function wi(e,t,n){let r=0;return async()=>{let i=++r;try{let n=await e();i===r&&t(n)}catch(e){i===r&&n(e)}}}async function Ti(e,t){let{buildId:n}=await e.beginBuild({manifest:t.manifest});for(let[r,i]of t.files.entries())for(let a=0;a<(t.manifest.files[r]?.chunks??0);a++)await e.uploadChunk({buildId:n,fileIndex:r,chunkIndex:a,base64:i.subarray(a*bi,(a+1)*bi).toString(`base64`)});await e.commitBuild({buildId:n})}var Ei=k.object({config:k.string().optional(),cwd:k.string().default(`.`),mode:k.string().optional(),outDir:k.string().optional(),replace:k.boolean().optional()}),Di=e=>{let t=Ei.parse(e);return{configPath:t.config,cwd:t.cwd,mode:t.mode,outDir:t.outDir,replace:t.replace}};async function Oi(e){let t=await ee(e.configPath,e.cwd);if(!t.config.appId)throw Error(`Missing appId. Deploy once before starting a remote preview.`);let n=await Ln(e),r=await Fn(n.hostUrl);if(!r?.deployToken)throw Error(`Not logged in. Run tailorkit login first.`);let{buildApp:i}=await import(`@tailorkit/app/builder`),a=await i({...e,watch:!0}),o=async()=>{a&&typeof a==`object`&&`close`in a&&await a.close()},s=await L({headers:{authorization:`Bearer ${r.deployToken}`},url:n.hostUrl}).preview.start({appId:t.config.appId,replaceActive:e.replace}).catch(async e=>{throw await o(),e}),l=`data`in s?s.data:s;if(!l)throw await o(),Error(`Unable to start preview session.`);let u=L({fetch:(e,t)=>fetch(e,{...t,signal:AbortSignal.timeout(5e3)}),headers:{authorization:`Bearer ${r.deployToken}`},url:n.hostUrl}),d=async()=>{try{await u.preview.stop({sessionId:l.sessionId})}catch(e){c.warn(`Unable to end preview session: ${Q(e)}`)}},f=E.resolve(t.root,e.outDir??t.config.build?.outDir??`.tailorkit`),p,h;try{p=await b(E.join(f,`client`)),h=await Ci(p)}catch(e){try{await o()}catch(e){c.warn(`Unable to close preview watcher: ${Q(e)}`)}throw await d(),e}let g,_,v,y=!1,x=!1,S,C,w,T=0,D=1e3,O=0,te=()=>{y||(y=!0,process.off(`SIGINT`,A),process.off(`SIGTERM`,A),S&&clearTimeout(S),C&&clearTimeout(C),w&&clearInterval(w),v?.close(),o().catch(e=>{c.warn(`Unable to close preview watcher: ${Q(e)}`)}),c.warn(`Preview session ended. Start a new preview to continue.`))},ne=()=>{y||!_||x||(S&&clearTimeout(S),S=setTimeout(()=>{if(S=void 0,!_||h.fingerprint===g)return;let e=h,t=_,n=O;x=!0,T=Date.now(),Ti(t,e).then(()=>{n===O&&(g=e.fingerprint)}).catch(e=>{y||c.warn(`Preview upload interrupted: ${Q(e)}`)}).finally(()=>{n===O&&(x=!1,h.fingerprint!==g&&ne())})},Math.max(500,500-(Date.now()-T))))},re=wi(()=>Ci(p),e=>{y||(h=e,ne())},e=>{y||c.warn(`Keeping the last successful preview: ${Q(e)}`)});a&&typeof a==`object`&&`on`in a&&a.on(`event`,e=>{e.code===`BUNDLE_END`&&re()});let k=()=>{if(y)return;let e=new URL(l.tunnelUrl);e.searchParams.set(`role`,`uploader`);let t=new WebSocket(e,l.tunnelToken);v=t,t.addEventListener(`open`,()=>{O+=1,D=1e3,_=Ft(t);let e=()=>void _?.heartbeat().catch(e=>{v!==t||y||(Si(e)?te():t.close())});e(),w=setInterval(e,2e4),ne()}),t.addEventListener(`close`,()=>{O+=1,x=!1,w&&clearInterval(w),v===t&&(v=void 0,_=void 0),y||(C=setTimeout(k,D),D=Math.min(D*2,3e4))}),t.addEventListener(`error`,()=>t.close())};k();let A=()=>{y||(y=!0,process.off(`SIGINT`,A),process.off(`SIGTERM`,A),o().catch(e=>{c.warn(`Unable to close preview watcher: ${Q(e)}`)}),S&&clearTimeout(S),C&&clearTimeout(C),w&&clearInterval(w),v?.close(),d().finally(()=>process.exit(0)))};process.once(`SIGINT`,A),process.once(`SIGTERM`,A);let ie=new URL(n.hostUrl);ie.pathname=`${ie.pathname.replace(/\/+$/u,``)}/preview/${l.shareId}`,c.info(m.green(`Host preview: ${ie.href}`)),c.info(m.dim(`Uploading built app assets from ${p}`))}var ki=e=>{let t=T();return t===`darwin`?{args:[e],command:`open`}:t===`win32`?{args:[`/c`,`start`,``,e],command:`cmd`}:{args:[e],command:`xdg-open`}},Ai=e=>new Promise(t=>{let{args:n,command:r}=ki(e),i=ce(r,n,{detached:!0,stdio:`ignore`,windowsHide:!0});i.once(`error`,()=>{t(!1)}),i.once(`spawn`,()=>{i.unref(),t(!0)})}),$=p(`tailorkit`),ji=e=>{if(e<1024)return`${e} B`;let t=[`KB`,`MB`,`GB`],n=e/1024,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r+=1;return`${n.toFixed(n>=10?1:2)} ${t[r]}`},Mi=async(e,t=!0)=>{let n=d(),r=!1;try{let i=await In(e,({expiresAt:e,hostUrl:i,userCode:a})=>{let o=jn(i,a);t&&Ai(o),c.info(`Enter this code in the host app: ${m.bold(a)}`),c.info(`Approval URL: ${m.cyan(o)}`),c.info(`Code expires at ${e.toLocaleString()}.`),c.info(`Waiting for approval...`),n.start(`Checking approval status`),r=!0});return r&&n.stop(`Approved.`),i}catch(e){throw r&&n.stop(`Approval failed.`),e}};$.option(`--cwd <path>`,`Working directory`,{default:`.`}),$.command(`preview`,`Preview the app inside a host app`).option(`--config <path>`,`Path to tailorkit config`).option(`--out-dir <path>`,`Build output directory`).option(`--mode <mode>`,`Vite mode`).option(`--replace`,`End the active preview for this app and start a new one`).action(async e=>{o(m.bold(`TailorKit`));try{await Oi(Di(e))}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`login`,`Authenticate the TailorKit CLI with a host app`).option(`--config <path>`,`Path to tailorkit config`).option(`--open`,`Open the approval URL in the default browser`,{default:!0}).option(`--timeout <seconds>`,`Seconds to wait for approval`,{default:1800}).action(async e=>{o(m.bold(`TailorKit`));try{let t=Number.parseInt(String(e.timeout??`1800`),10);if(!Number.isInteger(t)||t<=0)throw Error(`--timeout must be a positive integer.`);await Mi({configPath:e.config,cwd:String(e.cwd??`.`),timeout:t*1e3},e.open!==!1),l(`Authenticated successfully.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`logout`,`Remove stored TailorKit CLI credentials for a host app`).option(`--config <path>`,`Path to tailorkit config`).action(async e=>{o(m.bold(`TailorKit`));try{let t=await Rn({configPath:e.config,cwd:String(e.cwd??`.`)});l(t.removed?`Logged out of ${m.cyan(t.hostUrl)}.`:`No stored credentials found for ${m.cyan(t.hostUrl)}.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`whoami`,`Show the current TailorKit CLI authentication scope`).option(`--config <path>`,`Path to tailorkit config`).action(async e=>{o(m.bold(`TailorKit`));try{let t=await Ln({configPath:e.config,cwd:String(e.cwd??`.`)});c.info(`Host: ${m.cyan(t.hostUrl)}`),c.info(`Scope: ${m.cyan(JSON.stringify(t.scope))}`),l(`Authenticated.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`deploy`,`Build and deploy the TailorKit app`).option(`--config <path>`,`Path to tailorkit config`).option(`--out-dir <path>`,`Build output directory`).option(`--mode <mode>`,`Vite mode`).action(async e=>{o(m.bold(`TailorKit`));let t=d();try{t.start(`Building and deploying app`);let n=await Zn({configPath:e.config,cwd:String(e.cwd??`.`),mode:e.mode,onLoginRequired:async()=>{t.stop(`Authentication required.`);let n=await Mi({configPath:e.config,cwd:String(e.cwd??`.`)});return t.start(`Building and deploying app`),n},onMissingAppId:async({appName:e,configPath:n,hostUrl:r,reason:i})=>{t.stop(`App not linked.`),c.info(i===`missing`?`No appId found in ${m.cyan(n)}.`:`The appId in ${m.cyan(n)} does not exist.`),c.info(`Host: ${m.cyan(r)}`);let o=await a({initialValue:!0,message:i===`missing`?`Create a TailorKit app named ${e}?`:`Create a new TailorKit app named ${e} and update the config?`});return!s(o)&&(o&&t.start(`Creating app and deploying`),o===!0)},onTypecheckFailed:async({command:e,output:n})=>{t.stop(`Type check failed.`),c.error(`Type check failed while running ${m.cyan(e)}.`),n&&c.error(n);let r=await a({initialValue:!1,message:`Type check failed, but the app built successfully. Upload anyway?`});return!s(r)&&(r&&t.start(`Uploading app`),r===!0)},outDir:e.outDir});t.stop(`Deployed app.`),n.createdApp&&c.info(`Created app and updated tailorkit.config.ts with ${m.cyan(n.appId)}.`),c.info(`Host: ${m.cyan(n.hostUrl)}`),c.info(`App: ${m.cyan(n.appId)}`),c.info(`Deployment: ${m.cyan(n.deploymentId)}`),c.info(`Uploaded files:`);for(let e of n.uploadedFiles)c.info(` ${m.cyan(e.path)} ${m.dim(`${ji(e.size)} raw, ${ji(e.gzipSize)} gzip`)}`);n.status&&c.info(`Status: ${m.cyan(n.status)}`),l(`Deployment published.`)}catch(e){t.stop(`Deployment failed.`),c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`build`,`Build the TailorKit app`).option(`--config <path>`,`Path to tailorkit config`).option(`--out-dir <path>`,`Build output directory`).option(`--mode <mode>`,`Vite mode`).action(async e=>{o(m.bold(`TailorKit`));try{let{buildApp:t}=await import(`@tailorkit/app/builder`);await t({configPath:e.config,cwd:String(e.cwd??`.`),mode:e.mode,outDir:e.outDir}),l(`Built app.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`db <command>`,`Generate database migrations with db generate`).option(`--config <path>`,`Path to tailorkit config`).option(`--name <name>`,`Migration name`).action(async(e,t)=>{o(m.bold(`TailorKit`));try{if(e!==`generate`)throw Error(`Unknown database command: ${e}. Use tailorkit db generate.`);let{generateAppMigrations:n}=await import(`@tailorkit/app/builder`),r=await n({configPath:t.config,cwd:String(t.cwd??`.`),name:t.name});l(`Migrations are up to date in ${m.cyan(r)}.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`generate`,`Generate TailorKit app bindings`).option(`--config <path>`,`Path to tailorkit config`).option(`--out <path>`,`Generated TypeScript output file`).action(async e=>{o(m.bold(`TailorKit`));try{let t=await Mr({configPath:e.config,cwd:String(e.cwd??`.`),outFile:e.out});l(`Generated ${m.cyan(t)}.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`init [directory]`,`Create a new TailorKit app`).option(`--name <name>`,`Package name`).option(`--host <url>`,`TailorKit host URL`).option(`--package-manager <pm>`,`Package manager: bun, yarn, pnpm, or npm`).option(`--lint`,`Add oxlint (use --no-lint to skip)`).option(`--format`,`Add oxfmt (use --no-format to skip)`).option(`--install`,`Install dependencies after scaffolding (use --no-install to skip)`).option(`--force`,`Overwrite existing files`).action(async(e,t)=>{o(m.bold(`TailorKit`));try{let n=await yi({cwd:String(t.cwd??`.`),directory:e,force:t.force,formatting:t.format,host:t.host,install:t.install,linting:t.lint,name:t.name,packageManager:t.packageManager});l(`Created app at ${m.cyan(n)}.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`agent`,`Chat with the TailorKit app agent`).option(`--app <id>`,`App ID (uses config appId, or prompts to select or create an app)`).option(`--config <path>`,`Path to tailorkit config`).action(async e=>{try{let{runAgentCommand:t}=await import(`./assets/agent-BSIUE6vC.js`);await t({appId:e.app,configPath:e.config,cwd:String(e.cwd??`.`),onLoginRequired:()=>Mi({configPath:e.config,cwd:String(e.cwd??`.`)})})}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exitCode=1}}),$.help(),$.version(`0.1.0-beta.22`),$.parse();export{An as a,Fn as i,Bn as n,Ln as o,Mn as r,L as s,zn as t};
|
|
193
|
+
`,$r=new fe({strictVariables:!0}),ei=(e,t)=>$r.parseAndRender(e,t),ti=e=>g(e,{recursive:!0}).then(()=>{}),ni=async(e,t,n)=>{if(!n&&le(e))throw Error(`${e} already exists. Use --force to overwrite it.`);await C(e,t,`utf-8`)},ri=async e=>{let{targetDirectory:t,force:n,formatting:r,hostUrl:i,schema:a,linting:o,packageName:s,packageVersions:c,useWorkspaceDependencies:l}=e,u=Object.keys(a.slots??{}).sort(),d=Object.keys(a.views??{}).sort().find(e=>u.some(t=>a.slots?.[t]?.views.includes(e)));if(d===void 0)throw Error(`The host schema has no views supported by a slot. Add a view and slot before running tailorkit init.`);let f=u.find(e=>a.slots?.[e]?.views.includes(d)),p=a.components?.Box,m=p?.children===!0&&!p.fields?.required?.length,h=E.join(t,`src`,`tailorkit.gen.ts`);if(!n&&le(h))throw Error(`${h} already exists. Use --force to overwrite it.`);let g=l?`workspace:*`:c.tailorkit,_=[],v=[];o&&(_.push(`pnpm run lint`),v.push(`pnpm run lint:fix`)),r&&(_.push(`pnpm run format`),v.push(`pnpm run format:fix`));let y={viewPath:JSON.stringify(d),slotName:JSON.stringify(f),multiple:a.slots?.[f]?.multiple===!0,useBox:m,checkScript:_.join(` && `),fixScript:v.join(` && `),formatting:r,hostUrl:i,linting:o,oxfmtVersion:c.oxfmt,oxlintVersion:c.oxlint,packageName:s,preactVersion:c.preact,tailorkitVersion:g,typescriptVersion:c.typescript,zodVersion:c.zod??`^4.0.0`,drizzleKitVersion:c.drizzleKit??`1.0.0-rc.4-5d5b77c`,drizzleOrmVersion:c.drizzleOrm??`1.0.0-rc.4-5d5b77c`};await ti(E.join(t,`src`,`views`)),await ti(E.join(t,`src`,`functions`));let b=[{template:Br,dest:`package.json`},{template:Vr,dest:`tsconfig.json`},{template:Hr,dest:`tailorkit.config.ts`},{template:Zr,dest:`logo-dark.svg`},{template:Qr,dest:`logo-light.svg`},{template:Ur,dest:`.gitignore`},{template:Wr,dest:`oxlint.config.ts`,condition:o},{template:Gr,dest:`oxfmt.config.ts`,condition:r},{template:Kr,dest:E.join(`src`,`client.ts`)},{template:qr,dest:E.join(`src`,`views`,`default.tsx`)},{template:Jr,dest:E.join(`src`,`server.ts`)},{template:Yr,dest:E.join(`src`,`schema.ts`)},{template:Xr,dest:E.join(`src`,`functions`,`greeting.ts`)}];await Promise.all(b.filter(e=>e.condition!==!1).map(async({template:e,dest:r})=>{let i=await ei(e,y);await ni(E.join(t,r),i,n)})),await Mr({cwd:t,schema:a})},ii=[`pnpm`,`yarn`,`npm`,`bun`],ai=e=>ii.includes(e),oi=e=>e.trim().toLowerCase().replaceAll(/[^a-z0-9._/-]+/gu,`-`).replaceAll(/^-+|-+$/gu,``),Z=e=>(s(e)&&(i(`Init cancelled.`),process.exit(0)),e),si=(e,t)=>E.resolve(t,e??`.`),ci=async(e,t)=>{let n=oi(E.basename(t))||`tailorkit-app`;return oi(e===void 0?Z(await f({defaultValue:n,message:`Package name`,placeholder:n,validate:e=>oi(e??``).length===0?`Enter a package name.`:void 0})):e)},li=async e=>{if(e!==void 0){if(ai(e))return e;throw Error(`--package-manager must be one of: ${ii.join(`, `)}.`)}return Z(await u({initialValue:`pnpm`,message:`Package manager`,options:ii.map(e=>({label:e,value:e}))}))},ui=async e=>e===void 0?Z(await a({initialValue:!0,message:`Add linting with oxlint?`})):e,di=async e=>e===void 0?Z(await a({initialValue:!0,message:`Add formatting with oxfmt?`})):e,fi=e=>{try{gn(e??``);return}catch{return`Enter a valid host URL.`}},pi=async e=>{if(e!==void 0){let t=fi(e);if(t!==void 0)throw Error(t);return gn(e)}let t=`https://example.com/api/tailorkit`;return gn(Z(await f({defaultValue:t,message:`Host URL`,placeholder:t,validate:fi})))},mi=async e=>e===void 0?Z(await a({initialValue:!0,message:`Install dependencies?`})):e,hi=async(e,t)=>t||!le(e)?t:Z(await a({initialValue:!1,message:`${m.cyan(e)} already exists. Overwrite matching files?`})),gi=(e,t,n)=>new Promise((r,i)=>{let a=ce(e,t,{cwd:n,stdio:`inherit`});a.on(`close`,r),a.on(`error`,i)}),_i=async(e,t)=>{let n=d();n.start(`Installing dependencies with ${t}`);let r=await gi(t,[`install`],e);if(r!==0)throw n.stop(`Install failed.`),Error(`${t} install exited with code ${r}.`);n.stop(`Installed dependencies.`)},vi=async(e,t)=>{let n=d();n.start(`Formatting project`);let r=await gi(t,[`run`,`format:fix`],e);if(r!==0)throw n.stop(`Formatting failed.`),Error(`${t} run format:fix exited with code ${r}.`);n.stop(`Formatted project.`)},yi=async e=>{let t=si(e.directory,e.cwd),n=await ci(e.name,t),r=E.join(t,n),i=await hi(r,e.force??!1),a=await li(e.packageManager),o=await pi(e.host),s=await ui(e.linting),c=await di(e.formatting),l=await mi(e.install),u=d();u.start(`Fetching host schema`);let f;try{f=await jr(o),u.stop(`Fetched host schema.`)}catch(e){throw u.stop(`Unable to fetch host schema.`),e}u.start(`Resolving package versions`);let p=await zr();return u.stop(`Resolved package versions.`),await g(r,{recursive:!0}),await ri({force:i,formatting:c,hostUrl:o,linting:s,packageName:n,packageVersions:p,schema:f,targetDirectory:r}),l&&(await _i(r,a),c&&await vi(r,a)),r},bi=262144,xi={".css":`text/css; charset=utf-8`,".html":`text/html; charset=utf-8`,".js":`text/javascript; charset=utf-8`,".json":`application/json; charset=utf-8`,".map":`application/json; charset=utf-8`},Q=e=>e instanceof Error?e.message:String(e),Si=e=>typeof e==`object`&&!!e&&`code`in e&&e.code===`UNAUTHORIZED`&&`message`in e&&typeof e.message==`string`&&/Preview session is unavailable|Preview developer reconnect grace expired|Preview CLI token is unavailable/u.test(e.message);async function Ci(e){let t=await b(e),n=(await y(t,{recursive:!0,withFileTypes:!0})).filter(e=>e.isFile()).toSorted((e,t)=>E.join(e.parentPath,e.name).localeCompare(E.join(t.parentPath,t.name)));if(n.length>100)throw Error(`Preview build exceeds 100 files.`);let r=[],i={files:[]},a=0;for(let e of n){let n=await b(E.join(e.parentPath,e.name)),o=E.relative(t,n).replaceAll(E.sep,`/`);if(!o||o.startsWith(`../`)||E.isAbsolute(o))throw Error(`Preview file escapes the build output.`);let s=await v(n);if(s.length>1048576)throw Error(`Preview file ${o} exceeds 1 MiB.`);if(a+=s.length,a>10485760)throw Error(`Preview build exceeds 10 MiB.`);o===`views.json`&&(i.views=Ot.shape.views.unwrap().parse(JSON.parse(s.toString(`utf8`)))),r.push(s),i.files.push({path:o,contentType:xi[E.extname(o)]??`application/octet-stream`,size:s.length,chunks:Math.ceil(s.length/bi),sha256:oe(`sha256`).update(s).digest(`hex`)})}if(!i.files.some(e=>e.path===`client.js`))throw Error(`Preview build is missing client.js.`);return{files:r,manifest:i,fingerprint:oe(`sha256`).update(JSON.stringify(i)).digest(`hex`)}}function wi(e,t,n){let r=0;return async()=>{let i=++r;try{let n=await e();i===r&&t(n)}catch(e){i===r&&n(e)}}}async function Ti(e,t){let{buildId:n}=await e.beginBuild({manifest:t.manifest});for(let[r,i]of t.files.entries())for(let a=0;a<(t.manifest.files[r]?.chunks??0);a++)await e.uploadChunk({buildId:n,fileIndex:r,chunkIndex:a,base64:i.subarray(a*bi,(a+1)*bi).toString(`base64`)});await e.commitBuild({buildId:n})}var Ei=k.object({config:k.string().optional(),cwd:k.string().default(`.`),mode:k.string().optional(),outDir:k.string().optional(),replace:k.boolean().optional()}),Di=e=>{let t=Ei.parse(e);return{configPath:t.config,cwd:t.cwd,mode:t.mode,outDir:t.outDir,replace:t.replace}};async function Oi(e){let t=await ee(e.configPath,e.cwd);if(!t.config.appId)throw Error(`Missing appId. Deploy once before starting a remote preview.`);let n=await Ln(e),r=await Fn(n.hostUrl);if(!r?.deployToken)throw Error(`Not logged in. Run tailorkit login first.`);let{buildApp:i}=await import(`@tailorkit/app/builder`),a=await i({...e,watch:!0}),o=async()=>{a&&typeof a==`object`&&`close`in a&&await a.close()},s=await L({headers:{authorization:`Bearer ${r.deployToken}`},url:n.hostUrl}).preview.start({appId:t.config.appId,replaceActive:e.replace}).catch(async e=>{throw await o(),e}),l=`data`in s?s.data:s;if(!l)throw await o(),Error(`Unable to start preview session.`);let u=L({fetch:(e,t)=>fetch(e,{...t,signal:AbortSignal.timeout(5e3)}),headers:{authorization:`Bearer ${r.deployToken}`},url:n.hostUrl}),d=async()=>{try{await u.preview.stop({sessionId:l.sessionId})}catch(e){c.warn(`Unable to end preview session: ${Q(e)}`)}},f=E.resolve(t.root,e.outDir??t.config.build?.outDir??`.tailorkit`),p,h;try{p=await b(E.join(f,`client`)),h=await Ci(p)}catch(e){try{await o()}catch(e){c.warn(`Unable to close preview watcher: ${Q(e)}`)}throw await d(),e}let g,_,v,y=!1,x=!1,S,C,w,T=0,D=1e3,O=0,te=()=>{y||(y=!0,process.off(`SIGINT`,A),process.off(`SIGTERM`,A),S&&clearTimeout(S),C&&clearTimeout(C),w&&clearInterval(w),v?.close(),o().catch(e=>{c.warn(`Unable to close preview watcher: ${Q(e)}`)}),c.warn(`Preview session ended. Start a new preview to continue.`))},ne=()=>{y||!_||x||(S&&clearTimeout(S),S=setTimeout(()=>{if(S=void 0,!_||h.fingerprint===g)return;let e=h,t=_,n=O;x=!0,T=Date.now(),Ti(t,e).then(()=>{n===O&&(g=e.fingerprint)}).catch(e=>{y||c.warn(`Preview upload interrupted: ${Q(e)}`)}).finally(()=>{n===O&&(x=!1,h.fingerprint!==g&&ne())})},Math.max(500,500-(Date.now()-T))))},re=wi(()=>Ci(p),e=>{y||(h=e,ne())},e=>{y||c.warn(`Keeping the last successful preview: ${Q(e)}`)});a&&typeof a==`object`&&`on`in a&&a.on(`event`,e=>{e.code===`BUNDLE_END`&&re()});let k=()=>{if(y)return;let e=new URL(l.tunnelUrl);e.searchParams.set(`role`,`uploader`);let t=new WebSocket(e,l.tunnelToken);v=t,t.addEventListener(`open`,()=>{O+=1,D=1e3,_=Ft(t);let e=()=>void _?.heartbeat().catch(e=>{v!==t||y||(Si(e)?te():t.close())});e(),w=setInterval(e,2e4),ne()}),t.addEventListener(`close`,()=>{O+=1,x=!1,w&&clearInterval(w),v===t&&(v=void 0,_=void 0),y||(C=setTimeout(k,D),D=Math.min(D*2,3e4))}),t.addEventListener(`error`,()=>t.close())};k();let A=()=>{y||(y=!0,process.off(`SIGINT`,A),process.off(`SIGTERM`,A),o().catch(e=>{c.warn(`Unable to close preview watcher: ${Q(e)}`)}),S&&clearTimeout(S),C&&clearTimeout(C),w&&clearInterval(w),v?.close(),d().finally(()=>process.exit(0)))};process.once(`SIGINT`,A),process.once(`SIGTERM`,A);let ie=new URL(n.hostUrl);ie.pathname=`${ie.pathname.replace(/\/+$/u,``)}/preview/${l.shareId}`,c.info(m.green(`Host preview: ${ie.href}`)),c.info(m.dim(`Uploading built app assets from ${p}`))}var ki=e=>{let t=T();return t===`darwin`?{args:[e],command:`open`}:t===`win32`?{args:[`/c`,`start`,``,e],command:`cmd`}:{args:[e],command:`xdg-open`}},Ai=e=>new Promise(t=>{let{args:n,command:r}=ki(e),i=ce(r,n,{detached:!0,stdio:`ignore`,windowsHide:!0});i.once(`error`,()=>{t(!1)}),i.once(`spawn`,()=>{i.unref(),t(!0)})}),$=p(`tailorkit`),ji=e=>{if(e<1024)return`${e} B`;let t=[`KB`,`MB`,`GB`],n=e/1024,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r+=1;return`${n.toFixed(n>=10?1:2)} ${t[r]}`},Mi=async(e,t=!0)=>{let n=d(),r=!1;try{let i=await In(e,({expiresAt:e,hostUrl:i,userCode:a})=>{let o=jn(i,a);t&&Ai(o),c.info(`Enter this code in the host app: ${m.bold(a)}`),c.info(`Approval URL: ${m.cyan(o)}`),c.info(`Code expires at ${e.toLocaleString()}.`),c.info(`Waiting for approval...`),n.start(`Checking approval status`),r=!0});return r&&n.stop(`Approved.`),i}catch(e){throw r&&n.stop(`Approval failed.`),e}};$.option(`--cwd <path>`,`Working directory`,{default:`.`}),$.command(`preview`,`Preview the app inside a host app`).option(`--config <path>`,`Path to tailorkit config`).option(`--out-dir <path>`,`Build output directory`).option(`--mode <mode>`,`Vite mode`).option(`--replace`,`End the active preview for this app and start a new one`).action(async e=>{o(m.bold(`TailorKit`));try{await Oi(Di(e))}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`login`,`Authenticate the TailorKit CLI with a host app`).option(`--config <path>`,`Path to tailorkit config`).option(`--open`,`Open the approval URL in the default browser`,{default:!0}).option(`--timeout <seconds>`,`Seconds to wait for approval`,{default:1800}).action(async e=>{o(m.bold(`TailorKit`));try{let t=Number.parseInt(String(e.timeout??`1800`),10);if(!Number.isInteger(t)||t<=0)throw Error(`--timeout must be a positive integer.`);await Mi({configPath:e.config,cwd:String(e.cwd??`.`),timeout:t*1e3},e.open!==!1),l(`Authenticated successfully.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`logout`,`Remove stored TailorKit CLI credentials for a host app`).option(`--config <path>`,`Path to tailorkit config`).action(async e=>{o(m.bold(`TailorKit`));try{let t=await Rn({configPath:e.config,cwd:String(e.cwd??`.`)});l(t.removed?`Logged out of ${m.cyan(t.hostUrl)}.`:`No stored credentials found for ${m.cyan(t.hostUrl)}.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`whoami`,`Show the current TailorKit CLI authentication scope`).option(`--config <path>`,`Path to tailorkit config`).action(async e=>{o(m.bold(`TailorKit`));try{let t=await Ln({configPath:e.config,cwd:String(e.cwd??`.`)});c.info(`Host: ${m.cyan(t.hostUrl)}`),c.info(`Scope: ${m.cyan(JSON.stringify(t.scope))}`),l(`Authenticated.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`deploy`,`Build and deploy the TailorKit app`).option(`--config <path>`,`Path to tailorkit config`).option(`--out-dir <path>`,`Build output directory`).option(`--mode <mode>`,`Vite mode`).action(async e=>{o(m.bold(`TailorKit`));let t=d();try{t.start(`Building and deploying app`);let n=await Zn({configPath:e.config,cwd:String(e.cwd??`.`),mode:e.mode,onLoginRequired:async()=>{t.stop(`Authentication required.`);let n=await Mi({configPath:e.config,cwd:String(e.cwd??`.`)});return t.start(`Building and deploying app`),n},onMissingAppId:async({appName:e,configPath:n,hostUrl:r,reason:i})=>{t.stop(`App not linked.`),c.info(i===`missing`?`No appId found in ${m.cyan(n)}.`:`The appId in ${m.cyan(n)} does not exist.`),c.info(`Host: ${m.cyan(r)}`);let o=await a({initialValue:!0,message:i===`missing`?`Create a TailorKit app named ${e}?`:`Create a new TailorKit app named ${e} and update the config?`});return!s(o)&&(o&&t.start(`Creating app and deploying`),o===!0)},onTypecheckFailed:async({command:e,output:n})=>{t.stop(`Type check failed.`),c.error(`Type check failed while running ${m.cyan(e)}.`),n&&c.error(n);let r=await a({initialValue:!1,message:`Type check failed, but the app built successfully. Upload anyway?`});return!s(r)&&(r&&t.start(`Uploading app`),r===!0)},outDir:e.outDir});t.stop(`Deployed app.`),n.createdApp&&c.info(`Created app and updated tailorkit.config.ts with ${m.cyan(n.appId)}.`),c.info(`Host: ${m.cyan(n.hostUrl)}`),c.info(`App: ${m.cyan(n.appId)}`),c.info(`Deployment: ${m.cyan(n.deploymentId)}`),c.info(`Uploaded files:`);for(let e of n.uploadedFiles)c.info(` ${m.cyan(e.path)} ${m.dim(`${ji(e.size)} raw, ${ji(e.gzipSize)} gzip`)}`);n.status&&c.info(`Status: ${m.cyan(n.status)}`),l(`Deployment published.`)}catch(e){t.stop(`Deployment failed.`),c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`build`,`Build the TailorKit app`).option(`--config <path>`,`Path to tailorkit config`).option(`--out-dir <path>`,`Build output directory`).option(`--mode <mode>`,`Vite mode`).action(async e=>{o(m.bold(`TailorKit`));try{let{buildApp:t}=await import(`@tailorkit/app/builder`);await t({configPath:e.config,cwd:String(e.cwd??`.`),mode:e.mode,outDir:e.outDir}),l(`Built app.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`db <command>`,`Generate database migrations with db generate`).option(`--config <path>`,`Path to tailorkit config`).option(`--name <name>`,`Migration name`).action(async(e,t)=>{o(m.bold(`TailorKit`));try{if(e!==`generate`)throw Error(`Unknown database command: ${e}. Use tailorkit db generate.`);let{generateAppMigrations:n}=await import(`@tailorkit/app/builder`),r=await n({configPath:t.config,cwd:String(t.cwd??`.`),name:t.name});l(`Migrations are up to date in ${m.cyan(r)}.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`generate`,`Generate TailorKit app bindings`).option(`--config <path>`,`Path to tailorkit config`).option(`--out <path>`,`Generated TypeScript output file`).action(async e=>{o(m.bold(`TailorKit`));try{let t=await Mr({configPath:e.config,cwd:String(e.cwd??`.`),outFile:e.out});l(`Generated ${m.cyan(t)}.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`init [directory]`,`Create a new TailorKit app`).option(`--name <name>`,`Package name`).option(`--host <url>`,`TailorKit host URL`).option(`--package-manager <pm>`,`Package manager: bun, yarn, pnpm, or npm`).option(`--lint`,`Add oxlint (use --no-lint to skip)`).option(`--format`,`Add oxfmt (use --no-format to skip)`).option(`--install`,`Install dependencies after scaffolding (use --no-install to skip)`).option(`--force`,`Overwrite existing files`).action(async(e,t)=>{o(m.bold(`TailorKit`));try{let n=await yi({cwd:String(t.cwd??`.`),directory:e,force:t.force,formatting:t.format,host:t.host,install:t.install,linting:t.lint,name:t.name,packageManager:t.packageManager});l(`Created app at ${m.cyan(n)}.`)}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exit(1)}}),$.command(`agent`,`Chat with the TailorKit app agent`).option(`--app <id>`,`App ID (uses config appId, or prompts to select or create an app)`).option(`--config <path>`,`Path to tailorkit config`).action(async e=>{try{let{runAgentCommand:t}=await import(`./assets/agent-BSIUE6vC.js`);await t({appId:e.app,configPath:e.config,cwd:String(e.cwd??`.`),onLoginRequired:()=>Mi({configPath:e.config,cwd:String(e.cwd??`.`)})})}catch(e){c.error(e instanceof Error?e.message:String(e)),process.exitCode=1}}),$.help(),$.version(`0.1.0-beta.23`),$.parse();export{An as a,Fn as i,Bn as n,Ln as o,Mn as r,L as s,zn as t};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailorkit/cli",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.23",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"@ai-sdk/tui": "1.0.128",
|
|
27
27
|
"@clack/prompts": "^1.8.1",
|
|
28
28
|
"@orpc/client": "2.0.0-beta.40",
|
|
29
|
-
"@tailorkit/app": "0.1.0-beta.
|
|
30
|
-
"@tailorkit/client-platform": "0.1.0-beta.
|
|
31
|
-
"@tailorkit/core": "0.1.0-beta.
|
|
29
|
+
"@tailorkit/app": "0.1.0-beta.23",
|
|
30
|
+
"@tailorkit/client-platform": "0.1.0-beta.23",
|
|
31
|
+
"@tailorkit/core": "0.1.0-beta.23",
|
|
32
32
|
"ai": "^7.0.127",
|
|
33
33
|
"cac": "^7.0.0",
|
|
34
34
|
"jose": "6.2.12",
|