From 0abd3a6e23ad0e5ed98a155f2452c2853eaf2580 Mon Sep 17 00:00:00 2001 From: toddtarsi Date: Thu, 3 May 2018 22:29:18 -0500 Subject: [PATCH 1/4] Allow for custom queryTransformers First off, let me start by saying nice plugin! Next, I would like to request this feature. This would allow me to chain my custom persistgraphql queryTransformers via your tool, and still use the very simple assignment method of `generateId: query => persistedQueries[query]`. I am a fan of Apollo 2.0, but I don't feel ready to go all in on engine yet, so I don't use apollo-link-persisted-queries in the ad hoc method prescribed in the demos. As a result of using link directives, my queries have to be adjusted for the server. For example, I chain the addTypename queryTransformer with another transform to strip client fields. Rather than process the query in generateId and try to connect the dots, I'd rather transform the persistedQueries here as well and keep the same generateId call as before. Please let me know your thoughts, and thanks! --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 52ab3d4..012aac8 100644 --- a/index.js +++ b/index.js @@ -75,7 +75,7 @@ module.exports = function graphQLPersistedDocumentLoader(content) { function tryAddDocumentId(options, content, querySource) { const queryMap = new ExtractGQL({ - queryTransformers: [options.addTypename && queryTransformers.addTypenameTransformer].filter(Boolean) + queryTransformers: options.queryTransformers || [options.addTypename && queryTransformers.addTypenameTransformer].filter(Boolean) }).createOutputMapFromString(querySource); const queries = Object.keys(queryMap); From 2f315a6bd01d43270d02a03c43c0d4626ab9b11b Mon Sep 17 00:00:00 2001 From: toddtarsi Date: Wed, 6 Feb 2019 13:48:09 -0600 Subject: [PATCH 2/4] Documentation for custom queryTransformers --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index 4068e59..bb45eb1 100644 --- a/README.md +++ b/README.md @@ -56,5 +56,37 @@ console.log(query.documentId); // => 5eef6cd6a52ee0d67bfbb0fdc72bbbde4d70331834e * `generateId`: `function (querySource: string) => string` Function that allows to generate a custom documentId from the query source. This source contains all the dependencies sources concatenated, so it's suitable for hashing. By default it generates the sha256 hash in hexadecimal format. The source is concatenated in the same way as you'd get it from the `persistgraphql` tool, so hashing the queries from the output of that tool should get you the same hash value. * `addTypename`: `boolean` Apply a query transformation to the query documents, adding the __typename field at every level of the query. You must pass this option if your client code uses this query transformation. +* `queryTransformers`: `[function(documentNode) => documentNode]` Directly override the query transformations list to provide additional transforms as needed. Further reading on the DocumentNode object can be accomplished here: https://github.com/graphql/graphql-js/blob/master/src/language/ast.js This is what a query transformer to strip the client fields looks like: +```js + +function removeClientFieldsTransformer(doc: DocumentNode) => { + function removeClientFieldsFromSelectionSet(selectionSet) { + if (selectionSet.selections) { + // eslint-disable-next-line no-param-reassign + selectionSet.selections = selectionSet.selections.map((selection) => { + if (selection.directives && selection.directives.length) { + const hasClient = selection.directives.find(d => d.name.value === 'client'); + if (hasClient) return false; + } + if (selection.kind === 'Field' || selection.kind === 'InlineFragment') { + if (selection.selectionSet) { + removeClientFieldsFromSelectionSet(selection.selectionSet); + } + } + return selection; + }).filter(s => !!s); + } + return selectionSet; + } + + const docClone = JSON.parse(JSON.stringify(doc)); + docClone.definitions.forEach((definition: DefinitionNode) => { + const isRoot = definition.kind === 'OperationDefinition'; + removeClientFieldsFromSelectionSet(definition.selectionSet, isRoot); + }); + + return docClone; +}; +``` From 0eb2f4a9532747ad9286bea39fdaa9fdb63837df Mon Sep 17 00:00:00 2001 From: toddtarsi Date: Wed, 6 Feb 2019 13:49:44 -0600 Subject: [PATCH 3/4] Documentation, further reading to bottom --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bb45eb1..245f3fb 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ console.log(query.documentId); // => 5eef6cd6a52ee0d67bfbb0fdc72bbbde4d70331834e * `generateId`: `function (querySource: string) => string` Function that allows to generate a custom documentId from the query source. This source contains all the dependencies sources concatenated, so it's suitable for hashing. By default it generates the sha256 hash in hexadecimal format. The source is concatenated in the same way as you'd get it from the `persistgraphql` tool, so hashing the queries from the output of that tool should get you the same hash value. * `addTypename`: `boolean` Apply a query transformation to the query documents, adding the __typename field at every level of the query. You must pass this option if your client code uses this query transformation. -* `queryTransformers`: `[function(documentNode) => documentNode]` Directly override the query transformations list to provide additional transforms as needed. Further reading on the DocumentNode object can be accomplished here: https://github.com/graphql/graphql-js/blob/master/src/language/ast.js This is what a query transformer to strip the client fields looks like: +* `queryTransformers`: `[function(documentNode) => documentNode]` Directly override the query transformations list to provide additional transforms as needed. This is what a query transformer to strip the client fields looks like: ```js @@ -90,3 +90,4 @@ function removeClientFieldsTransformer(doc: DocumentNode) => { return docClone; }; ``` +Further reading on the DocumentNode object can be accomplished here: https://github.com/graphql/graphql-js/blob/master/src/language/ast.js From 0f26581cff6c58963343e94cb56a6a5532eef02b Mon Sep 17 00:00:00 2001 From: toddtarsi Date: Wed, 6 Feb 2019 13:50:51 -0600 Subject: [PATCH 4/4] Documentation, clarifying queryTransformer type --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 245f3fb..a3a9be5 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ console.log(query.documentId); // => 5eef6cd6a52ee0d67bfbb0fdc72bbbde4d70331834e * `generateId`: `function (querySource: string) => string` Function that allows to generate a custom documentId from the query source. This source contains all the dependencies sources concatenated, so it's suitable for hashing. By default it generates the sha256 hash in hexadecimal format. The source is concatenated in the same way as you'd get it from the `persistgraphql` tool, so hashing the queries from the output of that tool should get you the same hash value. * `addTypename`: `boolean` Apply a query transformation to the query documents, adding the __typename field at every level of the query. You must pass this option if your client code uses this query transformation. -* `queryTransformers`: `[function(documentNode) => documentNode]` Directly override the query transformations list to provide additional transforms as needed. This is what a query transformer to strip the client fields looks like: +* `queryTransformers`: `array[function(documentNode) => documentNode]` Directly override the query transformations list to provide additional transforms as needed. This is what a query transformer to strip the client fields looks like: ```js