UNPKG

@gqty/cli

Version:

Interactive codegen for GQty

179 lines (157 loc) • 11.4 kB
#! /usr/bin/env node import{SchemaUnionsKey as Oe,parseSchemaType as W}from"gqty";import*as K from"graphql";import{defaultConfig as d}from"./config.mjs";import{sortBy as U}from"./deps.mjs";import{formatPrettier as _e}from"./prettier.mjs";import{codegen as je}from"@graphql-codegen/core";import{printSchemaWithDirectives as Re}from"@graphql-tools/utils";import*as we from"@graphql-codegen/typescript";const{isEnumType:Ae,isInputObjectType:Te,isInterfaceType:Me,isNullableType:X,isObjectType:qe,isScalarType:xe,isUnionType:De,lexicographicSortSchema:Fe,parse:Qe,isSchema:He,assertSchema:Ue}=K;async function Ve(f,{enumsAsConst:Z,enumsAsStrings:v,enumStyle:$=Z?"assertion":v?"string":d.enumStyle,introspection:J=d.introspections,endpoint:A=J?.endpoint??d.endpoint,javascriptOutput:l=d.javascriptOutput,preImport:ee=d.preImport,react:b=d.react,frameworks:T=d.frameworks,scalarTypes:te=d.scalarTypes,subscriptions:g=d.subscriptions,transformSchema:V=d.transformSchema}={},{ignoreArgs:E}={}){l&&($!=="string"&&$!==d.enumStyle&&console.warn('"enumStyle" must be string unions with "javascriptOutput" enabled.'),$="string");const{format:M}=_e({parser:"typescript"});b??(b=T.includes("react"));const G=T.includes("solid-js"),ne=T.includes("pylon");if(f=Ue(f),ne||(f=Fe(f)),V&&(f=await V(f,K),!He(f)))throw Error('"transformSchema" returned an invalid GraphQL Schema!');const re=je({schema:Qe(Re(f)),config:{},documents:[],filename:"gqty.generated.ts",pluginMap:{typescript:we},plugins:[{typescript:{constEnums:$==="const",onlyOperationTypes:!0,declarationKind:"interface",addUnderscoreToArgsType:!0,scalars:te,namingConvention:"keep",enumsAsTypes:$==="string",enumsAsConst:$==="assertion"}}]}),m=f.toConfig(),S={},q=new Set,I=new Set,h={query:{},mutation:{},subscription:{}},L=new Map,C=new Map,O=new Map;function x(e){if(Array.isArray(e)){const[t,r,s]=e,n=s?C.get(t)?.[r]?.[s]:O.get(t)?.[r];let o="";return n?.description&&(o+=` `+n.description.trim().split(` `).map(i=>"* "+i).join(` `)),n?.deprecated&&(o+=` * @deprecated `+n.deprecated.trim().replace(/\n/g,". ").trim()),n?.defaultValue&&(o+="\n* @default `"+n.defaultValue.trim()+"`"),o?`/** ${o} */ `:""}else{const t=L.get(e);return t?`/** ${t.trim().split(` `).map(r=>"* "+r).join(` `)} */ `:""}}const se=e=>{S[e.name]=!0,q.add(e.name),O.set(e.name,e.getValues().reduce((t,r)=>((r.deprecationReason||r.description)&&(t[r.name]={description:r.description,deprecated:r.deprecationReason}),t),{}))},oe=e=>{S[e.name]=!0},ie=new Map,_=(e,t=e.name)=>{const r=e.getFields(),s=e.getInterfaces();if(s.length){ie.set(e.name,s.map(a=>a.name));for(const a of s){let c=y.get(a.name);c==null&&y.set(a.name,c=[]),c.push(e.name)}}const n={__typename:{__type:"String!"}},o={},i={};Object.entries(r).forEach(([a,c])=>{if((c.description||c.deprecationReason)&&(o[a]={description:c.description,deprecated:c.deprecationReason}),n[a]={__type:c.type.toString()},c.args.length){if(E&&c.args.every(({type:u})=>X(u))&&E(c))return;i[a]||(i[a]={}),n[a].__args=c.args.reduce((p,u)=>(p[u.name]=u.type.toString(),(u.description||u.deprecationReason||u.defaultValue!=null)&&(i[a][u.name]={defaultValue:u.defaultValue!=null?JSON.stringify(u.defaultValue):null,deprecated:u.deprecationReason,description:u.description}),p),{})}}),C.set(e.name,i),O.set(e.name,o),h[t]=n},y=new Map,ae=e=>{const t=e.getTypes(),r=[];y.set(e.name,r);for(const s of t)r.push(s.name);h[e.name]={__typename:{__type:"String!"}}},ce=e=>{I.add(e.name);const t=e.getFields(),r={};Object.entries(t).forEach(([s,n])=>{r[s]={__type:n.type.toString()},(n.description||n.deprecationReason||n.defaultValue)&&(n.description,n.deprecationReason,n.defaultValue!=null&&JSON.stringify(n.defaultValue))}),h[e.name]=r},pe=e=>{const t={__typename:{__type:"String!"}},r=e.getFields(),s={},n={};Object.entries(r).forEach(([o,i])=>{i.type.toString(),t[o]={__type:i.type.toString()};let a=!0;i.args.length?E&&i.args.every(({type:p})=>X(p))&&E(i)&&(a=!1):a=!1,a&&(s[o]||(s[o]={}),t[o].__args=i.args.reduce((c,p)=>(c[p.name]=p.type.toString(),(p.description||p.deprecationReason||p.defaultValue!=null)&&(s[o][p.name]={defaultValue:p.defaultValue!=null?JSON.stringify(p.defaultValue):null,deprecated:p.deprecationReason,description:p.description}),c),{})),(i.description||i.deprecationReason)&&(n[o]={description:i.description,deprecated:i.deprecationReason})}),C.set(e.name,s),O.set(e.name,n),h[e.name]=t};m.types.forEach(e=>{e.description&&L.set(e.name,e.description),!(e.name.startsWith("__")||e===m.query||e===m.mutation||e===m.subscription)&&(xe(e)?oe(e):qe(e)?_(e):Me(e)?pe(e):De(e)?ae(e):Ae(e)?se(e):Te(e)&&ce(e))}),m.query&&_(m.query,"query"),m.mutation&&_(m.mutation,"mutation"),m.subscription&&_(m.subscription,"subscription");const N=Array.from(y.entries()).reduce((e,[t,r])=>(h[t].$on={__type:`$${t}!`},e[t]=r,e),{});y.size&&(h[Oe]=N);function ue({pureType:e,isArray:t,nullableItems:r,isNullable:s,hasDefaultValue:n}){let o=S[e]&&!q.has(e)?`ScalarsEnums["${e}"]`:e;return t&&(o=`Array<${r?`Maybe<${o}>`:o}>`),(s||n)&&(o=`Maybe<${o}>`),o}function le({pureType:e,isArray:t,nullableItems:r,isNullable:s}){let n=[S[e]?`ScalarsEnums["${e}"]`:e];return t&&(n=["Array<",...r?["Maybe<",...n,">"]:n,">"]),s&&(n=["Maybe<",...n,">"]),n.join("")}const de={query:"Query",mutation:"Mutation",subscription:"Subscription"};let D=Object.entries(h).sort(U(0)).reduce((e,[t,r])=>{const s=de[t]??t;if(I.has(s))return e;const n=new Map,o=y.get(s);return e+=` ${x(s)}export interface ${s} { __typename?: ${o?o.map(i=>`"${i}"`).join(" | "):`"${s}"`}; ${Object.entries(r).reduce((i,[a,c])=>{if(a==="__typename")return n.set(a,`?: "${s}"`),i;const p=W(c.__type),u=le(p);let R;if(c.__args){let w=!0;const $e=Object.entries(c.__args).reduce((k,[Q,Se])=>{const H=W(Se,C.get(s)?.[a]?.[Q]),B=H.isNullable||H.hasDefaultValue;w&&(w=B);const be=x([s,a,Q]),Ee=B?"?:":":",Ce=ue(H);return k+=`${be}${Q}${Ee} ${Ce}; `,k},"");R=`: (args${w?"?:":":"} {${$e}}) => ${u}`}else R=`${p.isNullable?"?:":":"} ${u}`;return n.set(a,R),i+=` `+x([s,a])+a+R,i},"")} } `,e},"");y.size&&(D+=` ${Array.from(y).sort(U(0)).reduce((e,[t,r])=>(e+=` export interface $${t} { ${r.map(s=>`${s}?:${s}`).join(` `)} } `,e),"")} `),D+=` export interface GeneratedSchema { query: Query mutation: Mutation subscription: Subscription } export type ScalarsEnums = { [Key in keyof Scalars]: Scalars[Key] extends { output: unknown } ? Scalars[Key]['output'] : never; } & { ${Array.from(q).sort().map(e=>`${e}: ${e};`).join(` `)} } `;function j(e){return`/** * @type {${e}} */ `}const me=` ${l?j('import("gqty").QueryFetcher')+"const queryFetcher":"const queryFetcher: QueryFetcher"} = async function ({ query, variables, operationName }, fetchOptions) { // Modify "${A}" if needed const response = await fetch("${A}", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ query, variables, operationName, }), mode: "cors", ...fetchOptions }); return await defaultResponseHandler(response); }; `,F=y.size>0,z=JSON.stringify(Object.keys(S).sort().reduce((e,t)=>(e[t]=!0,e),{})),P=Object.entries(h).sort(U(0)).reduceRight((e,[t,r])=>`${JSON.stringify(t)}:${JSON.stringify(r)}, ${e}`,F?`[SchemaUnionsKey]: ${JSON.stringify(N)}`:""),fe=await M(` /** * GQty AUTO-GENERATED CODE: PLEASE DO NOT MODIFY MANUALLY */ ${F?'import { SchemaUnionsKey } from "gqty";':""} ${j('import("gqty").ScalarsEnumsHash')}export const scalarsEnumsHash = ${z}; export const generatedSchema = {${P}}; `),Y=[F&&"SchemaUnionsKey",!l&&"type ScalarsEnumsHash"].filter(e=>!!e),he=await M(` /** * GQty AUTO-GENERATED CODE: PLEASE DO NOT MODIFY MANUALLY */ ${ee} ${Y.length?`import { ${Y.join(", ")} } from "gqty";`:""} ${await re} export${l?" declare":""} const scalarsEnumsHash: ScalarsEnumsHash${l?";":` = ${z};`} export${l?" declare":""} const generatedSchema ${l?":":"="} {${P}}${l?"":" as const"}; ${D} `),ye=b?` export const { graphql, useQuery, usePaginatedQuery, useTransactionQuery, useLazyQuery, useRefetch, useMutation, useMetaState, prepareReactRender, useHydrateCache, prepareQuery, ${g?"useSubscription,":""} } = ${l?`${j('import("@gqty/react").ReactClient<import("./schema.generated").GeneratedSchema>')}createReactClient(client, {`:"createReactClient<GeneratedSchema>(client, {"} defaults: { // Enable Suspense, you can override this option for each hook. suspense: true, } }); `.trim():"",ge=G?` export const { createQuery } = createSolidClient(client); `:"";return{clientCode:await M(` /** * GQty: You can safely modify this file based on your needs. */ ${[b?'import { createReactClient } from "@gqty/react";':"",G?'import { createSolidClient } from "@gqty/solid";':"",g?`import { createClient as createSubscriptionsClient } from "${g===!0?"graphql-ws":g}";`:"",l?'import { Cache, createClient, defaultResponseHandler } from "gqty";':'import { Cache, createClient, defaultResponseHandler, type QueryFetcher } from "gqty";',l?'import { generatedSchema, scalarsEnumsHash } from "./schema.generated";':'import { generatedSchema, scalarsEnumsHash, type GeneratedSchema } from "./schema.generated";'].filter(Boolean).join(` `)} ${me} ${g?`const subscriptionsClient = typeof window !== "undefined" ? createSubscriptionsClient({ lazy: true, url: () => { // Modify if needed const url = new URL("${A}", window.location.href); url.protocol = url.protocol.replace('http', 'ws'); return url.href; } }) : undefined;`:""} const cache = new Cache( undefined, /** * Default option is immediate cache expiry but keep it for 5 minutes, * allowing soft refetches in background. */ { maxAge: 0, staleWhileRevalidate: 5 * 60 * 1000, normalization: true, } ); ${l?`${j('import("gqty").GQtyClient<import("./schema.generated").GeneratedSchema>')}export const client = createClient({ schema: generatedSchema, scalars: scalarsEnumsHash, cache, fetchOptions: { fetcher: queryFetcher, ${g?"subscriber: subscriptionsClient":""} }, }); `:` export const client = createClient<GeneratedSchema>({ schema: generatedSchema, scalars: scalarsEnumsHash, cache, fetchOptions:{ fetcher: queryFetcher, ${g?"subscriber: subscriptionsClient":""} }, }); `} // Core functions export const { resolve, subscribe, schema } = client; // Legacy functions export const { query, mutation, mutate, subscription, resolved, refetch, track } = client; ${ye} ${ge} export * from "./schema.generated"; `),generatedSchema:h,isJavascriptOutput:l,javascriptSchemaCode:fe,scalarsEnumsHash:S,schemaCode:he}}export{Ve as generate};