Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(deps): update dependency @graphql-tools/delegate to v10 #580

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

renovate[bot]
Copy link
Contributor

@renovate renovate bot commented May 9, 2024

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
@graphql-tools/delegate (source) ^8.8.1 -> ^10.2.2 age adoption passing confidence

Release Notes

graphql-hive/gateway (@​graphql-tools/delegate)

v10.2.2

Compare Source

Patch Changes

v10.2.1

Compare Source

Patch Changes

v10.2.0

Compare Source

Minor Changes

v10.1.3

Compare Source

Patch Changes
  • #​118 73c621d Thanks @​{! - Do not ignore request selection set when overriding the fields

    import { buildSchema, graphql } from 'graphql';
    import { addResolversToSchema } from '@​graphql-tools/schema';
    import { stitchSchemas } from '@​graphql-tools/stitch';
    import { delegateToSchema } from '@​graphql-tools/delegate';
    
    const sub_schema = addResolversToSchema({
      schema: buildSchema(`
      type Query {
        current_user: User
      }
    
      type User {
        id: ID!
        name: String!
        age: Int!
      }
    `),
      resolvers: {
        Query: {
          current_user: () => ({ id: '5', name: 'John Doe', age: 10 }),
        },
      },
    });
    
    const stitched_schema = stitchSchemas({
      subschemas: [
        {
          schema: sub_schema,
          createProxyingResolver: (options) => {
            return (_parent, _args, context, info) => {
              const operationName = info.operation.name ? info.operation.name.value : undefined;
              return delegateToSchema({
                schema: options.subschemaConfig,
                operation: options.operation,
                context,
                info,
                operationName,
              });
            };
          },
        },
      ],
      resolvers: {
    
          name: {
            selectionSet: '{ age }',
            resolve: (parent) => `${parent.name}(${parent.age})`, // Age should be here
          },
        },
      },
    });

v10.1.2

Compare Source

v10.1.1

Compare Source

Patch Changes
  • 342e044
    Thanks @​ardatan! - Prevent extra queries to the same subgraph
    multiple times on the same plan, and merge iterables correctly

v10.1.0

Compare Source

Minor Changes

v10.0.29

Compare Source

Patch Changes

v10.0.28

Compare Source

Patch Changes

v10.0.27

Compare Source

Patch Changes

v10.0.26

Compare Source

Patch Changes

v10.0.25

Compare Source

Patch Changes

v10.0.24

Compare Source

Patch Changes

v10.0.23

Compare Source

Patch Changes
  • #​6573
    7e2938d
    Thanks @​ardatan! - When there are two services like below then the
    following query senty, the gateway tries to fetch id as an extra field because it considers id
    might be needed while this is not correct. This patch avoids any extra calls, and forwards the
    query as is to the 2nd service.

    query {
      viewer {
        booksContainer(input: $input) {
          edges {
            cursor
            node {
              source {

Book(upc=)

          upc
        }
      }
    }
    pageInfo {
      endCursor
    }
  }
}

}


```graphql
type Book @​key(fields: "id") @​key(fields: "upc") {
  id: ID!
  upc: ID!
}
type BookContainer { # the type that is used in a collection
  id: ID!

### ... other stuff here
  source: Book!
}

type Book @​key(fields: "upc") {
  upc: ID!
}

type Query {
  viewer: Viewer
}

type Viewer {
  booksContainer: BooksContainerResult
}

type BooksContainerResult {
  edges: [BooksContainerEdge!]!
  pageInfo: PageInfo!
}

type BooksContainerEdge {
  node: BookContainer!
  cursor: String!
}

type PageInfo {
  endCursor: String
}

v10.0.22

Compare Source

Patch Changes

v10.0.21

Compare Source

Patch Changes

v10.0.20

Compare Source

Patch Changes
  • #​6469
    0e87805
    Thanks @​User!! - Handle merged selection sets in the computed fields;

    When a selection set for a computed field needs to be merged, resolve that required selection set
    fully then resolve the computed field. In the following case, the selection set for the author
    field in the Post type is merged with the selection set for the authorId field in the
    Comment type.

    type Query {
      feed: [Post!]!
    }
    
    type Post {
      id: ID! @​computed(selectionSet: "{ comments { authorId } }")
    }
    
    type Comment {
      id: ID!
      authorId: ID!
    }
    
    type User {
      id: ID!
      name: String!
    }
    type Post {
      id: ID!
      comments: [Comment!]!
    }
    
    type Comment {
      id: ID!
    }

v10.0.19

Compare Source

Patch Changes
  • #​6437
    3188051
    Thanks @​User, @​(),
    @​{, @​{, @​{,
    @​{, @​{! - Fix the bug happens when a merged field
    is a computed field requires another computed field requires a field from the initial subschema.

    In the following test case, totalOrdersPrices needs userOrders which needs lastName from
    initial Query.user. So the bug was skipping the dependencies of userOrders because it assumed
    lastName already there by mistake.

        const schema1 = makeExecutableSchema({
          typeDefs: /* GraphQL */ `
            type User {
              id: ID!
              firstName: String!
              lastName: String!
              address: String
            }
    
            type Query {
    
            }
          `,
          resolvers: {
            Query: {
     => {
                return {
                  id: 1,
                  firstName: 'Jake',
                  lastName: 'Dawkins',
                  address: 'everywhere',
                };
              },
            },
          },
        });
        const schema2 = makeExecutableSchema({
          typeDefs: /* GraphQL */ `
            type UserOrder {
              id: ID!
            }
    
            type User {
              id: ID!
              totalOrdersPrices: Int
              aggregatedOrdersByStatus: Int
            }
    
            type Query {
              userWithOrderDetails(userId: ID!, userOrderIds: [ID]): User
            }
          `,
          resolvers: {
            Query: {
              userWithOrderDetails: (_root, { userId, userOrderIds }) => {
                return {
                  id: userId,
                  userOrders: userOrderIds?.map((userOrderId: string) => ({ id: userOrderId })),
                };
              },
            },
    
              totalOrdersPrices(user) {
                if (user.userOrders instanceof Error) {
                  return user.userOrders;
                }
                if (!user.userOrders) {
                  throw new Error('UserOrders is required');
                }
                return 0;
              },
              aggregatedOrdersByStatus(user) {
                if (user.userOrders instanceof Error) {
                  return user.userOrders;
                }
                if (!user.userOrders) {
                  throw new Error('UserOrders is required');
                }
                return 1;
              },
            },
          },
        });
        const schema3 = makeExecutableSchema({
          typeDefs: /* GraphQL */ `
            type User {
              id: ID!
              userOrders: [UserOrder!]
            }
    
            type UserOrder {
              id: ID!
            }
    
            type Query {
              userWithOrders(id: ID!, lastName: String): User
            }
          `,
          resolvers: {
            Query: {
              userWithOrders: (_root, { id, lastName }) => {
                return {
                  id,
                  lastName,
                };
              },
            },
    
              userOrders(user) {
                if (!user.lastName) {
                  throw new Error('LastName is required');
                }
                return [
                  {
                    id: `${user.lastName}1`,
                  },
                ];
              },
            },
          },
        });
        const stitchedSchema = stitchSchemas({
          subschemas: [
            {
              schema: schema1,
            },
            {
              schema: schema2,
              merge: {
    
                  selectionSet: '{ id }',
                  fieldName: 'userWithOrderDetails',
                  args: ({ id, userOrders }: { id: string; userOrders: any[] }) => ({
                    userId: id,
                    userOrderIds: userOrders?.map?.(({ id }: { id: string }) => id),
                  }),
                  fields: {
                    totalOrdersPrices: {
                      selectionSet: '{ userOrders { id } }',
                      computed: true,
                    },
                    aggregatedOrdersByStatus: {
                      selectionSet: '{ userOrders { id } }',
                      computed: true,
                    },
                  },
                },
              },
            },
            {
              schema: schema3,
              merge: {
    
                  selectionSet: '{ id }',
                  fieldName: 'userWithOrders',
                  args: ({ id, lastName }: { id: string; lastName: string }) => ({
                    id,
                    lastName,
                  }),
                  fields: {
                    userOrders: {
                      selectionSet: '{ lastName }',
                      computed: true,
                    },
                  },
                },
              },
            },
          ],
        });
        const res = await normalizedExecutor({
          schema: stitchedSchema,
          document: parse(/* GraphQL */ `
            query User {
              user {
                aggregatedOrdersByStatus
                totalOrdersPrices
              }
            }
          `),
        });
        expect(res).toEqual({
          data: {
    
              aggregatedOrdersByStatus: 1,
              totalOrdersPrices: 0,
            },
          },
        });

v10.0.18

Compare Source

Patch Changes
  • #​6420
    a867bbc
    Thanks @​ardatan! - dependencies updates:

  • #​6420
    a867bbc
    Thanks @​ardatan! - Pass operation directives correctly to the
    subschema;

    query {
      hello @​someDir
    }
  • #​6418
    da93c08
    Thanks @​ardatan! - Fix extra inline fragments for all abstract types
    in the upstream schema call

    If there are two subschemas like below, the final Node interface is implemented by both Oven
    and Toaster while they are not implemented in both schemas. In this case the query
    { products { id ... on Node { id } } } will need to be transformed to
    { products { id ... on Oven { id } ... on Node { id } } } for the first subschema. But
    previously the query planner was automatically creating inline fragments for all possible types
    which was not optimal. Now it adds inline fragments only if this case is seen.

    type Query {
      products: [Product]
    }
    
    union Product = Oven | Toaster
    
    interface Node {
      id: ID!
    }
    
    type Oven {
      id: ID!
    }
    
    type Toaster implements Node {
      id: ID!
      warranty: Int
    }

    And another one like below;

    interface Node {
      id: ID!
    }
    
    type Oven implements Node {
      id: ID!
      warranty: Int
    }
  • Updated dependencies
    [a867bbc]:

v10.0.17

Compare Source

Patch Changes

v10.0.16

Compare Source

Patch Changes

v10.0.15

Compare Source

Patch Changes
  • d54b21a
    Thanks @​ardatan! - If an abstract type on the gateway resolves to a
    type that does not exist on the gateway, return null instead of showing an error to the user

  • d54b21a
    Thanks @​ardatan! - If an enum value coming from the subschema is not
    available on gateway, do not show an error to the user but return null instead

v10.0.14

Compare Source

Patch Changes
  • #​6356
    8094c37
    Thanks @​enisdenjo! - AggregateError errors are GraphQL located
    errors

    Instead of transforming the AggregateError itself to a GraphQL located error.

    This is because of two reasons:

    • AggregateError wont lose the instanceof its class
    • Expanding the AggregateError errors will each contain the proper locations

v10.0.13

Compare Source

Patch Changes

v10.0.12

Compare Source

Patch Changes

v10.0.11

Compare Source

Patch Changes
  • #​6194
    7368829
    Thanks @​ardatan! - Handle interface objects in a different way

  • #​6188
    e10c13a
    Thanks @​ardatan! - Add subtractSelectionSets to get the diff of
    two selection sets

  • #​6187
    dfccfbf
    Thanks @​ardatan! - Do not merge errors and regular resolved objects

    If a subschema returns an error for specific field that is already resolved by another subschema,
    the error should not be merged with the resolved object.

  • #​6189
    0134f7f
    Thanks @​ardatan! - Handle interface types with non-shared
    implementations;

    For example, you have the following services, where Node is implemented in both services, but
    Foo and Bar are only implemented in one service. And when the gateway receives the following
    query, it should be converted to this because Node is not implemented as Bar in Service 1
    while implemented in Service 2.

    Query conversion;

v10.0.10

Compare Source

Patch Changes
  • #​6134
    a83da08
    Thanks @​User! - Ignore unmerged fields

    Let's say you have a gateway schema like in the bottom, and id is added to the query, only if
    the age is requested;

v10.0.9

Compare Source

Patch Changes
  • #​6126
    680351e
    Thanks @​ardatan! - When there is a Node subschema, and others to
    resolve the rest of the entities by using a union resolver as in Federation like below, it was
    failing. This version fixes that issue.

    query {
      node(id: "1") {
        id # Fetches from Node
        ... on User {
          name # Fetches from User
        }
      }
    }
    type Query {
      node(id: ID!): Node
    }
    
    interface Node {
      id: ID!
    }
    
    type User implements Node {
      id: ID!
    }
    
    type Post implements Node {
      id: ID!
    }

v10.0.8

Compare Source

Patch Changes

v10.0.7

Compare Source

Patch Changes

v10.0.6

Compare Source

Patch Changes
  • af7be09
    Thanks @​ardatan! - Hotfix: do not use nullable and nonNullable
    prefixes if field names don't match

v10.0.5

Compare Source

Patch Changes
  • #​6091
    9bca9e0
    Thanks @​User, @​User! - If the gateway
    receives a query with an overlapping fields for the subschema, it uses aliases to resolve it
    correctly.

    Let's say subschema A has the following schema;

      type Query {
    
      }
    
      interface User {
        id: ID!
        name: String!
      }
    
      type Admin implements User {
        id: ID!
        name: String!
        role: String!
      }
    
      type Customer implements User {
        id: ID!
        name: String
        email: String
      }

    And let's say the gateway has the following schema instead;

      type Query {
    
      }
    
      interface User {
        id: ID!
        name: String!
      }
    
      type Admin implements User {
        id: ID!
        name: String!
        role: String!
      }
    
      type Customer implements User {
        id: ID!
        name: String!
        email: String!
      }

    In this case, the following query is fine for the gateway but for the subschema, it's not;

    query {
      user {
        ... on Admin {
          id
          name # This is nullable in the subschema
          role
        }
        ... on Customer {
          id
          name # This is non-nullable in the subschema
          email
        }
      }
    }

    So the subgraph will throw based on this rule
    OverlappingFieldsCanBeMerged

    To avoid this, the gateway will use aliases to resolve the query correctly. The query will be
    transformed to the following;

    query {
      user {
        ... on Admin {
          id
          name # This is nullable in the subschema
          role
        }
        ... on Customer {
          id
          name: _nullable_name # This is non-nullable in the subschema
          email
        }
      }
    }
  • #​6092
    243c353
    Thanks @​ardatan! - If one of the subgraphs are already able to
    resolve a nested field as in parent-entity-call example's Category.details from C's Product,
    resolve it from there instead of using type merging.

    query {
      product {
        category {
          details {

This is coming from C's Product, so resolve it from there instead of Type Merging

      id
      name
    }
  }
}

}

v10.0.4

Compare Source

Patch Changes

v10.0.3

Compare Source

Patch Changes

v10.0.2

Compare Source

Patch Changes

v10.0.1

Compare Source

Patch Changes
  • #​6437
    3188051
    Thanks @​User, @​(),
    @​{, @​{, @​{,
    @​{, @​{! - Fix the bug happens when a merged field
    is a computed field requires another computed field requires a field from the initial subschema.

    In the following test case, totalOrdersPrices needs userOrders which needs lastName from
    initial Query.user. So the bug was skipping the dependencies of userOrders because it assumed
    lastName already there by mistake.

        const schema1 = makeExecutableSchema({
          typeDefs: /* GraphQL */ `
            type User {
              id: ID!
              firstName: String!
              lastName: String!
              address: String
            }
    
            type Query {
    
            }
          `,
          resolvers: {
            Query: {
     => {
                return {
                  id: 1,
                  firstName: 'Jake',
                  lastName: 'Dawkins',
                  address: 'everywhere',
                };
              },
            },
          },
        });
        const schema2 = makeExecutableSchema({
          typeDefs: /* GraphQL */ `
            type UserOrder {
              id: ID!
            }
    
            type User {
              id: ID!
              totalOrdersPrices: Int
              aggregatedOrdersByStatus: Int
            }
    
            type Query {
              userWithOrderDetails(userId: ID!, userOrderIds: [ID]): User
            }
          `,
          resolvers: {
            Query: {
              userWithOrderDetails: (_root, { userId, userOrderIds }) => {
                return {
                  id: userId,
                  userOrders: userOrderIds?.map((userOrderId: string) => ({ id: userOrderId })),
                };
              },
            },
    
              totalOrdersPrices(user) {
                if (user.userOrders instanceof Error) {
                  return user.userOrders;
                }
                if (!user.userOrders) {
                  throw new Error('UserOrders is required');
                }
                return 0;
              },
              aggregatedOrdersByStatus(user) {
                if (user.userOrders instanceof Error) {
                  return user.userOrders;
                }
                if (!user.userOrders) {
                  throw new Error('UserOrders is required');
                }
                return 1;
              },
            },
          },
        });
        const schema3 = makeExecutableSchema({
          typeDefs: /* GraphQL */ `
            type User {
              id: ID!
              userOrders: [UserOrder!]
            }
    
            type UserOrder {
              id: ID!
            }
    
            type Query {
              userWithOrders(id: ID!, lastName: String): User
            }
          `,
          resolvers: {
            Query: {
              userWithOrders: (_root, { id, lastName }) => {
                return {
                  id,
                  lastName,
                };
              },
            },
    
              userOrders(user) {
                if (!user.lastName) {
                  throw new Error('LastName is required');
                }
                return [
                  {
                    id: `${user.lastName}1`,
                  },
                ];
              },
            },
          },
        });
        const stitchedSchema = stitchSchemas({
          subschemas: [
            {
              schema: schema1,
            },
            {
              schema: schema2,
              merge: {
    
                  selectionSet: '{ id }',
                  fieldName: 'userWithOrderDetails',
                  args: ({ id, userOrders }: { id: string; userOrders: any[] }) => ({
                    userId: id,
                    userOrderIds: userOrders?.map?.(({ id }: { id: string }) => id),
                  }),
                  fields: {
                    totalOrdersPrices: {
                      selectionSet: '{ userOrders { id } }',
                      computed: true,
                    },
                    aggregatedOrdersByStatus: {
                      selectionSet: '{ userOrders { id } }',
                      computed: true,
                    },
                  },
                },
              },
            },
            {
              schema: schema3,
              merge: {
    
                  selectionSet: '{ id }',
                  fieldName: 'userWithOrders',
                  args: ({ id, lastName }: { id: string; lastName: string }) => ({
                    id,
                    lastName,
                  }),
                  fields: {
                    userOrders: {
                      selectionSet: '{ lastName }',
                      computed: true,
                    },
                  },
                },
              },
            },
          ],
        });
        const res = await normalizedExecutor({
          schema: stitchedSchema,
          document: parse(/* GraphQL */ `
            query User {
              user {
                aggregatedOrdersByStatus
                totalOrdersPrices
              }
            }
          `),
        });
        expect(res).toEqual({
          data: {
    
              aggregatedOrdersByStatus: 1,
              totalOrdersPrices: 0,
            },
          },
        });

v10.0.0

Compare Source

Major Changes
Patch Changes

v9.0.35

Compare Source

Patch Changes

v9.0.34

Compare Source

Patch Changes

v9.0.33

Compare Source

Patch Changes

v9.0.32

Compare Source

Patch Changes

v9.0.31

Compare Source

Patch Changes

v9.0.30

Compare Source

Patch Changes

v9.0.29

Compare Source

Patch Changes
  • #​5131
    f26392a6
    Thanks @​neumark! - Create symbols with Symbol.for() because multiple
    copies of delegate cause stitching bugs otherwise.

v9.0.28

Compare Source

Patch Changes

v9.0.27

Compare Source

Patch Changes

v9.0.26

Compare Source

Patch Changes

Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch from 3676206 to d961591 Compare May 27, 2024 14:38
@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch from d961591 to 5f5c751 Compare July 4, 2024 00:02
@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch 3 times, most recently from 29b73bf to 59d484c Compare July 23, 2024 16:20
@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch 2 times, most recently from c38dfca to e9abefd Compare August 7, 2024 16:24
@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch from e9abefd to b32fdad Compare August 14, 2024 11:54
@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch 2 times, most recently from dcea61b to e7d64b6 Compare August 26, 2024 13:03
@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch 5 times, most recently from b9fe248 to 8a284e0 Compare October 17, 2024 13:59
@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch 3 times, most recently from d8bcc7d to 2790fcf Compare October 31, 2024 12:20
@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch 2 times, most recently from 9ad7788 to faf2109 Compare November 1, 2024 15:58
@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch 2 times, most recently from 4fa573e to 9e2de11 Compare November 19, 2024 17:05
@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch 2 times, most recently from 1031e6f to 99e674a Compare November 27, 2024 19:37
@renovate renovate bot force-pushed the renovate/examples-graphql-tools-delegate-10.x branch from 99e674a to cbac2a3 Compare November 29, 2024 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

0 participants