Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@gqty/cli doesn't work correctly (watch mode) #2022

Open
SpeedySH opened this issue Sep 27, 2024 · 3 comments
Open

@gqty/cli doesn't work correctly (watch mode) #2022

SpeedySH opened this issue Sep 27, 2024 · 3 comments

Comments

@SpeedySH
Copy link

The idea, as well as the client, is great. But there are some points that make me uncomfortable

  1. When trying to run the CLI, with --install enabled, it does not install dependencies, or even add them to package.json
  2. If not explicitly specified in package.json or with --react option, it generates a client not for react (the hooks are just not there)
  3. I need to be able to disable dependency installation and customization in general. For example: I want to regenerate a client, and I have all the settings already specified in package.json (gqty block), gqty reads them, and still asks me to use CLI input! Why?
  4. watch just doesn't work. Let's start from the beginning:
    4.1 See point 1, dependencies are simply not added.
    4.2 On startup, I get an error, and that's the end of it, error text:
ℹ Watching for schema changes... (Ctrl+C to exit)file:///E:/Projects/ONREZA/TEST_FRONTEND/node_modules/@gqty/cli/commands/default.mjs:2
import{cosmiconfig as I}from"cosmiconfig";import D from"assert";import{readFile as G,watch as L}from"fs/promises";import u 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 M from"fast-glob";import"graphql";import"lodash-es/sortBy.js";import"prettier";import{convertHeadersInput as x}from"./default/convertHeadersInput.mjs";import{fetchSchema as S,isURL as q}from"./default/fetchSchema.mjs";import{generateClient as O}from"./default/generateClient.mjs";import{getCommandName as A}from"./default/getCommandName.mjs";import{logger as d}from"./default/logger.mjs";import{promptInstall as W,runInstall as B}from"./default/promptInstall.mjs";const Q=i=>i.name(A()).usage("[options] [endpoints...]").argument("[endpoints...]","GraphQL endpoints or schema files.").option("-H, --header <header>","Custom header for the introspection query.",(o,e)=>[...e,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,e)=>{const t=await I("gqty").search().then(c=>c?.config??{});let r=o;if(r.length===0&&(v.stdin.isTTY||(d.error("Please provide your GraphQL endpoint(s)."),v.exit(1)),r=await F(t.introspections?Object.keys(t.introspections).join(", "):t.introspection?.endpoint)),r=r.map(c=>c.trim()).filter(Boolean),r.length===0)return d.error("Please provide your GraphQL endpoint(s).");t.introspections||(t.introspections={});const y=await S(r,{headers:x(e.header)??t.introspection?.headers,headersByEndpoint:t.introspections}).catch(U);Object.keys(t.introspections??{}).length>0,t.frameworks??(t.frameworks=[e.react&&"react",e.solid&&"solid-js"].filter(c=>!!c)),e.subscriptions!==void 0&&(t.subscriptions=e.subscriptions||!1),e.typescript&&(t.javascriptOutput=!1),e.target&&(t.destination=e.target,t.javascriptOutput=u.extname(e.target)===".js");const p=await(async()=>{try{return JSON.parse(await G("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===void 0&&p.devDependencies?.typescript===void 0)),y.getSubscriptionType()&&(t.subscriptions??(t.subscriptions="graphql-ws")),o.length===0&&(t.frameworks=await N(),t.subscriptions=await R(t.subscriptions?t.subscriptions===!0?"graphql-ws":t.subscriptions:void 0),t.javascriptOutput=!await H(!t.javascriptOutput),t.destination??(t.destination=await J(t.javascriptOutput?"gqty/index.js":"gqty/index.ts"))),t.destination??(t.destination=t.javascriptOutput?"gqty/index.js":"gqty/index.ts"),q(r[0])&&(t.endpoint=r[0]),await O(y,{destination:"",...t}),o.length===0&&e.install===void 0?await W(t):p&&e.install!==!1&&await B(p,t),e.watch){const{default:{isMatch:c}}=await import("micromatch"),{default:P}=await import("lodash-es/throttle.js"),{FasterSMA:T}=await import("trading-signals/dist/SMA/SMA.js"),{printSchema:b}=await import("graphql"),f=new T(3),C=()=>{try{return f.getResult()}catch{return f.prices.length===0?0:f.prices.reduce((n,s)=>n+s,0)/f.prices.length}},j=P(async()=>{if(w)return;w=!0;const n=Date.now();try{const s=await S(r,{headers:x(e.header),headersByEndpoint:t.introspections,silent:!0}).catch(a=>a instanceof Error?(d.errorProgress(a.message),Promise.resolve(void 0)):Promise.reject(a));if(!s)return;const m=b(s);m!==k&&(k=m,await O(s,{destination:"",...t}),f.update(Date.now()-n)),d.infoProgress("Watching for schema changes... (Ctrl+C to exit)")}finally{w=!1}},1e3,{leading:!0,trailing:!0});let w=!1,k=b(y);d.infoProgress("Watching for schema changes... (Ctrl+C to exit)"),r.some(n=>q(n))&&(async()=>{for(;;){const n=Math.max(5e3,Math.min(3e4,C()*10));await new Promise(s=>setTimeout(s,n)),j()}})(),(async()=>{const n=r.map(a=>u.resolve(a)),s=await M(n,{absolute:!0}).then(a=>a.map(l=>u.dirname(l).split(u.sep)).reduce((l,E)=>{let h=0;for(;h<l.length&&l[h]===E[h];)h++;return l.slice(0,h)}).join(u.sep)||void 0);D(s,"No common path for specified endpoints.");let m=!1;for await(const{filename:a}of L(s,{recursive:!0})){if(!a)continue;const l=u.resolve(s,a);c(l,n)&&(w||m||(m=!0,setTimeout(()=>{j().finally(()=>{m=!1})})))}})()}}),F=async i=>(await g.input({message:"Where is your GraphQL endpoint or schema files?",default:i})).split(/[,\s+]/).map(e=>e.trim()).filter(Boolean),J=async i=>await g.input({message:"Where should the client be generated?",default:i}),N=async()=>await g.checkbox({message:"Pick the frontend frameworks in use:",choices:[{value:"react"},{value:"solid-js"}]}),R=async i=>(await g.input({message:'Do you need a subscription client? (Enter "-" to skip)',default:i?.trim()||void 0}))?.trim().replace(/^-$/,"")||!1,H=async i=>await g.confirm({message:"Do you want a TypeScript client over vanilla.js?",default:i}),U=i=>{throw i instanceof Error&&(d.error(i.message),v.exit(1)),i};export{Q as addCommand};
                                                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                 


TypeError: Reduce of empty array with no initial value
    at Array.reduce (<anonymous>)
    at file:///E:/Projects/ONREZA/TEST_FRONTEND/node_modules/@gqty/cli/commands/default.mjs:2:4624
    at async file:///E:/Projects/ONREZA/TEST_FRONTEND/node_modules/@gqty/cli/commands/default.mjs:2:4555
@vicary
Copy link
Member

vicary commented Sep 30, 2024

Thanks, let's make it more comfortable to use.

I can roughly tell what's going on, but I'd like to know the exact commands used for each point.

Relevant info that I can share:

  1. When trying to run the CLI, with --install enabled, it does not install dependencies, or even add them to package.json
  • CLI detects what package manager you used to invoke it, so it depends. For example NPM creates a package.json when none is there, Yarn cannot.
  • CLI skips the installation when no missing dependencies are found.
  1. If not explicitly specified in package.json or with --react option, it generates a client not for react (the hooks are just not there)
  • When no options are defined, the default is to look for react in all dependencies, and if that's not found it skips the react part.
  • Same logic goes for solid.
  1. I need to be able to disable dependency installation and customization in general. For example: I want to regenerate a client, and I have all the settings already specified in package.json (gqty block), gqty reads them, and still asks me to use CLI input! Why?
  • The minimum required option to skip interactive mode is the GraphQL endpoint, I may need to read your config block and the command you used to know exactly why.
  1. watch just doesn't work. Let's start from the beginning:
  • The error is most likely caused by a wildcard endpoint that resolves to NO files, I'll make a quick patch update when we confirm this one.

@SpeedySH
Copy link
Author

Thanks, let's make it more comfortable to use.

I can roughly tell what's going on, but I'd like to know the exact commands used for each point.

Relevant info that I can share:

  1. When trying to run the CLI, with --install enabled, it does not install dependencies, or even add them to package.json
  • CLI detects what package manager you used to invoke it, so it depends. For example NPM creates a package.json when none is there, Yarn cannot.
  • CLI skips the installation when no missing dependencies are found.
  1. If not explicitly specified in package.json or with --react option, it generates a client not for react (the hooks are just not there)
  • When no options are defined, the default is to look for react in all dependencies, and if that's not found it skips the react part.
  • Same logic goes for solid.
  1. I need to be able to disable dependency installation and customization in general. For example: I want to regenerate a client, and I have all the settings already specified in package.json (gqty block), gqty reads them, and still asks me to use CLI input! Why?
  • The minimum required option to skip interactive mode is the GraphQL endpoint, I may need to read your config block and the command you used to know exactly why.
  1. watch just doesn't work. Let's start from the beginning:
  • The error is most likely caused by a wildcard endpoint that resolves to NO files, I'll make a quick patch update when we confirm this one.

Am I right that now, packages are only installed if you use npm? it won't work with bun or pnpm?

My package.json has information in react packages, but all ravon until I used the --react option it only generated basic (i.e. no hooks)

Command to start watch mode: bun gqty --watch. I also tried npx @gqty/cli --watch and bunx @gqty/cli --watch

  "gqty": {
    "introspection": {
      "endpoint": "https://localhost:51835/graphql"
    },
    "react": true,
    "javascriptOutput": false,
    "subscriptions": false,
    "destination": "./generated/index.ts",
    "scalarTypes": {
      "DateTime": "Date"
    },
    "enumStyle": "const"
  }

@vicary
Copy link
Member

vicary commented Oct 2, 2024

@SpeedySH The CLI auto-detects NPM, Yarn and PNPM. Bun is possible, let me put that in the roadmaps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants