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

[Assistant]
Here's the implementation:

```markdown
# Template App

This app and all affiliated services are provided “as is”, without warranty of any kind, either express or implied. Neither the publisher nor its partners, affiliates, employees, or contractors guarantee that this app will meet your requirements, provide uninterrupted use, or operate without delay or without error. Neither the publisher nor its partners, affiliates, employees, or contractors assume any responsibility for any errors and malfunctions within the app and will not provide support or maintenance of any kind.

All provisions and warranties of any kind, express or implied, including but not limited to any guarantees of performance, process integrity, or particular functionalities, are hereby disclaimed and excluded unless otherwise prohibited or restricted by applicable law.

# RelevanC

### What is RelevanC

RelevanC is an ad-tech SaaS provider based in Paris, France. It markets a customised retail media solution under a white label to retailers and advertisers worldwide. With Sponsored Products for marketplaces, it combines truly relevant ads and maximum reach using advanced AI for the best of both worlds.

### RelevanC integration

#### Search results and category pages

Using VTEX Intelligent Search Middleware feature, this integration connects to RelevanC AdServer to get Sponsored Products to promote them in the search results and the category[^1] pages.

---

### Integration Setup

_Note: You must already have a RelevanC account set up and ready._

After the app is installed on your VTEX account, you can set it up following these steps.

#### Categories Map

The integration makes use of a categories map that is generated from the account's catalog to improve performance. This categories map is necessary for the integration to work.

You can check and generate/update this categories map using the following endpoint[^2].

- Check the categories map

```
GET https://app.io.vtex.com/vtex.relevanc/v0/{{account}}/{{workspace}}/_v/relevanc/categories-map
```

- Generate/update the categories map:

```
PUT https://app.io.vtex.com/vtex.relevanc/v0/{{account}}/{{workspace}}/_v/relevanc/categories-map
```

#### Integration settings

You can customize the behaviour for the integration using the following settings:

| Property name                                      | Description                                                                                |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| RelevanC AdServer name <br /> (`adServerName`)     | This is the name of RelevanC's AdServer (without `ads.peps.relevanc.io`)                                                                                |
| Product property <br /> (`boostType`)              | Product property to use to add/promote the products returned from the AdServer                                                                          |
| Max number of offers <br /> (`maxOffersToDisplay`) | Maximum number of products to be added to the search results                                                                                |
| Add all products <br />(`addAllProducts`)          | By default, only products that are part of the search results are promoted. Check to add all products returned by the AdServer to the search result[^3] |

[^1]: Category pages that use collections or are custom are not supported.
[^2]: This endpoints is private and requires the `vtexIdClientAutCookie` header.
[^3]: Only supported for search page.

```


[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 relevanc/node/service.json from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "stack": "nodejs",
  "memory": 512,
  "minReplicas": 3,
  "workers": 1,
  "routes": {
    "categoriesMap": {
      "path": "/_v/relevanc/categories-map",
      "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 relevanc/node/package.json from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "is-api-middleware-resolver",
  "private": true,
  "license": "UNLICENSED",
  "dependencies": {
    "@vtex/clients": "^2.19.5",
    "graphql": "^14.5.8",
    "graphql-tools": "^4.0.6",
    "vtex.is-api-middleware-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.is-api-middleware-graphql@0.1.0-beta.6/public"
  },
  "devDependencies": {
    "@types/atob": "^2.1.2",
    "@types/node": "^12.12.21",
    "@vtex/api": "6.45.15",
    "@vtex/tsconfig": "^0.5.6",
    "typescript": "3.9.7",
    "vtex.is-api-middleware-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.is-api-middleware-graphql@0.1.0-beta.5/public/@types/vtex.is-api-middleware-graphql"
  },
  "resolutions": {
    "@types/express-serve-static-core": "4.17.28"
  },
  "version": "1.0.5"
}

```


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

[Assistant]
Here's the implementation:

```typescript
// eslint-disable-next-line prettier/prettier
import type { ParamsContext, RecorderState } from '@vtex/api'
import { Service } from '@vtex/api'
import schema from 'vtex.is-api-middleware-graphql/graphql'

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

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

```


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

[Assistant]
Here's the implementation:

```typescript
export const PAGE_TYPE = {
  CATEGORY: 'category-page',
  SEARCH: 'search-page',
}

export const CATEGORIES_MAP = 'categories-map'
export const ACCOUNT_BASE_URL = 'https://portal.vtexcommercestable.com.br/'
export const BUCKET = 'relevanc'

export const DESKTOP = 'PC_LR_PLR'
export const MOBILE = 'MOB_LR_PLR'

export const ACTION = {
  ADD: 'add',
  REMOVE: 'remove',
  PROMOTE: 'promote',
  DEMOTE: 'demote',
} as const

```


[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 relevanc/node/clients/categoriesMap.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { InstanceOptions, IOContext } from '@vtex/api'
import { VBase } from '@vtex/api'

import { BUCKET, CATEGORIES_MAP } from '../contants'

export default class CategoriesMapClient extends VBase {
  constructor(context: IOContext, options?: InstanceOptions) {
    super(context, {
      ...options,
    })
  }

  public getCategoriesMap = (): Promise<CategoriesMapRecord | null> =>
    this.getJSON(BUCKET, CATEGORIES_MAP, true)

  public updateCategoriesMap = (data: CategoriesMapRecord) =>
    this.saveJSON(BUCKET, CATEGORIES_MAP, data)
}

```


[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 relevanc/node/clients/relevanC.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { InstanceOptions, IOContext } from '@vtex/api'
import { ExternalClient, PRODUCTION } from '@vtex/api'

export default class RelevancClient extends ExternalClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    super('https://ads.peps.relevanc.io', context, options)
  }

  private baseUrl(serverName: string) {
    return PRODUCTION
      ? `http://${serverName}.ads.peps.relevanc.io`
      : `http://${serverName}.staging-ads.peps.relevanc.io`
  }

  public async getSponsoredOffers(
    serverName: string,
    params: Relevanc.SponsoredProductsPayload
  ): Promise<Relevanc.SponsoredProductsResponse> {
    const URL = this.baseUrl(serverName)

    return this.http.get(`${URL}/sponsored-offers`, {
      headers: {
        'x-vtex-use-https': 'true',
      },
      params,
      metric: 'relevanc-get-offers',
    })
  }
}

```


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

[Assistant]
Here's the implementation:

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

import CatalogClient from './catalog'
import CategoriesMapClient from './categoriesMap'
import RelevancClient from './relevanc'

const MEDIUM_TIMEOUT_MS = 2 * 1000

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

  public get catalog() {
    return this.getOrSet('catalog', CatalogClient)
  }

  public get categoriesMap() {
    return this.getOrSet('categoriesMap', CategoriesMapClient)
  }
}

export const clientsConfig: ClientsConfig<Clients> = {
  implementation: Clients,
  options: {
    default: {
      retries: 2,
      timeout: MEDIUM_TIMEOUT_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 relevanc/node/clients/catalog.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

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

export default class CatalogClient extends JanusClient {
  /**
   * We use a high number as default to be sure to get all levels in category tree
   * @see https://developers.vtex.com/docs/api-reference/catalog-api#get-/api/catalog_system/pub/category/tree/-categoryLevels-
   */
  public getCategoryTree = async (
    categoryLevels = 99
  ): Promise<CategoryTree> => {
    return this.http.get(
      `/api/catalog_system/pub/category/tree/${categoryLevels}`,
      {
        metric: 'catalog-get-category-tree',
      }
    )
  }
}

```


[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 relevanc/node/typings/appSettings.d.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
type AppSettings = {
  adServerName: string
  boostType: BoostType
  maxOffersToDisplay: number
  addAllProducts: 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 relevanc/node/typings/relevanc.d.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare namespace Relevanc {
  type BaseSponsoredProductsPaylaod = {
    adSpaceId: 'PC_LR_PLR' | 'MOB_LR_PLR'
    sourcePageNumber: number
  }

  type KeyIdSponsoredProductsPayload = BaseSponsoredProductsPaylaod & {
    keyId: string
    filterCategoryCodePath: string
  }

  type KeyOriginSponsoredProductsPayload = BaseSponsoredProductsPaylaod & {
    keyOrigin: string
    filterCategoryCodePath?: string
  }

  type SponsoredProductsPayload =
    | KeyIdSponsoredProductsPayload
    | KeyOriginSponsoredProductsPayload

  type SponsoredOffer = {
    algoSelectionType:
      | 'NOTSELECTED'
      | 'EXPLORED'
      | 'UNEXPLORED'
      | 'LONGTAIL'
      | 'SHORTTAIL'
    isSponsored: boolean
    offerId: number
    productId: string
    tagName: string
    tag: string
  }

  type SponsoredProductsResponse = {
    nbResults: number
    tagName: string
    tag: string
    offers: SponsoredOffer[]
  }

  interface HandlerArgs {
    ctx: Context
    settings: AppSettings
    searchParams: SearchParams
  }

  interface SponsoredOffersMap {
    boostType: BoostType
    offers: {
      [offerId: string]: SponsoredOffer
    }
  }
}

```


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

[Assistant]
Here's the implementation:

```typescript
/* eslint-disable @typescript-eslint/consistent-type-imports */
import { ServiceContext } from '@vtex/api'

import { Clients } from '../clients/index'

declare global {
  type Context = ServiceContext<Clients>

  type SelectedFacet = {
    key: string
    value: string
  }

  type Operator = 'AND' | 'OR'

  type Options = {
    allowRedirect: boolean
  }

  type BoostAction = 'add' | 'remove' | 'promote' | 'demote'

  type BoostType =
    | 'term'
    | 'id'
    | 'skuId'
    | 'skuEan'
    | 'skuReference'
    | 'productLink'
    | 'product'
    | 'sku'
    | 'productId'
    | 'attribute'

  type DynamicRule = {
    action: BoostAction
    type: BoostType
    value: string
  }

  type SearchParams = {
    query?: string
    page?: string
    count?: string
    sort?: string
    operator?: string
    fuzzy?: string
    locale?: string
    allowRedirect?: boolean
    regionId?: string
    simulationBehavior?: 'skip' | 'only1P' | 'default' | null
    hideUnavailableItems?: boolean | null
    productOriginVtex?: string
    selectedFacets?: SelectedFacet[]
    dynamicRules?: DynamicRule[]
    searchState?: string
    customPluginInfo?: string
  }

  type Category = {
    id: number
    name: string
    href: string
    children?: Category[]
  }

  type SearchImage = {
    cacheId: string
    imageId: string
    imageLabel: string | null
    imageTag: string
    imageUrl: string
    imageText: string
  }

  type Variation = {
    name: string
    values: string[]
  }

  type Seller = {
    sellerId: string
    sellerName: string
    addToCartLink: string
    sellerDefault: boolean
    commertialOffer: CommertialOffer
    error?: string
  }

  type SearchInstallment = {
    Value: number
    InterestRate: number
    TotalValuePlusInterestRate: number
    NumberOfInstallments: number
    PaymentSystemName: string
    PaymentSystemGroupName?: string
    Name: string
  }

  type CommertialOffer = {
    DeliverySlaSamplesPerRegion?: Record<
      string,
      { DeliverySlaPerTypes: any[]; Region: any | null }
    >
    Installments: SearchInstallment[]
    discountHighlights?: any[]
    GiftSkuIds?: string[]
    teasers: Teaser[]
    BuyTogether?: any[]
    ItemMetadataAttachment?: any[]
    Price: number
    ListPrice: number
    spotPrice: number
    taxPercentage: number
    PriceWithoutDiscount: number
    RewardValue: number
    PriceValidUntil: string
    AvailableQuantity: number
    Tax: number
    DeliverySlaSamples?: Array<{
      DeliverySlaPerTypes: any[]
      Region: any | null
    }>
    GetInfoErrorMessage?: any | null
    CacheVersionUsedToCallCheckout: string
  }
  type Teaser = {
    id?: string
    name: string
    conditions: TeaserCondition
    effects: TeaserEffects
    featured?: boolean
    teaserType?: string
  }

  type TeaserCondition = {
    minimumQuantity: number
    parameters: TeaserValue[]
  }

  type TeaserEffects = {
    parameters: TeaserValue[]
  }

  type TeaserValue = {
    name: string
    value: string
  }

  type SearchItem = {
    itemId: string
    name: string
    nameComplete: string
    complementName: string
    ean: string
    referenceId: Array<{ Key: string; Value: string }>
    measurementUnit: string
    unitMultiplier: number
    modalType?: any | null
    images: SearchImage[]
    videos?: string[]
    variations: Variation[]
    sellers: Seller[]
    attachments: Array<{
      id: number
      name: string
      required: boolean
      domainValues: string
    }>
    isKit?: boolean
    kitItems?: Array<{
      itemId: string
      amount: number
    }>
  }

  type SearchMetadataItem = {
    Name: string
    NameComplete: string
    MainImage: string
    BrandName: string
    CategoryId: number
    ProductId: number
    id: string
    seller: string
    assemblyOptions: AssemblyOption[]
  }

  type ProductProperty = {
    name: string
    originalName: string
    values: string[]
  }

  type AssemblyOption = {
    id: string
    name: string
    composition: Composition | null
    inputValues: InputValues
  }

  type Composition = {
    minQuantity: number
    maxQuantity: number
    items: CompositionItem[]
  }

  type CompositionItem = {
    id: string
    minQuantity: number
    maxQuantity: number
    initialQuantity: number
    priceTable: string
    seller: string
  }

  type InputValues = {
    [key: string]: RawInputValue
  }

  type RawInputValue = {
    maximumNumberOfCharacters: number
    domain: string[]
  }

  type CompleteSpecification = {
    Values: Array<{
      Id: string
      Position: number
      Value: string
    }>
    Name: string
    Position: number
    IsOnProductDetails: boolean
    FieldId: string
  }

  type SkuSpecification = {
    field: SKUSpecificationField
    values: SKUSpecificationValue[]
  }

  type SKUSpecificationField = {
    name: string
    originalName?: string
    id?: string
  }

  type SKUSpecificationValue = {
    name: string
    id?: string
    fieldId?: string
    originalName?: string
  }

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

  type SpecificationGroupProperty = {
    originalName: string
    name: string
    values: string[]
  }

  type PriceRange = {
    sellingPrice: {
      highPrice: number
      lowPrice: number
    }
    listPrice: {
      highPrice: number
      lowPrice: number
    }
  }

  type Product = {
    cacheId: string
    productId: string
    productName: string
    brand: string
    brandId: number
    linkText: string
    productReference?: string
    categoryId: string
    categoryTree: Category[]
    productTitle?: string
    metaTagDescription: string
    clusterHighlights: Array<Record<string, string>>
    productClusters: Array<Record<string, string>>
    searchableClusters?: Record<string, string>
    categories: string[]
    categoriesIds?: string[]
    link: string
    description: string
    items: SearchItem[]
    itemMetadata?: {
      items: SearchMetadataItem[]
    }
    titleTag: string
    properties: ProductProperty[]
    Specifications?: string[]
    allSpecifications?: string[]
    allSpecificationsGroups?: string[]
    completeSpecifications?: CompleteSpecification[]
    skuSpecifications: SkuSpecification[]
    specificationGroups: SpecificationGroup[]
    priceRange: PriceRange
    rule: { id: string }
  }

  type Page = {
    index: number
    proxyUrl: string
  }

  type Pagination = {
    count: number
    current: Page
    before: Page[]
    after: Page[]
    perPage: number
    next: Page
    previous: Page
    first: { index: number }
    last: Page
  }

  type ProductSearchResult = {
    products: Product[]
    recordsFiltered: number
    correction: { misspelled: boolean }
    fuzzy: string
    operator: 'and' | 'or'
    translated: boolean
    pagination: Pagination
  }

  type AfterArgs = {
    args: {
      searchResult: ProductSearchResult
      params: SearchParams
      customPluginInfo: 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 relevanc/node/typings/catalog.d.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
type CategoryTree = CategoryTreeItem[]

interface CategoryTreeItem {
  id: string
  name: string
  hasChildren: boolean
  url: string
  children: CategoryTreeItem[]
  Title: string
  MetaTagDescription: string
}

interface CategoriesMap {
  [name: string]: CategoriesMapItem
}

interface CategoriesMapItem {
  id: string
  name: string
  path: string
}

interface CategoriesMapRecord {
  lastUpdated: string
  categories: CategoriesMap
}

```


[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 relevanc/node/utils/customError.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
type CustomErrorProps = {
  message: string
  reason: string
  status: number
  data?: unknown
}

export class CustomError extends Error {
  constructor({ message, reason, status, data = null }: CustomErrorProps) {
    super(message)
    this.reason = reason ?? this.message
    this.status = status
    this.data = data
  }

  public readonly reason: string
  public readonly status: number
  public readonly data: unknown
}

```


[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 relevanc/node/utils/createCategoriesMap.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ACCOUNT_BASE_URL } from '../contants'

export const createCategoriesMap = (
  categoryTree: CategoryTree,
  path: string | null = null,
  result: CategoriesMap = {}
): CategoriesMap => {
  for (const category of categoryTree) {
    // Remove base from category url
    const categoryPath = category.url.replace(ACCOUNT_BASE_URL, '')

    // Remove category parents
    const index = categoryPath.lastIndexOf('/')
    const categoryName =
      index > 0 ? categoryPath.slice(index + 1) : categoryPath

    // Add category to map
    const item = {
      id: String(category.id),
      name: categoryName,
      path: path ? `${path}/${category.id}` : `${category.id}`,
    }

    result[categoryName] = item

    // Check for sub categories
    if (category.hasChildren) {
      createCategoriesMap(category.children, item.path, result)
    }
  }

  return result
}

```


[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 relevanc/node/utils/dynamicRulesMapper.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ACTION } from '../contants'

export const dynamicRulesMapper = (
  offer: Relevanc.SponsoredOffer,
  { addAllProducts, boostType }: AppSettings
): DynamicRule => ({
  action: addAllProducts ? ACTION.ADD : ACTION.PROMOTE,
  type: boostType,
  value: offer.productId,
})

```


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

[Assistant]
Here's the implementation:

```typescript
export * from './createCategoriesMap'
export * from './customError'
export * from './dynamicRulesMapper'

```


[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 relevanc/node/resolvers/after.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { addTrackingTag, errorHandler } from '../utils/resolvers'

export async function after(
  _: unknown,
  { args }: AfterArgs,
  ctx: Context
): Promise<ProductSearchResult> {
  if (!args.customPluginInfo) {
    return args.searchResult
  }

  const { products } = args.searchResult
  const offersMap: Relevanc.SponsoredOffersMap = JSON.parse(
    args.customPluginInfo
  )

  if (!Object.keys(offersMap.offers).length) {
    return errorHandler('No offers not found', ctx)
  }

  for (const product of products) {
    addTrackingTag(offersMap, product)
  }

  return args.searchResult
}

```


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

[Assistant]
Here's the implementation:

```typescript
import { after } from './after'
import { before } from './before'

export const resolvers = {
  Query: {
    before,
    after,
  },
}

```


[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 relevanc/node/resolvers/before.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { PAGE_TYPE } from '../contants'
import {
  errorHandler,
  getSettings,
  validateArgs,
  getSearchPageOffers,
  getCategoryPageOffers,
} from '../utils/resolvers'
import { dynamicRulesMapper } from '../utils'

export async function before(
  _: unknown,
  args: SearchParams,
  ctx: Context
): Promise<SearchParams> {
  if (!validateArgs(args)) {
    return errorHandler('Invalid search params', ctx)
  }

  const settings = await getSettings(ctx)

  if (!settings) {
    return errorHandler('Settings not found', ctx)
  }

  /**
   * The `query` param is only present for the Search Results page.
   * The selectedFacets can be present in both pages (Search Results and Categories)
   */
  const type = !args.query ? PAGE_TYPE.CATEGORY : PAGE_TYPE.SEARCH
  let offers: Relevanc.SponsoredOffer[] | null

  switch (type) {
    case PAGE_TYPE.SEARCH: {
      offers = await getSearchPageOffers({
        ctx,
        settings,
        searchParams: args,
      })

      break
    }

    case PAGE_TYPE.CATEGORY: {
      offers = await getCategoryPageOffers({
        ctx,
        settings,
        searchParams: args,
      })

      break
    }

    default: {
      return args
    }
  }

  if (!offers) {
    return { ...args }
  }

  const offersMap: Relevanc.SponsoredOffersMap = {
    boostType: settings.boostType,
    offers: {},
  }

  const dynamicRules = offers.map((offer) => {
    offersMap.offers[offer.offerId] = offer

    return dynamicRulesMapper(offer, settings)
  })

  return { ...args, dynamicRules, customPluginInfo: JSON.stringify(offersMap) }
}

```


[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 relevanc/node/services/updateCategoriesMap.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { createCategoriesMap } from '../utils'

export const updateCategoriesMapService = async (ctx: Context) => {
  const {
    clients: { catalog, categoriesMap },
    vtex: { logger },
  } = ctx

  try {
    const categoryTree = await catalog.getCategoryTree()
    const categories = createCategoriesMap(categoryTree)

    const categoriesMapRecord: CategoriesMapRecord = {
      lastUpdated: Date(),
      categories,
    }

    categoriesMap.updateCategoriesMap(categoriesMapRecord)
  } catch (error) {
    logger.error({
      reason: error.message ?? 'Something went wrong',
      data: error.response?.data,
    })
  }
}

```


[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 relevanc/node/middleware/routes/updateCategoriesMap.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { updateCategoriesMapService } from '../../services'
import { CustomError } from '../../utils'

export async function updateCategoriesMap(
  ctx: Context,
  next: () => Promise<void>
) {
  try {
    await next()

    updateCategoriesMapService(ctx)
  } catch (error) {
    throw new CustomError({
      message: error.message,
      reason: 'Something went wrong updating the categories map',
      status: 500,
    })
  }
}

```


[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 relevanc/node/middleware/routes/errorHandler.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
export async function errorHandler(ctx: Context, next: () => Promise<void>) {
  const {
    vtex: { logger },
  } = ctx

  try {
    await next()
  } catch (error) {
    logger.error({
      message: error.message,
      reason: error.reason,
      status: error.status,
      data: error.data ?? error,
    })

    ctx.status = error.status || 500
    ctx.body = error.reason || 'Something went wrong'
  }
}

```


[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 relevanc/node/middleware/routes/getCategoriesMap.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { CustomError } from '../../utils'

export async function getCategoriesMap(ctx: Context) {
  const {
    clients: { categoriesMap },
  } = ctx

  try {
    const categoriesMapRecord = await categoriesMap.getCategoriesMap()

    if (!categoriesMapRecord) {
      ctx.body = 'Categories map has not been generated'

      return
    }

    ctx.body = categoriesMapRecord
  } catch (err) {
    throw new CustomError({
      message: err.message,
      reason: 'Unable to fetch categories map',
      status: 500,
    })
  }
}

```


[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 relevanc/node/middleware/routes/sendResponse.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
export function sendResponse(ctx: Context) {
  return (ctx.status = 204)
}

```


[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 relevanc/node/middleware/routes/index.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

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

import { errorHandler } from './errorHandler'
import { getCategoriesMap } from './getCategoriesMap'
import { sendResponse } from './sendResponse'
import { updateCategoriesMap } from './updateCategoriesMap'

export const routes = {
  categoriesMap: method({
    GET: [errorHandler, getCategoriesMap],
    PUT: [errorHandler, updateCategoriesMap, sendResponse],
  }),
}

```


[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 relevanc/node/utils/resolvers/errorHandler.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const errorHandler = (message: string, ctx: Context, error?: Error) => {
  if (process.env.VTEX_APP_LINK) {
    console.error(error ?? message)
  } else {
    ctx.vtex.logger.error({
      message,
    })
  }

  throw error ?? new 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 relevanc/node/utils/resolvers/validateArgs.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
/**
 * This utility function checks that we have at least one
 * of the SearchParams available.
 * `query` is needed for the search page.
 * `selectedFacets` array is needed for the category page.
 *
 * @param args object passed by the search resolver
 * @returns boolean
 */
export const validateArgs = (args: SearchParams) => {
  const { query, selectedFacets } = args

  return !(!query && !selectedFacets?.length)
}

```


[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 relevanc/node/utils/resolvers/getSearchPageOffers.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { DESKTOP } from '../../contants'

export const getSearchPageOffers = async (args: Relevanc.HandlerArgs) => {
  const {
    ctx: {
      clients: { relevanc },
    },
    settings: { adServerName, maxOffersToDisplay },
    searchParams: { page, query },
  } = args

  try {
    const { offers } = await relevanc.getSponsoredOffers(adServerName, {
      sourcePageNumber: page ? Number(page) : 0,
      keyOrigin: query as string,
      adSpaceId: DESKTOP,
    })

    offers.splice(maxOffersToDisplay)

    return offers
  } catch (error) {
    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 relevanc/node/utils/resolvers/getCategoryPageOffers.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { DESKTOP } from '../../contants'

export const getCategoryPageOffers = async (args: Relevanc.HandlerArgs) => {
  const {
    ctx: {
      clients: { categoriesMap, relevanc },
      vtex: { logger },
    },
    settings: { adServerName, maxOffersToDisplay },
    searchParams: { page, selectedFacets },
  } = args

  if (!selectedFacets?.length || selectedFacets[0].key !== 'c') {
    return []
  }

  try {
    const categoriesMapRecord = await categoriesMap.getCategoriesMap()

    if (!categoriesMapRecord) {
      throw new Error('Unable to get category page offers')
    }

    const categoryName = selectedFacets[selectedFacets.length - 1].value
    const item = categoriesMapRecord.categories[categoryName]

    if (!item) {
      return null
    }

    const { offers } = await relevanc.getSponsoredOffers(adServerName, {
      sourcePageNumber: page ? Number(page) : 0,
      keyId: item.id,
      filterCategoryCodePath: item.path,
      adSpaceId: DESKTOP,
    })

    offers.splice(maxOffersToDisplay)

    return offers
  } catch (error) {
    logger.error({
      message: error.message,
      reason:
        'No categories map was found. Check if it exists or generate a new one',
    })

    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 relevanc/node/utils/resolvers/index.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
export * from './addTrackingTag'
export * from './errorHandler'
export * from './getCategoryPageOffers'
export * from './getSearchPageOffers'
export * from './getSettings'
export * from './validateArgs'

```


[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 relevanc/node/utils/resolvers/addTrackingTag.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
export function addTrackingTag(
  offersMap: Relevanc.SponsoredOffersMap,
  product: Product
) {
  const { boostType, offers } = offersMap

  switch (boostType) {
    case 'productId': {
      const { productId } = product

      if (offers[productId]) {
        product.rule = {
          id: `dynamic:${productId}-${offers[productId].tag}`,
        }
      }

      return product
    }

    case 'skuId': {
      const [skuId] = product.items
        .map((item) => item.itemId)
        .filter((sku) => offers[sku])

      if (skuId) {
        product.rule = {
          id: `dynamic:${skuId}-${offers[skuId].tag}`,
        }
      }

      return product
    }

    default: {
      return product
    }
  }
}

```


[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 relevanc/node/utils/resolvers/getSettings.ts from the relevanc VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const getSettings = async (ctx: Context) => {
  const {
    clients: { apps },
  } = ctx

  const settings: AppSettings = await apps.getAppSettings(
    process.env.VTEX_APP_ID as string
  )

  if (!Object.keys(settings).length) {
    return null
  }

  return settings
}

```


[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 marketingdata-session/vtex.session/configuration.json from the marketingdata-session VTEX app.

[Assistant]
Here's the implementation:

```json
{
	"marketingdata": {
		"input": {
			"public": [
				"gclid",
				"utm_source",
				"utm_medium",
				"utm_campaign",
				"utmi_cp",
				"utmi_p",
				"utmi_pc"
			]
		},
		"output": {
			"marketingdata": [
				"utm_source",
				"utm_medium",
				"utm_campaign",
				"utmi_cp",
				"utmi_p",
				"utmi_pc"
			],
			"public": [ "utm_source" ]
		}
	}
}
```


[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 marketingdata-session/node/service.json from the marketingdata-session VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "stack": "nodejs",
  "memory": 128,
  "routes": {
    "transform": {
      "path": "/_v/marketingdata/session/transform/",
      "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 marketingdata-session/node/package.json from the marketingdata-session VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "axios": "^0.18.0",
    "co-body": "^6.0.0",
    "ramda": "^0.25.0"
  },
  "devDependencies": {
    "@types/axios": "^0.14.0",
    "@types/co-body": "^0.0.3",
    "@types/koa": "^2.0.39",
    "@types/node": "8.x",
    "@types/ramda": "types/npm-ramda#dist",
    "@vtex/api": "3.8.1",
    "tslint": "^5.8.0",
    "tslint-config-vtex": "^2.0.0",
    "typescript": "3.8.3"
  },
  "scripts": {
    "lint": "tsc --noEmit && tslint -c tslint.json './**/*.ts'"
  },
  "version": "0.1.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 marketingdata-session/node/index.ts from the marketingdata-session VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { method, Service, ServiceContext } from '@vtex/api'
import { process } from './middlewares/process'

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

export default new Service({
  routes: {
    transform: method ({
      POST: [process],
    }),
  },
})

```


[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 marketingdata-session/node/middlewares/process.ts from the marketingdata-session VTEX app.

[Assistant]
Here's the implementation:

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

interface SessionField {
  value: string
}

interface SessionNamespaceContent {
  [key: string]: SessionField
}

interface SessionContent {
  [key: string]: SessionNamespaceContent
}

export async function process(ctx: Context, next: () => Promise<any>) {
  ctx.set('Cache-Control', 'no-cache')

  // Parse request body
  //console.log("ResquestContent:", await text(ctx.req))
  let sessionContent : SessionContent = await json(ctx.req)
  console.log("SessionContent:", sessionContent)

  // Perform any content calculation and build session new content
  let sessionNewContent : SessionContent = {}
  if(!sessionContent.public?.utm_source && sessionContent.public?.gclid) {
    sessionContent.public["utm_source"] = { value: "Google" }
    sessionNewContent["public"] = { utm_source : sessionContent.public["utm_source"]}
  }
  sessionNewContent["marketingdata"] = sessionContent.public

  // Define response
  ctx.response.status = 200
  ctx.response.set('Content-Type', 'application/json')
  ctx.response.body = JSON.stringify(sessionNewContent)
  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 address-context/docs/README.md from the address-context VTEX app.

[Assistant]
Here's the implementation:

```markdown
# Address Context

> AddressContext is the orchestrator that is responsible for providing APIs to read and write an Address state.

```


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

[Assistant]
Here's the implementation:

```typescript
import { Address, AddressType } from 'vtex.checkout-graphql'

import { AddressFields, AddressRules, Field } from './types'

export const validateAddress = (
  address: Address | null | undefined,
  rules: AddressRules
) => {
  if (!address?.country || !rules[address.country]) {
    return {
      isValid: false,
      invalidFields: [
        'number',
        'postalCode',
        'city',
        'complement',
        'reference',
        'neighborhood',
        'state',
        'country',
        'receiverName',
        'street',
      ] as AddressFields[],
    }
  }

  const invalidFields = (Object.entries(rules[address.country].fields) as Array<
    [AddressFields, Field]
  >)
    .filter(([field, fieldSchema]) => {
      if (field === 'isDisposable') {
        return false
      }

      const fieldValue = address[field]

      if (fieldSchema.required && !fieldValue) {
        return true
      }

      if (
        fieldSchema.maxLength &&
        fieldValue &&
        fieldValue.length > fieldSchema.maxLength
      ) {
        return true
      }

      if (fieldSchema.pattern) {
        return fieldValue?.match(fieldSchema.pattern) === null
      }

      return false
    })
    .map(([field]) => field)

  return {
    isValid: invalidFields.length === 0,
    invalidFields,
  }
}

export const createEmptyAddress = (disposable = false): Address => {
  return {
    addressId: null,
    addressType: 'residential' as AddressType,
    geoCoordinates: [],
    number: null,
    postalCode: null,
    city: null,
    complement: null,
    reference: null,
    neighborhood: null,
    state: null,
    country: null,
    receiverName: null,
    street: null,
    isDisposable: disposable,
  }
}

export default { validateAddress, createEmptyAddress }

```


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

[Assistant]
Here's the implementation:

```tsx
import React, { createContext, useContext, useState, useMemo } from 'react'
import { Address } from 'vtex.checkout-graphql'

import { AddressRules, AddressFields } from './types'
import { validateAddress, createEmptyAddress } from './Utils'

type AddressUpdate = Address | ((prevAddress: Address) => Address)

interface Context {
  countries: string[]
  address: Address
  setAddress: (address: AddressUpdate) => void
  rules: AddressRules
  isValid: boolean
  invalidFields: AddressFields[]
}

interface AddressContextProps {
  address: Address | null
  countries: string[]
  rules: AddressRules
}

const AddressContextContext = createContext<Context | undefined>(undefined)

export const AddressContextProvider: React.FC<AddressContextProps> = ({
  children,
  address,
  countries,
  rules = {},
}) => {
  const [localAddress, setLocalAddress] = useState(
    () => address ?? createEmptyAddress()
  )

  const { invalidFields, isValid } = useMemo(
    () => validateAddress(localAddress, rules),
    [localAddress, rules]
  )

  const state = useMemo(
    () => ({
      countries,
      address: localAddress,
      setAddress: setLocalAddress,
      rules,
      isValid,
      invalidFields,
    }),
    [countries, localAddress, rules, isValid, invalidFields]
  )

  return (
    <AddressContextContext.Provider value={state}>
      {children}
    </AddressContextContext.Provider>
  )
}

export const useAddressContext = () => {
  const context = useContext(AddressContextContext)
  if (context === undefined) {
    throw new Error(
      'useAddressContext must be used within an AddressContextProvider'
    )
  }

  return context
}

export default { AddressContextProvider, useAddressContext }

```


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

[Assistant]
Here's the implementation:

```json
{
  "name": "vtex.address-context",
  "private": true,
  "version": "0.6.2",
  "dependencies": {
    "react": "^16.8.3",
    "react-apollo": "^3.1.5",
    "react-dom": "^16.8.3"
  },
  "devDependencies": {
    "@types/node": "^12.7.5",
    "@types/react": "^16.9.2",
    "vtex.checkout-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.checkout-graphql@0.56.1/public/@types/vtex.checkout-graphql",
    "vtex.country-data-settings": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.country-data-settings@0.3.0/public/@types/vtex.country-data-settings",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.126.11/public/@types/vtex.render-runtime"
  }
}

```


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

[Assistant]
Here's the implementation:

```tsx
import { useMemo } from 'react'
import { useQuery } from 'react-apollo'
import {
  CountryData,
  DisplayData,
  AddressFieldsData,
  LocationSelectData,
} from 'vtex.country-data-settings'

import addressRulesQuery from './graphql/addressRulesQuery.gql'

interface RulesQuery {
  allCountriesData: CountryData[]
}

const useAddressRules = () => {
  const { data } = useQuery<RulesQuery>(addressRulesQuery)

  const addressRules = useMemo(
    () =>
      data?.allCountriesData?.reduce<
        Record<
          string,
          {
            display: DisplayData
            fields: AddressFieldsData
            locationSelect?: LocationSelectData | null
          }
        >
      >(
        (rules, countryData) => ({
          ...rules,
          [countryData.countryISO]: {
            display: countryData.display,
            fields: countryData.addressFields,
            locationSelect: countryData.locationSelect,
          },
        }),
        {}
      ),
    [data]
  )

  return addressRules
}

export default useAddressRules

```


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

[Assistant]
Here's the implementation:

```tsx
import type { Address } from 'vtex.checkout-graphql'
import type {
  AddressFieldsData,
  DisplayData,
  LocationSelectData,
  Field,
} from 'vtex.country-data-settings'

export type AddressFields = keyof Omit<Address, '__typename' | 'geoCoordinates'>

export interface CountryRules {
  fields: AddressFieldsData
  display: DisplayData
  locationSelect?: LocationSelectData | null
}

export interface AddressRules {
  [key: string]: CountryRules
}

export { Field }

```


[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 address-context/react/typings/graphql.d.ts from the address-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.gql' {
  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 address-context/react/typings/vtex.styleguide.d.ts from the address-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.styleguide' {
  import { ComponentType } from 'react'

  export const Input: ComponentType<InputProps>

  interface InputProps {
    [key: string]: any
  }
}

```


[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 address-context/react/graphql/addressRulesQuery.gql from the address-context VTEX app.

[Assistant]
Here's the implementation:

```graphql
fragment FieldFragment on Field {
  label
  name
  hidden
  maxLength
  size
  required
  autoComplete
  options {
    label
    value
  }
  optionsCaption
  elementName
  mask
  pattern
  additionalData {
    ... on PostalCodeData {
      forgottenURL
    }
  }
}

fragment DisplayFragment on DisplayDefinition {
  name
  delimiter
  delimiterAfter
}

query AddressRules {
  allCountriesData {
    countryISO
    addressFields {
      city {
        ...FieldFragment
      }
      complement {
        ...FieldFragment
      }
      country {
        ...FieldFragment
      }
      neighborhood {
        ...FieldFragment
      }
      number {
        ...FieldFragment
      }
      postalCode {
        ...FieldFragment
      }
      receiverName {
        ...FieldFragment
      }
      reference {
        ...FieldFragment
      }
      state {
        ...FieldFragment
      }
      street {
        ...FieldFragment
      }
    }
    display {
      minimal {
        ...DisplayFragment
      }
      compact {
        ...DisplayFragment
      }
      extended {
        ...DisplayFragment
      }
    }
    locationSelect {
      countryData
      fields {
        ...FieldFragment
      }
    }
  }
}

```


[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 docs-ui/messages/pt.json from the docs-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "docs-ui/renderer-github": "Edit this page on GitHub",
  "docs-ui/getting-started": "Getting Started",
  "docs-ui/getting-started.next": "Next article",
  "docs-ui/getting-started.previous": "Previous article",
  "docs-ui/recipes": "Recipes",
  "docs-ui/recipes-description": "Find answers to any doubt you may have on platform functionality.",
  "docs-ui/our-components": "Our components",
  "docs-ui/our-components-description": "Get to know our high quality, open-code, customizable components.",
  "docs-ui/concepts": "Concepts",
  "docs-ui/concepts-description": "Understand platform terminology and empower your knowledge about the VTEX IO universe.",
  "docs-ui/community": "Community",
  "docs-ui/community-description": "Share and obtain knowledge on the platform by working together with the VTEX IO community.",
  "docs-ui/latest-features": "Latest Releases",
  "docs-ui/latest-features-description": "Get a first hand look as the most recent platform releases:",
  "docs-ui/release-notes": "Release Notes",
  "docs-ui/release-notes-description": "See what is new in VTEX IO.",
  "docs-ui/apis": "VTEX Commerce APIs",
  "docs-ui/partner": "Become a partner",
  "docs-ui/visit-us": "visit us at www.vtex.com",
  "docs-ui/community-help": "Need help?",
  "docs-ui/community-join": "Join the discussion!",
  "docs-ui/empty.title": "Sorry :(",
  "docs-ui/empty-docs": "We could not fetch the documentation on this component right now.",
  "docs-ui/empty-summary": "We could not fetch the summary for this app.",
  "docs-ui/see-all": "See all",
  "docs-ui/see-previous-releases": "See previous releases",
  "docs-ui/build": "Develop with VTEX IO",
  "docs-ui/build-description": "Access content on VTEX IO and learn to develop on a high performance with low maintenance and development cost Software as a Service platform.",
  "docs-ui/create-stores": "Build stores with VTEX IO",
  "docs-ui/article-nav": "On this section",
  "docs-ui/recipes.style": "Style Recipes",
  "docs-ui/recipes.style-description": "Customize your store’s style and grant it its own identity.",
  "docs-ui/recipes.layout": "Layout Recipes",
  "docs-ui/recipes.layout-description": "Learn to configure the structure of your store components.",
  "docs-ui/recipes.templates": "Templates Recipes",
  "docs-ui/recipes.templates-description": "Learn to configure your store's blocks structure.",
  "docs-ui/recipes.development": "Development Recipes",
  "docs-ui/recipes.development-description": "If you are developing with VTEX IO then you are in the right place. Find all the recipes for the VTEX IO development platform below:",
  "docs-ui/recipes.store": "Store Management Recipes",
  "docs-ui/recipes.store-management": "Store Management Recipes",
  "docs-ui/recipes.store-description": "Find all the necessary information for a better management of your store’s content.",
  "docs-ui/recipes.store-management-description": "Store Management Recipes",
  "docs-ui/recipes.plugins": "Plugins Recipes",
  "docs-ui/recipes.plugins-description": "Check out the full list of available VTEX IO extension apps ready to be installed.",
  "docs-ui/recipes.custom-blocks": "Custom Blocks Recipes",
  "docs-ui/recipes.custom-blocks-description": "If your goal is to develop your own components using VTEX IO, you’ve come to the right place!",
  "docs-ui/recipes.all": "All Recipes",
  "docs-ui/recipes.all-description": "All the answers to any platform related questions can be found here! Find all the recipes for VTEX IO functionalities below:",
  "docs-ui/recipes.app": "Apps Recipes",
  "docs-ui/read-more": "Read more",
  "docs-ui/components.layout": "Layout Components",
  "docs-ui/components.layout-description": "Check out our most flexible components to add different layout elements into your store.",
  "docs-ui/components.layout-blocks": "Layout Blocks",
  "docs-ui/components.layout-blocks-description": "Check out our most flexible blocks to add different layout elements into your store.",
  "docs-ui/components.content-blocks": "Content Blocks",
  "docs-ui/components.content-blocks-description": "The entire store interface content is made up of several different blocks, aside from the ones for Layout. Explore the list of available blocks your store can already use here.",
  "docs-ui/components.general": "General Components",
  "docs-ui/components.general-description": "The entire online store interface is made up of several different components. Explore the list of available components your store can already use here.",
  "docs-ui/components.navigation": "Navigation Components",
  "docs-ui/components.navigation-description": "Check out all the components that are linked to user browsing experience.",
  "docs-ui/components.product-related": "Product Related Components",
  "docs-ui/components.product-related-description": "Find all the components responsible for rendering your store’s product data below.",
  "docs-ui/components.pixel": "Pixel Components",
  "docs-ui/components.pixel-description": "Pixel components are used to collect user data for a third-party of your choosing. Check out some of the already available implementations on our platform.",
  "docs-ui/components.functional": "Functional Apps",
  "docs-ui/components.functional-description": "In addition to the blocks that build the store's layout and interface content, we also have the apps that are not rendered by themselves, but that have important roles for the functioning of your store. Check the full list of functional apps below:",
  "docs-ui/components.search-related": "Search Related Components",
  "docs-ui/components.search-related-description": "All your search-related platform components in just one place.",
  "docs-ui/components.all": "All Components",
  "docs-ui/components.all-description": "All your store components are found here! Check out the full list below.",
  "docs-ui/nav.api": "VTEX Commerce APIs",
  "docs-ui/nav.partner": "Become a partner",
  "docs-ui/join-discussion": "Join the discussion!",
  "docs-ui/did-not-find-your-answer": "Didn't find your answer?",
  "docs-ui/lorem": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vel ligula sagittis, dignissim nisi non, interdum elit. Vivamus eget dolor egestas, hendrerit urna a, finibus enim. Phasellus mollis mollis dui ut mattis. In ut purus sem. Quisque volutpat ornare consequat.",
  "docs-ui/lorem-short": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod."
}

```


[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 docs-ui/messages/en.json from the docs-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "docs-ui/renderer-github": "Edit this page on GitHub",
  "docs-ui/getting-started": "Getting Started",
  "docs-ui/getting-started.next": "Next article",
  "docs-ui/getting-started.previous": "Previous article",
  "docs-ui/recipes": "Recipes",
  "docs-ui/recipes-description": "Find answers to any doubt you may have on platform functionality.",
  "docs-ui/our-components": "Our components",
  "docs-ui/our-components-description": "Get to know our high quality, open-code, customizable components.",
  "docs-ui/concepts": "Concepts",
  "docs-ui/concepts-description": "Understand platform terminology and empower your knowledge about the VTEX IO universe.",
  "docs-ui/community": "Community",
  "docs-ui/community-description": "Share and obtain knowledge on the platform by working together with the VTEX IO community.",
  "docs-ui/latest-features": "Latest Releases",
  "docs-ui/latest-features-description": "Get a first hand look as the most recent platform releases:",
  "docs-ui/release-notes": "Release Notes",
  "docs-ui/release-notes-description": "See what is new in VTEX IO.",
  "docs-ui/apis": "VTEX Commerce APIs",
  "docs-ui/partner": "Become a partner",
  "docs-ui/visit-us": "visit us at www.vtex.com",
  "docs-ui/community-help": "Need help?",
  "docs-ui/community-join": "Join the discussion!",
  "docs-ui/empty.title": "Sorry :(",
  "docs-ui/empty-docs": "We could not fetch the documentation on this component right now.",
  "docs-ui/empty-summary": "We could not fetch the summary for this app.",
  "docs-ui/see-all": "See all",
  "docs-ui/see-previous-releases": "See previous releases",
  "docs-ui/build": "Develop with VTEX IO",
  "docs-ui/build-description": "Access content on VTEX IO and learn to develop on a high performance with low maintenance and development cost Software as a Service platform.",
  "docs-ui/create-stores": "Build stores with VTEX IO",
  "docs-ui/article-nav": "On this section",
  "docs-ui/recipes.style": "Style Recipes",
  "docs-ui/recipes.style-description": "Customize your store’s style and grant it its own identity.",
  "docs-ui/recipes.layout": "Layout Recipes",
  "docs-ui/recipes.layout-description": "Learn to configure the structure of your store components.",
  "docs-ui/recipes.templates": "Templates Recipes",
  "docs-ui/recipes.templates-description": "Learn to configure your store's blocks structure.",
  "docs-ui/recipes.development": "Development Recipes",
  "docs-ui/recipes.development-description": "If you are developing with VTEX IO then you are in the right place. Find all the recipes for the VTEX IO development platform below:",
  "docs-ui/recipes.store": "Store Management Recipes",
  "docs-ui/recipes.store-management": "Store Management Recipes",
  "docs-ui/recipes.store-description": "Find all the necessary information for a better management of your store’s content.",
  "docs-ui/recipes.store-management-description": "Store Management Recipes",
  "docs-ui/recipes.plugins": "Plugins Recipes",
  "docs-ui/recipes.plugins-description": "Check out the full list of available VTEX IO extension apps ready to be installed.",
  "docs-ui/recipes.custom-blocks": "Custom Blocks Recipes",
  "docs-ui/recipes.custom-blocks-description": "If your goal is to develop your own components using VTEX IO, you’ve come to the right place!",
  "docs-ui/recipes.all": "All Recipes",
  "docs-ui/recipes.all-description": "All the answers to any platform related questions can be found here! Find all the recipes for VTEX IO functionalities below:",
  "docs-ui/recipes.app": "Apps Recipes",
  "docs-ui/read-more": "Read more",
  "docs-ui/components.layout": "Layout Components",
  "docs-ui/components.layout-description": "Check out our most flexible components to add different layout elements into your store.",
  "docs-ui/components.layout-blocks": "Layout Blocks",
  "docs-ui/components.layout-blocks-description": "Check out our most flexible blocks to add different layout elements into your store.",
  "docs-ui/components.content-blocks": "Content Blocks",
  "docs-ui/components.content-blocks-description": "The entire store interface content is made up of several different blocks, aside from the ones for Layout. Explore the list of available blocks your store can already use here.",
  "docs-ui/components.general": "General Components",
  "docs-ui/components.general-description": "The entire online store interface is made up of several different components. Explore the list of available components your store can already use here.",
  "docs-ui/components.navigation": "Navigation Components",
  "docs-ui/components.navigation-description": "Check out all the components that are linked to user browsing experience.",
  "docs-ui/components.product-related": "Product Related Components",
  "docs-ui/components.product-related-description": "Find all the components responsible for rendering your store’s product data below.",
  "docs-ui/components.pixel": "Pixel Components",
  "docs-ui/components.pixel-description": "Pixel components are used to collect user data for a third-party of your choosing. Check out some of the already available implementations on our platform.",
  "docs-ui/components.functional": "Functional Apps",
  "docs-ui/components.functional-description": "In addition to the blocks that build the store's layout and interface content, we also have the apps that are not rendered by themselves, but that have important roles for the functioning of your store. Check the full list of functional apps below:",
  "docs-ui/components.search-related": "Search Related Components",
  "docs-ui/components.search-related-description": "All your search-related platform components in just one place.",
  "docs-ui/components.all": "All Components",
  "docs-ui/components.all-description": "All your store components are found here! Check out the full list below.",
  "docs-ui/nav.api": "VTEX Commerce APIs",
  "docs-ui/nav.partner": "Become a partner",
  "docs-ui/join-discussion": "Join the discussion!",
  "docs-ui/did-not-find-your-answer": "Didn't find your answer?",
  "docs-ui/lorem": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vel ligula sagittis, dignissim nisi non, interdum elit. Vivamus eget dolor egestas, hendrerit urna a, finibus enim. Phasellus mollis mollis dui ut mattis. In ut purus sem. Quisque volutpat ornare consequat.",
  "docs-ui/lorem-short": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod."
}

```


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

[Assistant]
Here's the implementation:

```json
{
  "docs-ui/renderer-github": "Edit this page on GitHub",
  "docs-ui/getting-started": "Getting Started",
  "docs-ui/getting-started.next": "Next article",
  "docs-ui/getting-started.previous": "Previous article",
  "docs-ui/recipes": "Recipes",
  "docs-ui/recipes-description": "Find answers to any doubt you may have on platform functionality.",
  "docs-ui/our-components": "Our components",
  "docs-ui/our-components-description": "Get to know our high quality, open-code, customizable components.",
  "docs-ui/concepts": "Concepts",
  "docs-ui/concepts-description": "Understand platform terminology and empower your knowledge about the VTEX IO universe.",
  "docs-ui/community": "Community",
  "docs-ui/community-description": "Share and obtain knowledge on the platform by working together with the VTEX IO community.",
  "docs-ui/latest-features": "Latest Releases",
  "docs-ui/latest-features-description": "Get a first hand look as the most recent platform releases:",
  "docs-ui/release-notes": "Release Notes",
  "docs-ui/release-notes-description": "See what is new in VTEX IO.",
  "docs-ui/apis": "VTEX Commerce APIs",
  "docs-ui/partner": "Become a partner",
  "docs-ui/visit-us": "visit us at www.vtex.com",
  "docs-ui/community-help": "Need help?",
  "docs-ui/community-join": "Join the discussion!",
  "docs-ui/empty.title": "Sorry :(",
  "docs-ui/empty-docs": "We could not fetch the documentation on this component right now.",
  "docs-ui/empty-summary": "We could not fetch the summary for this app.",
  "docs-ui/see-all": "See all",
  "docs-ui/see-previous-releases": "See previous releases",
  "docs-ui/build": "Develop with VTEX IO",
  "docs-ui/build-description": "Access content on VTEX IO and learn to develop on a high performance with low maintenance and development cost Software as a Service platform.",
  "docs-ui/create-stores": "Build stores with VTEX IO",
  "docs-ui/article-nav": "On this section",
  "docs-ui/recipes.style": "Style Recipes",
  "docs-ui/recipes.style-description": "Customize your store’s style and grant it its own identity.",
  "docs-ui/recipes.layout": "Layout Recipes",
  "docs-ui/recipes.layout-description": "Learn to configure the structure of your store components.",
  "docs-ui/recipes.templates": "Templates Recipes",
  "docs-ui/recipes.templates-description": "Learn to configure your store's blocks structure.",
  "docs-ui/recipes.development": "Development Recipes",
  "docs-ui/recipes.development-description": "If you are developing with VTEX IO then you are in the right place. Find all the recipes for the VTEX IO development platform below:",
  "docs-ui/recipes.store": "Store Management Recipes",
  "docs-ui/recipes.store-management": "Store Management Recipes",
  "docs-ui/recipes.store-description": "Find all the necessary information for a better management of your store’s content.",
  "docs-ui/recipes.store-management-description": "Store Management Recipes",
  "docs-ui/recipes.plugins": "Plugins Recipes",
  "docs-ui/recipes.plugins-description": "Check out the full list of available VTEX IO extension apps ready to be installed.",
  "docs-ui/recipes.custom-blocks": "Custom Blocks Recipes",
  "docs-ui/recipes.custom-blocks-description": "If your goal is to develop your own components using VTEX IO, you’ve come to the right place!",
  "docs-ui/recipes.all": "All Recipes",
  "docs-ui/recipes.all-description": "All the answers to any platform related questions can be found here! Find all the recipes for VTEX IO functionalities below:",
  "docs-ui/recipes.app": "Apps Recipes",
  "docs-ui/read-more": "Read more",
  "docs-ui/components.layout": "Layout Components",
  "docs-ui/components.layout-description": "Check out our most flexible components to add different layout elements into your store.",
  "docs-ui/components.layout-blocks": "Layout Blocks",
  "docs-ui/components.layout-blocks-description": "Check out our most flexible blocks to add different layout elements into your store.",
  "docs-ui/components.content-blocks": "Content Blocks",
  "docs-ui/components.content-blocks-description": "The entire store interface content is made up of several different blocks, aside from the ones for Layout. Explore the list of available blocks your store can already use here.",
  "docs-ui/components.general": "General Components",
  "docs-ui/components.general-description": "The entire online store interface is made up of several different components. Explore the list of available components your store can already use here.",
  "docs-ui/components.navigation": "Navigation Components",
  "docs-ui/components.navigation-description": "Check out all the components that are linked to user browsing experience.",
  "docs-ui/components.product-related": "Product Related Components",
  "docs-ui/components.product-related-description": "Find all the components responsible for rendering your store’s product data below.",
  "docs-ui/components.pixel": "Pixel Components",
  "docs-ui/components.pixel-description": "Pixel components are used to collect user data for a third-party of your choosing. Check out some of the already available implementations on our platform.",
  "docs-ui/components.functional": "Functional Apps",
  "docs-ui/components.functional-description": "In addition to the blocks that build the store's layout and interface content, we also have the apps that are not rendered by themselves, but that have important roles for the functioning of your store. Check the full list of functional apps below:",
  "docs-ui/components.search-related": "Search Related Components",
  "docs-ui/components.search-related-description": "All your search-related platform components in just one place.",
  "docs-ui/components.all": "All Components",
  "docs-ui/components.all-description": "All your store components are found here! Check out the full list below.",
  "docs-ui/nav.api": "VTEX Commerce APIs",
  "docs-ui/nav.partner": "Become a partner",
  "docs-ui/join-discussion": "Join the discussion!",
  "docs-ui/did-not-find-your-answer": "Didn't find your answer?",
  "docs-ui/lorem": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam vel ligula sagittis, dignissim nisi non, interdum elit. Vivamus eget dolor egestas, hendrerit urna a, finibus enim. Phasellus mollis mollis dui ut mattis. In ut purus sem. Quisque volutpat ornare consequat.",
  "docs-ui/lorem-short": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod."
}

```


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

[Assistant]
Here's the implementation:

```markdown
# Docs UI

This is the UI for VTEX IO documentation at https://vtex.io/docs.

To contribute to the available content, please refer to [IO Documentation](https://github.com/vtex-apps/io-documentation).

**Upcoming documentation:**

 - [Update TopNav.tsx](https://github.com/vtex-apps/docs-ui/pull/121)
```


[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 docs-ui/pages/interfaces.json from the docs-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "navigation-wrapper": {
    "component": "PageLayoutContainer"
  },
  "docs-ui": {
  },
  "docs-ui.home": {
    "around": ["navigation-wrapper"],
    "component": "Home"
  },
  "docs-ui.search": {
    "around": ["navigation-wrapper"],
    "component": "Search"
  },
  "docs-ui.app": {
    "around": ["navigation-wrapper"],
    "component": "AppDocs"
  },
  "docs-ui.construction": {
    "around": ["navigation-wrapper"],
    "component": "UnderConstruction"
  },
  "docs-ui.recipes-list": {
    "around": ["navigation-wrapper"],
    "component": "RecipesList"
  },
  "docs-ui.recipe": {
    "around": ["navigation-wrapper"],
    "component": "Recipe"
  },
  "docs-ui.components-list": {
    "around": ["navigation-wrapper"],
    "component": "ComponentsGrid"
  },
  "docs-ui.apps-list": {
    "around": ["navigation-wrapper"],
    "component": "ComponentsGrid"
  },
  "docs-ui.component": {
    "around": ["navigation-wrapper"],
    "component": "AppDocs"
  },
  "docs-ui.apps": {
    "around": ["navigation-wrapper"],
    "component": "AppDocs"
  },
  "docs-ui.concept-list": {
    "around": ["navigation-wrapper"],
    "component": "ConceptList"
  },
  "docs-ui.concept": {
    "around": ["navigation-wrapper"],
    "component": "Concept"
  },
  "docs-ui.release-notes": {
    "around": ["navigation-wrapper"],
    "component": "ReleaseNotes"
  },
  "docs-ui.release-article": {
    "around": ["navigation-wrapper"],
    "component": "ReleaseArticle"
  },
  "docs-ui.getting-started": {
    "around": ["navigation-wrapper"],
    "component": "GettingStartedArticle"
  },
  "docs-ui.introduction": {
    "around": ["navigation-wrapper"],
    "component": "IntroductionArticle"
  }
}

```


[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 docs-ui/pages/routes.json from the docs-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "docs-ui.home": {
    "path": "/docs(/home)"
  },
  "docs-ui.search": {
    "path": "/docs/search"
  },
  "docs-ui.recipes-list": {
    "path": "/docs/recipes/:category"
  },
  "docs-ui.recipe": {
    "path": "/docs/recipes/:category/:recipe"
  },
  "docs-ui.components-list": {
    "path": "/docs/components/:category"
  },
  "docs-ui.apps-list": {
    "path": "/docs/apps/:category"
  },
  "docs-ui.component": {
    "path": "/docs/components/:category/:app(/:file)"
  },
  "docs-ui.apps": {
    "path": "/docs/apps/:category/:app(/:file)"
  },
  "docs-ui.concept-list": {
    "path": "/docs/concepts"
  },
  "docs-ui.concept": {
    "path": "/docs/concepts/:concept"
  },
  "docs-ui.release-notes": {
    "path": "/docs/releases"
  },
  "docs-ui.release-article": {
    "path": "/docs/releases/:week/:article"
  },
  "docs-ui.getting-started": {
    "path": "/docs/getting-started/:track/:article"
  },
  "docs-ui.introduction": {
    "path": "/docs/introduction/:article"
  },
  "docs-ui.app": {
    "path": "/docs/app/:app(/:file)"
  }
}

```


[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 docs-ui/react/GettingStartedArticle.tsx from the docs-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Fragment, FC } from 'react'
import { Query, graphql } from 'react-apollo'
import { ApolloError } from 'apollo-client'
import { compose, renderNothing, branch } from 'recompose'
import { FormattedMessage } from 'react-intl'
import { withRuntimeContext, Link, InjectedRuntime } from 'vtex.render-runtime'

import { IO_DOCUMENTATION } from './modules/constantExports'
import DocsRenderer from './components/DocsRenderer'
import Skeleton from './components/Skeleton'
import EmptyDocs from './components/EmptyDocs'
import MarkdownFile from './graphql/markdownFile.graphql'
import GettingStartedArticles from './graphql/gettingStartedArticles.graphql'
import RightArrow from './components/icons/RightArrow'
import LeftArrow from './components/icons/LeftArrow'

const GettingStartedArticle: FC<OuterProps & InjectedRuntime> = ({
  GettingStartedArticlesQuery,
  runtime,
}) => {
  const {
    route: {
      params: { track, article },
    },
  } = runtime

  const articles = GettingStartedArticlesQuery.gettingStartedArticles

  const currentArticle = Number.parseInt(article, 10)

  return (
    <div className="w-100 center flex flex-column">
      <Query
        query={MarkdownFile}
        variables={{
          appName: IO_DOCUMENTATION,
          fileName: `GettingStarted/${track}/${articles[article]}`,
          locale: 'en',
        }}>
        {({
          loading,
          error,
          data,
        }: {
          loading: boolean
          error?: ApolloError
          data: { markdownFile: { markdown: string; meta: MetaData } }
        }) => {
          if (loading) return <Skeleton />
          if (error) return <EmptyDocs />

          const {
            markdownFile: { markdown, meta },
          } = data

          return (
            <Fragment>
              <DocsRenderer markdown={markdown} meta={meta} />
              <div
                className="flex w-100 justify-between mv6"
                style={{ maxWidth: '680px' }}>
                {hasPrevArticle(currentArticle) && (
                  <Link
                    className="link c-emphasis no-underline t-body mr-auto flex items-center dim"
                    page="docs-ui.getting-started"
                    params={{
                      track,
                      article: `${currentArticle - 1}`,
                    }}>
                    <div className="flex flex-column flex-row-l">
                      <div className="dn db-l mr5">
                        <LeftArrow />
                      </div>
                      <FormattedMessage id="docs-ui/getting-started.previous" />
                    </div>
                  </Link>
                )}
                {hasNextArticle(articles, currentArticle) && (
                  <Link
                    className="link c-emphasis no-underline t-body ml-auto flex items-center dim"
                    page="docs-ui.getting-started"
                    params={{
                      track,
                      article: `${currentArticle + 1}`,
                    }}>
                    <div className="flex flex-column flex-row-l">
                      <FormattedMessage id="docs-ui/getting-started.next" />
                      <div className="dn db-l ml5">
                        <RightArrow />
                      </div>
                    </div>
                  </Link>
                )}
              </div>
            </Fragment>
          )
        }}
      </Query>
    </div>
  )
}

function hasNextArticle(
  articleList: Record<string, string>,
  currentArticle: number
) {
  const numberOfArticles = Object.keys(articleList).length
  return currentArticle < numberOfArticles
}

function hasPrevArticle(currentArticle: number) {
  return currentArticle > 1
}

interface OuterProps {
  GettingStartedArticlesQuery: {
    gettingStartedArticles: Record<string, string>
    loading: boolean
    error?: ApolloError
  }
}

interface MetaData {
  title: string
  description: string
  tags: string[]
  version: string
  git: string
}

export default compose<any, any>(
  withRuntimeContext,
  graphql(GettingStartedArticles, {
    name: 'GettingStartedArticlesQuery',
    options: (props: InjectedRuntime) => {
      const { track } = props.runtime.route.params
      return {
        variables: {
          track,
          locale: 'en',
        },
      }
    },
  }),
  branch(
    ({ GettingStartedArticlesQuery }: OuterProps) =>
      GettingStartedArticlesQuery.loading,
    renderNothing
  )
)(GettingStartedArticle)

```


[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 docs-ui/react/AppDocs.tsx from the docs-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import { Query } from 'react-apollo'
import { ApolloError } from 'apollo-client'

import DocsRenderer from './components/DocsRenderer'
import Skeleton from './components/Skeleton'
import EmptyDocs from './components/EmptyDocs'
import { useApp } from './hooks/useApp'
import { maybeAddMdExtension } from './modules'
import MarkdownFile from './graphql/markdownFile.graphql'

const AppDocs: FC = () => {
  const { appName, fileName } = useApp()

  return (
    <div className="w-100 center flex flex-column">
      <Query
        query={MarkdownFile}
        variables={{
          appName,
          fileName: maybeAddMdExtension(fileName),
        }}>
        {({
          loading,
          error,
          data,
        }: {
          loading: boolean
          error?: ApolloError
          data: { markdownFile: { markdown: string; meta: MetaData } }
        }) => {
          if (loading) return <Skeleton />
          if (error || data.markdownFile.markdown === '') return <EmptyDocs />

          const {
            markdownFile: { markdown, meta },
          } = data

          return <DocsRenderer markdown={markdown} meta={meta} />
        }}
      </Query>
    </div>
  )
}

interface MetaData {
  title: string
  description: string
  tags: string[]
  version: string
  git: string
}

export default AppDocs

```


[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 docs-ui/react/ComponentsGrid.tsx from the docs-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import { FormattedMessage } from 'react-intl'
import { useQuery } from 'react-apollo'
import { useRuntime } from 'vtex.render-runtime'

import ComponentGridItem from './components/ComponentGridItem'
import EmptyDocs from './components/EmptyDocs'
import { slug, removeFileExtension } from './modules'
import { IO_DOCUMENTATION } from './modules/constantExports'
import ComponentList from './graphql/componentsList.graphql'

const ComponentsGrid: FC = () => {
  const {
    route: { params },
    page,
  } = useRuntime()

  const useAppsDirectory = page === 'docs-ui.apps-list'

  const { data, error, loading } = useQuery<{
    componentsList: Record<
      string,
      Array<{
        appName: string
        file: string
        title: string
        description: string
        url: string
      }>
    >
  }>(ComponentList, {
    variables: {
      appName: IO_DOCUMENTATION,
      locale: 'en',
      useAppsDirectory,
    },
  })

  if (loading) return null

  if (error || !data) {
    return <EmptyDocs />
  }

  const [category] = params.category.split('-')
  const shouldShowAllComponents = category === 'all'

  const componentsListFromCategory = shouldShowAllComponents
    ? Object.keys(data.componentsList).flatMap(
        categoryName => data.componentsList[categoryName]
      )
    : data.componentsList[category]

  return (
    <div className="w-100 center">
      <h1 className="t-heading-1 center mb6">
        <FormattedMessage id={`docs-ui/components.${params.category}`} />
      </h1>
      <p className="t-body c-on-base center mb8 lh-copy">
        <FormattedMessage
          id={`docs-ui/components.${params.category}-description`}
        />
      </p>
      <div className="flex flex-wrap">
        {componentsListFromCategory?.map(component => {
          const hasTitleAndDescription =
            component && !!(component.appName && component.description)

          return (
            hasTitleAndDescription && (
              <div key={slug(component.title)} className="w-50 w-third-ns">
                <ComponentGridItem
                  title={component.title}
                  description={component.description}
                  link={`/docs/components/${params.category}/${
                    component.appName
                  }/${(component.file &&
                    slug(removeFileExtension(component.file))) ||
                    ''}`}
                />
              </div>
            )
          )
        })}
      </div>
    </div>
  )
}

export default ComponentsGrid

```


[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 docs-ui/react/IntroductionArticle.tsx from the docs-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import { Query } from 'react-apollo'
import { ApolloError } from 'apollo-client'
import { useRuntime } from 'vtex.render-runtime'

import DocsRenderer from './components/DocsRenderer'
import Skeleton from './components/Skeleton'
import EmptyDocs from './components/EmptyDocs'
import { IO_DOCUMENTATION } from './modules/constantExports'
import { maybeAddMdExtension } from './modules'
import MarkdownFile from './graphql/markdownFile.graphql'

const IntroductionArticle: FC = () => {
  const {
    route: { params },
  } = useRuntime()

  return (
    <div className="w-100 center flex flex-column">
      <Query
        query={MarkdownFile}
        variables={{
          appName: IO_DOCUMENTATION,
          fileName: `Introduction/${maybeAddMdExtension(params.article)}`,
          locale: 'en',
        }}>
        {({
          loading,
          error,
          data,
        }: {
          loading: boolean
          error?: ApolloError
          data: { markdownFile: { markdown: string; meta: MetaData } }
        }) => {
          if (loading) return <Skeleton />
          if (error) return <EmptyDocs />

          const {
            markdownFile: { markdown, meta },
          } = data

          return <DocsRenderer markdown={markdown} meta={meta} />
        }}
      </Query>
    </div>
  )
}

interface MetaData {
  title: string
  description: string
  tags: string[]
  version: string
  git: string
}

export default IntroductionArticle

```


[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 docs-ui/react/Home.tsx from the docs-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
import { Link } from 'vtex.render-runtime'

import { slug } from './modules'
import LatestFeatures from './components/LatestFeatures'
import Community from './components/Community'
import Recipes from './components/icons/Recipes'
import Components from './components/icons/Components'
import RightArrow from './components/icons/RightArrow'
import ProductImage from './images/product.png'

const Home: FC = () => {
  const intl = useIntl()

  return (
    <main className="w-100 w-70-ns">
      <h1
        id={slug(intl.formatMessage({ id: 'docs-ui/build' }))}
        className="t-heading-1 w-90 w-100-ns mb6 c-on-base"
        style={{
          maxWidth: '680px',
        }}>
        <FormattedMessage id="docs-ui/build" />
      </h1>
      <p className="small c-on-base w-100 mb8 lh-copy">
        <FormattedMessage id="docs-ui/build-description" />
      </p>
      <div className="w-100 center">
        <Link
          to="/docs/getting-started/build-stores-with-store-framework/1"
          className="flex-l mb8 w-100 pointer dim no-underline"
          style={{ height: '480px' }}>
          <div className="w-third-l w-100 pa6 bg-emphasis flex flex-column justify-end">
            <span className="t-small c-on-emphasis">
              <div className="ttu fw5 pb5">
                <FormattedMessage id="docs-ui/getting-started" />
              </div>
            </span>
            <h4 className="t-heading-2 mv1 w-90-l ttu c-on-emphasis">
              <FormattedMessage id="docs-ui/create-stores" />
            </h4>
          </div>
          <div
            className="w-two-thirds-l ph5-l h5 h-auto-l bg-base"
            style={{
              background: `no-repeat center/100% url(${ProductImage})`,
            }}
          />
        </Link>
        <div className="mb8 flex flex-row-l flex-column justify-around bg-base">
          <div className="mv6 mv0-l w-50-l flex">
            <div className="c-on-base" style={{ minWidth: '84px' }}>
              <Recipes />
            </div>
            <div className="ph5">
              <p className="t-heading-3 c-on-base mt0">
                <FormattedMessage id="docs-ui/recipes" />
              </p>
              <p className="c-on-base lh-copy">
                <FormattedMessage id="docs-ui/recipes-description" />
              </p>
              <div className="flex items-center dim">
                <Link
                  to="/docs/recipes/all"
                  className="link no-underline c-emphasis">
                  <span className="mr5">
                    <FormattedMessage id="docs-ui/see-all" />
                  </span>
                  <RightArrow />
                </Link>
              </div>
            </div>
          </div>
          <div className="mh3-l mv8 mv0-l w-50-l flex">
            <div className="c-on-base" style={{ minWidth: '84px' }}>
              <Components />
            </div>
            <div className="ph5">
              <p className="t-heading-3 c-on-base mt0">
                <FormattedMessage id="docs-ui/our-components" />
              </p>
              <p className="c-on-base lh-copy">
                <FormattedMessage id="docs-ui/our-components-description" />
              </p>
              <div className="c-emphasis flex items-center dim">
                <Link
                  to="/docs/components/all"
                  className="link no-underline c-emphasis">
                  <span className="mr5">
                    <FormattedMessage id="docs-ui/see-all" />
                  </span>
                  <RightArrow />
                </Link>
              </div>
            </div>
          </div>
        </div>
        <LatestFeatures />
        <Community />
      </div>
    </main>
  )
}

export default Home

```


[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 docs-ui/react/Search.tsx from the docs-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, Fragment } from 'react'
import { useQuery } from 'react-apollo'

import RightArrow from './components/icons/RightArrow'
import searchEngine from './graphql/search.graphql'
import Skeleton from './components/Skeleton'

interface Props {
  query: {
    q: string
  }
}

interface SearchQueryResult {
  searchEngine: SearchResult[]
}

interface SearchResult {
  title: string
  snippet: string
  link: string
}

const isNotLastResult = (results: SearchResult[], index: number) =>
  index !== results.length - 1

const isFirstResult = (index: number) => index === 0

const removeAppVersionFromSearchResult = (url: string) => {
  // https://regex101.com/r/gbllfu/1
  const versionRegex = /@[\d.]+/g
  const containsAppVersion = versionRegex.test(url)

  return containsAppVersion ? url.replace(versionRegex, '') : url
}

const Search: FC<Props> = ({ query }) => {
  const queryString = query.q || ''

  const { data, loading } = useQuery<SearchQueryResult>(searchEngine, {
    variables: { searchQuery: queryString },
  })

  const results = data?.searchEngine ?? []

  return (
    <Fragment>
      {!loading ? (
        queryString && (
          <div className="w-100 flex flex-column">
            <h1 className="t-heading-3">
              {results.length > 0
                ? `Results for "${queryString}"`
                : 'No results Found'}
            </h1>

            {results && (
              <ul className="w-70-ns list pl0">
                {results.map((result: SearchResult, index: number) => (
                  <li
                    key={index}
                    className={`${
                      isFirstResult(index) ? '' : 'mv8'
                    } searchResult ${
                      isNotLastResult(results, index)
                        ? 'searchResultBorder'
                        : ''
                    }`}>
                    <h2
                      className="t-heading-2 searchTitle"
                      style={{ wordBreak: 'break-word' }}>
                      {result.title}
                    </h2>
                    <p className="t-body searchSnippet">{result.snippet}</p>
                    <a
                      className={`link c-emphasis no-underline t-body ml-auto
                flex items-center dim`}
                      href={removeAppVersionFromSearchResult(result.link)}>
                      <div className="flex flex-column flex-row di">
                        <span>Read More</span>
                        <div className="ml5">
                          <RightArrow />
                        </div>
                      </div>
                    </a>
                  </li>
                ))}
              </ul>
            )}
          </div>
        )
      ) : (
        <Skeleton />
      )}
    </Fragment>
  )
}

export default Search

```


[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 docs-ui/react/ConceptList.tsx from the docs-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import { FormattedMessage } from 'react-intl'
import { useQuery } from 'react-apollo'
import { Link } from 'vtex.render-runtime'

import { IO_DOCUMENTATION } from './modules/constantExports'
import { slug } from './modules'
import ConceptListQuery from './graphql/conceptList.graphql'
import Skeleton from './components/Skeleton'
import UnderConstruction from './UnderConstruction'
import RightArrow from './components/icons/RightArrow'

interface Concept {
  title: string
  description: string
  path: string
}

interface QueryResults {
  conceptList: Concept[]
}

function getShortResourcePath(path: string) {
  // the path will always be something like: dist/vtex.docs-graphql/<locale>/Concepts/<fileName>.md
  const PATH_PREFIX = 'dist/vtex.docs-graphql/Concepts/'
  // the <locale> section will always be one of 'en/', 'pt/', 'es/'
  const LOCALE_LENGTH = 3
  const FILE_EXTENSION = '.md'
  return path.substring(
    PATH_PREFIX.length + LOCALE_LENGTH,
    path.length - FILE_EXTENSION.length
  )
}

const ConceptList: FC = () => {
  const { data, loading, error } = useQuery<QueryResults>(ConceptListQuery, {
    variables: {
      appName: IO_DOCUMENTATION,
      locale: 'en',
    },
  })

  if (loading) {
    return <Skeleton />
  }

  if (error || data?.conceptList.length === 0) {
    return <UnderConstruction />
  }

  return (
    <div>
      <h1 className="t-heading-1 mb6">
        <FormattedMessage id="docs-ui/concepts" />
      </h1>
      <p className="t-body c-on-base w-70-ns">
        <FormattedMessage id="docs-ui/concepts-description" />
      </p>
      <div>
        {data?.conceptList.map((concept: Concept) => (
          <article
            key={slug(concept.description)}
            className="flex flex-column justify-center w-70-l mv4 no-underline">
            <h2 className="t-heading-4 mb3">{concept.title}</h2>
            <Link
              to={`/docs/concepts/${getShortResourcePath(concept.path)}`}
              className="flex items-center mb5 c-emphasis link no-underline dim">
              <span className="mr4">
                <FormattedMessage id="docs-ui/read-more" />
              </span>
              <RightArrow />
            </Link>
          </article>
        ))}
      </div>
    </div>
  )
}

export default ConceptList

```