HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/shop.komma.nl/node_modules/apollo-codegen-scala/src/codeGeneration.ts
import {
  GraphQLError,
  getNamedType,
  isCompositeType,
  GraphQLEnumType,
  GraphQLInputObjectType,
  isNonNullType,
  isEnumType,
  isInputObjectType
} from "graphql";

import { isTypeProperSuperTypeOf } from "apollo-codegen-core/lib/utilities/graphql";

import { join } from "apollo-codegen-core/lib/utilities/printing";

import {
  packageDeclaration,
  objectDeclaration,
  escapeIdentifierIfNeeded,
  comment,
  traitDeclaration,
  propertyDeclaration,
  methodDeclaration
} from "./language";

import {
  traitNameForPropertyName,
  traitNameForFragmentName,
  traitNameForInlineFragment,
  operationClassName,
  enumCaseName,
  propertyFromLegacyField,
  propertyFromInputField
} from "./naming";

import { multilineString } from "./values";

import { possibleTypesForType, typeNameFromGraphQLType } from "./types";

import CodeGenerator from "apollo-codegen-core/lib/utilities/CodeGenerator";
import {
  LegacyCompilerContext,
  LegacyOperation,
  LegacyFragment,
  LegacyField,
  LegacyInlineFragment
} from "apollo-codegen-core/lib/compiler/legacyIR";
import { GraphQLType } from "graphql";
import { Property } from "./language";
import { GraphQLCompositeType } from "graphql";

export function generateSource(context: LegacyCompilerContext) {
  const generator = new CodeGenerator(context);

  generator.printOnNewline("// @generated");
  generator.printOnNewline(
    "//  This file was automatically generated and should not be edited."
  );
  generator.printNewline();

  if (context.options.namespace) {
    packageDeclaration(generator, context.options.namespace);
  }

  context.typesUsed.forEach(type => {
    typeDeclarationForGraphQLType(generator, type);
  });

  Object.values(context.operations).forEach(operation => {
    classDeclarationForOperation(generator, operation);
  });

  Object.values(context.fragments).forEach(fragment => {
    traitDeclarationForFragment(generator, fragment);
  });

  return generator.output;
}

export function classDeclarationForOperation(
  generator: CodeGenerator<LegacyCompilerContext, any>,
  {
    operationName,
    operationType,
    rootType,
    variables,
    fields,
    inlineFragments,
    fragmentSpreads,
    fragmentsReferenced,
    source,
    operationId
  }: LegacyOperation
) {
  let objectName;
  let protocol;

  switch (operationType) {
    case "query":
      objectName = `${operationClassName(operationName)}Query`;
      protocol = "com.apollographql.scalajs.GraphQLQuery";
      break;
    case "mutation":
      objectName = `${operationClassName(operationName)}Mutation`;
      protocol = "com.apollographql.scalajs.GraphQLMutation";
      break;
    default:
      throw new GraphQLError(`Unsupported operation type "${operationType}"`);
  }

  objectDeclaration(
    generator,
    {
      objectName,
      superclass: protocol
    },
    () => {
      if (source) {
        generator.printOnNewline("val operationString =");
        generator.withIndent(() => {
          multilineString(generator, source);
        });
      }

      if (operationId) {
        operationIdentifier(generator, operationId);
      }

      if (fragmentsReferenced && fragmentsReferenced.length > 0) {
        generator.printNewlineIfNeeded();
        generator.printOnNewline(
          "val requestString: String = { operationString"
        );
        fragmentsReferenced.forEach(fragment => {
          generator.print(
            ` + ${traitNameForFragmentName(fragment)}.fragmentString`
          );
        });
        generator.print(" }");

        generator.printOnNewline(
          "val operation = com.apollographql.scalajs.gql(requestString)"
        );
      } else {
        generator.printOnNewline(
          "val operation = com.apollographql.scalajs.gql(operationString)"
        );
      }

      generator.printNewlineIfNeeded();

      if (variables && variables.length > 0) {
        const properties = variables.map(({ name, type }) => {
          const propertyName = escapeIdentifierIfNeeded(name);
          const typeName = typeNameFromGraphQLType(
            generator.context,
            type,
            undefined,
            undefined,
            true
          );
          const isOptional = !isNonNullType(type);
          return { name, propertyName, type, typeName, isOptional };
        });

        dataContainerDeclaration(generator, {
          name: "Variables",
          properties
        });
      } else {
        generator.printOnNewline("type Variables = Unit");
      }

      traitDeclarationForSelectionSet(generator, {
        traitName: "Data",
        parentType: rootType,
        fields,
        inlineFragments,
        fragmentSpreads
      });
    }
  );
}

export function traitDeclarationForFragment(
  generator: CodeGenerator<LegacyCompilerContext, any>,
  {
    fragmentName,
    typeCondition,
    fields,
    inlineFragments,
    fragmentSpreads,
    source
  }: LegacyFragment
) {
  const traitName = traitNameForFragmentName(fragmentName);

  traitDeclarationForSelectionSet(
    generator,
    {
      traitName,
      parentType: typeCondition,
      fields,
      inlineFragments,
      fragmentSpreads
    },
    () => {
      if (source) {
        generator.printOnNewline("val fragmentString =");
        generator.withIndent(() => {
          multilineString(generator, source);
        });
      }
    }
  );
}

export function traitDeclarationForSelectionSet(
  generator: CodeGenerator<LegacyCompilerContext, any>,
  {
    traitName,
    parentType,
    fields,
    inlineFragments,
    fragmentSpreads,
    viewableAs,
    parentFragments
  }: {
    traitName: string;
    parentType: GraphQLCompositeType;
    fields: LegacyField[];
    inlineFragments?: LegacyInlineFragment[];
    fragmentSpreads?: string[];
    viewableAs?: {
      traitName: string;
      properties: (LegacyField & Property)[];
    };
    parentFragments?: string[];
  },
  objectClosure?: () => void
) {
  const possibleTypes = parentType
    ? possibleTypesForType(generator.context, parentType)
    : null;

  const properties = fields
    .map(field => propertyFromLegacyField(generator.context, field, traitName))
    .filter(field => field.propertyName != "__typename");

  const fragmentSpreadSuperClasses = (fragmentSpreads || []).filter(spread => {
    const fragment = generator.context.fragments[spread];
    const alwaysDefined = isTypeProperSuperTypeOf(
      generator.context.schema,
      fragment.typeCondition,
      parentType
    );

    return alwaysDefined;
  });

  // add types and implicit conversions
  if (inlineFragments && inlineFragments.length > 0) {
    inlineFragments.forEach(inlineFragment => {
      traitDeclarationForSelectionSet(generator, {
        traitName: traitNameForInlineFragment(inlineFragment),
        parentType: inlineFragment.typeCondition,
        fields: inlineFragment.fields,
        fragmentSpreads: inlineFragment.fragmentSpreads,
        viewableAs: {
          traitName,
          properties
        }
      });
    });
  }

  dataContainerDeclaration(generator, {
    name: traitName,
    properties,
    extraSuperClasses: [
      ...(viewableAs ? [viewableAs.traitName] : []),
      ...(fragmentSpreadSuperClasses || []),
      ...(parentFragments || [])
    ],
    insideCompanion: () => {
      if (possibleTypes) {
        generator.printNewlineIfNeeded();
        generator.printOnNewline("val possibleTypes = scala.collection.Set(");
        generator.print(
          join(Array.from(possibleTypes).map(type => `"${String(type)}"`), ", ")
        );
        generator.print(")");
      }

      generator.printNewlineIfNeeded();
      generator.printOnNewline(
        `implicit class ViewExtensions(private val orig: ${traitName}) extends AnyVal`
      );
      generator.withinBlock(() => {
        if (inlineFragments && inlineFragments.length > 0) {
          inlineFragments.forEach(inlineFragment => {
            const fragClass = traitNameForInlineFragment(inlineFragment);
            generator.printOnNewline(`def as${inlineFragment.typeCondition}`);
            generator.print(`: Option[${fragClass}] =`);
            generator.withinBlock(() => {
              generator.printOnNewline(
                `if (${fragClass}.possibleTypes.contains(orig.asInstanceOf[scala.scalajs.js.Dynamic].__typename.asInstanceOf[String])) Some(orig.asInstanceOf[${fragClass}]) else None`
              );
            });
          });
        }

        if (fragmentSpreads) {
          fragmentSpreads.forEach(s => {
            const fragment = generator.context.fragments[s];
            const alwaysDefined = isTypeProperSuperTypeOf(
              generator.context.schema,
              fragment.typeCondition,
              parentType
            );
            if (!alwaysDefined) {
              generator.printOnNewline(`def as${s}`);
              generator.print(`: Option[${s}] =`);
              generator.withinBlock(() => {
                generator.printOnNewline(
                  `if (${s}.possibleTypes.contains(orig.asInstanceOf[scala.scalajs.js.Dynamic].__typename.asInstanceOf[String])) Some(orig.asInstanceOf[${s}]) else None`
                );
              });
            }
          });
        }
      });

      const fragments = (fragmentSpreads || []).map(
        f => generator.context.fragments[f]
      );
      fields
        .filter(field => isCompositeType(getNamedType(field.type)))
        .forEach(field => {
          traitDeclarationForSelectionSet(generator, {
            traitName: traitNameForPropertyName(field.responseName),
            parentType: getNamedType(field.type) as GraphQLCompositeType,
            fields: field.fields || [],
            inlineFragments: field.inlineFragments,
            fragmentSpreads: field.fragmentSpreads,
            parentFragments: fragments
              .filter(f => {
                return f.fields.some(o => field.responseName == o.responseName);
              })
              .map(f => {
                return (
                  traitNameForFragmentName(f.fragmentName) +
                  "." +
                  traitNameForPropertyName(field.responseName)
                );
              })
          });
        });

      if (objectClosure) {
        objectClosure();
      }
    }
  });
}

function operationIdentifier(
  generator: CodeGenerator<LegacyCompilerContext, any>,
  operationId: string
) {
  if (!generator.context.options.generateOperationIds) {
    return;
  }

  generator.printNewlineIfNeeded();
  generator.printOnNewline(
    `val operationIdentifier: String = "${operationId}"`
  );
}

export function typeDeclarationForGraphQLType(
  generator: CodeGenerator<LegacyCompilerContext, any>,
  type: GraphQLType
) {
  if (isEnumType(type)) {
    enumerationDeclaration(generator, type);
  } else if (isInputObjectType(type)) {
    traitDeclarationForInputObjectType(generator, type);
  }
}

function enumerationDeclaration(
  generator: CodeGenerator<LegacyCompilerContext, any>,
  type: GraphQLEnumType
) {
  const { name, description } = type;
  const values = type.getValues();

  generator.printNewlineIfNeeded();
  comment(generator, description || "");
  generator.printOnNewline(`object ${name}`);
  generator.withinBlock(() => {
    values.forEach(value => {
      comment(generator, value.description || "");
      generator.printOnNewline(
        `val ${escapeIdentifierIfNeeded(enumCaseName(value.name))} = "${
          value.value
        }"`
      );
    });
  });
  generator.printNewline();
}

function traitDeclarationForInputObjectType(
  generator: CodeGenerator<LegacyCompilerContext, any>,
  type: GraphQLInputObjectType
) {
  const { name, description } = type;
  const fields = Object.values(type.getFields());
  const properties = fields.map(field =>
    propertyFromInputField(
      generator.context,
      field,
      generator.context.options.namespace
    )
  );

  dataContainerDeclaration(generator, {
    name,
    properties,
    description: description || undefined
  });
}

function dataContainerDeclaration(
  generator: CodeGenerator<LegacyCompilerContext, any>,
  {
    name,
    properties,
    extraSuperClasses,
    description,
    insideCompanion
  }: {
    name: string;
    properties: (Property & {
      name?: string;
      responseName?: string;
    })[];
    extraSuperClasses?: string[];
    description?: string;
    insideCompanion?: () => void;
  }
) {
  traitDeclaration(
    generator,
    {
      traitName: name,
      superclasses: ["scala.scalajs.js.Object", ...(extraSuperClasses || [])],
      annotations: ["scala.scalajs.js.native"],
      description: description || undefined
    },
    () => {
      properties.forEach(p => {
        propertyDeclaration(generator, {
          jsName: p.name || p.responseName,
          propertyName: p.propertyName,
          typeName: p.typeName
        });
      });
    }
  );

  objectDeclaration(
    generator,
    {
      objectName: name
    },
    () => {
      methodDeclaration(
        generator,
        {
          methodName: "apply",
          params: properties.map(p => {
            return {
              name: p.propertyName,
              type: p.typeName,
              defaultValue: p.isOptional
                ? "com.apollographql.scalajs.OptionalValue.empty"
                : ""
            };
          })
        },
        () => {
          const propertiesIn = properties
            .map(p => `"${p.name || p.responseName}" -> ${p.propertyName}`)
            .join(", ");
          generator.printOnNewline(
            `scala.scalajs.js.Dynamic.literal(${propertiesIn}).asInstanceOf[${name}]`
          );
        }
      );

      methodDeclaration(
        generator,
        {
          methodName: "unapply",
          params: [
            {
              name: "value",
              type: name
            }
          ]
        },
        () => {
          const propertiesExtracted = properties
            .map(p => `value.${p.propertyName}`)
            .join(", ");

          generator.printOnNewline(`Some((${propertiesExtracted}))`);
        }
      );

      generator.printNewlineIfNeeded();
      generator.printOnNewline(
        `implicit class CopyExtensions(private val orig: ${name}) extends AnyVal`
      );
      generator.withinBlock(() => {
        methodDeclaration(
          generator,
          {
            methodName: "copy",
            params: properties.map(p => {
              return {
                name: p.propertyName,
                type: p.typeName,
                defaultValue: `orig.${p.propertyName}`
              };
            })
          },
          () => {
            const propertiesIn = properties
              .map(p => `"${p.name || p.responseName}" -> ${p.propertyName}`)
              .join(", ");
            generator.printOnNewline(
              `scala.scalajs.js.Dynamic.literal(${propertiesIn}).asInstanceOf[${name}]`
            );
          }
        );
      });

      if (insideCompanion) {
        insideCompanion();
      }
    }
  );
}