UNPKG

@gqty/cli

Version:

Interactive codegen for GQty

3 lines (2 loc) 5.83 kB
#! /usr/bin/env node import{cosmiconfig as G}from"cosmiconfig";import D from"assert";import{readFile as L,watch as M}from"fs/promises";import d from"path";import v from"process";import"@commander-js/extra-typings";import"@graphql-codegen/core";import"@graphql-codegen/typescript";import"@graphql-tools/utils";import"@graphql-tools/wrap";import*as g from"@inquirer/prompts";import"cross-fetch";import W from"fast-glob";import"graphql";import"lodash-es/sortBy.js";import"prettier";import{convertHeadersInput as S}from"./default/convertHeadersInput.mjs";import{fetchSchema as O,isURL as P}from"./default/fetchSchema.mjs";import{generateClient as q}from"./default/generateClient.mjs";import{getCommandName as A}from"./default/getCommandName.mjs";import{logger as m}from"./default/logger.mjs";import{promptInstall as B,runInstall as F}from"./default/promptInstall.mjs";const Q=e=>e.name(A()).usage("[options] [endpoints...]").argument("[endpoints...]","GraphQL endpoints or schema files.").option("-H, --header <header>","Custom header for the introspection query.",(o,i)=>[...i,o],[]).option("--react","Include React hooks in the generated client.").option("--no-react").option("--solid","Include SolidJS signals in the generated client.").option("--no-solid").option("--subscriptions [client]","Includes specified package as subscription client, must be graphql-ws compatible.").option("--no-subscriptions").option("--target <path>","Destination path for the generated client.").option("--typescript","Generates a TypeScript client over a JavaScript one.").option("--no-typescript").option("--install","Automatically install dependencies with current package manager.").option("--no-install").option("-w, --watch","Activate watch mode, regenerate on change changes.",!1).action(async(o,i)=>{const t=await G("gqty").search().then(c=>c?.config??{});let r=o;if(r.length===0&&(v.stdin.isTTY||(m.error("Please provide your GraphQL endpoint(s)."),v.exit(1)),r=await J(t.introspections?Object.keys(t.introspections).join(", "):t.introspection?.endpoint)),r=r.map(c=>c.trim()).filter(Boolean),r.length===0)return m.error("Please provide your GraphQL endpoint(s).");t.introspections||(t.introspections={});const b=await O(r,{headers:S(i.header)??t.introspection?.headers,headersByEndpoint:t.introspections}).catch(Y);Object.keys(t.introspections??{}).length>0,t.frameworks?.length===0&&(t.frameworks=[i.react&&"react",i.solid&&"solid-js"].filter(c=>!!c)),i.subscriptions!==void 0&&(t.subscriptions=i.subscriptions||!1),i.typescript&&(t.javascriptOutput=!1),i.target&&(t.destination=i.target,t.javascriptOutput=d.extname(i.target)===".js");const p=await(async()=>{try{return JSON.parse(await L("package.json",{encoding:"utf-8"}))}catch{return}})();if(p&&(t.frameworks??(t.frameworks=[p.dependencies?.react&&"react",p.dependencies?.["solid-js"]&&"solid-js"].filter(c=>!!c)),t.javascriptOutput??(t.javascriptOutput=!p.dependencies?.typescript&&!p.devDependencies?.typescript&&(t.destination?.endsWith(".js")??!0))),b.getSubscriptionType()&&(t.subscriptions??(t.subscriptions="graphql-ws")),o.length===0&&(t.frameworks=await R(),t.subscriptions=await H(t.subscriptions?t.subscriptions===!0?"graphql-ws":t.subscriptions:void 0),t.javascriptOutput=!await U(!t.javascriptOutput),t.destination??(t.destination=await N(t.javascriptOutput?"gqty/index.js":"gqty/index.ts"))),t.destination??(t.destination=t.javascriptOutput?"gqty/index.js":"gqty/index.ts"),P(r[0])&&(t.endpoint=r[0]),await q(b,{destination:"",...t}),o.length===0&&i.install===void 0?await B(t):p&&i.install!==!1&&await F(p,t),i.watch){const{default:{isMatch:c}}=await import("micromatch"),{default:T}=await import("lodash-es/throttle.js"),{FasterSMA:E}=await import("trading-signals"),{printSchema:j}=await import("graphql"),f=new E(3),C=()=>{try{return f.getResult()??0}catch{return f.prices.length===0?0:f.prices.reduce((s,n)=>s+n,0)/f.prices.length}},k=T(async()=>{if(y)return;y=!0;const s=Date.now();try{const n=await O(r,{headers:S(i.header),headersByEndpoint:t.introspections,silent:!0}).catch(a=>a instanceof Error?(m.errorProgress(a.message),Promise.resolve(void 0)):Promise.reject(a));if(!n)return;const u=j(n);u!==x&&(x=u,await q(n,{destination:"",...t}),f.update(Date.now()-s,!1)),m.infoProgress("Watching for schema changes... (Ctrl+C to exit)")}finally{y=!1}},1e3,{leading:!0,trailing:!0});let y=!1,x=j(b);m.infoProgress("Watching for schema changes... (Ctrl+C to exit)"),r.some(s=>P(s))&&(async()=>{for(;;){const s=Math.max(5e3,Math.min(3e4,C()*10));await new Promise(n=>setTimeout(n,s)),k()}})(),(async()=>{const s=r.map(a=>d.resolve(a)),n=await W(s,{absolute:!0}).then(a=>a.map(l=>d.dirname(l).split(d.sep)).reduce((l,I)=>{let h=0;for(;h<l.length&&l[h]===I[h];)h++;return l.slice(0,h)}).join(d.sep)||void 0);D(n,"No common path for specified endpoints.");let u=!1;for await(const{filename:a}of M(n,{recursive:!0})){if(!a)continue;const l=d.resolve(n,a);c(l,s)&&(y||u||(u=!0,setTimeout(()=>{k().finally(()=>{u=!1})})))}})()}}),J=async e=>(await g.input({message:"Where is your GraphQL endpoint or schema files?",default:e}).catch(w)).split(/[,\s+]/).map(i=>i.trim()).filter(Boolean),N=async e=>await g.input({message:"Where should the client be generated?",default:e}).catch(w),R=async()=>await g.checkbox({message:"Pick the frontend frameworks in use:",choices:[{value:"react"},{value:"solid-js"}]}).catch(w),H=async e=>(await g.input({message:'Do you need a subscription client? (Enter "-" to skip)',default:e?.trim()||void 0}).catch(w))?.trim().replace(/^-$/,"")||!1,U=async e=>await g.confirm({message:"Do you want a TypeScript client over vanilla.js?",default:e}).catch(w),w=e=>{throw e instanceof Error&&e.name==="ExitPromptError"&&(m.info("Goodbye \u{1F44B}"),v.exit()),e},Y=e=>{throw e instanceof Error&&(m.error(e.message),v.exit(1)),e};export{Q as addCommand};