import type LRU from "@graphile/lru"; import type { FieldNode, GraphQLEnumType, GraphQLObjectType, GraphQLScalarType } from "graphql"; import * as graphql from "graphql"; import type { Bucket } from "../bucket.ts"; import type { ExecutionEntryFlags, JSONValue, LocationDetails } from "../interfaces.ts"; import type { Step } from "../step.ts"; import type { PayloadRoot } from "./executeOutputPlan.ts"; import type { LayerPlan } from "./LayerPlan.ts"; export type OutputPlanTypeIntrospection = { mode: "introspection"; /** * The GraphQL introspection field selection (may include arguments/etc). We * can build a GraphQL document from this and issue it to graphql-js rather * than replicating that effort. */ field: FieldNode; /** * The names of the variables used in this document. */ variableNames: string[]; /** * No need to re-run the introspection each time, may as well cache it, * right? * * Key: canonical JSON stringify of the variables used. * Value: the GraphQL result (`{data, errors}`) for this. */ introspectionCacheByVariableValues: LRU; }; export type OutputPlanTypeRoot = { /** * Always return `{}` */ mode: "root"; typeName: string; }; export type OutputPlanTypeObject = { /** * Return `{}` if non-null */ mode: "object"; typeName: string; deferLabel: string | undefined; }; export type OutputPlanTypePolymorphicObject = { /** * Return `{}` if non-null */ mode: "polymorphic"; typeNames: string[]; deferLabel: string | undefined; }; export type OutputPlanTypeArray = { /** * Return a list of the same length if an array */ mode: "array"; }; export type OutputPlanTypeLeaf = { /** * Return the value. */ mode: "leaf"; graphqlType: GraphQLScalarType | GraphQLEnumType; }; export type OutputPlanTypeNull = { mode: "null"; }; /** * Thanks to `@stream`, output plans must handle their own nullability concerns * and we might need an output plan for any of these: * * - A concrete object * - A polymorphic object * - A leaf (enum/scalar) * - Something we know will always be null * - A list of any of the above * - A list of lists * * In addition to the above, we also need to cover * * - The root object (which is like a concrete object, except it's never null) * - Introspection */ export type OutputPlanType = OutputPlanTypeRoot | OutputPlanTypeObject | OutputPlanTypePolymorphicObject | OutputPlanTypeLeaf | OutputPlanTypeNull | OutputPlanTypeArray | OutputPlanTypeIntrospection; export type OutputPlanKeyValueOutputPlan = { type: "outputPlan"; outputPlan: OutputPlan; isNonNull: boolean; locationDetails: LocationDetails; }; export type OutputPlanKeyValueTypeName = { type: "__typename"; locationDetails: LocationDetails; }; export type OutputPlanKeyValue = OutputPlanKeyValueOutputPlan | OutputPlanKeyValueTypeName; export type OutputPlanKeyValueOutputPlanWithCachedBits = OutputPlanKeyValueOutputPlan & { layerPlanId: number; }; /** * Defines a way of taking a layerPlan and converting it into an output value. * * The result of executing an output plan will be the following: * * - data?: the data for this layer, could be object, array or leaf (see OutputPlanMode) * - errors: a list of errors that occurred (if any), including path details _within the output plan_ * - streams: a list of streams that were created */ export declare class OutputPlan { /** For errors */ readonly locationDetails: LocationDetails; /** * The step that represents the root value. How this is used depends on the * OutputPlanMode. */ readonly rootStep: Step; /** * If this output plan should resolve to an error if a side effect step * raises an error, this is that side effect. */ readonly sideEffectStep: Step | null; /** * For root/object output plans, the keys to set on the resulting object * grouped by the concrete object type name. * * IMPORTANT: the order of these keys is significant, they MUST match the * order in the request otherwise we break GraphQL spec compliance! */ keys: { [key: string]: OutputPlanKeyValueTypeName | OutputPlanKeyValueOutputPlanWithCachedBits; }; /** * For list output plans, the output plan that describes the list children. */ child: OutputPlan | null; childIsNonNull: boolean; /** * For polymorphic output plans, the Object output plan for each specific type. */ childByTypeName: { [typeName: string]: OutputPlan; } | undefined; /** * For object output plan types only. */ deferredOutputPlans: OutputPlan[]; layerPlan: LayerPlan; readonly type: TType; constructor(layerPlan: LayerPlan, /** * For root, this should always be an object. * * For object this could represent an object or null. * * For polymorphic this could represent a polymorphic object or null. * * For array it's the list itself (or null) and dictates the length of the result. * * For leaf, it's the leaf plan itself. * * For `introspection`, `null` it's irrelevant. Use `constant(null)` or whatever. */ rootStep: Step, type: TType, locationDetails: LocationDetails); print(): string; toString(): string; expectChild(type: GraphQLObjectType | null, key: string | null): void; addChild(type: GraphQLObjectType | null, key: string | null, child: OutputPlanKeyValue): void; getLayerPlans(layerPlans?: Set>): Set; makeNextStepByLayerPlan(): Record; execute(this: OutputPlan, _root: PayloadRoot, _mutablePath: ReadonlyArray, _bucket: Bucket, _bucketIndex: number, _rawBucketRootValue?: any, _bucketRootFlags?: ExecutionEntryFlags): JSONValue; executeString(this: OutputPlan, _root: PayloadRoot, _mutablePath: ReadonlyArray, _bucket: Bucket, _bucketIndex: number, _rawBucketRootValue?: any, _bucketRootFlags?: ExecutionEntryFlags): string; optimize(): void; finalize(): void; } export declare function coerceError(error: Error, locationDetails: LocationDetails, path: ReadonlyArray): graphql.GraphQLError; export declare function nonNullError(locationDetails: LocationDetails, path: readonly (string | number)[]): graphql.GraphQLError; /** * Finds the child of `targetParent` that has a path towards `descendent` (by * walking backwards from descendent to targetParent). */ export declare function getDirectLayerPlanChild(targetParent: LayerPlan, descendent: LayerPlan): LayerPlan; //# sourceMappingURL=OutputPlan.d.ts.map