UNPKG

5.43 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const types_1 = require("@babel/types");
4const types_2 = require("@babel/types");
5const intermediates_1 = require("./intermediates");
6const types_3 = require("@babel/types");
7const types_4 = require("@babel/types");
8const types_5 = require("@babel/types");
9const types_6 = require("@babel/types");
10const types_7 = require("@babel/types");
11const types_8 = require("@babel/types");
12const constructors_1 = require("./constructors");
13const compact_1 = require("./compact");
14const types_9 = require("./types");
15const possiblyParenthesizedExpression = (expression, parentOperator) => types_4.isLogicalExpression(expression) && expression.operator != parentOperator
16 ? types_5.parenthesizedExpression(expression)
17 : expression;
18const 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));
23const and = (...expressions) => logicallyCombine("&&", expressions);
24const or = (...expressions) => logicallyCombine("||", expressions);
25const nullPredicate = (expression) => types_1.binaryExpression("==", expression, types_1.nullLiteral());
26const 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};
37const isFragmentReference = expression => fragmentReference => types_1.TSAsExpression(types_6.callExpression(types_2.identifier(`is${fragmentReference.name}`), [expression]), types_1.TSBooleanKeyword());
38const accumIdentifier = constructors_1.typedIdentifier("accum", types_1.TSAnyKeyword());
39const nextIdentifier = constructors_1.typedIdentifier("next", types_1.TSAnyKeyword());
40const 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]));
47const 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};
67const typenamePredicate = (object, type) => types_1.binaryExpression("==", types_1.memberExpression(object, types_2.identifier("__typename")), types_1.stringLiteral(type));
68const 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};
75const 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)));
76const fragmentIdentifier = types_2.identifier("fragment");
77exports.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//# sourceMappingURL=typePredicates.js.map
\No newline at end of file