From 75aea474d4a628056ed6e099e6049921926c1acb Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 20:43:48 -0300 Subject: [PATCH 01/14] chore(LicenseManager): apply linter --- src/clients/janus/LicenseManager.ts | 35 ++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/clients/janus/LicenseManager.ts b/src/clients/janus/LicenseManager.ts index 2c90e9c42..34fc818e4 100644 --- a/src/clients/janus/LicenseManager.ts +++ b/src/clients/janus/LicenseManager.ts @@ -13,12 +13,12 @@ const routes = { topbarData: `${BASE_URL}/site/pvt/newtopbar`, } -const inflightKey = ({baseURL, url, params}: RequestConfig) => { - return baseURL! + url! + stringify(params, {arrayFormat: 'repeat', addQueryPrefix: true}) +const inflightKey = ({ baseURL, url, params }: RequestConfig) => { + return baseURL! + url! + stringify(params, { arrayFormat: 'repeat', addQueryPrefix: true }) } export class LicenseManager extends JanusClient { - public getAccountData (VtexIdclientAutCookie: string, tracingConfig?: RequestTracingConfig) { + public getAccountData(VtexIdclientAutCookie: string, tracingConfig?: RequestTracingConfig) { const metric = 'lm-account-data' return this.http.get(routes.accountData, { forceMaxAge: TWO_MINUTES_S, @@ -34,7 +34,7 @@ export class LicenseManager extends JanusClient { }) } - public getTopbarData (VtexIdclientAutCookie: string, tracingConfig?: RequestTracingConfig) { + public getTopbarData(VtexIdclientAutCookie: string, tracingConfig?: RequestTracingConfig) { const metric = 'lm-topbar-data' return this.http.get(routes.topbarData, { headers: { @@ -48,17 +48,22 @@ export class LicenseManager extends JanusClient { }) } - public canAccessResource (VtexIdclientAutCookie: string, resourceKey: string, tracingConfig?: RequestTracingConfig) { + public canAccessResource(VtexIdclientAutCookie: string, resourceKey: string, tracingConfig?: RequestTracingConfig) { const metric = 'lm-resource-access' - return this.http.get(`${routes.resourceAccess}/${resourceKey}/access`, { - headers: { - VtexIdclientAutCookie, - }, - metric, - tracing: { - requestSpanNameSuffix: metric, - ...tracingConfig?.tracing, - }, - }).then(() => true, () => false) + return this.http + .get(`${routes.resourceAccess}/${resourceKey}/access`, { + headers: { + VtexIdclientAutCookie, + }, + metric, + tracing: { + requestSpanNameSuffix: metric, + ...tracingConfig?.tracing, + }, + }) + .then( + () => true, + () => false + ) } } From 336ddf4ede8be3efab89c6e968137a1b444dac93 Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 20:44:25 -0300 Subject: [PATCH 02/14] chore(LicenseManager): move to its own folder --- .../janus/{LicenseManager.ts => LicenseManager/index.ts} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename src/clients/janus/{LicenseManager.ts => LicenseManager/index.ts} (93%) diff --git a/src/clients/janus/LicenseManager.ts b/src/clients/janus/LicenseManager/index.ts similarity index 93% rename from src/clients/janus/LicenseManager.ts rename to src/clients/janus/LicenseManager/index.ts index 34fc818e4..93652786c 100644 --- a/src/clients/janus/LicenseManager.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -1,7 +1,7 @@ import { stringify } from 'qs' -import { RequestConfig, RequestTracingConfig } from '../../HttpClient' -import { JanusClient } from './JanusClient' +import { RequestConfig, RequestTracingConfig } from '../../../HttpClient' +import { JanusClient } from '../JanusClient' const TWO_MINUTES_S = 2 * 60 From b5d5b6777539b3fca5c5dc9f87a210064a74dbdb Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 21:15:55 -0300 Subject: [PATCH 03/14] feat(IOClients): add Catalog client with getSalesChannel --- src/clients/IOClients.ts | 6 +++++- src/clients/janus/Catalog/index.ts | 24 ++++++++++++++++++++++++ src/clients/janus/Catalog/types.ts | 5 +++++ src/clients/janus/index.ts | 1 + 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 src/clients/janus/Catalog/index.ts create mode 100644 src/clients/janus/Catalog/types.ts diff --git a/src/clients/IOClients.ts b/src/clients/IOClients.ts index a7f5f320d..3d4c81e01 100644 --- a/src/clients/IOClients.ts +++ b/src/clients/IOClients.ts @@ -5,7 +5,7 @@ import { CatalogGraphQL } from './apps/catalogGraphQL/index' import { ID, MasterData, PaymentProvider } from './external' import { Apps, Assets, BillingMetrics, Events, Registry, Router, VBase, Workspaces } from './infra' import { IOClient, IOClientConstructor } from './IOClient' -import { LicenseManager, Segment, Session, TenantClient } from './janus' +import { LicenseManager, Segment, Session, TenantClient, Catalog } from './janus' export type ClientsImplementation = new ( clientOptions: Record, @@ -93,6 +93,10 @@ export class IOClients { return this.getOrSet('catalogGraphQL', CatalogGraphQL) } + public get catalog() { + return this.getOrSet('catalog', Catalog) + } + public get paymentProvider() { return this.getOrSet('paymentProvider', PaymentProvider) } diff --git a/src/clients/janus/Catalog/index.ts b/src/clients/janus/Catalog/index.ts new file mode 100644 index 000000000..3f21f3801 --- /dev/null +++ b/src/clients/janus/Catalog/index.ts @@ -0,0 +1,24 @@ +import { inflightUrlWithQuery, RequestConfig } from '../../../HttpClient' +import { JanusClient } from '../JanusClient' +import { SalesChannel } from './types' + +const BASE_URL = '/api/catalog_system' + +const routes = { + salesChannel: (salesChannelId: number) => `${BASE_URL}/pub/saleschannel/${salesChannelId}`, +} + +export class Catalog extends JanusClient { + public getSalesChannel(id: number, config?: RequestConfig) { + const metric = 'catalog-saleschannel' + return this.http.get(routes.salesChannel(id), { + inflightKey: inflightUrlWithQuery, + metric, + ...config, + tracing: { + requestSpanNameSuffix: metric, + ...config?.tracing, + }, + }) + } +} diff --git a/src/clients/janus/Catalog/types.ts b/src/clients/janus/Catalog/types.ts new file mode 100644 index 000000000..22fe9b91f --- /dev/null +++ b/src/clients/janus/Catalog/types.ts @@ -0,0 +1,5 @@ +export interface SalesChannel { + Id: number + CultureInfo: string + CurrencyCode: string +} diff --git a/src/clients/janus/index.ts b/src/clients/janus/index.ts index 54081815a..ee8018761 100644 --- a/src/clients/janus/index.ts +++ b/src/clients/janus/index.ts @@ -3,3 +3,4 @@ export * from './LicenseManager' export * from './Segment' export * from './Session' export * from './Tenant' +export * from './Catalog' From e0496a7362fb83de0822b4065d1e4e3104cdb4db Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 21:25:09 -0300 Subject: [PATCH 04/14] chore(LicenseManager): refactor routes to be functions --- src/clients/janus/LicenseManager/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/clients/janus/LicenseManager/index.ts b/src/clients/janus/LicenseManager/index.ts index 93652786c..1588c3e38 100644 --- a/src/clients/janus/LicenseManager/index.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -8,9 +8,9 @@ const TWO_MINUTES_S = 2 * 60 const BASE_URL = '/api/license-manager' const routes = { - accountData: `${BASE_URL}/account`, - resourceAccess: `${BASE_URL}/resources`, - topbarData: `${BASE_URL}/site/pvt/newtopbar`, + accountData: () => `${BASE_URL}/account`, + resourceAccess: (resourceKey: string) => `${BASE_URL}/resources/${resourceKey}/access`, + topbarData: () => `${BASE_URL}/site/pvt/newtopbar`, } const inflightKey = ({ baseURL, url, params }: RequestConfig) => { @@ -20,7 +20,7 @@ const inflightKey = ({ baseURL, url, params }: RequestConfig) => { export class LicenseManager extends JanusClient { public getAccountData(VtexIdclientAutCookie: string, tracingConfig?: RequestTracingConfig) { const metric = 'lm-account-data' - return this.http.get(routes.accountData, { + return this.http.get(routes.accountData(), { forceMaxAge: TWO_MINUTES_S, headers: { VtexIdclientAutCookie, @@ -36,7 +36,7 @@ export class LicenseManager extends JanusClient { public getTopbarData(VtexIdclientAutCookie: string, tracingConfig?: RequestTracingConfig) { const metric = 'lm-topbar-data' - return this.http.get(routes.topbarData, { + return this.http.get(routes.topbarData(), { headers: { VtexIdclientAutCookie, }, @@ -51,7 +51,7 @@ export class LicenseManager extends JanusClient { public canAccessResource(VtexIdclientAutCookie: string, resourceKey: string, tracingConfig?: RequestTracingConfig) { const metric = 'lm-resource-access' return this.http - .get(`${routes.resourceAccess}/${resourceKey}/access`, { + .get(routes.resourceAccess(resourceKey), { headers: { VtexIdclientAutCookie, }, From 05728cd013932e58af461ee949bf5dfbbde0cc05 Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 21:30:39 -0300 Subject: [PATCH 05/14] chore(LicenseManager): refactor to import function --- src/clients/janus/LicenseManager/index.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/clients/janus/LicenseManager/index.ts b/src/clients/janus/LicenseManager/index.ts index 1588c3e38..7eeff7e71 100644 --- a/src/clients/janus/LicenseManager/index.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -1,6 +1,4 @@ -import { stringify } from 'qs' - -import { RequestConfig, RequestTracingConfig } from '../../../HttpClient' +import { RequestTracingConfig, inflightUrlWithQuery } from '../../../HttpClient' import { JanusClient } from '../JanusClient' const TWO_MINUTES_S = 2 * 60 @@ -13,10 +11,6 @@ const routes = { topbarData: () => `${BASE_URL}/site/pvt/newtopbar`, } -const inflightKey = ({ baseURL, url, params }: RequestConfig) => { - return baseURL! + url! + stringify(params, { arrayFormat: 'repeat', addQueryPrefix: true }) -} - export class LicenseManager extends JanusClient { public getAccountData(VtexIdclientAutCookie: string, tracingConfig?: RequestTracingConfig) { const metric = 'lm-account-data' @@ -25,7 +19,7 @@ export class LicenseManager extends JanusClient { headers: { VtexIdclientAutCookie, }, - inflightKey, + inflightKey: inflightUrlWithQuery, metric, tracing: { requestSpanNameSuffix: metric, From d6253fa91e266e27ea68f628e6a1d57949239a58 Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 21:36:40 -0300 Subject: [PATCH 06/14] feat(LicenseManager): add `listBindings` --- src/clients/janus/LicenseManager/index.ts | 21 ++++++++++++++++++- src/clients/janus/LicenseManager/types.ts | 25 +++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/clients/janus/LicenseManager/types.ts diff --git a/src/clients/janus/LicenseManager/index.ts b/src/clients/janus/LicenseManager/index.ts index 7eeff7e71..b5dc919d5 100644 --- a/src/clients/janus/LicenseManager/index.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -1,5 +1,6 @@ -import { RequestTracingConfig, inflightUrlWithQuery } from '../../../HttpClient' +import { RequestTracingConfig, RequestConfig, inflightUrlWithQuery } from '../../../HttpClient' import { JanusClient } from '../JanusClient' +import { OptionsListBindings, APIBindingRes } from './types' const TWO_MINUTES_S = 2 * 60 @@ -9,6 +10,7 @@ const routes = { accountData: () => `${BASE_URL}/account`, resourceAccess: (resourceKey: string) => `${BASE_URL}/resources/${resourceKey}/access`, topbarData: () => `${BASE_URL}/site/pvt/newtopbar`, + listBindings: (tenant: string) => `${BASE_URL}/binding/site/${tenant}`, } export class LicenseManager extends JanusClient { @@ -60,4 +62,21 @@ export class LicenseManager extends JanusClient { () => false ) } + + public listBindings = ({ tenant, adminUserAuthToken }: OptionsListBindings, config?: RequestConfig) => { + const metric = 'lm-list-bindings' + return this.http.get(routes.listBindings(tenant), { + inflightKey: inflightUrlWithQuery, + memoizeable: true, + metric, + headers: { + VtexIdclientAutCookie: adminUserAuthToken, + }, + ...config, + tracing: { + requestSpanNameSuffix: metric, + ...config?.tracing, + }, + }) + } } diff --git a/src/clients/janus/LicenseManager/types.ts b/src/clients/janus/LicenseManager/types.ts new file mode 100644 index 000000000..ebfa115d6 --- /dev/null +++ b/src/clients/janus/LicenseManager/types.ts @@ -0,0 +1,25 @@ +export interface OptionsListBindings { + tenant: string + adminUserAuthToken: string +} + +export interface APIAddress { + Host: string + IsCanonical: boolean + BasePath: string + Localization: { + [k: string]: string + } +} + +export interface APIBindingCreate { + Addresses: APIAddress[] + SiteName: string + DefaultSalesChannelId: number | null + DefaultLocale: string + SupportedLocales: string[] +} + +export interface APIBindingRes extends APIBindingCreate { + Id: string +} From 1f2e7288d70940e4f454bc7dcabd6e5d12e33fb2 Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 21:38:04 -0300 Subject: [PATCH 07/14] feat(LicenseManager): encode URI components --- src/clients/janus/LicenseManager/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clients/janus/LicenseManager/index.ts b/src/clients/janus/LicenseManager/index.ts index b5dc919d5..8254799f5 100644 --- a/src/clients/janus/LicenseManager/index.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -8,9 +8,9 @@ const BASE_URL = '/api/license-manager' const routes = { accountData: () => `${BASE_URL}/account`, - resourceAccess: (resourceKey: string) => `${BASE_URL}/resources/${resourceKey}/access`, + resourceAccess: (resourceKey: string) => `${BASE_URL}/resources/${encodeURIComponent(resourceKey)}/access`, topbarData: () => `${BASE_URL}/site/pvt/newtopbar`, - listBindings: (tenant: string) => `${BASE_URL}/binding/site/${tenant}`, + listBindings: (tenant: string) => `${BASE_URL}/binding/site/${encodeURIComponent(tenant)}`, } export class LicenseManager extends JanusClient { From 41e7e0bc9d939ce29c42dd1deaf01f12c0fa08ec Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 21:44:26 -0300 Subject: [PATCH 08/14] feat(LicenseManager): add `getBinding` --- src/clients/janus/LicenseManager/index.ts | 20 +++++++++++++++++++- src/clients/janus/LicenseManager/types.ts | 5 +++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/clients/janus/LicenseManager/index.ts b/src/clients/janus/LicenseManager/index.ts index 8254799f5..47377d90a 100644 --- a/src/clients/janus/LicenseManager/index.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -1,6 +1,6 @@ import { RequestTracingConfig, RequestConfig, inflightUrlWithQuery } from '../../../HttpClient' import { JanusClient } from '../JanusClient' -import { OptionsListBindings, APIBindingRes } from './types' +import { OptionsListBindings, APIBindingRes, OptionsGetBinding } from './types' const TWO_MINUTES_S = 2 * 60 @@ -11,6 +11,7 @@ const routes = { resourceAccess: (resourceKey: string) => `${BASE_URL}/resources/${encodeURIComponent(resourceKey)}/access`, topbarData: () => `${BASE_URL}/site/pvt/newtopbar`, listBindings: (tenant: string) => `${BASE_URL}/binding/site/${encodeURIComponent(tenant)}`, + getBinding: (bindingId: string) => `${BASE_URL}/binding/${encodeURIComponent(bindingId)}`, } export class LicenseManager extends JanusClient { @@ -79,4 +80,21 @@ export class LicenseManager extends JanusClient { }, }) } + + public getBinding = ({ adminUserAuthToken, bindingId }: OptionsGetBinding, config?: RequestConfig) => { + const metric = 'lm-get-binding' + return this.http.get(routes.getBinding(bindingId), { + inflightKey: inflightUrlWithQuery, + memoizeable: true, + metric, + headers: { + VtexIdclientAutCookie: adminUserAuthToken, + }, + ...config, + tracing: { + requestSpanNameSuffix: metric, + ...config?.tracing, + }, + }) + } } diff --git a/src/clients/janus/LicenseManager/types.ts b/src/clients/janus/LicenseManager/types.ts index ebfa115d6..7c51ded60 100644 --- a/src/clients/janus/LicenseManager/types.ts +++ b/src/clients/janus/LicenseManager/types.ts @@ -3,6 +3,11 @@ export interface OptionsListBindings { adminUserAuthToken: string } +export interface OptionsGetBinding { + adminUserAuthToken: string + bindingId: string +} + export interface APIAddress { Host: string IsCanonical: boolean From 51934a29f332996cd3af65f2a34cb74a26897777 Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 21:51:47 -0300 Subject: [PATCH 09/14] feat(LicenseManager): add `createBinding` --- src/clients/janus/LicenseManager/index.ts | 76 ++++++++++++++++++++++- src/clients/janus/LicenseManager/types.ts | 19 ++++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/clients/janus/LicenseManager/index.ts b/src/clients/janus/LicenseManager/index.ts index 47377d90a..d4e2fbfbb 100644 --- a/src/clients/janus/LicenseManager/index.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -1,6 +1,14 @@ import { RequestTracingConfig, RequestConfig, inflightUrlWithQuery } from '../../../HttpClient' import { JanusClient } from '../JanusClient' -import { OptionsListBindings, APIBindingRes, OptionsGetBinding } from './types' +import { + OptionsListBindings, + APIBindingRes, + OptionsGetBinding, + OptionsCreateBinding, + APIBindingCreate, + Addr, + APICreateBindingRes, +} from './types' const TWO_MINUTES_S = 2 * 60 @@ -12,6 +20,7 @@ const routes = { topbarData: () => `${BASE_URL}/site/pvt/newtopbar`, listBindings: (tenant: string) => `${BASE_URL}/binding/site/${encodeURIComponent(tenant)}`, getBinding: (bindingId: string) => `${BASE_URL}/binding/${encodeURIComponent(bindingId)}`, + createBinding: () => `${BASE_URL}/binding`, } export class LicenseManager extends JanusClient { @@ -97,4 +106,69 @@ export class LicenseManager extends JanusClient { }, }) } + + public createBinding = ( + { + tenant, + adminUserAuthToken, + defaultLocale, + supportedLocales, + salesChannelId, + addrs, + canonicalAddr, + }: OptionsCreateBinding, + config?: RequestConfig + ) => { + const metric = 'lm-create-binding' + + if (addrs.length === 0) { + throw new Error('A binding must have at least one address') + } + + const canonicalAddrExists = addrs.some( + (addr) => canonicalAddr.host === addr.host && canonicalAddr.path === addr.path + ) + + if (!canonicalAddrExists) { + throw new Error('The canonical address must exist within the address list') + } + + if (supportedLocales.length === 0) { + throw new Error('A binding must have at least one locale') + } + + const defaultLocaleExists = supportedLocales.some((locale) => defaultLocale === locale) + + if (!defaultLocaleExists) { + throw new Error('The default locale must exist within the supported locales') + } + + const bindingObj: APIBindingCreate = { + SiteName: tenant, + DefaultLocale: defaultLocale, + SupportedLocales: supportedLocales, + DefaultSalesChannelId: salesChannelId, + Addresses: addrs.map((addr: Addr) => ({ + Host: addr.host, + BasePath: addr.path, + IsCanonical: canonicalAddr.host === addr.host && canonicalAddr.path === addr.path, + Localization: { + '': defaultLocale, + }, + })), + } + + return this.http.post(routes.createBinding(), bindingObj, { + inflightKey: inflightUrlWithQuery, + metric, + headers: { + VtexIdclientAutCookie: adminUserAuthToken, + }, + ...config, + tracing: { + requestSpanNameSuffix: metric, + ...config?.tracing, + }, + }) + } } diff --git a/src/clients/janus/LicenseManager/types.ts b/src/clients/janus/LicenseManager/types.ts index 7c51ded60..d66e1292e 100644 --- a/src/clients/janus/LicenseManager/types.ts +++ b/src/clients/janus/LicenseManager/types.ts @@ -8,6 +8,21 @@ export interface OptionsGetBinding { bindingId: string } +export interface Addr { + host: string + path: string +} + +export interface OptionsCreateBinding { + tenant: string + adminUserAuthToken: string + defaultLocale: string + supportedLocales: string[] + salesChannelId: number | null + addrs: Addr[] + canonicalAddr: Addr +} + export interface APIAddress { Host: string IsCanonical: boolean @@ -28,3 +43,7 @@ export interface APIBindingCreate { export interface APIBindingRes extends APIBindingCreate { Id: string } + +export interface APICreateBindingRes { + Id: string +} From 72daeb0620081a2b0a4a18a3e5b549349edbd88e Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 21:53:21 -0300 Subject: [PATCH 10/14] feat(LicenseManager): add `deleteBinding` --- src/clients/janus/LicenseManager/index.ts | 19 +++++++++++++++++++ src/clients/janus/LicenseManager/types.ts | 5 +++++ 2 files changed, 24 insertions(+) diff --git a/src/clients/janus/LicenseManager/index.ts b/src/clients/janus/LicenseManager/index.ts index d4e2fbfbb..6076a9dfa 100644 --- a/src/clients/janus/LicenseManager/index.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -8,6 +8,7 @@ import { APIBindingCreate, Addr, APICreateBindingRes, + OptionsDeleteBinding, } from './types' const TWO_MINUTES_S = 2 * 60 @@ -21,6 +22,7 @@ const routes = { listBindings: (tenant: string) => `${BASE_URL}/binding/site/${encodeURIComponent(tenant)}`, getBinding: (bindingId: string) => `${BASE_URL}/binding/${encodeURIComponent(bindingId)}`, createBinding: () => `${BASE_URL}/binding`, + deleteBinding: (bindingId: string) => `${BASE_URL}/binding/${encodeURIComponent(bindingId)}`, } export class LicenseManager extends JanusClient { @@ -171,4 +173,21 @@ export class LicenseManager extends JanusClient { }, }) } + + public deleteBinding = ({ adminUserAuthToken, bindingId }: OptionsDeleteBinding, config?: RequestConfig) => { + const metric = 'lm-delete-binding' + + return this.http.delete(routes.deleteBinding(bindingId), { + inflightKey: inflightUrlWithQuery, + metric, + headers: { + VtexIdclientAutCookie: adminUserAuthToken, + }, + ...config, + tracing: { + requestSpanNameSuffix: metric, + ...config?.tracing, + }, + }) + } } diff --git a/src/clients/janus/LicenseManager/types.ts b/src/clients/janus/LicenseManager/types.ts index d66e1292e..66cbf5a1b 100644 --- a/src/clients/janus/LicenseManager/types.ts +++ b/src/clients/janus/LicenseManager/types.ts @@ -8,6 +8,11 @@ export interface OptionsGetBinding { bindingId: string } +export interface OptionsDeleteBinding { + adminUserAuthToken: string + bindingId: string +} + export interface Addr { host: string path: string From 2a93320f7434723d69c36b2711c1d7ce92dbe5e6 Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 21:56:39 -0300 Subject: [PATCH 11/14] feat(LicenseManager): add `updateBinding` method --- src/clients/janus/LicenseManager/index.ts | 70 +++++++++++++++++++++++ src/clients/janus/LicenseManager/types.ts | 8 +++ 2 files changed, 78 insertions(+) diff --git a/src/clients/janus/LicenseManager/index.ts b/src/clients/janus/LicenseManager/index.ts index 6076a9dfa..ab6829993 100644 --- a/src/clients/janus/LicenseManager/index.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -9,6 +9,8 @@ import { Addr, APICreateBindingRes, OptionsDeleteBinding, + OptionsUpdateBinding, + APIBindingUpdate, } from './types' const TWO_MINUTES_S = 2 * 60 @@ -23,6 +25,7 @@ const routes = { getBinding: (bindingId: string) => `${BASE_URL}/binding/${encodeURIComponent(bindingId)}`, createBinding: () => `${BASE_URL}/binding`, deleteBinding: (bindingId: string) => `${BASE_URL}/binding/${encodeURIComponent(bindingId)}`, + updateBinding: (bindingId: string) => `${BASE_URL}/binding/${bindingId}`, } export class LicenseManager extends JanusClient { @@ -190,4 +193,71 @@ export class LicenseManager extends JanusClient { }, }) } + + public updateBinding = ( + { + tenant, + adminUserAuthToken, + bindingId, + defaultLocale, + supportedLocales, + salesChannelId, + addrs, + canonicalAddr, + }: OptionsUpdateBinding, + config?: RequestConfig + ) => { + const metric = 'lm-update-binding' + + if (addrs.length === 0) { + throw new Error('A binding must have at least one address') + } + + const canonicalAddrExists = addrs.some( + (addr) => canonicalAddr.host === addr.host && canonicalAddr.path === addr.path + ) + + if (!canonicalAddrExists) { + throw new Error('The canonical address must exist within the address list') + } + + if (supportedLocales.length === 0) { + throw new Error('A binding must have at least one locale') + } + + const defaultLocaleExists = supportedLocales.some((locale) => defaultLocale === locale) + + if (!defaultLocaleExists) { + throw new Error('The default locale must exist within the supported locales') + } + + const bindingObj: APIBindingUpdate = { + Id: bindingId, + SiteName: tenant, + DefaultLocale: defaultLocale, + SupportedLocales: supportedLocales, + DefaultSalesChannelId: salesChannelId, + Addresses: addrs.map((addr: Addr) => ({ + Host: addr.host, + BasePath: addr.path, + IsCanonical: canonicalAddr.host === addr.host && canonicalAddr.path === addr.path, + Localization: { + '': defaultLocale, + }, + })), + } + + return this.http.put(routes.updateBinding(bindingId), bindingObj, { + inflightKey: inflightUrlWithQuery, + metric, + headers: { + VtexIdclientAutCookie: adminUserAuthToken, + }, + ...config, + tracing: { + requestSpanNameSuffix: metric, + ...config?.tracing, + }, + }) + } } diff --git a/src/clients/janus/LicenseManager/types.ts b/src/clients/janus/LicenseManager/types.ts index 66cbf5a1b..9d2e3fbd0 100644 --- a/src/clients/janus/LicenseManager/types.ts +++ b/src/clients/janus/LicenseManager/types.ts @@ -28,6 +28,10 @@ export interface OptionsCreateBinding { canonicalAddr: Addr } +export interface OptionsUpdateBinding extends OptionsCreateBinding { + bindingId: string +} + export interface APIAddress { Host: string IsCanonical: boolean @@ -45,6 +49,10 @@ export interface APIBindingCreate { SupportedLocales: string[] } +export interface APIBindingUpdate extends APIBindingCreate { + Id: string +} + export interface APIBindingRes extends APIBindingCreate { Id: string } From 87313d8a23242c1b20da3ca32d18e46d626c4da4 Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 22:06:59 -0300 Subject: [PATCH 12/14] chore(LicenseManager): fix types --- src/clients/janus/LicenseManager/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clients/janus/LicenseManager/index.ts b/src/clients/janus/LicenseManager/index.ts index ab6829993..ce7920a25 100644 --- a/src/clients/janus/LicenseManager/index.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -97,7 +97,7 @@ export class LicenseManager extends JanusClient { public getBinding = ({ adminUserAuthToken, bindingId }: OptionsGetBinding, config?: RequestConfig) => { const metric = 'lm-get-binding' - return this.http.get(routes.getBinding(bindingId), { + return this.http.get(routes.getBinding(bindingId), { inflightKey: inflightUrlWithQuery, memoizeable: true, metric, @@ -163,7 +163,7 @@ export class LicenseManager extends JanusClient { })), } - return this.http.post(routes.createBinding(), bindingObj, { + return this.http.post(routes.createBinding(), bindingObj, { inflightKey: inflightUrlWithQuery, metric, headers: { From 299a391fe2e9fafb72343012c29c8b082579e85f Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 27 Oct 2025 22:13:35 -0300 Subject: [PATCH 13/14] chore(LicenseManager): refactor to use input assertion abstraction --- .../LicenseManager/assertBindingInput.ts | 25 +++++++ src/clients/janus/LicenseManager/index.ts | 74 +++---------------- 2 files changed, 37 insertions(+), 62 deletions(-) create mode 100644 src/clients/janus/LicenseManager/assertBindingInput.ts diff --git a/src/clients/janus/LicenseManager/assertBindingInput.ts b/src/clients/janus/LicenseManager/assertBindingInput.ts new file mode 100644 index 000000000..b0dba6d21 --- /dev/null +++ b/src/clients/janus/LicenseManager/assertBindingInput.ts @@ -0,0 +1,25 @@ +import { OptionsCreateBinding } from './types' + +const assertBindingInput = ({ addrs, canonicalAddr, supportedLocales, defaultLocale }: OptionsCreateBinding) => { + if (addrs.length === 0) { + throw new Error('A binding must have at least one address') + } + + const canonicalAddrExists = addrs.some((addr) => canonicalAddr.host === addr.host && canonicalAddr.path === addr.path) + + if (!canonicalAddrExists) { + throw new Error('The canonical address must exist within the address list') + } + + if (supportedLocales.length === 0) { + throw new Error('A binding must have at least one locale') + } + + const defaultLocaleExists = supportedLocales.some((locale) => defaultLocale === locale) + + if (!defaultLocaleExists) { + throw new Error('The default locale must exist within the supported locales') + } +} + +export default assertBindingInput diff --git a/src/clients/janus/LicenseManager/index.ts b/src/clients/janus/LicenseManager/index.ts index ce7920a25..c55965fc3 100644 --- a/src/clients/janus/LicenseManager/index.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -1,5 +1,6 @@ import { RequestTracingConfig, RequestConfig, inflightUrlWithQuery } from '../../../HttpClient' import { JanusClient } from '../JanusClient' +import assertBindingInput from './assertBindingInput' import { OptionsListBindings, APIBindingRes, @@ -112,41 +113,12 @@ export class LicenseManager extends JanusClient { }) } - public createBinding = ( - { - tenant, - adminUserAuthToken, - defaultLocale, - supportedLocales, - salesChannelId, - addrs, - canonicalAddr, - }: OptionsCreateBinding, - config?: RequestConfig - ) => { - const metric = 'lm-create-binding' - - if (addrs.length === 0) { - throw new Error('A binding must have at least one address') - } - - const canonicalAddrExists = addrs.some( - (addr) => canonicalAddr.host === addr.host && canonicalAddr.path === addr.path - ) - - if (!canonicalAddrExists) { - throw new Error('The canonical address must exist within the address list') - } - - if (supportedLocales.length === 0) { - throw new Error('A binding must have at least one locale') - } - - const defaultLocaleExists = supportedLocales.some((locale) => defaultLocale === locale) + public createBinding = (options: OptionsCreateBinding, config?: RequestConfig) => { + assertBindingInput(options) - if (!defaultLocaleExists) { - throw new Error('The default locale must exist within the supported locales') - } + const metric = 'lm-create-binding' + const { tenant, adminUserAuthToken, defaultLocale, supportedLocales, salesChannelId, addrs, canonicalAddr } = + options const bindingObj: APIBindingCreate = { SiteName: tenant, @@ -194,8 +166,11 @@ export class LicenseManager extends JanusClient { }) } - public updateBinding = ( - { + public updateBinding = (options: OptionsUpdateBinding, config?: RequestConfig) => { + assertBindingInput(options) + + const metric = 'lm-update-binding' + const { tenant, adminUserAuthToken, bindingId, @@ -204,32 +179,7 @@ export class LicenseManager extends JanusClient { salesChannelId, addrs, canonicalAddr, - }: OptionsUpdateBinding, - config?: RequestConfig - ) => { - const metric = 'lm-update-binding' - - if (addrs.length === 0) { - throw new Error('A binding must have at least one address') - } - - const canonicalAddrExists = addrs.some( - (addr) => canonicalAddr.host === addr.host && canonicalAddr.path === addr.path - ) - - if (!canonicalAddrExists) { - throw new Error('The canonical address must exist within the address list') - } - - if (supportedLocales.length === 0) { - throw new Error('A binding must have at least one locale') - } - - const defaultLocaleExists = supportedLocales.some((locale) => defaultLocale === locale) - - if (!defaultLocaleExists) { - throw new Error('The default locale must exist within the supported locales') - } + } = options const bindingObj: APIBindingUpdate = { Id: bindingId, From fe4d898fc8ec977a5e43ec23fa067ee7c46f9465 Mon Sep 17 00:00:00 2001 From: Rafael Date: Wed, 29 Oct 2025 14:02:58 -0300 Subject: [PATCH 14/14] fix(LicenseManager): URI component was not encoded --- src/clients/janus/LicenseManager/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clients/janus/LicenseManager/index.ts b/src/clients/janus/LicenseManager/index.ts index c55965fc3..578164246 100644 --- a/src/clients/janus/LicenseManager/index.ts +++ b/src/clients/janus/LicenseManager/index.ts @@ -26,7 +26,7 @@ const routes = { getBinding: (bindingId: string) => `${BASE_URL}/binding/${encodeURIComponent(bindingId)}`, createBinding: () => `${BASE_URL}/binding`, deleteBinding: (bindingId: string) => `${BASE_URL}/binding/${encodeURIComponent(bindingId)}`, - updateBinding: (bindingId: string) => `${BASE_URL}/binding/${bindingId}`, + updateBinding: (bindingId: string) => `${BASE_URL}/binding/${encodeURIComponent(bindingId)}`, } export class LicenseManager extends JanusClient {