diff --git a/.changeset/poor-chairs-reflect.md b/.changeset/poor-chairs-reflect.md new file mode 100644 index 0000000..13b1253 --- /dev/null +++ b/.changeset/poor-chairs-reflect.md @@ -0,0 +1,17 @@ +--- +"saleor-app-emails-and-messages": patch +"saleor-app-data-importer": patch +"saleor-app-products-feed": patch +"saleor-app-monitoring": patch +"@saleor/apps-shared": patch +"saleor-app-invoices": patch +"saleor-app-klaviyo": patch +"saleor-app-search": patch +"saleor-app-slack": patch +"saleor-app-taxes": patch +"saleor-app-cms": patch +"saleor-app-crm": patch +--- + +Updated configuration and dependencies of GraphQL client - urql. +All applications use now unified config for creating the client. Also unused related packages has been removed. diff --git a/.changeset/stupid-insects-smash.md b/.changeset/stupid-insects-smash.md new file mode 100644 index 0000000..17761d0 --- /dev/null +++ b/.changeset/stupid-insects-smash.md @@ -0,0 +1,5 @@ +--- +"@saleor/apps-shared": patch +--- + +Added `createGraphQLClient` function to shared package. Can be used to create urql client instance with optional authorization. diff --git a/apps/cms/.graphqlrc.yml b/apps/cms/.graphqlrc.yml index ee7c7af..b0db306 100644 --- a/apps/cms/.graphqlrc.yml +++ b/apps/cms/.graphqlrc.yml @@ -10,7 +10,6 @@ extensions: plugins: - typescript - typescript-operations - - urql-introspection - typescript-urql: documentVariablePrefix: "Untyped" fragmentVariablePrefix: "Untyped" diff --git a/apps/cms/package.json b/apps/cms/package.json index 4e14423..dafacca 100644 --- a/apps/cms/package.json +++ b/apps/cms/package.json @@ -21,7 +21,7 @@ "@saleor/apps-shared": "workspace:*", "@saleor/macaw-ui": "^0.7.2", "@sentry/nextjs": "^7.43.0", - "@urql/exchange-auth": "^1.0.0", + "@urql/exchange-auth": "^2.1.4", "clsx": "^1.2.1", "graphql": "16.6.0", "graphql-tag": "^2.12.6", @@ -32,7 +32,7 @@ "react-dom": "18.2.0", "react-hook-form": "^7.39.1", "react-markdown": "^8.0.5", - "urql": "^3.0.3", + "urql": "^4.0.4", "usehooks-ts": "^2.9.1", "uuid": "^9.0.0", "vite": "4.3.9", @@ -45,7 +45,6 @@ "@graphql-codegen/typescript": "3.0.2", "@graphql-codegen/typescript-operations": "3.0.2", "@graphql-codegen/typescript-urql": "3.7.3", - "@graphql-codegen/urql-introspection": "2.2.1", "@graphql-typed-document-node/core": "3.2.0", "@testing-library/react": "^13.4.0", "@types/react": "18.2.5", diff --git a/apps/cms/src/lib/cms/client/metadata-execution.ts b/apps/cms/src/lib/cms/client/metadata-execution.ts index 709562e..0ab2b63 100644 --- a/apps/cms/src/lib/cms/client/metadata-execution.ts +++ b/apps/cms/src/lib/cms/client/metadata-execution.ts @@ -5,8 +5,8 @@ import { UpdateMetadataDocument, WebhookProductVariantFragment, } from "../../../../generated/graphql"; -import { createClient } from "../../graphql"; import { createCmsKeyForSaleorItem } from "./metadata"; +import { createGraphQLClient } from "@saleor/apps-shared"; type WebhookContext = Parameters["2"]; @@ -60,7 +60,7 @@ export const updateMetadata = async ({ cmsProviderInstanceIdsToDelete: Record; }) => { const { token, saleorApiUrl } = context.authData; - const apiClient = createClient(saleorApiUrl, async () => ({ token })); + const apiClient = createGraphQLClient({ saleorApiUrl, token }); await executeMetadataUpdateMutation({ apiClient, @@ -85,7 +85,7 @@ export const batchUpdateMetadata = async ({ variantCMSProviderInstanceIdsToDelete: ItemMetadataRecord[]; }) => { const { token, saleorApiUrl } = context.authData; - const apiClient = createClient(saleorApiUrl, async () => ({ token })); + const apiClient = createGraphQLClient({ saleorApiUrl, token }); const variantCMSProviderInstanceIdsToCreateMap = variantCMSProviderInstanceIdsToCreate.reduce( (acc, { id, cmsProviderInstanceIds }) => ({ diff --git a/apps/cms/src/lib/graphql.ts b/apps/cms/src/lib/graphql.ts deleted file mode 100644 index 9805875..0000000 --- a/apps/cms/src/lib/graphql.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { AuthConfig, authExchange } from "@urql/exchange-auth"; -import { - cacheExchange, - createClient as urqlCreateClient, - dedupExchange, - fetchExchange, -} from "urql"; - -interface IAuthState { - token: string; -} - -const getExchanges = (getAuth: AuthConfig["getAuth"]) => [ - dedupExchange, - cacheExchange, - authExchange({ - addAuthToOperation: ({ authState, operation }) => { - if (!authState || !authState?.token) { - return operation; - } - - const fetchOptions = - typeof operation.context.fetchOptions === "function" - ? operation.context.fetchOptions() - : operation.context.fetchOptions || {}; - - return { - ...operation, - context: { - ...operation.context, - fetchOptions: { - ...fetchOptions, - headers: { - ...fetchOptions.headers, - "Authorization-Bearer": authState.token, - }, - }, - }, - }; - }, - getAuth, - }), - fetchExchange, -]; - -export const createClient = (url: string, getAuth: AuthConfig["getAuth"]) => - urqlCreateClient({ - url, - exchanges: getExchanges(getAuth), - }); diff --git a/apps/cms/src/modules/cms/hooks/useQueryAllProducts.tsx b/apps/cms/src/modules/cms/hooks/useQueryAllProducts.tsx index fc0982e..ca48705 100644 --- a/apps/cms/src/modules/cms/hooks/useQueryAllProducts.tsx +++ b/apps/cms/src/modules/cms/hooks/useQueryAllProducts.tsx @@ -4,7 +4,7 @@ import { ProductsDataForImportDocument, ProductsDataForImportQuery, } from "../../../../generated/graphql"; -import { createClient } from "../../../lib/graphql"; +import { createGraphQLClient } from "@saleor/apps-shared"; const PER_PAGE = 100; @@ -32,7 +32,7 @@ export const useQueryAllProducts = (paused: boolean, channelSlug: string | null) } const token = appBridgeState.token; - const client = createClient(saleorApiUrl, () => Promise.resolve({ token })); + const client = createGraphQLClient({ saleorApiUrl, token }); if (!client) { return; diff --git a/apps/cms/src/pages/api/channels.ts b/apps/cms/src/pages/api/channels.ts index de48648..0049085 100644 --- a/apps/cms/src/pages/api/channels.ts +++ b/apps/cms/src/pages/api/channels.ts @@ -4,8 +4,8 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { saleorApp } from "../../../saleor-app"; import { CMSSchemaChannels, SingleChannelSchema } from "../../lib/cms/config"; -import { createClient } from "../../lib/graphql"; import { createSettingsManager } from "../../lib/metadata"; +import { createGraphQLClient } from "@saleor/apps-shared"; export type SettingsUpdateApiRequest = SingleChannelSchema; @@ -14,10 +14,12 @@ export interface ChannelsApiResponse { data?: CMSSchemaChannels; } -// todo: implement -// const obfuscateSecret = (secret: string) => { -// return "*".repeat(secret.length - 4) + secret.substring(secret.length - 4); -// }; +/* + * todo: implement + * const obfuscateSecret = (secret: string) => { + * return "*".repeat(secret.length - 4) + secret.substring(secret.length - 4); + * }; + */ const handler: NextProtectedApiHandler = async ( req: NextApiRequest, @@ -26,9 +28,10 @@ const handler: NextProtectedApiHandler = async ( ) => { const { authData } = context; - const client = createClient(authData.saleorApiUrl, async () => ({ + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, token: authData.token, - })); + }); const settingsManager = createSettingsManager(client); diff --git a/apps/cms/src/pages/api/ping-provider-instance.ts b/apps/cms/src/pages/api/ping-provider-instance.ts index 3ee4026..10d19da 100644 --- a/apps/cms/src/pages/api/ping-provider-instance.ts +++ b/apps/cms/src/pages/api/ping-provider-instance.ts @@ -2,11 +2,10 @@ import { NextProtectedApiHandler, createProtectedHandler } from "@saleor/app-sdk import { saleorApp } from "../../../saleor-app"; import type { NextApiRequest, NextApiResponse } from "next"; -import { createClient } from "../../lib/graphql"; import { createSettingsManager } from "../../lib/metadata"; import { getProviderInstancesSettings } from "../../lib/cms/client/settings"; import { pingProviderInstance } from "../../lib/cms/client/clients-execution"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; export interface ProviderInstancePingApiPayload { providerInstanceId: string; @@ -42,9 +41,11 @@ const handler: NextProtectedApiHandler = async ( }); } - const client = createClient(authData.saleorApiUrl, async () => ({ + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, token: authData.token, - })); + }); + const settingsManager = createSettingsManager(client); const providerInstancesSettingsParsed = await getProviderInstancesSettings(settingsManager); diff --git a/apps/cms/src/pages/api/provider-instances.ts b/apps/cms/src/pages/api/provider-instances.ts index e3e3492..80c88af 100644 --- a/apps/cms/src/pages/api/provider-instances.ts +++ b/apps/cms/src/pages/api/provider-instances.ts @@ -4,9 +4,9 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { saleorApp } from "../../../saleor-app"; import { CMSSchemaProviderInstances, SingleProviderSchema } from "../../lib/cms/config"; -import { createClient } from "../../lib/graphql"; import { createSettingsManager } from "../../lib/metadata"; import { generateUniqueId } from "../../modules/cms/utils"; +import { createGraphQLClient } from "@saleor/apps-shared"; export type SettingsUpdateApiRequest = SingleProviderSchema; @@ -15,10 +15,12 @@ export interface ProviderInstancesApiResponse { data?: CMSSchemaProviderInstances | SingleProviderSchema; } -// todo: implement -// const obfuscateSecret = (secret: string) => { -// return "*".repeat(secret.length - 4) + secret.substring(secret.length - 4); -// }; +/* + * todo: implement + * const obfuscateSecret = (secret: string) => { + * return "*".repeat(secret.length - 4) + secret.substring(secret.length - 4); + * }; + */ const handler: NextProtectedApiHandler = async ( req: NextApiRequest, @@ -27,9 +29,10 @@ const handler: NextProtectedApiHandler = async ( ) => { const { authData } = context; - const client = createClient(authData.saleorApiUrl, async () => ({ + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, token: authData.token, - })); + }); const settingsManager = createSettingsManager(client); diff --git a/apps/cms/src/pages/api/sync-products-variants.ts b/apps/cms/src/pages/api/sync-products-variants.ts index 02699f3..afda2f1 100644 --- a/apps/cms/src/pages/api/sync-products-variants.ts +++ b/apps/cms/src/pages/api/sync-products-variants.ts @@ -7,11 +7,10 @@ import { getChannelsSettings, getProviderInstancesSettings } from "../../lib/cms import { providersSchemaSet } from "../../lib/cms/config/providers"; import { cmsProviders, CMSProvider } from "../../lib/cms/providers"; -import { createClient } from "../../lib/graphql"; import { createSettingsManager } from "../../lib/metadata"; import { batchUpdateMetadata, MetadataRecord } from "../../lib/cms/client/metadata-execution"; import { CmsBatchOperations } from "../../lib/cms/types"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; export interface SyncProductsVariantsApiPayload { channelSlug: string; @@ -42,9 +41,10 @@ const handler: NextProtectedApiHandler = async ( logger.debug("Called endpoint sync-products-variants"); - const client = createClient(authData.saleorApiUrl, async () => ({ + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, token: authData.token, - })); + }); if (req.method !== "POST") { return res.status(405).json({ diff --git a/apps/cms/src/pages/api/webhooks/product-updated.ts b/apps/cms/src/pages/api/webhooks/product-updated.ts index 5fde6eb..c3fa080 100644 --- a/apps/cms/src/pages/api/webhooks/product-updated.ts +++ b/apps/cms/src/pages/api/webhooks/product-updated.ts @@ -9,10 +9,9 @@ import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata"; import { getChannelsSlugsFromSaleorItem } from "../../../lib/cms/client/channels"; import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client"; -import { createClient } from "../../../lib/graphql"; import { fetchProductVariantMetadata } from "../../../lib/metadata"; import { isAppWebhookIssuer } from "./_utils"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; export const config = { api: { @@ -79,9 +78,10 @@ export const handler: NextWebhookApiHandler ({ - token: token, - })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); const allCMSErrors: string[] = []; diff --git a/apps/cms/src/pages/api/webhooks/product-variant-created.ts b/apps/cms/src/pages/api/webhooks/product-variant-created.ts index c777ee7..27776d0 100644 --- a/apps/cms/src/pages/api/webhooks/product-variant-created.ts +++ b/apps/cms/src/pages/api/webhooks/product-variant-created.ts @@ -8,10 +8,9 @@ import { saleorApp } from "../../../../saleor-app"; import { getChannelsSlugsFromSaleorItem } from "../../../lib/cms/client/channels"; import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client"; -import { createClient } from "../../../lib/graphql"; import { fetchProductVariantMetadata } from "../../../lib/metadata"; import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; export const config = { api: { @@ -68,9 +67,10 @@ export const handler: NextWebhookApiHandler ({ - token: token, - })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); const productVariantChannels = getChannelsSlugsFromSaleorItem(productVariant); const productVariantMetadata = await fetchProductVariantMetadata(client, productVariant.id); diff --git a/apps/cms/src/pages/api/webhooks/product-variant-deleted.ts b/apps/cms/src/pages/api/webhooks/product-variant-deleted.ts index 6a2c59a..98d1de6 100644 --- a/apps/cms/src/pages/api/webhooks/product-variant-deleted.ts +++ b/apps/cms/src/pages/api/webhooks/product-variant-deleted.ts @@ -8,8 +8,7 @@ import { saleorApp } from "../../../../saleor-app"; import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata"; import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client"; -import { createClient } from "../../../lib/graphql"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; export const config = { api: { @@ -66,9 +65,10 @@ export const handler: NextWebhookApiHandler ({ - token: token, - })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); const productVariantCmsKeys = getCmsKeysFromSaleorItem(productVariant); const cmsOperations = await createCmsOperations({ diff --git a/apps/cms/src/pages/api/webhooks/product-variant-updated.ts b/apps/cms/src/pages/api/webhooks/product-variant-updated.ts index 3b4aba3..6439496 100644 --- a/apps/cms/src/pages/api/webhooks/product-variant-updated.ts +++ b/apps/cms/src/pages/api/webhooks/product-variant-updated.ts @@ -9,10 +9,9 @@ import { getCmsKeysFromSaleorItem } from "../../../lib/cms/client/metadata"; import { getChannelsSlugsFromSaleorItem } from "../../../lib/cms/client/channels"; import { createCmsOperations, executeCmsOperations, updateMetadata } from "../../../lib/cms/client"; -import { createClient } from "../../../lib/graphql"; import { fetchProductVariantMetadata } from "../../../lib/metadata"; import { isAppWebhookIssuer } from "./_utils"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; export const config = { api: { @@ -80,9 +79,10 @@ export const handler: NextWebhookApiHandler ({ - token: token, - })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); const productVariantChannels = getChannelsSlugsFromSaleorItem(productVariant); const productVariantMetadata = await fetchProductVariantMetadata(client, productVariant.id); diff --git a/apps/cms/src/providers/GraphQLProvider.tsx b/apps/cms/src/providers/GraphQLProvider.tsx index 7cfe6ea..c45ffd6 100644 --- a/apps/cms/src/providers/GraphQLProvider.tsx +++ b/apps/cms/src/providers/GraphQLProvider.tsx @@ -1,16 +1,17 @@ import { useAppBridge } from "@saleor/app-sdk/app-bridge"; +import { createGraphQLClient } from "@saleor/apps-shared"; import { PropsWithChildren } from "react"; import { Provider } from "urql"; -import { createClient } from "../lib/graphql"; - export function GraphQLProvider(props: PropsWithChildren<{}>) { const { appBridgeState } = useAppBridge(); const saleorApiUrl = appBridgeState?.saleorApiUrl!; + const token = appBridgeState?.token!; - const client = createClient(saleorApiUrl, async () => ({ - token: appBridgeState?.token!, - })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); return ; } diff --git a/apps/crm/.graphqlrc.yml b/apps/crm/.graphqlrc.yml index ee7c7af..b0db306 100644 --- a/apps/crm/.graphqlrc.yml +++ b/apps/crm/.graphqlrc.yml @@ -10,7 +10,6 @@ extensions: plugins: - typescript - typescript-operations - - urql-introspection - typescript-urql: documentVariablePrefix: "Untyped" fragmentVariablePrefix: "Untyped" diff --git a/apps/crm/package.json b/apps/crm/package.json index ef6a64c..4349cfd 100644 --- a/apps/crm/package.json +++ b/apps/crm/package.json @@ -22,21 +22,20 @@ "@trpc/next": "^10.18.0", "@trpc/react-query": "^10.18.0", "@trpc/server": "^10.18.0", - "@urql/exchange-auth": "^1.0.0", + "@urql/exchange-auth": "^2.1.4", "@vitejs/plugin-react": "4.0.0", "clsx": "^1.2.1", "graphql": "16.6.0", "graphql-tag": "^2.12.6", "jsdom": "^20.0.3", "next": "13.3.0", - "next-urql": "4.0.3", "pino": "^8.14.1", "pino-pretty": "^10.0.0", "react": "18.2.0", "react-dom": "18.2.0", "react-hook-form": "^7.43.0", "react-is": "^18.2.0", - "urql": "^3.0.3", + "urql": "^4.0.4", "usehooks-ts": "^2.9.1", "vite": "4.3.9", "vitest": "0.31.3", @@ -49,7 +48,6 @@ "@graphql-codegen/typescript": "3.0.2", "@graphql-codegen/typescript-operations": "3.0.2", "@graphql-codegen/typescript-urql": "3.7.3", - "@graphql-codegen/urql-introspection": "2.2.1", "@graphql-typed-document-node/core": "3.2.0", "@testing-library/react": "^13.4.0", "@testing-library/react-hooks": "^8.0.1", diff --git a/apps/crm/src/lib/create-graphq-client.ts b/apps/crm/src/lib/create-graphq-client.ts deleted file mode 100644 index 1448c8a..0000000 --- a/apps/crm/src/lib/create-graphq-client.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { AuthConfig, authExchange } from "@urql/exchange-auth"; -import { - cacheExchange, - createClient as urqlCreateClient, - dedupExchange, - fetchExchange, -} from "urql"; - -interface IAuthState { - token: string; -} - -export const createClient = (url: string, getAuth: AuthConfig["getAuth"]) => - urqlCreateClient({ - url, - exchanges: [ - dedupExchange, - cacheExchange, - authExchange({ - addAuthToOperation: ({ authState, operation }) => { - if (!authState || !authState?.token) { - return operation; - } - - const fetchOptions = - typeof operation.context.fetchOptions === "function" - ? operation.context.fetchOptions() - : operation.context.fetchOptions || {}; - - return { - ...operation, - context: { - ...operation.context, - fetchOptions: { - ...fetchOptions, - headers: { - ...fetchOptions.headers, - "Authorization-Bearer": authState.token, - }, - }, - }, - }; - }, - getAuth, - }), - fetchExchange, - ], - }); diff --git a/apps/crm/src/lib/graphql-provider.tsx b/apps/crm/src/lib/graphql-provider.tsx index 051d526..dd566d9 100644 --- a/apps/crm/src/lib/graphql-provider.tsx +++ b/apps/crm/src/lib/graphql-provider.tsx @@ -1,7 +1,7 @@ import { useAppBridge } from "@saleor/app-sdk/app-bridge"; +import { createGraphQLClient } from "@saleor/apps-shared"; import { PropsWithChildren } from "react"; import { Provider } from "urql"; -import { createClient } from "./create-graphq-client"; export function GraphQLProvider(props: PropsWithChildren<{}>) { const { appBridgeState } = useAppBridge(); @@ -11,9 +11,10 @@ export function GraphQLProvider(props: PropsWithChildren<{}>) { return
; } - const client = createClient(saleorApiUrl, async () => - Promise.resolve({ token: appBridgeState?.token! }) - ); + const client = createGraphQLClient({ + saleorApiUrl: saleorApiUrl, + token: appBridgeState?.token, + }); return ; } diff --git a/apps/crm/src/modules/saleor-customers-sync/use-fetch-all-customers.ts b/apps/crm/src/modules/saleor-customers-sync/use-fetch-all-customers.ts index ce30151..9d93946 100644 --- a/apps/crm/src/modules/saleor-customers-sync/use-fetch-all-customers.ts +++ b/apps/crm/src/modules/saleor-customers-sync/use-fetch-all-customers.ts @@ -1,9 +1,9 @@ import { useAppBridge } from "@saleor/app-sdk/app-bridge"; import { useEffect, useState } from "react"; -import { createClient } from "../../lib/create-graphq-client"; import { FetchCustomersDocument, FetchCustomersQuery } from "../../../generated/graphql"; import { OperationResult } from "urql"; import { metadataToMailchimpTags } from "./metadata-to-mailchimp-tags"; +import { createGraphQLClient } from "@saleor/apps-shared"; type CustomerCollectionItem = { email: string; @@ -27,9 +27,10 @@ export const useFetchAllCustomers = (enabled: boolean) => { return; } - const client = createClient(appBridgeState.saleorApiUrl, async () => ({ - token: appBridgeState.token!, - })); + const client = createGraphQLClient({ + saleorApiUrl: appBridgeState.saleorApiUrl, + token: appBridgeState.token, + }); const fetchPage = (cursor?: string) => client.query(FetchCustomersDocument, { cursor }).toPromise(); diff --git a/apps/crm/src/modules/trpc/protected-client-procedure.ts b/apps/crm/src/modules/trpc/protected-client-procedure.ts index 1f23e56..c6e2881 100644 --- a/apps/crm/src/modules/trpc/protected-client-procedure.ts +++ b/apps/crm/src/modules/trpc/protected-client-procedure.ts @@ -4,8 +4,7 @@ import { TRPCError } from "@trpc/server"; import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next"; import { saleorApp } from "../../saleor-app"; -import { createClient } from "../../lib/create-graphq-client"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; const logger = createLogger({ service: "protected-client-procedure" }); @@ -108,9 +107,10 @@ export const protectedClientProcedure = procedure .use(attachAppToken) .use(validateClientToken) .use(async ({ ctx, next }) => { - const client = createClient(ctx.saleorApiUrl, async () => - Promise.resolve({ token: ctx.appToken }) - ); + const client = createGraphQLClient({ + saleorApiUrl: ctx.saleorApiUrl, + token: ctx.token, + }); return next({ ctx: { diff --git a/apps/crm/src/pages/api/webhooks/customer-created.ts b/apps/crm/src/pages/api/webhooks/customer-created.ts index 9f2a438..d96988e 100644 --- a/apps/crm/src/pages/api/webhooks/customer-created.ts +++ b/apps/crm/src/pages/api/webhooks/customer-created.ts @@ -4,11 +4,10 @@ import { CustomerCreatedDocument, CustomerCreatedPayloadFragment, } from "../../../../generated/graphql"; -import { createClient } from "../../../lib/create-graphq-client"; import { MailchimpConfigSettingsManager } from "../../../modules/mailchimp/mailchimp-config-settings-manager"; import { MailchimpClientOAuth } from "../../../modules/mailchimp/mailchimp-client"; import { metadataToMailchimpTags } from "../../../modules/saleor-customers-sync/metadata-to-mailchimp-tags"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; export const customerCreatedWebhook = new SaleorAsyncWebhook({ name: "Customer Created in Saleor", @@ -40,9 +39,10 @@ export const customerCreatedHandler: NextWebhookApiHandler - Promise.resolve({ token: authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); const settingsManager = new MailchimpConfigSettingsManager(client, authData.appId); diff --git a/apps/crm/src/pages/api/webhooks/customer-updated.ts b/apps/crm/src/pages/api/webhooks/customer-updated.ts index c2a4cf6..5275ddf 100644 --- a/apps/crm/src/pages/api/webhooks/customer-updated.ts +++ b/apps/crm/src/pages/api/webhooks/customer-updated.ts @@ -5,11 +5,10 @@ import { CustomerUpdatedDocument, CustomerUpdatedPayloadFragment, } from "../../../../generated/graphql"; -import { createClient } from "../../../lib/create-graphq-client"; import { MailchimpConfigSettingsManager } from "../../../modules/mailchimp/mailchimp-config-settings-manager"; import { MailchimpClientOAuth } from "../../../modules/mailchimp/mailchimp-client"; import { metadataToMailchimpTags } from "../../../modules/saleor-customers-sync/metadata-to-mailchimp-tags"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; export const customerMetadataUpdatedWebhook = new SaleorAsyncWebhook({ @@ -41,9 +40,10 @@ const handler: NextWebhookApiHandler = async ( return res.status(200).end(); } - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); const settingsManager = new MailchimpConfigSettingsManager(client, authData.appId); diff --git a/apps/data-importer/.graphqlrc.yml b/apps/data-importer/.graphqlrc.yml index ee7c7af..b0db306 100644 --- a/apps/data-importer/.graphqlrc.yml +++ b/apps/data-importer/.graphqlrc.yml @@ -10,7 +10,6 @@ extensions: plugins: - typescript - typescript-operations - - urql-introspection - typescript-urql: documentVariablePrefix: "Untyped" fragmentVariablePrefix: "Untyped" diff --git a/apps/data-importer/package.json b/apps/data-importer/package.json index 30afd04..d9cf1bf 100644 --- a/apps/data-importer/package.json +++ b/apps/data-importer/package.json @@ -19,7 +19,7 @@ "@saleor/apps-shared": "workspace:*", "@saleor/macaw-ui": "^0.7.2", "@sentry/nextjs": "^7.39.0", - "@urql/exchange-auth": "^1.0.0", + "@urql/exchange-auth": "^2.1.4", "@vitejs/plugin-react": "4.0.0", "clsx": "^1.2.1", "dot-object": "^2.1.4", @@ -33,7 +33,7 @@ "pino-pretty": "^10.0.0", "react": "18.2.0", "react-dom": "18.2.0", - "urql": "^3.0.3", + "urql": "^4.0.4", "usehooks-ts": "^2.9.1", "vite": "4.3.9", "vitest": "0.31.3", @@ -47,7 +47,6 @@ "@graphql-codegen/typescript": "3.0.2", "@graphql-codegen/typescript-operations": "3.0.2", "@graphql-codegen/typescript-urql": "3.7.3", - "@graphql-codegen/urql-introspection": "2.2.1", "@graphql-typed-document-node/core": "3.2.0", "@testing-library/react": "^13.4.0", "@testing-library/react-hooks": "^8.0.1", diff --git a/apps/data-importer/src/lib/graphql.ts b/apps/data-importer/src/lib/graphql.ts deleted file mode 100644 index 1448c8a..0000000 --- a/apps/data-importer/src/lib/graphql.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { AuthConfig, authExchange } from "@urql/exchange-auth"; -import { - cacheExchange, - createClient as urqlCreateClient, - dedupExchange, - fetchExchange, -} from "urql"; - -interface IAuthState { - token: string; -} - -export const createClient = (url: string, getAuth: AuthConfig["getAuth"]) => - urqlCreateClient({ - url, - exchanges: [ - dedupExchange, - cacheExchange, - authExchange({ - addAuthToOperation: ({ authState, operation }) => { - if (!authState || !authState?.token) { - return operation; - } - - const fetchOptions = - typeof operation.context.fetchOptions === "function" - ? operation.context.fetchOptions() - : operation.context.fetchOptions || {}; - - return { - ...operation, - context: { - ...operation.context, - fetchOptions: { - ...fetchOptions, - headers: { - ...fetchOptions.headers, - "Authorization-Bearer": authState.token, - }, - }, - }, - }; - }, - getAuth, - }), - fetchExchange, - ], - }); diff --git a/apps/data-importer/src/providers/GraphQLProvider.tsx b/apps/data-importer/src/providers/GraphQLProvider.tsx index 769d264..9bdda65 100644 --- a/apps/data-importer/src/providers/GraphQLProvider.tsx +++ b/apps/data-importer/src/providers/GraphQLProvider.tsx @@ -1,15 +1,15 @@ import { useAppBridge } from "@saleor/app-sdk/app-bridge"; +import { createGraphQLClient } from "@saleor/apps-shared"; import { PropsWithChildren } from "react"; import { Provider } from "urql"; -import { createClient } from "../lib/graphql"; - export function GraphQLProvider(props: PropsWithChildren<{}>) { const { appBridgeState } = useAppBridge(); - const client = createClient(appBridgeState?.saleorApiUrl!, async () => - Promise.resolve({ token: appBridgeState?.token! }) - ); + const client = createGraphQLClient({ + saleorApiUrl: appBridgeState?.saleorApiUrl!, + token: appBridgeState?.token!, + }); return ; } diff --git a/apps/emails-and-messages/.graphqlrc.yml b/apps/emails-and-messages/.graphqlrc.yml index ee7c7af..b0db306 100644 --- a/apps/emails-and-messages/.graphqlrc.yml +++ b/apps/emails-and-messages/.graphqlrc.yml @@ -10,7 +10,6 @@ extensions: plugins: - typescript - typescript-operations - - urql-introspection - typescript-urql: documentVariablePrefix: "Untyped" fragmentVariablePrefix: "Untyped" diff --git a/apps/emails-and-messages/package.json b/apps/emails-and-messages/package.json index 7956695..1f85762 100644 --- a/apps/emails-and-messages/package.json +++ b/apps/emails-and-messages/package.json @@ -27,7 +27,7 @@ "@trpc/next": "^10.13.0", "@trpc/react-query": "^10.13.0", "@trpc/server": "^10.13.0", - "@urql/exchange-auth": "^1.0.0", + "@urql/exchange-auth": "^2.1.4", "@vitejs/plugin-react": "4.0.0", "clsx": "^1.2.1", "dotenv": "^16.0.3", @@ -38,7 +38,6 @@ "jsdom": "^20.0.3", "mjml": "^4.13.0", "next": "13.3.0", - "next-urql": "4.0.3", "nodemailer": "^6.9.1", "pino": "^8.14.1", "pino-pretty": "^10.0.0", @@ -47,7 +46,7 @@ "react-hook-form": "^7.43.9", "react-is": "^18.2.0", "react-query": "^3.39.3", - "urql": "^3.0.3", + "urql": "^4.0.4", "usehooks-ts": "^2.9.1", "vite": "4.3.9", "vitest": "0.31.3", @@ -61,7 +60,6 @@ "@graphql-codegen/typescript": "3.0.2", "@graphql-codegen/typescript-operations": "3.0.2", "@graphql-codegen/typescript-urql": "3.7.3", - "@graphql-codegen/urql-introspection": "2.2.1", "@graphql-typed-document-node/core": "3.2.0", "@testing-library/react": "^13.4.0", "@testing-library/react-hooks": "^8.0.1", diff --git a/apps/emails-and-messages/scripts/migrations/migration-utils.ts b/apps/emails-and-messages/scripts/migrations/migration-utils.ts index 8c78c31..84f97bc 100644 --- a/apps/emails-and-messages/scripts/migrations/migration-utils.ts +++ b/apps/emails-and-messages/scripts/migrations/migration-utils.ts @@ -1,13 +1,11 @@ /* eslint-disable turbo/no-undeclared-env-vars */ -import { createClient } from "../../src/lib/create-graphql-client"; +import { createGraphQLClient } from "@saleor/apps-shared"; import { SaleorCloudAPL } from "@saleor/app-sdk/APL"; import { createSettingsManager } from "../../src/lib/metadata-manager"; export const getMetadataManagerForEnv = (apiUrl: string, appToken: string, appId: string) => { - const client = createClient(apiUrl, async () => ({ - token: appToken, - })); + const client = createGraphQLClient({ saleorApiUrl: apiUrl, token: appToken }); return createSettingsManager(client, appId); }; diff --git a/apps/emails-and-messages/src/lib/create-graphql-client.ts b/apps/emails-and-messages/src/lib/create-graphql-client.ts deleted file mode 100644 index 1448c8a..0000000 --- a/apps/emails-and-messages/src/lib/create-graphql-client.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { AuthConfig, authExchange } from "@urql/exchange-auth"; -import { - cacheExchange, - createClient as urqlCreateClient, - dedupExchange, - fetchExchange, -} from "urql"; - -interface IAuthState { - token: string; -} - -export const createClient = (url: string, getAuth: AuthConfig["getAuth"]) => - urqlCreateClient({ - url, - exchanges: [ - dedupExchange, - cacheExchange, - authExchange({ - addAuthToOperation: ({ authState, operation }) => { - if (!authState || !authState?.token) { - return operation; - } - - const fetchOptions = - typeof operation.context.fetchOptions === "function" - ? operation.context.fetchOptions() - : operation.context.fetchOptions || {}; - - return { - ...operation, - context: { - ...operation.context, - fetchOptions: { - ...fetchOptions, - headers: { - ...fetchOptions.headers, - "Authorization-Bearer": authState.token, - }, - }, - }, - }; - }, - getAuth, - }), - fetchExchange, - ], - }); diff --git a/apps/emails-and-messages/src/modules/channels/channels.router.ts b/apps/emails-and-messages/src/modules/channels/channels.router.ts index 0c33549..33464f2 100644 --- a/apps/emails-and-messages/src/modules/channels/channels.router.ts +++ b/apps/emails-and-messages/src/modules/channels/channels.router.ts @@ -1,13 +1,11 @@ import { ChannelsFetcher } from "./channels-fetcher"; -import { createClient } from "../../lib/create-graphql-client"; +import { createGraphQLClient } from "@saleor/apps-shared"; import { router } from "../trpc/trpc-server"; import { protectedClientProcedure } from "../trpc/protected-client-procedure"; export const channelsRouter = router({ fetch: protectedClientProcedure.query(async ({ ctx }) => { - const client = createClient(ctx.saleorApiUrl, async () => - Promise.resolve({ token: ctx.appToken }) - ); + const client = createGraphQLClient({ saleorApiUrl: ctx.saleorApiUrl, token: ctx.token }); const fetcher = new ChannelsFetcher(client); diff --git a/apps/emails-and-messages/src/modules/trpc/protected-client-procedure.ts b/apps/emails-and-messages/src/modules/trpc/protected-client-procedure.ts index ce13f94..8048c86 100644 --- a/apps/emails-and-messages/src/modules/trpc/protected-client-procedure.ts +++ b/apps/emails-and-messages/src/modules/trpc/protected-client-procedure.ts @@ -3,8 +3,7 @@ import { middleware, procedure } from "./trpc-server"; import { TRPCError } from "@trpc/server"; import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next"; import { saleorApp } from "../../saleor-app"; -import { logger } from "@saleor/apps-shared"; -import { createClient } from "../../lib/create-graphql-client"; +import { createGraphQLClient, logger } from "@saleor/apps-shared"; const attachAppToken = middleware(async ({ ctx, next }) => { logger.debug("attachAppToken middleware"); @@ -105,9 +104,7 @@ export const protectedClientProcedure = procedure .use(attachAppToken) .use(validateClientToken) .use(async ({ ctx, next }) => { - const client = createClient(ctx.saleorApiUrl, async () => - Promise.resolve({ token: ctx.appToken }) - ); + const client = createGraphQLClient({ saleorApiUrl: ctx.saleorApiUrl, token: ctx.token }); return next({ ctx: { diff --git a/apps/emails-and-messages/src/pages/api/register.ts b/apps/emails-and-messages/src/pages/api/register.ts index 744fb1d..28fee18 100644 --- a/apps/emails-and-messages/src/pages/api/register.ts +++ b/apps/emails-and-messages/src/pages/api/register.ts @@ -1,8 +1,7 @@ import { createAppRegisterHandler } from "@saleor/app-sdk/handlers/next"; import { saleorApp } from "../../saleor-app"; -import { createClient } from "../../lib/create-graphql-client"; -import { logger } from "@saleor/apps-shared"; +import { logger, createGraphQLClient } from "@saleor/apps-shared"; import { getBaseUrl } from "../../lib/get-base-url"; import { registerNotifyWebhook } from "../../lib/register-notify-webhook"; @@ -29,9 +28,10 @@ export default createAppRegisterHandler({ // Subscribe to Notify using the mutation since it does not use subscriptions and can't be subscribed via manifest logger.debug("onAuthAplSaved executing"); const baseUrl = getBaseUrl(request.headers); - const client = createClient(ctx.authData.saleorApiUrl, async () => - Promise.resolve({ token: ctx.authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: ctx.authData.saleorApiUrl, + token: ctx.authData.token, + }); await registerNotifyWebhook({ client: client, diff --git a/apps/emails-and-messages/src/pages/api/webhooks/invoice-sent.ts b/apps/emails-and-messages/src/pages/api/webhooks/invoice-sent.ts index f43cbc4..2e1fbc3 100644 --- a/apps/emails-and-messages/src/pages/api/webhooks/invoice-sent.ts +++ b/apps/emails-and-messages/src/pages/api/webhooks/invoice-sent.ts @@ -1,13 +1,12 @@ import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next"; import { gql } from "urql"; import { saleorApp } from "../../../saleor-app"; -import { createLogger } from "@saleor/apps-shared"; +import { createLogger, createGraphQLClient } from "@saleor/apps-shared"; import { InvoiceSentWebhookPayloadFragment, OrderDetailsFragmentDoc, } from "../../../../generated/graphql"; import { sendEventMessages } from "../../../modules/event-handlers/send-event-messages"; -import { createClient } from "../../../lib/create-graphql-client"; const InvoiceSentWebhookPayload = gql` ${OrderDetailsFragmentDoc} @@ -73,9 +72,10 @@ const handler: NextWebhookApiHandler = async } const channel = order.channel.slug; - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); await sendEventMessages({ authData, diff --git a/apps/emails-and-messages/src/pages/api/webhooks/notify.ts b/apps/emails-and-messages/src/pages/api/webhooks/notify.ts index 40cecce..6c6d93c 100644 --- a/apps/emails-and-messages/src/pages/api/webhooks/notify.ts +++ b/apps/emails-and-messages/src/pages/api/webhooks/notify.ts @@ -1,8 +1,7 @@ import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next"; import { saleorApp } from "../../../saleor-app"; -import { createLogger } from "@saleor/apps-shared"; +import { createLogger, createGraphQLClient } from "@saleor/apps-shared"; import { sendEventMessages } from "../../../modules/event-handlers/send-event-messages"; -import { createClient } from "../../../lib/create-graphql-client"; import { MessageEventTypes } from "../../../modules/event-handlers/message-event-types"; /* @@ -99,9 +98,10 @@ const handler: NextWebhookApiHandler = async (req, re .json({ error: "Email recipient has not been specified in the event payload." }); } - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); await sendEventMessages({ authData, diff --git a/apps/emails-and-messages/src/pages/api/webhooks/order-cancelled.ts b/apps/emails-and-messages/src/pages/api/webhooks/order-cancelled.ts index 693b65d..7a03231 100644 --- a/apps/emails-and-messages/src/pages/api/webhooks/order-cancelled.ts +++ b/apps/emails-and-messages/src/pages/api/webhooks/order-cancelled.ts @@ -1,13 +1,12 @@ import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next"; import { gql } from "urql"; import { saleorApp } from "../../../saleor-app"; -import { createLogger } from "@saleor/apps-shared"; +import { createLogger, createGraphQLClient } from "@saleor/apps-shared"; import { OrderCancelledWebhookPayloadFragment, OrderDetailsFragmentDoc, } from "../../../../generated/graphql"; import { sendEventMessages } from "../../../modules/event-handlers/send-event-messages"; -import { createClient } from "../../../lib/create-graphql-client"; const OrderCancelledWebhookPayload = gql` ${OrderDetailsFragmentDoc} @@ -64,9 +63,10 @@ const handler: NextWebhookApiHandler = asy } const channel = order.channel.slug; - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); await sendEventMessages({ authData, diff --git a/apps/emails-and-messages/src/pages/api/webhooks/order-confirmed.ts b/apps/emails-and-messages/src/pages/api/webhooks/order-confirmed.ts index ebaf129..ce1cfff 100644 --- a/apps/emails-and-messages/src/pages/api/webhooks/order-confirmed.ts +++ b/apps/emails-and-messages/src/pages/api/webhooks/order-confirmed.ts @@ -1,13 +1,12 @@ import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next"; import { gql } from "urql"; import { saleorApp } from "../../../saleor-app"; -import { createLogger } from "@saleor/apps-shared"; +import { createLogger, createGraphQLClient } from "@saleor/apps-shared"; import { OrderConfirmedWebhookPayloadFragment, OrderDetailsFragmentDoc, } from "../../../../generated/graphql"; import { sendEventMessages } from "../../../modules/event-handlers/send-event-messages"; -import { createClient } from "../../../lib/create-graphql-client"; const OrderConfirmedWebhookPayload = gql` ${OrderDetailsFragmentDoc} @@ -65,9 +64,10 @@ const handler: NextWebhookApiHandler = asy } const channel = order.channel.slug; - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); await sendEventMessages({ authData, diff --git a/apps/emails-and-messages/src/pages/api/webhooks/order-created.ts b/apps/emails-and-messages/src/pages/api/webhooks/order-created.ts index 705c378..161ba27 100644 --- a/apps/emails-and-messages/src/pages/api/webhooks/order-created.ts +++ b/apps/emails-and-messages/src/pages/api/webhooks/order-created.ts @@ -2,10 +2,9 @@ import { OrderDetailsFragmentDoc } from "./../../../../generated/graphql"; import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next"; import { gql } from "urql"; import { saleorApp } from "../../../saleor-app"; -import { createLogger } from "@saleor/apps-shared"; +import { createLogger, createGraphQLClient } from "@saleor/apps-shared"; import { OrderCreatedWebhookPayloadFragment } from "../../../../generated/graphql"; import { sendEventMessages } from "../../../modules/event-handlers/send-event-messages"; -import { createClient } from "../../../lib/create-graphql-client"; const OrderCreatedWebhookPayload = gql` ${OrderDetailsFragmentDoc} @@ -62,9 +61,10 @@ const handler: NextWebhookApiHandler = async } const channel = order.channel.slug; - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); await sendEventMessages({ authData, diff --git a/apps/emails-and-messages/src/pages/api/webhooks/order-fulfilled.ts b/apps/emails-and-messages/src/pages/api/webhooks/order-fulfilled.ts index d1d14c5..cc4aa9a 100644 --- a/apps/emails-and-messages/src/pages/api/webhooks/order-fulfilled.ts +++ b/apps/emails-and-messages/src/pages/api/webhooks/order-fulfilled.ts @@ -1,13 +1,12 @@ import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next"; import { gql } from "urql"; import { saleorApp } from "../../../saleor-app"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; import { OrderDetailsFragmentDoc, OrderFulfilledWebhookPayloadFragment, } from "../../../../generated/graphql"; import { sendEventMessages } from "../../../modules/event-handlers/send-event-messages"; -import { createClient } from "../../../lib/create-graphql-client"; const OrderFulfilledWebhookPayload = gql` ${OrderDetailsFragmentDoc} @@ -65,9 +64,10 @@ const handler: NextWebhookApiHandler = asy } const channel = order.channel.slug; - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); await sendEventMessages({ authData, diff --git a/apps/emails-and-messages/src/pages/api/webhooks/order-fully-paid.ts b/apps/emails-and-messages/src/pages/api/webhooks/order-fully-paid.ts index a5191a5..d63f24a 100644 --- a/apps/emails-and-messages/src/pages/api/webhooks/order-fully-paid.ts +++ b/apps/emails-and-messages/src/pages/api/webhooks/order-fully-paid.ts @@ -1,13 +1,12 @@ import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handlers/next"; import { gql } from "urql"; import { saleorApp } from "../../../saleor-app"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; import { OrderDetailsFragmentDoc, OrderFullyPaidWebhookPayloadFragment, } from "../../../../generated/graphql"; import { sendEventMessages } from "../../../modules/event-handlers/send-event-messages"; -import { createClient } from "../../../lib/create-graphql-client"; const OrderFullyPaidWebhookPayload = gql` ${OrderDetailsFragmentDoc} @@ -65,9 +64,10 @@ const handler: NextWebhookApiHandler = asy } const channel = order.channel.slug; - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); await sendEventMessages({ authData, diff --git a/apps/invoices/.graphqlrc.yml b/apps/invoices/.graphqlrc.yml index ee7c7af..b0db306 100644 --- a/apps/invoices/.graphqlrc.yml +++ b/apps/invoices/.graphqlrc.yml @@ -10,7 +10,6 @@ extensions: plugins: - typescript - typescript-operations - - urql-introspection - typescript-urql: documentVariablePrefix: "Untyped" fragmentVariablePrefix: "Untyped" diff --git a/apps/invoices/package.json b/apps/invoices/package.json index 246d7a5..ce1288e 100644 --- a/apps/invoices/package.json +++ b/apps/invoices/package.json @@ -22,8 +22,7 @@ "@trpc/next": "^10.10.0", "@trpc/react-query": "^10.10.0", "@trpc/server": "^10.10.0", - "@urql/exchange-auth": "^1.0.0", - "@urql/exchange-multipart-fetch": "^1.0.1", + "@urql/exchange-auth": "^2.1.4", "@web-std/file": "^3.0.2", "clsx": "^1.2.1", "eslint": "8.42.0", @@ -37,7 +36,7 @@ "react-dom": "18.2.0", "react-hook-form": "^7.41.0", "tiny-invariant": "^1.3.1", - "urql": "^3.0.3", + "urql": "^4.0.4", "usehooks-ts": "^2.9.1", "zod": "^3.20.2" }, @@ -49,7 +48,6 @@ "@graphql-codegen/typescript": "3.0.2", "@graphql-codegen/typescript-operations": "3.0.2", "@graphql-codegen/typescript-urql": "3.7.3", - "@graphql-codegen/urql-introspection": "2.2.1", "@graphql-typed-document-node/core": "3.2.0", "@types/react": "18.2.5", "@types/react-dom": "18.2.5", diff --git a/apps/invoices/scripts/migrations/migration-utils.ts b/apps/invoices/scripts/migrations/migration-utils.ts index adfbd65..d24106e 100644 --- a/apps/invoices/scripts/migrations/migration-utils.ts +++ b/apps/invoices/scripts/migrations/migration-utils.ts @@ -1,13 +1,14 @@ /* eslint-disable turbo/no-undeclared-env-vars */ -import { createClient } from "../../src/lib/graphql"; +import { createGraphQLClient } from "@saleor/apps-shared"; import { createSettingsManager } from "../../src/modules/app-configuration/metadata-manager"; import { SaleorCloudAPL } from "@saleor/app-sdk/APL"; export const getMetadataManagerForEnv = (apiUrl: string, appToken: string) => { - const client = createClient(apiUrl, async () => ({ + const client = createGraphQLClient({ + saleorApiUrl: apiUrl, token: appToken, - })); + }); return createSettingsManager(client); }; diff --git a/apps/invoices/scripts/migrations/v1-to-v2/restore-migration.ts b/apps/invoices/scripts/migrations/v1-to-v2/restore-migration.ts index 7528d14..d0d11ee 100644 --- a/apps/invoices/scripts/migrations/v1-to-v2/restore-migration.ts +++ b/apps/invoices/scripts/migrations/v1-to-v2/restore-migration.ts @@ -2,9 +2,9 @@ import * as dotenv from "dotenv"; import { fetchCloudAplEnvs, verifyRequiredEnvs } from "../migration-utils"; -import { createClient } from "../../../src/lib/graphql"; import { RemoveMetadataDocument } from "../../../generated/graphql"; import { MigrationV1toV2Consts } from "./const"; +import { createGraphQLClient } from "@saleor/apps-shared"; dotenv.config(); @@ -15,9 +15,10 @@ const runMigration = async () => { const results = await Promise.all( allEnvs.map((env) => { - const client = createClient(env.saleorApiUrl, async () => ({ + const client = createGraphQLClient({ + saleorApiUrl: env.saleorApiUrl, token: env.token, - })); + }); return client .mutation(RemoveMetadataDocument, { diff --git a/apps/invoices/src/lib/graphql.ts b/apps/invoices/src/lib/graphql.ts deleted file mode 100644 index 6ed95c6..0000000 --- a/apps/invoices/src/lib/graphql.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { AuthConfig, authExchange } from "@urql/exchange-auth"; -import { cacheExchange, createClient as urqlCreateClient, dedupExchange } from "urql"; - -import { multipartFetchExchange } from "@urql/exchange-multipart-fetch"; - -interface IAuthState { - token: string; -} - -export const createClient = (url: string, getAuth: AuthConfig["getAuth"]) => - urqlCreateClient({ - url, - exchanges: [ - dedupExchange, - cacheExchange, - authExchange({ - addAuthToOperation: ({ authState, operation }) => { - if (!authState || !authState?.token) { - return operation; - } - - const fetchOptions = - typeof operation.context.fetchOptions === "function" - ? operation.context.fetchOptions() - : operation.context.fetchOptions || {}; - - return { - ...operation, - context: { - ...operation.context, - fetchOptions: { - ...fetchOptions, - headers: { - ...fetchOptions.headers, - "Authorization-Bearer": authState.token, - }, - }, - }, - }; - }, - getAuth, - }), - multipartFetchExchange, - ], - }); diff --git a/apps/invoices/src/modules/channels/channels.router.ts b/apps/invoices/src/modules/channels/channels.router.ts index e3b991a..b0ad1da 100644 --- a/apps/invoices/src/modules/channels/channels.router.ts +++ b/apps/invoices/src/modules/channels/channels.router.ts @@ -1,14 +1,15 @@ -import { createClient } from "../../lib/graphql"; import { router } from "../trpc/trpc-server"; import { protectedClientProcedure } from "../trpc/protected-client-procedure"; import { ChannelsFetcher } from "./channels-fetcher"; import { ChannelFragment } from "../../../generated/graphql"; +import { createGraphQLClient } from "@saleor/apps-shared"; export const channelsRouter = router({ fetch: protectedClientProcedure.query(async ({ ctx, input }): Promise => { - const client = createClient(ctx.saleorApiUrl, async () => - Promise.resolve({ token: ctx.appToken }) - ); + const client = createGraphQLClient({ + saleorApiUrl: ctx.saleorApiUrl, + token: ctx.token, + }); const fetcher = new ChannelsFetcher(client); diff --git a/apps/invoices/src/modules/trpc/protected-client-procedure.ts b/apps/invoices/src/modules/trpc/protected-client-procedure.ts index ac10ffc..bb9d161 100644 --- a/apps/invoices/src/modules/trpc/protected-client-procedure.ts +++ b/apps/invoices/src/modules/trpc/protected-client-procedure.ts @@ -1,10 +1,9 @@ -import { createClient } from "../../lib/graphql"; import { verifyJWT } from "@saleor/app-sdk/verify-jwt"; import { middleware, procedure } from "./trpc-server"; import { saleorApp } from "../../saleor-app"; import { TRPCError } from "@trpc/server"; import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next"; -import { logger } from "@saleor/apps-shared"; +import { createGraphQLClient, logger } from "@saleor/apps-shared"; const attachAppToken = middleware(async ({ ctx, next }) => { logger.debug("attachAppToken middleware"); @@ -103,9 +102,10 @@ export const protectedClientProcedure = procedure .use(attachAppToken) .use(validateClientToken) .use(async ({ ctx, next }) => { - const client = createClient(ctx.saleorApiUrl, async () => - Promise.resolve({ token: ctx.appToken }) - ); + const client = createGraphQLClient({ + saleorApiUrl: ctx.saleorApiUrl, + token: ctx.token, + }); return next({ ctx: { diff --git a/apps/invoices/src/pages/api/register.ts b/apps/invoices/src/pages/api/register.ts index 448c3ad..b0bc822 100644 --- a/apps/invoices/src/pages/api/register.ts +++ b/apps/invoices/src/pages/api/register.ts @@ -1,10 +1,13 @@ import { createAppRegisterHandler } from "@saleor/app-sdk/handlers/next"; import { REQUIRED_SALEOR_VERSION, saleorApp } from "../../saleor-app"; import { gql } from "urql"; -import { createClient } from "../../lib/graphql"; import { SaleorVersionQuery } from "../../../generated/graphql"; -import { createLogger, SaleorVersionCompatibilityValidator } from "@saleor/apps-shared"; +import { + createGraphQLClient, + createLogger, + SaleorVersionCompatibilityValidator, +} from "@saleor/apps-shared"; const allowedUrlsPattern = process.env.ALLOWED_DOMAIN_PATTERN; @@ -51,10 +54,9 @@ export default createAppRegisterHandler({ }); try { - const client = createClient(saleorApiUrl, async () => { - return { - token, - }; + const client = createGraphQLClient({ + saleorApiUrl: saleorApiUrl, + token: token, }); const saleorVersion = await client diff --git a/apps/invoices/src/pages/api/webhooks/invoice-requested.ts b/apps/invoices/src/pages/api/webhooks/invoice-requested.ts index 5a06102..b1c0e25 100644 --- a/apps/invoices/src/pages/api/webhooks/invoice-requested.ts +++ b/apps/invoices/src/pages/api/webhooks/invoice-requested.ts @@ -5,7 +5,6 @@ import { InvoiceRequestedPayloadFragment, OrderPayloadFragment, } from "../../../../generated/graphql"; -import { createClient } from "../../../lib/graphql"; import { SaleorInvoiceUploader } from "../../../modules/invoices/invoice-uploader/saleor-invoice-uploader"; import { InvoiceCreateNotifier } from "../../../modules/invoices/invoice-create-notifier/invoice-create-notifier"; import { @@ -15,7 +14,7 @@ import { import { MicroinvoiceInvoiceGenerator } from "../../../modules/invoices/invoice-generator/microinvoice/microinvoice-invoice-generator"; import { hashInvoiceFilename } from "../../../modules/invoices/invoice-file-name/hash-invoice-filename"; import { resolveTempPdfFileLocation } from "../../../modules/invoices/invoice-file-name/resolve-temp-pdf-file-location"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; import { SALEOR_API_URL_HEADER } from "@saleor/app-sdk/const"; import { GetAppConfigurationV2Service } from "../../../modules/app-configuration/schema-v2/get-app-configuration.v2.service"; import { ShopInfoFetcher } from "../../../modules/shop-info/shop-info-fetcher"; @@ -176,9 +175,10 @@ export const handler: NextWebhookApiHandler = a logger.debug({ invoiceName }, "Generated invoice name"); try { - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); const hashedInvoiceName = hashInvoiceFilename(invoiceName, orderId); diff --git a/apps/klaviyo/.graphqlrc.yml b/apps/klaviyo/.graphqlrc.yml index 9cbf367..73f5f2d 100644 --- a/apps/klaviyo/.graphqlrc.yml +++ b/apps/klaviyo/.graphqlrc.yml @@ -10,7 +10,6 @@ extensions: plugins: - typescript - typescript-operations - - urql-introspection - typescript-urql: documentVariablePrefix: "Untyped" fragmentVariablePrefix: "Untyped" diff --git a/apps/klaviyo/package.json b/apps/klaviyo/package.json index 29dc078..5611384 100644 --- a/apps/klaviyo/package.json +++ b/apps/klaviyo/package.json @@ -18,7 +18,7 @@ "@saleor/apps-shared": "workspace:*", "@saleor/macaw-ui": "^0.7.2", "@sentry/nextjs": "^7.36.0", - "@urql/exchange-auth": "^1.0.0", + "@urql/exchange-auth": "^2.1.4", "clsx": "^1.2.1", "graphql": "16.6.0", "graphql-tag": "^2.12.6", @@ -29,7 +29,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-helmet": "^6.1.0", - "urql": "^3.0.3", + "urql": "^4.0.4", "vite": "4.3.9", "vitest": "0.31.3" }, @@ -41,7 +41,6 @@ "@graphql-codegen/typescript": "3.0.2", "@graphql-codegen/typescript-operations": "3.0.2", "@graphql-codegen/typescript-urql": "3.7.3", - "@graphql-codegen/urql-introspection": "2.2.1", "@graphql-typed-document-node/core": "3.2.0", "@types/react": "18.2.5", "@types/react-dom": "18.2.5", diff --git a/apps/klaviyo/src/lib/graphql.ts b/apps/klaviyo/src/lib/graphql.ts deleted file mode 100644 index 1448c8a..0000000 --- a/apps/klaviyo/src/lib/graphql.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { AuthConfig, authExchange } from "@urql/exchange-auth"; -import { - cacheExchange, - createClient as urqlCreateClient, - dedupExchange, - fetchExchange, -} from "urql"; - -interface IAuthState { - token: string; -} - -export const createClient = (url: string, getAuth: AuthConfig["getAuth"]) => - urqlCreateClient({ - url, - exchanges: [ - dedupExchange, - cacheExchange, - authExchange({ - addAuthToOperation: ({ authState, operation }) => { - if (!authState || !authState?.token) { - return operation; - } - - const fetchOptions = - typeof operation.context.fetchOptions === "function" - ? operation.context.fetchOptions() - : operation.context.fetchOptions || {}; - - return { - ...operation, - context: { - ...operation.context, - fetchOptions: { - ...fetchOptions, - headers: { - ...fetchOptions.headers, - "Authorization-Bearer": authState.token, - }, - }, - }, - }; - }, - getAuth, - }), - fetchExchange, - ], - }); diff --git a/apps/klaviyo/src/pages/api/configuration.ts b/apps/klaviyo/src/pages/api/configuration.ts index eb90562..3971999 100644 --- a/apps/klaviyo/src/pages/api/configuration.ts +++ b/apps/klaviyo/src/pages/api/configuration.ts @@ -1,9 +1,9 @@ import { createProtectedHandler, NextProtectedApiHandler } from "@saleor/app-sdk/handlers/next"; import { EncryptedMetadataManager } from "@saleor/app-sdk/settings-manager"; -import { createClient } from "../../lib/graphql"; import { createSettingsManager } from "../../lib/metadata"; import { saleorApp } from "../../../saleor-app"; +import { createGraphQLClient } from "@saleor/apps-shared"; type ConfigurationKeysType = | "PUBLIC_TOKEN" @@ -46,7 +46,11 @@ const handler: NextProtectedApiHandler = async (request, res, ctx) => { const { authData: { token, saleorApiUrl, appId }, } = ctx; - const client = createClient(saleorApiUrl, async () => Promise.resolve({ token })); + + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); const settings = createSettingsManager(client, appId); diff --git a/apps/klaviyo/src/pages/api/webhooks/customer-created.ts b/apps/klaviyo/src/pages/api/webhooks/customer-created.ts index c9cf9d7..f91543f 100644 --- a/apps/klaviyo/src/pages/api/webhooks/customer-created.ts +++ b/apps/klaviyo/src/pages/api/webhooks/customer-created.ts @@ -5,10 +5,10 @@ import { CustomerCreatedWebhookPayloadFragment, UntypedCustomerCreatedDocument, } from "../../../../generated/graphql"; -import { createClient } from "../../../lib/graphql"; import { Klaviyo } from "../../../lib/klaviyo"; import { createSettingsManager } from "../../../lib/metadata"; import { saleorApp } from "../../../../saleor-app"; +import { createGraphQLClient } from "@saleor/apps-shared"; const CustomerCreatedWebhookPayload = gql` fragment CustomerCreatedWebhookPayload on CustomerCreated { @@ -68,7 +68,11 @@ const handler: NextWebhookApiHandler = as const { payload, authData } = context; const { saleorApiUrl, token, appId } = authData; - const client = createClient(saleorApiUrl, async () => Promise.resolve({ token })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); + const settings = createSettingsManager(client, appId); const klaviyoToken = await settings.get("PUBLIC_TOKEN"); diff --git a/apps/klaviyo/src/pages/api/webhooks/fulfillment-created.ts b/apps/klaviyo/src/pages/api/webhooks/fulfillment-created.ts index 10f5e3f..7a07858 100644 --- a/apps/klaviyo/src/pages/api/webhooks/fulfillment-created.ts +++ b/apps/klaviyo/src/pages/api/webhooks/fulfillment-created.ts @@ -5,10 +5,10 @@ import { FulfillmentCreatedWebhookPayloadFragment, UntypedFulfillmentCreatedDocument, } from "../../../../generated/graphql"; -import { createClient } from "../../../lib/graphql"; import { Klaviyo } from "../../../lib/klaviyo"; import { createSettingsManager } from "../../../lib/metadata"; import { saleorApp } from "../../../../saleor-app"; +import { createGraphQLClient } from "@saleor/apps-shared"; const FulfillmentCreatedWebhookPayload = gql` fragment FulfillmentCreatedWebhookPayload on FulfillmentCreated { @@ -74,7 +74,10 @@ const handler: NextWebhookApiHandler = const { payload, authData } = context; const { saleorApiUrl, token, appId } = authData; - const client = createClient(saleorApiUrl, async () => Promise.resolve({ token })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); const settings = createSettingsManager(client, appId); const klaviyoToken = await settings.get("PUBLIC_TOKEN"); diff --git a/apps/klaviyo/src/pages/api/webhooks/order-created.ts b/apps/klaviyo/src/pages/api/webhooks/order-created.ts index 9085125..9f76718 100644 --- a/apps/klaviyo/src/pages/api/webhooks/order-created.ts +++ b/apps/klaviyo/src/pages/api/webhooks/order-created.ts @@ -5,10 +5,10 @@ import { OrderCreatedWebhookPayloadFragment, UntypedOrderCreatedDocument, } from "../../../../generated/graphql"; -import { createClient } from "../../../lib/graphql"; import { Klaviyo } from "../../../lib/klaviyo"; import { createSettingsManager } from "../../../lib/metadata"; import { saleorApp } from "../../../../saleor-app"; +import { createGraphQLClient } from "@saleor/apps-shared"; const OrderCreatedWebhookPayload = gql` fragment OrderCreatedWebhookPayload on OrderCreated { @@ -44,7 +44,10 @@ const handler: NextWebhookApiHandler = async const { payload, authData } = context; const { saleorApiUrl, token, appId } = authData; - const client = createClient(saleorApiUrl, async () => Promise.resolve({ token })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); const settings = createSettingsManager(client, appId); const klaviyoToken = await settings.get("PUBLIC_TOKEN"); diff --git a/apps/klaviyo/src/pages/api/webhooks/order-fully-paid.ts b/apps/klaviyo/src/pages/api/webhooks/order-fully-paid.ts index 05d0d2e..9b4b645 100644 --- a/apps/klaviyo/src/pages/api/webhooks/order-fully-paid.ts +++ b/apps/klaviyo/src/pages/api/webhooks/order-fully-paid.ts @@ -5,10 +5,10 @@ import { OrderFullyPaidWebhookPayloadFragment, UntypedOrderFullyPaidDocument, } from "../../../../generated/graphql"; -import { createClient } from "../../../lib/graphql"; import { Klaviyo } from "../../../lib/klaviyo"; import { createSettingsManager } from "../../../lib/metadata"; import { saleorApp } from "../../../../saleor-app"; +import { createGraphQLClient } from "@saleor/apps-shared"; const OrderFullyPaidWebhookPayload = gql` fragment OrderFullyPaidWebhookPayload on OrderFullyPaid { @@ -44,7 +44,11 @@ const handler: NextWebhookApiHandler = asy const { payload, authData } = context; const { saleorApiUrl, token, appId } = authData; - const client = createClient(saleorApiUrl, async () => Promise.resolve({ token })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); + const settings = createSettingsManager(client, appId); const klaviyoToken = await settings.get("PUBLIC_TOKEN"); diff --git a/apps/monitoring/.graphqlrc.yml b/apps/monitoring/.graphqlrc.yml index c12fc81..7053ecd 100644 --- a/apps/monitoring/.graphqlrc.yml +++ b/apps/monitoring/.graphqlrc.yml @@ -10,7 +10,6 @@ extensions: plugins: - typescript - typescript-operations - - urql-introspection - typescript-urql: documentVariablePrefix: "Untyped" fragmentVariablePrefix: "Untyped" diff --git a/apps/monitoring/package.json b/apps/monitoring/package.json index b3eb759..c8ef28b 100644 --- a/apps/monitoring/package.json +++ b/apps/monitoring/package.json @@ -17,7 +17,7 @@ "@saleor/app-sdk": "0.40.1", "@saleor/apps-shared": "workspace:*", "@saleor/macaw-ui": "^0.7.2", - "@urql/exchange-auth": "^1.0.0", + "@urql/exchange-auth": "^2.1.4", "@vitejs/plugin-react": "4.0.0", "clsx": "^1.2.1", "graphql": "16.6.0", @@ -29,7 +29,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-hook-form": "^7.42.1", - "urql": "^3.0.3", + "urql": "^4.0.4", "vite": "4.3.9", "vitest": "0.31.3" }, @@ -41,7 +41,6 @@ "@graphql-codegen/typescript": "3.0.2", "@graphql-codegen/typescript-operations": "3.0.2", "@graphql-codegen/typescript-urql": "3.7.3", - "@graphql-codegen/urql-introspection": "2.2.1", "@graphql-typed-document-node/core": "3.2.0", "@testing-library/react": "^13.4.0", "@testing-library/react-hooks": "^8.0.1", diff --git a/apps/monitoring/src/graphql-provider.tsx b/apps/monitoring/src/graphql-provider.tsx index 8ad0a04..c45ffd6 100644 --- a/apps/monitoring/src/graphql-provider.tsx +++ b/apps/monitoring/src/graphql-provider.tsx @@ -1,16 +1,17 @@ import { useAppBridge } from "@saleor/app-sdk/app-bridge"; +import { createGraphQLClient } from "@saleor/apps-shared"; import { PropsWithChildren } from "react"; import { Provider } from "urql"; -import { createClient } from "./lib/create-graphq-client"; export function GraphQLProvider(props: PropsWithChildren<{}>) { const { appBridgeState } = useAppBridge(); + const saleorApiUrl = appBridgeState?.saleorApiUrl!; + const token = appBridgeState?.token!; - const client = createClient( - `/graphql`, - async () => Promise.resolve({ token: appBridgeState?.token! }), - () => appBridgeState?.saleorApiUrl! - ); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); return ; } diff --git a/apps/monitoring/src/lib/create-graphq-client.ts b/apps/monitoring/src/lib/create-graphq-client.ts deleted file mode 100644 index 052f17c..0000000 --- a/apps/monitoring/src/lib/create-graphq-client.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { AuthConfig, authExchange } from "@urql/exchange-auth"; -import { - cacheExchange, - createClient as urqlCreateClient, - dedupExchange, - fetchExchange, -} from "urql"; - -interface IAuthState { - token: string; -} - -export const createClient = ( - url: string, - getAuth: AuthConfig["getAuth"], - getSaleorApiUrl: () => string -) => - urqlCreateClient({ - url, - exchanges: [ - dedupExchange, - cacheExchange, - authExchange({ - addAuthToOperation: ({ authState, operation }) => { - if (!authState || !authState?.token) { - return operation; - } - - const fetchOptions = - typeof operation.context.fetchOptions === "function" - ? operation.context.fetchOptions() - : operation.context.fetchOptions || {}; - - return { - ...operation, - context: { - ...operation.context, - fetchOptions: { - ...fetchOptions, - headers: { - ...fetchOptions.headers, - "Authorization-Bearer": authState.token, - "Saleor-Api-Url": getSaleorApiUrl(), - }, - }, - }, - }; - }, - getAuth, - }), - fetchExchange, - ], - }); diff --git a/apps/products-feed/.graphqlrc.yml b/apps/products-feed/.graphqlrc.yml index ee7c7af..b0db306 100644 --- a/apps/products-feed/.graphqlrc.yml +++ b/apps/products-feed/.graphqlrc.yml @@ -10,7 +10,6 @@ extensions: plugins: - typescript - typescript-operations - - urql-introspection - typescript-urql: documentVariablePrefix: "Untyped" fragmentVariablePrefix: "Untyped" diff --git a/apps/products-feed/package.json b/apps/products-feed/package.json index deb6df3..fb3c8f7 100644 --- a/apps/products-feed/package.json +++ b/apps/products-feed/package.json @@ -25,7 +25,7 @@ "@trpc/next": "^10.9.0", "@trpc/react-query": "^10.9.0", "@trpc/server": "^10.9.0", - "@urql/exchange-auth": "^1.0.0", + "@urql/exchange-auth": "^2.1.4", "@vitejs/plugin-react": "4.0.0", "clsx": "^1.2.1", "fast-xml-parser": "^4.0.15", @@ -33,7 +33,6 @@ "graphql-tag": "^2.12.6", "jsdom": "^20.0.3", "next": "13.3.0", - "next-urql": "4.0.3", "pino": "^8.14.1", "pino-pretty": "^10.0.0", "react": "18.2.0", @@ -41,7 +40,7 @@ "react-hook-form": "^7.43.9", "react-is": "^18.2.0", "react-query": "^3.39.3", - "urql": "^3.0.3", + "urql": "^4.0.4", "usehooks-ts": "^2.9.1", "vite": "4.3.9", "vitest": "0.31.3", @@ -55,7 +54,6 @@ "@graphql-codegen/typescript": "3.0.2", "@graphql-codegen/typescript-operations": "3.0.2", "@graphql-codegen/typescript-urql": "3.7.3", - "@graphql-codegen/urql-introspection": "2.2.1", "@graphql-typed-document-node/core": "3.2.0", "@testing-library/react": "^13.4.0", "@testing-library/react-hooks": "^8.0.1", diff --git a/apps/products-feed/src/lib/create-graphq-client.ts b/apps/products-feed/src/lib/create-graphq-client.ts index 0d55adf..a58ada6 100644 --- a/apps/products-feed/src/lib/create-graphq-client.ts +++ b/apps/products-feed/src/lib/create-graphq-client.ts @@ -1,57 +1,11 @@ -import { AuthConfig, authExchange } from "@urql/exchange-auth"; -import { - cacheExchange, - createClient as urqlCreateClient, - dedupExchange, - fetchExchange, -} from "urql"; import { AuthData } from "@saleor/app-sdk/APL"; - -interface IAuthState { - token: string; -} - -export const createClient = (url: string, getAuth: AuthConfig["getAuth"]) => - urqlCreateClient({ - url, - exchanges: [ - dedupExchange, - cacheExchange, - authExchange({ - addAuthToOperation: ({ authState, operation }) => { - if (!authState || !authState?.token) { - return operation; - } - - const fetchOptions = - typeof operation.context.fetchOptions === "function" - ? operation.context.fetchOptions() - : operation.context.fetchOptions || {}; - - return { - ...operation, - context: { - ...operation.context, - fetchOptions: { - ...fetchOptions, - headers: { - ...fetchOptions.headers, - "Authorization-Bearer": authState.token, - }, - }, - }, - }; - }, - getAuth, - }), - fetchExchange, - ], - }); +import { createGraphQLClient } from "@saleor/apps-shared"; export const GraphqlClientFactory = { fromAuthData(authData: Pick) { - return createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); + return createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); }, }; diff --git a/apps/products-feed/src/pages/api/feed/[url]/[channel]/google.xml.ts b/apps/products-feed/src/pages/api/feed/[url]/[channel]/google.xml.ts index d5adaca..6331f83 100644 --- a/apps/products-feed/src/pages/api/feed/[url]/[channel]/google.xml.ts +++ b/apps/products-feed/src/pages/api/feed/[url]/[channel]/google.xml.ts @@ -1,8 +1,7 @@ import type { NextApiRequest, NextApiResponse } from "next"; -import { initUrqlClient } from "next-urql"; import { GoogleFeedProductVariantFragment } from "../../../../../../generated/graphql"; import { apl } from "../../../../../saleor-app"; -import { createLogger } from "@saleor/apps-shared"; +import { createGraphQLClient, createLogger } from "@saleor/apps-shared"; import { fetchProductData } from "../../../../../modules/google-feed/fetch-product-data"; import { GoogleFeedSettingsFetcher } from "../../../../../modules/google-feed/get-google-feed-settings"; import { generateGoogleXmlFeed } from "../../../../../modules/google-feed/generate-google-xml-feed"; @@ -67,12 +66,10 @@ export const handler = async (req: NextApiRequest, res: NextApiResponse) => { /** * use unauthorized client to eliminate possibility of spilling the non-public data */ - const client = initUrqlClient( - { - url: authData.saleorApiUrl, - }, - false - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); if (!client) { logger.error("Can't create the gql client"); diff --git a/apps/search/.graphqlrc.yml b/apps/search/.graphqlrc.yml index ee7c7af..b0db306 100644 --- a/apps/search/.graphqlrc.yml +++ b/apps/search/.graphqlrc.yml @@ -10,7 +10,6 @@ extensions: plugins: - typescript - typescript-operations - - urql-introspection - typescript-urql: documentVariablePrefix: "Untyped" fragmentVariablePrefix: "Untyped" diff --git a/apps/search/package.json b/apps/search/package.json index be810ae..f4c4f59 100644 --- a/apps/search/package.json +++ b/apps/search/package.json @@ -20,14 +20,13 @@ "@saleor/react-hook-form-macaw": "workspace:*", "@sentry/nextjs": "^7.46.0", "@types/debug": "^4.1.7", - "@urql/exchange-auth": "^1.0.0", + "@urql/exchange-auth": "^2.1.4", "algoliasearch": "4.14.2", "clsx": "^1.2.1", "debug": "^4.3.4", "graphql": "16.6.0", "graphql-tag": "^2.12.6", "next": "13.3.0", - "next-urql": "4.0.3", "pino": "^8.14.1", "pino-pretty": "^10.0.0", "react": "18.2.0", @@ -35,7 +34,7 @@ "react-helmet": "^6.1.0", "react-hook-form": "^7.43.9", "react-query": "^3.39.3", - "urql": "^3.0.3", + "urql": "^4.0.4", "zod": "^3.20.2" }, "devDependencies": { @@ -46,7 +45,6 @@ "@graphql-codegen/typescript": "3.0.2", "@graphql-codegen/typescript-operations": "3.0.2", "@graphql-codegen/typescript-urql": "3.7.3", - "@graphql-codegen/urql-introspection": "2.2.1", "@graphql-typed-document-node/core": "3.2.0", "@types/react": "18.2.5", "@types/react-dom": "18.2.5", diff --git a/apps/search/src/components/useQueryAllProducts.tsx b/apps/search/src/components/useQueryAllProducts.tsx index e733601..25f5688 100644 --- a/apps/search/src/components/useQueryAllProducts.tsx +++ b/apps/search/src/components/useQueryAllProducts.tsx @@ -5,7 +5,7 @@ import { ProductsDataForImportDocument, ProductsDataForImportQuery, } from "../../generated/graphql"; -import { nextClient } from "../lib/graphql"; +import { createGraphQLClient } from "@saleor/apps-shared"; const PER_PAGE = 100; @@ -29,7 +29,7 @@ export const useQueryAllProducts = (paused: boolean) => { } const token = appBridgeState.token; - const client = nextClient(saleorApiUrl, () => Promise.resolve({ token })); + const client = createGraphQLClient({ saleorApiUrl, token }); if (!client) { return; diff --git a/apps/search/src/lib/algolia/getAlgoliaConfiguration.ts b/apps/search/src/lib/algolia/getAlgoliaConfiguration.ts index 7d8d1b6..07be217 100644 --- a/apps/search/src/lib/algolia/getAlgoliaConfiguration.ts +++ b/apps/search/src/lib/algolia/getAlgoliaConfiguration.ts @@ -1,7 +1,7 @@ import { AuthData } from "@saleor/app-sdk/APL"; import { createDebug } from "../debug"; -import { createClient } from "../graphql"; import { createSettingsManager } from "../metadata"; +import { createGraphQLClient } from "@saleor/apps-shared"; interface GetAlgoliaConfigurationArgs { authData: AuthData; @@ -10,9 +10,10 @@ interface GetAlgoliaConfigurationArgs { const debug = createDebug("getAlgoliaConfiguration"); export const getAlgoliaConfiguration = async ({ authData }: GetAlgoliaConfigurationArgs) => { - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: authData.saleorApiUrl, + token: authData.token, + }); const settings = createSettingsManager(client); diff --git a/apps/search/src/lib/graphql.ts b/apps/search/src/lib/graphql.ts deleted file mode 100644 index cab2c53..0000000 --- a/apps/search/src/lib/graphql.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { initUrqlClient } from "next-urql"; -import { AuthConfig, authExchange } from "@urql/exchange-auth"; -import { - cacheExchange, Client, - createClient as urqlCreateClient, - dedupExchange, - fetchExchange -} from "urql"; - -interface IAuthState { - token: string; -} - -const getExchanges = (getAuth: AuthConfig["getAuth"]) => [ - dedupExchange, - cacheExchange, - authExchange({ - addAuthToOperation: ({ authState, operation }) => { - if (!authState || !authState?.token) { - return operation; - } - - const fetchOptions = - typeof operation.context.fetchOptions === "function" - ? operation.context.fetchOptions() - : operation.context.fetchOptions || {}; - - return { - ...operation, - context: { - ...operation.context, - fetchOptions: { - ...fetchOptions, - headers: { - ...fetchOptions.headers, - "Authorization-Bearer": authState.token, - }, - }, - }, - }; - }, - getAuth, - }), - fetchExchange, -]; - -export const nextClient = (url: string, getAuth: AuthConfig["getAuth"]) => { - return initUrqlClient( - { - url, - exchanges: getExchanges(getAuth), - }, - false - ); -}; - -export const createClient = (url: string, getAuth: AuthConfig["getAuth"]) => - urqlCreateClient({ - url, - exchanges: getExchanges(getAuth), - }); - -export type SimpleGraphqlClient = Pick; diff --git a/apps/search/src/lib/metadata.ts b/apps/search/src/lib/metadata.ts index 3225e47..e29b2a9 100644 --- a/apps/search/src/lib/metadata.ts +++ b/apps/search/src/lib/metadata.ts @@ -1,9 +1,16 @@ -import { EncryptedMetadataManager, MetadataEntry, SettingsManager } from "@saleor/app-sdk/settings-manager"; +import { + EncryptedMetadataManager, + MetadataEntry, + SettingsManager, +} from "@saleor/app-sdk/settings-manager"; -import { FetchAppDetailsDocument, FetchAppDetailsQuery, UpdateAppMetadataDocument } from "../../generated/graphql"; +import { + FetchAppDetailsDocument, + FetchAppDetailsQuery, + UpdateAppMetadataDocument, +} from "../../generated/graphql"; import { settingsManagerSecretKey } from "../../saleor-app"; -import { SimpleGraphqlClient } from "./graphql"; - +import { Client } from "urql"; /* * Function is using urql graphql client to fetch all available metadata. @@ -11,7 +18,7 @@ import { SimpleGraphqlClient } from "./graphql"; * which can be used by the manager. * Result of this query is cached by the manager. */ -export async function fetchAllMetadata(client: SimpleGraphqlClient): Promise { +export async function fetchAllMetadata(client: Client): Promise { const { error, data } = await client .query(FetchAppDetailsDocument, {}) .toPromise(); @@ -29,7 +36,7 @@ export async function fetchAllMetadata(client: SimpleGraphqlClient): Promise { +export const createSettingsManager = (client: Client): SettingsManager => { /* * EncryptedMetadataManager gives you interface to manipulate metadata and cache values in memory. * We recommend it for production, because all values are encrypted. diff --git a/apps/search/src/pages/api/configuration.ts b/apps/search/src/pages/api/configuration.ts index 00dbcf3..bf03ca9 100644 --- a/apps/search/src/pages/api/configuration.ts +++ b/apps/search/src/pages/api/configuration.ts @@ -1,7 +1,6 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { SettingsManager } from "@saleor/app-sdk/settings-manager"; -import { createClient } from "../../lib/graphql"; import { createSettingsManager } from "../../lib/metadata"; import { saleorApp } from "../../../saleor-app"; @@ -10,6 +9,7 @@ import { createLogger } from "../../lib/logger"; import { AppConfigurationFields } from "../../domain/configuration"; import { AlgoliaSearchProvider } from "../../lib/algolia/algoliaSearchProvider"; import { WebhookActivityTogglerService } from "../../domain/WebhookActivityToggler.service"; +import { createGraphQLClient } from "@saleor/apps-shared"; const logger = createLogger({ handler: "api/configuration", @@ -51,7 +51,10 @@ export const handler = async ( logger.debug({ saleorApiUrl }, "handler called"); - const client = createClient(saleorApiUrl, async () => Promise.resolve({ token: token })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); const settings = createSettingsManager(client); diff --git a/apps/search/src/pages/api/webhooks-status.ts b/apps/search/src/pages/api/webhooks-status.ts index 966d339..73e53da 100644 --- a/apps/search/src/pages/api/webhooks-status.ts +++ b/apps/search/src/pages/api/webhooks-status.ts @@ -1,6 +1,5 @@ import { createProtectedHandler, NextProtectedApiHandler } from "@saleor/app-sdk/handlers/next"; import { saleorApp } from "../../../saleor-app"; -import { createClient, SimpleGraphqlClient } from "../../lib/graphql"; import { FetchOwnWebhooksDocument } from "../../../generated/graphql"; import { AlgoliaSearchProvider } from "../../lib/algolia/algoliaSearchProvider"; import { createSettingsManager } from "../../lib/metadata"; @@ -10,8 +9,9 @@ import { } from "../../domain/WebhookActivityToggler.service"; import { createLogger } from "../../lib/logger"; import { SettingsManager } from "@saleor/app-sdk/settings-manager"; -import { Client } from "urql"; import { SearchProvider } from "../../lib/searchProvider"; +import { createGraphQLClient } from "@saleor/apps-shared"; +import { Client } from "urql"; const logger = createLogger({ service: "webhooksStatusHandler", @@ -21,13 +21,10 @@ const logger = createLogger({ * Simple dependency injection - factory injects all services, in tests everything can be configured without mocks */ type FactoryProps = { - settingsManagerFactory: (client: SimpleGraphqlClient) => SettingsManager; - webhookActivityTogglerFactory: ( - appId: string, - client: SimpleGraphqlClient - ) => IWebhookActivityTogglerService; + settingsManagerFactory: (client: Client) => SettingsManager; + webhookActivityTogglerFactory: (appId: string, client: Client) => IWebhookActivityTogglerService; algoliaSearchProviderFactory: (appId: string, apiKey: string) => Pick; - graphqlClientFactory: (saleorApiUrl: string, token: string) => SimpleGraphqlClient; + graphqlClientFactory: (saleorApiUrl: string, token: string) => Client; }; export const webhooksStatusHandlerFactory = @@ -113,9 +110,7 @@ export default createProtectedHandler( return new AlgoliaSearchProvider({ appId, apiKey }); }, graphqlClientFactory(saleorApiUrl: string, token: string) { - return createClient(saleorApiUrl, async () => ({ - token, - })); + return createGraphQLClient({ saleorApiUrl, token }); }, }), saleorApp.apl, diff --git a/apps/search/src/pages/api/webhooks/saleor/product_created.ts b/apps/search/src/pages/api/webhooks/saleor/product_created.ts index 7a8b8a1..b0e7941 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_created.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_created.ts @@ -4,8 +4,8 @@ import { saleorApp } from "../../../../../saleor-app"; import { AlgoliaSearchProvider } from "../../../../lib/algolia/algoliaSearchProvider"; import { getAlgoliaConfiguration } from "../../../../lib/algolia/getAlgoliaConfiguration"; import { WebhookActivityTogglerService } from "../../../../domain/WebhookActivityToggler.service"; -import { createClient } from "../../../../lib/graphql"; import { createLogger } from "../../../../lib/logger"; +import { createGraphQLClient } from "@saleor/apps-shared"; export const config = { api: { @@ -62,7 +62,7 @@ export const handler: NextWebhookApiHandler = async (req, res, c const webhooksToggler = new WebhookActivityTogglerService( authData.appId, - createClient(authData.saleorApiUrl, async () => ({ token: authData.token })) + createGraphQLClient({ saleorApiUrl: authData.saleorApiUrl, token: authData.token }) ); logger.trace("Will disable webhooks"); diff --git a/apps/search/src/pages/api/webhooks/saleor/product_deleted.ts b/apps/search/src/pages/api/webhooks/saleor/product_deleted.ts index a965c36..e4a511f 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_deleted.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_deleted.ts @@ -5,8 +5,8 @@ import { AlgoliaSearchProvider } from "../../../../lib/algolia/algoliaSearchProv import { getAlgoliaConfiguration } from "../../../../lib/algolia/getAlgoliaConfiguration"; import { createDebug } from "../../../../lib/debug"; import { WebhookActivityTogglerService } from "../../../../domain/WebhookActivityToggler.service"; -import { createClient } from "../../../../lib/graphql"; import { createLogger } from "../../../../lib/logger"; +import { createGraphQLClient } from "@saleor/apps-shared"; export const config = { api: { @@ -63,7 +63,7 @@ export const handler: NextWebhookApiHandler = async (req, res, c const webhooksToggler = new WebhookActivityTogglerService( authData.appId, - createClient(authData.saleorApiUrl, async () => ({ token: authData.token })) + createGraphQLClient({ saleorApiUrl: authData.saleorApiUrl, token: authData.token }) ); logger.trace("Will disable webhooks"); diff --git a/apps/search/src/pages/api/webhooks/saleor/product_updated.ts b/apps/search/src/pages/api/webhooks/saleor/product_updated.ts index a2994a5..661cf69 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_updated.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_updated.ts @@ -4,8 +4,8 @@ import { saleorApp } from "../../../../../saleor-app"; import { AlgoliaSearchProvider } from "../../../../lib/algolia/algoliaSearchProvider"; import { getAlgoliaConfiguration } from "../../../../lib/algolia/getAlgoliaConfiguration"; import { WebhookActivityTogglerService } from "../../../../domain/WebhookActivityToggler.service"; -import { createClient } from "../../../../lib/graphql"; import { createLogger } from "../../../../lib/logger"; +import { createGraphQLClient } from "@saleor/apps-shared"; export const config = { api: { @@ -62,7 +62,7 @@ export const handler: NextWebhookApiHandler = async (req, res, c const webhooksToggler = new WebhookActivityTogglerService( authData.appId, - createClient(authData.saleorApiUrl, async () => ({ token: authData.token })) + createGraphQLClient({ saleorApiUrl: authData.saleorApiUrl, token: authData.token }) ); logger.trace("Will disable webhooks"); diff --git a/apps/search/src/pages/api/webhooks/saleor/product_variant_created.ts b/apps/search/src/pages/api/webhooks/saleor/product_variant_created.ts index a569974..2ea637a 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_variant_created.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_variant_created.ts @@ -9,7 +9,7 @@ import { getAlgoliaConfiguration } from "../../../../lib/algolia/getAlgoliaConfi import { createDebug } from "../../../../lib/debug"; import { createLogger } from "../../../../lib/logger"; import { WebhookActivityTogglerService } from "../../../../domain/WebhookActivityToggler.service"; -import { createClient } from "../../../../lib/graphql"; +import { createGraphQLClient } from "@saleor/apps-shared"; export const config = { api: { @@ -65,7 +65,7 @@ export const handler: NextWebhookApiHandler = async (req, const webhooksToggler = new WebhookActivityTogglerService( authData.appId, - createClient(authData.saleorApiUrl, async () => ({ token: authData.token })) + createGraphQLClient({ saleorApiUrl: authData.saleorApiUrl, token: authData.token }) ); logger.trace("Will disable webhooks"); diff --git a/apps/search/src/pages/api/webhooks/saleor/product_variant_deleted.ts b/apps/search/src/pages/api/webhooks/saleor/product_variant_deleted.ts index 58fbed6..50b853f 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_variant_deleted.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_variant_deleted.ts @@ -9,7 +9,7 @@ import { getAlgoliaConfiguration } from "../../../../lib/algolia/getAlgoliaConfi import { createDebug } from "../../../../lib/debug"; import { createLogger } from "../../../../lib/logger"; import { WebhookActivityTogglerService } from "../../../../domain/WebhookActivityToggler.service"; -import { createClient } from "../../../../lib/graphql"; +import { createGraphQLClient } from "@saleor/apps-shared"; export const config = { api: { @@ -66,7 +66,7 @@ export const handler: NextWebhookApiHandler = async (req, const webhooksToggler = new WebhookActivityTogglerService( authData.appId, - createClient(authData.saleorApiUrl, async () => ({ token: authData.token })) + createGraphQLClient({ saleorApiUrl: authData.saleorApiUrl, token: authData.token }) ); logger.trace("Will disable webhooks"); diff --git a/apps/search/src/pages/api/webhooks/saleor/product_variant_updated.ts b/apps/search/src/pages/api/webhooks/saleor/product_variant_updated.ts index 14414d2..24a6d01 100644 --- a/apps/search/src/pages/api/webhooks/saleor/product_variant_updated.ts +++ b/apps/search/src/pages/api/webhooks/saleor/product_variant_updated.ts @@ -9,7 +9,7 @@ import { getAlgoliaConfiguration } from "../../../../lib/algolia/getAlgoliaConfi import { createDebug } from "../../../../lib/debug"; import { createLogger } from "../../../../lib/logger"; import { WebhookActivityTogglerService } from "../../../../domain/WebhookActivityToggler.service"; -import { createClient } from "../../../../lib/graphql"; +import { createGraphQLClient } from "@saleor/apps-shared"; export const config = { api: { @@ -66,7 +66,7 @@ export const handler: NextWebhookApiHandler = async (req, const webhooksToggler = new WebhookActivityTogglerService( authData.appId, - createClient(authData.saleorApiUrl, async () => ({ token: authData.token })) + createGraphQLClient({ saleorApiUrl: authData.saleorApiUrl, token: authData.token }) ); logger.trace("Will disable webhooks"); diff --git a/apps/search/src/providers/GraphQLProvider.tsx b/apps/search/src/providers/GraphQLProvider.tsx index 33b3611..22b41d4 100644 --- a/apps/search/src/providers/GraphQLProvider.tsx +++ b/apps/search/src/providers/GraphQLProvider.tsx @@ -2,7 +2,7 @@ import { useAppBridge } from "@saleor/app-sdk/app-bridge"; import { PropsWithChildren } from "react"; import { Provider } from "urql"; -import { createClient } from "../lib/graphql"; +import { createGraphQLClient } from "@saleor/apps-shared"; export function GraphQLProvider(props: PropsWithChildren<{}>) { const { appBridgeState } = useAppBridge(); @@ -12,9 +12,10 @@ export function GraphQLProvider(props: PropsWithChildren<{}>) { return
; } - const client = createClient(saleorApiUrl, async () => - Promise.resolve({ token: appBridgeState?.token! }) - ); + const client = createGraphQLClient({ + saleorApiUrl, + token: appBridgeState.token, + }); return ; } diff --git a/apps/slack/.graphqlrc.yml b/apps/slack/.graphqlrc.yml index ee7c7af..b0db306 100644 --- a/apps/slack/.graphqlrc.yml +++ b/apps/slack/.graphqlrc.yml @@ -10,7 +10,6 @@ extensions: plugins: - typescript - typescript-operations - - urql-introspection - typescript-urql: documentVariablePrefix: "Untyped" fragmentVariablePrefix: "Untyped" diff --git a/apps/slack/package.json b/apps/slack/package.json index ccb1fdd..df4910a 100644 --- a/apps/slack/package.json +++ b/apps/slack/package.json @@ -18,7 +18,7 @@ "@saleor/apps-shared": "workspace:*", "@saleor/macaw-ui": "^0.7.2", "@sentry/nextjs": "^7.30.0", - "@urql/exchange-auth": "^1.0.0", + "@urql/exchange-auth": "^2.1.4", "clsx": "^1.2.1", "eslint": "8.42.0", "graphql": "16.6.0", @@ -30,7 +30,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-helmet": "^6.1.0", - "urql": "^3.0.3", + "urql": "^4.0.4", "usehooks-ts": "^2.9.1", "vite": "4.3.9", "vitest": "0.31.3" @@ -43,7 +43,6 @@ "@graphql-codegen/typescript": "3.0.2", "@graphql-codegen/typescript-operations": "3.0.2", "@graphql-codegen/typescript-urql": "3.7.3", - "@graphql-codegen/urql-introspection": "2.2.1", "@graphql-typed-document-node/core": "3.2.0", "@types/react": "18.2.5", "@types/react-dom": "18.2.5", diff --git a/apps/slack/src/lib/graphql.ts b/apps/slack/src/lib/graphql.ts deleted file mode 100644 index 1448c8a..0000000 --- a/apps/slack/src/lib/graphql.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { AuthConfig, authExchange } from "@urql/exchange-auth"; -import { - cacheExchange, - createClient as urqlCreateClient, - dedupExchange, - fetchExchange, -} from "urql"; - -interface IAuthState { - token: string; -} - -export const createClient = (url: string, getAuth: AuthConfig["getAuth"]) => - urqlCreateClient({ - url, - exchanges: [ - dedupExchange, - cacheExchange, - authExchange({ - addAuthToOperation: ({ authState, operation }) => { - if (!authState || !authState?.token) { - return operation; - } - - const fetchOptions = - typeof operation.context.fetchOptions === "function" - ? operation.context.fetchOptions() - : operation.context.fetchOptions || {}; - - return { - ...operation, - context: { - ...operation.context, - fetchOptions: { - ...fetchOptions, - headers: { - ...fetchOptions.headers, - "Authorization-Bearer": authState.token, - }, - }, - }, - }; - }, - getAuth, - }), - fetchExchange, - ], - }); diff --git a/apps/slack/src/pages/api/configuration.ts b/apps/slack/src/pages/api/configuration.ts index 6f44e6e..75ec4a2 100644 --- a/apps/slack/src/pages/api/configuration.ts +++ b/apps/slack/src/pages/api/configuration.ts @@ -1,9 +1,9 @@ import { createProtectedHandler, ProtectedHandlerContext } from "@saleor/app-sdk/handlers/next"; import { NextApiRequest, NextApiResponse } from "next"; -import { createClient } from "../../lib/graphql"; import { createSettingsManager } from "../../lib/metadata"; import { saleorApp } from "../../lib/saleor-app"; +import { createGraphQLClient } from "@saleor/apps-shared"; const WEBHOOK_URL = "WEBHOOK_URL"; @@ -20,7 +20,10 @@ export const handler = async ( authData: { token, saleorApiUrl, appId }, } = ctx; - const client = createClient(saleorApiUrl, async () => Promise.resolve({ token })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); const settings = createSettingsManager(client, appId); diff --git a/apps/slack/src/pages/api/webhooks/order-created.ts b/apps/slack/src/pages/api/webhooks/order-created.ts index 0716d7b..6330933 100644 --- a/apps/slack/src/pages/api/webhooks/order-created.ts +++ b/apps/slack/src/pages/api/webhooks/order-created.ts @@ -2,10 +2,10 @@ import { NextWebhookApiHandler, SaleorAsyncWebhook } from "@saleor/app-sdk/handl import { gql } from "urql"; import { OrderCreatedWebhookPayloadFragment } from "../../../../generated/graphql"; -import { createClient } from "../../../lib/graphql"; import { createSettingsManager } from "../../../lib/metadata"; import { saleorApp } from "../../../lib/saleor-app"; import { sendSlackMessage } from "../../../lib/slack"; +import { createGraphQLClient } from "@saleor/apps-shared"; const OrderCreatedWebhookPayload = gql` fragment OrderCreatedWebhookPayload on OrderCreated { @@ -82,7 +82,10 @@ const handler: NextWebhookApiHandler = async const { saleorApiUrl, token, appId } = authData; - const client = createClient(saleorApiUrl, async () => Promise.resolve({ token })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); const settings = createSettingsManager(client, appId); diff --git a/apps/taxes/.graphqlrc.yml b/apps/taxes/.graphqlrc.yml index ee7c7af..b0db306 100644 --- a/apps/taxes/.graphqlrc.yml +++ b/apps/taxes/.graphqlrc.yml @@ -10,7 +10,6 @@ extensions: plugins: - typescript - typescript-operations - - urql-introspection - typescript-urql: documentVariablePrefix: "Untyped" fragmentVariablePrefix: "Untyped" diff --git a/apps/taxes/package.json b/apps/taxes/package.json index 74bc51a..664c769 100644 --- a/apps/taxes/package.json +++ b/apps/taxes/package.json @@ -24,8 +24,7 @@ "@trpc/next": "^10.9.0", "@trpc/react-query": "^10.9.0", "@trpc/server": "^10.9.0", - "@urql/exchange-auth": "^1.0.0", - "@urql/exchange-multipart-fetch": "^1.0.1", + "@urql/exchange-auth": "^2.1.4", "avatax": "^23.3.2", "clsx": "^1.2.1", "dotenv": "^16.0.3", @@ -40,7 +39,7 @@ "react-dom": "18.2.0", "react-hook-form": "^7.43.9", "taxjar": "^4.0.1", - "urql": "^3.0.3", + "urql": "^4.0.4", "usehooks-ts": "^2.9.1", "vite": "4.3.9", "vitest": "0.31.3", @@ -54,7 +53,6 @@ "@graphql-codegen/typescript": "3.0.2", "@graphql-codegen/typescript-operations": "3.0.2", "@graphql-codegen/typescript-urql": "3.7.3", - "@graphql-codegen/urql-introspection": "2.2.1", "@graphql-typed-document-node/core": "3.2.0", "@testing-library/react": "^13.4.0", "@testing-library/react-hooks": "^8.0.1", diff --git a/apps/taxes/scripts/migrations/migration-utils.ts b/apps/taxes/scripts/migrations/migration-utils.ts index 45c98a9..d232873 100644 --- a/apps/taxes/scripts/migrations/migration-utils.ts +++ b/apps/taxes/scripts/migrations/migration-utils.ts @@ -1,13 +1,14 @@ /* eslint-disable turbo/no-undeclared-env-vars */ import { SaleorCloudAPL } from "@saleor/app-sdk/APL"; -import { createClient } from "../../src/lib/graphql"; import { createSettingsManager } from "../../src/modules/app/metadata-manager"; +import { createGraphQLClient } from "@saleor/apps-shared"; export const getMetadataManagerForEnv = (apiUrl: string, appToken: string, appId: string) => { - const client = createClient(apiUrl, async () => ({ + const client = createGraphQLClient({ + saleorApiUrl: apiUrl, token: appToken, - })); + }); return createSettingsManager(client, appId); }; diff --git a/apps/taxes/scripts/migrations/run-generate-dummy-data.ts b/apps/taxes/scripts/migrations/run-generate-dummy-data.ts index 5934ea9..c90f99f 100644 --- a/apps/taxes/scripts/migrations/run-generate-dummy-data.ts +++ b/apps/taxes/scripts/migrations/run-generate-dummy-data.ts @@ -1,5 +1,4 @@ import { saleorApp } from "../../saleor-app"; -import { createClient } from "../../src/lib/graphql"; import { Logger, createLogger } from "../../src/lib/logger"; import { createSettingsManager } from "../../src/modules/app/metadata-manager"; import { TaxProvidersV1 } from "./tax-providers-config-schema-v1"; @@ -8,6 +7,7 @@ import { ChannelsV1 } from "./channels-config-schema-v1"; import * as dotenv from "dotenv"; import { TaxChannelsPrivateMetadataManagerV1 } from "./tax-channels-metadata-manager-v1"; +import { createGraphQLClient } from "@saleor/apps-shared"; dotenv.config(); @@ -94,9 +94,11 @@ class DummyConfigGenerator { console.log({ dummyTaxProvidersConfig, dummyTaxChannelsConfig }, "Dummy configs generated"); - const client = createClient(target.saleorApiUrl, async () => - Promise.resolve({ token: target.token }) - ); + const client = createGraphQLClient({ + saleorApiUrl: target.saleorApiUrl, + token: target.token, + }); + const metadataManager = createSettingsManager(client, target.appId); const taxProvidersManager = new TaxProvidersPrivateMetadataManagerV1( metadataManager, diff --git a/apps/taxes/src/lib/graphql.ts b/apps/taxes/src/lib/graphql.ts deleted file mode 100644 index 6ed95c6..0000000 --- a/apps/taxes/src/lib/graphql.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { AuthConfig, authExchange } from "@urql/exchange-auth"; -import { cacheExchange, createClient as urqlCreateClient, dedupExchange } from "urql"; - -import { multipartFetchExchange } from "@urql/exchange-multipart-fetch"; - -interface IAuthState { - token: string; -} - -export const createClient = (url: string, getAuth: AuthConfig["getAuth"]) => - urqlCreateClient({ - url, - exchanges: [ - dedupExchange, - cacheExchange, - authExchange({ - addAuthToOperation: ({ authState, operation }) => { - if (!authState || !authState?.token) { - return operation; - } - - const fetchOptions = - typeof operation.context.fetchOptions === "function" - ? operation.context.fetchOptions() - : operation.context.fetchOptions || {}; - - return { - ...operation, - context: { - ...operation.context, - fetchOptions: { - ...fetchOptions, - headers: { - ...fetchOptions.headers, - "Authorization-Bearer": authState.token, - }, - }, - }, - }; - }, - getAuth, - }), - multipartFetchExchange, - ], - }); diff --git a/apps/taxes/src/modules/trpc/protected-client-procedure.ts b/apps/taxes/src/modules/trpc/protected-client-procedure.ts index ec273fe..52594a3 100644 --- a/apps/taxes/src/modules/trpc/protected-client-procedure.ts +++ b/apps/taxes/src/modules/trpc/protected-client-procedure.ts @@ -1,10 +1,10 @@ -import { createClient } from "../../lib/graphql"; import { verifyJWT } from "@saleor/app-sdk/verify-jwt"; import { middleware, procedure } from "./trpc-server"; import { saleorApp } from "../../../saleor-app"; import { TRPCError } from "@trpc/server"; import { ProtectedHandlerError } from "@saleor/app-sdk/handlers/next"; import { logger } from "../../lib/logger"; +import { createGraphQLClient } from "@saleor/apps-shared"; const attachAppToken = middleware(async ({ ctx, next }) => { logger.debug("attachAppToken middleware"); @@ -103,9 +103,10 @@ export const protectedClientProcedure = procedure .use(attachAppToken) .use(validateClientToken) .use(async ({ ctx, next }) => { - const client = createClient(ctx.saleorApiUrl, async () => - Promise.resolve({ token: ctx.appToken }) - ); + const client = createGraphQLClient({ + saleorApiUrl: ctx.saleorApiUrl, + token: ctx.appToken, + }); return next({ ctx: { diff --git a/apps/taxes/src/pages/api/register.ts b/apps/taxes/src/pages/api/register.ts index da6bfd2..018de72 100644 --- a/apps/taxes/src/pages/api/register.ts +++ b/apps/taxes/src/pages/api/register.ts @@ -1,8 +1,11 @@ import { createAppRegisterHandler } from "@saleor/app-sdk/handlers/next"; import { REQUIRED_SALEOR_VERSION, saleorApp } from "../../../saleor-app"; -import { createLogger, SaleorVersionCompatibilityValidator } from "@saleor/apps-shared"; -import { createClient } from "../../lib/graphql"; +import { + createGraphQLClient, + createLogger, + SaleorVersionCompatibilityValidator, +} from "@saleor/apps-shared"; import { gql } from "urql"; import { SaleorVersionQuery } from "../../../generated/graphql"; @@ -46,10 +49,9 @@ export default createAppRegisterHandler({ }); try { - const client = createClient(saleorApiUrl, async () => { - return { - token, - }; + const client = createGraphQLClient({ + saleorApiUrl, + token, }); const saleorVersion = await client diff --git a/apps/taxes/src/pages/api/webhooks/order-created.ts b/apps/taxes/src/pages/api/webhooks/order-created.ts index 5f3b772..dbe3fef 100644 --- a/apps/taxes/src/pages/api/webhooks/order-created.ts +++ b/apps/taxes/src/pages/api/webhooks/order-created.ts @@ -10,10 +10,10 @@ import { import { saleorApp } from "../../../../saleor-app"; import { createLogger } from "../../../lib/logger"; import { getActiveConnection } from "../../../modules/taxes/active-connection"; -import { createClient } from "../../../lib/graphql"; import { Client } from "urql"; import { WebhookResponse } from "../../../modules/app/webhook-response"; import { PROVIDER_ORDER_ID_KEY } from "../../../modules/avatax/order-fulfilled/avatax-order-fulfilled-payload-transformer"; +import { createGraphQLClient } from "@saleor/apps-shared"; export const config = { api: { @@ -90,7 +90,10 @@ export default orderCreatedAsyncWebhook.createHandler(async (req, res, ctx) => { const createdOrder = await taxProvider.createOrder(payload.order); logger.info({ createdOrder }, "Order created"); - const client = createClient(saleorApiUrl, async () => Promise.resolve({ token })); + const client = createGraphQLClient({ + saleorApiUrl, + token, + }); await updateOrderMetadataWithExternalId(client, payload.order.id, createdOrder.id); logger.info("Updated order metadata with externalId"); diff --git a/apps/taxes/src/providers/GraphQLProvider.tsx b/apps/taxes/src/providers/GraphQLProvider.tsx index 8019543..aea5cdb 100644 --- a/apps/taxes/src/providers/GraphQLProvider.tsx +++ b/apps/taxes/src/providers/GraphQLProvider.tsx @@ -2,7 +2,7 @@ import { useAppBridge } from "@saleor/app-sdk/app-bridge"; import { PropsWithChildren } from "react"; import { Provider } from "urql"; -import { createClient } from "../lib/graphql"; +import { createGraphQLClient } from "@saleor/apps-shared"; export function GraphQLProvider(props: PropsWithChildren<{}>) { const { appBridgeState } = useAppBridge(); @@ -11,9 +11,10 @@ export function GraphQLProvider(props: PropsWithChildren<{}>) { return
; } - const client = createClient(appBridgeState?.saleorApiUrl, async () => - Promise.resolve({ token: appBridgeState?.token! }) - ); + const client = createGraphQLClient({ + saleorApiUrl: appBridgeState.saleorApiUrl, + token: appBridgeState.token, + }); return ; } diff --git a/packages/shared/index.ts b/packages/shared/index.ts index 36795f8..405dc8b 100644 --- a/packages/shared/index.ts +++ b/packages/shared/index.ts @@ -4,3 +4,4 @@ export * from "./src/no-ssr-wrapper"; export * from "./src/use-dashboard-notification"; export * from "./src/logger"; export * from "./src/saleor-version-compatibility-validator"; +export * from "./src/create-graphql-client"; diff --git a/packages/shared/package.json b/packages/shared/package.json index 531a9af..57a425f 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -5,11 +5,13 @@ "lint:fix": "eslint --fix ." }, "dependencies": { + "@urql/exchange-auth": "^2.1.4", "eslint": "8.42.0", "pino": "^8.14.1", "pino-pretty": "^10.0.0", "semver": "^7.5.1", - "typescript": "5.1.3" + "typescript": "5.1.3", + "urql": "^4.0.4" }, "devDependencies": { "@material-ui/core": "^4.12.4", diff --git a/packages/shared/src/create-graphql-client.ts b/packages/shared/src/create-graphql-client.ts new file mode 100644 index 0000000..cae30cd --- /dev/null +++ b/packages/shared/src/create-graphql-client.ts @@ -0,0 +1,45 @@ +import { authExchange } from "@urql/exchange-auth"; +import { cacheExchange, createClient as urqlCreateClient, fetchExchange } from "urql"; + +interface CreateGraphQLClientArgs { + saleorApiUrl: string; + token?: string; +} + +/* + * Creates instance of urql client with optional auth exchange (if token is provided). + * Accessing public parts of the Saleor API is possible without providing access token. + * When trying to access fields or operations protected by permissions. + * Token can be obtained: + * - by accessing token from appBridge https://github.com/saleor/saleor-app-sdk/blob/main/docs/app-bridge.md + * - by using token created during the app registration, saved in the APL https://github.com/saleor/saleor-app-sdk/blob/main/docs/apl.md + * - by token create mutation https://docs.saleor.io/docs/3.x/api-usage/authentication + * + * In the context of developing Apps, the two first options are recommended. + */ +export const createGraphQLClient = ({ saleorApiUrl, token }: CreateGraphQLClientArgs) => { + return urqlCreateClient({ + url: saleorApiUrl, + exchanges: [ + cacheExchange, + authExchange(async (utils) => { + return { + addAuthToOperation(operation) { + const headers: Record = token + ? { + "Authorization-Bearer": token, + } + : {}; + + return utils.appendHeaders(operation, headers); + }, + didAuthError(error) { + return error.graphQLErrors.some((e) => e.extensions?.code === "FORBIDDEN"); + }, + async refreshAuth() {}, + }; + }), + fetchExchange, + ], + }); +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9d194b5..0091a4d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,8 +65,8 @@ importers: specifier: ^7.43.0 version: 7.43.0(next@13.3.0)(react@18.2.0) '@urql/exchange-auth': - specifier: ^1.0.0 - version: 1.0.0(graphql@16.6.0) + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) clsx: specifier: ^1.2.1 version: 1.2.1 @@ -98,8 +98,8 @@ importers: specifier: ^8.0.5 version: 8.0.5(@types/react@18.2.5)(react@18.2.0) urql: - specifier: ^3.0.3 - version: 3.0.3(graphql@16.6.0)(react@18.2.0) + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) usehooks-ts: specifier: ^2.9.1 version: 2.9.1(react-dom@18.2.0)(react@18.2.0) @@ -131,9 +131,6 @@ importers: '@graphql-codegen/typescript-urql': specifier: 3.7.3 version: 3.7.3(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/urql-introspection': - specifier: 2.2.1 - version: 2.2.1(graphql@16.6.0) '@graphql-typed-document-node/core': specifier: 3.2.0 version: 3.2.0(graphql@16.6.0) @@ -198,8 +195,8 @@ importers: specifier: ^10.18.0 version: 10.18.0 '@urql/exchange-auth': - specifier: ^1.0.0 - version: 1.0.0(graphql@16.6.0) + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) '@vitejs/plugin-react': specifier: 4.0.0 version: 4.0.0(vite@4.3.9) @@ -218,9 +215,6 @@ importers: next: specifier: 13.3.0 version: 13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) - next-urql: - specifier: 4.0.3 - version: 4.0.3(react@18.2.0)(urql@3.0.3) pino: specifier: ^8.14.1 version: 8.14.1 @@ -240,8 +234,8 @@ importers: specifier: ^18.2.0 version: 18.2.0 urql: - specifier: ^3.0.3 - version: 3.0.3(graphql@16.6.0)(react@18.2.0) + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) usehooks-ts: specifier: ^2.9.1 version: 2.9.1(react-dom@18.2.0)(react@18.2.0) @@ -273,9 +267,6 @@ importers: '@graphql-codegen/typescript-urql': specifier: 3.7.3 version: 3.7.3(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/urql-introspection': - specifier: 2.2.1 - version: 2.2.1(graphql@16.6.0) '@graphql-typed-document-node/core': specifier: 3.2.0 version: 3.2.0(graphql@16.6.0) @@ -331,8 +322,8 @@ importers: specifier: ^7.39.0 version: 7.39.0(next@13.3.0)(react@18.2.0) '@urql/exchange-auth': - specifier: ^1.0.0 - version: 1.0.0(graphql@16.6.0) + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) '@vitejs/plugin-react': specifier: 4.0.0 version: 4.0.0(vite@4.3.9) @@ -373,8 +364,8 @@ importers: specifier: 18.2.0 version: 18.2.0(react@18.2.0) urql: - specifier: ^3.0.3 - version: 3.0.3(graphql@16.6.0)(react@18.2.0) + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) usehooks-ts: specifier: ^2.9.1 version: 2.9.1(react-dom@18.2.0)(react@18.2.0) @@ -409,9 +400,6 @@ importers: '@graphql-codegen/typescript-urql': specifier: 3.7.3 version: 3.7.3(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/urql-introspection': - specifier: 2.2.1 - version: 2.2.1(graphql@16.6.0) '@graphql-typed-document-node/core': specifier: 3.2.0 version: 3.2.0(graphql@16.6.0) @@ -491,8 +479,8 @@ importers: specifier: ^10.13.0 version: 10.14.0 '@urql/exchange-auth': - specifier: ^1.0.0 - version: 1.0.0(graphql@16.6.0) + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) '@vitejs/plugin-react': specifier: 4.0.0 version: 4.0.0(vite@4.3.9) @@ -523,9 +511,6 @@ importers: next: specifier: 13.3.0 version: 13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) - next-urql: - specifier: 4.0.3 - version: 4.0.3(react@18.2.0)(urql@3.0.3) nodemailer: specifier: ^6.9.1 version: 6.9.1 @@ -551,8 +536,8 @@ importers: specifier: ^3.39.3 version: 3.39.3(react-dom@18.2.0)(react@18.2.0) urql: - specifier: ^3.0.3 - version: 3.0.3(graphql@16.6.0)(react@18.2.0) + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) usehooks-ts: specifier: ^2.9.1 version: 2.9.1(react-dom@18.2.0)(react@18.2.0) @@ -587,9 +572,6 @@ importers: '@graphql-codegen/typescript-urql': specifier: 3.7.3 version: 3.7.3(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/urql-introspection': - specifier: 2.2.1 - version: 2.2.1(graphql@16.6.0) '@graphql-typed-document-node/core': specifier: 3.2.0 version: 3.2.0(graphql@16.6.0) @@ -657,11 +639,8 @@ importers: specifier: ^10.10.0 version: 10.10.0 '@urql/exchange-auth': - specifier: ^1.0.0 - version: 1.0.0(graphql@16.6.0) - '@urql/exchange-multipart-fetch': - specifier: ^1.0.1 - version: 1.0.1(graphql@16.6.0) + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) '@web-std/file': specifier: ^3.0.2 version: 3.0.2 @@ -702,8 +681,8 @@ importers: specifier: ^1.3.1 version: 1.3.1 urql: - specifier: ^3.0.3 - version: 3.0.3(graphql@16.6.0)(react@18.2.0) + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) usehooks-ts: specifier: ^2.9.1 version: 2.9.1(react-dom@18.2.0)(react@18.2.0) @@ -732,9 +711,6 @@ importers: '@graphql-codegen/typescript-urql': specifier: 3.7.3 version: 3.7.3(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/urql-introspection': - specifier: 2.2.1 - version: 2.2.1(graphql@16.6.0) '@graphql-typed-document-node/core': specifier: 3.2.0 version: 3.2.0(graphql@16.6.0) @@ -799,8 +775,8 @@ importers: specifier: ^7.36.0 version: 7.36.0(next@13.3.0)(react@18.2.0) '@urql/exchange-auth': - specifier: ^1.0.0 - version: 1.0.0(graphql@16.6.0) + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) clsx: specifier: ^1.2.1 version: 1.2.1 @@ -832,8 +808,8 @@ importers: specifier: ^6.1.0 version: 6.1.0(react@18.2.0) urql: - specifier: ^3.0.3 - version: 3.0.3(graphql@16.6.0)(react@18.2.0) + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) vite: specifier: 4.3.9 version: 4.3.9(@types/node@18.15.3) @@ -862,9 +838,6 @@ importers: '@graphql-codegen/typescript-urql': specifier: 3.7.3 version: 3.7.3(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/urql-introspection': - specifier: 2.2.1 - version: 2.2.1(graphql@16.6.0) '@graphql-typed-document-node/core': specifier: 3.2.0 version: 3.2.0(graphql@16.6.0) @@ -917,8 +890,8 @@ importers: specifier: ^0.7.2 version: 0.7.2(@material-ui/core@4.12.4)(@material-ui/icons@4.11.3)(@material-ui/lab@4.0.0-alpha.61)(@types/react@18.2.5)(react-dom@18.2.0)(react-helmet@6.1.0)(react@18.2.0) '@urql/exchange-auth': - specifier: ^1.0.0 - version: 1.0.0(graphql@16.6.0) + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) '@vitejs/plugin-react': specifier: 4.0.0 version: 4.0.0(vite@4.3.9) @@ -953,8 +926,8 @@ importers: specifier: ^7.42.1 version: 7.43.1(react@18.2.0) urql: - specifier: ^3.0.3 - version: 3.0.3(graphql@16.6.0)(react@18.2.0) + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) vite: specifier: 4.3.9 version: 4.3.9(@types/node@18.15.3) @@ -983,9 +956,6 @@ importers: '@graphql-codegen/typescript-urql': specifier: 3.7.3 version: 3.7.3(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/urql-introspection': - specifier: 2.2.1 - version: 2.2.1(graphql@16.6.0) '@graphql-typed-document-node/core': specifier: 3.2.0 version: 3.2.0(graphql@16.6.0) @@ -1053,8 +1023,8 @@ importers: specifier: ^10.9.0 version: 10.10.0 '@urql/exchange-auth': - specifier: ^1.0.0 - version: 1.0.0(graphql@16.6.0) + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) '@vitejs/plugin-react': specifier: 4.0.0 version: 4.0.0(vite@4.3.9) @@ -1076,9 +1046,6 @@ importers: next: specifier: 13.3.0 version: 13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) - next-urql: - specifier: 4.0.3 - version: 4.0.3(react@18.2.0)(urql@3.0.3) pino: specifier: ^8.14.1 version: 8.14.1 @@ -1101,8 +1068,8 @@ importers: specifier: ^3.39.3 version: 3.39.3(react-dom@18.2.0)(react@18.2.0) urql: - specifier: ^3.0.3 - version: 3.0.3(graphql@16.6.0)(react@18.2.0) + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) usehooks-ts: specifier: ^2.9.1 version: 2.9.1(react-dom@18.2.0)(react@18.2.0) @@ -1137,9 +1104,6 @@ importers: '@graphql-codegen/typescript-urql': specifier: 3.7.3 version: 3.7.3(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/urql-introspection': - specifier: 2.2.1 - version: 2.2.1(graphql@16.6.0) '@graphql-typed-document-node/core': specifier: 3.2.0 version: 3.2.0(graphql@16.6.0) @@ -1192,8 +1156,8 @@ importers: specifier: ^4.1.7 version: 4.1.7 '@urql/exchange-auth': - specifier: ^1.0.0 - version: 1.0.0(graphql@16.6.0) + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) algoliasearch: specifier: 4.14.2 version: 4.14.2 @@ -1212,9 +1176,6 @@ importers: next: specifier: 13.3.0 version: 13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0) - next-urql: - specifier: 4.0.3 - version: 4.0.3(react@18.2.0)(urql@3.0.3) pino: specifier: ^8.14.1 version: 8.14.1 @@ -1237,8 +1198,8 @@ importers: specifier: ^3.39.3 version: 3.39.3(react-dom@18.2.0)(react@18.2.0) urql: - specifier: ^3.0.3 - version: 3.0.3(graphql@16.6.0)(react@18.2.0) + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) zod: specifier: ^3.20.2 version: 3.20.2 @@ -1264,9 +1225,6 @@ importers: '@graphql-codegen/typescript-urql': specifier: 3.7.3 version: 3.7.3(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/urql-introspection': - specifier: 2.2.1 - version: 2.2.1(graphql@16.6.0) '@graphql-typed-document-node/core': specifier: 3.2.0 version: 3.2.0(graphql@16.6.0) @@ -1322,8 +1280,8 @@ importers: specifier: ^7.30.0 version: 7.36.0(next@13.3.0)(react@18.2.0) '@urql/exchange-auth': - specifier: ^1.0.0 - version: 1.0.0(graphql@16.6.0) + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) clsx: specifier: ^1.2.1 version: 1.2.1 @@ -1358,8 +1316,8 @@ importers: specifier: ^6.1.0 version: 6.1.0(react@18.2.0) urql: - specifier: ^3.0.3 - version: 3.0.3(graphql@16.6.0)(react@18.2.0) + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) usehooks-ts: specifier: ^2.9.1 version: 2.9.1(react-dom@18.2.0)(react@18.2.0) @@ -1391,9 +1349,6 @@ importers: '@graphql-codegen/typescript-urql': specifier: 3.7.3 version: 3.7.3(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/urql-introspection': - specifier: 2.2.1 - version: 2.2.1(graphql@16.6.0) '@graphql-typed-document-node/core': specifier: 3.2.0 version: 3.2.0(graphql@16.6.0) @@ -1467,11 +1422,8 @@ importers: specifier: ^10.9.0 version: 10.10.0 '@urql/exchange-auth': - specifier: ^1.0.0 - version: 1.0.0(graphql@16.6.0) - '@urql/exchange-multipart-fetch': - specifier: ^1.0.1 - version: 1.0.1(graphql@16.6.0) + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) avatax: specifier: ^23.3.2 version: 23.3.2 @@ -1515,8 +1467,8 @@ importers: specifier: ^4.0.1 version: 4.0.1 urql: - specifier: ^3.0.3 - version: 3.0.3(graphql@16.6.0)(react@18.2.0) + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) usehooks-ts: specifier: ^2.9.1 version: 2.9.1(react-dom@18.2.0)(react@18.2.0) @@ -1551,9 +1503,6 @@ importers: '@graphql-codegen/typescript-urql': specifier: 3.7.3 version: 3.7.3(graphql-tag@2.12.6)(graphql@16.6.0) - '@graphql-codegen/urql-introspection': - specifier: 2.2.1 - version: 2.2.1(graphql@16.6.0) '@graphql-typed-document-node/core': specifier: 3.2.0 version: 3.2.0(graphql@16.6.0) @@ -1678,6 +1627,9 @@ importers: packages/shared: dependencies: + '@urql/exchange-auth': + specifier: ^2.1.4 + version: 2.1.4(graphql@16.6.0) eslint: specifier: 8.42.0 version: 8.42.0 @@ -1693,6 +1645,9 @@ importers: typescript: specifier: 5.1.3 version: 5.1.3 + urql: + specifier: ^4.0.4 + version: 4.0.4(graphql@16.6.0)(react@18.2.0) devDependencies: '@material-ui/core': specifier: ^4.12.4 @@ -1791,6 +1746,17 @@ packages: uuid: 8.3.2 dev: false + /@0no-co/graphql.web@1.0.4(graphql@16.6.0): + resolution: {integrity: sha512-W3ezhHGfO0MS1PtGloaTpg0PbaT8aZSmmaerL7idtU5F7oCI+uu25k+MsMS31BVFlp4aMkHSrNRxiD72IlK8TA==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + peerDependenciesMeta: + graphql: + optional: true + dependencies: + graphql: 16.6.0 + dev: false + /@algolia/cache-browser-local-storage@4.14.2: resolution: {integrity: sha512-FRweBkK/ywO+GKYfAWbrepewQsPTIEirhi1BdykX9mxvBPtGNKccYAxvGdDCumU1jL4r3cayio4psfzKMejBlA==} dependencies: @@ -5792,17 +5758,6 @@ packages: - supports-color dev: true - /@graphql-codegen/urql-introspection@2.2.1(graphql@16.6.0): - resolution: {integrity: sha512-/KjHSf4dQNoYZZ+G10b3lbw304ik9xHzRf/syNvoYehmwdYE5J7RnO1v1Cz78LDm2NEdsFas6vJHi0sJd/pOHg==} - 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 - dependencies: - '@graphql-codegen/plugin-helpers': 2.7.2(graphql@16.6.0) - '@urql/introspection': 0.3.3(graphql@16.6.0) - graphql: 16.6.0 - tslib: 2.4.1 - dev: true - /@graphql-codegen/visitor-plugin-common@2.13.1(graphql@16.6.0): resolution: {integrity: sha512-mD9ufZhDGhyrSaWQGrU1Q1c5f01TeWtSWy/cDwXYjJcHIj1Y/DG2x0tOflEfCvh5WcnmHNIw4lzDsg1W7iFJEg==} peerDependencies: @@ -10016,44 +9971,24 @@ packages: eslint-visitor-keys: 3.4.1 dev: true - /@urql/core@3.1.1(graphql@16.6.0): - resolution: {integrity: sha512-Mnxtq4I4QeFJsgs7Iytw+HyhiGxISR6qtyk66c9tipozLZ6QVxrCiUPF2HY4BxNIabaxcp+rivadvm8NAnXj4Q==} - peerDependencies: - graphql: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + /@urql/core@4.0.10(graphql@16.6.0): + resolution: {integrity: sha512-Vs3nOSAnYftqOCg034Ostp/uSqWlQg5ryLIzcOrm8+O43s4M+Ew4GQAuemIH7ZDB8dek6h61zzWI3ujd8FH3NA==} dependencies: - graphql: 16.6.0 - wonka: 6.1.2 + '@0no-co/graphql.web': 1.0.4(graphql@16.6.0) + wonka: 6.3.2 + transitivePeerDependencies: + - graphql dev: false - /@urql/exchange-auth@1.0.0(graphql@16.6.0): - resolution: {integrity: sha512-79hqPQab+ifeINOxvQykvqub4ixWHBEIagN4U67ijcHGMfp3c4yEWRk4IJMPwF+OMT7LrRFuv+jRIZTQn/9VwQ==} - peerDependencies: - graphql: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + /@urql/exchange-auth@2.1.4(graphql@16.6.0): + resolution: {integrity: sha512-ijAKSgswusrProxrusX8TcYntCgMptQiirdNHwgy0EcWucxQ+1zgxiRNFKpkaRMpGk5WCFeCpsXTEYtlvuFmDg==} dependencies: - '@urql/core': 3.1.1(graphql@16.6.0) - graphql: 16.6.0 - wonka: 6.1.2 + '@urql/core': 4.0.10(graphql@16.6.0) + wonka: 6.3.2 + transitivePeerDependencies: + - graphql dev: false - /@urql/exchange-multipart-fetch@1.0.1(graphql@16.6.0): - resolution: {integrity: sha512-fjxRrKR/D9Rs52L8wJMvqsGQBC/mjFcg/VdkSkU5IXmqCb5KmicXl2208hoCnaBl/QLA6NDpCNnG3zjDniMOTg==} - peerDependencies: - graphql: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - '@urql/core': 3.1.1(graphql@16.6.0) - extract-files: 11.0.0 - graphql: 16.6.0 - wonka: 6.1.2 - dev: false - - /@urql/introspection@0.3.3(graphql@16.6.0): - resolution: {integrity: sha512-tekSLLqWnusfV6V7xaEnLJQSdXOD/lWy7f8JYQwrX+88Md+voGSCSx5WJXI7KLBN3Tat2OV08tAr8UROykls4Q==} - peerDependencies: - graphql: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - dependencies: - graphql: 16.6.0 - dev: true - /@vanilla-extract/babel-plugin-debug-ids@1.0.3: resolution: {integrity: sha512-vm4jYu1xhSa6ofQ9AhIpR3DkAp4c+eoR1Rpm8/TQI4DmWbmGbOjYRcqV0aWsfaIlNhN4kFuxFMKBNN9oG6iRzA==} dependencies: @@ -13385,6 +13320,7 @@ packages: /extract-files@11.0.0: resolution: {integrity: sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==} engines: {node: ^12.20 || >= 14.13} + dev: true /extract-files@9.0.0: resolution: {integrity: sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==} @@ -16854,17 +16790,6 @@ packages: /neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - /next-urql@4.0.3(react@18.2.0)(urql@3.0.3): - resolution: {integrity: sha512-pesvwu1ZuGzMla8tPMo0V0yiV3ObDF4dbZyZLB2rZoORy+ebdWtClU/pfz1XDrPEgzyfGC3tqvbR5gH7Kt59XA==} - peerDependencies: - react: '>=16.8.0' - urql: ^3.0.0 - dependencies: - react: 18.2.0 - react-ssr-prepass: 1.5.0(react@18.2.0) - urql: 3.0.3(graphql@16.6.0)(react@18.2.0) - dev: false - /next@13.3.0(@babel/core@7.22.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-OVTw8MpIPa12+DCUkPqRGPS3thlJPcwae2ZL4xti3iBff27goH024xy4q2lhlsdoYiKOi8Kz6uJoLW/GXwgfOA==} engines: {node: '>=14.6.0'} @@ -20507,16 +20432,16 @@ packages: braces: 3.0.2 dev: true - /urql@3.0.3(graphql@16.6.0)(react@18.2.0): - resolution: {integrity: sha512-aVUAMRLdc5AOk239DxgXt6ZxTl/fEmjr7oyU5OGo8uvpqu42FkeJErzd2qBzhAQ3DyusoZIbqbBLPlnKo/yy2A==} + /urql@4.0.4(graphql@16.6.0)(react@18.2.0): + resolution: {integrity: sha512-C5P4BMnAsk+rbytCWglit5ijXbIKXsa9wofSGPbuMyJKsDdL+9GfipS362Nff/Caag+eYOK5W+sox8fwEILT6Q==} peerDependencies: - graphql: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 react: '>= 16.8.0' dependencies: - '@urql/core': 3.1.1(graphql@16.6.0) - graphql: 16.6.0 + '@urql/core': 4.0.10(graphql@16.6.0) react: 18.2.0 - wonka: 6.1.2 + wonka: 6.3.2 + transitivePeerDependencies: + - graphql dev: false /use-callback-ref@1.3.0(@types/react@18.2.5)(react@18.2.0): @@ -21144,8 +21069,8 @@ packages: engines: {node: '>=0.8'} dev: false - /wonka@6.1.2: - resolution: {integrity: sha512-zNrXPMccg/7OEp9tSfFkMgTvhhowqasiSHdJ3eCZolXxVTV/aT6HUTofoZk9gwRbGoFey/Nss3JaZKUMKMbofg==} + /wonka@6.3.2: + resolution: {integrity: sha512-2xXbQ1LnwNS7egVm1HPhW2FyKrekolzhpM3mCwXdQr55gO+tAiY76rhb32OL9kKsW8taj++iP7C6hxlVzbnvrw==} dev: false /word-wrap@1.2.3: