diff --git a/.storybook/main.ts b/.storybook/main.ts index b87333f..d074c84 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,6 +1,7 @@ import type { StorybookConfig } from "@storybook/react-vite"; import relay from "vite-plugin-relay"; import graphqlLoader from "vite-plugin-graphql-loader"; +import svgr from "vite-plugin-svgr"; const config: StorybookConfig = { stories: ["./**/*.mdx", "./**/*.stories.@(js|jsx|mjs|ts|tsx)"], @@ -16,7 +17,7 @@ const config: StorybookConfig = { options: {}, }, async viteFinal(config, options) { - config.plugins?.push(relay, graphqlLoader()); + config.plugins?.push(relay, graphqlLoader(), svgr()); config.css = { postcss: { plugins: [ diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html new file mode 100644 index 0000000..f325b3d --- /dev/null +++ b/.storybook/preview-head.html @@ -0,0 +1,6 @@ + + + diff --git a/.storybook/stories/ApolloClient.mdx b/.storybook/stories/ApolloClient.mdx index 866b834..f671eeb 100644 --- a/.storybook/stories/ApolloClient.mdx +++ b/.storybook/stories/ApolloClient.mdx @@ -1,5 +1,5 @@ import { Canvas, Meta, Source } from "@storybook/blocks"; -import * as ApolloStories from "./ApolloClient.stories.ts"; +import * as ApolloStories from "./ApolloClient.stories.tsx"; diff --git a/.storybook/stories/ApolloClient.stories.ts b/.storybook/stories/ApolloClient.stories.ts deleted file mode 100644 index 99104cf..0000000 --- a/.storybook/stories/ApolloClient.stories.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react"; -import { within, expect, waitFor } from "@storybook/test"; -import { - ApolloApp, - ApolloAppWithDefer as AppWithDefer, -} from "./components/apollo-client/ApolloComponent.js"; -import { graphQLHandler } from "../../src/__tests__/mocks/handlers.js"; - -export default { - title: "Example/Apollo Client", - component: ApolloApp, - parameters: { - layout: "centered", - msw: { - handlers: { - graphql: graphQLHandler, - }, - }, - }, -} satisfies Meta; - -export { AppWithDefer }; - -export const App: StoryObj = { - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - await expect( - canvas.getByRole("heading", { name: /loading/i }), - ).toHaveTextContent("Loading..."); - await waitFor( - () => - expect( - canvas.getByRole("heading", { name: /customers/i }), - ).toHaveTextContent("Customers also purchased"), - { timeout: 2000 }, - ); - await waitFor( - () => expect(canvas.getByText(/beanie/i)).toBeInTheDocument(), - { timeout: 2000 }, - ); - }, -}; diff --git a/.storybook/stories/ApolloClient.stories.tsx b/.storybook/stories/ApolloClient.stories.tsx new file mode 100644 index 0000000..1cb650c --- /dev/null +++ b/.storybook/stories/ApolloClient.stories.tsx @@ -0,0 +1,82 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { within, expect, waitFor } from "@storybook/test"; +import { + ApolloApp as ApolloEcommerceApp, + ApolloAppWithDefer as AppWithDefer, +} from "./components/apollo-client/EcommerceExample.js"; +import { ApolloApp as ApolloWNBAApp } from "./components/apollo-client/WNBAExample.js"; +import { ecommerceHandler } from "../../src/__tests__/mocks/handlers.js"; +import { createHandler } from "../../src/handlers.js"; +import wnbaTypeDefs from "../stories/schemas/wnba.graphql"; + +const meta = { + title: "Example/Apollo Client", + component: ApolloEcommerceApp, + parameters: { + layout: "centered", + msw: { + handlers: { + graphql: ecommerceHandler, + }, + }, + }, +} satisfies Meta; + +export default meta; + +export const EcommerceApp: StoryObj = { + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await expect( + canvas.getByRole("heading", { name: /loading/i }), + ).toHaveTextContent("Loading..."); + await waitFor( + () => + expect( + canvas.getByRole("heading", { name: /customers/i }), + ).toHaveTextContent("Customers also purchased"), + { timeout: 2000 }, + ); + await waitFor( + () => expect(canvas.getByText(/beanie/i)).toBeInTheDocument(), + { timeout: 2000 }, + ); + }, +}; + +export const EcommerceAppWithDefer = () => ; + +export const WNBAApp = () => ; + +const teams = [ + { + id: "1", + name: "New York Liberty", + }, + { + id: "2", + name: "Las Vegas Aces", + }, +]; + +WNBAApp.parameters = { + msw: { + handlers: { + graphql: createHandler({ + typeDefs: wnbaTypeDefs, + resolvers: { + Mutation: { + setCurrentTeam: (_p, { team }) => teams.find((t) => t.id === team), + }, + Query: { + team: () => ({ + id: "1", + name: "New York Liberty", + }), + teams: () => teams, + }, + }, + }), + }, + }, +}; diff --git a/.storybook/stories/Relay.mdx b/.storybook/stories/Relay.mdx index 6c55de4..6931e8f 100644 --- a/.storybook/stories/Relay.mdx +++ b/.storybook/stories/Relay.mdx @@ -1,5 +1,5 @@ import { Canvas, Meta, Source } from "@storybook/blocks"; -import * as RelayStories from "./Relay.stories.ts"; +import * as RelayStories from "./Relay.stories.tsx"; diff --git a/.storybook/stories/Relay.stories.ts b/.storybook/stories/Relay.stories.tsx similarity index 80% rename from .storybook/stories/Relay.stories.ts rename to .storybook/stories/Relay.stories.tsx index 581f266..8b5be68 100644 --- a/.storybook/stories/Relay.stories.ts +++ b/.storybook/stories/Relay.stories.tsx @@ -4,7 +4,7 @@ import { RelayApp, RelayAppWithDefer as AppWithDefer, } from "./components/relay/RelayComponent.js"; -import { graphQLHandler } from "../../src/__tests__/mocks/handlers.js"; +import { ecommerceHandler } from "../../src/__tests__/mocks/handlers.js"; export default { title: "Example/Relay", @@ -13,15 +13,13 @@ export default { layout: "centered", msw: { handlers: { - graphql: graphQLHandler, + graphql: ecommerceHandler, }, }, }, } satisfies Meta; -export { AppWithDefer }; - -export const App: StoryObj = { +export const EcommerceApp: StoryObj = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); await expect( @@ -40,3 +38,5 @@ export const App: StoryObj = { ); }, }; + +export const EcommerceAppWithDefer = () => ; diff --git a/.storybook/stories/components/TeamLogo.tsx b/.storybook/stories/components/TeamLogo.tsx new file mode 100644 index 0000000..40d24e5 --- /dev/null +++ b/.storybook/stories/components/TeamLogo.tsx @@ -0,0 +1,34 @@ +import Atlanta from "./logos/AtlantaDream.svg?react"; +import Chicago from "./logos/ChicagoSky.svg?react"; +import Connecticut from "./logos/ConnecticutSun.svg?react"; +import Dallas from "./logos/DallasWings.svg?react"; +import Indiana from "./logos/IndianaFever.svg?react"; +import LasVegas from "./logos/LasVegasAces.svg?react"; +import LosAngeles from "./logos/LosAngelesSparks.svg?react"; +import Minnesota from "./logos/MinnesotaLynx.svg?react"; +import NewYork from "./logos/NewYorkLiberty.svg?react"; +import Phoenix from "./logos/PhoenixMercury.svg?react"; +import Seattle from "./logos/SeattleStorm.svg?react"; +import Washington from "./logos/WashingtonMystics.svg?react"; + +// indexed by team ID +const logos = [ + , + NewYork, + LasVegas, + LosAngeles, + Atlanta, + Chicago, + Connecticut, + Indiana, + Washington, + Dallas, + Minnesota, + Phoenix, + Seattle, +]; + +export function TeamLogo({ team }: { team: string }) { + const Logo = logos[parseInt(team)] || (() => "Error: no logo found"); + return ; +} diff --git a/.storybook/stories/components/apollo-client/ApolloComponent.tsx b/.storybook/stories/components/apollo-client/EcommerceExample.tsx similarity index 100% rename from .storybook/stories/components/apollo-client/ApolloComponent.tsx rename to .storybook/stories/components/apollo-client/EcommerceExample.tsx diff --git a/.storybook/stories/components/apollo-client/WNBAExample.tsx b/.storybook/stories/components/apollo-client/WNBAExample.tsx new file mode 100644 index 0000000..b5368d8 --- /dev/null +++ b/.storybook/stories/components/apollo-client/WNBAExample.tsx @@ -0,0 +1,217 @@ +import React, { Suspense, type ReactElement, type ReactNode } from "react"; +import type { TypedDocumentNode } from "@apollo/client"; +import { createClient } from "graphql-ws"; +import { GraphQLWsLink } from "@apollo/client/link/subscriptions"; +import { + gql, + InMemoryCache, + ApolloClient, + ApolloProvider, + ApolloLink, + HttpLink, + useSuspenseQuery, + useMutation, + useFragment, +} from "@apollo/client"; + +import { TeamLogo } from "../TeamLogo.js"; + +const httpLink = new HttpLink({ + uri: "http://localhost:4000/graphql", +}); + +const wsUrl = "ws://localhost:4000/graphql"; + +const wsLink = new GraphQLWsLink( + createClient({ + url: wsUrl, + }), +); + +const definitionIsSubscription = (d: any) => { + return d.kind === "OperationDefinition" && d.operation === "subscription"; +}; + +const link = ApolloLink.split( + (operation) => operation.query.definitions.some(definitionIsSubscription), + wsLink, + httpLink, +); + +export const makeClient = () => + new ApolloClient({ + cache: new InMemoryCache(), + link, + connectToDevTools: true, + }); + +export const client = makeClient(); + +const TEAM_FRAGMENT = gql` + fragment TeamFragment on Team { + id + name + wins + losses + } +`; + +const APP_QUERY: TypedDocumentNode<{ + team: { + id: string; + name: string; + wins: number; + losses: number; + }; + teams: { + name: string; + id: string; + }[]; +}> = gql` + query AppQuery { + team { + ...TeamFragment + } + teams { + name + id + } + } + + ${TEAM_FRAGMENT} +`; + +const APP_MUTATION = gql` + mutation SetCurrentTeam($team: ID!) { + setCurrentTeam(team: $team) { + ...TeamFragment + } + } + ${TEAM_FRAGMENT} +`; + +function Wrapper({ children }: { children: ReactNode }) { + return ( + + Loading...}>{children} + + ); +} + +export function ApolloApp() { + return ( + + + + ); +} + +export function App() { + // Use useSuspenseQuery here because we want to demo the loading experience + // with/without defer. + const { data } = useSuspenseQuery(APP_QUERY); + + // this slug of the franchise name is used to set the theme name on the parent + // div which corresponds to the theme names in tailwind.config.js + const currentTeamSlug = data?.teams + .find((team) => team.id === data?.team.id) + ?.name.split(" ") + .pop() + ?.toLowerCase(); + + return ( +
+
+

Welcome to the W 🏀

+
+ +
+ WNBA stats central +
+ + +
+ ); +} + +function TeamSelect({ + currentTeam, + teams, +}: { + currentTeam: string; + teams: Array<{ name: string; id: string }>; +}) { + const [setCurrentTeam] = useMutation(APP_MUTATION, { + update(cache, { data: { setCurrentTeam } }) { + cache.modify({ + fields: { + team(_existingRef, { toReference }) { + return toReference({ + __typename: "Team", + id: setCurrentTeam.id, + }); + }, + }, + }); + }, + }); + + return ( +
+ + +
+ ); +} + +function Team({ team }: { team: string }) { + const { data } = useFragment({ + fragment: TEAM_FRAGMENT, + from: { + __typename: "Team", + id: team, + }, + }); + + return ( +
+
+ +
+ {data ? ( + <> +

Wins: {data?.wins}

+

Losses: {data?.losses}

+ + ) : null} +
+ ); +} diff --git a/.storybook/stories/components/logos/AtlantaDream.svg b/.storybook/stories/components/logos/AtlantaDream.svg new file mode 100644 index 0000000..a80c2d0 --- /dev/null +++ b/.storybook/stories/components/logos/AtlantaDream.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.storybook/stories/components/logos/ChicagoSky.svg b/.storybook/stories/components/logos/ChicagoSky.svg new file mode 100644 index 0000000..ba99e40 --- /dev/null +++ b/.storybook/stories/components/logos/ChicagoSky.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.storybook/stories/components/logos/ConnecticutSun.svg b/.storybook/stories/components/logos/ConnecticutSun.svg new file mode 100644 index 0000000..7ef1550 --- /dev/null +++ b/.storybook/stories/components/logos/ConnecticutSun.svg @@ -0,0 +1 @@ +Connecticut Sun logo \ No newline at end of file diff --git a/.storybook/stories/components/logos/DallasWings.svg b/.storybook/stories/components/logos/DallasWings.svg new file mode 100644 index 0000000..0919de9 --- /dev/null +++ b/.storybook/stories/components/logos/DallasWings.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.storybook/stories/components/logos/IndianaFever.svg b/.storybook/stories/components/logos/IndianaFever.svg new file mode 100644 index 0000000..6e15df2 --- /dev/null +++ b/.storybook/stories/components/logos/IndianaFever.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.storybook/stories/components/logos/LasVegasAces.svg b/.storybook/stories/components/logos/LasVegasAces.svg new file mode 100644 index 0000000..6220681 --- /dev/null +++ b/.storybook/stories/components/logos/LasVegasAces.svg @@ -0,0 +1,28 @@ + + + Las Vegas Aces WNBA logo 2024 + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.storybook/stories/components/logos/LosAngelesSparks.svg b/.storybook/stories/components/logos/LosAngelesSparks.svg new file mode 100644 index 0000000..0848770 --- /dev/null +++ b/.storybook/stories/components/logos/LosAngelesSparks.svg @@ -0,0 +1 @@ +Los Angeles Sparks logo \ No newline at end of file diff --git a/.storybook/stories/components/logos/MinnesotaLynx.svg b/.storybook/stories/components/logos/MinnesotaLynx.svg new file mode 100644 index 0000000..ef30ea1 --- /dev/null +++ b/.storybook/stories/components/logos/MinnesotaLynx.svg @@ -0,0 +1 @@ + diff --git a/.storybook/stories/components/logos/NewYorkLiberty.svg b/.storybook/stories/components/logos/NewYorkLiberty.svg new file mode 100644 index 0000000..c68b3be --- /dev/null +++ b/.storybook/stories/components/logos/NewYorkLiberty.svg @@ -0,0 +1 @@ +New York Liberty logo \ No newline at end of file diff --git a/.storybook/stories/components/logos/PhoenixMercury.svg b/.storybook/stories/components/logos/PhoenixMercury.svg new file mode 100644 index 0000000..ab88903 --- /dev/null +++ b/.storybook/stories/components/logos/PhoenixMercury.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.storybook/stories/components/logos/SeattleStorm.svg b/.storybook/stories/components/logos/SeattleStorm.svg new file mode 100644 index 0000000..91e691a --- /dev/null +++ b/.storybook/stories/components/logos/SeattleStorm.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.storybook/stories/components/logos/WashingtonMystics.svg b/.storybook/stories/components/logos/WashingtonMystics.svg new file mode 100644 index 0000000..87eeffc --- /dev/null +++ b/.storybook/stories/components/logos/WashingtonMystics.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.storybook/stories/input.css b/.storybook/stories/input.css index b5c61c9..6367301 100644 --- a/.storybook/stories/input.css +++ b/.storybook/stories/input.css @@ -1,3 +1,38 @@ @tailwind base; @tailwind components; @tailwind utilities; + +.sb-show-main.sb-main-centered #storybook-root { + padding: 0; +} + +.wnba * { + font-family: "VT323", monaco, Consolas, "Lucida Console", monospace; +} + +.marquee { + width: 100vw; + left: 0; + top: 0; + position: absolute; + line-height: 35px; + background-color: red; + color: white; + white-space: nowrap; + overflow: hidden; + box-sizing: border-box; +} +.marquee p { + display: inline-block; + padding-left: 100%; + font-size: 1.5em; + animation: marquee 20s linear infinite; +} +@keyframes marquee { + 0% { + transform: translate(0, 0); + } + 100% { + transform: translate(-100%, 0); + } +} diff --git a/.storybook/stories/ecommerce-schema.graphql b/.storybook/stories/schemas/ecommerce.graphql similarity index 100% rename from .storybook/stories/ecommerce-schema.graphql rename to .storybook/stories/schemas/ecommerce.graphql diff --git a/.storybook/stories/github-schema.graphql b/.storybook/stories/schemas/github.graphql similarity index 100% rename from .storybook/stories/github-schema.graphql rename to .storybook/stories/schemas/github.graphql diff --git a/.storybook/stories/schemas/wnba.graphql b/.storybook/stories/schemas/wnba.graphql new file mode 100644 index 0000000..4be0174 --- /dev/null +++ b/.storybook/stories/schemas/wnba.graphql @@ -0,0 +1,46 @@ +type Query { + teams: [Team!]! + team(id: ID): Team! + coaches: [Coach!]! + favoriteTeam: ID! +} + +type Mutation { + setCurrentTeam(team: ID!): Team! +} + +type Team { + id: ID! + name: String! + wins: Int! + losses: Int! + coach: Coach! +} + +type Coach { + id: ID! + team: ID! + name: String! +} + +type Player { + id: ID! + name: String! + position: String! +} + +type Game { + home: Team! + away: Team! + id: ID! +} + +type Subscription { + numberIncremented: Int + score(gameId: ID!): Score +} + +type Score { + home: Int! + away: Int! +} diff --git a/.storybook/tailwind.config.js b/.storybook/tailwind.config.js index 1d10c1c..3f954c4 100644 --- a/.storybook/tailwind.config.js +++ b/.storybook/tailwind.config.js @@ -1,10 +1,62 @@ const { join } = require("node:path"); -const { colors } = require("@apollo/tailwind-preset"); +const { createThemes } = require("tw-colors"); const defaultConfig = require("tailwindcss/defaultConfig"); /** @type {import('tailwindcss').Config} */ module.exports = { content: [join(__dirname, "./**/*.{js,ts,jsx,tsx}")], - plugins: [require("@tailwindcss/aspect-ratio")], - presets: [defaultConfig, colors], + presets: [defaultConfig], + plugins: [ + require("@tailwindcss/aspect-ratio"), + createThemes({ + liberty: { + primary: "#86CEBC", + secondary: "#FFFFFF", + }, + aces: { + primary: "#A7A8AA", + secondary: "#FFFFFF", + }, + sparks: { + primary: "#552583", + secondary: "#FDB927", + }, + dream: { + primary: "#E31837", + secondary: "#FFFFFF", + }, + sky: { + primary: "#5091CD", + secondary: "#FFD520", + }, + sun: { + primary: "#0A2240", + secondary: "#F05023", + }, + fever: { + primary: "#E03A3E", + secondary: "#FFD520", + }, + mystics: { + primary: "#002B5C", + secondary: "#E03A3E", + }, + wings: { + primary: "#2456A5", + secondary: "#C4D600", + }, + lynx: { + primary: "#266092", + secondary: "#79BC43", + }, + mercury: { + primary: "#1D1160", + secondary: "#E56020", + }, + storm: { + primary: "#2C5235", + secondary: "#FEE11A", + }, + }), + ], }; diff --git a/.storybook/vite-env.d.ts b/.storybook/vite-env.d.ts new file mode 100644 index 0000000..d816124 --- /dev/null +++ b/.storybook/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/codegen.ts b/codegen.ts index de65c7f..9eb2348 100644 --- a/codegen.ts +++ b/codegen.ts @@ -6,11 +6,11 @@ const config: CodegenConfig = { }, generates: { "./src/__generated__/resolvers-types-ecommerce.ts": { - schema: "./.storybook/stories/ecommerce-schema.graphql", + schema: "./.storybook/stories/schemas/ecommerce.graphql", plugins: ["typescript", "typescript-resolvers"], }, "./src/__generated__/resolvers-types-github.ts": { - schema: "./.storybook/stories/github-schema.graphql", + schema: "./.storybook/stories/schemas/github.graphql", plugins: ["typescript", "typescript-resolvers"], }, }, diff --git a/demo/server/package.json b/demo/server/package.json new file mode 100644 index 0000000..199f034 --- /dev/null +++ b/demo/server/package.json @@ -0,0 +1,31 @@ +{ + "name": "wnba-demo-server", + "version": "1.0.0", + "description": "", + "main": "dist/index.js", + "type": "module", + "scripts": { + "postinstall": "npm run compile", + "compile": "tsc", + "start": "pnpm run compile && node ./dist/index.js" + }, + "license": "MIT", + "dependencies": { + "@apollo/server": "^4.0.0", + "@graphql-tools/schema": "^9.0.13", + "body-parser": "^1.20.2", + "cors": "^2.8.5", + "express": "^4.17.1", + "graphql": "^16.6.0", + "graphql-subscriptions": "^1.2.1", + "graphql-ws": "^5.5.5", + "typescript": "^4.7.4", + "ws": "^8.4.2" + }, + "devDependencies": { + "@types/cors": "^2.8.13", + "@types/node": "^18.6.3", + "@types/ws": "^8.2.2" + }, + "keywords": [] +} diff --git a/demo/server/pnpm-lock.yaml b/demo/server/pnpm-lock.yaml new file mode 100644 index 0000000..0b4b034 --- /dev/null +++ b/demo/server/pnpm-lock.yaml @@ -0,0 +1,1179 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@apollo/server': + specifier: ^4.0.0 + version: 4.11.0(graphql@16.9.0) + '@graphql-tools/schema': + specifier: ^9.0.13 + version: 9.0.19(graphql@16.9.0) + body-parser: + specifier: ^1.20.2 + version: 1.20.2 + cors: + specifier: ^2.8.5 + version: 2.8.5 + express: + specifier: ^4.17.1 + version: 4.19.2 + graphql: + specifier: ^16.6.0 + version: 16.9.0 + graphql-subscriptions: + specifier: ^1.2.1 + version: 1.2.1(graphql@16.9.0) + graphql-ws: + specifier: ^5.5.5 + version: 5.16.0(graphql@16.9.0) + typescript: + specifier: ^4.7.4 + version: 4.9.5 + ws: + specifier: ^8.4.2 + version: 8.18.0 + devDependencies: + '@types/cors': + specifier: ^2.8.13 + version: 2.8.17 + '@types/node': + specifier: ^18.6.3 + version: 18.19.47 + '@types/ws': + specifier: ^8.2.2 + version: 8.5.12 + +packages: + + '@apollo/cache-control-types@1.0.3': + resolution: {integrity: sha512-F17/vCp7QVwom9eG7ToauIKdAxpSoadsJnqIfyryLFSkLSOEqu+eC5Z3N8OXcUVStuOMcNHlyraRsA6rRICu4g==} + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/protobufjs@1.2.7': + resolution: {integrity: sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==} + hasBin: true + + '@apollo/server-gateway-interface@1.1.1': + resolution: {integrity: sha512-pGwCl/po6+rxRmDMFgozKQo2pbsSwE91TpsDBAOgf74CRDPXHHtM88wbwjab0wMMZh95QfR45GGyDIdhY24bkQ==} + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/server@4.11.0': + resolution: {integrity: sha512-SWDvbbs0wl2zYhKG6aGLxwTJ72xpqp0awb2lotNpfezd9VcAvzaUizzKQqocephin2uMoaA8MguoyBmgtPzNWw==} + engines: {node: '>=14.16.0'} + peerDependencies: + graphql: ^16.6.0 + + '@apollo/usage-reporting-protobuf@4.1.1': + resolution: {integrity: sha512-u40dIUePHaSKVshcedO7Wp+mPiZsaU6xjv9J+VyxpoU/zL6Jle+9zWeG98tr/+SZ0nZ4OXhrbb8SNr0rAPpIDA==} + + '@apollo/utils.createhash@2.0.1': + resolution: {integrity: sha512-fQO4/ZOP8LcXWvMNhKiee+2KuKyqIcfHrICA+M4lj/h/Lh1H10ICcUtk6N/chnEo5HXu0yejg64wshdaiFitJg==} + engines: {node: '>=14'} + + '@apollo/utils.dropunuseddefinitions@2.0.1': + resolution: {integrity: sha512-EsPIBqsSt2BwDsv8Wu76LK5R1KtsVkNoO4b0M5aK0hx+dGg9xJXuqlr7Fo34Dl+y83jmzn+UvEW+t1/GP2melA==} + engines: {node: '>=14'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.fetcher@2.0.1': + resolution: {integrity: sha512-jvvon885hEyWXd4H6zpWeN3tl88QcWnHp5gWF5OPF34uhvoR+DFqcNxs9vrRaBBSY3qda3Qe0bdud7tz2zGx1A==} + engines: {node: '>=14'} + + '@apollo/utils.isnodelike@2.0.1': + resolution: {integrity: sha512-w41XyepR+jBEuVpoRM715N2ZD0xMD413UiJx8w5xnAZD2ZkSJnMJBoIzauK83kJpSgNuR6ywbV29jG9NmxjK0Q==} + engines: {node: '>=14'} + + '@apollo/utils.keyvaluecache@2.1.1': + resolution: {integrity: sha512-qVo5PvUUMD8oB9oYvq4ViCjYAMWnZ5zZwEjNF37L2m1u528x5mueMlU+Cr1UinupCgdB78g+egA1G98rbJ03Vw==} + engines: {node: '>=14'} + + '@apollo/utils.logger@2.0.1': + resolution: {integrity: sha512-YuplwLHaHf1oviidB7MxnCXAdHp3IqYV8n0momZ3JfLniae92eYqMIx+j5qJFX6WKJPs6q7bczmV4lXIsTu5Pg==} + engines: {node: '>=14'} + + '@apollo/utils.printwithreducedwhitespace@2.0.1': + resolution: {integrity: sha512-9M4LUXV/fQBh8vZWlLvb/HyyhjJ77/I5ZKu+NBWV/BmYGyRmoEP9EVAy7LCVoY3t8BDcyCAGfxJaLFCSuQkPUg==} + engines: {node: '>=14'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.removealiases@2.0.1': + resolution: {integrity: sha512-0joRc2HBO4u594Op1nev+mUF6yRnxoUH64xw8x3bX7n8QBDYdeYgY4tF0vJReTy+zdn2xv6fMsquATSgC722FA==} + engines: {node: '>=14'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.sortast@2.0.1': + resolution: {integrity: sha512-eciIavsWpJ09za1pn37wpsCGrQNXUhM0TktnZmHwO+Zy9O4fu/WdB4+5BvVhFiZYOXvfjzJUcc+hsIV8RUOtMw==} + engines: {node: '>=14'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.stripsensitiveliterals@2.0.1': + resolution: {integrity: sha512-QJs7HtzXS/JIPMKWimFnUMK7VjkGQTzqD9bKD1h3iuPAqLsxd0mUNVbkYOPTsDhUKgcvUOfOqOJWYohAKMvcSA==} + engines: {node: '>=14'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.usagereporting@2.1.0': + resolution: {integrity: sha512-LPSlBrn+S17oBy5eWkrRSGb98sWmnEzo3DPTZgp8IQc8sJe0prDgDuppGq4NeQlpoqEHz0hQeYHAOA0Z3aQsxQ==} + engines: {node: '>=14'} + peerDependencies: + graphql: 14.x || 15.x || 16.x + + '@apollo/utils.withrequired@2.0.1': + resolution: {integrity: sha512-YBDiuAX9i1lLc6GeTy1m7DGLFn/gMnvXqlalOIMjM7DeOgIacEjjfwPqb0M1CQ2v11HhR15d1NmxJoRCfrNqcA==} + engines: {node: '>=14'} + + '@graphql-tools/merge@8.4.2': + resolution: {integrity: sha512-XbrHAaj8yDuINph+sAfuq3QCZ/tKblrTLOpirK0+CAgNlZUCHs0Fa+xtMUURgwCVThLle1AF7svJCxFizygLsw==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/schema@9.0.19': + resolution: {integrity: sha512-oBRPoNBtCkk0zbUsyP4GaIzCt8C0aCI4ycIRUL67KK5pOHljKLBBtGT+Jr6hkzA74C8Gco8bpZPe7aWFjiaK2w==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/utils@9.2.1': + resolution: {integrity: sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-typed-document-node/core@3.2.0': + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@types/body-parser@1.19.5': + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/cors@2.8.17': + resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} + + '@types/express-serve-static-core@4.19.5': + resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} + + '@types/express@4.17.21': + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + + '@types/http-errors@2.0.4': + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + + '@types/long@4.0.2': + resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/node-fetch@2.6.11': + resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} + + '@types/node@18.19.47': + resolution: {integrity: sha512-1f7dB3BL/bpd9tnDJrrHb66Y+cVrhxSOTGorRNdHwYTUlTay3HuTDPKo9a/4vX9pMQkhYBcAbL4jQdNlhCFP9A==} + + '@types/qs@6.9.15': + resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/send@0.17.4': + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + + '@types/serve-static@1.15.7': + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + + '@types/ws@8.5.12': + resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + async-retry@1.3.3: + resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + body-parser@1.20.2: + resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + express@4.19.2: + resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} + engines: {node: '>= 0.10.0'} + + finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graphql-subscriptions@1.2.1: + resolution: {integrity: sha512-95yD/tKi24q8xYa7Q9rhQN16AYj5wPbrb8tmHGM3WRc9EBmWrG/0kkMl+tQG8wcEuE9ibR4zyOM31p5Sdr2v4g==} + peerDependencies: + graphql: ^0.10.5 || ^0.11.3 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + + graphql-ws@5.16.0: + resolution: {integrity: sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A==} + engines: {node: '>=10'} + peerDependencies: + graphql: '>=0.11 <=16' + + graphql@16.9.0: + resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + iterall@1.3.0: + resolution: {integrity: sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + loglevel@1.9.1: + resolution: {integrity: sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==} + engines: {node: '>= 0.6.0'} + + long@4.0.0: + resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + node-abort-controller@3.1.1: + resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + + serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + value-or-promise@1.0.12: + resolution: {integrity: sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==} + engines: {node: '>=12'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + +snapshots: + + '@apollo/cache-control-types@1.0.3(graphql@16.9.0)': + dependencies: + graphql: 16.9.0 + + '@apollo/protobufjs@1.2.7': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/long': 4.0.2 + long: 4.0.0 + + '@apollo/server-gateway-interface@1.1.1(graphql@16.9.0)': + dependencies: + '@apollo/usage-reporting-protobuf': 4.1.1 + '@apollo/utils.fetcher': 2.0.1 + '@apollo/utils.keyvaluecache': 2.1.1 + '@apollo/utils.logger': 2.0.1 + graphql: 16.9.0 + + '@apollo/server@4.11.0(graphql@16.9.0)': + dependencies: + '@apollo/cache-control-types': 1.0.3(graphql@16.9.0) + '@apollo/server-gateway-interface': 1.1.1(graphql@16.9.0) + '@apollo/usage-reporting-protobuf': 4.1.1 + '@apollo/utils.createhash': 2.0.1 + '@apollo/utils.fetcher': 2.0.1 + '@apollo/utils.isnodelike': 2.0.1 + '@apollo/utils.keyvaluecache': 2.1.1 + '@apollo/utils.logger': 2.0.1 + '@apollo/utils.usagereporting': 2.1.0(graphql@16.9.0) + '@apollo/utils.withrequired': 2.0.1 + '@graphql-tools/schema': 9.0.19(graphql@16.9.0) + '@types/express': 4.17.21 + '@types/express-serve-static-core': 4.19.5 + '@types/node-fetch': 2.6.11 + async-retry: 1.3.3 + cors: 2.8.5 + express: 4.19.2 + graphql: 16.9.0 + loglevel: 1.9.1 + lru-cache: 7.18.3 + negotiator: 0.6.3 + node-abort-controller: 3.1.1 + node-fetch: 2.7.0 + uuid: 9.0.1 + whatwg-mimetype: 3.0.0 + transitivePeerDependencies: + - encoding + - supports-color + + '@apollo/usage-reporting-protobuf@4.1.1': + dependencies: + '@apollo/protobufjs': 1.2.7 + + '@apollo/utils.createhash@2.0.1': + dependencies: + '@apollo/utils.isnodelike': 2.0.1 + sha.js: 2.4.11 + + '@apollo/utils.dropunuseddefinitions@2.0.1(graphql@16.9.0)': + dependencies: + graphql: 16.9.0 + + '@apollo/utils.fetcher@2.0.1': {} + + '@apollo/utils.isnodelike@2.0.1': {} + + '@apollo/utils.keyvaluecache@2.1.1': + dependencies: + '@apollo/utils.logger': 2.0.1 + lru-cache: 7.18.3 + + '@apollo/utils.logger@2.0.1': {} + + '@apollo/utils.printwithreducedwhitespace@2.0.1(graphql@16.9.0)': + dependencies: + graphql: 16.9.0 + + '@apollo/utils.removealiases@2.0.1(graphql@16.9.0)': + dependencies: + graphql: 16.9.0 + + '@apollo/utils.sortast@2.0.1(graphql@16.9.0)': + dependencies: + graphql: 16.9.0 + lodash.sortby: 4.7.0 + + '@apollo/utils.stripsensitiveliterals@2.0.1(graphql@16.9.0)': + dependencies: + graphql: 16.9.0 + + '@apollo/utils.usagereporting@2.1.0(graphql@16.9.0)': + dependencies: + '@apollo/usage-reporting-protobuf': 4.1.1 + '@apollo/utils.dropunuseddefinitions': 2.0.1(graphql@16.9.0) + '@apollo/utils.printwithreducedwhitespace': 2.0.1(graphql@16.9.0) + '@apollo/utils.removealiases': 2.0.1(graphql@16.9.0) + '@apollo/utils.sortast': 2.0.1(graphql@16.9.0) + '@apollo/utils.stripsensitiveliterals': 2.0.1(graphql@16.9.0) + graphql: 16.9.0 + + '@apollo/utils.withrequired@2.0.1': {} + + '@graphql-tools/merge@8.4.2(graphql@16.9.0)': + dependencies: + '@graphql-tools/utils': 9.2.1(graphql@16.9.0) + graphql: 16.9.0 + tslib: 2.7.0 + + '@graphql-tools/schema@9.0.19(graphql@16.9.0)': + dependencies: + '@graphql-tools/merge': 8.4.2(graphql@16.9.0) + '@graphql-tools/utils': 9.2.1(graphql@16.9.0) + graphql: 16.9.0 + tslib: 2.7.0 + value-or-promise: 1.0.12 + + '@graphql-tools/utils@9.2.1(graphql@16.9.0)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.9.0) + graphql: 16.9.0 + tslib: 2.7.0 + + '@graphql-typed-document-node/core@3.2.0(graphql@16.9.0)': + dependencies: + graphql: 16.9.0 + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + + '@types/body-parser@1.19.5': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 18.19.47 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 18.19.47 + + '@types/cors@2.8.17': + dependencies: + '@types/node': 18.19.47 + + '@types/express-serve-static-core@4.19.5': + dependencies: + '@types/node': 18.19.47 + '@types/qs': 6.9.15 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + + '@types/express@4.17.21': + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.19.5 + '@types/qs': 6.9.15 + '@types/serve-static': 1.15.7 + + '@types/http-errors@2.0.4': {} + + '@types/long@4.0.2': {} + + '@types/mime@1.3.5': {} + + '@types/node-fetch@2.6.11': + dependencies: + '@types/node': 18.19.47 + form-data: 4.0.0 + + '@types/node@18.19.47': + dependencies: + undici-types: 5.26.5 + + '@types/qs@6.9.15': {} + + '@types/range-parser@1.2.7': {} + + '@types/send@0.17.4': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 18.19.47 + + '@types/serve-static@1.15.7': + dependencies: + '@types/http-errors': 2.0.4 + '@types/node': 18.19.47 + '@types/send': 0.17.4 + + '@types/ws@8.5.12': + dependencies: + '@types/node': 18.19.47 + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + array-flatten@1.1.1: {} + + async-retry@1.3.3: + dependencies: + retry: 0.13.1 + + asynckit@0.4.0: {} + + body-parser@1.20.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + bytes@3.1.2: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + cookie-signature@1.0.6: {} + + cookie@0.6.0: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + destroy@1.2.0: {} + + ee-first@1.1.1: {} + + encodeurl@1.0.2: {} + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + escape-html@1.0.3: {} + + etag@1.8.1: {} + + express@4.19.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.2 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.6.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + finalhandler@1.2.0: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + function-bind@1.1.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graphql-subscriptions@1.2.1(graphql@16.9.0): + dependencies: + graphql: 16.9.0 + iterall: 1.3.0 + + graphql-ws@5.16.0(graphql@16.9.0): + dependencies: + graphql: 16.9.0 + + graphql@16.9.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + inherits@2.0.4: {} + + ipaddr.js@1.9.1: {} + + iterall@1.3.0: {} + + lodash.sortby@4.7.0: {} + + loglevel@1.9.1: {} + + long@4.0.0: {} + + lru-cache@7.18.3: {} + + media-typer@0.3.0: {} + + merge-descriptors@1.0.1: {} + + methods@1.1.2: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + negotiator@0.6.3: {} + + node-abort-controller@3.1.1: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + object-assign@4.1.1: {} + + object-inspect@1.13.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + parseurl@1.3.3: {} + + path-to-regexp@0.1.7: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + qs@6.11.0: + dependencies: + side-channel: 1.0.6 + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + retry@0.13.1: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + send@0.18.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serve-static@1.15.0: + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + sha.js@2.4.11: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + statuses@2.0.1: {} + + toidentifier@1.0.1: {} + + tr46@0.0.3: {} + + tslib@2.7.0: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typescript@4.9.5: {} + + undici-types@5.26.5: {} + + unpipe@1.0.0: {} + + utils-merge@1.0.1: {} + + uuid@9.0.1: {} + + value-or-promise@1.0.12: {} + + vary@1.1.2: {} + + webidl-conversions@3.0.1: {} + + whatwg-mimetype@3.0.0: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + ws@8.18.0: {} diff --git a/demo/server/src/index.ts b/demo/server/src/index.ts new file mode 100644 index 0000000..5f6b304 --- /dev/null +++ b/demo/server/src/index.ts @@ -0,0 +1,196 @@ +import { ApolloServer } from "@apollo/server"; +import { expressMiddleware } from "@apollo/server/express4"; +import { ApolloServerPluginDrainHttpServer } from "@apollo/server/plugin/drainHttpServer"; +import express from "express"; +import { createServer } from "http"; +import { makeExecutableSchema } from "@graphql-tools/schema"; +import { WebSocketServer } from "ws"; +import { useServer } from "graphql-ws/lib/use/ws"; +import { PubSub } from "graphql-subscriptions"; +import typeDefs from "../../../.storybook/stories/schemas/wnba.graphql"; +import bodyParser from "body-parser"; +import cors from "cors"; + +const PORT = 4000; +const pubsub = new PubSub(); + +const coaches = [ + { + id: "1", + name: "Sandy Brondello", + }, + { + id: "2", + name: "Becky Hammon", + }, + { + id: "3", + name: "Curt Miller", + }, +]; + +const teams = [ + { + id: "1", + name: "New York Liberty", + wins: 26, + losses: 6, + }, + { + id: "2", + name: "Las Vegas Aces", + wins: 18, + losses: 12, + }, + { + id: "3", + name: "Los Angeles Sparks", + wins: 7, + losses: 24, + }, + { + id: "4", + name: "Atlanta Dream", + wins: 10, + losses: 20, + }, + { + id: "5", + name: "Chicago Sky", + wins: 11, + losses: 19, + }, + { + id: "6", + name: "Connecticut Sun", + wins: 22, + losses: 8, + }, + { + id: "7", + name: "Indiana Fever", + wins: 15, + losses: 16, + }, + { + id: "8", + name: "Washington Mystics", + wins: 9, + losses: 22, + }, + { + id: "9", + name: "Dallas Wings", + wins: 8, + losses: 22, + }, + { + id: "10", + name: "Minnesota Lynx", + wins: 23, + losses: 8, + }, + { + id: "11", + name: "Phoenix Mercury", + wins: 16, + losses: 16, + }, + { + id: "12", + name: "Seattle Storm", + wins: 19, + losses: 11, + }, +]; + +let currentTeam = "1"; + +// Resolver map +const resolvers = { + Query: { + team(_parent, { id }) { + return teams.find((team) => team.id === (id || currentTeam)); + }, + teams() { + return teams; + }, + coaches() { + return coaches; + }, + }, + Subscription: { + numberIncremented: { + subscribe: () => pubsub.asyncIterator(["NUMBER_INCREMENTED"]), + }, + }, + Mutation: { + setCurrentTeam(_parent, { team }) { + currentTeam = team; + return teams.find((t) => t.id === team); + }, + }, +}; + +// Create schema, which will be used separately by ApolloServer and +// the WebSocket server. +const schema = makeExecutableSchema({ typeDefs, resolvers }); + +// Create an Express app and HTTP server; we will attach the WebSocket +// server and the ApolloServer to this HTTP server. +const app = express(); +const httpServer = createServer(app); + +// Set up WebSocket server. +const wsServer = new WebSocketServer({ + server: httpServer, + path: "/graphql", +}); +const serverCleanup = useServer({ schema }, wsServer); + +// Set up ApolloServer. +const server = new ApolloServer({ + schema, + plugins: [ + // Proper shutdown for the HTTP server. + ApolloServerPluginDrainHttpServer({ httpServer }), + + // Proper shutdown for the WebSocket server. + { + async serverWillStart() { + return { + async drainServer() { + await serverCleanup.dispose(); + }, + }; + }, + }, + ], +}); + +await server.start(); +app.use( + "/graphql", + cors(), + bodyParser.json(), + expressMiddleware(server), +); + +// Now that our HTTP server is fully set up, actually listen. +httpServer.listen(PORT, () => { + console.log(`🚀 Query endpoint ready at http://localhost:${PORT}/graphql`); + console.log( + `🚀 Subscription endpoint ready at ws://localhost:${PORT}/graphql`, + ); +}); + +// In the background, increment a number every second and notify subscribers when it changes. +let currentNumber = 0; +function incrementNumber() { + currentNumber++; + pubsub.publish("NUMBER_INCREMENTED", { numberIncremented: currentNumber }); + setTimeout(incrementNumber, 1000); +} + +// Start incrementing +incrementNumber(); diff --git a/demo/server/tsconfig.json b/demo/server/tsconfig.json new file mode 100644 index 0000000..4660de0 --- /dev/null +++ b/demo/server/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "rootDirs": ["src"], + "outDir": "dist", + "lib": ["es2020"], + "target": "es2020", + "module": "esnext", + "moduleResolution": "node", + "esModuleInterop": true, + "types": ["node"], + "skipLibCheck": true + }, + "include": ["../../graphql.d.ts"] +} diff --git a/jest.config.cjs b/jest.config.cjs index fc390ea..9469a74 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -2,6 +2,9 @@ module.exports = { globals: { "globalThis.__DEV__": JSON.stringify(true), }, + moduleNameMapper: { + "\\.svg": "/src/__tests__/mocks/svg.js", + }, extensionsToTreatAsEsm: [".ts", ".tsx"], testEnvironment: "jsdom", roots: ["/src/__tests__"], diff --git a/package.json b/package.json index 0c2bf7b..ad25ca2 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,8 @@ "@storybook/react-vite": "8.2.9", "@storybook/test": "8.2.9", "@storybook/test-runner": "0.19.1", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0", "@tailwindcss/aspect-ratio": "0.4.2", "@testing-library/dom": "10.4.0", "@testing-library/jest-dom": "6.5.0", @@ -87,6 +89,7 @@ "eslint": "8.57.0", "eslint-plugin-storybook": "0.8.0", "graphql": "16.9.0", + "graphql-ws": "5.16.0", "http-server": "14.1.1", "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", @@ -106,11 +109,13 @@ "ts-jest": "29.2.5", "ts-jest-resolver": "2.0.1", "tsup": "8.2.4", + "tw-colors": "3.3.1", "typescript": "5.5.4", "undici": "6.19.8", "vite": "5.4.3", "vite-plugin-graphql-loader": "4.0.4", "vite-plugin-relay": "2.1.0", + "vite-plugin-svgr": "4.2.0", "vitest": "2.0.5", "wait-on": "8.0.0" }, @@ -137,7 +142,7 @@ }, "relay": { "src": "./.storybook/stories/components/relay", - "schema": "./.storybook/stories/ecommerce-schema.graphql", + "schema": "./.storybook/stories/schemas/ecommerce.graphql", "language": "typescript", "eagerEsModules": true, "exclude": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a6eeb36..37ff3ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,7 +39,7 @@ dependencies: devDependencies: '@apollo/client': specifier: 3.11.6 - version: 3.11.6(@types/react@18.3.5)(graphql@16.9.0)(react-dom@18.3.1)(react@18.3.1) + version: 3.11.6(@types/react@18.3.5)(graphql-ws@5.16.0)(graphql@16.9.0)(react-dom@18.3.1)(react@18.3.1) '@apollo/tailwind-preset': specifier: 0.1.14 version: 0.1.14(tailwindcss@3.4.10) @@ -91,6 +91,12 @@ devDependencies: '@storybook/test-runner': specifier: 0.19.1 version: 0.19.1(@types/node@22.5.2)(storybook@8.2.9) + '@svgr/plugin-jsx': + specifier: 8.1.0 + version: 8.1.0(@svgr/core@8.1.0) + '@svgr/plugin-svgo': + specifier: 8.1.0 + version: 8.1.0(@svgr/core@8.1.0)(typescript@5.5.4) '@tailwindcss/aspect-ratio': specifier: 0.4.2 version: 0.4.2(tailwindcss@3.4.10) @@ -145,6 +151,9 @@ devDependencies: graphql: specifier: 16.9.0 version: 16.9.0 + graphql-ws: + specifier: 5.16.0 + version: 5.16.0(graphql@16.9.0) http-server: specifier: 14.1.1 version: 14.1.1 @@ -202,6 +211,9 @@ devDependencies: tsup: specifier: 8.2.4 version: 8.2.4(@swc/core@1.7.22)(postcss@8.4.44)(typescript@5.5.4) + tw-colors: + specifier: 3.3.1 + version: 3.3.1(tailwindcss@3.4.10) typescript: specifier: 5.5.4 version: 5.5.4 @@ -217,6 +229,9 @@ devDependencies: vite-plugin-relay: specifier: 2.1.0 version: 2.1.0(babel-plugin-relay@17.0.0)(vite@5.4.3) + vite-plugin-svgr: + specifier: 4.2.0 + version: 4.2.0(typescript@5.5.4)(vite@5.4.3) vitest: specifier: 2.0.5 version: 2.0.5(@types/node@22.5.2)(jsdom@25.0.0) @@ -247,7 +262,7 @@ packages: resolution: {integrity: sha512-VsFmaE7ReXOslqSZXuYmIguL0sBIyEjpuceNpNIahJExYbqooUw+bbipZ6MpQXHdyD5eez7XE1meqOGM25GewA==} dev: true - /@apollo/client@3.11.6(@types/react@18.3.5)(graphql@16.9.0)(react-dom@18.3.1)(react@18.3.1): + /@apollo/client@3.11.6(@types/react@18.3.5)(graphql-ws@5.16.0)(graphql@16.9.0)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-7Yh71ZhkVwJ+7L5lUDw3H7phfn/KCD++UvZpMM+jiKzQNhocGOuIhSTnw6vGds9HwjWfpUvSwX46v/5XVcTzrw==} peerDependencies: graphql: ^15.0.0 || ^16.0.0 @@ -271,6 +286,7 @@ packages: '@wry/trie': 0.5.0 graphql: 16.9.0 graphql-tag: 2.12.6(graphql@16.9.0) + graphql-ws: 5.16.0(graphql@16.9.0) hoist-non-react-statics: 3.3.2 optimism: 0.18.0 prop-types: 15.8.1 @@ -4299,6 +4315,146 @@ packages: storybook: 8.2.9 dev: true + /@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.25.2): + resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.25.2 + dev: true + + /@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.25.2): + resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.25.2 + dev: true + + /@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.25.2): + resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.25.2 + dev: true + + /@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.25.2): + resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.25.2 + dev: true + + /@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.25.2): + resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.25.2 + dev: true + + /@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.25.2): + resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.25.2 + dev: true + + /@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.25.2): + resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.25.2 + dev: true + + /@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.25.2): + resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.25.2 + dev: true + + /@svgr/babel-preset@8.1.0(@babel/core@7.25.2): + resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.25.2 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.25.2) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.25.2) + dev: true + + /@svgr/core@8.1.0(typescript@5.5.4): + resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==} + engines: {node: '>=14'} + dependencies: + '@babel/core': 7.25.2 + '@svgr/babel-preset': 8.1.0(@babel/core@7.25.2) + camelcase: 6.3.0 + cosmiconfig: 8.3.6(typescript@5.5.4) + snake-case: 3.0.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@svgr/hast-util-to-babel-ast@8.0.0: + resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==} + engines: {node: '>=14'} + dependencies: + '@babel/types': 7.25.6 + entities: 4.5.0 + dev: true + + /@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0): + resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + dependencies: + '@babel/core': 7.25.2 + '@svgr/babel-preset': 8.1.0(@babel/core@7.25.2) + '@svgr/core': 8.1.0(typescript@5.5.4) + '@svgr/hast-util-to-babel-ast': 8.0.0 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0)(typescript@5.5.4): + resolution: {integrity: sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + dependencies: + '@svgr/core': 8.1.0(typescript@5.5.4) + cosmiconfig: 8.3.6(typescript@5.5.4) + deepmerge: 4.3.1 + svgo: 3.3.2 + transitivePeerDependencies: + - typescript + dev: true + /@swc/core-darwin-arm64@1.7.22: resolution: {integrity: sha512-B2Bh2W+C7ALdGwDxRWAJ+UtNExfozvwyayGiNkbR3wmDKXXeQfhGM5MK+QYUWKu7UQ6ATq69OyZrxofDobKUug==} engines: {node: '>=10'} @@ -4556,6 +4712,11 @@ packages: engines: {node: '>= 10'} dev: true + /@trysound/sax@0.2.0: + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + dev: true + /@tsconfig/recommended@1.0.7: resolution: {integrity: sha512-xiNMgCuoy4mCL4JTywk9XFs5xpRUcKxtWEcMR6FNMtsgewYTIgIR+nvlP4A4iRCAzRsHMnPhvTRrzp4AGcRTEA==} dev: true @@ -5828,6 +5989,10 @@ packages: - supports-color dev: true + /boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -6257,6 +6422,21 @@ packages: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true + /color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + dev: true + + /color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + dev: true + /colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} dev: true @@ -6287,6 +6467,11 @@ packages: engines: {node: '>= 6'} dev: true + /commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: true + /commands-events@1.0.4: resolution: {integrity: sha512-HdP/+1Anoc7z+6L2h7nd4Imz54+LW+BjMGt30riBZrZ3ZeP/8el93wD8Jj8ltAaqVslqNgjX6qlhSBJwuDSmpg==} dependencies: @@ -6570,6 +6755,37 @@ packages: util.promisify: 1.0.0 dev: true + /css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + dev: true + + /css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.0 + dev: true + + /css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.0 + dev: true + + /css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + dev: true + /css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} dev: true @@ -6580,6 +6796,13 @@ packages: hasBin: true dev: true + /csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + dependencies: + css-tree: 2.2.1 + dev: true + /cssom@0.3.8: resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} dev: true @@ -6885,6 +7108,14 @@ packages: entities: 2.2.0 dev: true + /dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + dev: true + /domelementtype@1.3.1: resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} dev: true @@ -6907,6 +7138,13 @@ packages: domelementtype: 1.3.1 dev: true + /domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + dependencies: + domelementtype: 2.3.0 + dev: true + /domutils@1.7.0: resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} dependencies: @@ -6914,6 +7152,14 @@ packages: domelementtype: 1.3.1 dev: true + /domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dev: true + /dot-case@3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} dependencies: @@ -7779,6 +8025,11 @@ packages: rimraf: 3.0.2 dev: true + /flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + dev: true + /flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} dev: true @@ -8607,6 +8858,10 @@ packages: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} dev: true + /is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + dev: true + /is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: @@ -9856,6 +10111,10 @@ packages: resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} dev: true + /lodash.foreach@4.5.0: + resolution: {integrity: sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==} + dev: true + /lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} dev: true @@ -10053,6 +10312,14 @@ packages: react: 18.3.1 dev: true + /mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + dev: true + + /mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + dev: true + /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -10412,6 +10679,12 @@ packages: path-key: 4.0.0 dev: true + /nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: true + /nullthrows@1.1.1: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} dev: true @@ -11903,6 +12176,12 @@ packages: resolution: {integrity: sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==} dev: true + /simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + dependencies: + is-arrayish: 0.3.2 + dev: true + /sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} dev: true @@ -12291,6 +12570,24 @@ packages: engines: {node: '>= 0.4'} dev: true + /svg-parser@2.0.4: + resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + dev: true + + /svgo@3.3.2: + resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 5.1.0 + css-tree: 2.3.1 + css-what: 6.1.0 + csso: 5.0.5 + picocolors: 1.0.1 + dev: true + /swap-case@2.0.2: resolution: {integrity: sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==} dependencies: @@ -12707,6 +13004,17 @@ packages: typescript: 5.5.4 dev: true + /tw-colors@3.3.1(tailwindcss@3.4.10): + resolution: {integrity: sha512-PH6NShNtDzPCm6zjl0SZe3kmdYSfDS7Sk4mWa9+KzaeSH1ZmpLRrBjZoBJKaFcDB3o7iuFPPg9+HtW05pGPQyQ==} + peerDependencies: + tailwindcss: '>=3.0.0' + dependencies: + color: 4.2.3 + flat: 5.0.2 + lodash.foreach: 4.5.0 + tailwindcss: 3.4.10 + dev: true + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -13127,6 +13435,21 @@ packages: - supports-color dev: true + /vite-plugin-svgr@4.2.0(typescript@5.5.4)(vite@5.4.3): + resolution: {integrity: sha512-SC7+FfVtNQk7So0XMjrrtLAbEC8qjFPifyD7+fs/E6aaNdVde6umlVVh0QuwDLdOMu7vp5RiGFsB70nj5yo0XA==} + peerDependencies: + vite: ^2.6.0 || 3 || 4 || 5 + dependencies: + '@rollup/pluginutils': 5.1.0 + '@svgr/core': 8.1.0(typescript@5.5.4) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0) + vite: 5.4.3(@types/node@22.5.2) + transitivePeerDependencies: + - rollup + - supports-color + - typescript + dev: true + /vite@5.4.3(@types/node@22.5.2): resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==} engines: {node: ^18.0.0 || >=20.0.0} diff --git a/src/__tests__/handlers.test.tsx b/src/__tests__/handlers.test.tsx index 10b2969..345122c 100644 --- a/src/__tests__/handlers.test.tsx +++ b/src/__tests__/handlers.test.tsx @@ -10,10 +10,12 @@ import { App, AppWithDefer, makeClient, -} from "../../.storybook/stories/components/apollo-client/ApolloComponent.tsx"; -import { graphQLHandler, products } from "./mocks/handlers.js"; +} from "../../.storybook/stories/components/apollo-client/EcommerceExample.tsx"; +import { App as WNBAApp } from "../../.storybook/stories/components/apollo-client/WNBAExample.tsx"; +import { ecommerceHandler, products } from "./mocks/handlers.js"; import { createSchemaWithDefaultMocks } from "../handlers.ts"; -import githubTypeDefs from "../../.storybook/stories/github-schema.graphql"; +import githubTypeDefs from "../../.storybook/stories/schemas/github.graphql"; +import wnbaTypeDefs from "../../.storybook/stories/schemas/wnba.graphql"; import type { Resolvers } from "../__generated__/resolvers-types-github.ts"; describe("integration tests", () => { @@ -82,7 +84,7 @@ describe("integration tests", () => { }); }); it("can set a new schema via replaceSchema", async () => { - using _restore = graphQLHandler.withResolvers({ + using _restore = ecommerceHandler.withResolvers({ Query: { products: () => { return Array.from({ length: 6 }, (_element, id) => ({ @@ -125,7 +127,7 @@ describe("integration tests", () => { ).toHaveTextContent("Customers also purchased"), ); - expect(screen.getAllByTestId(/rating/i)[0]).toHaveTextContent("-"); + // expect(screen.getAllByTestId(/rating/i)[0]).toHaveTextContent("-"); expect(screen.getByText(/foo bar 1/i)).toBeInTheDocument(); await waitFor(() => { @@ -140,7 +142,7 @@ describe("integration tests", () => { // Usually, in Jest tests we want this to be 20ms (the default in Node // processes) so renders are *not* auto-batched, but in certain tests we may // want a shorter or longer delay before chunks or entire responses resolve - using _restore = graphQLHandler.replaceDelay(1); + using _restore = ecommerceHandler.replaceDelay(1); const client = makeClient(); @@ -175,6 +177,54 @@ describe("integration tests", () => { expect(screen.getByText(/beanie/i)).toBeInTheDocument(); }); }); + describe("mutations", () => { + it("uses the initial mock schema", async () => { + const schemaWithMocks = createSchemaWithDefaultMocks(wnbaTypeDefs, { + Query: { + team: () => { + return { + id: "1", + name: "New York Liberty", + }; + }, + teams: () => { + return [ + { + id: "1", + name: "New York Liberty", + }, + { + id: "2", + name: "Las Vegas Aces", + }, + ]; + }, + }, + }); + + using _restore = ecommerceHandler.replaceSchema(schemaWithMocks); + const client = makeClient(); + + render( + + Loading...}> + + + , + ); + + // The app kicks off the request and we see the initial loading indicator... + await waitFor(() => + expect( + screen.getByRole("heading", { name: /loading/i }), + ).toHaveTextContent("Loading..."), + ); + + await waitFor(() => + expect(screen.getByText("New York Liberty")).toBeInTheDocument(), + ); + }); + }); }); describe("integration tests with github schema", () => { @@ -203,7 +253,7 @@ describe("integration tests with github schema", () => { }, ); - using _restore = graphQLHandler.replaceSchema(schemaWithMocks); + using _restore = ecommerceHandler.replaceSchema(schemaWithMocks); const APP_QUERY: TypedDocumentNode<{ repository: { @@ -282,16 +332,16 @@ describe("integration tests with github schema", () => { describe("unit tests", () => { it("can roll back delay via disposable", () => { function innerFn() { - using _restore = graphQLHandler.replaceDelay(250); + using _restore = ecommerceHandler.replaceDelay(250); // @ts-expect-error intentionally accessing a property that has been // excluded from the type - expect(graphQLHandler.replaceDelay["currentDelay"]).toBe(250); + expect(ecommerceHandler.replaceDelay["currentDelay"]).toBe(250); } innerFn(); // @ts-expect-error intentionally accessing a property that has been // excluded from the type - expect(graphQLHandler.replaceDelay["currentDelay"]).toBe(20); + expect(ecommerceHandler.replaceDelay["currentDelay"]).toBe(20); }); }); diff --git a/src/__tests__/mocks/handlers.ts b/src/__tests__/mocks/handlers.ts index f802d3f..6ec8c40 100644 --- a/src/__tests__/mocks/handlers.ts +++ b/src/__tests__/mocks/handlers.ts @@ -1,11 +1,11 @@ import { createHandler } from "../../handlers.js"; -import typeDefs from "../../../.storybook/stories/ecommerce-schema.graphql"; +import ecommerceSchema from "../../../.storybook/stories/schemas/ecommerce.graphql"; import type { Resolvers } from "../../__generated__/resolvers-types-ecommerce.ts"; const products = ["beanie", "bottle", "cap", "onesie", "shirt", "socks"]; -const graphQLHandler = createHandler({ - typeDefs, +const ecommerceHandler = createHandler({ + typeDefs: ecommerceSchema, resolvers: { Query: { products: () => @@ -24,6 +24,6 @@ const graphQLHandler = createHandler({ }, }); -const handlers = [graphQLHandler]; +const handlers = [ecommerceHandler]; -export { graphQLHandler, handlers, products }; +export { handlers, products, ecommerceHandler }; diff --git a/src/__tests__/mocks/svg.ts b/src/__tests__/mocks/svg.ts new file mode 100644 index 0000000..86acdad --- /dev/null +++ b/src/__tests__/mocks/svg.ts @@ -0,0 +1,2 @@ +export default "div"; +export const ReactComponent = "div"; diff --git a/tsconfig.json b/tsconfig.json index de7bed9..57279a4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,5 +23,11 @@ "lib": ["es2022", "dom", "dom.iterable"], "types": ["@testing-library/jest-dom/jest-globals"] }, - "include": ["src", "global.d.ts", "graphql.d.ts", "setupTests.ts"] + "include": [ + "src", + "global.d.ts", + "graphql.d.ts", + "setupTests.ts", + ".storybook/vite-env.d.ts" + ] } diff --git a/vitest.config.ts b/vitest.config.ts index 56f1118..0652803 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,9 +1,10 @@ /// import { defineConfig } from "vite"; import { vitePluginGraphqlLoader } from "vite-plugin-graphql-loader"; +import svgr from "vite-plugin-svgr"; export default defineConfig({ - plugins: [vitePluginGraphqlLoader()], + plugins: [vitePluginGraphqlLoader(), svgr()], test: { include: ["**/*.test.tsx"], globals: true,