graphql#isAbstractType TypeScript Examples

The following examples show how to use graphql#isAbstractType. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts    From graphql-mesh with MIT License 5 votes vote down vote up
private prepareSearchParams(fragment: ResolveTree, schema: GraphQLSchema) {
    const fragmentTypeNames = Object.keys(fragment.fieldsByTypeName) as string[];
    const returnType = schema.getType(fragmentTypeNames[0]);
    const { args, fields } = simplifyParsedResolveInfoFragmentWithType(fragment, returnType);
    const searchParams = new URLSearchParams();
    if ('queryOptions' in args) {
      const { queryOptions } = args as any;
      for (const param in queryOptionsFields) {
        if (param in queryOptions) {
          searchParams.set('$' + param, queryOptions[param]);
        }
      }
    }

    // $select doesn't work with inherited types' fields. So if there is an inline fragment for
    // implemented types, we cannot use $select
    const isSelectable = !isAbstractType(returnType);

    if (isSelectable) {
      const { entityInfo } = returnType.extensions as unknown as EntityTypeExtensions;
      const selectionFields: string[] = [];
      const expandedFields: string[] = [];
      for (const fieldName in fields) {
        if (entityInfo.actualFields.includes(fieldName)) {
          selectionFields.push(fieldName);
        }
        if (this.config.expandNavProps && entityInfo.navigationFields.includes(fieldName)) {
          const searchParams = this.prepareSearchParams(fields[fieldName], schema);
          const searchParamsStr = decodeURIComponent(searchParams.toString());
          expandedFields.push(`${fieldName}(${searchParamsStr.split('&').join(';')})`);
          selectionFields.push(fieldName);
        }
      }
      if (!selectionFields.includes(entityInfo.identifierFieldName)) {
        selectionFields.push(entityInfo.identifierFieldName);
      }
      if (selectionFields.length) {
        searchParams.set('$select', selectionFields.join(','));
      }
      if (expandedFields.length) {
        searchParams.set('$expand', expandedFields.join(','));
      }
    }
    return searchParams;
  }
Example #2
Source File: index.ts    From amplify-codegen with Apache License 2.0 5 votes vote down vote up
possibleTypesForType(type: GraphQLCompositeType): GraphQLObjectType[] {
    if (isAbstractType(type)) {
      return Array.from(this.schema.getPossibleTypes(type)) || [];
    } else {
      return [type];
    }
  }
Example #3
Source File: codeGeneration.ts    From amplify-codegen with Apache License 2.0 5 votes vote down vote up
export function interfaceDeclarationForFragment(generator: CodeGenerator, fragment: LegacyFragment) {
  const { fragmentName, typeCondition, fields, inlineFragments } = fragment;

  const interfaceName = `${fragmentName}Fragment`;

  interfaceDeclaration(
    generator,
    {
      interfaceName,
      noBrackets: isAbstractType(typeCondition),
    },
    () => {
      if (isAbstractType(typeCondition)) {
        const propertySets = fragment.possibleTypes.map(type => {
          // NOTE: inlineFragment currently consists of the merged fields
          // from both inline fragments and fragment spreads.
          // TODO: Rename inlineFragments in the IR.
          const inlineFragment = inlineFragments.find(inlineFragment => {
            return inlineFragment.typeCondition.toString() == type.toString();
          });

          if (inlineFragment) {
            const fields = inlineFragment.fields.map(field => {
              if (field.fieldName === '__typename') {
                return {
                  ...field,
                  typeName: `"${inlineFragment.typeCondition}"`,
                  type: { name: `"${inlineFragment.typeCondition}"` } as GraphQLType,
                };
              } else {
                return field;
              }
            });

            return propertiesFromFields(generator.context, fields);
          } else {
            const fragmentFields = fields.map(field => {
              if (field.fieldName === '__typename') {
                return {
                  ...field,
                  typeName: `"${type}"`,
                  type: { name: `"${type}"` } as GraphQLType,
                };
              } else {
                return field;
              }
            });

            return propertiesFromFields(generator.context, fragmentFields);
          }
        });

        pickedPropertySetsDeclaration(generator, fragment, propertySets, true);
      } else {
        const fragmentFields = fields.map(field => {
          if (field.fieldName === '__typename') {
            return {
              ...field,
              typeName: `"${fragment.typeCondition}"`,
              type: { name: `"${fragment.typeCondition}"` } as GraphQLType,
            };
          } else {
            return updateTypeNameField(field);
          }
        });

        const properties = propertiesFromFields(generator.context, fragmentFields);
        pickedPropertyDeclarations(generator, properties);
      }
    },
  );
}
Example #4
Source File: codeGeneration.ts    From amplify-codegen with Apache License 2.0 5 votes vote down vote up
// pickedPropertyDeclarations declares specific properties selected by execution schemas or fragment schemas.
export function pickedPropertyDeclarations(generator: CodeGenerator, properties: Property[], isOptional = false) {
  if (!properties) return;
  properties.forEach(property => {
    if (isAbstractType(getNamedType(property.type || property.fieldType!))) {
      const propertySets = getPossibleTypeNames(generator, property).map(type => {
        const inlineFragment =
          property.inlineFragments &&
          property.inlineFragments.find(inlineFragment => {
            return inlineFragment.typeCondition.toString() == type;
          });

        if (inlineFragment) {
          const fields = inlineFragment.fields.map(field => {
            if (field.fieldName === '__typename') {
              return {
                ...field,
                typeName: `"${inlineFragment.typeCondition}"`,
                type: { name: `"${inlineFragment.typeCondition}"` } as GraphQLType,
              };
            } else {
              return field;
            }
          });

          return propertiesFromFields(generator.context, fields);
        } else {
          const fields = property.fields!.map(field => {
            if (field.fieldName === '__typename') {
              return {
                ...field,
                typeName: `"${type}"`,
                type: { name: `"${type}"` } as GraphQLType,
              };
            } else {
              return field;
            }
          });

          return propertiesFromFields(generator.context, fields);
        }
      });

      pickedPropertySetsDeclaration(generator, property, propertySets);
    } else {
      if (
        (property.fields && property.fields.length > 0) ||
        (property.inlineFragments && property.inlineFragments.length > 0) ||
        (property.fragmentSpreads && property.fragmentSpreads.length > 0)
      ) {
        propertyDeclaration(generator, property, () => {
          const properties = propertiesFromFields(generator.context, property.fields!);
          pickedPropertyDeclarations(generator, properties, isOptional);
        });
      } else {
        propertyDeclaration(generator, { ...property, isOptional });
      }
    }
  });
}
Example #5
Source File: graphql.ts    From amplify-codegen with Apache License 2.0 5 votes vote down vote up
export function isTypeProperSuperTypeOf(schema: GraphQLSchema, maybeSuperType: GraphQLCompositeType, subType: GraphQLCompositeType) {
  return (
    isEqualType(maybeSuperType, subType) ||
    (subType instanceof GraphQLObjectType && (isAbstractType(maybeSuperType) && schema.isPossibleType(maybeSuperType, subType)))
  );
}
Example #6
Source File: resolve-additional-resolvers.ts    From graphql-mesh with MIT License 4 votes vote down vote up
function generateSelectionSetFactory(
  schema: GraphQLSchema,
  additionalResolver: YamlConfig.AdditionalStitchingBatchResolverObject | YamlConfig.AdditionalStitchingResolverObject
) {
  if (additionalResolver.sourceSelectionSet) {
    return () => parseSelectionSet(additionalResolver.sourceSelectionSet);
    // If result path provided without a selectionSet
  } else if (additionalResolver.result) {
    const resultPath = toPath(additionalResolver.result);
    let abstractResultTypeName: string;

    const sourceType = schema.getType(additionalResolver.sourceTypeName) as GraphQLObjectType;
    const sourceTypeFields = sourceType.getFields();
    const sourceField = sourceTypeFields[additionalResolver.sourceFieldName];
    const resultFieldType = getTypeByPath(sourceField.type, resultPath);

    if (isAbstractType(resultFieldType)) {
      if (additionalResolver.resultType) {
        abstractResultTypeName = additionalResolver.resultType;
      } else {
        const targetType = schema.getType(additionalResolver.targetTypeName) as GraphQLObjectType;
        const targetTypeFields = targetType.getFields();
        const targetField = targetTypeFields[additionalResolver.targetFieldName];
        const targetFieldType = getNamedType(targetField.type);
        abstractResultTypeName = targetFieldType?.name;
      }
      if (abstractResultTypeName !== resultFieldType.name) {
        const abstractResultType = schema.getType(abstractResultTypeName);
        if (
          (isInterfaceType(abstractResultType) || isObjectType(abstractResultType)) &&
          !schema.isSubType(resultFieldType, abstractResultType)
        ) {
          throw new Error(
            `${additionalResolver.sourceTypeName}.${additionalResolver.sourceFieldName}.${resultPath.join(
              '.'
            )} doesn't implement ${abstractResultTypeName}.}`
          );
        }
      }
    }

    return (subtree: SelectionSetNode) => {
      let finalSelectionSet = subtree;
      let isLastResult = true;
      const resultPathReversed = [...resultPath].reverse();
      for (const pathElem of resultPathReversed) {
        // Ensure the path elem is not array index
        if (Number.isNaN(parseInt(pathElem))) {
          if (isLastResult && abstractResultTypeName && abstractResultTypeName !== resultFieldType.name) {
            finalSelectionSet = {
              kind: Kind.SELECTION_SET,
              selections: [
                {
                  kind: Kind.INLINE_FRAGMENT,
                  typeCondition: {
                    kind: Kind.NAMED_TYPE,
                    name: {
                      kind: Kind.NAME,
                      value: abstractResultTypeName,
                    },
                  },
                  selectionSet: finalSelectionSet,
                },
              ],
            };
          }
          finalSelectionSet = {
            kind: Kind.SELECTION_SET,
            selections: [
              {
                // we create a wrapping AST Field
                kind: Kind.FIELD,
                name: {
                  kind: Kind.NAME,
                  value: pathElem,
                },
                // Inside the field selection
                selectionSet: finalSelectionSet,
              },
            ],
          };
          isLastResult = false;
        }
      }
      return finalSelectionSet;
    };
  }
  return undefined;
}