Socket
Socket
Sign inDemoInstall

apollo-utilities

Package Overview
Dependencies
Maintainers
1
Versions
105
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apollo-utilities - npm Package Compare versions

Comparing version 0.2.0-alpha.4 to 0.2.0-alpha.5

1

CHANGELOG.md
# Change log
### vNEXT
- Added hasDirectives to recurse the AST and return a boolean for an array of directive names
- Improved performance of common store actions by memoizing addTypename and removeConnectionDirective

5

lib/directives.d.ts

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

import { FieldNode, SelectionNode } from 'graphql';
import { FieldNode, SelectionNode, DocumentNode } from 'graphql';
export declare type DirectiveInfo = {

@@ -11,1 +11,4 @@ [fieldName: string]: {

}): boolean;
export declare function flattenSelections(selection: SelectionNode): SelectionNode[];
export declare function getDirectiveNames(doc: DocumentNode): any;
export declare function hasDirectives(names: string[], doc: DocumentNode): any;

@@ -60,2 +60,38 @@ "use strict";

exports.shouldInclude = shouldInclude;
function flattenSelections(selection) {
if (!selection.selectionSet ||
!(selection.selectionSet.selections.length > 0))
return [selection];
return [selection].concat(selection.selectionSet.selections
.map(function (selectionNode) {
return [selectionNode].concat(flattenSelections(selectionNode));
})
.reduce(function (selections, selected) { return selections.concat(selected); }, []));
}
exports.flattenSelections = flattenSelections;
var added = new Map();
function getDirectiveNames(doc) {
var cached = added.get(doc);
if (cached)
return cached;
var directives = doc.definitions
.filter(function (definition) {
return definition.selectionSet && definition.selectionSet.selections;
})
.map(function (x) { return flattenSelections(x); })
.reduce(function (selections, selected) { return selections.concat(selected); }, [])
.filter(function (selection) {
return selection.directives && selection.directives.length > 0;
})
.map(function (selection) { return selection.directives; })
.reduce(function (directives, directive) { return directives.concat(directive); }, [])
.map(function (directive) { return directive.name.value; });
added.set(doc, directives);
return directives;
}
exports.getDirectiveNames = getDirectiveNames;
function hasDirectives(names, doc) {
return getDirectiveNames(doc).some(function (name) { return names.indexOf(name) > -1; });
}
exports.hasDirectives = hasDirectives;
//# sourceMappingURL=directives.js.map
{
"name": "apollo-utilities",
"version": "0.2.0-alpha.4",
"version": "0.2.0-alpha.5",
"description": "Utilities for working with GraphQL ASTs",

@@ -5,0 +5,0 @@ "author": "James Baxley <james@meteor.com>",

import gql from 'graphql-tag';
import { cloneDeep } from 'lodash';
import { shouldInclude } from '../directives';
import { shouldInclude, hasDirectives } from '../directives';
import { getQueryDefinition } from '../getFromAST';
describe('query directives', () => {
describe('hasDirective', () => {
it('should allow searching the ast for a directive', () => {
const query = gql`
query Simple {
field @live
}
`;
expect(hasDirectives(['live'], query)).toBe(true);
expect(hasDirectives(['defer'], query)).toBe(false);
});
it('works for all operation types', () => {
const query = gql`
{
field @live {
subField {
hello @live
}
}
}
`;
const mutation = gql`
mutation Directive {
mutate {
field {
subField {
hello @live
}
}
}
}
`;
const subscription = gql`
subscription LiveDirective {
sub {
field {
subField {
hello @live
}
}
}
}
`;
[query, mutation, subscription].forEach(x => {
expect(hasDirectives(['live'], x)).toBe(true);
expect(hasDirectives(['defer'], x)).toBe(false);
});
});
it('works for simple fragments', () => {
const query = gql`
query Simple {
...fieldFragment
}
fragment fieldFragment on Field {
foo @live
}
`;
expect(hasDirectives(['live'], query)).toBe(true);
expect(hasDirectives(['defer'], query)).toBe(false);
});
it('works for nested fragments', () => {
const query = gql`
query Simple {
...fieldFragment1
}
fragment fieldFragment1 on Field {
bar {
baz {
...nestedFragment
}
}
}
fragment nestedFragment on Field {
foo @live
}
`;
expect(hasDirectives(['live'], query)).toBe(true);
expect(hasDirectives(['defer'], query)).toBe(false);
});
});
describe('shouldInclude', () => {
it('should should not include a skipped field', () => {

@@ -9,0 +95,0 @@ const query = gql`

@@ -5,2 +5,3 @@ // Provides the methods that allow QueryManager to handle

FieldNode,
OperationDefinitionNode,
SelectionNode,

@@ -10,2 +11,3 @@ VariableNode,

DirectiveNode,
DocumentNode,
} from 'graphql';

@@ -97,1 +99,54 @@

}
export function flattenSelections(selection: SelectionNode): SelectionNode[] {
if (
!(selection as FieldNode).selectionSet ||
!((selection as FieldNode).selectionSet.selections.length > 0)
)
return [selection];
return [selection].concat(
(selection as FieldNode).selectionSet.selections
.map(selectionNode =>
[selectionNode].concat(flattenSelections(selectionNode)),
)
.reduce((selections, selected) => selections.concat(selected), []),
);
}
const added = new Map();
export function getDirectiveNames(doc: DocumentNode) {
const cached = added.get(doc);
if (cached) return cached;
// operation => [names of directives];
const directives = doc.definitions
.filter(
(definition: OperationDefinitionNode) =>
definition.selectionSet && definition.selectionSet.selections,
)
// operation => [[Selection]]
.map(x => flattenSelections(x as any))
// [[Selection]] => [Selection]
.reduce((selections, selected) => selections.concat(selected), [])
// [Selection] => [Selection with Directives]
.filter(
(selection: SelectionNode) =>
selection.directives && selection.directives.length > 0,
)
// [Selection with Directives] => [[Directives]]
.map((selection: SelectionNode) => selection.directives)
// [[Directives]] => [Directives]
.reduce((directives, directive) => directives.concat(directive), [])
// [Directives] => [Name]
.map((directive: DirectiveNode) => directive.name.value);
added.set(doc, directives);
return directives;
}
export function hasDirectives(names: string[], doc: DocumentNode) {
return getDirectiveNames(doc).some(
(name: string) => names.indexOf(name) > -1,
);
}

Sorry, the diff of this file is not supported yet

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