Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions lint.sh

This file was deleted.

14 changes: 14 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@
"path": "/*"
}
},
{
"name": "outbound-access",
"attrs": {
"host": "portal.vtexcommercestable.com.br",
"path": "/api/intelligent-search"
}
},
{
"name": "outbound-access",
"attrs": {
"host": "portal.vtexcommercebeta.com.br",
"path": "/api/intelligent-search"
}
},
{
"name": "vtex.messages:graphql-translate-messages"
}
Expand Down
5 changes: 5 additions & 0 deletions node/clients/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Search } from './search'
import { Checkout } from './checkout'
import { Rewriter } from './rewriter'
import { IntelligentSearchApi } from './intelligent-search-api'
import { Intsch } from './intsch'

export class Clients extends IOClients {
public get search() {
Expand All @@ -18,4 +19,8 @@ export class Clients extends IOClients {
public get intelligentSearchApi() {
return this.getOrSet('intelligentSearchApi', IntelligentSearchApi)
}

public get intsch() {
return this.getOrSet('intsch', Intsch)
}
}
98 changes: 72 additions & 26 deletions node/clients/intelligent-search-api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { ExternalClient, InstanceOptions, IOContext } from "@vtex/api";
import { parseState } from "../utils/searchState";
import type { InstanceOptions, IOContext } from '@vtex/api'
import { ExternalClient } from '@vtex/api'

import { parseState } from '../utils/searchState'
import { IIntelligentSearchClient } from './intsch/types'

const isPathTraversal = (str: string) => str.indexOf('..') >= 0

interface CorrectionParams {
query: string
}
Expand Down Expand Up @@ -44,59 +48,89 @@ const decodeQuery = (query: string) => {
}
}

export class IntelligentSearchApi extends ExternalClient {
export class IntelligentSearchApi
extends ExternalClient
implements IIntelligentSearchClient
{
private locale: string | undefined

public constructor(context: IOContext, options?: InstanceOptions) {
super(`http://${context.workspace}--${context.account}.myvtex.com/_v/api/intelligent-search`, context, {
...options,
headers: {
...options?.headers,
super(
`http://${context.workspace}--${context.account}.myvtex.com/_v/api/intelligent-search`,
context,
{
...options,
headers: {
...options?.headers,
},
}
})
)

const { locale, tenant } = context

this.locale = locale ?? tenant?.locale
}

public async topSearches() {
return this.http.get('/top_searches', {params: {
locale: this.locale
}, metric: 'topSearches'})
return this.http.get('/top_searches', {
params: {
locale: this.locale,
},
metric: 'topSearches',
})
}

public async correction(params: CorrectionParams) {
return this.http.get('/correction_search', {params: {...params, locale: this.locale}, metric: 'correction'})
return this.http.get('/correction_search', {
params: { ...params, locale: this.locale },
metric: 'correction',
})
}

public async searchSuggestions(params: SearchSuggestionsParams) {
return this.http.get('/search_suggestions', {params: {...params, locale: this.locale}, metric: 'searchSuggestions'})
return this.http.get('/search_suggestions', {
params: { ...params, locale: this.locale },
metric: 'searchSuggestions',
})
}

public async autocompleteSearchSuggestions(params: AutocompleteSearchSuggestionsParams) {
return this.http.get('/autocomplete_suggestions', {params: {...params, locale: this.locale}, metric: 'autocompleteSearchSuggestions'})
public async fetchAutocompleteSuggestions(
params: AutocompleteSearchSuggestionsParams
) {
return this.http.get('/autocomplete_suggestions', {
params: { ...params, locale: this.locale },
metric: 'autocompleteSearchSuggestions',
})
}

public async banners(params: BannersArgs, path: string) {
if (isPathTraversal(path)) {
throw new Error("Malformed URL")
throw new Error('Malformed URL')
}

return this.http.get(`/banners/${path}`, {params: {...params, query: params.query, locale: this.locale}, metric: 'banners'})
return this.http.get(`/banners/${path}`, {
params: { ...params, query: params.query, locale: this.locale },
metric: 'banners',
})
}

public async facets(params: FacetsArgs, path: string, shippingHeader?: string[]) {
public async facets(
params: FacetsArgs,
path: string,
shippingHeader?: string[]
) {
if (isPathTraversal(path)) {
throw new Error("Malformed URL")
throw new Error('Malformed URL')
}

const {query, leap, searchState} = params
const { query, leap, searchState } = params

return this.http.get(`/facets/${path}`, {
params: {
...params,
query: query && decodeQuery(query),
locale: this.locale,
// eslint-disable-next-line @typescript-eslint/camelcase
bgy_leap: leap ? true : undefined,
...parseState(searchState),
},
Expand All @@ -107,16 +141,22 @@ export class IntelligentSearchApi extends ExternalClient {
})
}

public async productSearch(params: SearchResultArgs, path: string, shippingHeader?: string[]) {
const {query, leap, searchState} = params
public async productSearch(
params: SearchResultArgs,
path: string,
shippingHeader?: string[]
) {
const { query, leap, searchState } = params

if (isPathTraversal(path)) {
throw new Error("Malformed URL")
throw new Error('Malformed URL')
}

return this.http.get(`/product_search/${path}`, {
params: {
query: query && decodeQuery(query),
locale: this.locale,
// eslint-disable-next-line @typescript-eslint/camelcase
bgy_leap: leap ? true : undefined,
...parseState(searchState),
...params,
Expand All @@ -128,16 +168,22 @@ export class IntelligentSearchApi extends ExternalClient {
})
}

public async sponsoredProducts(params: SearchResultArgs, path: string, shippingHeader?: string[]) {
const {query, leap, searchState} = params
public async sponsoredProducts(
params: SearchResultArgs,
path: string,
shippingHeader?: string[]
) {
const { query, leap, searchState } = params

if (isPathTraversal(path)) {
throw new Error("Malformed URL")
throw new Error('Malformed URL')
}

return this.http.get(`/sponsored_products/${path}`, {
params: {
query: query && decodeQuery(query),
locale: this.locale,
// eslint-disable-next-line @typescript-eslint/camelcase
bgy_leap: leap ? true : undefined,
...parseState(searchState),
...params,
Expand Down
33 changes: 33 additions & 0 deletions node/clients/intsch/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { InstanceOptions, IOContext, JanusClient } from '@vtex/api'

import {
AutocompleteSuggestionsArgs,
AutocompleteSuggestionsResponse,
IIntelligentSearchClient,
} from './types'

export class Intsch extends JanusClient implements IIntelligentSearchClient {
private locale: string | undefined

public constructor(ctx: IOContext, options?: InstanceOptions) {
const env = ctx.production ? 'stable' : 'beta'

super(ctx, options, env)

const { locale, tenant } = ctx

this.locale = locale ?? tenant?.locale
}

public fetchAutocompleteSuggestions(
args: AutocompleteSuggestionsArgs
): Promise<AutocompleteSuggestionsResponse> {
return this.http.get(
'/api/intelligent-search/v0/autocomplete-suggestions',
{
params: { query: args.query, locale: this.locale },
metric: 'autocompleteSearchSuggestions-new',
}
)
}
}
25 changes: 25 additions & 0 deletions node/clients/intsch/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* eslint-disable @typescript-eslint/prefer-interface */

export type AutocompleteSuggestionsArgs = {
query: string
}

export type AutocompleteSuggestionsResponse = {
searches: {
term: string
count: number
attributes?: {
key: string
value: string
labelKey: string
labelValue: string
}[]
}[]
}

// eslint-disable-next-line @typescript-eslint/interface-name-prefix
export interface IIntelligentSearchClient {
fetchAutocompleteSuggestions(
args: AutocompleteSuggestionsArgs
): Promise<AutocompleteSuggestionsResponse>
}
6 changes: 3 additions & 3 deletions node/clients/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ enum SimulationBehavior {

const inflightKey = ({ baseURL, url, params, headers }: RequestConfig) => {
return (
baseURL! +
url! +
(baseURL ?? '') +
(url ?? '') +
stringify(params, { arrayFormat: 'repeat', addQueryPrefix: true }) +
`&segmentToken=${headers['x-vtex-segment']}`
`&segmentToken=${headers ? headers['x-vtex-segment'] : ''}`
)
}

Expand Down
2 changes: 1 addition & 1 deletion node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@types/node": "^20.0.0",
"@types/qs": "^6.5.1",
"@types/ramda": "^0.26.21",
"@vtex/api": "6.48.0",
"@vtex/api": "^7.0.0",
"@vtex/tsconfig": "^0.6.0",
"axios": "^0.21.1",
"eslint": "^5.15.3",
Expand Down
Loading
Loading