@gqty/cli
Version:
Interactive codegen for GQty
176 lines (155 loc) • 12.7 kB
JavaScript
;Object.defineProperty(exports,"__esModule",{value:!0});const gqty=require("gqty"),graphql=require("graphql"),config=require("./config.js");require("@commander-js/extra-typings");const core=require("@graphql-codegen/core"),typescript=require("@graphql-codegen/typescript"),utils=require("@graphql-tools/utils");require("@graphql-tools/wrap"),require("@inquirer/prompts"),require("cosmiconfig"),require("cross-fetch"),require("fast-glob");const sortBy_js=require("lodash-es/sortBy.js");require("prettier");const prettier=require("./prettier.js");function _interopDefaultLegacy(i){return i&&typeof i=="object"&&"default"in i?i:{default:i}}function _interopNamespace(i){if(i&&i.__esModule)return i;const S=Object.create(null);if(i){for(const y in i)if(y!=="default"){const m=Object.getOwnPropertyDescriptor(i,y);Object.defineProperty(S,y,m.get?m:{enumerable:!0,get:function(){return i[y]}})}}return S.default=i,Object.freeze(S)}const graphql__namespace=_interopNamespace(graphql),typescript__namespace=_interopNamespace(typescript),sortBy_js__default=_interopDefaultLegacy(sortBy_js),{isEnumType,isInputObjectType,isInterfaceType,isNullableType,isObjectType,isScalarType,isUnionType,lexicographicSortSchema,parse,isSchema,assertSchema}=graphql__namespace;async function generate(i,{enumsAsConst:S,enumsAsStrings:y,enumStyle:m=S?"assertion":y?"string":config.defaultConfig.enumStyle,introspection:J=config.defaultConfig.introspections,endpoint:R=J?.endpoint??config.defaultConfig.endpoint,javascriptOutput:d=config.defaultConfig.javascriptOutput,preImport:ee=config.defaultConfig.preImport,react:_=config.defaultConfig.react,frameworks:G=config.defaultConfig.frameworks,scalarTypes:te=config.defaultConfig.scalarTypes,subscriptions:g=config.defaultConfig.subscriptions,transformSchema:I=config.defaultConfig.transformSchema}={},{ignoreArgs:C}={}){d&&(m!=="string"&&m!==config.defaultConfig.enumStyle&&console.warn('"enumStyle" must be string unions with "javascriptOutput" enabled.'),m="string");const{format:A}=prettier.formatPrettier({parser:"typescript"});if(i=lexicographicSortSchema(assertSchema(i)),I&&(i=await I(i,graphql__namespace),!isSchema(i)))throw Error('"transformSchema" returned an invalid GraphQL Schema!');_??(_=G.includes("react"));const L=G.includes("solid-js"),ne=core.codegen({schema:parse(utils.printSchemaWithDirectives(i)),config:{},documents:[],filename:"gqty.generated.ts",pluginMap:{typescript:typescript__namespace},plugins:[{typescript:{constEnums:m==="const",onlyOperationTypes:!0,declarationKind:"interface",addUnderscoreToArgsType:!0,scalars:te,namingConvention:"keep",enumsAsTypes:m==="string",enumsAsConst:m==="assertion"}}]}),j=i.toConfig(),$={},M=[],P=new Set,h={query:{},mutation:{},subscription:{}},D=j.query,x=j.mutation,F=j.subscription,k=new Map,O=new Map,b=new Map;function V(e){if(Array.isArray(e)){const t=e[2]?b.get(e[0])?.[e[1]]?.[e[2]]:O.get(e[0])?.[e[1]];let r="";return t?.description&&(r+=`
`+t.description.trim().split(`
`).map(n=>"* "+n).join(`
`)),t?.deprecated&&(r+=`
* @deprecated `+t.deprecated.trim().replace(/\n/g,". ").trim()),t?.defaultValue&&(r+="\n* @defaultValue `"+t.defaultValue.trim()+"`"),r?`/** ${r}
*/
`:""}else{const t=k.get(e);return t?`/**
${t.trim().split(`
`).map(r=>"* "+r).join(`
`)}
*/
`:""}}const re=e=>{$[e.name]=!0,M.push(e.name);const t=e.getValues(),r={};for(const n of t)(n.deprecationReason||n.description)&&(r[n.name]={description:n.description,deprecated:n.deprecationReason});O.set(e.name,r)},se=e=>{$[e.name]=!0},oe=new Map,E=(e,t=e.name)=>{const r=e.getFields(),n=e.getInterfaces();if(n.length){oe.set(e.name,n.map(o=>o.name));for(const o of n){let c=f.get(o.name);c==null&&f.set(o.name,c=[]),c.push(e.name)}}const s={__typename:{__type:"String!"}},l={},a={};Object.entries(r).forEach(([o,c])=>{if((c.description||c.deprecationReason)&&(l[o]={description:c.description,deprecated:c.deprecationReason}),s[o]={__type:c.type.toString()},c.args.length){if(C&&c.args.every(({type:p})=>isNullableType(p))&&C(c))return;a[o]||(a[o]={}),s[o].__args=c.args.reduce((u,p)=>(u[p.name]=p.type.toString(),(p.description||p.deprecationReason||p.defaultValue!=null)&&(a[o][p.name]={defaultValue:p.defaultValue!=null?JSON.stringify(p.defaultValue):null,deprecated:p.deprecationReason,description:p.description}),u),{})}}),O.set(e.name,l),b.set(e.name,a),h[t]=s},f=new Map,ie=e=>{const t=e.getTypes(),r=[];f.set(e.name,r);for(const n of t)r.push(n.name);h[e.name]={__typename:{__type:"String!"}}},ae=e=>{P.add(e.name);const t=e.getFields(),r={};Object.entries(t).forEach(([n,s])=>{r[n]={__type:s.type.toString()},(s.description||s.deprecationReason||s.defaultValue)&&(s.description,s.deprecationReason,s.defaultValue!=null&&JSON.stringify(s.defaultValue))}),h[e.name]=r},ce=e=>{const t={__typename:{__type:"String!"}},r=e.getFields(),n={},s={};Object.entries(r).forEach(([l,a])=>{a.type.toString(),t[l]={__type:a.type.toString()};let o=!0;a.args.length?C&&a.args.every(({type:u})=>isNullableType(u))&&C(a)&&(o=!1):o=!1,o&&(s[l]||(s[l]={}),t[l].__args=a.args.reduce((c,u)=>(c[u.name]=u.type.toString(),(u.description||u.deprecationReason||u.defaultValue!=null)&&(s[l][u.name]={defaultValue:u.defaultValue!=null?JSON.stringify(u.defaultValue):null,deprecated:u.deprecationReason,description:u.description}),c),{})),(a.description||a.deprecationReason)&&(n[l]={description:a.description,deprecated:a.deprecationReason})}),O.set(e.name,n),b.set(e.name,s),h[e.name]=t};j.types.forEach(e=>{e.description&&k.set(e.name,e.description),!(e.name.startsWith("__")||e===D||e===x||e===F)&&(isScalarType(e)?se(e):isObjectType(e)?E(e):isInterfaceType(e)?ce(e):isUnionType(e)?ie(e):isEnumType(e)?re(e):isInputObjectType(e)&&ae(e))}),D&&E(D,"query"),x&&E(x,"mutation"),F&&E(F,"subscription");const z=Array.from(f.entries()).reduce((e,[t,r])=>(h[t].$on={__type:`$${t}!`},e[t]=r,e),{});f.size&&(h[gqty.SchemaUnionsKey]=z);function ue({pureType:e,isArray:t,nullableItems:r,isNullable:n,hasDefaultValue:s}){let l=[$[e]?M.includes(e)?e:`ScalarsEnums["${e}"]`:e];return t&&(l=["Array<",...r?["Maybe<",...l,">"]:l,">"]),(n||s)&&(l=["Maybe<",...l,">"]),l.join("")}function le({pureType:e,isArray:t,nullableItems:r,isNullable:n}){let s=[$[e]?`ScalarsEnums["${e}"]`:e];return t&&(s=["Array<",...r?["Maybe<",...s,">"]:s,">"]),n&&(s=["Maybe<",...s,">"]),s.join("")}const pe=new Map;let Q=sortBy_js__default.default(Object.entries(h),e=>e[0]).reduce((e,[t,r])=>{const n=(()=>{switch(t){case"query":return"Query";case"mutation":return"Mutation";case"subscription":return"Subscription";default:return t}})();if(P.has(n))return e;const s=new Map;f.has(n)||pe.set(n,s);const l=f.get(n);return e+=`
${V(n)}export interface ${n} {
__typename?: ${l?l.map(a=>`"${a}"`).join(" | "):`"${n}"`}; ${Object.entries(r).reduce((a,[o,c])=>{if(o==="__typename")return s.set(o,`?: "${n}"`),a;const u=b.has(n)?b.get(n):void 0,p=u&&u[o]?u[o]:{},Y=gqty.parseSchemaType(c.__type),W=le(Y);let T;if(c.__args){const X=Object.entries(c.__args);let Z=!0;const ye=X.reduce((K,[U,$e])=>{const w=gqty.parseSchemaType($e,p[U]),Se=w.isNullable||w.hasDefaultValue?"?:":":";w.isNullable||(Z=!1);const be=ue(w);return K+=`${V([n,o,U])}${U}${Se} ${be};
`,K},"");T=`: (args${Z?"?:":":"} {${ye}}) => ${W}`}else T=`${Y.isNullable?"?:":":"} ${W}`;return s.set(o,T),a+=`
`+V([n,o])+o+T,a},"")}
}
`,e},"");f.size&&(Q+=`
${sortBy_js__default.default(Array.from(f.entries()),e=>e[0]).reduce((e,[t,r])=>(e+=`
export interface $${t} {
${r.map(n=>`${n}?:${n}`).join(`
`)}
}
`,e),"")}
`),Q+=`
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;
} & {
${sortBy_js__default.default(M).reduce((e,t)=>(e+=`${t}: ${t};`,e),"")}
}
`;function q(e){return`/**
* @type {${e}}
*/
`}const de=`
${d?q('import("gqty").QueryFetcher')+"const queryFetcher":"const queryFetcher: QueryFetcher"} = async function ({ query, variables, operationName }, fetchOptions) {
// Modify "${R}" if needed
const response = await fetch("${R}", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
query,
variables,
operationName,
}),
mode: "cors",
...fetchOptions
});
return await defaultResponseHandler(response);
};
`,H=!!f.size,v=JSON.stringify(Object.keys($).sort().reduce((e,t)=>(e[t]=!0,e),{})),B=sortBy_js__default.default(Object.entries(h),e=>e[0]).reduceRight((e,[t,r])=>`${JSON.stringify(t)}:${JSON.stringify(r)}, ${e}`,H?`[SchemaUnionsKey]: ${JSON.stringify(z)}`:""),fe=await A(`
/**
* GQty AUTO-GENERATED CODE: PLEASE DO NOT MODIFY MANUALLY
*/
${H?'import { SchemaUnionsKey } from "gqty";':""}
${q('import("gqty").ScalarsEnumsHash')}export const scalarsEnumsHash = ${v};
export const generatedSchema = {${B}};
`),N=[H&&"SchemaUnionsKey",!d&&"type ScalarsEnumsHash"].filter(e=>!!e),me=await A(`
/**
* GQty AUTO-GENERATED CODE: PLEASE DO NOT MODIFY MANUALLY
*/
${ee}
${N.length?`import { ${N.join(", ")} } from "gqty";`:""}
${await ne}
export${d?" declare":""} const scalarsEnumsHash: ScalarsEnumsHash${d?";":` = ${v};`}
export${d?" declare":""} const generatedSchema ${d?":":"="} {${B}}${d?"":" as const"};
${Q}
`),he=_?`
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():"",ge=L?`
export const { createQuery } = createSolidClient(client);
`:"";return{clientCode:await A(`
/**
* GQty: You can safely modify this file based on your needs.
*/
${[_?'import { createReactClient } from "@gqty/react";':"",L?'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(`
`)}
${de}
${g?`const subscriptionsClient =
typeof window !== "undefined" ?
createSubscriptionsClient({
lazy: true,
url: () => {
// Modify if needed
const url = new URL("${R}", 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;
${he}
${ge}
export * from "./schema.generated";
`),generatedSchema:h,isJavascriptOutput:d,javascriptSchemaCode:fe,scalarsEnumsHash:$,schemaCode:me}}exports.generate=generate;