@vtex/api 7.3.1-beta.0 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [7.4.0] - 2026-06-22
11
+ ### Changed
12
+ - Renamed the base `IOClients` Janus Catalog getter from `catalogSystem` to
13
+ `janusCatalogSystem` to avoid a name collision with apps that already define
14
+ their own `catalogSystem` client (e.g. vtex-apps/promotion-cloner).
15
+ ### Added
16
+ - Base `IOClients` getter `janusCatalogSystem` (Janus Catalog) and
17
+ `licenseManager.listBindings`, plus binding-mapping helpers
18
+ (getCanonicalAndAlternateAddresses, inferTargetProduct) used by the
19
+ Tenant API migration.
20
+
21
+ ## [7.3.1] - 2026-01-06
22
+
23
+ ### Added
24
+ - OpenTelemetry context-based base attributes to DiagnosticsMetrics
25
+
26
+ ### Fixed
27
+ - Merge request context attributes with custom metrics - custom metrics now automatically include request-scoped base attributes (account, route_id, status_code, etc.) using OpenTelemetry Context API
28
+
29
+ ## [7.3.0] - 2025-12-16
30
+ ### Changed
31
+ - Update temporality to delta in metrics client
32
+ - New deploy pipeline with npm publish flow
33
+
34
+ ### Fixed
35
+ - Fix account attribute to diagnostics metrics
36
+
10
37
  ## [7.2.9-beta.1] - 2025-12-12
11
38
  ### Changed
12
39
  - Increase maximum attributes limit for diagnostics metrics
package/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # VTEX IO API Client for Node
2
2
 
3
+
3
4
  This library enables developers to quickly integrate with the VTEX IO APIs and create full fledged node services using VTEX IO.
4
5
 
5
6
  [![Build Status](https://travis-ci.org/vtex/node-vtex-api.svg?branch=master)](https://travis-ci.org/vtex/node-vtex-api)
@@ -63,3 +64,5 @@ export const example = async (ctx: Context, next: () => Promise<void>) => {
63
64
  Now, when you get a workspace up and running for your app with `vtex link`, you'll have this package linked as well.
64
65
 
65
66
  > When done developing, don't forget to unlink it from `<your-app>/node`: `yarn unlink @vtex/api`
67
+
68
+ <!-- Test PR to validate SonarQube configuration -->
@@ -5,7 +5,7 @@ import { CatalogGraphQL } from './apps/catalogGraphQL/index';
5
5
  import { ID, MasterData, PaymentProvider } from './external';
6
6
  import { Apps, Assets, BillingMetrics, Events, Registry, Router, VBase, Workspaces } from './infra';
7
7
  import { IOClientConstructor } from './IOClient';
8
- import { LicenseManager, Segment, Session, TenantClient } from './janus';
8
+ import { LicenseManager, Segment, Session, TenantClient, Catalog } from './janus';
9
9
  export type ClientsImplementation<T extends IOClients> = new (clientOptions: Record<string, InstanceOptions>, ctx: IOContext) => T;
10
10
  export declare class IOClients {
11
11
  private clientOptions;
@@ -31,6 +31,7 @@ export declare class IOClients {
31
31
  get vbase(): VBase;
32
32
  get workspaces(): Workspaces;
33
33
  get catalogGraphQL(): CatalogGraphQL;
34
+ get janusCatalogSystem(): Catalog;
34
35
  get paymentProvider(): PaymentProvider;
35
36
  protected getOrSet<TClient extends IOClientConstructor>(key: string, Implementation: TClient): InstanceType<TClient>;
36
37
  }
@@ -69,6 +69,9 @@ class IOClients {
69
69
  get catalogGraphQL() {
70
70
  return this.getOrSet('catalogGraphQL', index_1.CatalogGraphQL);
71
71
  }
72
+ get janusCatalogSystem() {
73
+ return this.getOrSet('janusCatalogSystem', janus_1.Catalog);
74
+ }
72
75
  get paymentProvider() {
73
76
  return this.getOrSet('paymentProvider', external_1.PaymentProvider);
74
77
  }
@@ -0,0 +1,7 @@
1
+ import { RequestConfig } from '../../../HttpClient';
2
+ import { JanusClient } from '../JanusClient';
3
+ import { SalesChannel } from './types';
4
+ export declare class Catalog extends JanusClient {
5
+ getSalesChannel(id: number, config?: RequestConfig): Promise<SalesChannel>;
6
+ getDefaultSalesChannel(config?: RequestConfig): Promise<SalesChannel>;
7
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Catalog = void 0;
4
+ const HttpClient_1 = require("../../../HttpClient");
5
+ const JanusClient_1 = require("../JanusClient");
6
+ const BASE_URL = '/api/catalog_system';
7
+ const routes = {
8
+ salesChannel: (salesChannelId) => `${BASE_URL}/pub/saleschannel/${salesChannelId}`,
9
+ defaultSalesChannel: () => `${BASE_URL}/pub/saleschannel/default`,
10
+ };
11
+ class Catalog extends JanusClient_1.JanusClient {
12
+ getSalesChannel(id, config) {
13
+ const metric = 'catalog-saleschannel';
14
+ return this.http.get(routes.salesChannel(id), {
15
+ inflightKey: HttpClient_1.inflightUrlWithQuery,
16
+ metric,
17
+ ...config,
18
+ tracing: {
19
+ requestSpanNameSuffix: metric,
20
+ ...config === null || config === void 0 ? void 0 : config.tracing,
21
+ },
22
+ });
23
+ }
24
+ getDefaultSalesChannel(config) {
25
+ const metric = 'catalog-saleschannel-default';
26
+ return this.http.get(routes.defaultSalesChannel(), {
27
+ inflightKey: HttpClient_1.inflightUrlWithQuery,
28
+ metric,
29
+ ...config,
30
+ tracing: {
31
+ requestSpanNameSuffix: metric,
32
+ ...config === null || config === void 0 ? void 0 : config.tracing,
33
+ },
34
+ });
35
+ }
36
+ }
37
+ exports.Catalog = Catalog;
@@ -0,0 +1,5 @@
1
+ export interface SalesChannel {
2
+ Id: number;
3
+ CultureInfo: string;
4
+ CurrencyCode: string;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +1,11 @@
1
- import { RequestTracingConfig } from '../../HttpClient';
2
- import { JanusClient } from './JanusClient';
1
+ import { RequestTracingConfig, RequestConfig } from '../../../HttpClient';
2
+ import { JanusClient } from '../JanusClient';
3
+ import { APIBindingRes } from './types';
4
+ export * from './types';
5
+ export * from './utils';
3
6
  export declare class LicenseManager extends JanusClient {
4
7
  getAccountData(VtexIdclientAutCookie: string, tracingConfig?: RequestTracingConfig): Promise<any>;
5
8
  getTopbarData(VtexIdclientAutCookie: string, tracingConfig?: RequestTracingConfig): Promise<any>;
6
9
  canAccessResource(VtexIdclientAutCookie: string, resourceKey: string, tracingConfig?: RequestTracingConfig): Promise<boolean>;
10
+ listBindings(tenant: string, config?: RequestConfig): Promise<APIBindingRes[]>;
7
11
  }
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.LicenseManager = void 0;
18
+ const HttpClient_1 = require("../../../HttpClient");
19
+ const JanusClient_1 = require("../JanusClient");
20
+ __exportStar(require("./types"), exports);
21
+ __exportStar(require("./utils"), exports);
22
+ const TWO_MINUTES_S = 2 * 60;
23
+ const BASE_URL = '/api/license-manager';
24
+ const routes = {
25
+ accountData: () => `${BASE_URL}/account`,
26
+ resourceAccess: (resourceKey) => `${BASE_URL}/resources/${encodeURIComponent(resourceKey)}/access`,
27
+ topbarData: () => `${BASE_URL}/site/pvt/newtopbar`,
28
+ listBindings: (tenant) => `${BASE_URL}/binding/site/${encodeURIComponent(tenant)}`,
29
+ };
30
+ class LicenseManager extends JanusClient_1.JanusClient {
31
+ getAccountData(VtexIdclientAutCookie, tracingConfig) {
32
+ const metric = 'lm-account-data';
33
+ return this.http.get(routes.accountData(), {
34
+ forceMaxAge: TWO_MINUTES_S,
35
+ headers: {
36
+ VtexIdclientAutCookie,
37
+ },
38
+ inflightKey: HttpClient_1.inflightUrlWithQuery,
39
+ metric,
40
+ tracing: {
41
+ requestSpanNameSuffix: metric,
42
+ ...tracingConfig === null || tracingConfig === void 0 ? void 0 : tracingConfig.tracing,
43
+ },
44
+ });
45
+ }
46
+ getTopbarData(VtexIdclientAutCookie, tracingConfig) {
47
+ const metric = 'lm-topbar-data';
48
+ return this.http.get(routes.topbarData(), {
49
+ headers: {
50
+ VtexIdclientAutCookie,
51
+ },
52
+ metric,
53
+ tracing: {
54
+ requestSpanNameSuffix: metric,
55
+ ...tracingConfig === null || tracingConfig === void 0 ? void 0 : tracingConfig.tracing,
56
+ },
57
+ });
58
+ }
59
+ canAccessResource(VtexIdclientAutCookie, resourceKey, tracingConfig) {
60
+ const metric = 'lm-resource-access';
61
+ return this.http
62
+ .get(routes.resourceAccess(resourceKey), {
63
+ headers: {
64
+ VtexIdclientAutCookie,
65
+ },
66
+ metric,
67
+ tracing: {
68
+ requestSpanNameSuffix: metric,
69
+ ...tracingConfig === null || tracingConfig === void 0 ? void 0 : tracingConfig.tracing,
70
+ },
71
+ })
72
+ .then(() => true, () => false);
73
+ }
74
+ listBindings(tenant, config) {
75
+ const metric = 'lm-list-bindings';
76
+ return this.http.get(routes.listBindings(tenant), {
77
+ inflightKey: HttpClient_1.inflightUrlWithQuery,
78
+ memoizeable: true,
79
+ metric,
80
+ headers: {
81
+ VtexIdclientAutCookie: this.context.authToken,
82
+ },
83
+ ...config,
84
+ tracing: {
85
+ requestSpanNameSuffix: metric,
86
+ ...config === null || config === void 0 ? void 0 : config.tracing,
87
+ },
88
+ });
89
+ }
90
+ }
91
+ exports.LicenseManager = LicenseManager;
@@ -0,0 +1,16 @@
1
+ export interface APIAddress {
2
+ Host: string;
3
+ IsCanonical: boolean;
4
+ BasePath: string;
5
+ Localization: {
6
+ [k: string]: string;
7
+ };
8
+ }
9
+ export interface APIBindingRes {
10
+ Id: string;
11
+ Addresses: APIAddress[];
12
+ SiteName: string;
13
+ DefaultSalesChannelId: number | null;
14
+ DefaultLocale: string;
15
+ SupportedLocales: string[];
16
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ import { APIBindingRes } from './types';
2
+ export declare const getCanonicalAndAlternateAddresses: (lmBinding: APIBindingRes) => {
3
+ canonicalBaseAddress: string;
4
+ alternateBaseAddresses: string[];
5
+ };
6
+ export declare const inferTargetProduct: (canonicalBaseAddress: string, alternateBaseAddresses: string[]) => 'vtex-admin' | 'vtex-storefront';
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.inferTargetProduct = exports.getCanonicalAndAlternateAddresses = void 0;
4
+ const buildAddressPath = (basePath, localizationKey) => {
5
+ if (basePath === '') {
6
+ return `/${localizationKey}`;
7
+ }
8
+ if (localizationKey === '') {
9
+ return `/${basePath}`;
10
+ }
11
+ return `/${basePath}/${localizationKey}`;
12
+ };
13
+ const getCanonicalAndAlternateAddresses = (lmBinding) => {
14
+ let canonicalBaseAddress = '';
15
+ const alternateBaseAddresses = [];
16
+ for (const addressEntry of lmBinding.Addresses) {
17
+ const localizationKeys = Object.keys(addressEntry.Localization);
18
+ for (const localizationKey of localizationKeys) {
19
+ alternateBaseAddresses.push(addressEntry.Host + buildAddressPath(addressEntry.BasePath, localizationKey));
20
+ }
21
+ if (addressEntry.IsCanonical) {
22
+ // The canonical address is built from the shortest localization key.
23
+ const [shortestLocalizationKey = ''] = [...localizationKeys].sort((a, b) => a.length - b.length);
24
+ canonicalBaseAddress = addressEntry.Host + buildAddressPath(addressEntry.BasePath, shortestLocalizationKey);
25
+ }
26
+ }
27
+ // The canonical address must not also appear in the alternates list.
28
+ const canonicalIndexInAlternates = alternateBaseAddresses.indexOf(canonicalBaseAddress);
29
+ if (canonicalIndexInAlternates !== -1) {
30
+ alternateBaseAddresses.splice(canonicalIndexInAlternates, 1);
31
+ }
32
+ return { canonicalBaseAddress, alternateBaseAddresses };
33
+ };
34
+ exports.getCanonicalAndAlternateAddresses = getCanonicalAndAlternateAddresses;
35
+ const inferTargetProduct = (canonicalBaseAddress, alternateBaseAddresses) => {
36
+ const isAdmin = canonicalBaseAddress.endsWith('myvtex.com/admin') ||
37
+ alternateBaseAddresses.some(address => address.endsWith('myvtex.com/admin'));
38
+ return isAdmin ? 'vtex-admin' : 'vtex-storefront';
39
+ };
40
+ exports.inferTargetProduct = inferTargetProduct;
@@ -3,3 +3,4 @@ export * from './LicenseManager';
3
3
  export * from './Segment';
4
4
  export * from './Session';
5
5
  export * from './Tenant';
6
+ export * from './Catalog';
@@ -19,3 +19,4 @@ __exportStar(require("./LicenseManager"), exports);
19
19
  __exportStar(require("./Segment"), exports);
20
20
  __exportStar(require("./Session"), exports);
21
21
  __exportStar(require("./Tenant"), exports);
22
+ __exportStar(require("./Catalog"), exports);
@@ -11,7 +11,7 @@ const constants_1 = require("../constants");
11
11
  *
12
12
  * Total attributes sent = base attributes + custom attributes (up to MAX_CUSTOM_ATTRIBUTES)
13
13
  */
14
- const MAX_CUSTOM_ATTRIBUTES = 5;
14
+ const MAX_CUSTOM_ATTRIBUTES = 7;
15
15
  /**
16
16
  * Context key for storing base attributes in OpenTelemetry context.
17
17
  * These attributes are automatically merged with custom attributes in all metric methods.
@@ -1,8 +1,8 @@
1
1
  import { Types } from '@vtex/diagnostics-nodejs';
2
2
  export declare const RequestsMetricLabels: {
3
- readonly STATUS_CODE: "status_code";
4
- readonly REQUEST_HANDLER: "handler";
5
3
  readonly ACCOUNT_NAME: "vtex.account.name";
4
+ readonly REQUEST_HANDLER: "handler";
5
+ readonly STATUS_CODE: "status_code";
6
6
  };
7
7
  export interface OtelRequestInstruments {
8
8
  concurrentRequests: Types.Gauge;
@@ -1,56 +1,56 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getOtelInstruments = exports.RequestsMetricLabels = void 0;
4
- const client_1 = require("./client");
5
4
  const constants_1 = require("../../constants");
5
+ const client_1 = require("./client");
6
6
  exports.RequestsMetricLabels = {
7
- STATUS_CODE: 'status_code',
8
- REQUEST_HANDLER: 'handler',
9
7
  ACCOUNT_NAME: constants_1.AttributeKeys.VTEX_ACCOUNT_NAME,
8
+ REQUEST_HANDLER: 'handler',
9
+ STATUS_CODE: 'status_code',
10
10
  };
11
11
  const createOtelConcurrentRequestsInstrument = async () => {
12
12
  const metricsClient = await (0, client_1.getMetricClient)();
13
13
  return metricsClient.createGauge('io_http_requests_current', {
14
14
  description: 'The current number of requests in course.',
15
- unit: '1'
15
+ unit: '1',
16
16
  });
17
17
  };
18
18
  const createOtelRequestsTimingsInstrument = async () => {
19
19
  const metricsClient = await (0, client_1.getMetricClient)();
20
20
  return metricsClient.createHistogram('runtime_http_requests_duration_milliseconds', {
21
21
  description: 'The incoming http requests total duration.',
22
- unit: 'ms'
22
+ unit: 'ms',
23
23
  });
24
24
  };
25
25
  const createOtelTotalRequestsInstrument = async () => {
26
26
  const metricsClient = await (0, client_1.getMetricClient)();
27
27
  return metricsClient.createCounter('runtime_http_requests_total', {
28
28
  description: 'The total number of HTTP requests.',
29
- unit: '1'
29
+ unit: '1',
30
30
  });
31
31
  };
32
32
  const createOtelRequestsResponseSizesInstrument = async () => {
33
33
  const metricsClient = await (0, client_1.getMetricClient)();
34
34
  return metricsClient.createHistogram('runtime_http_response_size_bytes', {
35
35
  description: 'The outgoing response sizes (only applicable when the response isn\'t a stream).',
36
- unit: 'bytes'
36
+ unit: 'bytes',
37
37
  });
38
38
  };
39
39
  const createOtelTotalAbortedRequestsInstrument = async () => {
40
40
  const metricsClient = await (0, client_1.getMetricClient)();
41
41
  return metricsClient.createCounter('runtime_http_aborted_requests_total', {
42
42
  description: 'The total number of HTTP requests aborted.',
43
- unit: '1'
43
+ unit: '1',
44
44
  });
45
45
  };
46
46
  class OtelInstrumentsSingleton {
47
- constructor() { }
48
47
  static getInstance() {
49
48
  if (!OtelInstrumentsSingleton.instance) {
50
49
  OtelInstrumentsSingleton.instance = new OtelInstrumentsSingleton();
51
50
  }
52
51
  return OtelInstrumentsSingleton.instance;
53
52
  }
53
+ constructor() { }
54
54
  async getInstruments() {
55
55
  if (this.instruments) {
56
56
  return this.instruments;
@@ -73,19 +73,19 @@ class OtelInstrumentsSingleton {
73
73
  }
74
74
  }
75
75
  async initializeInstruments() {
76
- const [concurrentRequests, requestTimings, totalRequests, responseSizes, abortedRequests] = await Promise.all([
76
+ const [concurrentRequests, requestTimings, totalRequests, responseSizes, abortedRequests,] = await Promise.all([
77
77
  createOtelConcurrentRequestsInstrument(),
78
78
  createOtelRequestsTimingsInstrument(),
79
79
  createOtelTotalRequestsInstrument(),
80
80
  createOtelRequestsResponseSizesInstrument(),
81
- createOtelTotalAbortedRequestsInstrument()
81
+ createOtelTotalAbortedRequestsInstrument(),
82
82
  ]);
83
83
  return {
84
+ abortedRequests,
84
85
  concurrentRequests,
85
86
  requestTimings,
86
- totalRequests,
87
87
  responseSizes,
88
- abortedRequests
88
+ totalRequests,
89
89
  };
90
90
  }
91
91
  }
@@ -11,7 +11,7 @@ const addOtelRequestMetricsMiddleware = () => {
11
11
  try {
12
12
  return await Promise.race([
13
13
  (0, metrics_1.getOtelInstruments)(),
14
- new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout waiting for OpenTelemetry instruments initialization')), INSTRUMENTS_INITIALIZATION_TIMEOUT))
14
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout waiting for OpenTelemetry instruments initialization')), INSTRUMENTS_INITIALIZATION_TIMEOUT)),
15
15
  ]);
16
16
  }
17
17
  catch (error) {
@@ -1,12 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resetTelemetry = exports.initializeTelemetry = void 0;
4
+ const instrumentation_koa_1 = require("@opentelemetry/instrumentation-koa");
4
5
  const diagnostics_nodejs_1 = require("@vtex/diagnostics-nodejs");
5
6
  const constants_1 = require("../../constants");
6
- const instrumentation_koa_1 = require("@opentelemetry/instrumentation-koa");
7
7
  const hostMetrics_1 = require("../metrics/instruments/hostMetrics");
8
8
  const APPLICATION_ID = constants_1.APP.ID || 'vtex-io-app';
9
9
  class TelemetryClientSingleton {
10
+ static getInstance() {
11
+ if (!TelemetryClientSingleton.instance) {
12
+ TelemetryClientSingleton.instance = new TelemetryClientSingleton();
13
+ }
14
+ return TelemetryClientSingleton.instance;
15
+ }
10
16
  constructor() {
11
17
  this.initializationPromise = undefined;
12
18
  this.initializeTracesClient = async (telemetryClient) => await telemetryClient.newTracesClient({
@@ -18,8 +24,8 @@ class TelemetryClientSingleton {
18
24
  exporter: diagnostics_nodejs_1.Exporters.CreateExporter(diagnostics_nodejs_1.Exporters.CreateMetricsExporterConfig({
19
25
  endpoint: constants_1.OTEL_EXPORTER_OTLP_ENDPOINT,
20
26
  interval: 60,
21
- timeoutSeconds: 60,
22
27
  temporality: 'delta',
28
+ timeoutSeconds: 60,
23
29
  }), 'otlp'),
24
30
  });
25
31
  this.initializeLogsClient = async (telemetryClient) => await telemetryClient.newLogsClient({
@@ -29,17 +35,23 @@ class TelemetryClientSingleton {
29
35
  loggerName: `node-vtex-api-${APPLICATION_ID}`,
30
36
  });
31
37
  }
32
- static getInstance() {
33
- if (!TelemetryClientSingleton.instance) {
34
- TelemetryClientSingleton.instance = new TelemetryClientSingleton();
38
+ async getTelemetryClients() {
39
+ if (this.telemetryClients) {
40
+ return this.telemetryClients;
35
41
  }
36
- return TelemetryClientSingleton.instance;
42
+ if (this.initializationPromise) {
43
+ return this.initializationPromise;
44
+ }
45
+ this.initializationPromise = this.initializeTelemetryClients();
46
+ return this.initializationPromise;
47
+ }
48
+ reset() {
49
+ this.telemetryClients = undefined;
50
+ this.initializationPromise = undefined;
37
51
  }
38
52
  async initializeTelemetryClients() {
39
53
  try {
40
54
  const telemetryClient = await (0, diagnostics_nodejs_1.NewTelemetryClient)(constants_1.DK_APP_ID, 'node-vtex-api', APPLICATION_ID, {
41
- // Use built-in no-op functionality when telemetry is disabled
42
- noop: !constants_1.DIAGNOSTICS_TELEMETRY_ENABLED,
43
55
  additionalAttrs: {
44
56
  [constants_1.AttributeKeys.VTEX_IO_APP_ID]: APPLICATION_ID,
45
57
  'vendor': constants_1.APP.VENDOR,
@@ -47,6 +59,8 @@ class TelemetryClientSingleton {
47
59
  [constants_1.AttributeKeys.VTEX_IO_WORKSPACE_NAME]: constants_1.WORKSPACE,
48
60
  [constants_1.AttributeKeys.VTEX_IO_WORKSPACE_TYPE]: constants_1.PRODUCTION ? 'production' : 'development',
49
61
  },
62
+ // Use built-in no-op functionality when telemetry is disabled
63
+ noop: !constants_1.DIAGNOSTICS_TELEMETRY_ENABLED,
50
64
  });
51
65
  const [tracesClient, metricsClient, logsClient] = await Promise.all([
52
66
  this.initializeTracesClient(telemetryClient),
@@ -59,8 +73,8 @@ class TelemetryClientSingleton {
59
73
  ...diagnostics_nodejs_1.Instrumentation.CommonInstrumentations.minimal(),
60
74
  new instrumentation_koa_1.KoaInstrumentation(),
61
75
  new hostMetrics_1.HostMetricsInstrumentation({
62
- name: 'host-metrics-instrumentation',
63
76
  meterProvider: metricsClient.provider(),
77
+ name: 'host-metrics-instrumentation',
64
78
  }),
65
79
  ];
66
80
  telemetryClient.registerInstrumentations(instrumentations);
@@ -81,20 +95,6 @@ class TelemetryClientSingleton {
81
95
  this.initializationPromise = undefined;
82
96
  }
83
97
  }
84
- async getTelemetryClients() {
85
- if (this.telemetryClients) {
86
- return this.telemetryClients;
87
- }
88
- if (this.initializationPromise) {
89
- return this.initializationPromise;
90
- }
91
- this.initializationPromise = this.initializeTelemetryClients();
92
- return this.initializationPromise;
93
- }
94
- reset() {
95
- this.telemetryClients = undefined;
96
- this.initializationPromise = undefined;
97
- }
98
98
  }
99
99
  async function initializeTelemetry() {
100
100
  return TelemetryClientSingleton.getInstance().getTelemetryClients();
@@ -14,8 +14,8 @@ const constants_1 = require("../../constants");
14
14
  const loaders_1 = require("../loaders");
15
15
  const console_1 = require("../logger/console");
16
16
  const loggerTypes_1 = require("../logger/loggerTypes");
17
- const requestMetricsMiddleware_1 = require("../metrics/requestMetricsMiddleware");
18
17
  const otelRequestMetricsMiddleware_1 = require("../metrics/otelRequestMetricsMiddleware");
18
+ const requestMetricsMiddleware_1 = require("../metrics/requestMetricsMiddleware");
19
19
  const TracerSingleton_1 = require("../tracing/TracerSingleton");
20
20
  const tracingMiddlewares_1 = require("../tracing/tracingMiddlewares");
21
21
  const listeners_1 = require("./listeners");
@@ -50,7 +50,7 @@ async function auth(ctx, authArgs) {
50
50
  }
51
51
  }
52
52
  function parseArgs(authArgs) {
53
- if (authArgs.scope == 'PUBLIC') {
53
+ if (authArgs.scope === 'PUBLIC') {
54
54
  return authArgs;
55
55
  }
56
56
  if (!authArgs.productCode || !authArgs.resourceCode) {
@@ -63,7 +63,7 @@ class Auth extends graphql_tools_1.SchemaDirectiveVisitor {
63
63
  const { resolve = graphql_1.defaultFieldResolver } = field;
64
64
  field.resolve = async (root, args, ctx, info) => {
65
65
  const authArgs = parseArgs(this.args);
66
- if (!authArgs.scope || authArgs.scope == 'PRIVATE') {
66
+ if (!authArgs.scope || authArgs.scope === 'PRIVATE') {
67
67
  await auth(ctx, authArgs);
68
68
  }
69
69
  return resolve(root, args, ctx, info);
@@ -61,8 +61,8 @@ async function timings(ctx, next) {
61
61
  // We only need to provide the response-specific attributes here
62
62
  if (global.diagnosticsMetrics) {
63
63
  const responseAttributes = {
64
- status_code: statusCode,
65
64
  status,
65
+ status_code: statusCode,
66
66
  };
67
67
  // Record latency histogram (record all requests, not just successful ones)
68
68
  global.diagnosticsMetrics.recordLatency(total, responseAttributes);
@@ -79,6 +79,7 @@ async function timings(ctx, next) {
79
79
  await global.diagnosticsMetrics.runWithBaseAttributes(baseAttributes, executeWithBaseAttributes);
80
80
  }
81
81
  else {
82
+ console.warn('DiagnosticsMetrics not available. HTTP handler metrics not reported.');
82
83
  await executeWithBaseAttributes();
83
84
  }
84
85
  }
@@ -3,7 +3,7 @@
3
3
  // It is used to build a full URL by combining a base URL with a relative URL.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  // It is originally not intended to be used directly, but rather as a utility function within the Axios library.
6
- // Since Axios 1.0, this function is not exported by default, and the team does not recommend using it directly,
6
+ // Since Axios 1.0, this function is not exported by default, and the team does not recommend using it directly,
7
7
  // as it may not be available in future versions.
8
8
  // The function takes a base URL and a relative URL as input, and returns the full URL.
9
9
  // It handles both absolute and relative URLs, and ensures that the resulting URL is properly formatted.
@@ -19,8 +19,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
19
19
  * @returns {string} The combined full path
20
20
  */
21
21
  function default_1(baseURL, requestedURL, allowAbsoluteUrls) {
22
- let isRelativeUrl = !isAbsoluteURL(requestedURL);
23
- if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {
22
+ const isRelativeUrl = !isAbsoluteURL(requestedURL);
23
+ if (baseURL && (isRelativeUrl || allowAbsoluteUrls === false)) {
24
24
  return combineURLs(baseURL, requestedURL);
25
25
  }
26
26
  return requestedURL;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/api",
3
- "version": "7.3.1-beta.0",
3
+ "version": "7.4.0",
4
4
  "description": "VTEX I/O API client",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -19,7 +19,7 @@
19
19
  "format-lint": "yarn format && yarn lint",
20
20
  "prepublishOnly": "bash ./scripts/publishLock.sh",
21
21
  "ci:build": "yarn build && yarn gen",
22
- "ci:test": "yarn test --ci",
22
+ "ci:test": "yarn test --ci --coverage",
23
23
  "ci:prettier-check": "prettier --check --config ./.prettierrc \"src/**/*.ts\" \"src/**/*.js\""
24
24
  },
25
25
  "jest": {
@@ -1,59 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LicenseManager = void 0;
4
- const qs_1 = require("qs");
5
- const JanusClient_1 = require("./JanusClient");
6
- const TWO_MINUTES_S = 2 * 60;
7
- const BASE_URL = '/api/license-manager';
8
- const routes = {
9
- accountData: `${BASE_URL}/account`,
10
- resourceAccess: `${BASE_URL}/resources`,
11
- topbarData: `${BASE_URL}/site/pvt/newtopbar`,
12
- };
13
- const inflightKey = ({ baseURL, url, params }) => {
14
- return baseURL + url + (0, qs_1.stringify)(params, { arrayFormat: 'repeat', addQueryPrefix: true });
15
- };
16
- class LicenseManager extends JanusClient_1.JanusClient {
17
- getAccountData(VtexIdclientAutCookie, tracingConfig) {
18
- const metric = 'lm-account-data';
19
- return this.http.get(routes.accountData, {
20
- forceMaxAge: TWO_MINUTES_S,
21
- headers: {
22
- VtexIdclientAutCookie,
23
- },
24
- inflightKey,
25
- metric,
26
- tracing: {
27
- requestSpanNameSuffix: metric,
28
- ...tracingConfig === null || tracingConfig === void 0 ? void 0 : tracingConfig.tracing,
29
- },
30
- });
31
- }
32
- getTopbarData(VtexIdclientAutCookie, tracingConfig) {
33
- const metric = 'lm-topbar-data';
34
- return this.http.get(routes.topbarData, {
35
- headers: {
36
- VtexIdclientAutCookie,
37
- },
38
- metric,
39
- tracing: {
40
- requestSpanNameSuffix: metric,
41
- ...tracingConfig === null || tracingConfig === void 0 ? void 0 : tracingConfig.tracing,
42
- },
43
- });
44
- }
45
- canAccessResource(VtexIdclientAutCookie, resourceKey, tracingConfig) {
46
- const metric = 'lm-resource-access';
47
- return this.http.get(`${routes.resourceAccess}/${resourceKey}/access`, {
48
- headers: {
49
- VtexIdclientAutCookie,
50
- },
51
- metric,
52
- tracing: {
53
- requestSpanNameSuffix: metric,
54
- ...tracingConfig === null || tracingConfig === void 0 ? void 0 : tracingConfig.tracing,
55
- },
56
- }).then(() => true, () => false);
57
- }
58
- }
59
- exports.LicenseManager = LicenseManager;