This commit is contained in:
127
node_modules/apollo-utilities/src/directives.ts
generated
vendored
Normal file
127
node_modules/apollo-utilities/src/directives.ts
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
// Provides the methods that allow QueryManager to handle the `skip` and
|
||||
// `include` directives within GraphQL.
|
||||
import {
|
||||
FieldNode,
|
||||
SelectionNode,
|
||||
VariableNode,
|
||||
BooleanValueNode,
|
||||
DirectiveNode,
|
||||
DocumentNode,
|
||||
ArgumentNode,
|
||||
ValueNode,
|
||||
} from 'graphql';
|
||||
|
||||
import { visit } from 'graphql/language/visitor';
|
||||
|
||||
import { invariant } from 'ts-invariant';
|
||||
|
||||
import { argumentsObjectFromField } from './storeUtils';
|
||||
|
||||
export type DirectiveInfo = {
|
||||
[fieldName: string]: { [argName: string]: any };
|
||||
};
|
||||
|
||||
export function getDirectiveInfoFromField(
|
||||
field: FieldNode,
|
||||
variables: Object,
|
||||
): DirectiveInfo {
|
||||
if (field.directives && field.directives.length) {
|
||||
const directiveObj: DirectiveInfo = {};
|
||||
field.directives.forEach((directive: DirectiveNode) => {
|
||||
directiveObj[directive.name.value] = argumentsObjectFromField(
|
||||
directive,
|
||||
variables,
|
||||
);
|
||||
});
|
||||
return directiveObj;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function shouldInclude(
|
||||
selection: SelectionNode,
|
||||
variables: { [name: string]: any } = {},
|
||||
): boolean {
|
||||
return getInclusionDirectives(
|
||||
selection.directives,
|
||||
).every(({ directive, ifArgument }) => {
|
||||
let evaledValue: boolean = false;
|
||||
if (ifArgument.value.kind === 'Variable') {
|
||||
evaledValue = variables[(ifArgument.value as VariableNode).name.value];
|
||||
invariant(
|
||||
evaledValue !== void 0,
|
||||
`Invalid variable referenced in @${directive.name.value} directive.`,
|
||||
);
|
||||
} else {
|
||||
evaledValue = (ifArgument.value as BooleanValueNode).value;
|
||||
}
|
||||
return directive.name.value === 'skip' ? !evaledValue : evaledValue;
|
||||
});
|
||||
}
|
||||
|
||||
export function getDirectiveNames(doc: DocumentNode) {
|
||||
const names: string[] = [];
|
||||
|
||||
visit(doc, {
|
||||
Directive(node) {
|
||||
names.push(node.name.value);
|
||||
},
|
||||
});
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
export function hasDirectives(names: string[], doc: DocumentNode) {
|
||||
return getDirectiveNames(doc).some(
|
||||
(name: string) => names.indexOf(name) > -1,
|
||||
);
|
||||
}
|
||||
|
||||
export function hasClientExports(document: DocumentNode) {
|
||||
return (
|
||||
document &&
|
||||
hasDirectives(['client'], document) &&
|
||||
hasDirectives(['export'], document)
|
||||
);
|
||||
}
|
||||
|
||||
export type InclusionDirectives = Array<{
|
||||
directive: DirectiveNode;
|
||||
ifArgument: ArgumentNode;
|
||||
}>;
|
||||
|
||||
function isInclusionDirective({ name: { value } }: DirectiveNode): boolean {
|
||||
return value === 'skip' || value === 'include';
|
||||
}
|
||||
|
||||
export function getInclusionDirectives(
|
||||
directives: ReadonlyArray<DirectiveNode>,
|
||||
): InclusionDirectives {
|
||||
return directives ? directives.filter(isInclusionDirective).map(directive => {
|
||||
const directiveArguments = directive.arguments;
|
||||
const directiveName = directive.name.value;
|
||||
|
||||
invariant(
|
||||
directiveArguments && directiveArguments.length === 1,
|
||||
`Incorrect number of arguments for the @${directiveName} directive.`,
|
||||
);
|
||||
|
||||
const ifArgument = directiveArguments[0];
|
||||
invariant(
|
||||
ifArgument.name && ifArgument.name.value === 'if',
|
||||
`Invalid argument for the @${directiveName} directive.`,
|
||||
);
|
||||
|
||||
const ifValue: ValueNode = ifArgument.value;
|
||||
|
||||
// means it has to be a variable value if this is a valid @skip or @include directive
|
||||
invariant(
|
||||
ifValue &&
|
||||
(ifValue.kind === 'Variable' || ifValue.kind === 'BooleanValue'),
|
||||
`Argument for the @${directiveName} directive must be a variable or a boolean value.`,
|
||||
);
|
||||
|
||||
return { directive, ifArgument };
|
||||
}) : [];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user