1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var graphql_1 = require("graphql");
|
4 | var apollo_utilities_1 = require("apollo-utilities");
|
5 | var lodash_1 = require("lodash");
|
6 | var lodash_2 = require("lodash");
|
7 | var lodash_3 = require("lodash");
|
8 | var lodash_4 = require("lodash");
|
9 | var lodash_5 = require("lodash");
|
10 | var schema_1 = require("./schema");
|
11 | var transformations_1 = require("./transformations");
|
12 | function graphqlLodash(query, operationName) {
|
13 | var pathToArgs = {};
|
14 | var reshape = {};
|
15 | var queryAST = typeof query === 'string' ? graphql_1.parse(query) : query;
|
16 | traverseOperationFields(queryAST, operationName, function (node, resultPath, alias) {
|
17 | var args = getLodashDirectiveArgs(node, schema_1.lodashAST());
|
18 | if (args === null) {
|
19 | return;
|
20 | }
|
21 | var argsSetPath = resultPath.concat(['@_']);
|
22 | var previousArgsValue = lodash_2.get(pathToArgs, argsSetPath, null);
|
23 | if (previousArgsValue !== null && !lodash_3.isEqual(previousArgsValue, args)) {
|
24 | throw Error("Different \"@_\" args for the \"" + resultPath.join('.') + "\" path");
|
25 | }
|
26 | lodash_5.set(pathToArgs, argsSetPath, args);
|
27 | lodash_5.set(reshape, resultPath.concat(['_@']), alias[resultPath.length - 1]);
|
28 | });
|
29 | return {
|
30 | apply: !!Object.keys(pathToArgs).length,
|
31 | query: stripQuery(queryAST),
|
32 | transform: function (data) { return applyLodashDirective(pathToArgs, data); },
|
33 | queryShape: pathToArgs,
|
34 | reshape: reshape,
|
35 | };
|
36 | }
|
37 | exports.graphqlLodash = graphqlLodash;
|
38 | function traverseOperationFields(queryAST, operationName, cb) {
|
39 | var fragments = {};
|
40 | var operationAST = graphql_1.getOperationAST(queryAST, operationName);
|
41 | if (!operationAST) {
|
42 | throw new Error('Must provide operation name if query contains multiple operations.');
|
43 | }
|
44 | queryAST.definitions.forEach(function (definition) {
|
45 | if (definition.kind === graphql_1.Kind.FRAGMENT_DEFINITION) {
|
46 | fragments[definition.name.value] = definition;
|
47 | }
|
48 | });
|
49 | var resultPath = [];
|
50 | var alias = [];
|
51 | cb(operationAST, resultPath, alias);
|
52 | traverse(operationAST);
|
53 | function traverse(root) {
|
54 | graphql_1.visit(root, {
|
55 | enter: function (node) {
|
56 | var _a;
|
57 | if (node.kind === graphql_1.Kind.FIELD) {
|
58 | resultPath.push((node.alias || node.name).value);
|
59 | alias.push((_a = {}, _a[(node.alias || node.name).value] = node.name.value, _a));
|
60 | }
|
61 | if (node.kind === graphql_1.Kind.FRAGMENT_SPREAD) {
|
62 | var fragmentName = node.name.value;
|
63 | var fragment = fragments[fragmentName];
|
64 | if (!fragment) {
|
65 | throw Error("Unknown fragment: " + fragmentName);
|
66 | }
|
67 | traverse(fragment);
|
68 | }
|
69 | },
|
70 | leave: function (node) {
|
71 | if (node.kind !== graphql_1.Kind.FIELD) {
|
72 | return;
|
73 | }
|
74 | cb(node, resultPath, alias);
|
75 | resultPath.pop();
|
76 | alias.pop();
|
77 | },
|
78 | });
|
79 | }
|
80 | }
|
81 | function getLodashDirectiveArgs(node, lodashDirectiveDef) {
|
82 | var lodashNode = null;
|
83 | for (var _i = 0, _a = node.directives; _i < _a.length; _i++) {
|
84 | var directive = _a[_i];
|
85 | if (directive.name.value !== lodashDirectiveDef.name) {
|
86 | continue;
|
87 | }
|
88 | if (lodashNode) {
|
89 | throw Error("Duplicating \"@_\" on the \"" + node.name.value + "\"");
|
90 | }
|
91 | lodashNode = directive;
|
92 | }
|
93 | if (lodashNode === null) {
|
94 | return null;
|
95 | }
|
96 | var args = apollo_utilities_1.argumentsObjectFromField(lodashNode, lodashDirectiveDef);
|
97 | return normalizeLodashArgs(lodashNode.arguments, args);
|
98 | }
|
99 | function normalizeLodashArgs(argNodes, args) {
|
100 | if (!argNodes) {
|
101 | return args;
|
102 | }
|
103 | argNodes = lodash_4.keyBy(argNodes, function (argNode) { return argNode.name.value; });
|
104 | var orderedArgs = {};
|
105 | lodash_1.each(argNodes, function (node, name) {
|
106 | var argValue = args[name];
|
107 | if (node.value.kind === 'ObjectValue') {
|
108 | orderedArgs[name] = normalizeLodashArgs(node.value.fields, argValue);
|
109 | }
|
110 | else if (node.value.kind === 'ListValue') {
|
111 | var nodeValues = node.value.values;
|
112 | orderedArgs[name] = [];
|
113 | for (var i = 0; i < nodeValues.length; ++i) {
|
114 | orderedArgs[name][i] = normalizeLodashArgs(nodeValues[i].fields, argValue[i]);
|
115 | }
|
116 | }
|
117 | else if (node.value.kind === 'EnumValue' && node.value.value === 'none') {
|
118 | orderedArgs[name] = undefined;
|
119 | }
|
120 | else {
|
121 | orderedArgs[name] = argValue;
|
122 | }
|
123 | });
|
124 | return orderedArgs;
|
125 | }
|
126 | function stripQuery(queryAST) {
|
127 | var _a;
|
128 | return graphql_1.visit(queryAST, (_a = {},
|
129 | _a[graphql_1.Kind.DIRECTIVE] = function (node) {
|
130 | if (node.name.value === '_') {
|
131 | return null;
|
132 | }
|
133 | },
|
134 | _a));
|
135 | }
|
136 | function applyLodashDirective(pathToArgs, data) {
|
137 | if (data === null) {
|
138 | return null;
|
139 | }
|
140 | var changedData = applyOnPath(data, pathToArgs);
|
141 | return applyLodashArgs([], changedData, pathToArgs['@_']);
|
142 | }
|
143 | function applyOnPath(result, pathToArgs) {
|
144 | var currentPath = [];
|
145 | return traverse(result, pathToArgs);
|
146 | function traverse(root, pathRoot) {
|
147 | if (Array.isArray(root)) {
|
148 | return root.map(function (item) { return traverse(item, pathRoot); });
|
149 | }
|
150 | if (typeof root === 'object') {
|
151 | var changedObject = root ? Object.assign({}, root) : root;
|
152 | for (var key in pathRoot) {
|
153 | if (key === '@_') {
|
154 | continue;
|
155 | }
|
156 | currentPath.push(key);
|
157 | var changedValue = traverse(lodash_2.get(root, key), lodash_2.get(pathRoot, key));
|
158 | var lodashArgs = lodash_2.get(pathRoot, [key, '@_'].join('.'));
|
159 | changedValue = applyLodashArgs(currentPath, changedValue, lodashArgs);
|
160 | if (typeof changedValue === 'function') {
|
161 | changedValue(changedObject, key);
|
162 | }
|
163 | else {
|
164 | lodash_5.set(changedObject, key, changedValue);
|
165 | }
|
166 | currentPath.pop();
|
167 | }
|
168 | return changedObject;
|
169 | }
|
170 | else {
|
171 | return root;
|
172 | }
|
173 | }
|
174 | }
|
175 | function applyLodashArgs(path, object, args) {
|
176 | try {
|
177 | return transformations_1.applyTransformations(object, args);
|
178 | }
|
179 | catch (e) {
|
180 | console.log(path);
|
181 | throw e;
|
182 | }
|
183 | }
|
184 |
|
\ | No newline at end of file |