{
  "version": 3,
  "sources": ["../src/index.ts"],
  "sourcesContent": ["import {\n  ApolloLink,\n  Observable,\n  ApolloClient,\n  InMemoryCache,\n} from \"@apollo/client\";\nimport type {\n  Operation,\n  FetchResult,\n  NormalizedCacheObject,\n  InMemoryCacheConfig,\n} from \"@apollo/client\";\nimport { assertType, isAbstractType } from \"graphql\";\nimport type { DocumentNode, ExecutionResult, GraphQLSchema } from \"graphql\";\nimport invariant from \"invariant\";\n\nexport interface RequestDescriptor<Node = DocumentNode> {\n  readonly node: Node;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  readonly variables: Record<string, any>;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  readonly context?: Record<string, any>;\n}\n\nexport interface OperationDescriptor<\n  Schema = GraphQLSchema,\n  Node = DocumentNode,\n> {\n  readonly schema: Schema;\n  readonly request: RequestDescriptor<Node>;\n}\n\ntype OperationMockResolver<Schema = GraphQLSchema, Node = DocumentNode> = (\n  operation: OperationDescriptor<Schema, Node>,\n) => ExecutionResult | Error | undefined | null;\n\nexport interface MockFunctions<Schema = GraphQLSchema, Node = DocumentNode> {\n  /**\n   * Get all operation executed during the test by the current time.\n   */\n  getAllOperations(): OperationDescriptor<Schema, Node>[];\n\n  /**\n   * Return the most recent operation. This method will throw if no operations were executed prior this call.\n   */\n  getMostRecentOperation(): OperationDescriptor<Schema, Node>;\n\n  /**\n   * Find a particular operation in the list of all executed operations. This method will throw if the operation is not\n   * found.\n   */\n  findOperation(\n    findFn: (operation: OperationDescriptor<Schema, Node>) => boolean,\n  ): OperationDescriptor<Schema, Node>;\n\n  /**\n   * Provide a payload for an operation, but not complete the request. Practically useful when testing incremental\n   * updates and subscriptions.\n   *\n   * @note\n   *\n   * ApolloClient requires a delay until the next tick of the runloop before it updates,\n   * as per https://www.apollographql.com/docs/react/development-testing/testing/\n   */\n  nextValue(\n    operation: OperationDescriptor<Schema, Node>,\n    data: ExecutionResult,\n  ): Promise<void>;\n\n  /**\n   * Complete the operation. No more payloads are expected for this operation.\n   *\n   * @note\n   *\n   * ApolloClient requires a delay until the next tick of the runloop before it updates,\n   * as per https://www.apollographql.com/docs/react/development-testing/testing/\n   */\n  complete(operation: OperationDescriptor<Schema, Node>): Promise<void>;\n\n  /**\n   * Resolve the request with the provided payload. This is a shortcut for `nextValue(...)` and `complete(...)`.\n   *\n   * @note\n   *\n   * ApolloClient requires a delay until the next tick of the runloop before it updates,\n   * as per https://www.apollographql.com/docs/react/development-testing/testing/\n   */\n  resolve(\n    operation: OperationDescriptor<Schema, Node>,\n    data: ExecutionResult,\n  ): Promise<void>;\n\n  /**\n   * Reject the request with a given error.\n   *\n   * @note\n   *\n   * ApolloClient requires a delay until the next tick of the runloop before it updates,\n   * as per https://www.apollographql.com/docs/react/development-testing/testing/\n   */\n  reject(\n    operation: OperationDescriptor<Schema, Node>,\n    error: Error,\n  ): Promise<void>;\n\n  /**\n   * A shortcut for `getMostRecentOperation()` and `resolve()`.\n   *\n   * @note\n   *\n   * ApolloClient requires a delay until the next tick of the runloop before it updates,\n   * as per https://www.apollographql.com/docs/react/development-testing/testing/\n   */\n  resolveMostRecentOperation(\n    resolver: (\n      operation: OperationDescriptor<Schema, Node>,\n    ) => ExecutionResult | Promise<ExecutionResult>,\n  ): Promise<void>;\n\n  /**\n   * A shortcut for `getMostRecentOperation()` and `reject()`.\n   * @note\n   *\n   * ApolloClient requires a delay until the next tick of the runloop before it updates,\n   * as per https://www.apollographql.com/docs/react/development-testing/testing/\n   */\n  rejectMostRecentOperation(\n    error: Error | ((operation: OperationDescriptor<Schema, Node>) => Error),\n  ): Promise<void>;\n\n  /**\n   * Adds a resolver function that will be used to resolve/reject operations as they appear.\n   */\n  queueOperationResolver: (\n    resolver: OperationMockResolver<Schema, Node>,\n  ) => Promise<void>;\n}\n\ninterface ApolloClientExtension {\n  mock: MockFunctions;\n  // mockClear: () => void;\n}\n\nexport interface ApolloMockClient\n  extends ApolloClient<NormalizedCacheObject>,\n    ApolloClientExtension {}\n\nclass MockLink extends ApolloLink {\n  public schema: GraphQLSchema;\n  public mock: Mock;\n\n  constructor(schema: GraphQLSchema) {\n    super();\n    this.schema = schema;\n    this.mock = new Mock();\n  }\n\n  // FIXME: This does't actually work well and is likely due to the client\n  //        being in a tainted state.\n  // public mockClear() {\n  //   this.mock = new Mock();\n  // }\n\n  public request(operation: Operation): Observable<FetchResult> | null {\n    return new Observable<FetchResult>((observer) => {\n      this.mock.addOperation(\n        {\n          schema: this.schema,\n          request: {\n            node: operation.query,\n            variables: operation.variables || {},\n            context: operation.getContext(),\n          },\n        },\n        observer,\n      );\n    });\n  }\n}\n\nfunction executeOperationMockResolver(\n  resolver: OperationMockResolver,\n  operation: OperationDescriptor,\n  observer: ZenObservable.SubscriptionObserver<FetchResult>,\n) {\n  const resolved = resolver(operation);\n  if (resolved) {\n    if (resolved instanceof Error) {\n      observer.error(resolved);\n    } else {\n      observer.next(resolved);\n    }\n    observer.complete();\n    return true;\n  }\n  return false;\n}\n\nclass Mock implements MockFunctions {\n  private operations: Map<\n    OperationDescriptor,\n    ZenObservable.SubscriptionObserver<FetchResult>\n  >;\n\n  private resolversQueue: OperationMockResolver[];\n\n  constructor() {\n    this.operations = new Map();\n    this.resolversQueue = [];\n  }\n\n  public addOperation(\n    operation: OperationDescriptor,\n    observer: ZenObservable.SubscriptionObserver<FetchResult>,\n  ) {\n    for (const resolver of this.resolversQueue) {\n      if (executeOperationMockResolver(resolver, operation, observer)) {\n        return;\n      }\n    }\n    // If not immediately resolved, store it for later\n    this.operations.set(operation, observer);\n  }\n\n  private getObserver(operation: OperationDescriptor) {\n    const observer = this.operations.get(operation);\n    invariant(observer, \"Could not find operation in execution queue\");\n    return observer;\n  }\n\n  /**\n   * MockFunctions\n   */\n\n  public getAllOperations(): OperationDescriptor[] {\n    return Array.from(this.operations.keys());\n  }\n\n  public getMostRecentOperation(): OperationDescriptor {\n    const operations = this.getAllOperations();\n    invariant(\n      operations.length > 0,\n      \"Expected at least one operation to have been started\",\n    );\n    return operations[operations.length - 1];\n  }\n\n  public findOperation(\n    findFn: (operation: OperationDescriptor) => boolean,\n  ): OperationDescriptor {\n    let result: OperationDescriptor | null = null;\n    for (const operation of this.operations.keys()) {\n      if (findFn(operation)) {\n        result = operation;\n        break;\n      }\n    }\n    invariant(\n      result,\n      \"Operation was not found in the list of pending operations\",\n    );\n    return result;\n  }\n\n  public async nextValue(\n    operation: OperationDescriptor,\n    data: ExecutionResult,\n  ): Promise<void> {\n    this.getObserver(operation).next(data);\n  }\n\n  public async complete(operation: OperationDescriptor): Promise<void> {\n    const observer = this.getObserver(operation);\n    observer.complete();\n    this.operations.delete(operation);\n  }\n\n  public async resolve(\n    operation: OperationDescriptor,\n    data: ExecutionResult,\n  ): Promise<void> {\n    this.nextValue(operation, data);\n    this.complete(operation);\n  }\n\n  public async reject(\n    operation: OperationDescriptor,\n    error: Error,\n  ): Promise<void> {\n    this.getObserver(operation).error(error);\n    this.complete(operation);\n  }\n\n  public async resolveMostRecentOperation(\n    resolver: (\n      operation: OperationDescriptor,\n    ) => ExecutionResult | Promise<ExecutionResult>,\n  ): Promise<void> {\n    const operation = this.getMostRecentOperation();\n    this.resolve(operation, await resolver(operation));\n  }\n\n  public async rejectMostRecentOperation(\n    error: Error | ((operation: OperationDescriptor) => Error),\n  ): Promise<void> {\n    const operation = this.getMostRecentOperation();\n    this.reject(\n      operation,\n      typeof error === \"function\" ? error(operation) : error,\n    );\n  }\n\n  public async queueOperationResolver(resolver: OperationMockResolver) {\n    this.resolversQueue.push(resolver);\n    for (const [operation, observer] of this.operations) {\n      if (executeOperationMockResolver(resolver, operation, observer)) {\n        this.operations.delete(operation);\n      }\n    }\n  }\n}\n\nexport function createMockClient(\n  schema: GraphQLSchema,\n  options?: { cache?: InMemoryCacheConfig },\n): ApolloMockClient {\n  // Build a list of abstract types and their possible types.\n  // TODO: Cache this on the schema?\n  const possibleTypes: Record<string, string[]> = {};\n  Object.keys(schema.getTypeMap()).forEach((typeName) => {\n    const type = schema.getType(typeName);\n    assertType(type);\n    if (isAbstractType(type)) {\n      possibleTypes[typeName] = schema\n        .getPossibleTypes(type)\n        .map((possibleType) => possibleType.name);\n    }\n  });\n\n  const link = new MockLink(schema);\n\n  return Object.assign<\n    ApolloClient<NormalizedCacheObject>,\n    ApolloClientExtension\n  >(\n    new ApolloClient({\n      cache: new InMemoryCache({\n        addTypename: true,\n        ...options?.cache,\n        possibleTypes,\n      }),\n      link,\n    }),\n    {\n      get mock() {\n        return link.mock;\n      },\n      // mockClear() {\n      //   link.mockClear();\n      // },\n    },\n  );\n}\n"],
  "mappings": "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",
  "names": []
}
