UNPKG

next-shopify-storefront

Version:

A Shopping Cart built with TypeScript, Tailwind CSS, Headless UI, Next.js, React.js, Shopify Hydrogen React,... and Shopify Storefront GraphQL API.

1,312 lines (1,253 loc) 752 kB
/* eslint-disable */ import { AllTypesProps, ReturnTypes, Ops } from './const'; export const HOST = "https://graphql.myshopify.com/api/2023-01/graphql.json" export const HEADERS = {} export const apiSubscription = (options: chainOptions) => (query: string) => { try { const queryString = options[0] + '?query=' + encodeURIComponent(query); const wsString = queryString.replace('http', 'ws'); const host = (options.length > 1 && options[1]?.websocket?.[0]) || wsString; const webSocketOptions = options[1]?.websocket || [host]; const ws = new WebSocket(...webSocketOptions); return { ws, on: (e: (args: any) => void) => { ws.onmessage = (event: any) => { if (event.data) { const parsed = JSON.parse(event.data); const data = parsed.data; return e(data); } }; }, off: (e: (args: any) => void) => { ws.onclose = e; }, error: (e: (args: any) => void) => { ws.onerror = e; }, open: (e: () => void) => { ws.onopen = e; }, }; } catch { throw new Error('No websockets implemented'); } }; const handleFetchResponse = (response: Response): Promise<GraphQLResponse> => { if (!response.ok) { return new Promise((_, reject) => { response .text() .then((text) => { try { reject(JSON.parse(text)); } catch (err) { reject(text); } }) .catch(reject); }); } return response.json() as Promise<GraphQLResponse>; }; export const apiFetch = (options: fetchOptions) => (query: string, variables: Record<string, unknown> = {}) => { const fetchOptions = options[1] || {}; if (fetchOptions.method && fetchOptions.method === 'GET') { return fetch(`${options[0]}?query=${encodeURIComponent(query)}`, fetchOptions) .then(handleFetchResponse) .then((response: GraphQLResponse) => { if (response.errors) { throw new GraphQLError(response); } return response.data; }); } return fetch(`${options[0]}`, { body: JSON.stringify({ query, variables }), method: 'POST', headers: { 'Content-Type': 'application/json', }, ...fetchOptions, }) .then(handleFetchResponse) .then((response: GraphQLResponse) => { if (response.errors) { throw new GraphQLError(response); } return response.data; }); }; export const InternalsBuildQuery = ({ ops, props, returns, options, scalars, }: { props: AllTypesPropsType; returns: ReturnTypesType; ops: Operations; options?: OperationOptions; scalars?: ScalarDefinition; }) => { const ibb = ( k: string, o: InputValueType | VType, p = '', root = true, vars: Array<{ name: string; graphQLType: string }> = [], ): string => { const keyForPath = purifyGraphQLKey(k); const newPath = [p, keyForPath].join(SEPARATOR); if (!o) { return ''; } if (typeof o === 'boolean' || typeof o === 'number') { return k; } if (typeof o === 'string') { return `${k} ${o}`; } if (Array.isArray(o)) { const args = InternalArgsBuilt({ props, returns, ops, scalars, vars, })(o[0], newPath); return `${ibb(args ? `${k}(${args})` : k, o[1], p, false, vars)}`; } if (k === '__alias') { return Object.entries(o) .map(([alias, objectUnderAlias]) => { if (typeof objectUnderAlias !== 'object' || Array.isArray(objectUnderAlias)) { throw new Error( 'Invalid alias it should be __alias:{ YOUR_ALIAS_NAME: { OPERATION_NAME: { ...selectors }}}', ); } const operationName = Object.keys(objectUnderAlias)[0]; const operation = objectUnderAlias[operationName]; return ibb(`${alias}:${operationName}`, operation, p, false, vars); }) .join('\n'); } const hasOperationName = root && options?.operationName ? ' ' + options.operationName : ''; const keyForDirectives = o.__directives ?? ''; const query = `{${Object.entries(o) .filter(([k]) => k !== '__directives') .map((e) => ibb(...e, [p, `field<>${keyForPath}`].join(SEPARATOR), false, vars)) .join('\n')}}`; if (!root) { return `${k} ${keyForDirectives}${hasOperationName} ${query}`; } const varsString = vars.map((v) => `${v.name}: ${v.graphQLType}`).join(', '); return `${k} ${keyForDirectives}${hasOperationName}${varsString ? `(${varsString})` : ''} ${query}`; }; return ibb; }; export const Thunder = (fn: FetchFunction) => <O extends keyof typeof Ops, SCLR extends ScalarDefinition, R extends keyof ValueTypes = GenericOperation<O>>( operation: O, graphqlOptions?: ThunderGraphQLOptions<SCLR>, ) => <Z extends ValueTypes[R]>(o: Z | ValueTypes[R], ops?: OperationOptions & { variables?: Record<string, unknown> }) => fn( Zeus(operation, o, { operationOptions: ops, scalars: graphqlOptions?.scalars, }), ops?.variables, ).then((data) => { if (graphqlOptions?.scalars) { return decodeScalarsInResponse({ response: data, initialOp: operation, initialZeusQuery: o as VType, returns: ReturnTypes, scalars: graphqlOptions.scalars, ops: Ops, }); } return data; }) as Promise<InputType<GraphQLTypes[R], Z, SCLR>>; export const Chain = (...options: chainOptions) => Thunder(apiFetch(options)); export const SubscriptionThunder = (fn: SubscriptionFunction) => <O extends keyof typeof Ops, SCLR extends ScalarDefinition, R extends keyof ValueTypes = GenericOperation<O>>( operation: O, graphqlOptions?: ThunderGraphQLOptions<SCLR>, ) => <Z extends ValueTypes[R]>(o: Z | ValueTypes[R], ops?: OperationOptions & { variables?: ExtractVariables<Z> }) => { const returnedFunction = fn( Zeus(operation, o, { operationOptions: ops, scalars: graphqlOptions?.scalars, }), ) as SubscriptionToGraphQL<Z, GraphQLTypes[R], SCLR>; if (returnedFunction?.on && graphqlOptions?.scalars) { const wrapped = returnedFunction.on; returnedFunction.on = (fnToCall: (args: InputType<GraphQLTypes[R], Z, SCLR>) => void) => wrapped((data: InputType<GraphQLTypes[R], Z, SCLR>) => { if (graphqlOptions?.scalars) { return fnToCall( decodeScalarsInResponse({ response: data, initialOp: operation, initialZeusQuery: o as VType, returns: ReturnTypes, scalars: graphqlOptions.scalars, ops: Ops, }), ); } return fnToCall(data); }); } return returnedFunction; }; export const Subscription = (...options: chainOptions) => SubscriptionThunder(apiSubscription(options)); export const Zeus = < Z extends ValueTypes[R], O extends keyof typeof Ops, R extends keyof ValueTypes = GenericOperation<O>, >( operation: O, o: Z | ValueTypes[R], ops?: { operationOptions?: OperationOptions; scalars?: ScalarDefinition; }, ) => InternalsBuildQuery({ props: AllTypesProps, returns: ReturnTypes, ops: Ops, options: ops?.operationOptions, scalars: ops?.scalars, })(operation, o as VType); export const ZeusSelect = <T>() => ((t: unknown) => t) as SelectionFunction<T>; export const Selector = <T extends keyof ValueTypes>(key: T) => key && ZeusSelect<ValueTypes[T]>(); export const TypeFromSelector = <T extends keyof ValueTypes>(key: T) => key && ZeusSelect<ValueTypes[T]>(); export const Gql = Chain(HOST, { headers: { 'Content-Type': 'application/json', ...HEADERS, }, }); export const ZeusScalars = ZeusSelect<ScalarCoders>(); export const decodeScalarsInResponse = <O extends Operations>({ response, scalars, returns, ops, initialZeusQuery, initialOp, }: { ops: O; response: any; returns: ReturnTypesType; scalars?: Record<string, ScalarResolver | undefined>; initialOp: keyof O; initialZeusQuery: InputValueType | VType; }) => { if (!scalars) { return response; } const builder = PrepareScalarPaths({ ops, returns, }); const scalarPaths = builder(initialOp as string, ops[initialOp], initialZeusQuery); if (scalarPaths) { const r = traverseResponse({ scalarPaths, resolvers: scalars })(initialOp as string, response, [ops[initialOp]]); return r; } return response; }; export const traverseResponse = ({ resolvers, scalarPaths, }: { scalarPaths: { [x: string]: `scalar.${string}` }; resolvers: { [x: string]: ScalarResolver | undefined; }; }) => { const ibb = (k: string, o: InputValueType | VType, p: string[] = []): unknown => { if (Array.isArray(o)) { return o.map((eachO) => ibb(k, eachO, p)); } if (o == null) { return o; } const scalarPathString = p.join(SEPARATOR); const currentScalarString = scalarPaths[scalarPathString]; if (currentScalarString) { const currentDecoder = resolvers[currentScalarString.split('.')[1]]?.decode; if (currentDecoder) { return currentDecoder(o); } } if (typeof o === 'boolean' || typeof o === 'number' || typeof o === 'string' || !o) { return o; } const entries = Object.entries(o).map(([k, v]) => [k, ibb(k, v, [...p, purifyGraphQLKey(k)])] as const); const objectFromEntries = entries.reduce<Record<string, unknown>>((a, [k, v]) => { a[k] = v; return a; }, {}); return objectFromEntries; }; return ibb; }; export type AllTypesPropsType = { [x: string]: | undefined | `scalar.${string}` | 'enum' | { [x: string]: | undefined | string | { [x: string]: string | undefined; }; }; }; export type ReturnTypesType = { [x: string]: | { [x: string]: string | undefined; } | `scalar.${string}` | undefined; }; export type InputValueType = { [x: string]: undefined | boolean | string | number | [any, undefined | boolean | InputValueType] | InputValueType; }; export type VType = | undefined | boolean | string | number | [any, undefined | boolean | InputValueType] | InputValueType; export type PlainType = boolean | number | string | null | undefined; export type ZeusArgsType = | PlainType | { [x: string]: ZeusArgsType; } | Array<ZeusArgsType>; export type Operations = Record<string, string>; export type VariableDefinition = { [x: string]: unknown; }; export const SEPARATOR = '|'; export type fetchOptions = Parameters<typeof fetch>; type websocketOptions = typeof WebSocket extends new (...args: infer R) => WebSocket ? R : never; export type chainOptions = [fetchOptions[0], fetchOptions[1] & { websocket?: websocketOptions }] | [fetchOptions[0]]; export type FetchFunction = (query: string, variables?: Record<string, unknown>) => Promise<any>; export type SubscriptionFunction = (query: string) => any; type NotUndefined<T> = T extends undefined ? never : T; export type ResolverType<F> = NotUndefined<F extends [infer ARGS, any] ? ARGS : undefined>; export type OperationOptions = { operationName?: string; }; export type ScalarCoder = Record<string, (s: unknown) => string>; export interface GraphQLResponse { data?: Record<string, any>; errors?: Array<{ message: string; }>; } export class GraphQLError extends Error { constructor(public response: GraphQLResponse) { super(''); console.error(response); } toString() { return 'GraphQL Response Error'; } } export type GenericOperation<O> = O extends keyof typeof Ops ? typeof Ops[O] : never; export type ThunderGraphQLOptions<SCLR extends ScalarDefinition> = { scalars?: SCLR | ScalarCoders; }; const ExtractScalar = (mappedParts: string[], returns: ReturnTypesType): `scalar.${string}` | undefined => { if (mappedParts.length === 0) { return; } const oKey = mappedParts[0]; const returnP1 = returns[oKey]; if (typeof returnP1 === 'object') { const returnP2 = returnP1[mappedParts[1]]; if (returnP2) { return ExtractScalar([returnP2, ...mappedParts.slice(2)], returns); } return undefined; } return returnP1 as `scalar.${string}` | undefined; }; export const PrepareScalarPaths = ({ ops, returns }: { returns: ReturnTypesType; ops: Operations }) => { const ibb = ( k: string, originalKey: string, o: InputValueType | VType, p: string[] = [], pOriginals: string[] = [], root = true, ): { [x: string]: `scalar.${string}` } | undefined => { if (!o) { return; } if (typeof o === 'boolean' || typeof o === 'number' || typeof o === 'string') { const extractionArray = [...pOriginals, originalKey]; const isScalar = ExtractScalar(extractionArray, returns); if (isScalar?.startsWith('scalar')) { const partOfTree = { [[...p, k].join(SEPARATOR)]: isScalar, }; return partOfTree; } return {}; } if (Array.isArray(o)) { return ibb(k, k, o[1], p, pOriginals, false); } if (k === '__alias') { return Object.entries(o) .map(([alias, objectUnderAlias]) => { if (typeof objectUnderAlias !== 'object' || Array.isArray(objectUnderAlias)) { throw new Error( 'Invalid alias it should be __alias:{ YOUR_ALIAS_NAME: { OPERATION_NAME: { ...selectors }}}', ); } const operationName = Object.keys(objectUnderAlias)[0]; const operation = objectUnderAlias[operationName]; return ibb(alias, operationName, operation, p, pOriginals, false); }) .reduce((a, b) => ({ ...a, ...b, })); } const keyName = root ? ops[k] : k; return Object.entries(o) .filter(([k]) => k !== '__directives') .map(([k, v]) => { // Inline fragments shouldn't be added to the path as they aren't a field const isInlineFragment = originalKey.match(/^...\s*on/) != null; return ibb( k, k, v, isInlineFragment ? p : [...p, purifyGraphQLKey(keyName || k)], isInlineFragment ? pOriginals : [...pOriginals, purifyGraphQLKey(originalKey)], false, ); }) .reduce((a, b) => ({ ...a, ...b, })); }; return ibb; }; export const purifyGraphQLKey = (k: string) => k.replace(/\([^)]*\)/g, '').replace(/^[^:]*\:/g, ''); const mapPart = (p: string) => { const [isArg, isField] = p.split('<>'); if (isField) { return { v: isField, __type: 'field', } as const; } return { v: isArg, __type: 'arg', } as const; }; type Part = ReturnType<typeof mapPart>; export const ResolveFromPath = (props: AllTypesPropsType, returns: ReturnTypesType, ops: Operations) => { const ResolvePropsType = (mappedParts: Part[]) => { const oKey = ops[mappedParts[0].v]; const propsP1 = oKey ? props[oKey] : props[mappedParts[0].v]; if (propsP1 === 'enum' && mappedParts.length === 1) { return 'enum'; } if (typeof propsP1 === 'string' && propsP1.startsWith('scalar.') && mappedParts.length === 1) { return propsP1; } if (typeof propsP1 === 'object') { if (mappedParts.length < 2) { return 'not'; } const propsP2 = propsP1[mappedParts[1].v]; if (typeof propsP2 === 'string') { return rpp( `${propsP2}${SEPARATOR}${mappedParts .slice(2) .map((mp) => mp.v) .join(SEPARATOR)}`, ); } if (typeof propsP2 === 'object') { if (mappedParts.length < 3) { return 'not'; } const propsP3 = propsP2[mappedParts[2].v]; if (propsP3 && mappedParts[2].__type === 'arg') { return rpp( `${propsP3}${SEPARATOR}${mappedParts .slice(3) .map((mp) => mp.v) .join(SEPARATOR)}`, ); } } } }; const ResolveReturnType = (mappedParts: Part[]) => { if (mappedParts.length === 0) { return 'not'; } const oKey = ops[mappedParts[0].v]; const returnP1 = oKey ? returns[oKey] : returns[mappedParts[0].v]; if (typeof returnP1 === 'object') { if (mappedParts.length < 2) return 'not'; const returnP2 = returnP1[mappedParts[1].v]; if (returnP2) { return rpp( `${returnP2}${SEPARATOR}${mappedParts .slice(2) .map((mp) => mp.v) .join(SEPARATOR)}`, ); } } }; const rpp = (path: string): 'enum' | 'not' | `scalar.${string}` => { const parts = path.split(SEPARATOR).filter((l) => l.length > 0); const mappedParts = parts.map(mapPart); const propsP1 = ResolvePropsType(mappedParts); if (propsP1) { return propsP1; } const returnP1 = ResolveReturnType(mappedParts); if (returnP1) { return returnP1; } return 'not'; }; return rpp; }; export const InternalArgsBuilt = ({ props, ops, returns, scalars, vars, }: { props: AllTypesPropsType; returns: ReturnTypesType; ops: Operations; scalars?: ScalarDefinition; vars: Array<{ name: string; graphQLType: string }>; }) => { const arb = (a: ZeusArgsType, p = '', root = true): string => { if (typeof a === 'string') { if (a.startsWith(START_VAR_NAME)) { const [varName, graphQLType] = a.replace(START_VAR_NAME, '$').split(GRAPHQL_TYPE_SEPARATOR); const v = vars.find((v) => v.name === varName); if (!v) { vars.push({ name: varName, graphQLType, }); } else { if (v.graphQLType !== graphQLType) { throw new Error( `Invalid variable exists with two different GraphQL Types, "${v.graphQLType}" and ${graphQLType}`, ); } } return varName; } } const checkType = ResolveFromPath(props, returns, ops)(p); if (checkType.startsWith('scalar.')) { // eslint-disable-next-line @typescript-eslint/no-unused-vars const [_, ...splittedScalar] = checkType.split('.'); const scalarKey = splittedScalar.join('.'); return (scalars?.[scalarKey]?.encode?.(a) as string) || JSON.stringify(a); } if (Array.isArray(a)) { return `[${a.map((arr) => arb(arr, p, false)).join(', ')}]`; } if (typeof a === 'string') { if (checkType === 'enum') { return a; } return `${JSON.stringify(a)}`; } if (typeof a === 'object') { if (a === null) { return `null`; } const returnedObjectString = Object.entries(a) .filter(([, v]) => typeof v !== 'undefined') .map(([k, v]) => `${k}: ${arb(v, [p, k].join(SEPARATOR), false)}`) .join(',\n'); if (!root) { return `{${returnedObjectString}}`; } return returnedObjectString; } return `${a}`; }; return arb; }; export const resolverFor = <X, T extends keyof ResolverInputTypes, Z extends keyof ResolverInputTypes[T]>( type: T, field: Z, fn: ( args: Required<ResolverInputTypes[T]>[Z] extends [infer Input, any] ? Input : any, source: any, ) => Z extends keyof ModelTypes[T] ? ModelTypes[T][Z] | Promise<ModelTypes[T][Z]> | X : never, ) => fn as (args?: any, source?: any) => ReturnType<typeof fn>; export type UnwrapPromise<T> = T extends Promise<infer R> ? R : T; export type ZeusState<T extends (...args: any[]) => Promise<any>> = NonNullable<UnwrapPromise<ReturnType<T>>>; export type ZeusHook< T extends (...args: any[]) => Record<string, (...args: any[]) => Promise<any>>, N extends keyof ReturnType<T>, > = ZeusState<ReturnType<T>[N]>; export type WithTypeNameValue<T> = T & { __typename?: boolean; __directives?: string; }; export type AliasType<T> = WithTypeNameValue<T> & { __alias?: Record<string, WithTypeNameValue<T>>; }; type DeepAnify<T> = { [P in keyof T]?: any; }; type IsPayLoad<T> = T extends [any, infer PayLoad] ? PayLoad : T; export type ScalarDefinition = Record<string, ScalarResolver>; type IsScalar<S, SCLR extends ScalarDefinition> = S extends 'scalar' & { name: infer T } ? T extends keyof SCLR ? SCLR[T]['decode'] extends (s: unknown) => unknown ? ReturnType<SCLR[T]['decode']> : unknown : unknown : S; type IsArray<T, U, SCLR extends ScalarDefinition> = T extends Array<infer R> ? InputType<R, U, SCLR>[] : InputType<T, U, SCLR>; type FlattenArray<T> = T extends Array<infer R> ? R : T; type BaseZeusResolver = boolean | 1 | string | Variable<any, string>; type IsInterfaced<SRC extends DeepAnify<DST>, DST, SCLR extends ScalarDefinition> = FlattenArray<SRC> extends | ZEUS_INTERFACES | ZEUS_UNIONS ? { [P in keyof SRC]: SRC[P] extends '__union' & infer R ? P extends keyof DST ? IsArray<R, '__typename' extends keyof DST ? DST[P] & { __typename: true } : DST[P], SCLR> : IsArray<R, '__typename' extends keyof DST ? { __typename: true } : never, SCLR> : never; }[keyof SRC] & { [P in keyof Omit< Pick< SRC, { [P in keyof DST]: SRC[P] extends '__union' & infer R ? never : P; }[keyof DST] >, '__typename' >]: IsPayLoad<DST[P]> extends BaseZeusResolver ? IsScalar<SRC[P], SCLR> : IsArray<SRC[P], DST[P], SCLR>; } : { [P in keyof Pick<SRC, keyof DST>]: IsPayLoad<DST[P]> extends BaseZeusResolver ? IsScalar<SRC[P], SCLR> : IsArray<SRC[P], DST[P], SCLR>; }; export type MapType<SRC, DST, SCLR extends ScalarDefinition> = SRC extends DeepAnify<DST> ? IsInterfaced<SRC, DST, SCLR> : never; // eslint-disable-next-line @typescript-eslint/ban-types export type InputType<SRC, DST, SCLR extends ScalarDefinition = {}> = IsPayLoad<DST> extends { __alias: infer R } ? { [P in keyof R]: MapType<SRC, R[P], SCLR>[keyof MapType<SRC, R[P], SCLR>]; } & MapType<SRC, Omit<IsPayLoad<DST>, '__alias'>, SCLR> : MapType<SRC, IsPayLoad<DST>, SCLR>; export type SubscriptionToGraphQL<Z, T, SCLR extends ScalarDefinition> = { ws: WebSocket; on: (fn: (args: InputType<T, Z, SCLR>) => void) => void; off: (fn: (e: { data?: InputType<T, Z, SCLR>; code?: number; reason?: string; message?: string }) => void) => void; error: (fn: (e: { data?: InputType<T, Z, SCLR>; errors?: string[] }) => void) => void; open: () => void; }; // eslint-disable-next-line @typescript-eslint/ban-types export type FromSelector<SELECTOR, NAME extends keyof GraphQLTypes, SCLR extends ScalarDefinition = {}> = InputType< GraphQLTypes[NAME], SELECTOR, SCLR >; export type ScalarResolver = { encode?: (s: unknown) => string; decode?: (s: unknown) => unknown; }; export type SelectionFunction<V> = <T>(t: T | V) => T; type BuiltInVariableTypes = { ['String']: string; ['Int']: number; ['Float']: number; ['ID']: unknown; ['Boolean']: boolean; }; type AllVariableTypes = keyof BuiltInVariableTypes | keyof ZEUS_VARIABLES; type VariableRequired<T extends string> = `${T}!` | T | `[${T}]` | `[${T}]!` | `[${T}!]` | `[${T}!]!`; type VR<T extends string> = VariableRequired<VariableRequired<T>>; export type GraphQLVariableType = VR<AllVariableTypes>; type ExtractVariableTypeString<T extends string> = T extends VR<infer R1> ? R1 extends VR<infer R2> ? R2 extends VR<infer R3> ? R3 extends VR<infer R4> ? R4 extends VR<infer R5> ? R5 : R4 : R3 : R2 : R1 : T; type DecomposeType<T, Type> = T extends `[${infer R}]` ? Array<DecomposeType<R, Type>> | undefined : T extends `${infer R}!` ? NonNullable<DecomposeType<R, Type>> : Type | undefined; type ExtractTypeFromGraphQLType<T extends string> = T extends keyof ZEUS_VARIABLES ? ZEUS_VARIABLES[T] : T extends keyof BuiltInVariableTypes ? BuiltInVariableTypes[T] : any; export type GetVariableType<T extends string> = DecomposeType< T, ExtractTypeFromGraphQLType<ExtractVariableTypeString<T>> >; type UndefinedKeys<T> = { [K in keyof T]-?: T[K] extends NonNullable<T[K]> ? never : K; }[keyof T]; type WithNullableKeys<T> = Pick<T, UndefinedKeys<T>>; type WithNonNullableKeys<T> = Omit<T, UndefinedKeys<T>>; type OptionalKeys<T> = { [P in keyof T]?: T[P]; }; export type WithOptionalNullables<T> = OptionalKeys<WithNullableKeys<T>> & WithNonNullableKeys<T>; export type Variable<T extends GraphQLVariableType, Name extends string> = { ' __zeus_name': Name; ' __zeus_type': T; }; export type ExtractVariables<Query> = Query extends Variable<infer VType, infer VName> ? { [key in VName]: GetVariableType<VType> } : Query extends [infer Inputs, infer Outputs] ? ExtractVariables<Inputs> & ExtractVariables<Outputs> : Query extends string | number | boolean ? // eslint-disable-next-line @typescript-eslint/ban-types {} : UnionToIntersection<{ [K in keyof Query]: WithOptionalNullables<ExtractVariables<Query[K]>> }[keyof Query]>; type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never; export const START_VAR_NAME = `$ZEUS_VAR`; export const GRAPHQL_TYPE_SEPARATOR = `__$GRAPHQL__`; export const $ = <Type extends GraphQLVariableType, Name extends string>(name: Name, graphqlType: Type) => { return (START_VAR_NAME + name + GRAPHQL_TYPE_SEPARATOR + graphqlType) as unknown as Variable<Type, Name>; }; type ZEUS_INTERFACES = GraphQLTypes["CartDiscountAllocation"] | GraphQLTypes["DiscountApplication"] | GraphQLTypes["DisplayableError"] | GraphQLTypes["HasMetafields"] | GraphQLTypes["Media"] | GraphQLTypes["Node"] | GraphQLTypes["OnlineStorePublishable"] export type ScalarCoders = { Color?: ScalarResolver; DateTime?: ScalarResolver; Decimal?: ScalarResolver; HTML?: ScalarResolver; JSON?: ScalarResolver; URL?: ScalarResolver; UnsignedInt64?: ScalarResolver; } type ZEUS_UNIONS = GraphQLTypes["DeliveryAddress"] | GraphQLTypes["Merchandise"] | GraphQLTypes["MetafieldParentResource"] | GraphQLTypes["MetafieldReference"] | GraphQLTypes["PricingValue"] | GraphQLTypes["SellingPlanCheckoutChargeValue"] | GraphQLTypes["SellingPlanPriceAdjustmentValue"] export type ValueTypes = { /** A version of the API, as defined by [Shopify API versioning](https://shopify.dev/api/usage/versioning). Versions are commonly referred to by their handle (for example, `2021-10`). */ ["ApiVersion"]: AliasType<{ /** The human-readable name of the version. */ displayName?:boolean | `@${string}`, /** The unique identifier of an ApiVersion. All supported API versions have a date-based (YYYY-MM) or `unstable` handle. */ handle?:boolean | `@${string}`, /** Whether the version is actively supported by Shopify. Supported API versions are guaranteed to be stable. Unsupported API versions include unstable, release candidate, and end-of-life versions that are marked as unsupported. For more information, refer to [Versioning](https://shopify.dev/api/usage/versioning). */ supported?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** Details about the gift card used on the checkout. */ ["AppliedGiftCard"]: AliasType<{ /** The amount that was taken from the gift card by applying it. */ amountUsed?:ValueTypes["MoneyV2"], /** The amount that was taken from the gift card by applying it. */ amountUsedV2?:ValueTypes["MoneyV2"], /** The amount left on the gift card. */ balance?:ValueTypes["MoneyV2"], /** The amount left on the gift card. */ balanceV2?:ValueTypes["MoneyV2"], /** A globally-unique identifier. */ id?:boolean | `@${string}`, /** The last characters of the gift card. */ lastCharacters?:boolean | `@${string}`, /** The amount that was applied to the checkout in its currency. */ presentmentAmountUsed?:ValueTypes["MoneyV2"], __typename?: boolean | `@${string}` }>; /** An article in an online store blog. */ ["Article"]: AliasType<{ /** The article's author. */ author?:ValueTypes["ArticleAuthor"], /** The article's author. */ authorV2?:ValueTypes["ArticleAuthor"], /** The blog that the article belongs to. */ blog?:ValueTypes["Blog"], comments?: [{ /** Returns up to the first `n` elements from the list. */ first?: number | undefined | null | Variable<any, string>, /** Returns the elements that come after the specified cursor. */ after?: string | undefined | null | Variable<any, string>, /** Returns up to the last `n` elements from the list. */ last?: number | undefined | null | Variable<any, string>, /** Returns the elements that come before the specified cursor. */ before?: string | undefined | null | Variable<any, string>, /** Reverse the order of the underlying list. */ reverse?: boolean | undefined | null | Variable<any, string>},ValueTypes["CommentConnection"]], content?: [{ /** Truncates string after the given length. */ truncateAt?: number | undefined | null | Variable<any, string>},boolean | `@${string}`], /** The content of the article, complete with HTML formatting. */ contentHtml?:boolean | `@${string}`, excerpt?: [{ /** Truncates string after the given length. */ truncateAt?: number | undefined | null | Variable<any, string>},boolean | `@${string}`], /** The excerpt of the article, complete with HTML formatting. */ excerptHtml?:boolean | `@${string}`, /** A human-friendly unique string for the Article automatically generated from its title. */ handle?:boolean | `@${string}`, /** A globally-unique identifier. */ id?:boolean | `@${string}`, /** The image associated with the article. */ image?:ValueTypes["Image"], metafield?: [{ /** A container for a set of metafields. */ namespace: string | Variable<any, string>, /** The identifier for the metafield. */ key: string | Variable<any, string>},ValueTypes["Metafield"]], metafields?: [{ /** The list of metafields to retrieve by namespace and key. */ identifiers: Array<ValueTypes["HasMetafieldsIdentifier"]> | Variable<any, string>},ValueTypes["Metafield"]], /** The URL used for viewing the resource on the shop's Online Store. Returns `null` if the resource is currently not published to the Online Store sales channel. */ onlineStoreUrl?:boolean | `@${string}`, /** The date and time when the article was published. */ publishedAt?:boolean | `@${string}`, /** The article’s SEO information. */ seo?:ValueTypes["SEO"], /** A categorization that a article can be tagged with. */ tags?:boolean | `@${string}`, /** The article’s name. */ title?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** The author of an article. */ ["ArticleAuthor"]: AliasType<{ /** The author's bio. */ bio?:boolean | `@${string}`, /** The author’s email. */ email?:boolean | `@${string}`, /** The author's first name. */ firstName?:boolean | `@${string}`, /** The author's last name. */ lastName?:boolean | `@${string}`, /** The author's full name. */ name?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** An auto-generated type for paginating through multiple Articles. */ ["ArticleConnection"]: AliasType<{ /** A list of edges. */ edges?:ValueTypes["ArticleEdge"], /** A list of the nodes contained in ArticleEdge. */ nodes?:ValueTypes["Article"], /** Information to aid in pagination. */ pageInfo?:ValueTypes["PageInfo"], __typename?: boolean | `@${string}` }>; /** An auto-generated type which holds one Article and a cursor during pagination. */ ["ArticleEdge"]: AliasType<{ /** A cursor for use in pagination. */ cursor?:boolean | `@${string}`, /** The item at the end of ArticleEdge. */ node?:ValueTypes["Article"], __typename?: boolean | `@${string}` }>; /** The set of valid sort keys for the Article query. */ ["ArticleSortKeys"]:ArticleSortKeys; /** Represents a generic custom attribute. */ ["Attribute"]: AliasType<{ /** Key or name of the attribute. */ key?:boolean | `@${string}`, /** Value of the attribute. */ value?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** Specifies the input fields required for an attribute. */ ["AttributeInput"]: { /** Key or name of the attribute. */ key: string | Variable<any, string>, /** Value of the attribute. */ value: string | Variable<any, string> }; /** Automatic discount applications capture the intentions of a discount that was automatically applied. */ ["AutomaticDiscountApplication"]: AliasType<{ /** The method by which the discount's value is allocated to its entitled items. */ allocationMethod?:boolean | `@${string}`, /** Which lines of targetType that the discount is allocated over. */ targetSelection?:boolean | `@${string}`, /** The type of line that the discount is applicable towards. */ targetType?:boolean | `@${string}`, /** The title of the application. */ title?:boolean | `@${string}`, /** The value of the discount application. */ value?:ValueTypes["PricingValue"], __typename?: boolean | `@${string}` }>; /** A collection of available shipping rates for a checkout. */ ["AvailableShippingRates"]: AliasType<{ /** Whether or not the shipping rates are ready. The `shippingRates` field is `null` when this value is `false`. This field should be polled until its value becomes `true`. */ ready?:boolean | `@${string}`, /** The fetched shipping rates. `null` until the `ready` field is `true`. */ shippingRates?:ValueTypes["ShippingRate"], __typename?: boolean | `@${string}` }>; /** An online store blog. */ ["Blog"]: AliasType<{ articleByHandle?: [{ /** The handle of the article. */ handle: string | Variable<any, string>},ValueTypes["Article"]], articles?: [{ /** Returns up to the first `n` elements from the list. */ first?: number | undefined | null | Variable<any, string>, /** Returns the elements that come after the specified cursor. */ after?: string | undefined | null | Variable<any, string>, /** Returns up to the last `n` elements from the list. */ last?: number | undefined | null | Variable<any, string>, /** Returns the elements that come before the specified cursor. */ before?: string | undefined | null | Variable<any, string>, /** Reverse the order of the underlying list. */ reverse?: boolean | undefined | null | Variable<any, string>, /** Sort the underlying list by the given key. */ sortKey?: ValueTypes["ArticleSortKeys"] | undefined | null | Variable<any, string>, /** Supported filter parameters: - `author` - `blog_title` - `created_at` - `tag` - `tag_not` - `updated_at` See the detailed [search syntax](https://shopify.dev/api/usage/search-syntax) for more information about using filters. */ query?: string | undefined | null | Variable<any, string>},ValueTypes["ArticleConnection"]], /** The authors who have contributed to the blog. */ authors?:ValueTypes["ArticleAuthor"], /** A human-friendly unique string for the Blog automatically generated from its title. */ handle?:boolean | `@${string}`, /** A globally-unique identifier. */ id?:boolean | `@${string}`, metafield?: [{ /** A container for a set of metafields. */ namespace: string | Variable<any, string>, /** The identifier for the metafield. */ key: string | Variable<any, string>},ValueTypes["Metafield"]], metafields?: [{ /** The list of metafields to retrieve by namespace and key. */ identifiers: Array<ValueTypes["HasMetafieldsIdentifier"]> | Variable<any, string>},ValueTypes["Metafield"]], /** The URL used for viewing the resource on the shop's Online Store. Returns `null` if the resource is currently not published to the Online Store sales channel. */ onlineStoreUrl?:boolean | `@${string}`, /** The blog's SEO information. */ seo?:ValueTypes["SEO"], /** The blogs’s title. */ title?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** An auto-generated type for paginating through multiple Blogs. */ ["BlogConnection"]: AliasType<{ /** A list of edges. */ edges?:ValueTypes["BlogEdge"], /** A list of the nodes contained in BlogEdge. */ nodes?:ValueTypes["Blog"], /** Information to aid in pagination. */ pageInfo?:ValueTypes["PageInfo"], __typename?: boolean | `@${string}` }>; /** An auto-generated type which holds one Blog and a cursor during pagination. */ ["BlogEdge"]: AliasType<{ /** A cursor for use in pagination. */ cursor?:boolean | `@${string}`, /** The item at the end of BlogEdge. */ node?:ValueTypes["Blog"], __typename?: boolean | `@${string}` }>; /** The set of valid sort keys for the Blog query. */ ["BlogSortKeys"]:BlogSortKeys; /** The store's branding configuration. */ ["Brand"]: AliasType<{ /** The colors of the store's brand. */ colors?:ValueTypes["BrandColors"], /** The store's cover image. */ coverImage?:ValueTypes["MediaImage"], /** The store's default logo. */ logo?:ValueTypes["MediaImage"], /** The store's short description. */ shortDescription?:boolean | `@${string}`, /** The store's slogan. */ slogan?:boolean | `@${string}`, /** The store's preferred logo for square UI elements. */ squareLogo?:ValueTypes["MediaImage"], __typename?: boolean | `@${string}` }>; /** A group of related colors for the shop's brand. */ ["BrandColorGroup"]: AliasType<{ /** The background color. */ background?:boolean | `@${string}`, /** The foreground color. */ foreground?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** The colors of the shop's brand. */ ["BrandColors"]: AliasType<{ /** The shop's primary brand colors. */ primary?:ValueTypes["BrandColorGroup"], /** The shop's secondary brand colors. */ secondary?:ValueTypes["BrandColorGroup"], __typename?: boolean | `@${string}` }>; /** Card brand, such as Visa or Mastercard, which can be used for payments. */ ["CardBrand"]:CardBrand; /** A cart represents the merchandise that a buyer intends to purchase, and the estimated cost associated with the cart. Learn how to [interact with a cart](https://shopify.dev/custom-storefronts/internationalization/international-pricing) during a customer's session. */ ["Cart"]: AliasType<{ attribute?: [{ /** The key of the attribute. */ key: string | Variable<any, string>},ValueTypes["Attribute"]], /** The attributes associated with the cart. Attributes are represented as key-value pairs. */ attributes?:ValueTypes["Attribute"], /** Information about the buyer that is interacting with the cart. */ buyerIdentity?:ValueTypes["CartBuyerIdentity"], /** The URL of the checkout for the cart. */ checkoutUrl?:boolean | `@${string}`, /** The estimated costs that the buyer will pay at checkout. The costs are subject to change and changes will be reflected at checkout. The `cost` field uses the `buyerIdentity` field to determine [international pricing](https://shopify.dev/custom-storefronts/internationalization/international-pricing). */ cost?:ValueTypes["CartCost"], /** The date and time when the cart was created. */ createdAt?:boolean | `@${string}`, deliveryGroups?: [{ /** Returns up to the first `n` elements from the list. */ first?: number | undefined | null | Variable<any, string>, /** Returns the elements that come after the specified cursor. */ after?: string | undefined | null | Variable<any, string>, /** Returns up to the last `n` elements from the list. */ last?: number | undefined | null | Variable<any, string>, /** Returns the elements that come before the specified cursor. */ before?: string | undefined | null | Variable<any, string>, /** Reverse the order of the underlying list. */ reverse?: boolean | undefined | null | Variable<any, string>},ValueTypes["CartDeliveryGroupConnection"]], /** The discounts that have been applied to the entire cart. */ discountAllocations?:ValueTypes["CartDiscountAllocation"], /** The case-insensitive discount codes that the customer added at checkout. */ discountCodes?:ValueTypes["CartDiscountCode"], /** The estimated costs that the buyer will pay at checkout. The estimated costs are subject to change and changes will be reflected at checkout. The `estimatedCost` field uses the `buyerIdentity` field to determine [international pricing](https://shopify.dev/custom-storefronts/internationalization/international-pricing). */ estimatedCost?:ValueTypes["CartEstimatedCost"], /** A globally-unique identifier. */ id?:boolean | `@${string}`, lines?: [{ /** Returns up to the first `n` elements from the list. */ first?: number | undefined | null | Variable<any, string>, /** Returns the elements that come after the specified cursor. */ after?: string | undefined | null | Variable<any, string>, /** Returns up to the last `n` elements from the list. */ last?: number | undefined | null | Variable<any, string>, /** Returns the elements that come before the specified cursor. */ before?: string | undefined | null | Variable<any, string>, /** Reverse the order of the underlying list. */ reverse?: boolean | undefined | null | Variable<any, string>},ValueTypes["CartLineConnection"]], /** A note that is associated with the cart. For example, the note can be a personalized message to the buyer. */ note?:boolean | `@${string}`, /** The total number of items in the cart. */ totalQuantity?:boolean | `@${string}`, /** The date and time when the cart was updated. */ updatedAt?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** Return type for `cartAttributesUpdate` mutation. */ ["CartAttributesUpdatePayload"]: AliasType<{ /** The updated cart. */ cart?:ValueTypes["Cart"], /** The list of errors that occurred from executing the mutation. */ userErrors?:ValueTypes["CartUserError"], __typename?: boolean | `@${string}` }>; /** The discounts automatically applied to the cart line based on prerequisites that have been met. */ ["CartAutomaticDiscountAllocation"]: AliasType<{ /** The discounted amount that has been applied to the cart line. */ discountedAmount?:ValueTypes["MoneyV2"], /** The title of the allocated discount. */ title?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** Represents information about the buyer that is interacting with the cart. */ ["CartBuyerIdentity"]: AliasType<{ /** The country where the buyer is located. */ countryCode?:boolean | `@${string}`, /** The customer account associated with the cart. */ customer?:ValueTypes["Customer"], /** An ordered set of delivery addresses tied to the buyer that is interacting with the cart. The rank of the preferences is determined by the order of the addresses in the array. Preferences can be used to populate relevant fields in the checkout flow. */ deliveryAddressPreferences?:ValueTypes["DeliveryAddress"], /** The email address of the buyer that is interacting with the cart. */ email?:boolean | `@${string}`, /** The phone number of the buyer that is interacting with the cart. */ phone?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** Specifies the input fields to update the buyer information associated with a cart. Buyer identity is used to determine [international pricing](https://shopify.dev/custom-storefronts/internationalization/international-pricing) and should match the customer's shipping address. */ ["CartBuyerIdentityInput"]: { /** The email address of the buyer that is interacting with the cart. */ email?: string | undefined | null | Variable<any, string>, /** The phone number of the buyer that is interacting with the cart. */ phone?: string | undefined | null | Variable<any, string>, /** The country where the buyer is located. */ countryCode?: ValueTypes["CountryCode"] | undefined | null | Variable<any, string>, /** The access token used to identify the customer associated with the cart. */ customerAccessToken?: string | undefined | null | Variable<any, string>, /** An ordered set of delivery addresses tied to the buyer that is interacting with the cart. The rank of the preferences is determined by the order of the addresses in the array. Preferences can be used to populate relevant fields in the checkout flow. */ deliveryAddressPreferences?: Array<ValueTypes["DeliveryAddressInput"]> | undefined | null | Variable<any, string> }; /** Return type for `cartBuyerIdentityUpdate` mutation. */ ["CartBuyerIdentityUpdatePayload"]: AliasType<{ /** The updated cart. */ cart?:ValueTypes["Cart"], /** The list of errors that occurred from executing the mutation. */ userErrors?:ValueTypes["CartUserError"], __typename?: boolean | `@${string}` }>; /** The discount that has been applied to the cart line using a discount code. */ ["CartCodeDiscountAllocation"]: AliasType<{ /** The code used to apply the discount. */ code?:boolean | `@${string}`, /** The discounted amount that has been applied to the cart line. */ discountedAmount?:ValueTypes["MoneyV2"], __typename?: boolean | `@${string}` }>; /** The costs that the buyer will pay at checkout. The cart cost uses [`CartBuyerIdentity`](https://shopify.dev/api/storefront/reference/cart/cartbuyeridentity) to determine [international pricing](https://shopify.dev/custom-storefronts/internationalization/international-pricing). */ ["CartCost"]: AliasType<{ /** The estimated amount, before taxes and discounts, for the customer to pay at checkout. The checkout charge amount doesn't include any deferred payments that'll be paid at a later date. If the cart has no deferred payments, then the checkout charge amount is equivalent to `subtotalAmount`. */ checkoutChargeAmount?:ValueTypes["MoneyV2"], /** The amount, before taxes and cart-level discounts, for the customer to pay. */ subtotalAmount?:ValueTypes["MoneyV2"], /** Whether the subtotal amount is estimated. */ subtotalAmountEstimated?:boolean | `@${string}`, /** The total amount for the customer to pay. */ totalAmount?:ValueTypes["MoneyV2"], /** Whether the total amount is estimated. */ totalAmountEstimated?:boolean | `@${string}`, /** The duty amount for the customer to pay at checkout. */ totalDutyAmount?:ValueTypes["MoneyV2"], /** Whether the total duty amount is estimated. */ totalDutyAmountEstimated?:boolean | `@${string}`, /** The tax amount for the customer to pay at checkout. */ totalTaxAmount?:ValueTypes["MoneyV2"], /** Whether the total tax amount is estimated. */ totalTaxAmountEstimated?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** Return type for `cartCreate` mutation. */ ["CartCreatePayload"]: AliasType<{ /** The new cart. */ cart?:ValueTypes["Cart"], /** The list of errors that occurred from executing the mutation. */ userErrors?:ValueTypes["CartUserError"], __typename?: boolean | `@${string}` }>; /** The discounts automatically applied to the cart line based on prerequisites that have been met. */ ["CartCustomDiscountAllocation"]: AliasType<{ /** The discounted amount that has been applied to the cart line. */ discountedAmount?:ValueTypes["MoneyV2"], /** The title of the allocated discount. */ title?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** Information about the options available for one or more line items to be delivered to a specific address. */ ["CartDeliveryGroup"]: AliasType<{ cartLines?: [{ /** Returns up to the first `n` elements from the list. */ first?: number | undefined | null | Variable<any, string>, /** Returns the elements that come after the specified cursor. */ after?: string | undefined | null | Variable<any, string>, /** Returns up to the last `n` elements from the list. */ last?: number | undefined | null | Variable<any, string>, /** Returns the elements that come before the specified cursor. */ before?: string | undefined | null | Variable<any, string>, /** Reverse the order of the underlying list. */ reverse?: boolean | undefined | null | Variable<any, string>},ValueTypes["CartLineConnection"]], /** The destination address for the delivery group. */ deliveryAddress?:ValueTypes["MailingAddress"], /** The delivery options available for the delivery group. */ deliveryOptions?:ValueTypes["CartDeliveryOption"], /** The ID for the delivery group. */ id?:boolean | `@${string}`, /** The selected delivery option for the delivery group. */ selectedDeliveryOption?:ValueTypes["CartDeliveryOption"], __typename?: boolean | `@${string}` }>; /** An auto-generated type for paginating through multiple CartDeliveryGroups. */ ["CartDeliveryGroupConnection"]: AliasType<{ /** A list of edges. */ edges?:ValueTypes["CartDeliveryGroupEdge"], /** A list of the nodes contained in CartDeliveryGroupEdge. */ nodes?:ValueTypes["CartDeliveryGroup"], /** Information to aid in pagination. */ pageInfo?:ValueTypes["PageInfo"], __typename?: boolean | `@${string}` }>; /** An auto-generated type which holds one CartDeliveryGroup and a cursor during pagination. */ ["CartDeliveryGroupEdge"]: AliasType<{ /** A cursor for use in pagination. */ cursor?:boolean | `@${string}`, /** The item at the end of CartDeliveryGroupEdge. */ node?:ValueTypes["CartDeliveryGroup"], __typename?: boolean | `@${string}` }>; /** Information about a delivery option. */ ["CartDeliveryOption"]: AliasType<{ /** The code of the delivery option. */ code?:boolean | `@${string}`, /** The method for the delivery option. */ deliveryMethodType?:boolean | `@${string}`, /** The description of the delivery option. */ description?:boolean | `@${string}`, /** The estimated cost for the delivery option. */ estimatedCost?:ValueTypes["MoneyV2"], /** The unique identifier of the delivery option. */ handle?:boolean | `@${string}`, /** The title of the delivery option. */ title?:boolean | `@${string}`, __typename?: boolean | `@${string}` }>; /** The discounts that have been applied to the cart line. */ ["CartDiscountAllocation"]:AliasType<{ /** The discounted amount that has been applied to the cart line. */ discountedA