[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 pwa-components/messages/context.json from the pwa-components VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/promotion-banner.button-dismiss.label": "store/promotion-banner.button-dismiss.label",
  "store/promotion-banner.install.title": "store/promotion-banner.install.title",
  "store/promotion-banner.install.description": "store/promotion-banner.install.description",
  "store/promotion-banner.install.button-accept.label": "store/promotion-banner.install.button-accept.label",
  "store/promotion-banner.push-notification.title": "store/promotion-banner.push-notification.title",
  "store/promotion-banner.push-notification.description": "store/promotion-banner.push-notification.description",
  "store/promotion-banner.push-notification.button-accept.label": "store/promotion-banner.push-notification.button-accept.label",
  "store/offline-warning.button": "store/offline-warning.button",
  "store/offline-warning.message": "store/offline-warning.message",
  "store/offline-warning.title": "store/offline-warning.title"
}
```


[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 pwa-components/messages/es.json from the pwa-components VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/promotion-banner.button-dismiss.label": "Ahora no",
  "store/promotion-banner.install.title": "Lleve un registro de sus pedidos",
  "store/promotion-banner.install.description": "Nuestra aplicación es rápida, pequeña y funciona sin conexión",
  "store/promotion-banner.install.button-accept.label": "Instalar",
  "store/promotion-banner.push-notification.title": "Lleve un registro de sus pedidos",
  "store/promotion-banner.push-notification.description": "Reciba notificaciones sobre el estado de sus pedidos",
  "store/promotion-banner.push-notification.button-accept.label": "Aceptar",
  "store/offline-warning.button": "Actualizar",
  "store/offline-warning.message": "No se puede cargar esta página. Comprueba tu conexión de red",
  "store/offline-warning.title": "Esta página no se puede cargar."
}
```


[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 pwa-components/docs/README.md from the pwa-components VTEX app.

[Assistant]
Here's the implementation:

```markdown
# PWA Components

[![Build Status](https://travis-ci.org/vtex-apps/pwa-components.svg?branch=master)](https://travis-ci.org/vtex-apps/pwa-components)

## Description

VTEX PWA Components is a collection of components PWA-related.

:loudspeaker: **Disclaimer:** Don't fork this project; Use, contribute or open issue with your feature request.

## Table of Contents

- [Usage](#Usage)
- [Components Specs](#components-specs)

## Usage

This app uses our store builder with the blocks architecture. To know more about Store Builder [click here.](https://help.vtex.com/en/tutorial/understanding-storebuilder-and-stylesbuilder#structuring-and-configuring-our-store-with-object-object)

To use this app, you need to import in your dependencies on `manifest.json`.

```json
  "dependencies": {
    "vtex.pwa-components": "0.x"
  }
```

## Components Specs

Below we have a README for each component of this project that explains how to use them.

- [PromotionBanner](PromotionBanner.md)
- [OfflineWarning](OfflineWarning.md)

```


[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 pwa-components/react/OfflineWarning.tsx from the pwa-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import { Button, EmptyState } from 'vtex.styleguide'
import { injectIntl, intlShape, InjectedIntlProps } from 'react-intl'
import PropTypes from 'prop-types'

const propTypes = {
  intl: intlShape,
}

type Props = PropTypes.InferProps<typeof propTypes>

const OfflineWarning: FC<Props & InjectedIntlProps> = ({ intl }) => {
  const handleReload = () => {
    if (window && window.location) {
      window.location.reload()
    }
  }

  return (
    <EmptyState
      title={intl.formatMessage({ id: 'store/offline-warning.title' })}
    >
      <p>{intl.formatMessage({ id: 'store/offline-warning.message' })}</p>
      <div className="pt5">
        <Button variation="secondary" size="small" onClick={handleReload}>
          <span className="flex align-baseline">
            {intl.formatMessage({ id: 'store/offline-warning.button' })}
          </span>
        </Button>
      </div>
    </EmptyState>
  )
}

OfflineWarning.propTypes = propTypes

export default injectIntl(OfflineWarning)

```


[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 pwa-components/react/PWAHelmet.tsx from the pwa-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import PropTypes from 'prop-types'

// @ts-ignore
import { Helmet, useRuntime } from 'vtex.render-runtime'

const propTypes = {
  appId: PropTypes.string.isRequired,
}

type Props = PropTypes.InferProps<typeof propTypes>

const PWAHelmet: FC<Props> = ({ appId }) => {
  const { rootPath = '' } = useRuntime()

  return (
    <Helmet
      meta={[
        { name: 'theme-color', content: '#F71963' },
        { name: 'apple-mobile-web-app-capable', content: 'yes' },
      ]}
      script={[
        {
          type: 'text/javascript',
          src: `${rootPath}/pwa/workers/register.js?scope=${encodeURIComponent(
            rootPath
          )}`,
          defer: true,
        },
      ]}
      link={[
        {
          rel: 'manifest',
          href: `${rootPath}/pwa/manifest.json?app=${appId}`,
        },
      ]}
    />
  )
}

PWAHelmet.propTypes = propTypes

export default PWAHelmet

```


[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 pwa-components/react/package.json from the pwa-components VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "pwa-components",
  "version": "0.4.2",
  "description": "Components related to PWA features",
  "scripts": {
    "pretest": "yarn",
    "test": "vtex-test-tools test --passWithNoTests"
  },
  "devDependencies": {
    "@types/graphql": "^14.5.0",
    "@types/jest": "^24.0.18",
    "@types/node": "^12.7.7",
    "@types/prop-types": "^15.7.3",
    "@types/react": "^16.9.3",
    "@vtex/test-tools": "^1.2.0",
    "prop-types": "^15.7.2",
    "vtex.pwa-graphql": "http://vtex.vteximg.com.br/_v/public/typings/v1/vtex.pwa-graphql@1.10.0/public/@types/vtex.pwa-graphql",
    "vtex.render-runtime": "http://vtex.vteximg.com.br/_v/public/typings/v1/vtex.render-runtime@8.66.2/public/@types/vtex.render-runtime",
    "vtex.store-resources": "http://vtex.vteximg.com.br/_v/public/typings/v1/vtex.store-resources@0.30.0/public/@types/vtex.store-resources",
    "vtex.styleguide": "http://vtex.vteximg.com.br/_v/public/typings/v1/vtex.styleguide@9.87.2/public/@types/vtex.styleguide"
  },
  "dependencies": {
    "react": "^16.9.0",
    "react-intl": "2.8.0"
  }
}

```


[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 pwa-components/react/PromotionBanner.tsx from the pwa-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, useCallback } from 'react'
import PropTypes from 'prop-types'
import { injectIntl, InjectedIntlProps, intlShape } from 'react-intl'

// @ts-ignore
import { Button } from 'vtex.styleguide'

// @ts-ignore
import { usePWA } from 'vtex.store-resources/PWAContext'

const propTypes = {
  intl: intlShape,
  type: PropTypes.oneOf(['install', 'push-notification']),
  onDismiss: PropTypes.func,
}

const CONSTANTS = {
  TYPE_INSTALL: 'install',
  TYPE_PUSH_NOTIFICATION: 'push-notification',
  INSTALL_TITLE: 'store/promotion-banner.install.title',
  INSTALL_DESCRIPTION: 'store/promotion-banner.install.description',
  INSTALL_ACCEPT_BUTTON_LABEL:
    'store/promotion-banner.install.button-accept.label',
  PUSH_NOTIFICATION_TITLE: 'store/promotion-banner.push-notification.title',
  PUSH_NOTIFICATION_DESCRIPTION:
    'store/promotion-banner.push-notification.description',
  PUSH_NOTIFICATIONS_ACCEPT_BUTTON_LABEL:
    'store/promotion-banner.push-notification.button-accept.label',
  DISMISS_BUTTON_LABEL: 'store/promotion-banner.button-dismiss.label',
}

type Props = PropTypes.InferProps<typeof propTypes>

const PromotionBanner: FC<Props & InjectedIntlProps> = ({
  intl,
  type = 'install',
  onDismiss,
}) => {
  const { showInstallPrompt = null } = usePWA() || {}

  const handleDismiss = useCallback(async () => {
    if (type === CONSTANTS.TYPE_INSTALL)
      localStorage.setItem('webAppInstallDismissed', 'true')
    else localStorage.setItem('pushNotificationsDismissed', 'true')

    if (onDismiss) {
      onDismiss()
    }
  }, [type, onDismiss])

  const handleAccept = useCallback(() => {
    if (type === CONSTANTS.TYPE_INSTALL) {
      showInstallPrompt()
    }
  }, [type, showInstallPrompt])

  return (
    <div className="pa6 br2 bg-muted-5 mb8 mw5 w-80-ns w-90 center fr-l">
      <p className="t-body">
        {intl.formatMessage({
          id:
            type === CONSTANTS.TYPE_INSTALL
              ? CONSTANTS.INSTALL_TITLE
              : CONSTANTS.PUSH_NOTIFICATION_TITLE,
        })}
      </p>
      <p className="t-small c-muted-1">
        {intl.formatMessage({
          id:
            type === CONSTANTS.TYPE_INSTALL
              ? CONSTANTS.INSTALL_DESCRIPTION
              : CONSTANTS.PUSH_NOTIFICATION_DESCRIPTION,
        })}
      </p>
      <Button onClick={handleDismiss} variation="tertiary" size="small">
        {intl.formatMessage({
          id: CONSTANTS.DISMISS_BUTTON_LABEL,
        })}
      </Button>
      <Button onClick={handleAccept} size="small">
        {intl.formatMessage({
          id:
            type === CONSTANTS.TYPE_INSTALL
              ? CONSTANTS.INSTALL_ACCEPT_BUTTON_LABEL
              : CONSTANTS.PUSH_NOTIFICATIONS_ACCEPT_BUTTON_LABEL,
        })}
      </Button>
    </div>
  )
}

PromotionBanner.propTypes = propTypes

export default injectIntl(PromotionBanner)

```


[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 pwa-components/store/interfaces.json from the pwa-components VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "promotion-banner": {
    "component": "PromotionBanner"
  },
  "offline-warning": {
    "component": "OfflineWarning"
  }
}
```


[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 pwa-components/react/typings/vtex.styleguide.d.ts from the pwa-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.styleguide' {
  export const Button
  export const EmptyState
}

```


[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 octopia-scheduler/graphql/schema.graphql from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```graphql
type Query {
  getAllSchedulers: [SchedulerInformation]
  getSchedulerById(id: ID!): SchedulerInformation
}

type Mutation {
  createOrUpdateScheduler(
    configuration: SchedulerConfigurationInput
  ): SchedulerInformation

  deleteScheduler(id: ID!): 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 octopia-scheduler/node/service.json from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "memory": 256,
  "ttl": 10,
  "timeout": 2,
  "minReplicas": 2,
  "maxReplicas": 4,
  "workers": 1,
  "routes": {
    "getAllSchedulers": {
      "path": "/_v/octopia-scheduler/pvt/schedulers",
      "public": false
    },
    "getSchedulerById": {
      "path": "/_v/octopia-scheduler/pvt/schedulers/:id",
      "public": false
    },
    "createOrUpdateScheduler": {
      "path": "/_v/octopia-scheduler/pvt/schedulers/create-or-update/:type",
      "public": false
    },
    "deleteScheduler": {
      "path": "/_v/octopia-scheduler/pvt/schedulers/delete/:id",
      "public": false
    }
  }
}

```


[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 octopia-scheduler/node/package.json from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "co-body": "^6.0.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.15",
    "@vtex/test-tools": "^1.0.0",
    "@vtex/tsconfig": "^0.5.6",
    "typescript": "3.9.7",
    "vtex.octopia-scheduler": "https://octopia--edydemo.myvtex.com/_v/private/typings/linked/v1/vtex.octopia-scheduler@0.0.1+build1683562679/public/@types/vtex.octopia-scheduler"
  },
  "resolutions": {
    "@types/testing-library__dom": "6.12.1",
    "@types/express": "4.16.0",
    "@types/express-serve-static-core": "4.16.0"
  },
  "scripts": {
    "lint": "tsc --noEmit --pretty"
  },
  "version": "0.2.21"
}

```


[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 octopia-scheduler/node/index.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ParamsContext, RecorderState } from '@vtex/api'
import { Service } from '@vtex/api'

import type { Clients } from './clients'
import { clientsConfig } from './clients'
import { applicationRoutes } from './middlewares/routes'
import { resolvers } from './resolvers'

export default new Service<Clients, RecorderState, ParamsContext>({
  clients: clientsConfig,
  routes: applicationRoutes,
  graphql: {
    resolvers,
  },
})

```


[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 octopia-scheduler/graphql/types/Scheduler.graphql from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```graphql
type SchedulerInformation {
  id: ID!
  workspace: String!
  app: String!
  attempt: Int!
  endDate: String!
  expression: String!
  NextExecution: String!
  request: Request!
  retry: Retry!
}

type SchedulerConfiguration {
  id: ID!
  scheduler: Scheduler
  request: Request
  retry: Retry
}

type SchedulerConfigurationPayload {
  type: String!
  production: Boolean!
  account: String!
  workspace: String!
  id: String
  endDate: String
  expression: String
  uri: String
  headers: JSON
  body: JSON
}

scalar JSON

type Request {
  uri: String!
  method: String!
  headers: JSON!
  body: JSON
}

type Retry {
  delay: Delay
  times: Int!
  backOffRate: Int!
}

type Delay {
  addMinutes: Int!
  addHours: Int!
  addDays: Int!
}

type Scheduler {
  expression: String!
  endDate: String!
}

input SchedulerConfigurationInput {
  type: String!
  production: Boolean!
  account: String!
  workspace: String!
  id: String
  endDate: String
  expression: String
  uri: String
  headers: JSON
  body: 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 octopia-scheduler/node/clients/scheduler.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { IOContext, InstanceOptions } from '@vtex/api'
import { JanusClient } from '@vtex/api'
import type {
  SchedulerConfiguration,
  SchedulerInformation,
} from 'vtex.octopia-scheduler'

import { SCHEDULER_VERSION, VTEX_APP_NAME } from '../constants'

export class SchedulerClient extends JanusClient {
  constructor(ctx: IOContext, options?: InstanceOptions) {
    super(ctx, {
      ...options,
      params: {
        version: SCHEDULER_VERSION,
      },
      headers: {
        ...options?.headers,
        VtexIdclientAutCookie: ctx.authToken,
      },
    })
  }

  private baseRoute = `/api/scheduler/${this.context.workspace}/${VTEX_APP_NAME}`

  public getAll(): Promise<SchedulerInformation[]> {
    return this.http.get(this.baseRoute, {
      metric: 'scheduler-list-all',
    })
  }

  public getById(schedulerId: string): Promise<SchedulerInformation> {
    return this.http.get(`${this.baseRoute}/${schedulerId}`, {
      metric: 'scheduler-get-by-id',
    })
  }

  public createOrUpdate(
    config: SchedulerConfiguration
  ): Promise<SchedulerInformation> {
    return this.http.put(this.baseRoute, config, {
      metric: 'scheduler-create-or-update',
    })
  }

  public delete(schedulerId: string) {
    return this.http.delete(`${this.baseRoute}/${schedulerId}`, {
      metric: 'scheduler-delete',
    })
  }
}

```


[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 octopia-scheduler/node/clients/index.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

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

import { SchedulerClient } from './scheduler'

export class Clients extends IOClients {
  public get scheduler() {
    return this.getOrSet('scheduler', SchedulerClient)
  }
}

export const clientsConfig: ClientsConfig<Clients> = {
  implementation: Clients,
  options: {
    default: {
      retries: 2,
      timeout: 10000,
    },
  },
}

```


[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 octopia-scheduler/node/constants/index.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const VTEX_APP_NAME = 'vtex.octopia-scheduler'
export const SCHEDULER_VERSION = '4'

```


[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 octopia-scheduler/node/typings/global.d.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ServiceContext } from '@vtex/api'
import type { Clients } from '../clients'

declare global {
  type Context = ServiceContext<Clients>
}

```


[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 octopia-scheduler/node/resolvers/index.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { getAllSchedulers } from './schedulers/getAll'
import { getSchedulerById } from './schedulers/getById'
import { createOrUpdateScheduler } from './schedulers/createOrUpdate'
import { deleteScheduler } from './schedulers/delete'

export const resolvers = {
  Query: {
    getAllSchedulers,
    getSchedulerById,
  },
  Mutation: {
    createOrUpdateScheduler,
    deleteScheduler,
  },
}

```


[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 octopia-scheduler/node/helpers/serviceError.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
type ServiceErrorArgs = {
  message: string
  reason: string
  status?: number
}

export class ServiceError extends Error {
  constructor({ message, reason, status }: ServiceErrorArgs) {
    super(message)
    this.reason = reason ?? 'INTERNAL_SERVER_ERROR'
    this.status = status ?? 500
  }

  public readonly reason: string
  public readonly 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 octopia-scheduler/node/helpers/scheduler.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type {
  SchedulerConfiguration,
  SchedulerConfigurationPayload,
} from 'vtex.octopia-scheduler'

/**
 * Function to create the scheduler configuration
 * @param args
 * @returns SchedulerConfiguration
 */
export function createSchedulerConfiguration(
  args: SchedulerConfigurationPayload
): SchedulerConfiguration {
  const {
    type,
    production,
    account,
    workspace,
    id,
    endDate,
    expression,
    uri,
    headers = defaultHeaders(),
    body = defaultBody(type),
  } = args

  return {
    id: id ?? createId(type),
    scheduler: {
      expression: expression ?? defaultExpression(type),
      endDate: endDate ?? createEndDate(production),
    },
    retry: {
      delay: {
        addMinutes: 2,
        addHours: 0,
        addDays: 0,
      },
      times: 2,
      backOffRate: 2,
    },
    request: {
      uri: uri ?? defaultUri(workspace, account, type),
      method: 'POST',
      headers,
      body,
    },
  }
}

function createId(type: SchedulerConfigurationPayload['type']) {
  return `${type.toUpperCase()}_SCHEDULER`
}

function createEndDate(production: boolean) {
  const endDate = new Date()

  // If the environment is not production, the endDate will be 24 hours from now
  endDate.setHours(endDate.getHours() + 24)

  // If the environment is production, the endDate will be 10 years from now
  if (production) {
    endDate.setFullYear(endDate.getFullYear() + 10)
  }

  return endDate.toISOString()
}

function defaultExpression(type: SchedulerConfigurationPayload['type']) {
  return type === 'offers' ? '0 0/12 * * *' : '0 * * * *'
}

function defaultUri(
  workspace: string,
  account: string,
  type: SchedulerConfigurationPayload['type']
) {
  return `https://${workspace}--${account}.myvtex.com/_v/octopia-integration/${type}`
}

function defaultHeaders() {
  return {
    'Content-Type': 'application/json',
    Accept: 'application/json',
  }
}

function defaultBody(type: SchedulerConfigurationPayload['type']) {
  return {
    text: `${type} scheduler`,
  }
}

```


[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 octopia-scheduler/node/middlewares/routes/errorHandler.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
export async function errorHandler(ctx: Context, next: () => Promise<void>) {
  try {
    await next()
  } catch (error) {
    if (process.env.VTEX_APP_LINKED) {
      console.error(error)

      return
    }

    const {
      vtex: { logger },
    } = ctx

    logger.error({
      message: error.message,
      reason: error.reason,
      exception: error,
    })

    ctx.status = error.status || error.response?.status || 500
    ctx.body = { error: error.message, reason: error.reason }
    ctx.app.emit('error', error, ctx)
  }
}

```


[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 octopia-scheduler/node/middlewares/routes/index.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

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

import { errorHandler } from './errorHandler'
import { getAllSchedulers } from './schedulers/getAll'
import { getSchedulerById } from './schedulers/getById'
import { createOrUpdateScheduler } from './schedulers/createOrUpdate'
import { deleteScheduler } from './schedulers/delete'

export const applicationRoutes = {
  getAllSchedulers: method({
    GET: [errorHandler, getAllSchedulers],
  }),
  getSchedulerById: method({
    GET: [errorHandler, getSchedulerById],
  }),
  createOrUpdateScheduler: method({
    PUT: [errorHandler, createOrUpdateScheduler],
  }),
  deleteScheduler: method({
    DELETE: [errorHandler, deleteScheduler],
  }),
}

```


[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 octopia-scheduler/node/middlewares/routes/schedulers/createOrUpdate.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { json } from 'co-body'

import { ServiceError } from '../../../helpers/serviceError'
import { createOrUpdateSchedulerService } from '../../../services/schedulers/createOrUpdate'

export async function createOrUpdateScheduler(ctx: Context) {
  const {
    params: { type },
  } = ctx

  const body = await json(ctx.req)

  const configuration = {
    type,
    ...body,
  }

  try {
    const schedulerInformation = await createOrUpdateSchedulerService(
      configuration,
      ctx
    )

    ctx.body = schedulerInformation
  } catch (error) {
    throw new ServiceError({
      message: 'Error creating or updating scheduler',
      reason: error.message,
    })
  }
}

```


[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 octopia-scheduler/node/middlewares/routes/schedulers/getAll.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ServiceError } from '../../../helpers/serviceError'
import { getAllSchedulersService } from '../../../services/schedulers/getAll'

export async function getAllSchedulers(ctx: Context) {
  try {
    const schedulers = await getAllSchedulersService(ctx)

    ctx.body = schedulers
  } catch (error) {
    throw new ServiceError({
      message: 'Error getting schedulers',
      reason: error.message,
    })
  }
}

```


[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 octopia-scheduler/node/middlewares/routes/schedulers/getById.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ServiceError } from '../../../helpers/serviceError'
import { getSchedulerByIdService } from '../../../services/schedulers/getById'

export async function getSchedulerById(ctx: Context) {
  const {
    vtex: {
      route: {
        params: { id },
      },
    },
  } = ctx

  try {
    const schedulerInformation = await getSchedulerByIdService(
      id as string,
      ctx
    )

    ctx.body = schedulerInformation
  } catch (error) {
    throw new ServiceError({
      message: 'Error getting scheduler',
      reason: error.message,
    })
  }
}

```


[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 octopia-scheduler/node/middlewares/routes/schedulers/delete.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ServiceError } from '../../../helpers/serviceError'
import { deleteSchedulerService } from '../../../services/schedulers/delete'

export async function deleteScheduler(ctx: Context) {
  const {
    vtex: {
      route: {
        params: { id },
      },
    },
  } = ctx

  try {
    await deleteSchedulerService(id as string, ctx)

    ctx.status = 204
  } catch (error) {
    throw new ServiceError({
      message: 'Error deleting scheduler',
      reason: error.message,
    })
  }
}

```


[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 octopia-scheduler/node/resolvers/schedulers/createOrUpdate.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ResolverError } from '@vtex/api'
import type { SchedulerConfigurationPayload } from 'vtex.octopia-scheduler'

import { createOrUpdateSchedulerService } from '../../services/schedulers/createOrUpdate'

export async function createOrUpdateScheduler(
  _: unknown,
  args: { configuration: SchedulerConfigurationPayload },
  ctx: Context
) {
  // eslint-disable-next-line no-console
  console.log('Args', args)

  const { configuration } = args

  if (configuration.type !== 'offers' && configuration.type !== 'orders') {
    throw new ResolverError('Invalid type', 400, 'INVALID_TYPE')
  }

  try {
    const schedulerInformation = await createOrUpdateSchedulerService(
      configuration,
      ctx
    )

    return schedulerInformation
  } catch (error) {
    throw new ResolverError(
      'Error creating or updating scheduler',
      error.statusCode ?? 500,
      error.message ?? 'INTERNAL_SERVER_ERROR'
    )
  }
}

```


[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 octopia-scheduler/node/resolvers/schedulers/getAll.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

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

import { getAllSchedulersService } from '../../services/schedulers/getAll'

export async function getAllSchedulers(_: unknown, __: unknown, ctx: Context) {
  try {
    const schedulers = await getAllSchedulersService(ctx)

    return schedulers
  } catch (error) {
    throw new ResolverError(
      'Error getting all schedulers',
      error.statusCode ?? 500,
      error.message ?? 'INTERNAL_SERVER_ERROR'
    )
  }
}

```


[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 octopia-scheduler/node/resolvers/schedulers/getById.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

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

export async function getSchedulerById(
  _: unknown,
  args: { id: string },
  ctx: Context
) {
  const { id } = args

  const {
    clients: { scheduler },
  } = ctx

  try {
    const schedulerInformation = await scheduler.getById(id)

    return schedulerInformation
  } catch (error) {
    throw new ResolverError(
      'Error getting scheduler',
      error.statusCode ?? 500,
      error.message ?? 'INTERNAL_SERVER_ERROR'
    )
  }
}

```


[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 octopia-scheduler/node/resolvers/schedulers/delete.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

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

import { deleteSchedulerService } from '../../services/schedulers/delete'

export async function deleteScheduler(
  _: unknown,
  args: { id: string },
  ctx: Context
) {
  // eslint-disable-next-line no-console
  console.log('Args', args)

  const { id } = args

  try {
    await deleteSchedulerService(id, ctx)

    return true
  } catch (error) {
    throw new ResolverError(
      'Error deleting scheduler',
      error.statusCode ?? 500,
      error.message ?? 'INTERNAL_SERVER_ERROR'
    )
  }
}

```


[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 octopia-scheduler/node/services/schedulers/createOrUpdate.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { UserInputError } from '@vtex/api'
import type { SchedulerConfigurationPayload } from 'vtex.octopia-scheduler'

import { createSchedulerConfiguration } from '../../helpers/scheduler'

export async function createOrUpdateSchedulerService(
  configuration: SchedulerConfigurationPayload,
  ctx: Context
) {
  const {
    clients: { scheduler },
    vtex: { production, workspace, account },
  } = ctx

  try {
    const { type } = configuration

    if (type !== 'offers' && type !== 'orders') {
      throw new UserInputError('Invalid type')
    }

    const schedulerConfiguration = createSchedulerConfiguration({
      ...configuration,
      production,
      account,
      workspace,
    })

    const schedulerInformation = await scheduler.createOrUpdate(
      schedulerConfiguration
    )

    return schedulerInformation
  } catch (error) {
    throw new Error(error.message)
  }
}

```


[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 octopia-scheduler/node/services/schedulers/getAll.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
export async function getAllSchedulersService(ctx: Context) {
  const {
    clients: { scheduler },
  } = ctx

  try {
    const schedulers = await scheduler.getAll()

    return schedulers
  } catch (error) {
    throw new Error(error.message)
  }
}

```


[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 octopia-scheduler/node/services/schedulers/getById.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
export async function getSchedulerByIdService(id: string, ctx: Context) {
  const {
    clients: { scheduler },
  } = ctx

  try {
    const schedulerInformation = await scheduler.getById(id)

    return schedulerInformation
  } catch (error) {
    throw new Error(error.message)
  }
}

```


[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 octopia-scheduler/node/services/schedulers/delete.ts from the octopia-scheduler VTEX app.

[Assistant]
Here's the implementation:

```typescript
export async function deleteSchedulerService(id: string, ctx: Context) {
  const {
    clients: { scheduler },
  } = ctx

  try {
    await scheduler.delete(id)

    return true
  } catch (error) {
    throw new Error(error.message)
  }
}

```


[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 product-context/docs/README.md from the product-context VTEX app.

[Assistant]
Here's the implementation:

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

# Product Context

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

The Product Context app is designed to provide essential product data to all child blocks within your store theme.

## Configuration

1. Add the `product-context` app as a dependency to your store theme's `manifest.json` file:

    ```diff manifest.json
      "dependencies": {
    +   "vtex.product-context": "0.x"
      }
    ```

2. Install the TypeScript types exported by the app by running the following command:

    ```sh
    vtex setup
    ```

Now, you're ready to import components and hooks from the app. Check this example component that displays the product name using data stored in the nearest `ProductContext`:

```tsx
// Notice that this is TypeScript, and this code should be in a .tsx file
import React, { FC } from 'react'
import { useProduct } from 'vtex.product-context'

const MyComponent: FC = () => {
  const productContextValue = useProduct();

  return (
    <Fragment>
      {productContextValue?.product?.productName}
    </Fragment>
  )
}

export default MyComponent
```

## Hooks

### `useProduct`

The `useProduct` hook allows your app to retrieve data from the nearest `ProductContext` relative to its caller. Expect an object with the structure below as the return value:

```ts
interface ProductContextState {
  selectedItem?: Item | null
  product: MaybeProduct
  selectedQuantity: number
  skuSelector: {
    selectedImageVariationSKU: string | null
    isVisible: boolean
    areAllVariationsSelected: boolean
  }
  buyButton: BuyButtonContextState
  assemblyOptions: {
    items: Record<GroupId, AssemblyOptionItem[]>
    inputValues: Record<GroupId, InputValues>
    areGroupsValid: Record<GroupId, boolean>
  }
}
```

> Note that if the hook is called outside a `ProductContextProvider`, the return value may be `undefined` or an empty object.

### `useProductDispatch`

The `useProductDispatch` hook provides a `dispatch` function to manipulate the nearest `ProductContext`. The function supports the following actions:

- `SELECT_IMAGE_VARIATION`: Sets the value for the `skuSelector.selectedImageVariationSKU` property.
- `SET_QUANTITY`: Sets the value for the `selectedQuantity` property.
- `SKU_SELECTOR_SET_VARIATIONS_SELECTED`: Sets the value for the `skuSelector.areAllVariationsSelected` property.
- `SET_BUY_BUTTON_CLICKED`: Sets the value for the `buyButton.clicked` property.
- `SKU_SELECTOR_SET_IS_VISIBLE`: Sets the value for the `skuSelector.isVisible` property.
- `SET_SELECTED_ITEM`: Sets the value for the `selectedItem` property.
- `SET_ASSEMBLY_OPTIONS`: Sets the value for the `assemblyOptions` property.
- `SET_PRODUCT`: Sets the value for the `product` property.
- `SET_LOADING_ITEM`: Sets the value of whether a selected item is loading.

<!-- DOCS-IGNORE:start -->

## Contributors ✨

Thanks goes to these wonderful people:

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
  <tr>
    <td align="center"><a href="https://github.com/sahanljc"><img src="https://avatars.githubusercontent.com/u/42151054?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sahan Jayawardana</b></sub></a><br /><a href="https://github.com/vtex-apps/product-context/commits?author=sahanljc" title="Code">💻</a></td>
  </tr>
</table>

<!-- markdownlint-restore -->
<!-- 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!

<!-- DOCS-IGNORE:end -->

```


[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 product-context/react/ProductContext.ts from the product-context VTEX app.

[Assistant]
Here's the implementation:

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

import type { ProductContextState } from './ProductContextProvider'

const ProductContext = createContext<Partial<ProductContextState> | undefined>(
  {}
)

export default 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 product-context/react/useProductDispatch.ts from the product-context VTEX app.

[Assistant]
Here's the implementation:

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

import { ProductDispatchContext } from './ProductDispatchContext'

/**
 * useProductDispatch hook. Use this hook to make changes to the data from the nearest
 * `ProductContext`.
 *
 * @returns `dispatch` function | `null`.
 */
function useProductDispatch() {
  return useContext(ProductDispatchContext)
}

export default useProductDispatch

```


[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 product-context/react/ProductContextProvider.tsx from the product-context VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, useEffect, Dispatch } from 'react'

import ProductContext from './ProductContext'
import { ProductDispatchContext } from './ProductDispatchContext'
import { useProductReducer, getSelectedItem } from './reducer'
import { getSelectedSKUFromQueryString } from './modules/skuQueryString'
import { MaybeProduct, Item } from './ProductTypes'

export interface ProductAndQuery {
  query: Record<string, any>
  product: MaybeProduct
}

type GroupId = string

export interface AssemblyOptionItem {
  id: string
  quantity: number
  seller: string
  initialQuantity: number
  choiceType: string
  name: string
  price: number
  children: Record<string, AssemblyOptionItem[]> | null
}

export interface BuyButtonContextState {
  clicked: boolean
}

export interface SkuSelectorContextState {
  selectedImageVariationSKU: string | null
  isVisible: boolean
  areAllVariationsSelected: boolean
}

export interface ProductContextState {
  loadingItem: boolean
  selectedItem?: Item | null
  product: MaybeProduct
  selectedQuantity: number
  skuSelector: Partial<SkuSelectorContextState>
  buyButton: BuyButtonContextState
  assemblyOptions: {
    items: Record<GroupId, AssemblyOptionItem[]>
    inputValues: Record<GroupId, InputValues>
    areGroupsValid: Record<GroupId, boolean>
  }
}

type InputValues = Record<string, string>

type Action<K, V = void> = V extends void ? { type: K } : { type: K } & V

export type Actions =
  | Action<
      'SELECT_IMAGE_VARIATION',
      { args: { selectedImageVariationSKU: string | null } }
    >
  | Action<'SET_QUANTITY', { args: { quantity: number } }>
  | Action<
      'SKU_SELECTOR_SET_VARIATIONS_SELECTED',
      { args: { allSelected: boolean } }
    >
  | Action<'SET_BUY_BUTTON_CLICKED', { args: { clicked: boolean } }>
  | Action<'SKU_SELECTOR_SET_IS_VISIBLE', { args: { isVisible: boolean } }>
  | Action<'SET_SELECTED_ITEM', { args: { item: Item | undefined | null } }>
  | Action<
      'SET_ASSEMBLY_OPTIONS',
      {
        args: {
          groupId: string
          groupItems: AssemblyOptionItem[]
          groupInputValues: InputValues
          isValid: boolean
        }
      }
    >
  | Action<'SET_PRODUCT', { args: { product: MaybeProduct } }>
  | Action<'SET_LOADING_ITEM', { args: { loadingItem: boolean } }>

function useProductInState(product: MaybeProduct, dispatch: Dispatch<Actions>) {
  useEffect(() => {
    if (product) {
      dispatch({
        type: 'SET_PRODUCT',
        args: { product },
      })
    }
  }, [product, dispatch])
}

function useSelectedItemFromId(
  dispatch: Dispatch<Actions>,
  product: MaybeProduct,
  skuId?: string
) {
  useEffect(() => {
    const items = product?.items ?? []

    dispatch({
      type: 'SET_SELECTED_ITEM',
      args: { item: getSelectedItem(skuId, items) },
    })
  }, [dispatch, skuId, product])
}

const ProductContextProvider: FC<ProductAndQuery> = ({
  query,
  product,
  children,
}) => {
  const [state, dispatch] = useProductReducer({ query, product })

  // These hooks are used to keep the state in sync with API data, specially when switching between products without exiting the product page
  useProductInState(product, dispatch)
  const selectedSkuQueryString = getSelectedSKUFromQueryString(
    query,
    product?.items
  )

  useSelectedItemFromId(dispatch, product, selectedSkuQueryString)

  return (
    <ProductContext.Provider value={state}>
      <ProductDispatchContext.Provider value={dispatch}>
        {children}
      </ProductDispatchContext.Provider>
    </ProductContext.Provider>
  )
}

export default ProductContextProvider

```


[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 product-context/react/useProduct.ts from the product-context VTEX app.

[Assistant]
Here's the implementation:

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

import ProductContext from './ProductContext'

/**
 * useProduct hook. Use this hook to access the data from the nearest
 * `ProductContext`.
 *
 * Be aware that this could be an empty Object if used outside of a
 * `ProductContextProvider`.
 *
 * @returns `ProductContextState` | `undefined` | `{}`
 */
function useProduct() {
  return useContext(ProductContext)
}

export default useProduct

```


[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 product-context/react/ProductDispatchContext.ts from the product-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { Dispatch } from 'react'
import { createContext, useContext } from 'react'

import type { Actions } from './ProductContextProvider'

export const ProductDispatchContext = createContext<Dispatch<Actions> | null>(
  null
)

function useProductDispatch() {
  return useContext(ProductDispatchContext)
}

export default { ProductDispatchContext, useProductDispatch }

```


[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 product-context/react/package.json from the product-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "scripts": {
    "test": "vtex-test-tools test"
  },
  "devDependencies": {
    "@apollo/react-testing": "^4.0.0",
    "@types/node": "^11.13.4",
    "@types/ramda": "^0.26.21",
    "@types/react": "^16.8.13",
    "@vtex/test-tools": "^3.1.0",
    "@vtex/tsconfig": "^0.4.4",
    "react-intl": "^5.4.0",
    "typescript": "3.9.7",
    "vtex.render-runtime": "http://vtex.vteximg.com.br/_v/public/typings/v1/vtex.render-runtime@8.62.2/public/_types/react"
  },
  "version": "0.10.1"
}

```


[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 product-context/react/ProductTypes.ts from the product-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
export type {
  ProductContextState,
  AssemblyOptionItem,
  SkuSelectorContextState,
} from './ProductContextProvider'

type Maybe<T> = T | null | undefined

export type MaybeProduct = Maybe<Product>

export type ProductSpecification = {
  name: string
  originalName: string
  values: string[]
}

/** @deprecated Use `ProductSpecification` */
export type SpecificationGroupItem = ProductSpecification

export type SpecificationGroup = {
  name: string
  originalName: string
  specifications: ProductSpecification[]
}

export type Product = {
  brand: string
  brandId: string
  cacheId: string
  categories: string[]
  categoriesIds: string[]
  categoryId: string
  categoryTree: Array<{ id: string; name: string; href: string }>
  clusterHighlights: Array<{ id: string; name: string }>
  description: string
  itemMetadata: ItemMetadata
  items: Item[]
  link: string
  linkText: string
  metaTagDescription: string
  priceRange: {
    sellingPrice: { highPrice: number; lowPrice: number }
    listPrice: { highPrice: number; lowPrice: number }
  }
  productClusters: Array<{ id: string; name: string }>
  productId: string
  productName: string
  productReference: string
  properties: ProductSpecification[]
  skuSpecifications: SkuSpecification[]
  specificationGroups: SpecificationGroup[]
  titleTag: string
}

export type Item = {
  complementName: string
  ean: string
  images: Array<{
    imageId: string
    imageLabel: string
    imageTag: string
    imageUrl: string
    imageText: string
  }>
  itemId: string
  measurementUnit: string
  name: string
  nameComplete: string
  referenceId: Array<{ Key: string; Value: string }>
  sellers: Seller[]
  unitMultiplier: number
  variations: Array<{ name: string; values: string[] }>
  videos: Array<{ videoUrl: string }>
}

export type SkuSpecification = {
  field: SkuSpecificationField
  values: SkuSpecificationValues[]
}

export type SkuSpecificationField = {
  name: string
}

export type SkuSpecificationValues = {
  name: string
}

export type Seller = {
  sellerId: string
  sellerName: string
  addToCartLink: string
  sellerDefault: boolean
  commertialOffer: CommercialOffer
}

type TeaserCondition = {
  minimumQuantity: number
  parameters: Array<{
    name: string
    value: string
  }>
}

type TeaserEffects = {
  parameters: Array<{
    name: string
    value: string
  }>
}

export type Teaser = {
  name: string
  conditions: TeaserCondition
  effects: TeaserEffects
}

export type CommercialOffer = {
  Installments: Installment[]
  discountHighlights: Array<{ name: string }>
  teasers: Teaser[]
  Price: number
  ListPrice: number
  spotPrice: number
  SellingPrice?: number
  PriceWithoutDiscount: number
  RewardValue: number
  PriceValidUntil: string
  AvailableQuantity: number
  Tax: number
  taxPercentage: number
  CacheVersionUsedToCallCheckout: string
}

export type Installment = {
  Value: number
  InterestRate: number
  TotalValuePlusInterestRate: number
  NumberOfInstallments: number
  PaymentSystemName: string
  PaymentSystemGroupName: string
  Name: string
}

export type ItemMetadata = {
  items: Array<{
    id: string
    name: string
    imageUrl: string
    seller: string
    assemblyOptions: Array<{
      id: string
      name: string
      required: boolean
      inputValues: InputValue[]
      composition: Composition | null
    }>
  }>
  priceTable: Array<{
    type: string
    values: Array<{ id: string; assemblyId: string; price: number | null }>
  }>
}

export type InputValue = TextInputValue | BooleanInputValue | OptionsInputValue

const enum InputValueType {
  'TEXT' = 'TEXT',
  'BOOLEAN' = 'BOOLEAN',
  'OPTIONS' = 'OPTIONS',
}

export type TextInputValue = {
  type: InputValueType.TEXT
  defaultValue: ''
  label: string
  maxLength: number
  domain: null
}

export type BooleanInputValue = {
  type: InputValueType.BOOLEAN
  defaultValue: boolean
  label: string
  maxLength: null
  domain: null
}

export type OptionsInputValue = {
  type: InputValueType.OPTIONS
  defaultValue: string
  label: string
  maxLength: null
  domain: string[]
}

export type Composition = {
  minQuantity: number
  maxQuantity: number
  items: Array<{
    id: string
    minQuantity: number
    maxQuantity: number
    priceTable: string
    seller: string
    initialQuantity: 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 product-context/react/reducer/index.ts from the product-context VTEX app.

[Assistant]
Here's the implementation:

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

import { getSelectedSKUFromQueryString } from '../modules/skuQueryString'
import { findAvailableProduct } from '../modules/items'
import type { Item } from '../ProductTypes'
import type {
  ProductContextState,
  Actions,
  ProductAndQuery,
} from '../ProductContextProvider'

const defaultState: ProductContextState = {
  loadingItem: false,
  product: undefined,
  selectedItem: null,
  selectedQuantity: 1,
  skuSelector: {
    selectedImageVariationSKU: null,
    isVisible: false,
    areAllVariationsSelected: true,
  },
  buyButton: {
    clicked: false,
  },
  assemblyOptions: {
    items: {},
    inputValues: {},
    areGroupsValid: {},
  },
}

function reducer(
  state: ProductContextState,
  action: Actions
): ProductContextState {
  switch (action.type) {
    case 'SET_QUANTITY': {
      const args = action.args || {}

      return {
        ...state,
        selectedQuantity: args.quantity,
      }
    }

    case 'SELECT_IMAGE_VARIATION': {
      const args = action.args || {}

      return {
        ...state,
        skuSelector: {
          ...state.skuSelector,
          selectedImageVariationSKU: args.selectedImageVariationSKU,
        },
      }
    }

    case 'SKU_SELECTOR_SET_VARIATIONS_SELECTED': {
      const args = action.args || {}

      return {
        ...state,
        skuSelector: {
          ...state.skuSelector,
          areAllVariationsSelected: args.allSelected,
        },
      }
    }

    case 'SET_BUY_BUTTON_CLICKED': {
      const args = action.args || {}

      return {
        ...state,
        buyButton: {
          ...state.buyButton,
          clicked: args.clicked,
        },
      }
    }

    case 'SKU_SELECTOR_SET_IS_VISIBLE': {
      const args = action.args || {}

      return {
        ...state,
        skuSelector: {
          ...state.skuSelector,
          isVisible: args.isVisible,
        },
      }
    }

    case 'SET_SELECTED_ITEM': {
      const args = action.args || {}

      return {
        ...state,
        loadingItem: false,
        selectedItem: args.item,
      }
    }

    case 'SET_LOADING_ITEM': {
      return {
        ...state,
        loadingItem: Boolean(action.args.loadingItem),
      }
    }

    case 'SET_ASSEMBLY_OPTIONS': {
      const {
        groupId = '',
        groupItems = [],
        groupInputValues = {},
        isValid = false,
      } = action.args || {}

      return {
        ...state,
        assemblyOptions: {
          ...state.assemblyOptions,
          inputValues: {
            ...state.assemblyOptions.inputValues,
            [groupId]: groupInputValues,
          },
          items: {
            ...state.assemblyOptions.items,
            [groupId]: groupItems,
          },
          areGroupsValid: {
            ...state.assemblyOptions.areGroupsValid,
            [groupId]: isValid,
          },
        },
      }
    }

    case 'SET_PRODUCT': {
      const args = action.args || {}
      const differentSlug = state?.product?.linkText !== args?.product?.linkText

      return {
        ...state,
        ...(differentSlug ? defaultState : {}),
        product: args.product,
      }
    }

    default:
      return state
  }
}

export function getSelectedItem(skuId: string | undefined, items: Item[]) {
  return skuId
    ? items.find((item) => item.itemId === skuId)
    : items.find(findAvailableProduct) ?? items[0]
}

function initReducer({ query, product }: ProductAndQuery) {
  const items = product?.items ?? []

  return {
    ...defaultState,
    selectedItem: getSelectedItem(
      getSelectedSKUFromQueryString(query, items),
      items
    ),
    product,
  }
}

export const useProductReducer = ({ query, product }: ProductAndQuery) =>
  useReducer(reducer, { query, product }, initReducer)

```


[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 product-context/react/__tests__/ProductContextProvider.test.tsx from the product-context VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-env jest */
import React, { useContext } from 'react'
import { render } from '@vtex/test-tools/react'

// eslint-disable-next-line jest/no-mocks-import
import { getProduct, getItem } from '../__mocks__/productMock'
import ProductContextProvider from '../ProductContextProvider'
import ProductContext from '../ProductContext'
import ProductDispatchContext from '../ProductDispatchContext'

const { useProductDispatch } = ProductDispatchContext

const ProductPageMock = () => {
  const { selectedItem, product, selectedQuantity } = useContext(
    ProductContext
  ) as any

  return (
    <div>
      <div>Product Page</div>
      <div>Selected Item id: {selectedItem?.itemId}</div>
      <div>Selected Item name: {selectedItem?.name}</div>
      {product ? (
        <div>product slug: {product?.linkText}</div>
      ) : (
        <div>no product</div>
      )}
      <div>Selected Quantity: {selectedQuantity}</div>
    </div>
  )
}

describe('ProductContextProvider component', () => {
  const getProps = (customProps: Partial<ProductAndQuery>): ProductAndQuery => {
    const product = getProduct()
    const props = {
      product,
      query: {},
      ...customProps,
    }

    return props
  }

  const renderComponent = (customProps: Partial<ProductAndQuery> = {}) => {
    const component = render(
      <ProductContextProvider {...getProps(customProps)}>
        <ProductPageMock />
      </ProductContextProvider>
    )

    const { getByText, rerender } = component

    return {
      ...component,
      testNoProduct: () => getByText('no product'),
      getSelectedItemId: (item: { itemId: string }) =>
        getByText(`Selected Item id: ${item.itemId}`),
      getSelectedItemName: (item: { name: string }) =>
        getByText(`Selected Item name: ${item.name}`),
      getProductSlug: (product: { linkText: string }) =>
        getByText(`product slug: ${product.linkText}`),
      rerender: (newProps: any) =>
        rerender(
          <ProductContextProvider {...newProps}>
            <ProductPageMock />
          </ProductContextProvider>
        ),
    }
  }

  it('should render with product', () => {
    const product = getProduct()
    const { getProductSlug } = renderComponent()

    getProductSlug(product)
  })

  it('should render with no product and then switch', () => {
    const { getProductSlug, rerender, testNoProduct } = renderComponent({
      product: undefined,
    })

    testNoProduct()

    const product = getProduct()

    rerender({ product, query: {} })

    getProductSlug(product)
  })

  it('should switch items and reset state', () => {
    const product = getProduct()
    const {
      rerender,
      getSelectedItemId,
      getSelectedItemName,
      getProductSlug,
    } = renderComponent()

    const newItem = getItem('2')
    const newProduct = getProduct({
      items: [newItem],
      productId: '2',
      linkText: 'product-slug-2',
      titleTag: 'Product 2',
      productName: 'Product 2',
    })

    getSelectedItemId(product.items[0])
    getSelectedItemName(product.items[0])
    getProductSlug(product)

    rerender({ product: newProduct, query: {} })

    getSelectedItemId(newProduct.items[0])
    getSelectedItemName(newProduct.items[0])
    getProductSlug(newProduct)
  })

  it('should select first item with available quantity', async () => {
    const noQuantity = getItem('no quantity', 90, 0)
    const itemWithQuantity = getItem('Item with quantity', 90, 10)
    const otherItemWithQuantity = getItem('other item with quantity', 90, 10)
    const newProduct = getProduct({
      items: [noQuantity, noQuantity, itemWithQuantity, otherItemWithQuantity],
    })

    const { getSelectedItemId, getSelectedItemName } = renderComponent({
      product: newProduct,
    })

    getSelectedItemId(itemWithQuantity)
    getSelectedItemName(itemWithQuantity)
  })

  it('should switch items when changing query prop', async () => {
    const itemone = getItem('1', 90, 1)
    const itemtwo = getItem('2', 90, 10)
    const itemthree = getItem('3', 90, 10)
    const newProduct = getProduct({
      items: [itemone, itemtwo, itemthree],
    })

    const props = {
      product: newProduct,
      params: { slug: newProduct.linkText },
      productQuery: { product: newProduct, loading: false },
    }

    const {
      getSelectedItemId,
      getSelectedItemName,
      rerender,
    } = renderComponent(props)

    getSelectedItemId(itemone)
    getSelectedItemName(itemone)

    rerender({ product: newProduct, query: { skuId: itemtwo.itemId } })

    getSelectedItemId(itemtwo)
    getSelectedItemName(itemtwo)
  })

  it('should dispatch action with bad args and not break anything', () => {
    const BadComponent = () => {
      const dispatch = useProductDispatch()

      dispatch?.({ type: 'SET_QUANTITY', quantity: 1 } as any)
      dispatch?.({
        type: 'SKU_SELECTOR_SET_VARIATIONS_SELECTED',
        quantity: 1,
      } as any)
      dispatch?.({ type: 'SKU_SELECTOR_SET_IS_VISIBLE', quantity: 1 } as any)
      dispatch?.({ type: 'SET_SELECTED_ITEM', quantity: 1 } as any)
      dispatch?.({ type: 'SET_ASSEMBLY_OPTIONS', quantity: 1 } as any)
      dispatch?.({ type: 'SET_PRODUCT', quantity: 1 } as any)

      return <div>Bad Component rendered OK</div>
    }

    const { getByText } = render(
      <ProductContextProvider {...getProps({})}>
        <BadComponent />
      </ProductContextProvider>
    )

    getByText('Bad Component rendered OK')
  })
})

```


[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 product-context/react/modules/items.ts from the product-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { Item, Seller } from '../ProductTypes'

export function findAvailableProduct(item: Item) {
  return item.sellers.find((seller: Seller) => {
    return seller?.commertialOffer?.AvailableQuantity > 0
  })
}

export function itemHasVariation(
  item: Item,
  { name, value }: { name: string; value: string }
) {
  return Boolean(
    item.variations.find(
      (variation) =>
        variation.name === name &&
        variation.values.some((variationValue) => variationValue === 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 product-context/react/modules/skuQueryString.ts from the product-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { itemHasVariation, findAvailableProduct } from './items'
import type { Item } from '../ProductTypes'

interface QueryParams {
  skuId?: string
  idsku?: string
}

const QUERY_STRING_VARIANT_PREFIX = 'property__'

// `idsku` querystring is to keep compatibility with Google Shopping integration
export const getSelectedSKUFromQueryString = (
  query: QueryParams,
  items: Item[] = []
) => {
  const skuId = query.skuId ?? query.idsku

  if (skuId) {
    return skuId
  }

  const variantQueryProps = Object.entries(query)
    .filter(([key]) => key.startsWith(QUERY_STRING_VARIANT_PREFIX))
    .map(([key, value]) => [
      key.slice(QUERY_STRING_VARIANT_PREFIX.length),
      value,
    ])

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

  const itemsWithVariation = items.filter((item) =>
    variantQueryProps.every(([name, value]) => {
      return itemHasVariation(item, { name, value })
    })
  )

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

  const availableItem = itemsWithVariation.find((item) =>
    findAvailableProduct(item)
  )

  if (availableItem) {
    return availableItem.itemId
  }

  return itemsWithVariation[0].itemId
}

```


[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-vbase-example/messages/pt.json from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin-example.navigation.label": "Aplicação de Exemplo de Admin",
  "admin-example.navigation.search.kws": "token",
  "admin-example.navigation.insight": "Insights",
  "admin-example.navigation.management": "Gerenciamento"
}

```


[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-vbase-example/messages/en.json from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin-example.navigation.label": "Admin Example Application",
  "admin-example.navigation.search.kws": "token",
  "admin-example.navigation.insight": "Insights",
  "admin-example.navigation.management": "Management"
}

```


[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-vbase-example/messages/es.json from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin-example.navigation.label": "Aplicacíon de Ejemplo de Admin",
  "admin-example.navigation.search.kws": "token",
  "admin-example.navigation.insight": "Insights",
  "admin-example.navigation.management": "Management"
}

```


[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-vbase-example/admin/navigation.json from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "section": "orders",
  "titleId": "admin-example.navigation.label",
  "searchKeyWordsHelpers": "admin-example.navigation.search.kws",
  "subSectionItems": [
    {
      "labelId": "admin-example.navigation.insight",
      "path": "/admin/adminExample"
    },
    {
      "labelId": "admin-example.navigation.management",
      "path": "/admin/adminOtherExample"
    }
  ]
}

```


[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-vbase-example/admin/routes.json from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin.app.example": {
    "component": "adminExample",
    "path": "/admin/app/adminExample"
  },
  "admin.app.otherexample": {
    "component": "adminOtherExample",
    "path": "/admin/app/adminOtherExample"
  }
}

```


[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-vbase-example/docs/README.md from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```markdown
# Admin Example - VBase

This example is an admin app with VBase save and retrieval implementation.

![image](https://user-images.githubusercontent.com/43679629/97359348-60dbe580-187b-11eb-9b31-62a7fc8d79eb.png)

```


[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-vbase-example/graphql/schema.graphql from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```graphql
type Query {
  token: String
}

type Mutation {
  saveToken(token: String): 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 admin-vbase-example/node/service.json from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "memory": 256,
  "ttl": 10,
  "timeout": 2,
  "minReplicas": 2,
  "maxReplicas": 4,
  "workers": 1
}

```


[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-vbase-example/node/package.json from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "co-body": "^6.0.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.36.3",
    "@vtex/test-tools": "^1.0.0",
    "tslint": "^5.14.0",
    "tslint-config-vtex": "^2.1.0",
    "typescript": "3.9.7"
  },
  "scripts": {
    "lint": "tsc --noEmit --pretty && tslint -c tslint.json --fix './**/*.ts'"
  },
  "version": "0.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 admin-vbase-example/node/index.ts from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {
  ClientsConfig,
  LRUCache,
  Service,
  ServiceContext,
  ParamsContext,
  RecorderState,
} from '@vtex/api'

import { Clients } from './clients'
import { queries, mutations } from './resolvers'

const TIMEOUT_MS = 800

// Create a LRU memory cache for the Status client.
// The @vtex/api HttpClient respects Cache-Control headers and uses the provided cache.
const memoryCache = new LRUCache<string, any>({ max: 5000 })
metrics.trackCache('status', memoryCache)

// 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: TIMEOUT_MS,
    },
    // This key will be merged with the default options and add this cache to our Status client.
    orders: {
      timeout: 3000,
    },
    status: {
      memoryCache,
    },
  },
}

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>

  // The shape of our State object found in `ctx.state`. This is used as state bag to communicate between middlewares.
  interface State extends RecorderState {
    code: number
  }
}

// Export a service that defines route handlers and client options.
export default new Service<Clients, State, ParamsContext>({
  clients,
  graphql: {
    resolvers: {
      Query: {
        ...queries,
      },
      Mutation: {
        ...mutations,
      },
    },
  },
})

```


[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-vbase-example/react/adminExample.tsx from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, useState } from 'react'
import { useMutation, useQuery } from 'react-apollo'
import { Layout, PageBlock, Button, Input } from 'vtex.styleguide'
import saveTokenGQL from './graphql/saveToken.gql'
import tokenGQL from './graphql/token.gql'

const AdminExample: FC = () => {
  const [token, setToken] = useState('')
  useQuery(tokenGQL, { onCompleted: ({ token }) => setToken(token) })
  const [saveToken] = useMutation(saveTokenGQL)
  return (
    <Layout>
      <PageBlock
        title="Configuração de Token"
        subtitle="Explicação aqui dos tokens"
        variation="full"
      >
        <Input
          placeholder="API Token"
          value={token}
          onChange={(e: any) => setToken(e.target.value)}
        />
        <Button
          onClick={() => {
            saveToken({ variables: { token } })
          }}
        >
          Salvar
        </Button>
      </PageBlock>
    </Layout>
  )
}
export default AdminExample

```


[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-vbase-example/react/package.json from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "CHANGE_ME",
  "version": "0.0.2",
  "scripts": {
    "test": "vtex-test-tools test"
  },
  "dependencies": {
    "apollo-client": "^2.6.8",
    "react": "^16.12.0",
    "react-apollo": "^3.1.3",
    "react-dom": "^16.12.0",
    "react-intl": "^3.12.0"
  },
  "devDependencies": {
    "@apollo/react-testing": "^3.1.3",
    "@types/jest": "^25.1.4",
    "@types/node": "^13.9.8",
    "@types/react": "^16.9.31",
    "@vtex/test-tools": "^3.3.2",
    "@vtex/tsconfig": "^0.4.4",
    "apollo-cache-inmemory": "^1.6.5",
    "graphql": "^14.6.0",
    "typescript": "3.9.7"
  }
}

```


[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-vbase-example/react/adminOtherExample.tsx from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import { Layout, PageBlock } from 'vtex.styleguide'
import { useQuery } from 'react-apollo'

import tokenGQL from './graphql/token.gql'

const AdminOtherExample: FC = () => {
  const { data: retrievedToken } = useQuery(tokenGQL)

  return (
    <Layout>
      <PageBlock
        title="Gerenciamento"
        subtitle="Tokens e Dados de Configuração"
        variation="full"
      >
        <p>Current token: {retrievedToken?.token}</p>
      </PageBlock>
    </Layout>
  )
}

export default AdminOtherExample

```


[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-vbase-example/node/clients/index.ts from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

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

export class Clients extends IOClients {}

```


[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-vbase-example/node/resolvers/index.ts from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
import token from './token'
import saveToken from './saveToken'

export const mutations = {
  saveToken,
}

export const queries = {
  token,
}

```


[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-vbase-example/node/resolvers/saveToken.ts from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
export default function saveToken(
  _: any,
  { token }: { token: string },
  ctx: Context
) {
  return ctx.clients.vbase
    .saveJSON('account.example', 'configs', { token })
    .then((_) => 'success')
}

```


[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-vbase-example/node/resolvers/token.ts from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
export default function token(_: any, __: any, ctx: Context) {
  return ctx.clients.vbase
    .getJSON<{ token: string }>('account.example', 'configs')
    .then(({ token }) => token)
}

```


[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-vbase-example/react/__tests__/index.test.tsx from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```tsx
describe('Orders List Scenarios', () => {
  it('should work', () => {
    expect(1).toBe(1)
  })
})

```


[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-vbase-example/react/graphql/saveToken.gql from the admin-vbase-example VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation saveToken($token: String) {
  saveToken(token: $token)
}

```


[System] You are a VTEX documentation expert. You provide accurate, detailed information about VTEX platform, APIs, apps, and Store Framework development.

[User] Provide a guide on guides vtex io documentation business guidelines self service level in VTEX.

[Assistant]
Documentation

[Feedback](https://read.calvincode.net/reader?url=https://docs.google.com/forms/d/e/1FAIpQLSfmnotPvPjw-SjiE7lt2Nt3RQgNUe10ixXZmuO2v9enOJReoQ/viewform?entry.1972292648=developers.vtex.com%26entry.1799503232=)

[GuidesLearn how to use our APIs and extend the VTEX platform.](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/guides)

[API ReferenceExplore detailed information about our endpoints.](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/api-reference)

[App DevelopmentLearn how to build cloud-based apps and integrations.](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/app-development)

[Storefront DevelopmentExpress your brand identity creating unique storefronts.](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/storefront-development)

[VTEX IO AppsFind pre-built solutions to grow your business.](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/vtex-io-apps)

[TroubleshootingFind practical solutions to common development issues.](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/troubleshooting)

[Release NotesStay up to date with our latest releases and bug fixes.](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/updates/release-notes)

[Guides](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/guides)

[API Reference](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/api-reference)

[App Development](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/app-development)

[Storefront Development](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/storefront-development)

[VTEX IO Apps](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/vtex-io-apps)

[Troubleshooting](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/troubleshooting)

---

[Release Notes](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/updates/release-notes)

Self-service level

VTEX App Store's mission is to provide scalable, reliable and high-level self-service solutions to our retailers anywhere in the world. For your app to be approved in our homologation process, it must:

* Be plug and play.
* Offer a direct support channel.
* Have technical documentation.

## Plug&Play

Those interested in your application should be able to install and configure it on their own, using only the VTEX admin panel to enable its features.

External assistance to support the app implementation process should not be considered an option. For homologation approval, it is required that your application is plug and play.

## Support channel

Every application in the VTEX App Store must provide a direct support channel for retailers who install it, such as email, phone, ticketing tool, or a combination of these options.

In addition, the first response time must be a maximum of eight business hours in the developer's time zone. This requirement aims to ensure that store operations will not be affected by errors in third-party applications.

## Technical documentation

Provide official documentation to support future users in implementing and understanding the application.

This documentation should include all the technical and commercial requirements for the application's operation, installation and configuration, the frequently asked questions (FAQ) among users who have installed it, etc.

Contributors

1

[![Photo of the contributor](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/_next/image?url=https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F60782333%3Fv%3D4%26w=64%26q=75)](https://github.com/carolinamenezes)

Was this helpful?

Yes

No

[Suggest Edits (GitHub)](https://read.calvincode.net/reader?url=https://github.com/vtexdocs/dev-portal-content/edit/main/docs/guides/vtex-io/Perks/vtex-io-documentation-homologation-requirements-for-vtex-app-store/vtex-io-documentation-business-guidelines-self-service-level.md)

Contributors

1

[![Photo of the contributor](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/_next/image?url=https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F60782333%3Fv%3D4%26w=64%26q=75)](https://github.com/carolinamenezes)

ON THIS PAGE

[Plug&Play](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/guides/vtex-io-documentation-business-guidelines-self-service-level%23plugplay)

[Support channel](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/guides/vtex-io-documentation-business-guidelines-self-service-level%23support-channel)

[Technical documentation](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/guides/vtex-io-documentation-business-guidelines-self-service-level%23technical-documentation)

Was this helpful?

 Send feedback

[Suggest edits (GitHub)](https://read.calvincode.net/reader?url=https://github.com/vtexdocs/dev-portal-content/edit/main/docs/guides/vtex-io/Perks/vtex-io-documentation-homologation-requirements-for-vtex-app-store/vtex-io-documentation-business-guidelines-self-service-level.md)

Copy page

On this page

ON THIS PAGE

[Plug&Play](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/guides/vtex-io-documentation-business-guidelines-self-service-level%23plugplay)

[Support channel](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/guides/vtex-io-documentation-business-guidelines-self-service-level%23support-channel)

[Technical documentation](https://read.calvincode.net/reader?url=https://developers.vtex.com/docs/guides/vtex-io-documentation-business-guidelines-self-service-level/docs/guides/vtex-io-documentation-business-guidelines-self-service-level%23technical-documentation)

On this page

[Github](https://read.calvincode.net/reader?url=https://github.com/vtex-apps)[Help Center](https://read.calvincode.net/reader?url=https://help.vtex.com/)[Community](https://read.calvincode.net/reader?url=https://community.vtex.com/?%5Fga=2.198523433.743584735.1647618303-1974737580.1645714642)[Feedback](https://read.calvincode.net/reader?url=https://docs.google.com/forms/d/e/1FAIpQLSfmnotPvPjw-SjiE7lt2Nt3RQgNUe10ixXZmuO2v9enOJReoQ/viewform?entry.1972292648=developers.vtex.com%26entry.1799503232=)