Skip to content

Commit

Permalink
Merge pull request #1 from vtex-apps/chore/refactor-for-publication
Browse files Browse the repository at this point in the history
Chore/refactor for publication
  • Loading branch information
edyespinal authored Nov 4, 2022
2 parents b268e69 + f4fedb2 commit 23cfc3b
Show file tree
Hide file tree
Showing 15 changed files with 198 additions and 3,240 deletions.
4 changes: 1 addition & 3 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
"extends": "vtex",
"root": true,
"env": {
"node": true,
"es6": true,
"jest": true
"node": true
}
}
43 changes: 40 additions & 3 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"vendor": "vtex",
"name": "is-relevanc-api-middleware-resolver",
"name": "relevanc-is-api-middleware-resolver",
"version": "0.0.1",
"title": "Intelligent Search API middleware resolver",
"description": "Implementation of the GraphQL schema for the intelligent search middleware.",
Expand All @@ -15,10 +15,47 @@
{
"name": "outbound-access",
"attrs": {
"host": "exito.staging-ads.peps.relevanc.io",
"path": "/sponsored-offers*"
"host": "*",
"path": "*.peps.relevanc.io/sponsored-offers"
}
}
],
"settingsSchema": {
"title": "RelevanC search resolver middleware",
"type": "object",
"properties": {
"adServerName": {
"title": "RelevanC AdServer name",
"type": "string",
"description": "Name of the RelevanC AdServer (without the \"ads.peps.relevanc.io\")",
"default": "relevanc"
},
"boostType": {
"title": "Product property",
"type": "string",
"default": "skuId",
"enum": ["skuId"],
"enumNames": ["SKU ID"]
},
"maxOffersToDisplay": {
"title": "Max number of offers",
"type": "number",
"description": "Max number of sponsored offers to display on the search results.",
"default": 4
},
"addAllProducts": {
"title": "Add all products",
"type": "boolean",
"description": "By default, only products that are part of the search results are promoted.\n Check to add all products returned by the AdServer.",
"default": false
},
"production": {
"title": "Production",
"type": "boolean",
"description": "Toggle between development and production environment.",
"default": false
}
}
},
"$schema": "https://raw.githubusercontent.com/vtex/node-vtex-api/master/gen/manifest.schema"
}
4 changes: 0 additions & 4 deletions node/clients/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ import RelevanC from './relevanC'
const MEDIUM_TIMEOUT_MS = 2 * 1000

export class Clients extends IOClients {
// Add client example
// public get myClient(): ClientType {
// return this.getOrSet('myClient', ClientType)
// }
public get relevanC() {
return this.getOrSet('relevanC', RelevanC)
}
Expand Down
31 changes: 21 additions & 10 deletions node/clients/relevanC.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
import type { InstanceOptions, IOContext} from '@vtex/api'
import { ExternalClient } from '@vtex/api'
import { InstanceOptions, IOContext, ExternalClient } from '@vtex/api'

const BASE_URL = (name: string) => ({
STAGING: `http://${name}.staging-ads.peps.relevanc.io`,
PRODUCTION: `http://${name}.ads.peps.relevanc.io`,
})

export default class RelevanC extends ExternalClient {
constructor(context: IOContext, options?: InstanceOptions) {
super(
'http://exito.staging-ads.peps.relevanc.io/sponsored-offers?sourcePageNumber=0&keyOrigin=',
context,
options
)
super('https://ads/peps.relevanc.io', context, options)
}

public async getOffers(params: string): Promise<any> {
return this.http.get(params.toString(), {
public async getSponsoredOffers(
production: boolean,
serverName: string,
params: SponsoredProductsPayload
): Promise<SponsoredProductsResponse> {
const URL = production
? BASE_URL(serverName).PRODUCTION
: BASE_URL(serverName).STAGING

return this.http.get(`${URL}/sponsored-offers`, {
headers: {
'x-vtex-use-https': 'true',
},
metric: 'status-get-raw',
params: {
...params,
},
metric: 'relevanc-get-offers',
})
}
}
8 changes: 8 additions & 0 deletions node/contants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const DESKTOP = 'PC_LR_PLR'
export const MOBILE = 'MOB_LR_PLR'
export enum ACTION {
ADD = 'add',
REMOVE = 'remove',
PROMOTE = 'promote',
DEMOTE = 'demote',
}
8 changes: 2 additions & 6 deletions node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ import { Service, RecorderState, ParamsContext } from '@vtex/api'
import schema from 'vtex.is-api-middleware-graphql/graphql'

import { Clients, clients } from './clients'
import before from './resolvers/before'
import { resolvers } from './resolvers'

export default new Service<Clients, RecorderState, ParamsContext>({
clients,
graphql: {
resolvers: {
Query: {
before,
},
},
resolvers,
schema,
},
})
4 changes: 3 additions & 1 deletion node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
"husky": "^4.2.0",
"lint-staged": "^10.0.2",
"prettier": "^1.19.1",
"typescript": "3.9.7"
"typescript": "3.9.7",
"vtex.is-api-middleware-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.is-api-middleware-graphql@0.0.2/public/@types/vtex.is-api-middleware-graphql",
"vtex.relevanc-is-api-middleware-resolver": "https://relevanc--exitocol.myvtex.com/_v/private/typings/linked/v1/vtex.relevanc-is-api-middleware-resolver@0.0.1+build1666861070/public/_types/react"
},
"version": "0.1.1"
}
112 changes: 62 additions & 50 deletions node/resolvers/before.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,74 @@
export default async function before(
import { ACTION, DESKTOP } from '../contants'

export async function before(
_: unknown,
args: SearchParams,
ctx: Context
): Promise<SearchParams> {
const {
clients: { relevanC },
clients: { relevanC, apps },
vtex: { logger },
} = ctx
// This is just an example. Change the implementation of this function however you like :)
console.log(args.query)

const searchQuery = args.query
const sponsoredProducts = await relevanC.getOffers(
`${searchQuery}&adSpaceId=PC_LR_PLR`

if (!searchQuery) {
const message = 'Query was undefined'

logger.error({
message,
})

throw new Error(message)
}

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

if (sponsoredProducts.offers.length) {
console.log('hola cesarin')
const myDynamicRules: DynamicRule[] = []
for (const spProduct of sponsoredProducts.offers) {
myDynamicRules.push({
action: 'promote',
type: 'id',
value: spProduct.productId,
})
}
console.log(myDynamicRules)

return { ...args, dynamicRules: myDynamicRules }
if (!Object.keys(settings).length) {
const message = 'Settings for RelevanC Integration not found'

logger.error({
message,
})

throw new Error(message)
}
const customRules: DynamicRule[] = [
{
action: 'add',
type: 'id',
value: '1253',
},
{
action: 'promote',
type: 'id',
value: '1253',
},

const {
adServerName,
boostType,
maxOffersToDisplay,
addAllProducts,
production,
} = settings

const { offers } = await relevanC.getSponsoredOffers(
production,
adServerName,
{
action: 'remove',
type: 'id',
value: '1336358',
},

// {
// action: 'promote',
// type: 'id',
// value: '857952',
// },
// {
// action: 'promote',
// type: 'id',
// value: '308625',
// },
]
console.log(customRules)

return { ...args, dynamicRules: customRules }
sourcePageNumber: 0,
keyOrigin: searchQuery,
adSpaceId: DESKTOP,
}
)

if (!offers.length) {
return args
}

const dynamicRules = offers.reduce((rules: DynamicRule[], offer, index) => {
if (index < maxOffersToDisplay) {
rules.push({
action: addAllProducts ? ACTION.ADD : ACTION.PROMOTE,
type: boostType,
value: offer.productId,
})
}

return rules
}, [])

return { ...args, dynamicRules }
}
7 changes: 7 additions & 0 deletions node/resolvers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { before } from './before'

export const resolvers = {
Query: {
before,
},
}
10 changes: 5 additions & 5 deletions node/service.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"stack": "nodejs",
"memory": 256,
"minReplicas": 3,
"workers": 1
}
"stack": "nodejs",
"memory": 512,
"minReplicas": 3,
"workers": 1
}
7 changes: 7 additions & 0 deletions node/typings/appSettings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type AppSettings = {
adServerName: string
boostType: BoostType
maxOffersToDisplay: number
addAllProducts: boolean
production: boolean
}
2 changes: 1 addition & 1 deletion node/global.ts → node/typings/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ServiceContext } from '@vtex/api'

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

declare global {
type Context = ServiceContext<Clients>
Expand Down
37 changes: 37 additions & 0 deletions node/typings/relevanc.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
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 Offer = {
algoSelectionType:
| 'NOTSELECTED'
| 'EXPLORED'
| 'UNEXPLORED'
| 'LONGTAIL'
| 'SHORTTAIL'
isSponsored: boolean
offerId: number
productId: string
tagName: string
tag: string
}

type SponsoredProductsResponse = {
nbResults: number
offers: Offer[]
}
Loading

0 comments on commit 23cfc3b

Please sign in to comment.