UNPKG

@samarium.sdk/make

Version:
1,163 lines (1,044 loc) 250 kB
var __defProp = Object.defineProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true, configurable: true, set: (newValue) => all[name] = () => newValue }); }; // src/graphql/builder/base.ts class GeneratorSelectionTypeFlavor { collector; options; authConfig; static FieldValueWrapperType; static EnumTypesMapped; static HelperTypes; static HelperFunctions; typeMeta; typeName; originalFullTypeName; constructor(typeName, collector, options, authConfig) { this.collector = collector; this.options = options; this.authConfig = authConfig; this.typeMeta = collector.getType(typeName); this.originalFullTypeName = typeName; this.typeName = this.originalTypeNameToTypescriptFriendlyName(typeName); } originalTypeNameToTypescriptFriendlyName(originalTypeName) { return originalTypeName.replaceAll("[", "").replaceAll("]", "Array").replaceAll("!", "NotNull"); } originalTypeNameToTypescriptTypeNameWithoutModifiers(originalTypeName, suffix = "") { return `${originalTypeName.replaceAll("[", "").replaceAll("]", "").replaceAll("!", "")}${suffix}`; } originalTypeNameToTypescriptTypeName(originalTypeName, suffix = "") { return `${this.originalTypeNameToTypescriptTypeNameWithoutModifiers(originalTypeName, suffix)}${Array.from({ length: originalTypeName.split("[").length - 1 }).fill("[]").join("")}`; } static makeRootOperationFunction(collector) { throw new Error("Method not implemented."); } } // src/graphql/flavors/default/generator-flavor.ts import { DirectiveLocation } from "graphql"; // src/graphql/flavors/default/wrapper.ts var wrapper_default = `const Proxy = globalThis.Proxy; Proxy.prototype = {}; function getReconstructedData(data: any, prefixes: string[], keepRest = true, hoist = true): any { if (!prefixes?.length) return data; if (Array.isArray(data)) return data.map((item) => getReconstructedData(item, prefixes, keepRest)) as any[]; const entries = keepRest ? Object.entries(data) : Object.entries(data).filter(([key]) => prefixes.some((p) => key.startsWith(p))); const hoistedObjs: Map<string, [key: string, val: any][]> = new Map(); const newEntries: [key: string, val: any][] = []; for (let keyval of entries) { let res: typeof keyval | undefined = keyval; for (const prefix of prefixes) { const [key, val] = keyval; if (key.startsWith(prefix)) { res = [key.replace(prefix, ""), val] as [key: string, val: any]; if (hoist) { if (!hoistedObjs.has(prefix)) hoistedObjs.set(prefix, []); hoistedObjs.get(prefix)!.push(res); res = undefined; break; } } } if (res) newEntries.push(res); } if (hoist) newEntries.push( ...Array.from(hoistedObjs.entries(), ([alias, vals]) => { return [alias, Object.fromEntries(vals)] as [key: string, val: any]; }), ); return Object.fromEntries(newEntries); } function proxify(_data: any, slw: SelectionWrapperImpl<any, any, any, any, any>): any & ArrayLike<any> { const aliases = Object.entries(slw[SLW_VALUE] || {}) .map(([k, v]) => (v instanceof SelectionWrapperImpl ? v[SLW_ALIAS_PREFIX] : 0)) .filter(Boolean) as string[]; const data = getReconstructedData(_data, aliases); // Create proxy around empty array (ensures Array.isArray(proxy) === true) const proxy = new Proxy(data as any | any[], { get(target: any[], prop: PropertyKey, receiver: any): any { return Reflect.get(slw, prop, receiver); }, set(target: any[], prop: PropertyKey, value: any, receiver: any): boolean { return Reflect.set(slw, prop, value, receiver); }, has(target: any[], prop: PropertyKey): boolean { return Reflect.has(slw, prop); }, deleteProperty(target: any[], prop: PropertyKey): boolean { return Reflect.deleteProperty(slw, prop); }, ownKeys(target: any[]): ArrayLike<string | symbol> { return Reflect.ownKeys(target); }, getOwnPropertyDescriptor(target: any[], prop: PropertyKey): PropertyDescriptor | undefined { return Reflect.getOwnPropertyDescriptor(target, prop); }, getPrototypeOf(target: any[]): object | null { // Return Array.prototype for better array-like behavior (e.g., instanceof Array) return Object.getPrototypeOf(target); }, // Add more traps as needed for full array-like behavior (e.g., apply/construct if callable) }); // Optionally, augment here (e.g., add methods or computed props via additional get trap logic) return proxy as unknown as any & ArrayLike<any>; } type FnOrPromisOrPrimitive = | (() => string | { [key: string]: string } | undefined) | (() => Promise<string | { [key: string]: string } | undefined>) | string | { [key: string]: string }; export const _ = Symbol("_") as any; export const OPTIONS = Symbol("OPTIONS"); export const PLUGINS = Symbol("PLUGINS"); export class RootOperation { public static authHeaderName = "[AUTH_HEADER_NAME]"; private resolveFnOrPromisOrPrimitiveHeaders = (arg?: FnOrPromisOrPrimitive) => { if (!arg) return undefined; let headers: Record<string, string> | undefined = undefined; if (typeof arg === "string") { headers = { [RootOperation.authHeaderName]: arg }; } else if (typeof arg === "function") { const tokenOrPromise = arg(); if (tokenOrPromise instanceof Promise) { return tokenOrPromise.then((t) => { if (typeof t === "string") headers = { [RootOperation.authHeaderName]: t }; else headers = t; return headers; }); } if (typeof tokenOrPromise === "string") { headers = { [RootOperation.authHeaderName]: tokenOrPromise }; } else { headers = tokenOrPromise; } } else { headers = arg; } return headers; }; constructor( public authArg?: FnOrPromisOrPrimitive, public headers?: FnOrPromisOrPrimitive, ) { } public setAuth(auth: FnOrPromisOrPrimitive) { this.authArg = auth; return this; } public setHeaders(headers: FnOrPromisOrPrimitive) { this.headers = headers; return this; } public static [OPTIONS] = { headers: {}, fetcher: undefined as unknown as ( input: string | URL | globalThis.Request, init?: RequestInit, ) => Promise<Response>, sseFetchTransform: undefined as unknown as ( input: string | URL | globalThis.Request, init?: RequestInit, ) => Promise<[string | URL | globalThis.Request, RequestInit | undefined]>, _auth_fn: undefined as | (() => string | { [key: string]: string } | undefined) | (() => Promise<string | { [key: string]: string } | undefined>) | undefined, scalars: { DateTime: (value: string) => new Date(value), DateTimeISO: (value: string) => new Date(value), Date: (value: string) => new Date(value), Time: (value: string) => new Date(value), JSON: (value: string) => JSON.parse(value), }, }; private static [PLUGINS]: { onSLWConstruct?: (slw: SelectionWrapperImpl<any, any, any, any, any>) => void; onSLWSetTrap?: ( target: SelectionWrapperImpl<any, any, any, any, any>, p: PropertyKey, newValue: any, receiver: any, ) => void; onGetResultData?: (t: SelectionWrapperImpl<any, any, any, any, any>, path?: string) => void; }[] = []; private static hasPlugins = false; public static setPlugins(plugins: (typeof RootOperation)[typeof PLUGINS]) { RootOperation[PLUGINS] = plugins; RootOperation.hasPlugins = plugins.length > 0; } public static runPlugins<N extends keyof (typeof RootOperation)[typeof PLUGINS][number]>( name: N, ...args: Parameters<NonNullable<(typeof RootOperation)[typeof PLUGINS][number][N]>> ) { if (!RootOperation.hasPlugins) return; for (const plugin of RootOperation[PLUGINS]) { const fn = plugin[name as keyof typeof plugin]; if (fn) (fn as (...args: any[]) => any).apply(undefined, args); } } private utilSet = (obj: Record<string, any>, path: string[], value: any) => path.reduce((o, p, i, a) => (o[p] = a.length - 1 === i ? value : o[p] || {}), obj); private rootCollector: OperationSelectionCollector | undefined = undefined; public registerRootCollector(collector: OperationSelectionCollector) { this.rootCollector = collector; } public async execute(headers: Record<string, string> = {}) { if (!this.rootCollector?.op) { throw new Error("RootOperation has no registered collector"); } const authHeaders = await this.rootCollector.op!.resolveFnOrPromisOrPrimitiveHeaders( this.rootCollector.op!.authArg ?? RootOperation[OPTIONS]._auth_fn, ); const headersHeaders = await this.rootCollector.op!.resolveFnOrPromisOrPrimitiveHeaders( this.rootCollector.op!.headers ?? RootOperation[OPTIONS].headers, ); headers = { ...authHeaders, ...headersHeaders, ...headers, }; type selection = ReturnType<typeof OperationSelectionCollector.prototype.renderSelections>; const operations: { [key: string]: { selection: selection; rootSlw: SelectionWrapperImpl<string, string, number, any>; }; } = {}; for (const [opName, opSelection] of this.rootCollector?.selections.entries()) { if (opSelection[SLW_LAZY_FLAG]) continue; let rootSlw = opSelection; while (!rootSlw[SLW_IS_ROOT_TYPE]) { if (!rootSlw[SLW_PARENT_SLW]) break; rootSlw = rootSlw[SLW_PARENT_SLW]!; } const selection = rootSlw[SLW_COLLECTOR]!.renderSelections( [opName], {}, new Map(), opSelection === rootSlw ? [] : [opSelection], ); operations[opName] = { selection, rootSlw, }; } const ops = Object.entries(operations).reduce( (acc, [opName, { selection, rootSlw }]) => ({ ...acc, [opName]: { opType: rootSlw[SLW_IS_ROOT_TYPE]?.toLowerCase() as "subscription" | "query" | "mutation", query: \`\${rootSlw[SLW_IS_ROOT_TYPE]?.toLowerCase()} \${opName} \${selection.variableDefinitions.length ? \`(\${selection.variableDefinitions.join(", ")}) \` : "" }\${selection.selection}\`, variables: selection.variables, fragments: selection.usedFragments, }, }), {} as Record< string, { opType: "subscription" | "query" | "mutation"; query: string; variables: any; fragments: Map<string, string>; } >, ); const results = Object.fromEntries( await Promise.all([ ...Object.entries(ops).map( async ([opName, op]) => [ opName, op.opType === "subscription" ? await this.subscribeOperation(op, headers) : await this.executeOperation(op, headers), ] as const, ), ]), ); return results; } private async subscribeOperation( query: { opType: "subscription" | "query" | "mutation"; query: string; variables: any; fragments: Map<string, string>; }, headers: Record<string, string> = {}, ): Promise<AsyncGenerator<any, void, unknown>> { const that = this; const generator = (async function* () { const [url, options] = (await ( RootOperation[OPTIONS].sseFetchTransform ?? ((url: string, options?: RequestInit) => [url, options]) )("[ENDPOINT]", { method: "POST", headers: { ...headers, "Content-Type": "application/json", Accept: "text/event-stream", }, body: JSON.stringify({ query: \`\${[...query.fragments.values()].join("\\n")}\\n \${query.query}\`.trim(), variables: query.variables, }), })) as [string | URL | Request, RequestInit]; const response = await (RootOperation[OPTIONS].fetcher ?? globalThis.fetch)(url, { ...options, headers: { ...options?.headers, "Content-Type": "application/json", Accept: "text/event-stream", }, }); const reader = response.body!.getReader(); const decoder = new TextDecoder(); let buffer = ""; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const events = buffer.split("\\n\\n"); buffer = events.pop() || ""; for (const event of events) { if (event.trim()) { const eventName = event.match(/^event: (.*)$/m)?.[1]; const rawdata = event.match(/^data: (.*)$/m)?.[1]; if ((eventName === null && rawdata === "") || !rawdata) continue; if (eventName === "complete" || done) break; const parsed = JSON.parse(rawdata) as { data: any; errors: any[]; }; const { data, errors } = parsed ?? {}; if (errors?.length > 0) { if (!data) { const err = new Error(JSON.stringify(errors), { cause: "Only errors were returned from the server.", }); throw err; } for (const error of errors) { if (error.path) { that.utilSet(data, error.path, error); } } } yield data; } } } return; })(); return generator; } private async executeOperation( query: { opType: "subscription" | "query" | "mutation"; query: string; variables: any; fragments: Map<string, string>; }, headers: Record<string, string> = {}, ) { const res = await (RootOperation[OPTIONS].fetcher ?? globalThis.fetch)("[ENDPOINT]", { method: "POST", headers: { "Content-Type": "application/json", ...headers, }, body: JSON.stringify({ query: \`\${[...query.fragments.values()].join("\\n")}\\n \${query.query}\`.trim(), variables: query.variables, }), }); const result = (await res.json()) as { data: any; errors: any[] }; const { data, errors } = result ?? {}; if (errors?.length > 0) { if (!data) { const err = new Error(JSON.stringify(errors), { cause: "Only errors were returned from the server.", }); throw err; } for (const error of errors) { if (error.path) { this.utilSet(data, error.path, error); } } } return data; } } export type OperationSelectionCollectorRef = { ref: OperationSelectionCollector; }; export class OperationSelectionCollector { constructor( public readonly name?: string, public readonly parent?: OperationSelectionCollector | OperationSelectionCollectorRef, public readonly op?: RootOperation, ) { if (op) op.registerRootCollector(this); } private executed = false; private operationResult: any | undefined = undefined; public cache: { data: Map<string, any>; proxiedArray: Map<string, any[]>; } = { data: new Map(), proxiedArray: new Map(), }; public async execute(headers?: Record<string, string>) { if (!this.op) { throw new Error("OperationSelectionCollector is not registered to a root operation"); } this.operationResult = await this.op.execute(headers); this.executed = true; return this.operationResult; } public get isExecuted() { return this.executed; } public readonly selections = new Map<string, SelectionWrapperImpl<string, string, number, any>>(); public registerSelection(id: string, selection: SelectionWrapperImpl<string, string, number, any, any>) { this.selections.set(id, selection); } public renderSelections( path: string[] = [], opVars: Record<string, any> = {}, usedFragments: Map<string, string> = new Map(), renderOnlyTheseSelections: SelectionWrapperImpl<string, string, number, any>[] = [], ) { const result: Record<string, string | undefined> = {}; const varDefs: string[] = []; const variables: Record<string, any> = {}; for (const [key, value] of [...this.selections.entries()].filter( ([k, v]) => renderOnlyTheseSelections.length === 0 || renderOnlyTheseSelections.find((r) => r[SLW_UID] === v[SLW_UID]), )) { const subPath = [...path, key]; const aliasPrefix = value[SLW_PARENT_SLW]?.[SLW_ALIAS_PREFIX] ?? ""; const { selection: fieldSelection, variableDefinitions: fieldVarDefs, variables: fieldVars, directive: directiveRendered, } = value[SLW_RENDER_WITH_ARGS](opVars); Object.assign(variables, fieldVars); Object.assign(opVars, fieldVars); varDefs.push(...fieldVarDefs); if (directiveRendered) { const { variableDefinitions: directiveVarDefs, variables: directiveVars } = directiveRendered; varDefs.push(...directiveVarDefs); Object.assign(variables, directiveVars); Object.assign(opVars, directiveVars); } value[SLW_REGISTER_PATH](subPath); if (value[SLW_PARENT_COLLECTOR] === undefined) { if (directiveRendered) { result[\`\${aliasPrefix}\${key}\`] = \`\${fieldSelection} \${directiveRendered.rendered}\`; } else { result[\`\${aliasPrefix}\${key}\`] = \`\${fieldSelection}\`; } } else if (value[SLW_COLLECTOR] instanceof OperationSelectionCollector) { const { selection: subSelection, variableDefinitions: subVarDefs, variables: subVars, } = value[SLW_COLLECTOR].renderSelections(subPath, opVars, usedFragments, []); if (value[SLW_IS_ON_TYPE_FRAGMENT]) { if (directiveRendered) { result[\`\${aliasPrefix}\${key}\`] = \`... on \${value[SLW_IS_ON_TYPE_FRAGMENT]} \${directiveRendered.rendered} \${subSelection}\`; } else { result[\`\${aliasPrefix}\${key}\`] = \`... on \${value[SLW_IS_ON_TYPE_FRAGMENT]} \${subSelection}\`; } } else if (value[SLW_IS_FRAGMENT]) { const fragmentName = \`\${key}_\${subVarDefs.map((v) => v.split(":")[0].slice(1)).join("_")}\`; if (directiveRendered) { result[\`\${aliasPrefix}\${key}\`] = \`...\${fragmentName} \${directiveRendered.rendered}\`; } else { result[\`\${aliasPrefix}\${key}\`] = \`...\${fragmentName}\`; } const fragment = \`fragment \${fragmentName} on \${value[SLW_FIELD_TYPENAME]} \${subSelection}\`; if (!usedFragments.has(fragmentName)) { usedFragments.set(fragmentName, fragment); } else if (usedFragments.get(fragmentName) !== fragment) { console.warn(\`Fragment \${fragmentName} is already defined with a different selection\`); } } else { if (directiveRendered) { result[\`\${aliasPrefix}\${key}\`] = \`\${fieldSelection} \${directiveRendered.rendered} \${subSelection}\`; } else { result[\`\${aliasPrefix}\${key}\`] = \`\${fieldSelection} \${subSelection}\`; } } Object.assign(variables, subVars); Object.assign(opVars, subVars); varDefs.push(...subVarDefs); } } let rendered = "{ "; for (const [key, value] of Object.entries(result).filter(([k, v]) => v !== undefined) as [string, string][]) { const keyIsFieldName = value.startsWith(\`\${key} {\`) || value.startsWith(\`\${key} (\`); const isSubSelection = value.startsWith("{"); const isOnType = value.startsWith("... on"); const isFragment = value.startsWith("..."); if (key === value) { rendered += \`\${key} \`; } else if (isOnType || isFragment || keyIsFieldName) { rendered += \`\${value} \`; } else { rendered += \`\${key}\${!isSubSelection ? ":" : ""} \${value} \`; } } rendered += "}"; return { selection: rendered, variableDefinitions: varDefs, variables, usedFragments, }; } private utilGet = (obj: Record<string, any>, path: (string | number)[]) => path.reduce((o, p) => o?.[p], obj); private utilSet = (o: Record<string, any>, p: (string | number)[], v: any) => { for (let i = 0, len = p.length - 1; i < len; i++) o = o[p[i]] ??= Number.isInteger(p[i + 1]) ? [] : {}; o[p[p.length - 1]] = v; }; public getOperationResultPath<T>( path: (string | number)[] = [], _type?: string, opResultDataOverride?: any, aliasPrefix?: string, ): T { if (!this.op) { throw new Error("OperationSelectionCollector is not registered to a root operation"); } let result = opResultDataOverride ?? this.operationResult; if (aliasPrefix) { this.utilSet( result, path, getReconstructedData(this.utilGet(result, path.slice(0, -1)), [aliasPrefix], false)[aliasPrefix], ); } if (path.length === 0) return result as T; result = this.utilGet(result, path) as T; const type = _type?.replaceAll("!", ""); if (type && result && type in RootOperation[OPTIONS].scalars) { let depth = 0; let finalResult = result instanceof Array ? [...result] : result; while (result instanceof Array) { result = result[0]; depth++; } const deepParse = (res: any | any[], depth: number, parse: (v: string) => any) => { if (depth === 0) { return parse(res); } return res.map((rarr: any) => deepParse(rarr, depth - 1, parse)); }; return deepParse( finalResult, depth, RootOperation[OPTIONS].scalars[type as keyof (typeof RootOperation)[typeof OPTIONS]["scalars"]] ?? ((value: string) => JSON.parse(value)), ) as T; } return result as T; } } export const SLW_UID = Symbol("SLW_UID"); export const SLW_FIELD_NAME = Symbol("SLW_FIELD_NAME"); export const SLW_FIELD_TYPENAME = Symbol("SLW_FIELD_TYPENAME"); export const SLW_FIELD_ARR_DEPTH = Symbol("SLW_FIELD_ARR_DEPTH"); export const SLW_IS_ROOT_TYPE = Symbol("SLW_IS_ROOT_TYPE"); export const SLW_IS_ON_TYPE_FRAGMENT = Symbol("SLW_IS_ON_TYPE_FRAGMENT"); export const SLW_IS_FRAGMENT = Symbol("SLW_IS_FRAGMENT"); export const SLW_VALUE = Symbol("SLW_VALUE"); export const SLW_ARGS = Symbol("SLW_ARGS"); export const SLW_ARGS_META = Symbol("SLW_ARGS_META"); export const SLW_DIRECTIVE = Symbol("SLW_DIRECTIVE"); export const SLW_DIRECTIVE_ARGS = Symbol("SLW_DIRECTIVE_ARGS"); export const SLW_DIRECTIVE_ARGS_META = Symbol("SLW_DIRECTIVE_ARGS_META"); export const SLW_PARENT_SLW = Symbol("SLW_PARENT_SLW"); export const SLW_LAZY_FLAG = Symbol("SLW_LAZY_FLAG"); export const SLW_ALIAS_PREFIX = Symbol("SLW_ALIAS_PREFIX"); export const OP = Symbol("OP"); export const ROOT_OP_COLLECTOR = Symbol("ROOT_OP_COLLECTOR"); export const SLW_PARENT_COLLECTOR = Symbol("SLW_PARENT_COLLECTOR"); export const SLW_COLLECTOR = Symbol("SLW_COLLECTOR"); export const SLW_OP_PATH = Symbol("SLW_OP_PATH"); export const SLW_REGISTER_PATH = Symbol("SLW_REGISTER_PATH"); export const SLW_RENDER_WITH_ARGS = Symbol("SLW_RENDER_WITH_ARGS"); export const SLW_OP_RESULT_DATA_OVERRIDE = Symbol("SLW_OP_RESULT_DATA_OVERRIDE"); export const SLW_RECREATE_VALUE_CALLBACK = Symbol("SLW_RECREATE_VALUE_CALLBACK"); export const SLW_SETTER_DATA_OVERRIDE = Symbol("SLW_SETTER_DATA_OVERRIDE"); export const SLW_NEEDS_CLONE = Symbol("SLW_NEEDS_CLONE"); export const SLW_CLONE = Symbol("SLW_CLONE"); export class SelectionWrapperImpl< fieldName extends string, typeNamePure extends string, typeArrDepth extends number, valueT extends any = any, argsT extends Record<string, any> | undefined = undefined, > { private generateUniqueId(): string { return performance.now().toString(36) + Math.random().toString(36).substring(2); } [SLW_CLONE]( overrides: { SLW_OP_PATH?: string; OP_RESULT_DATA?: any; SLW_SETTER_DATA_OVERRIDE?: any; SLW_NEEDS_CLONE?: boolean; } = {}, ) { const slw = new SelectionWrapper( this[SLW_FIELD_NAME], this[SLW_FIELD_TYPENAME], this[SLW_FIELD_ARR_DEPTH], this[SLW_VALUE], this[SLW_COLLECTOR], this[SLW_PARENT_COLLECTOR], this[SLW_ARGS], this[SLW_ARGS_META], this[SLW_RECREATE_VALUE_CALLBACK], ); slw[SLW_IS_ROOT_TYPE] = this[SLW_IS_ROOT_TYPE]; slw[SLW_IS_ON_TYPE_FRAGMENT] = this[SLW_IS_ON_TYPE_FRAGMENT]; slw[SLW_IS_FRAGMENT] = this[SLW_IS_FRAGMENT]; slw[SLW_PARENT_SLW] = this[SLW_PARENT_SLW]; slw[SLW_OP_PATH] = overrides.SLW_OP_PATH ?? this[SLW_OP_PATH]; slw[SLW_SETTER_DATA_OVERRIDE] = overrides.SLW_SETTER_DATA_OVERRIDE ?? this[SLW_SETTER_DATA_OVERRIDE]; slw[SLW_NEEDS_CLONE] = overrides.SLW_NEEDS_CLONE ? true : this[SLW_NEEDS_CLONE] ? false : true; slw[SLW_ALIAS_PREFIX] = this[SLW_ALIAS_PREFIX]; if (overrides.OP_RESULT_DATA) { slw[SLW_OP_RESULT_DATA_OVERRIDE] = overrides.OP_RESULT_DATA; } if (this[ROOT_OP_COLLECTOR]) { slw[ROOT_OP_COLLECTOR] = this[ROOT_OP_COLLECTOR]; } return slw; } [SLW_UID] = this.generateUniqueId(); [ROOT_OP_COLLECTOR]?: OperationSelectionCollectorRef; [SLW_PARENT_COLLECTOR]?: OperationSelectionCollector; [SLW_COLLECTOR]?: OperationSelectionCollector; [SLW_FIELD_NAME]?: fieldName; [SLW_FIELD_TYPENAME]?: typeNamePure; [SLW_FIELD_ARR_DEPTH]?: typeArrDepth; [SLW_VALUE]?: valueT; [SLW_IS_ROOT_TYPE]?: "Query" | "Mutation" | "Subscription"; [SLW_IS_ON_TYPE_FRAGMENT]?: string; [SLW_IS_FRAGMENT]?: string; [SLW_ARGS]?: argsT; [SLW_ARGS_META]?: Record<string, string>; [SLW_DIRECTIVE]?: string; [SLW_DIRECTIVE_ARGS]?: Record<string, any>; [SLW_DIRECTIVE_ARGS_META]?: Record<string, string>; [SLW_PARENT_SLW]?: SelectionWrapperImpl<string, string, number, any, any>; [SLW_LAZY_FLAG]?: boolean; [SLW_RECREATE_VALUE_CALLBACK]?: () => valueT; [SLW_ALIAS_PREFIX]?: string; [SLW_OP_RESULT_DATA_OVERRIDE]?: any; [SLW_SETTER_DATA_OVERRIDE]?: any; [SLW_NEEDS_CLONE]?: boolean; constructor( fieldName?: fieldName, typeNamePure?: typeNamePure, typeArrDepth?: typeArrDepth, value?: valueT, collector?: OperationSelectionCollector, parent?: OperationSelectionCollector | OperationSelectionCollectorRef, args?: argsT, argsMeta?: Record<string, string>, reCreateValueCallback?: () => valueT, ) { this[SLW_FIELD_NAME] = fieldName; this[SLW_FIELD_TYPENAME] = typeNamePure; this[SLW_FIELD_ARR_DEPTH] = typeArrDepth; this[SLW_VALUE] = value; this[SLW_ARGS] = args; this[SLW_ARGS_META] = argsMeta; if (parent instanceof OperationSelectionCollector) { this[SLW_PARENT_COLLECTOR] = parent; } else if (parent && "ref" in parent) { this[SLW_PARENT_COLLECTOR] = parent.ref; } if (collector instanceof OperationSelectionCollector) { this[SLW_COLLECTOR] = collector; let rootCollector = collector; while (rootCollector?.parent instanceof OperationSelectionCollector) { rootCollector = rootCollector.parent; } if (rootCollector.parent && "ref" in rootCollector.parent) { this[ROOT_OP_COLLECTOR] = rootCollector.parent; } } if (reCreateValueCallback) { this[SLW_RECREATE_VALUE_CALLBACK] = reCreateValueCallback; } RootOperation.runPlugins("onSLWConstruct", this); } [SLW_OP_PATH]?: string; [SLW_REGISTER_PATH](path: string[]) { if (!this[SLW_OP_PATH]) this[SLW_OP_PATH] = path.join("."); } [SLW_RENDER_WITH_ARGS](opVars: Record<string, any> = {}) { const renderArgsString = (args: Record<string, any>, argsMeta: Record<string, string>) => { const argToVarMap: Record<string, string> = {}; let argsString = "("; const argsStringParts: string[] = []; for (const key of Object.keys(args)) { let varName = key; if (opVars[key] !== undefined) { varName = \`\${key}_\${Object.keys(opVars).filter((k) => k.startsWith(key)).length}\`; argToVarMap[varName] = varName; args[varName] = args[key]; argsMeta[varName] = argsMeta[key]; delete args[key]; } argsStringParts.push(\`\${key}: $\${varName}\`); } argsString += argsStringParts.join(", ").trim() + ")"; return { argsString, argToVarMap }; }; const directiveRender = { rendered: undefined as string | undefined, variables: {} as Record<string, any>, variableDefinitions: [] as string[], }; if (this[SLW_DIRECTIVE]) { const directive = this[SLW_DIRECTIVE]; if (this[SLW_DIRECTIVE_ARGS]) { const args = this[SLW_DIRECTIVE_ARGS]; const argsMeta = this[SLW_DIRECTIVE_ARGS_META]!; const { argsString, argToVarMap } = renderArgsString(args, argsMeta); directiveRender.rendered = \`@\${directive}\${Object.keys(args).length ? argsString : ""}\`; directiveRender.variables = args; directiveRender.variableDefinitions = Object.keys(args).map((key) => { const varName = argToVarMap[key] ?? key; return \`$\${varName}: \${argsMeta[key]}\`; }); } else { directiveRender.rendered = \`@\${directive}\`; } } if (this[SLW_ARGS]) { const args = this[SLW_ARGS]; const argsMeta = this[SLW_ARGS_META]!; const { argsString, argToVarMap } = renderArgsString(args, argsMeta); return { selection: \`\${this[SLW_FIELD_NAME]}\${Object.keys(args).length ? argsString : ""}\`, variables: args, variableDefinitions: Object.keys(args).map((key) => { const varName = argToVarMap[key] ?? key; return \`$\${varName}: \${argsMeta[key]}\`; }), directive: directiveRender.rendered ? directiveRender : undefined, }; } return { selection: this[SLW_FIELD_NAME], variables: {}, variableDefinitions: [] as string[], directive: directiveRender.rendered ? directiveRender : undefined, }; } } export class SelectionWrapper< fieldName extends string, typeNamePure extends string, typeArrDepth extends number, valueT extends any = any, argsT extends Record<string, any> | undefined = undefined, > extends Proxy<SelectionWrapperImpl<fieldName, typeNamePure, typeArrDepth, valueT, argsT>> { constructor( fieldName?: fieldName, typeNamePure?: typeNamePure, typeArrDepth?: typeArrDepth, value?: valueT, collector?: OperationSelectionCollector, parent?: OperationSelectionCollector | OperationSelectionCollectorRef, args?: argsT, argsMeta?: Record<string, string>, reCreateValueCallback?: () => valueT, ) { super( new SelectionWrapperImpl<fieldName, typeNamePure, typeArrDepth, valueT, argsT>( fieldName, typeNamePure, typeArrDepth, value, collector, parent, args, argsMeta, reCreateValueCallback, ), (() => { const getCache = (t: SelectionWrapperImpl<fieldName, typeNamePure, typeArrDepth, valueT, argsT>) => t[SLW_OP_RESULT_DATA_OVERRIDE] ? { data: new Map(), proxiedArray: new Map() } : t[ROOT_OP_COLLECTOR]!.ref.cache; const getResultDataForTarget = ( t: SelectionWrapperImpl<fieldName, typeNamePure, typeArrDepth, valueT, argsT>, overrideOpPath?: string, skipPlugins?: boolean, ): valueT | undefined => { const cache = getCache(t); const path = overrideOpPath ?? t[SLW_OP_PATH] ?? undefined; if (!skipPlugins) RootOperation.runPlugins("onGetResultData", t, path); if (path && cache.data.has(path) && !t[SLW_NEEDS_CLONE]) return cache.data.get(path); const data = t[ROOT_OP_COLLECTOR]!.ref.getOperationResultPath<valueT>( (path?.split(".") ?? []).map((p) => (!isNaN(+p) ? +p : p)), t[SLW_FIELD_TYPENAME], t[SLW_OP_RESULT_DATA_OVERRIDE], t[SLW_ALIAS_PREFIX], ); if (path) cache.data.set(path, data); return data; }; return { // implement ProxyHandler methods ownKeys(target) { if (target[SLW_FIELD_ARR_DEPTH]) { return Reflect.ownKeys(new Array(target[SLW_FIELD_ARR_DEPTH])); } return Reflect.ownKeys(value ?? {}); }, getOwnPropertyDescriptor(target, prop) { if (target[SLW_FIELD_ARR_DEPTH]) { return Reflect.getOwnPropertyDescriptor(new Array(target[SLW_FIELD_ARR_DEPTH]), prop); } return Reflect.getOwnPropertyDescriptor(value ?? {}, prop); }, has(target, prop) { if (prop === Symbol.for("nodejs.util.inspect.custom")) return true; if (prop === Symbol.iterator && typeArrDepth) { const dataArr = getResultDataForTarget(target, undefined, true); if (Array.isArray(dataArr)) return true; if (dataArr === undefined || dataArr === null) return false; } if (target[SLW_FIELD_ARR_DEPTH]) { return Reflect.has(new Array(target[SLW_FIELD_ARR_DEPTH]), prop); } return Reflect.has(value ?? {}, prop); }, set(target, p, newValue, receiver) { RootOperation.runPlugins("onSLWSetTrap", target, p, newValue, receiver); const pstr = String(p); if ( typeof p === "symbol" && (pstr.startsWith("Symbol(SLW_") || pstr == "Symbol(ROOT_OP_COLLECTOR)") ) { return Reflect.set(target, p, newValue, receiver); } return Reflect.set( target, SLW_SETTER_DATA_OVERRIDE, { ...(target[SLW_SETTER_DATA_OVERRIDE] ?? {}), [p]: newValue, }, receiver, ); }, get: (target, prop) => { if (target[SLW_SETTER_DATA_OVERRIDE] && target[SLW_SETTER_DATA_OVERRIDE][prop]) { return target[SLW_SETTER_DATA_OVERRIDE][prop]; } if (prop === "$lazy") { const that = this; function lazy( this: { parentSlw: SelectionWrapperImpl< fieldName, typeNamePure, typeArrDepth, valueT, argsT >; key: string; }, args?: argsT, ) { const { parentSlw, key } = this; const newRootOpCollectorRef = { ref: new OperationSelectionCollector( undefined, undefined, new RootOperation( that[ROOT_OP_COLLECTOR]!.ref.op!.authArg, that[ROOT_OP_COLLECTOR]!.ref.op!.headers, ), ), }; const newThisCollector = new OperationSelectionCollector( undefined, newRootOpCollectorRef, ); const r = that[SLW_RECREATE_VALUE_CALLBACK]?.bind(newThisCollector)?.() ?? {}; const newThat = new SelectionWrapper( that[SLW_FIELD_NAME], that[SLW_FIELD_TYPENAME], that[SLW_FIELD_ARR_DEPTH], r, newThisCollector, // only set parent collector, if 'that' had one, // the absence indicates, that 'that' is a scalar field // without a subselection! that[SLW_PARENT_COLLECTOR] ? newRootOpCollectorRef : undefined, that[SLW_ARGS], that[SLW_ARGS_META], ); newThat[SLW_UID] = that[SLW_UID]; Object.keys(r!).forEach((key) => (newThat as valueT)[key as keyof valueT]); newThat[SLW_IS_ROOT_TYPE] = that[SLW_IS_ROOT_TYPE]; newThat[SLW_IS_ON_TYPE_FRAGMENT] = that[SLW_IS_ON_TYPE_FRAGMENT]; newThat[SLW_IS_FRAGMENT] = that[SLW_IS_FRAGMENT]; newThat[SLW_PARENT_SLW] = parentSlw; parentSlw[SLW_COLLECTOR]?.registerSelection(key, newThat); newThat[SLW_ARGS] = { ...(that[SLW_ARGS] ?? {}), ...args, } as argsT; newThat[SLW_OP_PATH] = that[SLW_OP_PATH]; newRootOpCollectorRef.ref.registerSelection(newThat[SLW_FIELD_NAME]!, newThat); const isScalar = newThat[SLW_PARENT_COLLECTOR] === undefined; let constPromise: Promise<any> | undefined; let constPromiseStatus: "pending" | "fulfilled" | "rejected" = "pending"; let constPromiseReason: string | undefined; let constPromiseValue: any | undefined; const resultProxy = new Proxy( {}, { get(_t, _prop) { const result = constPromise ?? (constPromise = new Promise((resolve, reject) => { newRootOpCollectorRef.ref .execute() .catch((reason) => { constPromiseStatus = "rejected"; constPromiseReason = reason; return reject(reason); }) .then((_data) => { constPromiseStatus = "fulfilled"; if (_data === undefined || _data === null) { constPromiseValue = _data; return resolve(_data); } const fieldName = newThat[SLW_FIELD_NAME]!; const d = _data[fieldName]; if (Symbol.asyncIterator in d) { constPromiseValue = newThat; return resolve(newThat); } if (typeof d === "object" && d && fieldName in d) { const retval = d[fieldName]; if (retval === undefined || retval === null) { constPromiseValue = retval; return resolve(retval); } const ret = isScalar ? getResultDataForTarget( newThat as SelectionWrapper< fieldName, typeNamePure, typeArrDepth, valueT, argsT >, ) : proxify(retval, newThat); constPromiseValue = ret; return resolve(ret); } constPromiseValue = newThat; return resolve(newThat); }); })); if (String(_prop) === "then") { return result.then.bind(result); } if (String(_prop) === "status") { return constPromiseStatus; } if (String(_prop) === "reason") { return constPromiseReason; } if (String(_prop) === "value") { return constPromiseValue; } return result; }, }, ) as any; return new Proxy( {}, { get(_t, _prop) { if (String(_prop) === "auth") { return (auth: FnOrPromisOrPrimitive) => { newRootOpCollectorRef.ref.op!.setAuth(auth); return resultProxy; }; } return resultProxy[_prop]; }, }, ); } target[SLW_LAZY_FLAG] = true; lazy[SLW_LAZY_FLAG] = true; return lazy; } if ( prop === SLW_UID || prop === SLW_FIELD_NAME || prop === SLW_FIELD_TYPENAME || prop === SLW_FIELD_ARR_DEPTH || prop === SLW_IS_ROOT_TYPE || prop === SLW_IS_ON_TYPE_FRAGMENT || prop === SLW_IS_FRAGMENT || prop === SLW_VALUE || prop === SLW_ARGS || prop === SLW_ARGS_META || prop === SLW_DIRECTIVE || prop === SLW_DIRECTIVE_ARGS ||