1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const types_1 = require("@babel/types");
|
4 | const types_2 = require("@babel/types");
|
5 | const intermediates_1 = require("./intermediates");
|
6 | const types_3 = require("@babel/types");
|
7 | const types_4 = require("@babel/types");
|
8 | const types_5 = require("@babel/types");
|
9 | const types_6 = require("@babel/types");
|
10 | const types_7 = require("@babel/types");
|
11 | const types_8 = require("@babel/types");
|
12 | const constructors_1 = require("./constructors");
|
13 | const compact_1 = require("./compact");
|
14 | const types_9 = require("./types");
|
15 | const possiblyParenthesizedExpression = (expression, parentOperator) => types_4.isLogicalExpression(expression) && expression.operator != parentOperator
|
16 | ? types_5.parenthesizedExpression(expression)
|
17 | : expression;
|
18 | const logicallyCombine = (operator, expressions) => expressions.length < 1
|
19 | ? types_1.booleanLiteral(operator == "&&")
|
20 | : expressions
|
21 | .slice(1)
|
22 | .reduce((expression, nextExpression) => types_3.logicalExpression(operator, expression, possiblyParenthesizedExpression(nextExpression, operator)), possiblyParenthesizedExpression(expressions[0], operator));
|
23 | const and = (...expressions) => logicallyCombine("&&", expressions);
|
24 | const or = (...expressions) => logicallyCombine("||", expressions);
|
25 | const nullPredicate = (expression) => types_1.binaryExpression("==", expression, types_1.nullLiteral());
|
26 | const scalarType = (scalar) => {
|
27 | switch (scalar.name) {
|
28 | case "Int":
|
29 | case "Float":
|
30 | return "number";
|
31 | case "Boolean":
|
32 | return "boolean";
|
33 | default:
|
34 | return "string";
|
35 | }
|
36 | };
|
37 | const isFragmentReference = expression => fragmentReference => types_1.TSAsExpression(types_6.callExpression(types_2.identifier(`is${fragmentReference.name}`), [expression]), types_1.TSBooleanKeyword());
|
38 | const accumIdentifier = constructors_1.typedIdentifier("accum", types_1.TSAnyKeyword());
|
39 | const nextIdentifier = constructors_1.typedIdentifier("next", types_1.TSAnyKeyword());
|
40 | const listPredicate = (expression, ofType) => and(types_6.callExpression(types_1.memberExpression(types_2.identifier("Array"), types_2.identifier("isArray")), [expression]), types_6.callExpression(types_1.memberExpression(types_6.callExpression(types_1.memberExpression(expression, types_2.identifier("slice")), [
|
41 | types_7.numericLiteral(0),
|
42 | types_7.numericLiteral(5)
|
43 | ]), types_2.identifier("reduce")), [
|
44 | types_1.arrowFunctionExpression([accumIdentifier, nextIdentifier], and(accumIdentifier, typePredicate(nextIdentifier, ofType))),
|
45 | types_1.booleanLiteral(true)
|
46 | ]));
|
47 | const typePredicate = (expression, type, validated) => {
|
48 | switch (type.kind) {
|
49 | case "Maybe":
|
50 | return or(nullPredicate(expression), typePredicate(expression, type.ofType));
|
51 | case "List":
|
52 | return listPredicate(expression, type.ofType);
|
53 | case "FragmentReference":
|
54 | return isFragmentReference(expression)(type);
|
55 | case "InlineSelection":
|
56 | return inlineSelectionPredicate(type, expression, validated);
|
57 | case "Enum":
|
58 | return or(...type.values.map(value => types_1.binaryExpression("==", expression, types_1.stringLiteral(value))));
|
59 | case "Scalar":
|
60 | return types_1.binaryExpression("==", types_8.unaryExpression("typeof", expression), types_1.stringLiteral(scalarType(type)));
|
61 | case "Typename":
|
62 | return or(...type.possibleTypes
|
63 | .toArray()
|
64 | .map(type => types_1.binaryExpression("==", expression, types_1.stringLiteral(type))));
|
65 | }
|
66 | };
|
67 | const typenamePredicate = (object, type) => types_1.binaryExpression("==", types_1.memberExpression(object, types_2.identifier("__typename")), types_1.stringLiteral(type));
|
68 | const typeConditionsPredicate = (inlineSelection, object) => {
|
69 | const remainingTypes = types_9.remainingPossibleTypes(inlineSelection.typeConditions, inlineSelection.possibleTypes);
|
70 | return (inlineSelection.typeConditions.length > 0 &&
|
71 | or(...inlineSelection.typeConditions.map(condition => and(or(...condition.possibleTypes
|
72 | .toArray()
|
73 | .map(type => typenamePredicate(object, type))), typePredicate(object, condition, true))), ...remainingTypes.toArray().map(type => typenamePredicate(object, type))));
|
74 | };
|
75 | const inlineSelectionPredicate = (inlineSelection, object, validated) => and(...compact_1.default(...inlineSelection.intersections.map(isFragmentReference(object)), inlineSelection.intersections.length == 0 && !validated && object, ...inlineSelection.fields.map(field => typePredicate(types_1.memberExpression(object, types_2.identifier(field.name)), field.type)), typeConditionsPredicate(inlineSelection, object)));
|
76 | const fragmentIdentifier = types_2.identifier("fragment");
|
77 | exports.isFragmentDeclaration = (fragment) => types_1.variableDeclaration("const", [
|
78 | types_1.variableDeclarator(types_2.identifier(`is${fragment.fragmentName}`), Object.assign({}, types_1.arrowFunctionExpression([constructors_1.typedIdentifier(fragmentIdentifier.name, types_1.TSAnyKeyword())], inlineSelectionPredicate(intermediates_1.InlineSelection(fragment.selectionSet), fragmentIdentifier)), { returnType: types_1.TSTypeAnnotation(types_1.TSTypePredicate(fragmentIdentifier, types_1.TSTypeAnnotation(types_1.TSTypeReference(types_2.identifier(fragment.fragmentName))))) }))
|
79 | ]);
|
80 |
|
\ | No newline at end of file |