Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@apollo/query-graphs

Package Overview
Dependencies
Maintainers
1
Versions
131
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@apollo/query-graphs - npm Package Compare versions

Comparing version 2.8.0-connectors.5 to 2.8.0

12

dist/conditionsCaching.js

@@ -9,6 +9,6 @@ "use strict";

const cache = new querygraph_1.QueryGraphState(graph);
return (edge, context, excludedDestinations, excludedConditions) => {
(0, federation_internals_1.assert)(edge.conditions, 'Should not have been called for edge without conditions');
if (!context.isEmpty() || excludedConditions.length > 0) {
return resolver(edge, context, excludedDestinations, excludedConditions);
return (edge, context, excludedDestinations, excludedConditions, extraConditions) => {
(0, federation_internals_1.assert)(edge.conditions || extraConditions, 'Should not have been called for edge without conditions');
if (!context.isEmpty() || excludedConditions.length > 0 || extraConditions) {
return resolver(edge, context, excludedDestinations, excludedConditions, extraConditions);
}

@@ -20,6 +20,6 @@ const cachedResolutionAndExcludedEdges = cache.getEdgeState(edge);

? cachedResolution
: resolver(edge, context, excludedDestinations, excludedConditions);
: resolver(edge, context, excludedDestinations, excludedConditions, extraConditions);
}
else {
const resolution = resolver(edge, context, excludedDestinations, excludedConditions);
const resolution = resolver(edge, context, excludedDestinations, excludedConditions, extraConditions);
cache.setEdgeState(edge, [resolution, excludedDestinations]);

@@ -26,0 +26,0 @@ return resolution;

@@ -30,4 +30,4 @@ "use strict";

function simpleValidationConditionResolver({ supergraph, queryGraph, withCaching, }) {
const resolver = (edge, context, excludedDestinations, excludedConditions) => {
const conditions = edge.conditions;
const resolver = (edge, context, excludedDestinations, excludedConditions, extraConditions) => {
const conditions = (extraConditions !== null && extraConditions !== void 0 ? extraConditions : edge.conditions);
excludedConditions = (0, graphPath_1.addConditionExclusion)(excludedConditions, conditions);

@@ -34,0 +34,0 @@ const initialPath = graphPath_1.GraphPath.create(queryGraph, edge.head);

@@ -1,2 +0,2 @@

import { NamedType, OperationElement, Schema, SchemaRootKind, SelectionSet, ObjectType, DeferDirectiveArgs } from "@apollo/federation-internals";
import { NamedType, OperationElement, Schema, SchemaRootKind, SelectionSet, ObjectType, DeferDirectiveArgs, Type } from "@apollo/federation-internals";
import { OpPathTree } from "./pathTree";

@@ -6,3 +6,9 @@ import { Vertex, QueryGraph, Edge, RootVertex } from "./querygraph";

import { PathContext } from "./pathContext";
export declare class GraphPath<TTrigger, RV extends Vertex = Vertex, TNullEdge extends null | never = never> implements Iterable<[Edge | TNullEdge, TTrigger, OpPathTree | null]> {
export type ContextAtUsageEntry = {
contextId: string;
relativePath: string[];
selectionSet: SelectionSet;
subgraphArgType: Type;
};
export declare class GraphPath<TTrigger, RV extends Vertex = Vertex, TNullEdge extends null | never = never> implements Iterable<[Edge | TNullEdge, TTrigger, OpPathTree | null, Set<string> | null, Map<string, ContextAtUsageEntry> | null]> {
private readonly props;

@@ -37,2 +43,3 @@ private constructor();

add(trigger: TTrigger, edge: Edge | TNullEdge, conditionsResolution: ConditionResolution, defer?: DeferDirectiveArgs): GraphPath<TTrigger, RV, TNullEdge>;
private mergeEdgeConditionsWithResolution;
concat(tailPath: GraphPath<TTrigger, Vertex, TNullEdge>): GraphPath<TTrigger, RV, TNullEdge>;

@@ -58,3 +65,3 @@ checkDirectPathFromPreviousSubgraphTo(typeName: string, triggerToEdge: (graph: QueryGraph, vertex: Vertex, t: TTrigger, overrideConditions: Map<string, boolean>) => Edge | null | undefined, overrideConditions: Map<string, boolean>, prevSubgraphStartingVertex?: Vertex): Vertex | undefined;

}
export interface PathIterator<TTrigger, TNullEdge extends null | never = never> extends Iterator<[Edge | TNullEdge, TTrigger, OpPathTree | null]> {
export interface PathIterator<TTrigger, TNullEdge extends null | never = never> extends Iterator<[Edge | TNullEdge, TTrigger, OpPathTree | null, Set<string> | null, Map<string, ContextAtUsageEntry> | null]> {
currentIndex: number;

@@ -70,3 +77,13 @@ currentVertex: Vertex;

export declare function traversePath(path: GraphPath<any>, onEdges: (edge: Edge) => void): void;
export type ConditionResolver = (edge: Edge, context: PathContext, excludedDestinations: ExcludedDestinations, excludedConditions: ExcludedConditions) => ConditionResolution;
export type ConditionResolver = (edge: Edge, context: PathContext, excludedDestinations: ExcludedDestinations, excludedConditions: ExcludedConditions, extraConditions?: SelectionSet) => ConditionResolution;
type ContextMapEntry = {
levelsInDataPath: number;
levelsInQueryPath: number;
pathTree?: OpPathTree;
selectionSet: SelectionSet;
inboundEdge: Edge;
paramName: string;
argType: Type;
id: string;
};
export type ConditionResolution = {

@@ -76,6 +93,8 @@ satisfied: boolean;

pathTree?: OpPathTree;
contextMap?: Map<string, ContextMapEntry>;
unsatisfiedConditionReason?: UnsatisfiedConditionReason;
};
export declare enum UnsatisfiedConditionReason {
NO_POST_REQUIRE_KEY = 0
NO_POST_REQUIRE_KEY = 0,
NO_CONTEXT_SET = 1
}

@@ -82,0 +101,0 @@ export declare const noConditionsResolution: ConditionResolution;

import { SelectionSet } from "@apollo/federation-internals";
import { GraphPath, OpGraphPath, OpTrigger } from "./graphPath";
import { OpGraphPath, OpTrigger, ContextAtUsageEntry } from "./graphPath";
import { Edge, QueryGraph, RootVertex, Vertex } from "./querygraph";

@@ -18,7 +18,5 @@ export declare class PathTree<TTrigger, RV extends Vertex = Vertex, TNullEdge extends null | never = never> {

private static createFromPaths;
static mergeAllOpTrees<RV extends Vertex = Vertex>(graph: QueryGraph, root: RV, trees: OpPathTree<RV>[]): OpPathTree<RV>;
private static mergeAllTreesInternal;
childCount(): number;
isLeaf(): boolean;
childElements(reverseOrder?: boolean): Generator<[Edge | TNullEdge, TTrigger, OpPathTree | null, PathTree<TTrigger, Vertex, TNullEdge>], void, undefined>;
childElements(reverseOrder?: boolean): Generator<[Edge | TNullEdge, TTrigger, OpPathTree | null, PathTree<TTrigger, Vertex, TNullEdge>, Set<string> | null, Map<string, ContextAtUsageEntry> | null], void, undefined>;
private element;

@@ -30,6 +28,4 @@ private mergeChilds;

private equalsSameRoot;
private static parameterToContextEquals;
concat(other: PathTree<TTrigger, RV, TNullEdge>): PathTree<TTrigger, RV, TNullEdge>;
mergePath(path: GraphPath<TTrigger, RV, TNullEdge>): PathTree<TTrigger, RV, TNullEdge>;
private childsFromPathElements;
private mergePathInternal;
private findIndex;

@@ -36,0 +32,0 @@ isAllInSameSubgraph(): boolean;

@@ -61,3 +61,3 @@ "use strict";

}
const [edge, trigger, conditions] = iterResult.value;
const [edge, trigger, conditions, contextToSelection, parameterToContext] = iterResult.value;
const idx = edge ? edge.index : maxEdges;

@@ -71,3 +71,3 @@ if (edge) {

if (triggerIdx < 0) {
forIndex.push([trigger, conditions, [ps]]);
forIndex.push([trigger, conditions, [ps], contextToSelection, parameterToContext]);
totalChilds++;

@@ -80,4 +80,6 @@ }

const newPaths = existing[2];
const mergedContextToSelection = (0, federation_internals_1.composeSets)(existing[3], contextToSelection);
const mergedParameterToContext = (0, federation_internals_1.mergeMapOrNull)(existing[4], parameterToContext);
newPaths.push(ps);
forIndex[triggerIdx] = [trigger, mergedConditions, newPaths];
forIndex[triggerIdx] = [trigger, mergedConditions, newPaths, mergedContextToSelection, mergedParameterToContext];
}

@@ -87,3 +89,3 @@ }

order[currentOrder++] = idx;
forEdgeIndex[idx] = [[trigger, conditions, [ps]]];
forEdgeIndex[idx] = [[trigger, conditions, [ps], contextToSelection, parameterToContext]];
totalChilds++;

@@ -99,3 +101,3 @@ }

const values = forEdgeIndex[edgeIndex];
for (const [trigger, conditions, subPathAndSelections] of values) {
for (const [trigger, conditions, subPathAndSelections, contextToSelection, parameterToContext] of values) {
childs[idx++] = {

@@ -105,3 +107,5 @@ index,

conditions,
tree: this.createFromPaths(graph, triggerEquality, newVertex, subPathAndSelections)
tree: this.createFromPaths(graph, triggerEquality, newVertex, subPathAndSelections),
contextToSelection,
parameterToContext,
};

@@ -113,69 +117,2 @@ }

}
static mergeAllOpTrees(graph, root, trees) {
return this.mergeAllTreesInternal(graph, opTriggerEquality, root, trees);
}
static mergeAllTreesInternal(graph, triggerEquality, currentVertex, trees) {
const maxEdges = graph.outEdgesCount(currentVertex);
const forEdgeIndex = new Array(maxEdges + 1);
const newVertices = new Array(maxEdges);
const order = new Array(maxEdges + 1);
let localSelections = undefined;
let currentOrder = 0;
let totalChilds = 0;
for (const tree of trees) {
if (tree.localSelections) {
if (localSelections) {
localSelections = localSelections.concat(tree.localSelections);
}
else {
localSelections = tree.localSelections;
}
}
for (const child of tree.childs) {
const idx = child.index === null ? maxEdges : child.index;
if (!newVertices[idx]) {
newVertices[idx] = child.tree.vertex;
}
const forIndex = forEdgeIndex[idx];
if (forIndex) {
const triggerIdx = findTriggerIdx(triggerEquality, forIndex, child.trigger);
if (triggerIdx < 0) {
forIndex.push([child.trigger, child.conditions, [child.tree]]);
totalChilds++;
}
else {
const existing = forIndex[triggerIdx];
const existingCond = existing[1];
const mergedConditions = existingCond ? (child.conditions ? existingCond.mergeIfNotEqual(child.conditions) : existingCond) : child.conditions;
const newTrees = existing[2];
newTrees.push(child.tree);
forIndex[triggerIdx] = [child.trigger, mergedConditions, newTrees];
}
}
else {
order[currentOrder++] = idx;
forEdgeIndex[idx] = [[child.trigger, child.conditions, [child.tree]]];
totalChilds++;
}
}
}
const childs = new Array(totalChilds);
let idx = 0;
for (let i = 0; i < currentOrder; i++) {
const edgeIndex = order[i];
const index = (edgeIndex === maxEdges ? null : edgeIndex);
const newVertex = index === null ? currentVertex : newVertices[edgeIndex];
const values = forEdgeIndex[edgeIndex];
for (const [trigger, conditions, subTrees] of values) {
childs[idx++] = {
index,
trigger,
conditions,
tree: this.mergeAllTreesInternal(graph, triggerEquality, newVertex, subTrees)
};
}
}
(0, federation_internals_1.assert)(idx === totalChilds, () => `Expected to have ${totalChilds} childs but only ${idx} added`);
return new PathTree(graph, currentVertex, localSelections, triggerEquality, childs);
}
childCount() {

@@ -205,3 +142,5 @@ return this.childs.length;

child.conditions,
child.tree
child.tree,
child.contextToSelection,
child.parameterToContext,
];

@@ -216,3 +155,5 @@ }

conditions: cond1 ? (cond2 ? cond1.mergeIfNotEqual(cond2) : cond1) : cond2,
tree: c1.tree.merge(c2.tree)
tree: c1.tree.merge(c2.tree),
contextToSelection: (0, federation_internals_1.composeSets)(c1.contextToSelection, c2.contextToSelection),
parameterToContext: (0, federation_internals_1.mergeMapOrNull)(c1.parameterToContext, c2.parameterToContext),
};

@@ -278,5 +219,31 @@ }

&& (c1.conditions ? (c2.conditions ? c1.conditions.equalsSameRoot(c2.conditions) : false) : !c2.conditions)
&& c1.tree.equalsSameRoot(c2.tree);
&& c1.tree.equalsSameRoot(c2.tree)
&& (0, federation_internals_1.setsEqual)(c1.contextToSelection, c2.contextToSelection)
&& PathTree.parameterToContextEquals(c1.parameterToContext, c2.parameterToContext);
});
}
static parameterToContextEquals(ptc1, ptc2) {
var _a, _b;
if (ptc1 === ptc2) {
return true;
}
const thisKeys = Array.from((_a = ptc1 === null || ptc1 === void 0 ? void 0 : ptc1.keys()) !== null && _a !== void 0 ? _a : []);
const thatKeys = Array.from((_b = ptc2 === null || ptc2 === void 0 ? void 0 : ptc2.keys()) !== null && _b !== void 0 ? _b : []);
if (thisKeys.length !== thatKeys.length) {
return false;
}
for (const key of thisKeys) {
const thisSelection = ptc1.get(key);
const thatSelection = ptc2.get(key);
(0, federation_internals_1.assert)(thisSelection, () => `Expected to have a selection for key ${key}`);
if (!thatSelection
|| (thisSelection.contextId !== thatSelection.contextId)
|| !(0, federation_internals_1.arrayEquals)(thisSelection.relativePath, thatSelection.relativePath)
|| !thisSelection.selectionSet.equals(thatSelection.selectionSet)
|| (thisSelection.subgraphArgType !== thatSelection.subgraphArgType)) {
return false;
}
}
return true;
}
concat(other) {

@@ -295,52 +262,2 @@ (0, federation_internals_1.assert)(other.graph === this.graph, 'Cannot concat path tree build on another graph');

}
mergePath(path) {
(0, federation_internals_1.assert)(path.graph === this.graph, 'Cannot merge path build on another graph');
(0, federation_internals_1.assert)(path.root.index === this.vertex.index, () => `Cannot merge path rooted at vertex ${path.root} into tree rooted at other vertex ${this.vertex}`);
return this.mergePathInternal(path[Symbol.iterator]());
}
childsFromPathElements(currentVertex, elements) {
const iterResult = elements.next();
if (iterResult.done) {
return [];
}
const [edge, trigger, conditions] = iterResult.value;
const edgeIndex = (edge ? edge.index : null);
currentVertex = edge ? edge.tail : currentVertex;
return [{
index: edgeIndex,
trigger: trigger,
conditions: conditions,
tree: new PathTree(this.graph, currentVertex, undefined, this.triggerEquality, this.childsFromPathElements(currentVertex, elements))
}];
}
mergePathInternal(elements) {
const iterResult = elements.next();
if (iterResult.done) {
return this;
}
const [edge, trigger, conditions] = iterResult.value;
(0, federation_internals_1.assert)(!edge || edge.head.index === this.vertex.index, () => `Next element head of ${edge} is not equal to current tree vertex ${this.vertex}`);
const edgeIndex = (edge ? edge.index : null);
const idx = this.findIndex(trigger, edgeIndex);
if (idx < 0) {
const currentVertex = edge ? edge.tail : this.vertex;
return new PathTree(this.graph, this.vertex, undefined, this.triggerEquality, this.childs.concat({
index: edgeIndex,
trigger: trigger,
conditions: conditions,
tree: new PathTree(this.graph, currentVertex, undefined, this.triggerEquality, this.childsFromPathElements(currentVertex, elements))
}));
}
else {
const newChilds = this.childs.concat();
const existing = newChilds[idx];
newChilds[idx] = {
index: existing.index,
trigger: existing.trigger,
conditions: conditions ? (existing.conditions ? existing.conditions.merge(conditions) : conditions) : existing.conditions,
tree: existing.tree.mergePathInternal(elements)
};
return new PathTree(this.graph, this.vertex, undefined, this.triggerEquality, newChilds);
}
}
findIndex(trigger, edgeIndex) {

@@ -347,0 +264,0 @@ for (let i = 0; i < this.childs.length; i++) {

@@ -1,2 +0,2 @@

import { MultiMap, NamedType, Schema, SchemaRootKind, SelectionSet, MapWithCachedArrays, Supergraph } from '@apollo/federation-internals';
import { MultiMap, NamedType, Schema, SchemaRootKind, Type, SelectionSet, MapWithCachedArrays, Supergraph } from '@apollo/federation-internals';
import { Transition } from './transition';

@@ -25,2 +25,11 @@ export declare const FEDERATED_GRAPH_ROOT_SOURCE = "_";

}
export type ContextCondition = {
context: string;
subgraphName: string;
namedParameter: string;
selection: string;
typesWithContextSet: Set<string>;
argType: Type;
coordinate: string;
};
export declare class Edge {

@@ -33,3 +42,4 @@ readonly index: number;

private _conditions?;
constructor(index: number, head: Vertex, tail: Vertex, transition: Transition, conditions?: SelectionSet, overrideCondition?: OverrideCondition | undefined);
requiredContexts: ContextCondition[];
constructor(index: number, head: Vertex, tail: Vertex, transition: Transition, conditions?: SelectionSet, overrideCondition?: OverrideCondition | undefined, requiredContexts?: ContextCondition[]);
get conditions(): SelectionSet | undefined;

@@ -42,2 +52,3 @@ isEdgeForField(name: string): boolean;

addToConditions(newConditions: SelectionSet): void;
addToContextConditions(contextConditions: ContextCondition[]): void;
isKeyOrRootTypeEdgeToSelf(): boolean;

@@ -54,4 +65,7 @@ satisfiesOverrideConditions(conditionsToCheck: Map<string, boolean>): boolean;

readonly sources: ReadonlyMap<string, Schema>;
readonly subgraphToArgs: Map<string, string[]>;
readonly subgraphToArgIndices: Map<string, Map<string, string>>;
readonly schema: Schema;
readonly nonTrivialFollowupEdges: (edge: Edge) => readonly Edge[];
constructor(name: string, vertices: Vertex[], _outEdges: Edge[][], typesToVertices: MultiMap<string, number>, rootVertices: MapWithCachedArrays<SchemaRootKind, RootVertex>, sources: ReadonlyMap<string, Schema>);
constructor(name: string, vertices: Vertex[], _outEdges: Edge[][], typesToVertices: MultiMap<string, number>, rootVertices: MapWithCachedArrays<SchemaRootKind, RootVertex>, sources: ReadonlyMap<string, Schema>, subgraphToArgs: Map<string, string[]>, subgraphToArgIndices: Map<string, Map<string, string>>, schema: Schema);
verticesCount(): number;

@@ -58,0 +72,0 @@ edgesCount(): number;

@@ -49,3 +49,3 @@ "use strict";

class Edge {
constructor(index, head, tail, transition, conditions, overrideCondition) {
constructor(index, head, tail, transition, conditions, overrideCondition, requiredContexts) {
this.index = index;

@@ -56,3 +56,7 @@ this.head = head;

this.overrideCondition = overrideCondition;
this.requiredContexts = [];
this._conditions = conditions;
if (requiredContexts) {
this.requiredContexts = [...requiredContexts];
}
}

@@ -94,3 +98,3 @@ get conditions() {

withNewHead(newHead) {
return new Edge(this.index, newHead, this.tail, this.transition, this._conditions, this.overrideCondition);
return new Edge(this.index, newHead, this.tail, this.transition, this._conditions, this.overrideCondition, this.requiredContexts);
}

@@ -102,2 +106,5 @@ addToConditions(newConditions) {

}
addToContextConditions(contextConditions) {
this.requiredContexts.push(...contextConditions);
}
isKeyOrRootTypeEdgeToSelf() {

@@ -118,3 +125,3 @@ return this.head === this.tail && (this.transition.kind === 'KeyResolution' || this.transition.kind === 'RootTypeResolution');

class QueryGraph {
constructor(name, vertices, _outEdges, typesToVertices, rootVertices, sources) {
constructor(name, vertices, _outEdges, typesToVertices, rootVertices, sources, subgraphToArgs, subgraphToArgIndices, schema) {
this.name = name;

@@ -126,2 +133,5 @@ this.vertices = vertices;

this.sources = sources;
this.subgraphToArgs = subgraphToArgs;
this.subgraphToArgIndices = subgraphToArgIndices;
this.schema = schema;
this.nonTrivialFollowupEdges = (0, nonTrivialEdgePrecomputing_1.preComputeNonTrivialFollowupEdges)(this);

@@ -255,4 +265,5 @@ }

function federateSubgraphs(supergraph, subgraphs) {
var _a;
const [verticesCount, rootKinds, schemas] = federatedProperties(subgraphs);
const builder = new GraphBuilder(verticesCount);
const builder = new GraphBuilder(supergraph, verticesCount);
rootKinds.forEach(k => builder.createRootVertex(k, new federation_internals_1.ObjectType(federatedGraphRootTypeName(k)), exports.FEDERATED_GRAPH_ROOT_SOURCE, FEDERATED_GRAPH_ROOT_SCHEMA));

@@ -369,2 +380,63 @@ const copyPointers = new Array(subgraphs.length);

}
const subgraphToArgs = new Map();
const subgraphToArgIndices = new Map();
for (const [i, subgraph] of subgraphs.entries()) {
const subgraphSchema = schemas[i];
const subgraphMetadata = (0, federation_internals_1.federationMetadata)(subgraphSchema);
(0, federation_internals_1.assert)(subgraphMetadata, `Subgraph ${i} is not a valid federation subgraph`);
const contextNameToTypes = new Map();
for (const application of subgraphMetadata.contextDirective().applications()) {
const { name: context } = application.arguments();
if (contextNameToTypes.has(context)) {
contextNameToTypes.get(context).add(application.parent.name);
}
else {
contextNameToTypes.set(context, new Set([application.parent.name]));
}
}
const coordinateMap = new Map();
for (const application of subgraphMetadata.fromContextDirective().applications()) {
const { field } = application.arguments();
const { context, selection } = (0, federation_internals_1.parseContext)(field);
(0, federation_internals_1.assert)(context, () => `FieldValue has invalid format. Context not found ${field}`);
(0, federation_internals_1.assert)(selection, () => `FieldValue has invalid format. Selection not found ${field}`);
const namedParameter = application.parent.name;
const argCoordinate = application.parent.coordinate;
const args = (_a = subgraphToArgs.get(subgraph.name)) !== null && _a !== void 0 ? _a : [];
args.push(argCoordinate);
subgraphToArgs.set(subgraph.name, args);
const fieldCoordinate = application.parent.parent.coordinate;
const typesWithContextSet = contextNameToTypes.get(context);
(0, federation_internals_1.assert)(typesWithContextSet, () => `Context ${context} is never set in subgraph`);
const z = coordinateMap.get(fieldCoordinate);
if (z) {
z.push({ namedParameter, coordinate: argCoordinate, context, selection, typesWithContextSet, subgraphName: subgraph.name, argType: application.parent.type });
}
else {
coordinateMap.set(fieldCoordinate, [{ namedParameter, coordinate: argCoordinate, context, selection, typesWithContextSet, subgraphName: subgraph.name, argType: application.parent.type }]);
}
}
for (const [subgraphName, args] of subgraphToArgs) {
args.sort();
const argToIndex = new Map();
for (let idx = 0; idx < args.length; idx++) {
argToIndex.set(args[idx], `contextualArgument_${i}_${idx}`);
}
subgraphToArgIndices.set(subgraphName, argToIndex);
}
builder.setContextMaps(subgraphToArgs, subgraphToArgIndices);
simpleTraversal(subgraph, _v => { return undefined; }, e => {
if (e.head.type.kind === 'ObjectType' && e.transition.kind === 'FieldCollection') {
const coordinate = `${e.head.type.name}.${e.transition.definition.name}`;
const requiredContexts = coordinateMap.get(coordinate);
if (requiredContexts) {
const headInSupergraph = copyPointers[i].copiedVertex(e.head);
(0, federation_internals_1.assert)(headInSupergraph, () => `Vertex for type ${e.head.type.name} not found in supergraph`);
const edgeInSupergraph = builder.edge(headInSupergraph, e.index);
edgeInSupergraph.addToContextConditions(requiredContexts);
}
}
return true;
});
}
let provideId = 0;

@@ -464,3 +536,3 @@ for (const [i, subgraph] of subgraphs.entries()) {

class GraphBuilder {
constructor(verticesCount) {
constructor(schema, verticesCount) {
this.nextIndex = 0;

@@ -470,5 +542,8 @@ this.typesToVertices = new federation_internals_1.MultiMap();

this.sources = new Map();
this.subgraphToArgs = new Map();
this.subgraphToArgIndices = new Map();
this.vertices = verticesCount ? new Array(verticesCount) : [];
this.outEdges = verticesCount ? new Array(verticesCount) : [];
this.inEdges = verticesCount ? new Array(verticesCount) : [];
this.schema = schema;
}

@@ -482,6 +557,6 @@ verticesForType(typeName) {

}
addEdge(head, tail, transition, conditions, overrideCondition) {
addEdge(head, tail, transition, conditions, overrideCondition, requiredContexts) {
const headOutEdges = this.outEdges[head.index];
const tailInEdges = this.inEdges[tail.index];
const edge = new Edge(headOutEdges.length, head, tail, transition, conditions, overrideCondition);
const edge = new Edge(headOutEdges.length, head, tail, transition, conditions, overrideCondition, requiredContexts);
headOutEdges.push(edge);

@@ -546,3 +621,3 @@ tailInEdges.push(edge);

const newTail = this.getOrCopyVertex(edge.tail, offset, graph);
this.addEdge(newHead, newTail, edge.transition, edge.conditions);
this.addEdge(newHead, newTail, edge.transition, edge.conditions, edge.overrideCondition, edge.requiredContexts);
}

@@ -574,3 +649,3 @@ }

for (const edge of this.outEdges[vertex.index]) {
this.addEdge(newVertex, edge.tail, edge.transition, edge.conditions);
this.addEdge(newVertex, edge.tail, edge.transition, edge.conditions, edge.overrideCondition, edge.requiredContexts);
}

@@ -580,3 +655,3 @@ return newVertex;

updateEdgeTail(edge, newTail) {
const newEdge = new Edge(edge.index, edge.head, newTail, edge.transition, edge.conditions, edge.overrideCondition);
const newEdge = new Edge(edge.index, edge.head, newTail, edge.transition, edge.conditions, edge.overrideCondition, edge.requiredContexts);
this.outEdges[edge.head.index][edge.index] = newEdge;

@@ -596,10 +671,13 @@ this.inEdges[edge.tail.index] = this.inEdges[edge.tail.index].filter((e) => e !== edge);

build(name) {
return new QueryGraph(name, this.vertices, this.outEdges, this.typesToVertices, this.rootVertices, this.sources);
return new QueryGraph(name, this.vertices, this.outEdges, this.typesToVertices, this.rootVertices, this.sources, this.subgraphToArgs, this.subgraphToArgIndices, this.schema);
}
setContextMaps(subgraphToArgs, subgraphToArgIndices) {
this.subgraphToArgs = subgraphToArgs;
this.subgraphToArgIndices = subgraphToArgIndices;
}
}
class GraphBuilderFromSchema extends GraphBuilder {
constructor(name, schema, supergraph, overrideLabelsByCoordinate) {
super();
super(schema);
this.name = name;
this.schema = schema;
this.supergraph = supergraph;

@@ -606,0 +684,0 @@ this.overrideLabelsByCoordinate = overrideLabelsByCoordinate;

{
"name": "@apollo/query-graphs",
"version": "2.8.0-connectors.5",
"version": "2.8.0",
"description": "Apollo Federation library to work with 'query graphs'",

@@ -26,3 +26,3 @@ "main": "dist/index.js",

"dependencies": {
"@apollo/federation-internals": "2.8.0-connectors.5",
"@apollo/federation-internals": "2.8.0",
"deep-equal": "^2.0.5",

@@ -29,0 +29,0 @@ "ts-graphviz": "^1.5.4",

@@ -1,2 +0,2 @@

import { assert } from "@apollo/federation-internals";
import { SelectionSet, assert } from "@apollo/federation-internals";
import { ConditionResolution, ConditionResolver, ExcludedConditions, ExcludedDestinations, sameExcludedDestinations } from "./graphPath";

@@ -17,4 +17,4 @@ import { PathContext } from "./pathContext";

const cache = new QueryGraphState<undefined, [ConditionResolution, ExcludedDestinations]>(graph);
return (edge: Edge, context: PathContext, excludedDestinations: ExcludedDestinations, excludedConditions: ExcludedConditions) => {
assert(edge.conditions, 'Should not have been called for edge without conditions');
return (edge: Edge, context: PathContext, excludedDestinations: ExcludedDestinations, excludedConditions: ExcludedConditions, extraConditions?: SelectionSet) => {
assert(edge.conditions || extraConditions, 'Should not have been called for edge without conditions');

@@ -29,4 +29,4 @@ // We don't cache if there is a context or excluded conditions because those would impact the resolution and

// that commonly, so this is probably not an urgent improvement.
if (!context.isEmpty() || excludedConditions.length > 0) {
return resolver(edge, context, excludedDestinations, excludedConditions);
if (!context.isEmpty() || excludedConditions.length > 0 || extraConditions) {
return resolver(edge, context, excludedDestinations, excludedConditions, extraConditions);
}

@@ -39,5 +39,5 @@

? cachedResolution
: resolver(edge, context, excludedDestinations, excludedConditions);
: resolver(edge, context, excludedDestinations, excludedConditions, extraConditions);
} else {
const resolution = resolver(edge, context, excludedDestinations, excludedConditions);
const resolution = resolver(edge, context, excludedDestinations, excludedConditions, extraConditions);
cache.setEdgeState(edge, [resolution, excludedDestinations]);

@@ -44,0 +44,0 @@ return resolution;

@@ -1,2 +0,2 @@

import { Schema, Selection } from "@apollo/federation-internals";
import { Schema, Selection, SelectionSet } from "@apollo/federation-internals";
import {

@@ -85,4 +85,5 @@ ConditionResolution,

excludedConditions: ExcludedConditions,
extraConditions?: SelectionSet,
): ConditionResolution => {
const conditions = edge.conditions!;
const conditions = (extraConditions ?? edge.conditions)!; // TODO: ensure that only one is set
excludedConditions = addConditionExclusion(excludedConditions, conditions);

@@ -89,0 +90,0 @@

@@ -1,3 +0,3 @@

import { arrayEquals, assert, copyWitNewLength, SelectionSet } from "@apollo/federation-internals";
import { GraphPath, OpGraphPath, OpTrigger, PathIterator } from "./graphPath";
import { arrayEquals, assert, composeSets, copyWitNewLength, mergeMapOrNull, SelectionSet, setsEqual } from "@apollo/federation-internals";
import { OpGraphPath, OpTrigger, PathIterator, ContextAtUsageEntry } from "./graphPath";
import { Edge, QueryGraph, RootVertex, isRootVertex, Vertex } from "./querygraph";

@@ -23,3 +23,5 @@ import { isPathContext } from "./pathContext";

conditions: OpPathTree | null,
tree: PathTree<TTrigger, RV, TNullEdge>
tree: PathTree<TTrigger, RV, TNullEdge>,
contextToSelection: Set<string> | null,
parameterToContext: Map<string, ContextAtUsageEntry> | null,
}

@@ -29,3 +31,3 @@

triggerEquality: (t1: TTrigger, t2: TTrigger) => boolean,
forIndex: [TTrigger, OpPathTree | null, TElements][],
forIndex: [TTrigger, OpPathTree | null, TElements, Set<string> | null, Map<string, ContextAtUsageEntry> | null][],
trigger: TTrigger

@@ -91,3 +93,3 @@ ): number {

// We store 'null' edges at `maxEdges` index
const forEdgeIndex: [TTrigger, OpPathTree | null, IterAndSelection<TTrigger, TNullEdge>[]][][] = new Array(maxEdges + 1);
const forEdgeIndex: [TTrigger, OpPathTree | null, IterAndSelection<TTrigger, TNullEdge>[], Set<string> | null, Map<string, ContextAtUsageEntry> | null][][] = new Array(maxEdges + 1);
const newVertices: Vertex[] = new Array(maxEdges);

@@ -106,3 +108,3 @@ const order: number[] = new Array(maxEdges + 1);

}
const [edge, trigger, conditions] = iterResult.value;
const [edge, trigger, conditions, contextToSelection, parameterToContext] = iterResult.value;
const idx = edge ? edge.index : maxEdges;

@@ -116,3 +118,3 @@ if (edge) {

if (triggerIdx < 0) {
forIndex.push([trigger, conditions, [ps]]);
forIndex.push([trigger, conditions, [ps], contextToSelection, parameterToContext]);
totalChilds++;

@@ -124,4 +126,6 @@ } else {

const newPaths = existing[2];
const mergedContextToSelection = composeSets(existing[3], contextToSelection);
const mergedParameterToContext = mergeMapOrNull(existing[4], parameterToContext);
newPaths.push(ps);
forIndex[triggerIdx] = [trigger, mergedConditions, newPaths];
forIndex[triggerIdx] = [trigger, mergedConditions, newPaths, mergedContextToSelection, mergedParameterToContext];
// Note that as we merge, we don't create a new child

@@ -132,3 +136,3 @@ }

order[currentOrder++] = idx;
forEdgeIndex[idx] = [[trigger, conditions, [ps]]];
forEdgeIndex[idx] = [[trigger, conditions, [ps], contextToSelection, parameterToContext]];
totalChilds++;

@@ -145,3 +149,3 @@ }

const values = forEdgeIndex[edgeIndex];
for (const [trigger, conditions, subPathAndSelections] of values) {
for (const [trigger, conditions, subPathAndSelections, contextToSelection, parameterToContext] of values) {
childs[idx++] = {

@@ -151,3 +155,5 @@ index,

conditions,
tree: this.createFromPaths(graph, triggerEquality, newVertex, subPathAndSelections)
tree: this.createFromPaths(graph, triggerEquality, newVertex, subPathAndSelections),
contextToSelection,
parameterToContext,
};

@@ -160,79 +166,2 @@ }

// Assumes all root are rooted on the same vertex
static mergeAllOpTrees<RV extends Vertex = Vertex>(graph: QueryGraph, root: RV, trees: OpPathTree<RV>[]): OpPathTree<RV> {
return this.mergeAllTreesInternal(graph, opTriggerEquality, root, trees);
}
private static mergeAllTreesInternal<TTrigger, RV extends Vertex, TNullEdge extends null | never>(
graph: QueryGraph,
triggerEquality: (t1: TTrigger, t2: TTrigger) => boolean,
currentVertex: RV,
trees: PathTree<TTrigger, RV, TNullEdge>[]
): PathTree<TTrigger, RV, TNullEdge> {
const maxEdges = graph.outEdgesCount(currentVertex);
// We store 'null' edges at `maxEdges` index
const forEdgeIndex: [TTrigger, OpPathTree | null, PathTree<TTrigger, Vertex, TNullEdge>[]][][] = new Array(maxEdges + 1);
const newVertices: Vertex[] = new Array(maxEdges);
const order: number[] = new Array(maxEdges + 1);
let localSelections: readonly SelectionSet[] | undefined = undefined;
let currentOrder = 0;
let totalChilds = 0;
for (const tree of trees) {
if (tree.localSelections) {
if (localSelections) {
localSelections = localSelections.concat(tree.localSelections);
} else {
localSelections = tree.localSelections;
}
}
for (const child of tree.childs) {
const idx = child.index === null ? maxEdges : child.index;
if (!newVertices[idx]) {
newVertices[idx] = child.tree.vertex;
}
const forIndex = forEdgeIndex[idx];
if (forIndex) {
const triggerIdx = findTriggerIdx(triggerEquality, forIndex, child.trigger);
if (triggerIdx < 0) {
forIndex.push([child.trigger, child.conditions, [child.tree]]);
totalChilds++;
} else {
const existing = forIndex[triggerIdx];
const existingCond = existing[1];
const mergedConditions = existingCond ? (child.conditions ? existingCond.mergeIfNotEqual(child.conditions) : existingCond) : child.conditions;
const newTrees = existing[2];
newTrees.push(child.tree);
forIndex[triggerIdx] = [child.trigger, mergedConditions, newTrees];
// Note that as we merge, we don't create a new child
}
} else {
// First time we see someone from that index; record the order
order[currentOrder++] = idx;
forEdgeIndex[idx] = [[child.trigger, child.conditions, [child.tree]]];
totalChilds++;
}
}
}
const childs: Child<TTrigger, Vertex, TNullEdge>[] = new Array(totalChilds);
let idx = 0;
for (let i = 0; i < currentOrder; i++) {
const edgeIndex = order[i];
const index = (edgeIndex === maxEdges ? null : edgeIndex) as number | TNullEdge;
const newVertex = index === null ? currentVertex : newVertices[edgeIndex];
const values = forEdgeIndex[edgeIndex];
for (const [trigger, conditions, subTrees] of values) {
childs[idx++] = {
index,
trigger,
conditions,
tree: this.mergeAllTreesInternal(graph, triggerEquality, newVertex, subTrees)
};
}
}
assert(idx === totalChilds, () => `Expected to have ${totalChilds} childs but only ${idx} added`);
return new PathTree<TTrigger, RV, TNullEdge>(graph, currentVertex, localSelections, triggerEquality, childs);
}
childCount(): number {

@@ -246,3 +175,3 @@ return this.childs.length;

*childElements(reverseOrder: boolean = false): Generator<[Edge | TNullEdge, TTrigger, OpPathTree | null, PathTree<TTrigger, Vertex, TNullEdge>], void, undefined> {
*childElements(reverseOrder: boolean = false): Generator<[Edge | TNullEdge, TTrigger, OpPathTree | null, PathTree<TTrigger, Vertex, TNullEdge>, Set<string> | null, Map<string, ContextAtUsageEntry> | null], void, undefined> {
if (reverseOrder) {

@@ -259,3 +188,3 @@ for (let i = this.childs.length - 1; i >= 0; i--) {

private element(i: number): [Edge | TNullEdge, TTrigger, OpPathTree | null, PathTree<TTrigger, Vertex, TNullEdge>] {
private element(i: number): [Edge | TNullEdge, TTrigger, OpPathTree | null, PathTree<TTrigger, Vertex, TNullEdge>, Set<string> | null, Map<string, ContextAtUsageEntry> | null] {
const child = this.childs[i];

@@ -266,3 +195,5 @@ return [

child.conditions,
child.tree
child.tree,
child.contextToSelection,
child.parameterToContext,
];

@@ -278,3 +209,5 @@ }

conditions: cond1 ? (cond2 ? cond1.mergeIfNotEqual(cond2) : cond1) : cond2,
tree: c1.tree.merge(c2.tree)
tree: c1.tree.merge(c2.tree),
contextToSelection: composeSets(c1.contextToSelection, c2.contextToSelection),
parameterToContext: mergeMapOrNull(c1.parameterToContext, c2.parameterToContext),
};

@@ -328,2 +261,3 @@ }

let addIdx = thisSize;
for (let i = 0; i < other.childs.length; i++) {

@@ -353,6 +287,35 @@ const idx = mergeIndexes[i];

&& (c1.conditions ? (c2.conditions ? c1.conditions.equalsSameRoot(c2.conditions) : false) : !c2.conditions)
&& c1.tree.equalsSameRoot(c2.tree);
});
&& c1.tree.equalsSameRoot(c2.tree)
&& setsEqual(c1.contextToSelection, c2.contextToSelection)
&& PathTree.parameterToContextEquals(c1.parameterToContext, c2.parameterToContext)
});
}
private static parameterToContextEquals(ptc1: Map<string, ContextAtUsageEntry> | null, ptc2: Map<string, ContextAtUsageEntry> | null): boolean {
if (ptc1 === ptc2) {
return true;
}
const thisKeys = Array.from(ptc1?.keys() ?? []);
const thatKeys = Array.from(ptc2?.keys() ?? []);
if (thisKeys.length !== thatKeys.length) {
return false;
}
for (const key of thisKeys) {
const thisSelection = ptc1!.get(key);
const thatSelection = ptc2!.get(key);
assert(thisSelection, () => `Expected to have a selection for key ${key}`);
if (!thatSelection
|| (thisSelection.contextId !== thatSelection.contextId)
|| !arrayEquals(thisSelection.relativePath, thatSelection.relativePath)
|| !thisSelection.selectionSet.equals(thatSelection.selectionSet)
|| (thisSelection.subgraphArgType !== thatSelection.subgraphArgType)) {
return false;
}
}
return true;
}
// Like merge(), this create a new tree that contains the content of both `this` and `other` to this pathTree, but contrarily

@@ -375,61 +338,2 @@ // to merge() this never merge childs together, even if they are equal. This is only for the special case of mutations.

mergePath(path: GraphPath<TTrigger, RV, TNullEdge>): PathTree<TTrigger, RV, TNullEdge> {
assert(path.graph === this.graph, 'Cannot merge path build on another graph');
assert(path.root.index === this.vertex.index, () => `Cannot merge path rooted at vertex ${path.root} into tree rooted at other vertex ${this.vertex}`);
return this.mergePathInternal(path[Symbol.iterator]());
}
private childsFromPathElements(currentVertex: Vertex, elements: PathIterator<TTrigger, TNullEdge>): Child<TTrigger, Vertex, TNullEdge>[] {
const iterResult = elements.next();
if (iterResult.done) {
return [];
}
const [edge, trigger, conditions] = iterResult.value;
const edgeIndex = (edge ? edge.index : null) as number | TNullEdge;
currentVertex = edge ? edge.tail : currentVertex;
return [{
index: edgeIndex,
trigger: trigger,
conditions: conditions,
tree: new PathTree<TTrigger, Vertex, TNullEdge>(this.graph, currentVertex, undefined, this.triggerEquality, this.childsFromPathElements(currentVertex, elements))
}];
}
private mergePathInternal(elements: PathIterator<TTrigger, TNullEdge>): PathTree<TTrigger, RV, TNullEdge> {
const iterResult = elements.next();
if (iterResult.done) {
return this;
}
const [edge, trigger, conditions] = iterResult.value;
assert(!edge || edge.head.index === this.vertex.index, () => `Next element head of ${edge} is not equal to current tree vertex ${this.vertex}`);
const edgeIndex = (edge ? edge.index : null) as number | TNullEdge;
const idx = this.findIndex(trigger, edgeIndex);
if (idx < 0) {
const currentVertex = edge ? edge.tail : this.vertex;
return new PathTree<TTrigger, RV, TNullEdge>(
this.graph,
this.vertex,
undefined,
this.triggerEquality,
this.childs.concat({
index: edgeIndex,
trigger: trigger,
conditions: conditions,
tree: new PathTree<TTrigger, Vertex, TNullEdge>(this.graph, currentVertex, undefined, this.triggerEquality, this.childsFromPathElements(currentVertex, elements))
})
);
} else {
const newChilds = this.childs.concat();
const existing = newChilds[idx];
newChilds[idx] = {
index: existing.index,
trigger: existing.trigger,
conditions: conditions ? (existing.conditions ? existing.conditions.merge(conditions) : conditions) : existing.conditions,
tree: existing.tree.mergePathInternal(elements)
};
return new PathTree<TTrigger, RV, TNullEdge>(this.graph, this.vertex, undefined, this.triggerEquality, newChilds);
}
}
private findIndex(trigger: TTrigger, edgeIndex: number | TNullEdge): number {

@@ -436,0 +340,0 @@ for (let i = 0; i < this.childs.length; i++) {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc