@gqty/cli
Version:
Interactive codegen for GQty
178 lines (156 loc) • 12.2 kB
JavaScript
;Object.defineProperty(exports,"__esModule",{value:!0});const gqty=require("gqty"),graphql=require("graphql"),config=require("./config.js"),deps=require("./deps.js"),prettier=require("./prettier.js"),core=require("@graphql-codegen/core"),utils=require("@graphql-tools/utils"),typescript=require("@graphql-codegen/typescript");function _interopNamespace(p){if(p&&p.__esModule)return p;const b=Object.create(null);if(p){for(const $ in p)if($!=="default"){const m=Object.getOwnPropertyDescriptor(p,$);Object.defineProperty(b,$,m.get?m:{enumerable:!0,get:function(){return p[$]}})}}return b.default=p,Object.freeze(b)}const graphql__namespace=_interopNamespace(graphql),typescript__namespace=_interopNamespace(typescript),{isEnumType,isInputObjectType,isInterfaceType,isNullableType,isObjectType,isScalarType,isUnionType,lexicographicSortSchema,parse,isSchema,assertSchema}=graphql__namespace;async function generate(p,{enumsAsConst:b,enumsAsStrings:$,enumStyle:m=b?"assertion":$?"string":config.defaultConfig.enumStyle,introspection:W=config.defaultConfig.introspections,endpoint:A=W?.endpoint??config.defaultConfig.endpoint,javascriptOutput:d=config.defaultConfig.javascriptOutput,preImport:K=config.defaultConfig.preImport,react:C=config.defaultConfig.react,frameworks:M=config.defaultConfig.frameworks,scalarTypes:X=config.defaultConfig.scalarTypes,subscriptions:g=config.defaultConfig.subscriptions,transformSchema:V=config.defaultConfig.transformSchema}={},{ignoreArgs:_}={}){d&&(m!=="string"&&m!==config.defaultConfig.enumStyle&&console.warn('"enumStyle" must be string unions with "javascriptOutput" enabled.'),m="string");const{format:T}=prettier.formatPrettier({parser:"typescript"});C??(C=M.includes("react"));const G=M.includes("solid-js"),Z=M.includes("pylon");if(p=assertSchema(p),Z||(p=lexicographicSortSchema(p)),V&&(p=await V(p,graphql__namespace),!isSchema(p)))throw Error('"transformSchema" returned an invalid GraphQL Schema!');const v=core.codegen({schema:parse(utils.printSchemaWithDirectives(p)),config:{},documents:[],filename:"gqty.generated.ts",pluginMap:{typescript:typescript__namespace},plugins:[{typescript:{constEnums:m==="const",onlyOperationTypes:!0,declarationKind:"interface",addUnderscoreToArgsType:!0,scalars:X,namingConvention:"keep",enumsAsTypes:m==="string",enumsAsConst:m==="assertion"}}]}),f=p.toConfig(),S={},x=new Set,I=new Set,h={query:{},mutation:{},subscription:{}},L=new Map,O=new Map,j=new Map;function D(e){if(Array.isArray(e)){const[t,r,s]=e,n=s?O.get(t)?.[r]?.[s]:j.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 J=e=>{S[e.name]=!0,x.add(e.name),j.set(e.name,e.getValues().reduce((t,r)=>((r.deprecationReason||r.description)&&(t[r.name]={description:r.description,deprecated:r.deprecationReason}),t),{}))},ee=e=>{S[e.name]=!0},te=new Map,E=(e,t=e.name)=>{const r=e.getFields(),s=e.getInterfaces();if(s.length){te.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(_&&c.args.every(({type:l})=>isNullableType(l))&&_(c))return;i[a]||(i[a]={}),n[a].__args=c.args.reduce((u,l)=>(u[l.name]=l.type.toString(),(l.description||l.deprecationReason||l.defaultValue!=null)&&(i[a][l.name]={defaultValue:l.defaultValue!=null?JSON.stringify(l.defaultValue):null,deprecated:l.deprecationReason,description:l.description}),u),{})}}),O.set(e.name,i),j.set(e.name,o),h[t]=n},y=new Map,ne=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!"}}},re=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},se=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?_&&i.args.every(({type:u})=>isNullableType(u))&&_(i)&&(a=!1):a=!1,a&&(s[o]||(s[o]={}),t[o].__args=i.args.reduce((c,u)=>(c[u.name]=u.type.toString(),(u.description||u.deprecationReason||u.defaultValue!=null)&&(s[o][u.name]={defaultValue:u.defaultValue!=null?JSON.stringify(u.defaultValue):null,deprecated:u.deprecationReason,description:u.description}),c),{})),(i.description||i.deprecationReason)&&(n[o]={description:i.description,deprecated:i.deprecationReason})}),O.set(e.name,s),j.set(e.name,n),h[e.name]=t};f.types.forEach(e=>{e.description&&L.set(e.name,e.description),!(e.name.startsWith("__")||e===f.query||e===f.mutation||e===f.subscription)&&(isScalarType(e)?ee(e):isObjectType(e)?E(e):isInterfaceType(e)?se(e):isUnionType(e)?ne(e):isEnumType(e)?J(e):isInputObjectType(e)&&re(e))}),f.query&&E(f.query,"query"),f.mutation&&E(f.mutation,"mutation"),f.subscription&&E(f.subscription,"subscription");const N=Array.from(y.entries()).reduce((e,[t,r])=>(h[t].$on={__type:`$${t}!`},e[t]=r,e),{});y.size&&(h[gqty.SchemaUnionsKey]=N);function oe({pureType:e,isArray:t,nullableItems:r,isNullable:s,hasDefaultValue:n}){let o=S[e]&&!x.has(e)?`ScalarsEnums["${e}"]`:e;return t&&(o=`Array<${r?`Maybe<${o}>`:o}>`),(s||n)&&(o=`Maybe<${o}>`),o}function ie({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 ae={query:"Query",mutation:"Mutation",subscription:"Subscription"};let F=Object.entries(h).sort(deps.sortBy(0)).reduce((e,[t,r])=>{const s=ae[t]??t;if(I.has(s))return e;const n=new Map,o=y.get(s);return e+=`
${D(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 u=gqty.parseSchemaType(c.__type),l=ie(u);let R;if(c.__args){let w=!0;const fe=Object.entries(c.__args).reduce((Y,[H,me])=>{const U=gqty.parseSchemaType(me,O.get(s)?.[a]?.[H]),k=U.isNullable||U.hasDefaultValue;w&&(w=k);const he=D([s,a,H]),ye=k?"?:":":",ge=oe(U);return Y+=`${he}${H}${ye} ${ge};
`,Y},"");R=`: (args${w?"?:":":"} {${fe}}) => ${l}`}else R=`${u.isNullable?"?:":":"} ${l}`;return n.set(a,R),i+=`
`+D([s,a])+a+R,i},"")}
}
`,e},"");y.size&&(F+=`
${Array.from(y).sort(deps.sortBy(0)).reduce((e,[t,r])=>(e+=`
export interface $${t} {
${r.map(s=>`${s}?:${s}`).join(`
`)}
}
`,e),"")}
`),F+=`
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(x).sort().map(e=>`${e}: ${e};`).join(`
`)}
}
`;function q(e){return`/**
* @type {${e}}
*/
`}const ce=`
${d?q('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);
};
`,Q=y.size>0,P=JSON.stringify(Object.keys(S).sort().reduce((e,t)=>(e[t]=!0,e),{})),z=Object.entries(h).sort(deps.sortBy(0)).reduceRight((e,[t,r])=>`${JSON.stringify(t)}:${JSON.stringify(r)}, ${e}`,Q?`[SchemaUnionsKey]: ${JSON.stringify(N)}`:""),ue=await T(`
/**
* GQty AUTO-GENERATED CODE: PLEASE DO NOT MODIFY MANUALLY
*/
${Q?'import { SchemaUnionsKey } from "gqty";':""}
${q('import("gqty").ScalarsEnumsHash')}export const scalarsEnumsHash = ${P};
export const generatedSchema = {${z}};
`),B=[Q&&"SchemaUnionsKey",!d&&"type ScalarsEnumsHash"].filter(e=>!!e),pe=await T(`
/**
* GQty AUTO-GENERATED CODE: PLEASE DO NOT MODIFY MANUALLY
*/
${K}
${B.length?`import { ${B.join(", ")} } from "gqty";`:""}
${await v}
export${d?" declare":""} const scalarsEnumsHash: ScalarsEnumsHash${d?";":` = ${P};`}
export${d?" declare":""} const generatedSchema ${d?":":"="} {${z}}${d?"":" as const"};
${F}
`),le=C?`
export const {
graphql,
useQuery,
usePaginatedQuery,
useTransactionQuery,
useLazyQuery,
useRefetch,
useMutation,
useMetaState,
prepareReactRender,
useHydrateCache,
prepareQuery,
${g?"useSubscription,":""}
} = ${d?`${q('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():"",de=G?`
export const { createQuery } = createSolidClient(client);
`:"";return{clientCode:await T(`
/**
* GQty: You can safely modify this file based on your needs.
*/
${[C?'import { createReactClient } from "@gqty/react";':"",G?'import { createSolidClient } from "@gqty/solid";':"",g?`import { createClient as createSubscriptionsClient } from "${g===!0?"graphql-ws":g}";`:"",d?'import { Cache, createClient, defaultResponseHandler } from "gqty";':'import { Cache, createClient, defaultResponseHandler, type QueryFetcher } from "gqty";',d?'import { generatedSchema, scalarsEnumsHash } from "./schema.generated";':'import { generatedSchema, scalarsEnumsHash, type GeneratedSchema } from "./schema.generated";'].filter(Boolean).join(`
`)}
${ce}
${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,
}
);
${d?`${q('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;
${le}
${de}
export * from "./schema.generated";
`),generatedSchema:h,isJavascriptOutput:d,javascriptSchemaCode:ue,scalarsEnumsHash:S,schemaCode:pe}}exports.generate=generate;