[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-graphql-ide/react/components/Controller.tsx from the admin-graphql-ide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import GraphiQL from 'graphiql'
import { buildClientSchema, GraphQLSchema, IntrospectionQuery, introspectionQuery } from 'graphql'
import { path } from 'ramda'
import React, { Fragment } from 'react'
import { defineMessages, InjectedIntlProps, injectIntl } from 'react-intl'
import { EXPERIMENTAL_Select, Spinner } from 'vtex.styleguide'

import { getOrCreateScopedStorage } from '../utils/storage'
import { ErrorState } from './ErrorState'
import { NoAppSelected } from './NoAppSelected'

type Fetcher = (params: any) => Promise<string>

enum ViewState {
  ON_ERROR = 'error',
  ON_SELECT_APP = 'select',
  ON_GRAPHIQL = 'graphiql',
  ON_FETCHING_SCHEMA = 'fetch',
}

interface State {
  error: boolean
  chosenAppId: string | undefined
  schema: GraphQLSchema | undefined
  fetcher: Fetcher | undefined
  mode: ViewState
}

interface Props extends InjectedIntlProps {
  apps: string[]
}

const fetcherForApp = (appId: string) => (params: any) => fetch(`/_v/private/admin-graphql-ide/v0/${appId}`, {
  body: JSON.stringify(params),
  headers: { 'Content-Type': 'application/json' },
  method: 'post',
}).then(response => response.json())

const messages = defineMessages({
  appChooser: {
    id: 'admin/controller.app-picker',
    defaultMessage: "Choose your app from the list below"
  }
})

class GraphiQLControllerComponent extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props)
    this.state = {
      chosenAppId: undefined,
      error: false,
      fetcher: undefined,
      schema: undefined,
      mode: ViewState.ON_SELECT_APP
    }
  }

  public setState = (state: any, cb?: () => void) => {
    const { schema, chosenAppId, error, fetcher }: any = typeof state === 'function' ? state(this.state) : { ...this.state, ...state }
    let mode: ViewState
    if (error) {
      mode = ViewState.ON_ERROR
    } else if (!schema && fetcher && chosenAppId) {
      mode = ViewState.ON_FETCHING_SCHEMA
    } else if (schema && chosenAppId) {
      mode = ViewState.ON_GRAPHIQL
    } else {
      mode = ViewState.ON_SELECT_APP
    }

    super.setState({
      schema,
      chosenAppId,
      error,
      fetcher,
      mode,
    }, () => {
      if (mode === ViewState.ON_FETCHING_SCHEMA) {
        this.fetchSchema()
      }
      if (cb) {
        cb()
      }
    })
  }

  public render = () => (
    <Fragment>
      <div className="mb5 z-max">
        <EXPERIMENTAL_Select
          label={this.props.intl.formatMessage(messages.appChooser)}
          options={this.props.apps.map(app => ({ value: app, label: app }))}
          multi={false}
          onChange={(chosen: { value?: string } | null) => this.setState(
            (oldState: State) => {
              const chosenAppId = chosen ? chosen.value : undefined
              return {
                ...oldState,
                chosenAppId,
                fetcher: chosenAppId ? fetcherForApp(chosenAppId) : undefined,
                schema: undefined,
              }
            }
          )}
        />
      </div>
      {
        this.state.mode === ViewState.ON_GRAPHIQL
          ? (
            <GraphiQL
              fetcher={this.state.fetcher}
              storage={getOrCreateScopedStorage(this.state.chosenAppId!)}
              schema={this.state.schema}
            />
          )
          : this.state.mode === ViewState.ON_SELECT_APP
            ? (
              <NoAppSelected />
            )
            : this.state.mode === ViewState.ON_FETCHING_SCHEMA
              ? (
                <Spinner />
              )
              : (
                <ErrorState
                  onRetryClick={() => this.setState({ error: false })}
                />
              )
      }
    </Fragment>
  )

  private fetchSchema = async () => {
    try {
      const response = await this.state.fetcher!({ query: introspectionQuery })
      const schema = path(['data'], response) as IntrospectionQuery | undefined
      this.setState({
        schema: schema && buildClientSchema(schema),
        error: schema ? false : true,
      })
    }
    catch (_) {
      this.setState({ error: true })
    }
  }
}

export const GraphiQLController = injectIntl(GraphiQLControllerComponent)
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-graphql-ide/react/components/ErrorState.tsx from the admin-graphql-ide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { FormattedMessage, injectIntl, InjectedIntlProps, defineMessages } from 'react-intl'
import { Button, EmptyState } from 'vtex.styleguide'

interface Props extends InjectedIntlProps {
  onRetryClick: () => void
}

const messages = defineMessages({
  errorShortMessage: {
    id: 'admin/error.title',
    defaultMessage: 'Something bad happened'
  }
})

const ErrorStateComponent: FunctionComponent<Props> = ({onRetryClick, intl}) => (
  <EmptyState title={intl.formatMessage(messages.errorShortMessage)}>
    <div className="pt5">
      <Button variation="secondary" size="small" onClick={onRetryClick}>
        <span className="flex align-baseline">
          <FormattedMessage id="admin/error.state" defaultMessage="Try Again" />
        </span>
      </Button>
    </div>
  </EmptyState>
)

export const ErrorState = injectIntl(ErrorStateComponent)
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-graphql-ide/react/components/NoAppSelected.tsx from the admin-graphql-ide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { defineMessages, FormattedMessage, InjectedIntlProps, injectIntl } from 'react-intl'
import { EmptyState } from 'vtex.styleguide'

const messages = defineMessages({
  title: {
    id: 'admin/no-app-selected.title',
    defaultMessage: 'Choose an App'
  }
})

const NoAppSelectedComponent: FunctionComponent<InjectedIntlProps> = ({intl}) => (
  <EmptyState title={intl.formatMessage(messages.title)}>
    <p>
      <FormattedMessage
        id='admin/no-app-selected.state'
        defaultMessage="Please choose an App to start making queries to"
      />
    </p>
  </EmptyState>
)

export const NoAppSelected = injectIntl(NoAppSelectedComponent)
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-graphql-ide/react/graphql/getApps.tsx from the admin-graphql-ide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { Query as QueryComponent } from 'react-apollo'

import { Query } from '../../typedql/schema'
import getAppsQuery from './apps.graphql'

type Data = Pick<Query, 'apps'>

interface Props {
  children: (data: any) => React.ReactNode
}

export const GetApps: FunctionComponent<Props> = ({children}) => (
 <QueryComponent<Data> query={getAppsQuery}>
    {({data, loading}) => {
      if (loading) {
        return null
      }
      return children!(data)
    }}
  </QueryComponent>
)
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of admin-graphql-ide/react/graphql/apps.graphql from the admin-graphql-ide VTEX app.

[Assistant]
Here's the implementation:

```graphql
query GetApps {
  apps @context(provider: "vtex.admin-graphql-ide")
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of landing-pages/docs/README.md from the landing-pages VTEX app.

[Assistant]
Here's the implementation:

```markdown
# VTEX Landing Pages

This app aggregates all landing pages served by VTEX IO.

Each landing page has its own IO App:

- [TETRIX](https://tetrix.vtex.com): https://github.com/vtex-apps/tetrix
- [VTEX Code Cup](https://codecup.vtex.com): https://github.com/vtex-apps/code-cup
- [VTEX IO](https://vtex.io): https://github.com/vtex-apps/io-landing
- [VTEX IO Docs](https://vtex.io/docs): https://github.com/vtex-apps/docs-ui

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/docs/README.md from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```markdown
📢 Use this project, [contribute](https://github.com/vtex-apps/affirm-components) to it or open issues to help evolve it using [Store Discussion](https://github.com/vtex-apps/store-discussion).

# Affirm Components

This app provides promotional messaging components related to the Affirm payment method.

## Configuration

1. Follow the install instructions for [Affirm Payment](https://github.com/vtex-apps/affirm-payment)
2. Add `"vtex.affirm-components": "0.x"` to your store-theme dependencies.
3. Place the desired Affirm component blocks in your `/store/` folder.

The available blocks are:

- `"product-teaser.product.affirm"`: This block should be placed on the product page (PDP). It displays a promotional message such as `As low as \$\__/mo at _% APR` followed by a `Prequalify now` or `Learn More` link.
- `"product-teaser.summary.affirm"`: Similar to the above but designed to be placed on product shelves.

## Customization

In order to apply CSS customizations to this and other blocks, follow the instructions given in the recipe on [Using CSS Handles for store customization](https://vtex.io/docs/recipes/style/using-css-handles-for-store-customization).

| CSS Handles          |
|----------------------|
| `affirmPromo`        |
| `affirmPromoSummary` |

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/package.json from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "affirm-components",
  "version": "0.0.9",
  "description": "",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "VTEX",
  "license": "UNLICENSED",
  "dependencies": {
    "apollo-cache": "^1.3.4",
    "apollo-client": "^2.6.8",
    "apollo-link": "^1.2.13",
    "apollo-utilities": "^1.3.3",
    "graphql": "^14.0.2",
    "ramda": "^0.27.0",
    "react": "^16.8.6",
    "react-apollo": "^3.1.3",
    "react-dom": "^16.8.5"
  },
  "devDependencies": {
    "@types/bootstrap": "^4.3.0",
    "@types/graphql": "^14.0.5",
    "@types/jquery": "^3.3.34",
    "@types/node": "^10.14.4",
    "@types/ramda": "^0.27.0",
    "@types/react": "^16.8.8",
    "@types/react-dom": "^16.8.3",
    "vtex.affirm-components": "https://betocheckout--sandboxusdev.myvtex.com/_v/private/typings/linked/v1/vtex.affirm-components@0.0.5+build1644630177/public/@types/vtex.affirm-components",
    "vtex.affirm-payment": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.affirm-payment@2.1.8-beta.0/public/@types/vtex.affirm-payment",
    "vtex.css-handles": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.css-handles@0.4.4/public/@types/vtex.css-handles",
    "vtex.product-context": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.product-context@0.10.0/public/@types/vtex.product-context",
    "vtex.product-summary-context": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.product-summary-context@0.9.0/public/@types/vtex.product-summary-context",
    "vtex.product-teaser-interfaces": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.product-teaser-interfaces@1.0.2/public/_types/react",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.132.3/public/@types/vtex.render-runtime",
    "vtex.store": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.store@2.122.0/public/@types/vtex.store"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/AffirmPromo.tsx from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import AffirmPromo from './components/AffirmPromo'

export default AffirmPromo

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/AffirmSummaryPromo.tsx from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import AffirmSummaryPromo from './components/AffirmSummaryPromo'

export default AffirmSummaryPromo

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/store/interfaces.json from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "product-teaser.product.affirm": {
    "component": "AffirmPromo"
  },
  "product-teaser.summary.affirm": {
    "component": "AffirmSummaryPromo"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/public/metadata/messages/es-AR.json from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```json

{
  "name": "Affirm",
  "headline": "Permita que sus clientes paguen en cuotas con Affirm.",
  "overview": "Affirm es una forma sencilla y transparente de que los clientes paguen sus compras en cuotas. Al utilizar Affirm, puede mostrar un precio de pago mensual para cada ítem, mostrando a sus clientes un plan de pago de su elección y que se ajuste a su presupuesto. Conecte esta aplicación a su tienda VTEX y podrá ofrecer a sus clientes una forma alternativa de pagar en cuotas.",
  "features": [
   "Muestre opciones de financiación para los clientes en la página del producto",
   "Permita que sus clientes paguen a través del método de pago Affirm"
  ],
  "websiteURL": "https://vtex.com/",
  "support": {
    "url": "https://help-tickets.vtex.com/en/support?app=vtex.affirm-payment"
  }
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/public/metadata/messages/pt-BR.json from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```json

{
  "name": "Affirm",
  "headline": "Disponibilize aos seus clientes a opção de pagar a prazo com o Affirm.",
  "overview": "O Affirm oferece uma maneira simples e transparente de pagar compras a prazo. Ao utilizar o Affirm, é possível exibir o preço a ser pago mensalmente para cada item, disponibilizando aos clientes um cronograma de acordo com o orçamento desejado. Conecte este aplicativo à sua loja VTEX e empodere seus clientes com uma forma alternativa de pagamento a prazo.",
  "features": [
   "Exibe opções de financiamento para os clientes na página do produto",
   "Permite que os clientes paguem através do meio de pagamento Affirm"
  ],
  "websiteURL": "https://vtex.com/",
  "support": {
    "url": "https://help-tickets.vtex.com/en/support?app=vtex.affirm-payment"
  }
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/public/metadata/messages/en-US.json from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```json

{
  "name": "Affirm",
  "headline": "Allow shoppers to pay over time with Affirm.",
  "overview": "Affirm is a simple and transparent way for customers to pay for purchases over time. By using Affirm, you can display a monthly payment price for each item — showing shoppers a budget friendly schedule of their choosing. Connect this app to your VTEX store and you'll be able to empower your customers with an alternative way to pay over time.",
  "features": [
    "Displays financing options for shoppers on the product page",
    "Allows shoppers to pay through the Affirm payment method"
  ],
  "websiteURL": "https://vtex.com/",
  "support": {
    "url": "https://help-tickets.vtex.com/en/support?app=vtex.affirm-payment"
  }
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/typings/storefront.d.ts from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { FunctionComponent } from 'react'

declare global {
  interface StorefrontFunctionComponent<P = {}> extends FunctionComponent<P> {
    getSchema?(props: P): object
    schema?: object
  }

  interface StorefrontComponent<P = {}, S = {}> extends Component<P, S> {
    getSchema?(props: P): object
    schema: object
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/typings/vtex.product-context.d.ts from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.product-context/useProduct' {
  import { Context } from 'react'

  interface ProductContext {
    product: any
    selectedItem: any
  }

  export default function useProduct(): ProductContext
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/typings/global.d.ts from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare const vtex: any
interface Window extends Window {
  affirm: any
  _affirm_config: any
  modalTriggered: boolean
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/typings/vtex.product-summary-context.d.ts from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.product-summary-context/ProductSummaryContext' {
  import { Context } from 'react'

  interface ProductSummaryContext {
    product: any
    isLoading: boolean
  }

  export function useProductSummary(): ProductSummaryContext
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/typings/graphql.d.ts from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.graphql' {
  import { DocumentNode } from 'graphql'

  const value: DocumentNode
  export default value
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/components/AffirmPromo.tsx from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useProduct } from 'vtex.product-context'
import React, { useEffect } from 'react'
import { useQuery } from 'react-apollo'
import { useCssHandles } from 'vtex.css-handles'

import useScriptLoader from './hooks/useScriptLoader'
import Settings from '../graphql/Settings.graphql'

interface AffirmPromoProps {
  affirmSettings: AffirmSettings
}

interface AffirmSettings {
  publicApiKey: string
  isLive: boolean
}

const CSS_HANDLES = ['affirmPromo'] as const

const AffirmPromoDiv: StorefrontFunctionComponent<AffirmPromoProps> = ({
  affirmSettings,
}) => {
  const { publicApiKey = '', isLive = false } = affirmSettings

  const [affirm, { error }] = useScriptLoader(
    isLive
      ? 'https://cdn1.affirm.com/js/v2/affirm.js'
      : 'https://cdn1-sandbox.affirm.com/js/v2/affirm.js',
    'affirm'
  )
  const productContext = useProduct()
  const product = productContext?.product
  const selectedItem = productContext?.selectedItem
  const selectedQty = productContext?.selectedQuantity ?? 1

  const handles = useCssHandles(CSS_HANDLES)

  useEffect(() => {
    if (!affirm || error || !publicApiKey) return

    window._affirm_config = {
      public_api_key: publicApiKey,
    }

    affirm.ui.refresh()
  }, [affirm, error, publicApiKey])

  useEffect(() => {
    if (!affirm || error || !publicApiKey) return

    affirm.ui.refresh()
  }, [selectedItem, selectedQty])

  if (!product || !selectedItem || !affirm || error || !publicApiKey) {
    return null
  }

  const price = selectedItem.sellers[0].commertialOffer.Price

  return (
    <p
      className={`affirm-as-low-as ${handles.affirmPromo}`}
      data-page-type="product"
      data-amount={price * selectedQty * 100}
    ></p>
  )
}

const AffirmPromo: StorefrontFunctionComponent = () => {
  const { data: settingsData } = useQuery(Settings, { ssr: false })

  if (!settingsData?.affirmSettings) return null

  return <AffirmPromoDiv affirmSettings={settingsData.affirmSettings} />
}

export default AffirmPromo

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/components/AffirmSummaryPromo.tsx from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useProductSummary } from 'vtex.product-summary-context/ProductSummaryContext'
import React, { useEffect } from 'react'
import { useQuery } from 'react-apollo'
import { path, prop } from 'ramda'
import { useCssHandles } from 'vtex.css-handles'

import useScriptLoader from './hooks/useScriptLoader'
import Settings from '../graphql/Settings.graphql'

interface AffirmPromoProps {
  affirmSettings: AffirmSettings
}

interface AffirmSettings {
  publicApiKey: string
  isLive: boolean
}

const CSS_HANDLES = ['affirmPromoSummary'] as const

const AffirmSummaryPromoDiv: StorefrontFunctionComponent<AffirmPromoProps> = ({
  affirmSettings,
}) => {
  const { publicApiKey = '', isLive = false } = affirmSettings

  const [affirm, { error }] = useScriptLoader(
    isLive
      ? 'https://cdn1.affirm.com/js/v2/affirm.js'
      : 'https://cdn1-sandbox.affirm.com/js/v2/affirm.js',
    'affirm'
  )

  useEffect(() => {
    if (!affirm || error || !publicApiKey || window._affirm_config) return

    window._affirm_config = {
      public_api_key: publicApiKey,
    }
    affirm.ui.refresh()
  }, [affirm, error, publicApiKey])

  const handles = useCssHandles(CSS_HANDLES)
  const { product, isLoading } = useProductSummary()
  const commertialOffer = path<any>(
    ['sku', 'seller', 'commertialOffer'],
    product
  )

  const price = prop('Price', commertialOffer)

  if (
    isLoading ||
    !affirm ||
    !product ||
    !commertialOffer ||
    error ||
    !publicApiKey
  )
    return null

  return (
    <p
      className={`affirm-as-low-as ${handles.affirmPromoSummary}`}
      data-page-type="category"
      data-amount={price * 100}
    ></p>
  )
}

const AffirmSummaryPromo: StorefrontFunctionComponent = () => {
  const { data: settingsData } = useQuery(Settings, { ssr: false })

  if (!settingsData?.affirmSettings) return null

  return <AffirmSummaryPromoDiv affirmSettings={settingsData.affirmSettings} />
}

export default AffirmSummaryPromo

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/graphql/Settings.graphql from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Settings {
  affirmSettings @context(provider: "vtex.affirm-payment"){
    isLive
    enableKatapult
    companyName
    publicApiKey
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of affirm-components/react/components/hooks/useScriptLoader.tsx from the affirm-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useCallback, useEffect, useState } from 'react'

const useScriptLoader = <T extends object = any>(
  url: string,
  libName: string,
  init?: T
) => {
  const [x, setX] = useState<T>(init as any)
  const [error, setError] = useState<string>('')

  const reload = useCallback(() => {
    const script = document.createElement('script')
    setError('')

    script.src = url
    script.async = true

    script.onload = () => {
      setX((window as any)[libName])
      document.body.removeChild(script)
    }

    script.onerror = () => {
      setError(`<script src="${url}" /> error.`)
      document.body.removeChild(script)
    }

    script.onabort = () => {
      setError(`<script src="${url}" /> was aborted.`)
      document.body.removeChild(script)
    }

    document.body.appendChild(script)

    return () => {}
  }, [libName, url])

  useEffect(() => {
    return reload()
  }, [reload, url])

  const helper = {
    error,
    retry: reload,
  }
  const anwser: [typeof x, typeof helper] = [x, helper]
  return anwser
}

export default useScriptLoader

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/docs/README.md from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```markdown
# vtex.responsive-values

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

[![All Contributors](https://img.shields.io/badge/all_contributors-0-orange.svg?style=flat-square)](#contributors-)

<!-- ALL-CONTRIBUTORS-BADGE:END -->

Utility for using props that accept different values for different devices or media queries.

For example, a given prop could accept both just a number...

```js
props: {
  quantity: 1,
}
```

...or different values depending on the device or a media query:

```js
props: {
  quantity: {
    mobile: 1,
    desktop: 2,
    '(min-width: 1500px)': 4,
  }
}
```

...and the component, in turn, would use it like this:

```js
import { useResponsiveValue } from 'vtex.responsive-values'

const MyComponent = ({ quantity }) => {
  const quantity = useResponsiveValue(quantity)

  return {quantity}
}

<MyComponent quantity={1} /> {/* always returns 1 */}

<MyComponent quantity={{
  '(min-width: 1500px)': 4,
  desktop: 2,
  mobile: 1,
}} /> {/* returns 1 on mobile devices, 2 on desktop */}
```

Alternately, if you want to apply it to multiple values at once, or even the entire `props` object, you can use the hook `useResponsiveValues` (notice the plural) hook.

```tsx
import { useResponsiveValues } from 'vtex.responsive-values'

const MyComponent = props => {
  const { margin, padding } = useResponsiveValues(
    {
      margin: props.margin,
      padding: props.padding
    }
  )

  return (

      {props.children}

  )
}

<MyComponent margin={4} padding={4} /> {/* always returns margin 4 / padding 4 */}

<MyComponent
  margin={{
    desktop: 4,
    mobile: 2,
  }}
  padding={{
    desktop: 4,
    mobile: 2,
  }}
/> {/* returns 1 on mobile devices, 2 on desktop */}
```

There are some things to keep in mind when using media queries:

- Media queries take precedence over devices. If one matches, any device-specific value is ignored.
- Media queries are written following the [standard media query syntax](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#Syntax).
- The definiton order matters. If more than one media query is matched, the first matched one is used.

## API

Props that use this hook accept either a value by itself, or an object with the following options: `phone` and `tablet` separately (or just `mobile` for both), `desktop` and generic media queries.

If there is any missing device, it will fallback to the next largest one. For example, if only the values of `phone` and `desktop` are passed, `tablet` devices will receive the value from `desktop`. Media queries have no fallback behavior.

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/react/ResponsiveValuesTypes.ts from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```typescript
/** The user is able to input `mobile` as a device (as opposed to `desktop`),
 * but the output will be converted to `phone` and `tablet` */

export type InputDevice = 'mobile' | 'phone' | 'tablet' | 'desktop'
export type OutputDevice = 'phone' | 'tablet' | 'desktop'

// TODO: replace that `| string` with `MediaQueryString` when IO supports TS 4.1+
// type MinMax = 'min' | 'max'
// type Dimensions = 'width' | 'height'
// type Units = 'rem' | 'px' | 'px' | '%'
// type MediaQueryProperty = `${MinMax}-${Dimensions}`
// export type MediaQueryString = `(${MediaQueryProperty}:${number}${Units})`
export type ResponsiveInput<T> = Record<InputDevice | string, T>

export type ResponsiveValue<T> = T | ResponsiveInput<T>

// We can't know the values types beforehand, so we default them to unknown
export type ResponsiveValues = Record<string, ResponsiveValue<unknown>>

// Gets the type of a value wrapped in ResponsiveValues
export type GetResponsiveValueType<
  T extends ResponsiveValue<unknown>
> = T extends ResponsiveValue<infer U> ? U : never

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/react/useResponsiveValues.ts from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useDevice } from 'vtex.device-detector'

import type {
  GetResponsiveValueType,
  ResponsiveValues,
} from './ResponsiveValuesTypes'
import { normalizeResponsiveInputs } from './modules/normalizeResponsiveInput'
import {
  useMediaQueryList,
  findFirstMatchingQuery,
} from './hooks/useMediaQueryList'

type UsedResponsiveValues<Input> = {
  [key in keyof Input]: GetResponsiveValueType<Input[key]>
}

const useResponsiveValues = <Input extends ResponsiveValues>(
  input: Input
): UsedResponsiveValues<Input> => {
  const { device } = useDevice()

  const { inputList, queryList } = normalizeResponsiveInputs(input)
  const { mediaQueries } = useMediaQueryList(queryList)

  const result = {} as UsedResponsiveValues<Input>

  inputList.forEach(([key, values]) => {
    if (Object.keys(values.queries).length > 0) {
      const matched = findFirstMatchingQuery(mediaQueries)

      if (matched) {
        result[key] = values.queries[matched] as GetResponsiveValueType<
          Input[typeof key]
        >

        return
      }
    }

    result[key] = values.devices[device] as GetResponsiveValueType<
      Input[typeof key]
    >
  })

  return result
}

export default useResponsiveValues

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/react/package.json from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "scripts": {
    "lint": "tsc --noEmit && eslint --quiet --fix --ext ts,tsx .",
    "test": "vtex-test-tools test"
  },
  "dependencies": {
    "apollo-client": "^2.6.3",
    "react": "^16.8.6",
    "react-apollo": "^2.5.8",
    "react-dom": "^16.8.6",
    "react-intl": "3"
  },
  "devDependencies": {
    "@apollo/react-testing": "^4.0.0",
    "@testing-library/react-hooks": "^3.4.1",
    "@types/graphql": "^14.2.2",
    "@types/react": "^16.8.22",
    "@types/react-intl": "^2.3.18",
    "@vtex/test-tools": "^3.1.0",
    "typescript": "3.9.7"
  },
  "version": "0.4.2"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/react/useResponsiveValue.ts from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useDevice } from 'vtex.device-detector'

import type { ResponsiveValue } from './ResponsiveValuesTypes'
import { normalizeResponsiveInput } from './modules/normalizeResponsiveInput'
import {
  useMediaQueryList,
  findFirstMatchingQuery,
} from './hooks/useMediaQueryList'

const useResponsiveValue = <T>(input: ResponsiveValue<T>): T => {
  const { device } = useDevice()
  const { devices, queries } = normalizeResponsiveInput(input)
  const queryList = Object.keys(queries)
  const { mediaQueries } = useMediaQueryList(queryList)

  if (queryList.length > 0) {
    const matched = findFirstMatchingQuery(mediaQueries)

    if (matched) {
      return queries[matched]
    }
  }

  return devices[device]
}

export default useResponsiveValue

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/react/typings/vtex.device-detector.d.ts from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.device-detector' {
  interface Device {
    device: 'phone' | 'tablet' | 'desktop'
    isMobile: boolean
  }

  export function useDevice(): Device
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/react/__tests__/normalizeResponsiveInput.test.tsx from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```tsx
import {
  isResponsiveInput,
  normalizeResponsiveInput,
} from '../modules/normalizeResponsiveInput'

jest.spyOn(console, 'warn').mockImplementation()

afterEach(() => {
  jest.clearAllMocks()
})

describe('isResponsiveInput', () => {
  it('returns false if passed null', () => {
    const value = null

    expect(isResponsiveInput(value)).toBe(false)
  })

  it('returns false if passed a non-object', () => {
    const value = 2

    expect(isResponsiveInput(value)).toBe(false)
  })

  it('returns true if passed an object with a single device', () => {
    const value = {
      desktop: 1,
    }

    expect(isResponsiveInput(value)).toBe(true)
  })

  it('returns true if passed an object with all devices', () => {
    const value = {
      desktop: 1,
      mobile: 1,
      tablet: 1,
      phone: 1,
    }

    expect(isResponsiveInput(value)).toBe(true)
  })

  it('returns true if media queries are passed (wrapped between parenthesis)', () => {
    const value = {
      tablet: 1,
      '(max-width: 100px)': 1,
      '(max-width: 300px)': 2,
    }

    expect(isResponsiveInput(value)).toBe(true)
  })

  it('returns false if passed an object with an extraneous key', () => {
    const value = {
      desktop: 1,
      mobile: 1,
      tablet: 1,
      phone: 1,
      oops: 0,
      'max-width: 300px': 0,
    }

    expect(isResponsiveInput(value)).toBe(false)
  })
})

describe('responsiveValue', () => {
  it('complains if "mobile" is defined along with "tablet"', () => {
    const value = {
      tablet: 1,
      phone: 1,
      mobile: 2,
      desktop: 3,
    }

    const result = normalizeResponsiveInput(value)

    expect(console.warn).toBeCalled()

    expect(result).toStrictEqual({
      devices: { phone: 1, tablet: 1, desktop: 3 },
      queries: {},
    })
  })

  it('returns an object with equal keys if the input has all the parameters', () => {
    const value = {
      desktop: 1,
      tablet: 2,
      phone: 3,
    }

    expect(normalizeResponsiveInput(value)).toStrictEqual({
      devices: { desktop: 1, tablet: 2, phone: 3 },
      queries: {},
    })
  })

  describe('single values should populate the device object', () => {
    it('works with straight values', () => {
      const value = 1

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: { desktop: 1, tablet: 1, phone: 1 },
        queries: {},
      })
    })

    it('works with "desktop"', () => {
      const value = { desktop: 1 }

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: { desktop: 1, tablet: 1, phone: 1 },
        queries: {},
      })
    })

    it('works with "mobile"', () => {
      const value = { mobile: 1 }

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: { desktop: 1, tablet: 1, phone: 1 },
        queries: {},
      })
    })

    it('works with "tablet"', () => {
      const value = { tablet: 1 }

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: { desktop: 1, tablet: 1, phone: 1 },
        queries: {},
      })
    })

    it('works with "phone"', () => {
      const value = {
        phone: 1,
      }

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: { desktop: 1, tablet: 1, phone: 1 },
        queries: {},
      })
    })
  })

  describe('fallbacks', () => {
    it('tablet fallbacks to desktop instead of phone, when both are defined', () => {
      const value = {
        desktop: 1,
        phone: 2,
      }

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: { desktop: 1, tablet: 1, phone: 2 },
        queries: {},
      })
    })

    it('desktop fallbacks to tablet instead of phone, when both are defined', () => {
      const value = {
        tablet: 1,
        phone: 2,
      }

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: { desktop: 1, tablet: 1, phone: 2 },
        queries: {},
      })
    })

    it('phone fallbacks to tablet instead of desktop, when both are defined', () => {
      const value = {
        tablet: 1,
        desktop: 2,
      }

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: { desktop: 2, tablet: 1, phone: 1 },
        queries: {},
      })
    })

    it('tablet fallbacks to mobile,', () => {
      const value = {
        phone: 1,
        mobile: 2,
        desktop: 3,
      }

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: { desktop: 3, tablet: 2, phone: 1 },
        queries: {},
      })
    })

    it('phone and tablet should override mobile', () => {
      const value = {
        phone: 1,
        mobile: 2,
        tablet: 3,
        desktop: 4,
      }

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: {
          phone: 1,
          tablet: 3,
          desktop: 4,
        },
        queries: {},
      })
    })
  })

  describe('generic media queries', () => {
    it('adds media query values to queries dictionary', () => {
      const value = {
        '(max-width: 800px)': 1,
        '(max-width: 1200px)': 2,
      }

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: { desktop: undefined, tablet: undefined, phone: undefined },
        queries: {
          '(max-width: 800px)': 1,
          '(max-width: 1200px)': 2,
        },
      })
    })

    it('works together with devices', () => {
      const value = {
        phone: 3,
        '(max-width: 800px)': 1,
        '(max-width: 1200px)': 2,
      }

      expect(normalizeResponsiveInput(value)).toStrictEqual({
        devices: { desktop: 3, tablet: 3, phone: 3 },
        queries: {
          '(max-width: 800px)': 1,
          '(max-width: 1200px)': 2,
        },
      })
    })
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/react/__tests__/useMediaQueryList.test.tsx from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { renderHook, act } from '@testing-library/react-hooks'

import {
  useMediaQueryList,
  clearMatchersCache,
  findFirstMatchingQuery,
} from '../hooks/useMediaQueryList'
import { mockMatchMedia } from '../testUtils/mockMatchMedia'

type HookArgs = string[]
type HookReturnType = ReturnType<typeof useMediaQueryList>

afterEach(clearMatchersCache)

test('returns a list of media queries and that match state', () => {
  const queries = [
    '(max-width: 800px)',
    '(max-width: 600px)',
    '(max-width: 1200px)',
  ]

  const matchedQueries = ['(max-width: 800px)', '(max-width: 600px)']

  mockMatchMedia({ matchedQueries })
  const { result } = renderHook<HookArgs, HookReturnType>(() =>
    useMediaQueryList(queries)
  )

  expect(result.current.mediaQueries).toMatchObject([
    ['(max-width: 800px)', true],
    ['(max-width: 600px)', true],
    ['(max-width: 1200px)', false],
  ])
})

test('returns the first matched media query', () => {
  const queries = [
    '(max-width: 800px)',
    '(max-width: 600px)',
    '(max-width: 1200px)',
  ]

  const matchedQueries = ['(max-width: 800px)', '(max-width: 600px)']

  mockMatchMedia({ matchedQueries })
  const { result } = renderHook<HookArgs, HookReturnType>(() =>
    useMediaQueryList(queries)
  )

  const firstMatch = findFirstMatchingQuery(result.current.mediaQueries)

  expect(firstMatch).toMatch('(max-width: 800px)')
})

test('returns undefined if not query matches', () => {
  const queries = [
    '(max-width: 800px)',
    '(max-width: 600px)',
    '(max-width: 1200px)',
  ]

  mockMatchMedia()
  const { result } = renderHook<HookArgs, HookReturnType>(() =>
    useMediaQueryList(queries)
  )

  const firstMatch = findFirstMatchingQuery(result.current.mediaQueries)

  expect(firstMatch).toBeUndefined()
})

test('does nothing if no media queries are passed', () => {
  const queries: string[] = []

  mockMatchMedia()

  const { result } = renderHook<HookArgs, HookReturnType>(() =>
    useMediaQueryList(queries)
  )

  expect(result.current.mediaQueries).toHaveLength(0)
})

test('updates the matched list after a media listener is triggered', () => {
  const queries = [
    '(max-width: 600px)',
    '(max-width: 800px)',
    '(min-width: 1200px)',
  ]

  const resizeWindow = mockMatchMedia({
    matchedQueries: ['(min-width: 1200px)'],
  })

  const { result } = renderHook<HookArgs, HookReturnType>(() =>
    useMediaQueryList(queries)
  )

  expect(result.current.mediaQueries).toMatchObject([
    ['(max-width: 600px)', false],
    ['(max-width: 800px)', false],
    ['(min-width: 1200px)', true],
  ])

  act(() => {
    resizeWindow({
      matchedQueries: ['(max-width: 600px)', '(max-width: 800px)'],
    })
  })

  expect(result.current.mediaQueries).toMatchObject([
    ['(max-width: 600px)', true],
    ['(max-width: 800px)', true],
    ['(min-width: 1200px)', false],
  ])
})

test('returns an updated list of media queries after the hook params changes', () => {
  const initialQueries: string[] = []

  mockMatchMedia({
    matchedQueries: ['(max-width: 800px)'],
  })

  const { result, rerender } = renderHook<HookArgs, HookReturnType>(
    (hookArgs) => useMediaQueryList(hookArgs),
    { initialProps: initialQueries }
  )

  expect(result.current.mediaQueries).toMatchObject([])

  const rerenderQueries = ['(max-width: 600px)', '(max-width: 800px)']

  rerender(rerenderQueries)

  expect(result.current.mediaQueries).toMatchObject([
    ['(max-width: 600px)', false],
    ['(max-width: 800px)', true],
  ])
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/react/__tests__/useResponsiveValue.test.tsx from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { renderHook } from '@testing-library/react-hooks'
import { useDevice } from 'vtex.device-detector'

import { mockMatchMedia } from '../testUtils/mockMatchMedia'
import useResponsiveValue from '../useResponsiveValue'
import useResponsiveValues from '../useResponsiveValues'

const devices = ['desktop', 'tablet', 'phone']

jest.mock('vtex.device-detector', () => {
  return { useDevice: jest.fn() }
})

function switchDevice(device: string) {
  return (useDevice as jest.Mock).mockImplementation(() => ({ device }))
}

describe('useResponsiveValue', () => {
  devices.forEach((device) => {
    it(`returns a single value for the current device: ${device}`, () => {
      switchDevice(device)

      const input = {
        desktop: 1,
        phone: 2,
        tablet: 3,
      }

      const { result } = renderHook(() => useResponsiveValue(input))

      expect(result.current).toBe(input[device as keyof typeof input])
    })

    it('returns a single value if the input is also a single value', () => {
      switchDevice(device)

      const input = 1

      const { result } = renderHook(() => useResponsiveValue(input))

      expect(result.current).toBe(input)
    })
  })

  it(`returns a single value matching a specific media query`, () => {
    mockMatchMedia({ matchedQueries: ['(max-width: 1000px)'] })
    switchDevice('desktop')

    const input = {
      desktop: 1,
      '(max-width: 1000px)': 2,
    }

    const { result } = renderHook(() => useResponsiveValue(input))

    expect(result.current).toBe(2)
  })
})

describe('useResponsiveValues', () => {
  it('returns the correct values for different keys', () => {
    switchDevice('desktop')

    const input = {
      first: { desktop: 1, mobile: 2 },
      second: { desktop: '3', mobile: '4' },
      third: { desktop: 1, '(max-width: 1000px)': 2 },
    }

    const { result } = renderHook(() => useResponsiveValues(input))

    expect(result.current.first).toBe(1)
    expect(result.current.second).toBe('3')
    expect(result.current.third).toBe(2)
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/react/hooks/useMediaQueryList.ts from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useLayoutEffect, useState } from 'react'

const BreakpointMatchers: Record<string, MediaQueryList> = {}

export function clearMatchersCache() {
  Object.keys(BreakpointMatchers).forEach(
    (key) => delete BreakpointMatchers[key]
  )
}

function getBreakpointMatcher(query: string): MediaQueryList | undefined {
  if (!BreakpointMatchers[query] && typeof window?.matchMedia === 'function') {
    // ugly side-effect to get a up-to-date initial value（＞д＜）
    BreakpointMatchers[query] = window.matchMedia(query)
  }

  return BreakpointMatchers[query]
}

export function useMediaQueryList(queries: string[]) {
  const [matches, setMatches] = useState<Record<string, boolean>>(() => {
    const initial: Record<string, boolean> = {}

    queries.forEach((query) => {
      initial[query] = Boolean(getBreakpointMatcher(query)?.matches)
    })

    return initial
  })

  useLayoutEffect(
    function updateQueryListeners() {
      if (typeof window?.matchMedia !== 'function' || queries.length === 0) {
        return
      }

      const cancels = queries.map((query) => {
        let mounted = true
        const mediaQueryList = getBreakpointMatcher(query)

        if (matches[query] === undefined || matches[query] === null) {
          setMatches((curMatches) => ({
            ...curMatches,
            [query]: Boolean(mediaQueryList?.matches),
          }))
        }

        const listener = (e: MediaQueryListEvent) => {
          if (!mounted) return
          setMatches((curMatches) => ({ ...curMatches, [query]: e.matches }))
        }

        mediaQueryList?.addListener(listener)

        return () => {
          mounted = false
          mediaQueryList?.removeListener(listener)
        }
      })

      return () => {
        cancels.forEach((cancel) => cancel())
      }
    },
    // We disable this rule because it doesn't treat `JSON.stringify(queries)`
    // as an explicit dependency of `queries`.
    // We're also doing a JSON.stringify because we need to guarantee that it won't
    // re-run if the reference was changed but its content didn't.
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [JSON.stringify(queries), setMatches]
  )

  return {
    mediaQueries: Object.entries(matches),
  }
}

export const findFirstMatchingQuery = (
  queryMatches: Array<[string, boolean]>
): undefined | string => {
  const matchedBreakpoint = queryMatches.find(([, matches]) => matches)

  if (!matchedBreakpoint) {
    return
  }

  const [query] = matchedBreakpoint

  return query
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/react/modules/normalizeResponsiveInput.ts from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```typescript
/** The user is able to input `mobile` as a device (as opposed to `desktop`),
 * but the output will be converted to `phone` and `tablet` */

import type { InputDevice, OutputDevice } from '../ResponsiveValuesTypes'

const InputDevicesMap: Record<InputDevice, InputDevice> = {
  mobile: 'mobile',
  phone: 'phone',
  tablet: 'tablet',
  desktop: 'desktop',
}

export type ResponsiveInput<T> = Record<InputDevice | string, T>
export type MaybeResponsiveInput<T> = T | ResponsiveInput<T>

export type NormalizedInput<T> = {
  devices: Record<OutputDevice, T>
  queries: Record<string, T>
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const isUndefined = (value: any) => typeof value === 'undefined'

/** Returns the first value of the input that is not undefined,
 * given a sorted array of keys */
const fallbackOrder = <T>(
  input: ResponsiveInput<T>,
  devices: Array<keyof ResponsiveInput<T>>
) => devices.map((key) => input[key]).find((value) => !isUndefined(value)) as T

/** Checks if the input value is a ResponsiveInput type (an object with
 * one or more keys of Device type--e.g. `desktop`, `mobile`) */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const isResponsiveInput = <T>(value: any): value is ResponsiveInput<T> =>
  Boolean(
    value &&
      typeof value === 'object' &&
      Object.keys(value).every((key) => {
        return (
          key in InputDevicesMap ||
          (key.charAt(0) === '(' && key.charAt(key.length - 1) === ')')
        )
      })
  )

const showWarnings = <T>(value: ResponsiveInput<T>) => {
  if (isUndefined(value.mobile)) {
    return
  }

  const devices: string[] = []

  if (!isUndefined(value.phone)) {
    devices.push('"phone"')
  }

  if (!isUndefined(value.tablet)) {
    devices.push('"tablet"')
  }

  if (devices.length === 0) {
    return
  }

  const devicesLabel = devices.join(' and ')

  console.warn(
    `You are defining a "mobile" value along with ${devicesLabel} ${
      devices.length > 1 ? 'values' : 'value'
    } in the props of a component. Please use "phone" and "tablet" in this case.`
  )
}

/** Takes an input that might be a responsive object or not
 * (i.e. either "prop: {mobile: 1, desktop:2}" or just "prop: 2")
 * and returns an object of the values broken down into devices
 * (i.e. {phone: 1, tablet: 1, desktop: 2})
 *
 * TODO: this can return undefined if only media queries are defined
 * should we add undefined to the return type of our hooks?
 * it would make it a bit annoying to use, but probably safer
 */
export const normalizeResponsiveInput = <T>(
  input: MaybeResponsiveInput<T>
): NormalizedInput<T> => {
  if (!isResponsiveInput(input)) {
    return {
      devices: { phone: input, tablet: input, desktop: input },
      queries: {},
    }
  }

  const { phone, tablet, mobile, desktop, ...queries } = input

  showWarnings(input)

  return {
    devices: {
      phone: fallbackOrder(input, ['phone', 'mobile', 'tablet', 'desktop']),
      tablet: fallbackOrder(input, ['tablet', 'mobile', 'desktop', 'phone']),
      desktop: fallbackOrder(input, ['desktop', 'tablet', 'phone', 'mobile']),
    },
    queries,
  }
}

export const normalizeResponsiveInputs = <
  Input extends Record<string, MaybeResponsiveInput<unknown>>
>(
  input: Input
) => {
  const normalizedInputs: Array<[keyof Input, NormalizedInput<unknown>]> = []
  const queryList: Set<string> = new Set()

  Object.keys(input).forEach((key) => {
    const normalizedInput = normalizeResponsiveInput(input[key])

    Object.keys(normalizedInput.queries).forEach((query) =>
      queryList.add(query)
    )

    normalizedInputs.push([key as keyof Input, normalizedInput])
  })

  return {
    inputList: normalizedInputs,
    queryList: [...queryList],
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of responsive-values/react/testUtils/mockMatchMedia.ts from the responsive-values VTEX app.

[Assistant]
Here's the implementation:

```typescript
type MockMatchMedia = {
  matchedQueries?: string[]
}

export function mockMatchMedia({ matchedQueries = [] }: MockMatchMedia = {}) {
  const mqls: Array<{ mql: MediaQueryList; listeners: any[] }> = []

  Object.defineProperty(window, 'matchMedia', {
    writable: true,
    value: jest.fn().mockImplementation((media: string) => {
      let _listeners: any[] = []

      const mql = {
        media,
        get matches() {
          return matchedQueries.includes(media)
        },
        onchange: () => {},
        addListener: jest.fn((fn) => _listeners.push(fn)),
        addEventListener: jest.fn((fn: any) => _listeners.push(fn)),
        removeListener: jest.fn(
          (fn) => (_listeners = _listeners.filter((f) => f !== fn))
        ),
        removeEventListener: jest.fn(
          (fn: any) => (_listeners = _listeners.filter((f) => f !== fn))
        ),
        dispatchEvent: (_: Event) => true,
      }

      mqls.push({
        mql,
        get listeners() {
          return _listeners
        },
      })

      return mql
    }),
  })

  return ({
    matchedQueries: newMatchedQueries,
  }: {
    matchedQueries: string[]
  }) => {
    matchedQueries = newMatchedQueries

    mqls.forEach(({ mql, listeners }) =>
      listeners.forEach((fn) => fn({ matches: mql.matches }))
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/service.json from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "memory": 4096,
  "ttl": 43200,
  "timeout": 60,
  "minReplicas": 10,
  "maxReplicas": 400,
  "workers": 1,
  "routes": {
    "proxy": {
      "path": "/_v/private/oauth-proxy/authorizations/*path",
      "public": true
    },
    "access_token": {
      "path": "/_v/private/oauth-proxy/autheticated/access-token/",
      "public": true
    },
    "refresh_token": {
      "path": "/_v/private/oauth-proxy/autheticated/refresh-token/",
      "public": true
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/package.json from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "co-body": "^6.0.0",
    "qs": "^6.11.0",
    "ramda": "^0.25.0"
  },
  "devDependencies": {
    "@types/co-body": "^0.0.3",
    "@types/jest": "^24.0.18",
    "@types/node": "^12.0.0",
    "@types/ramda": "types/npm-ramda#dist",
    "@vtex/api": "6.45.12",
    "@vtex/test-tools": "^1.0.0",
    "@vtex/tsconfig": "^0.5.6",
    "typescript": "3.9.7"
  },
  "scripts": {
    "lint": "tsc --noEmit --pretty"
  },
  "version": "1.0.2"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/index.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ClientsConfig } from '@vtex/api'
import { Service } from '@vtex/api'

import { Clients } from './clients'
import { getAccessToken } from './handlers/getAccessToken'
import { proxyRequest } from './handlers/proxyRequest'
import { refreshAccessToken } from './handlers/refreshAccessToken'
import { checkUserAuth } from './middlewares/checkUserAuth'
import { getAppSettings } from './middlewares/getAppSettings'
import { prepare } from './middlewares/prepare'

const TIMEOUT_MS = 800
const FOUR_SECONDS_MS = 5 * TIMEOUT_MS

// This is the configuration for clients available in `ctx.clients`.
const clients: ClientsConfig<Clients> = {
  // We pass our custom implementation of the clients bag, containing the Status client.
  implementation: Clients,
  options: {
    // All IO Clients will be initialized with these options, unless otherwise specified.
    default: {
      retries: 2,
      timeout: FOUR_SECONDS_MS,
    },
  },
}

// Export a service that defines route handlers and client options.
export default new Service({
  clients,
  routes: {
    // `status` is the route ID from service.json. It maps to an array of middlewares (or a single handler).
    proxy: [prepare, getAppSettings, proxyRequest],
    access_token: [prepare, checkUserAuth, getAppSettings, getAccessToken],
    refresh_token:[prepare, checkUserAuth, getAppSettings, refreshAccessToken]
  },
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/clients/vtexid.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type {
  InstanceOptions,
  IOContext,
  IOResponse,
  RequestConfig,
} from '@vtex/api'
import { ExternalClient } from '@vtex/api'
import { createTracing } from '../utils/'
import { statusToError } from '../utils/'

export default class VTEXID extends ExternalClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    // TO-DO: Fix production URL with the correct one
    super('https://vtexid.vtex.com.br', context, options)
  }

  public async getUserFromVTEXID(): Promise<IOResponse<AuthUser>> {
    const metric = `${this.context.account}-VTEXID-User-GET`

    return this.get('/api/vtexid/pub/authenticated/user', {
      params: {
        account: this.context.account,
        authToken: this.context.storeUserAuthToken,
      },
      metric,
      tracing: createTracing(metric),
    })
  }

  protected get = <T = any>(url: string, config?: RequestConfig) =>
    this.http.getRaw<T>(url, config).catch(statusToError) as Promise<
      IOResponse<T>
    >
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/clients/customVBase.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { AxiosError } from 'axios'
import {
  inflightURL,
  InstanceOptions,
  IOResponse,
  RequestTracingConfig,
} from '@vtex/api/lib/HttpClient'
import { InfraClient, IOContext } from '@vtex/api'
import { IgnoreNotFoundRequestConfig } from '@vtex/api/lib/HttpClient/middlewares/notFound'
import { Logger } from '@vtex/api/lib/service/logger/logger'

const appId = process.env.VTEX_APP_ID
const [runningAppName] = appId ? appId.split('@') : ['']

const routes = {
  Bucket: (bucket: string) => `/buckets/${runningAppName}/${bucket}`,
  File: (bucket: string, path: string) => `${routes.Bucket(bucket)}/files/${path}`,
  Files: (bucket: string) => `${routes.Bucket(bucket)}/files`,
}

export class CustomVBase extends InfraClient {
  constructor (context: IOContext, options?: InstanceOptions) {
    super('vbase@2.x', { ...context, workspace: "master" }, options)
    if (runningAppName === '') {
      throw new Error(`Invalid path to access VBase. Variable VTEX_APP_ID is not available.`)
    }
  }

  public getJSON = <T>(bucket: string, path: string, nullIfNotFound?: boolean, conflictsResolver?: ConflictsResolver<T>, tracingConfig?: RequestTracingConfig) => {
    return this.getRawJSON<T>(bucket, path, nullIfNotFound, conflictsResolver, tracingConfig)
      .then(response => response.data)
  }

  public getRawJSON = <T>(bucket: string, path: string, nullIfNotFound?: boolean, conflictsResolver?: ConflictsResolver<T>, tracingConfig?: RequestTracingConfig) => {
    const headers = conflictsResolver? {'X-Vtex-Detect-Conflicts': true}: {}
    const inflightKey = inflightURL
    const metric = 'vbase-get-json'
    return this.http.getRaw<T>(routes.File(bucket, path), { headers, inflightKey, metric, nullIfNotFound, tracing: {
      requestSpanNameSuffix: metric,
      ...tracingConfig?.tracing,
    }} as IgnoreNotFoundRequestConfig)
      .catch(async (error: AxiosError<T>) => {
        const { response } = error
        if (response && response.status === 409 && conflictsResolver) {
          const conflictsMergedData = await conflictsResolver.resolve(this.context.logger)
          return { ...response, data: conflictsMergedData } as IOResponse<T>
        }
        throw error
      })
  }

  public saveJSON = <T>(bucket: string, path: string, data: T, tracingConfig?: RequestTracingConfig, ifMatch?: string) => {
    const headers: Headers = { 'Content-Type': 'application/json' }
    if (ifMatch) {
      headers['If-Match'] = ifMatch
    }
    const metric = 'vbase-save-json'
    return this.http.put(routes.File(bucket, path), data, {headers, metric, tracing: {
      requestSpanNameSuffix: metric,
      ...tracingConfig?.tracing,
    }})
  }
}

interface Headers { [key: string]: string | number }

export interface ConflictsResolver<T>{
  resolve: (logger?: Logger) => T | Promise<T>
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/clients/salesforceProxy.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type {
  InstanceOptions,
  IOContext,
  IOResponse,
  RequestConfig,
} from '@vtex/api'
import { ExternalClient } from '@vtex/api'
import { createTracing } from '../utils/'
import { statusToError } from '../utils/'

export default class SalesforceProxy extends ExternalClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    // TO-DO: Fix production URL with the correct one
    super(
      context.production || (context as CustomIOContext).appSettings.configs.forceProduction
        ? (context as CustomIOContext).appSettings.production.endpoint
        : (context as CustomIOContext).appSettings.staging.endpoint,
      context,
      options
    )
  }

  public async proxyGet(path: string, params: {}): Promise<IOResponse<any>> {
    const metric = `${this.context.account}-Salesforce-OAuth-Proxy-GET`
    const host = this.getHost()
    return this.get(path, {
      params,
      headers: {
        'host': host,
        'x-forwarded-host': host
      },
      metric,
      tracing: createTracing(metric),
    })
  }

  public async proxyPost(path: string, body: any, params: {}): Promise<IOResponse<any>> {
    const metric = `${this.context.account}-Salesforce-OAuth-Proxy-POST`
    const host = this.getHost()
    return this.post(path, body, {
      params,
      headers: {
        'host': host,
        'x-forwarded-host': host
      },
      metric,
      tracing: createTracing(metric),
    })
  }

  public async refreshToken(refreshToken: string): Promise<IOResponse<any>> {
    const metric = `${this.context.account}-Salesforce-OAuth-RefreshToken-POST`
    const host = this.getHost()
    const env = this.context.production || (this.context as CustomIOContext).appSettings.configs.forceProduction ? "production" : "staging"
    const credentials = (this.context as CustomIOContext).appSettings[env].credentials

    return this.post('/services/oauth2/token', null, {
      params: {
        grant_type: "refresh_token",
        client_id: credentials.clientId,
        client_secret: credentials.clientSecret,
        refresh_token: refreshToken
      },
      headers: {
        'host': host,
        'x-forwarded-host': host
      },
      metric,
      tracing: createTracing(metric),
    })
  }

  protected getHost: () => string = () => {
    return new URL(this.options?.baseURL as string).hostname
  }

  protected get = <T = any>(url: string, config?: RequestConfig) =>
    this.http.getRaw<T>(url, config).catch(statusToError) as Promise<
      IOResponse<T>
    >

  protected put = <T = any>(url: string, data?: any, config?: RequestConfig) =>
    this.http.putRaw<T>(url, data, config).catch(statusToError) as Promise<
      IOResponse<T>
    >

  protected post = <T = any>(url: string, data?: any, config?: RequestConfig) =>
    this.http.post<T>(url, data, config).catch(statusToError) as Promise<
      IOResponse<T>
    >

  protected delete = <T = any>(url: string, config?: RequestConfig) =>
    this.http.delete<T>(url, config).catch(statusToError) as Promise<
      IOResponse<T>
    >
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/clients/index.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { IOClients } from '@vtex/api'

import SalesforceProxy from './salesforceProxy'
import VTEXID from './vtexid'
import { CustomVBase } from './customVBase'

// Extend the default IOClients implementation with our own custom clients.
export class Clients extends IOClients {
  public get salesforceProxy() {
    return this.getOrSet('salesforceProxy', SalesforceProxy)
  }

  public get vtexid() {
    return this.getOrSet('vtexid', VTEXID)
  }

  public get customVBase() {
    return this.getOrSet('customVBase', CustomVBase)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/parsers/cleanErrorParser.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { cleanError } from '@vtex/api'

export const cleanErrorParser = (
  customMessage: string,
  error: any
) => {
  const cleanedError = cleanError(error)
  return {
    ...cleanedError,
    ...{
      customMessage,
    },
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/parsers/errorParses.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
export function errorParser(
  ctx: Context,
  error: any,
  message: string,
  method: string
) {
  const {
    vtex: {
      route: { params },
    },
    state: { currentUser },
    req: { method: reqMethod },
  } = ctx

  const path = params?.path as string
  const requestMethod = reqMethod?.toLowerCase() as string

  let appMessage: string = ''
  let stackTrace: any = null

  if (error.isAxiosError) {
    appMessage = `${message} ${error.response?.status}`
  } else {
    appMessage = error.message || 'Unhandled exception'
    stackTrace = error.stack
  }

  return {
    appMessage,
    data: error.response?.data,
    message: error.message,
    path,
    method,
    requestMethod,
    stackTrace,
    status: error.response?.status,
    statusText: error.response?.statusText,
    currentUser,
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/typings/authetication.d.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface AuthUser {
  userId: string
  user: string
  userType: string
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/typings/session.d.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface Session {
  namespaces?: {
    profile?: {
      id: {
        value: string
      }
      email: {
        value: string
      }
    }
    authentication?: {
      storeUserId: {
        value: string
      }
      storeUserEmail: {
        value: string
      }
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/typings/proxy.d.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface proxyResponse {
  data: any
  status: number
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/typings/appSettings.d.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
export interface AppSettings {
  production: {
    endpoint: string
    credentials: Credentials
  },
  staging: {
    endpoint: string
    credentials: Credentials
  },
  configs: {
    forceProduction: boolean
  }
}

export interface Credentials {
  clientId: string
  clientSecret: string
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/typings/global.d.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ServiceContext, RecorderState, ParamsContext } from '@vtex/api'
import type { IOContext } from '@vtex/api'
import { Clients } from '../clients'
import { AppSettings } from './appSettings'

declare global {
  // We declare a global Context type just to avoid re-writing ServiceContext<Clients, State> in every handler and resolver
  type Context = ServiceContext<Clients, State, ParamsContextm, CustomIOContext>

  interface State extends RecorderState {
    body: any
    salesforceAccessToken: string
    currentUser: CurrentUser
  }

  interface CustomIOContext extends IOContext {
    appSettings: AppSettings
  }

  interface CurrentUser {
    email: string
    userId: string
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/typings/salesforceAccessToken.d.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface ISalesforceAccessTokenRes {
  sub: string
  user_id: string
  organization_id: string
  preferred_username: string
  nickname: string
  name: string
  email: string
  email_verified: boolean
  given_name: string
  family_name: string
  zoneinfo: string
  photos: {
      picture: string
      thumbnail: string
  }
  profile: string
  picture: string
  address: {
      country: string
  }
  urls: {
      enterprise: string
      metadata: string
      partner: string
      rest: string
      sobjects: string
      search: string
      query: string
      recent: string
      tooling_soap: string
      tooling_rest: string
      profile: string
      feeds: string
      groups: string
      users: string
      feed_items: string
      feed_elements: string
      custom_domain: string
  }
  active: boolean
  user_type: string
  language: string
  locale: string
  utcOffset: number
  updated_at: string
}

interface ISalesforceAccessToken extends ISalesforceAccessTokenRes {
    end_date: Date
}

interface ISalesforceRefreshToken {
  access_token: string
  id: string
  id_token?: string
  instance_url: string
  issued_at: string
  refresh_token?: string
  scope: string
  sfdc_community_id: string
  sfdc_community_url: string
  signature: string
  token_type: string
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/middlewares/prepare.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ResolverError } from '@vtex/api'
import { form, json } from 'co-body'

export async function prepare(ctx: Context, next: () => Promise<any>) {
  const {
    method: reqMethod,
    query,
    req
  } = ctx

  let args: any;

  if (['POST'].includes(reqMethod) && (!ctx.request.type.includes('application/json') && !ctx.request.type.includes('application/x-www-form-urlencoded'))) {
    ctx.throw(406, 'Content type not allowed')
  }

  if (['POST'].includes(reqMethod) && ctx.request.type.includes('application/json')) {
    args = await json(req)
  }

  if (['POST'].includes(reqMethod) && ctx.request.type.includes('application/x-www-form-urlencoded')) {
    args = await form(req)
  }

  if (!reqMethod) {
    throw new ResolverError('Empty request method')
  }

  if (!['GET', 'POST'].includes(reqMethod)) {
    ctx.throw(405)
  }

  if (['POST'].includes(reqMethod) && args) {
    ctx.state.body = args
  }

  if(query && query.access_token) {
    ctx.state.salesforceAccessToken = query.access_token
  }

  await next()
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/middlewares/checkUserAuth.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { AuthenticationError } from '@vtex/api'

import { getCurrentUserFromSession } from '../utils/getCurrentUserFromSession'
import { getCurrentUserFromVTEXAuthCookie } from '../utils/getCurrentUserFromVTEXAuthCookie'

function isLogged(user: CurrentUser | null) {
  return user?.email
}

export async function checkUserAuth(ctx: Context, next: () => Promise<any>) {
  let currentUser: CurrentUser | null

  currentUser = await getCurrentUserFromSession(ctx)

  if (!isLogged(currentUser)) {
    currentUser = await getCurrentUserFromVTEXAuthCookie(ctx)
  }

  if (!isLogged(currentUser)) {
    throw new AuthenticationError('User not authenticated')
  }

  ctx.state.currentUser = currentUser as CurrentUser

  await next()
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/middlewares/getAppSettings.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ResolverError } from '@vtex/api'

import { appSettingsService } from "../services/appSettingsService";
import type { AppSettings } from '../typings/appSettings';

export async function getAppSettings(ctx: Context, next: () => Promise<any>) {
  const {
        clients: { apps}
  } = ctx

  const service = appSettingsService(ctx.vtex.account, ctx.vtex.workspace, apps)
  const appSettings: AppSettings = await service.getSettings()

  if (!appSettings) {
    throw new ResolverError('No app settings found')
  }

  if (!appSettings.staging.endpoint || !appSettings.production.endpoint ) {
    throw new ResolverError('Missing Staging or Production endpoint app config')
  }

  if (
    !appSettings.staging.credentials.clientId || !appSettings.staging.credentials.clientSecret
    || !appSettings.production.credentials.clientId || !appSettings.production.credentials.clientSecret
  ) {
    throw new ResolverError('Missing Staging or Production credentials app config')
  }

  ctx.vtex.appSettings = appSettings

  await next()
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/utils/getCurrentUserFromSession.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ResolverError } from '@vtex/api'
import { path } from 'ramda'
import { cleanErrorParser } from '../parsers/cleanErrorParser'

export async function getCurrentUserFromSession(
  ctx: Context
): Promise<CurrentUser | null> {
  try {
    const {
      clients: { session },
      vtex: { logger }
    } = ctx

    const currentSession = await session.getSession(
      ctx.vtex.sessionToken as string,
      ['*']
    )
    const thisSession = currentSession.sessionData as Session

    if (!thisSession || !thisSession.namespaces) {
      const warn = cleanErrorParser("Error getting logged user info from session", new ResolverError('Error fetching session data'))
      logger.warn(warn)
      return null
    }

    const idPath = ['namespaces', 'authentication', 'storeUserId', 'value']
    const emailPath = [
      'namespaces',
      'authentication',
      'storeUserEmail',
      'value',
    ]

    return {
      email: path(emailPath, thisSession) as string,
      userId: path(idPath, thisSession) as string,
    }
  } catch (error) {
    const {
      vtex: { logger },
    } = ctx

    const log = cleanErrorParser("Error getting logged user info from session", error)
    logger.error(log)

    return null
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/utils/statusToError.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { AuthenticationError, ForbiddenError, UserInputError } from '@vtex/api'
import { AxiosError } from 'axios'

export function statusToError<T>(e: AxiosError): T {
  if (!e.response) {
    throw e
  }

  const { response } = e
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  const { status } = response!

  if (status === 401) {
    throw new AuthenticationError(e)
  }
  if (status === 403) {
    throw new ForbiddenError(e)
  }
  if (status === 400) {
    throw new UserInputError(e)
  }

  throw e
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/utils/constants.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
const DEFAULT_SETTINGS_CACHE_MAX_AGE_IN_MS = 5000

export {
  DEFAULT_SETTINGS_CACHE_MAX_AGE_IN_MS,
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/utils/getCurrentUserFromVTEXAuthCookie.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ResolverError } from '@vtex/api'
import { cleanErrorParser } from '../parsers/cleanErrorParser'

export async function getCurrentUserFromVTEXAuthCookie(
  ctx: Context
): Promise<CurrentUser | null> {
  try {
    const {
      clients: { vtexid },
      vtex: { logger }
    } = ctx

    const { data: currentAuthUser } = await vtexid.getUserFromVTEXID()

    if (!currentAuthUser || !currentAuthUser.user) {
      const warn = cleanErrorParser("Error getting logged user info from cookie", new ResolverError('Error fetching VTEX ID user data'))
      logger.warn(warn)
      return null
    }

    return {
      email: currentAuthUser.user as string,
      userId: currentAuthUser.userId as string,
    }
  } catch (error) {
    const {
      vtex: { logger },
    } = ctx

    const log = cleanErrorParser("Error getting logged user info from cookie", error)
    logger.error(log)

    return null
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/utils/index.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { createTracing } from './createTracing'
import { statusToError } from './statusToError'

export { statusToError, createTracing }

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/utils/createTracing.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { RequestTracingConfig } from '@vtex/api'

export const createTracing = (
  metric: string,
  tracingConfig?: RequestTracingConfig
) => ({
  requestSpanNameSuffix: metric,
  ...tracingConfig?.tracing,
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/handlers/proxyRequest.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ResolverError } from '@vtex/api'

import { proxyGetHandler } from './proxyGetHandler'
import { proxyPostHandler } from './proxyPostHandler'
import { errorParser } from '../parsers/errorParses'
import SalesforceAccessToken from '../services/salesforceAccessToken'
import SalesforceRefreshToken from '../services/salesforceRefreshToken'
import { getUserInfo } from './getUserInfoHandler'

export async function proxyRequest(ctx: Context) {
  try {
    const {
      vtex: {
        logger,
        route: {
          params: { path },
        },
      },
      req: { method: reqMethod }
    } = ctx

    let proxyResponse: proxyResponse | any

    if (!reqMethod) {
      throw new ResolverError('Empty request method')
    }

    switch (reqMethod.toLocaleLowerCase()) {
      case 'get':
        proxyResponse = await proxyGetHandler(ctx)
        break
      case 'post':
        proxyResponse = await proxyPostHandler(ctx)
        break
      default:
        throw new Error(`Proxy request handler for ${reqMethod} not implementd`)
    }

    if (path.includes('services/oauth2/userinfo') && proxyResponse.data) {
      const salesforceAccessToken = new SalesforceAccessToken()
      const userEmail = proxyResponse.data?.email
      salesforceAccessToken.save(ctx, userEmail, proxyResponse.data)
    } else if (path.includes('services/oauth2/token')) {
      const salesforceRefreshToken = new SalesforceRefreshToken()
      const { data: { email } } = await getUserInfo(ctx, proxyResponse.access_token)

      if(!email)
        throw new ResolverError("No user email found")

      salesforceRefreshToken.save(ctx, email, proxyResponse)

    }

    logger.info({
      message: 'Salesforce OAuth Provider request success',
      path,
      reqMethod,
    })

    ctx.set('Cache-Control', 'no-cache,no-store')
    ctx.status = proxyResponse.status || 200
    ctx.body = proxyResponse?.data || proxyResponse

  } catch (error) {
    const {
      vtex: { logger },
    } = ctx

    const log = errorParser(
      ctx,
      error,
      'Request to Salesforce OAuth Provider failed with status',
      'proxyRequest'
    )

    logger.error(log)

    ctx.status = log.status || 500
    ctx.set('Cache-Control', 'no-cache,no-store')
    ctx.body = {
      message: log.message,
      status: log.status
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/handlers/proxyGetHandler.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
export async function proxyGetHandler(ctx: Context) {
  const {
    clients: { salesforceProxy },
    vtex: {
      route: {
        params: { path },
      },
    },
    query
  } = ctx

  return salesforceProxy.proxyGet(path as string, query)
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/handlers/getAccessToken.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { errorParser } from '../parsers/errorParses'
import SalesforceAccessToken from '../services/salesforceAccessToken'

export async function getAccessToken(ctx: Context) {
  try {
    const {
      vtex: { logger },
      state: { currentUser },
    } = ctx

    const salesforceAccessToken = new SalesforceAccessToken()
    const salesforceUserAccessToken = await salesforceAccessToken.get(
      ctx,
      currentUser.email
    )

    logger.info({
      message: 'Retrieve user access token success',
      currentUser,
    })

    ctx.set('Cache-Control', 'no-cache,no-store')
    ctx.status = 200
    ctx.body = salesforceUserAccessToken

  } catch (error) {
    const {
      vtex: { logger },
    } = ctx

    const log = errorParser(
      ctx,
      error,
      'Retrieve user access token failed with status',
      'getAccessToken'
    )

    logger.error(log)

    ctx.status = log.status || 500
    ctx.set('Cache-Control', 'no-cache,no-store')
    ctx.body = {
      appMessage: log.appMessage,
      method: log.method,
      status: log.status,
      statusText: log.statusText
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/handlers/proxyPostHandler.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import qs from 'qs';

export async function proxyPostHandler(ctx: Context) {
  const {
    clients: { salesforceProxy },
    state: { body },
    vtex: {
      route: {
        params: { path },
      },
    },
    query
  } = ctx
  let reqBody = body

  if (ctx.request.type.includes('application/x-www-form-urlencoded')) {
    reqBody = qs.stringify(body)
  }

  return salesforceProxy.proxyPost(path as string, reqBody, query)
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/handlers/refreshAccessToken.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ResolverError } from '@vtex/api'
import { errorParser } from '../parsers/errorParses'
import SalesforceAccessToken from '../services/salesforceAccessToken'
import SalesforceRefreshToken from '../services/salesforceRefreshToken'

export async function refreshAccessToken(ctx: Context) {
  try {
    const {
      clients: { salesforceProxy },
      state: { currentUser },
    } = ctx

    let refreshedData

    const salesforceRefreshToken = new SalesforceRefreshToken()
    const refreshTokenData: ISalesforceRefreshToken = await salesforceRefreshToken.get(
      ctx,
      currentUser.email
    )
    const salesforceAccessToken = new SalesforceAccessToken()
    const accessTokenData: ISalesforceAccessToken = await salesforceAccessToken.get(
      ctx,
      currentUser.email
    )

    const refreshToken = refreshTokenData.refresh_token

    if (!refreshToken) {
      throw new ResolverError("No refresh token found")
    }

    const refreshAccessTokenRes: ISalesforceRefreshToken = await salesforceProxy.refreshToken(refreshToken)
    const refreshedAccessToken: string = refreshAccessTokenRes.access_token

    if(refreshedAccessToken) {
      refreshedData = await salesforceAccessToken.save(ctx, currentUser.email, accessTokenData, refreshedAccessToken)
    }

    ctx.set('Cache-Control', 'no-cache,no-store')
    ctx.status = 200
    ctx.body = refreshedData

  } catch (error) {
    const {
      vtex: { logger },
    } = ctx
    let body

    const log = errorParser(
      ctx,
      error,
      'Refresh user access token failed with status',
      'refreshAccessToken'
    )

    logger.error(log)

    if (log.status === 400) {
      body = error.response?.data
    } else {
      body = {
        appMessage: log.appMessage,
        method: log.method,
        status: log.status,
        statusText: log.statusText
      }
    }

    ctx.status = log.status || 500
    ctx.set('Cache-Control', 'no-cache,no-store')
    ctx.body = body
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/handlers/getUserInfoHandler.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
export async function getUserInfo(ctx: Context, accessToken: string) {
  const {
    clients: { salesforceProxy }
  } = ctx

  return salesforceProxy.proxyGet("/services/oauth2/userinfo", { access_token: accessToken })
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/services/appSettingsService.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { Apps } from '@vtex/api'
import { LRUCache } from '@vtex/api'

import type { AppSettings } from '../typings/appSettings'
import { DEFAULT_SETTINGS_CACHE_MAX_AGE_IN_MS } from '../utils/constants'

export const appSettingsService = (
  account: string,
  workspace: string,
  apps: Apps
) => {
  const getSettings = async () => {
    const SettingsCache = new LRUCache<string, AppSettings>({ max: 5000 })
    const cacheKey = `${account}-${workspace}-${process.env.VTEX_APP_ID}`

    return (await SettingsCache.getOrSet(cacheKey, () =>
      apps.getAppSettings(process.env.VTEX_APP_ID as string).then((res) => {
        return {
          value: res,
          maxAge: DEFAULT_SETTINGS_CACHE_MAX_AGE_IN_MS,
        }
      })
    )) as AppSettings
  }

  return {
    getSettings,
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/services/salesforceRefreshToken.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { createHash } from 'crypto'

export default class SalesforceRefreshToken {
  constructor() {}

  public async get(
    ctx: Context,
    userEmail: string
  ): Promise<ISalesforceRefreshToken> {
    const {
      clients: { customVBase },
    } = ctx

    const normalizedFilePath = this.normalizedJSONFile(userEmail)

    return customVBase.getJSON<ISalesforceRefreshToken>(
      'sf_refresh_token',
      normalizedFilePath
    )
  }

  public async save(
    ctx: Context,
    userEmail: string,
    res: ISalesforceRefreshToken
  ): Promise<ISalesforceRefreshToken> {
    const {
      clients: { customVBase }
    } = ctx

    const normalizedFilePath = this.normalizedJSONFile(userEmail)

    customVBase.saveJSON<ISalesforceRefreshToken>(
      'sf_refresh_token',
      normalizedFilePath,
      res
    )

    return res
  }

  protected getTTL = (expirationInMinutes?: number) => {
    const ttl = new Date()

    ttl.setMinutes(ttl.getMinutes() + (expirationInMinutes || 1440))

    return ttl
  }

  protected normalizedJSONFile = (filePath: string) =>
    createHash('md5').update(filePath).digest('hex') + '.json'
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of salesforce-oauth-middleware/node/services/salesforceAccessToken.ts from the salesforce-oauth-middleware VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { createHash } from 'crypto'

export default class SalesforceAccessToken {
  constructor() {}

  public async get(
    ctx: Context,
    userEmail: string
  ): Promise<ISalesforceAccessToken> {
    const {
      clients: { customVBase },
    } = ctx

    const normalizedFilePath = this.normalizedJSONFile(userEmail)

    return customVBase.getJSON<ISalesforceAccessToken>(
      'sf_token',
      normalizedFilePath
    )
  }

  public async save(
    ctx: Context,
    userEmail: string,
    res: ISalesforceAccessToken | ISalesforceAccessTokenRes,
    accessToken?: string
  ): Promise<ISalesforceAccessToken> {
    const {
      clients: { customVBase },
      state: { salesforceAccessToken }
    } = ctx

    const endDate = this.getTTL()
    const userInfo = {
      ...res,
      ...{
        access_token: accessToken ?? salesforceAccessToken,
        end_date: endDate,
      },
    }

    const normalizedFilePath = this.normalizedJSONFile(userEmail)

    customVBase.saveJSON<ISalesforceAccessToken>(
      'sf_token',
      normalizedFilePath,
      userInfo
    )

    return userInfo
  }

  protected getTTL = (expirationInMinutes?: number) => {
    const ttl = new Date()

    ttl.setMinutes(ttl.getMinutes() + (expirationInMinutes || 1440))

    return ttl
  }

  protected normalizedJSONFile = (filePath: string) =>
    createHash('md5').update(filePath).digest('hex') + '.json'
}

```