@samarium.sdk/make
Version:
1,163 lines (1,044 loc) • 250 kB
JavaScript
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 ||