@vtex/api 7.1.0-beta.0 → 7.1.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.
@@ -1,2 +1,2 @@
1
- export declare const startApp: () => Promise<void>;
1
+ export declare const startApp: () => void;
2
2
  export { appPath } from './loaders';
@@ -1,51 +1,25 @@
1
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
6
  exports.appPath = exports.startApp = void 0;
30
- const telemetry_1 = require("./telemetry");
31
7
  const cluster_1 = __importDefault(require("cluster"));
32
8
  const constants_1 = require("../constants");
33
9
  const loaders_1 = require("./loaders");
34
10
  const logger_1 = require("./logger");
35
- const startApp = async () => {
36
- await (0, telemetry_1.initializeTelemetry)();
11
+ const master_1 = require("./master");
12
+ const worker_1 = require("./worker");
13
+ const startApp = () => {
37
14
  const serviceJSON = (0, loaders_1.getServiceJSON)();
38
15
  try {
39
16
  // if it is a master process then call setting up worker process
40
17
  if (cluster_1.default.isMaster) {
41
- const { startMaster } = await Promise.resolve().then(() => __importStar(require('./master')));
42
- startMaster(serviceJSON);
18
+ (0, master_1.startMaster)(serviceJSON);
43
19
  }
44
20
  else {
45
21
  // to setup server configurations and share port address for incoming requests
46
- const { startWorker } = await Promise.resolve().then(() => __importStar(require('./worker')));
47
- const app = await startWorker(serviceJSON);
48
- app.listen(constants_1.HTTP_SERVER_PORT);
22
+ (0, worker_1.startWorker)(serviceJSON).listen(constants_1.HTTP_SERVER_PORT);
49
23
  }
50
24
  }
51
25
  catch (err) {
@@ -3,8 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resetTelemetry = exports.initializeTelemetry = void 0;
4
4
  const diagnostics_nodejs_1 = require("@vtex/diagnostics-nodejs");
5
5
  const constants_1 = require("../../constants");
6
- const instrumentation_koa_1 = require("@opentelemetry/instrumentation-koa");
7
- const hostMetrics_1 = require("../metrics/instruments/hostMetrics");
8
6
  const CLIENT_NAME = constants_1.APP.NAME || 'node-vtex-api';
9
7
  const APPLICATION_ID = constants_1.APP.ID || 'vtex-io-app';
10
8
  const EXPORTER_OTLP_ENDPOINT = process.env.EXPORTER_OTLP_ENDPOINT;
@@ -51,11 +49,6 @@ class TelemetryClientSingleton {
51
49
  ]);
52
50
  const instrumentations = [
53
51
  ...diagnostics_nodejs_1.Instrumentation.CommonInstrumentations.minimal(),
54
- new instrumentation_koa_1.KoaInstrumentation(),
55
- new hostMetrics_1.HostMetricsInstrumentation({
56
- name: 'host-metrics-instrumentation',
57
- meterProvider: metricsClient.provider(),
58
- }),
59
52
  ];
60
53
  telemetryClient.registerInstrumentations(instrumentations);
61
54
  const clients = {
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.startWorker = void 0;
7
- const diagnostics_nodejs_1 = require("@vtex/diagnostics-nodejs");
8
7
  const http_1 = require("http");
9
8
  const koa_1 = __importDefault(require("koa"));
10
9
  const koa_compress_1 = __importDefault(require("koa-compress"));
@@ -16,7 +15,6 @@ const loaders_1 = require("../loaders");
16
15
  const console_1 = require("../logger/console");
17
16
  const loggerTypes_1 = require("../logger/loggerTypes");
18
17
  const requestMetricsMiddleware_1 = require("../metrics/requestMetricsMiddleware");
19
- const otelRequestMetricsMiddleware_1 = require("../metrics/otelRequestMetricsMiddleware");
20
18
  const TracerSingleton_1 = require("../tracing/TracerSingleton");
21
19
  const tracingMiddlewares_1 = require("../tracing/tracingMiddlewares");
22
20
  const listeners_1 = require("./listeners");
@@ -159,11 +157,9 @@ const startWorker = (serviceJSON) => {
159
157
  app.proxy = true;
160
158
  app
161
159
  .use(error_1.error)
162
- .use(diagnostics_nodejs_1.Instrumentation.Middlewares.ContextMiddlewares.Koa.ContextPropagationMiddleware())
163
160
  .use((0, middlewares_1.prometheusLoggerMiddleware)())
164
161
  .use((0, tracingMiddlewares_1.addTracingMiddleware)(tracer))
165
162
  .use((0, requestMetricsMiddleware_1.addRequestMetricsMiddleware)())
166
- .use((0, otelRequestMetricsMiddleware_1.addOtelRequestMetricsMiddleware)())
167
163
  .use((0, middlewares_1.addMetricsLoggerMiddleware)())
168
164
  .use((0, rateLimit_1.concurrentRateLimiter)((_a = serviceJSON === null || serviceJSON === void 0 ? void 0 : serviceJSON.rateLimitPerReplica) === null || _a === void 0 ? void 0 : _a.concurrent))
169
165
  .use((0, koa_compress_1.default)())
@@ -3,4 +3,4 @@ import { SchemaDirectiveVisitor } from 'graphql-tools';
3
3
  export declare class Auth extends SchemaDirectiveVisitor {
4
4
  visitFieldDefinition(field: GraphQLField<any, any>): void;
5
5
  }
6
- export declare const authDirectiveTypeDefs = "\ndirective @auth(\n productCode: String\n resourceCode: String\n) on FIELD_DEFINITION\n";
6
+ export declare const authDirectiveTypeDefs = "\n\nenum IOAuthScope {\n PUBLIC\n PRIVATE\n}\n\ndirective @auth(\n scope: IOAuthScope\n productCode: String\n resourceCode: String\n) on FIELD_DEFINITION\n";
@@ -50,8 +50,11 @@ async function auth(ctx, authArgs) {
50
50
  }
51
51
  }
52
52
  function parseArgs(authArgs) {
53
+ if (authArgs.scope == 'PUBLIC') {
54
+ return authArgs;
55
+ }
53
56
  if (!authArgs.productCode || !authArgs.resourceCode) {
54
- throw new apollo_server_errors_1.UserInputError('Invalid auth schema directive args. Usage: @auth(productCode: String, resourceCode: String).');
57
+ throw new apollo_server_errors_1.UserInputError('Invalid auth schema directive args. Usage: @auth(scope: IOAuthScope, productCode: String, resourceCode: String).');
55
58
  }
56
59
  return authArgs;
57
60
  }
@@ -60,14 +63,23 @@ class Auth extends graphql_tools_1.SchemaDirectiveVisitor {
60
63
  const { resolve = graphql_1.defaultFieldResolver } = field;
61
64
  field.resolve = async (root, args, ctx, info) => {
62
65
  const authArgs = parseArgs(this.args);
63
- await auth(ctx, authArgs);
66
+ if (!authArgs.scope || authArgs.scope == 'PRIVATE') {
67
+ await auth(ctx, authArgs);
68
+ }
64
69
  return resolve(root, args, ctx, info);
65
70
  };
66
71
  }
67
72
  }
68
73
  exports.Auth = Auth;
69
74
  exports.authDirectiveTypeDefs = `
75
+
76
+ enum IOAuthScope {
77
+ PUBLIC
78
+ PRIVATE
79
+ }
80
+
70
81
  directive @auth(
82
+ scope: IOAuthScope
71
83
  productCode: String
72
84
  resourceCode: String
73
85
  ) on FIELD_DEFINITION
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/api",
3
- "version": "7.1.0-beta.0",
3
+ "version": "7.1.0",
4
4
  "description": "VTEX I/O API client",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -47,10 +47,6 @@
47
47
  },
48
48
  "license": "MIT",
49
49
  "dependencies": {
50
- "@opentelemetry/api": "^1.9.0",
51
- "@opentelemetry/host-metrics": "0.35.5",
52
- "@opentelemetry/instrumentation": "0.57.2",
53
- "@opentelemetry/instrumentation-koa": "0.47.1",
54
50
  "@types/koa": "^2.11.0",
55
51
  "@types/koa-compose": "^3.2.3",
56
52
  "@vtex/diagnostics-nodejs": "0.1.0-io-beta.19",
@@ -1,2 +0,0 @@
1
- import { Types } from "@vtex/diagnostics-nodejs";
2
- export declare function getMetricClient(): Promise<Types.MetricClient>;
@@ -1,35 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getMetricClient = void 0;
4
- const telemetry_1 = require("../telemetry");
5
- let client;
6
- let isInitializing = false;
7
- let initPromise = undefined;
8
- async function getMetricClient() {
9
- if (client) {
10
- return client;
11
- }
12
- if (initPromise) {
13
- return initPromise;
14
- }
15
- isInitializing = true;
16
- initPromise = initializeClient();
17
- return initPromise;
18
- }
19
- exports.getMetricClient = getMetricClient;
20
- async function initializeClient() {
21
- try {
22
- const { metricsClient } = await (0, telemetry_1.initializeTelemetry)();
23
- client = metricsClient;
24
- initPromise = undefined;
25
- return metricsClient;
26
- }
27
- catch (error) {
28
- console.error('Failed to initialize metrics client:', error);
29
- initPromise = undefined;
30
- throw error;
31
- }
32
- finally {
33
- isInitializing = false;
34
- }
35
- }
@@ -1,14 +0,0 @@
1
- import { InstrumentationBase, InstrumentationConfig } from "@opentelemetry/instrumentation";
2
- import { MeterProvider } from '@opentelemetry/api';
3
- interface HostMetricsInstrumentationConfig extends InstrumentationConfig {
4
- name?: string;
5
- meterProvider?: MeterProvider;
6
- }
7
- export declare class HostMetricsInstrumentation extends InstrumentationBase<HostMetricsInstrumentationConfig> {
8
- private hostMetrics?;
9
- constructor(config?: HostMetricsInstrumentationConfig);
10
- init(): void;
11
- enable(): void;
12
- disable(): void;
13
- }
14
- export {};
@@ -1,31 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HostMetricsInstrumentation = void 0;
4
- const instrumentation_1 = require("@opentelemetry/instrumentation");
5
- const host_metrics_1 = require("@opentelemetry/host-metrics");
6
- class HostMetricsInstrumentation extends instrumentation_1.InstrumentationBase {
7
- constructor(config = {}) {
8
- const instrumentation_name = config.name || 'host-metrics-instrumentation';
9
- const instrumentation_version = '1.0.0';
10
- super(instrumentation_name, instrumentation_version, config);
11
- }
12
- init() { }
13
- enable() {
14
- if (!this._config.meterProvider) {
15
- throw new Error('MeterProvider is required for HostMetricsInstrumentation');
16
- }
17
- this.hostMetrics = new host_metrics_1.HostMetrics({
18
- meterProvider: this._config.meterProvider,
19
- name: this._config.name || 'host-metrics',
20
- });
21
- this.hostMetrics.start();
22
- console.debug('HostMetricsInstrumentation enabled');
23
- }
24
- disable() {
25
- if (this.hostMetrics) {
26
- this.hostMetrics = undefined;
27
- console.debug('HostMetricsInstrumentation disabled');
28
- }
29
- }
30
- }
31
- exports.HostMetricsInstrumentation = HostMetricsInstrumentation;
@@ -1,13 +0,0 @@
1
- import { Types } from '@vtex/diagnostics-nodejs';
2
- export declare const enum RequestsMetricLabels {
3
- STATUS_CODE = "status_code",
4
- REQUEST_HANDLER = "handler"
5
- }
6
- export interface OtelRequestInstruments {
7
- concurrentRequests: Types.Gauge;
8
- requestTimings: Types.Histogram;
9
- totalRequests: Types.Counter;
10
- responseSizes: Types.Histogram;
11
- abortedRequests: Types.Counter;
12
- }
13
- export declare const getOtelInstruments: () => Promise<OtelRequestInstruments>;
@@ -1,74 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getOtelInstruments = void 0;
4
- const client_1 = require("./client");
5
- let instruments;
6
- let initializingPromise;
7
- const createOtelConcurrentRequestsInstrument = async () => {
8
- const metricsClient = await (0, client_1.getMetricClient)();
9
- return metricsClient.createGauge('io_http_requests_current', {
10
- description: 'The current number of requests in course.',
11
- unit: '1'
12
- });
13
- };
14
- const createOtelRequestsTimingsInstrument = async () => {
15
- const metricsClient = await (0, client_1.getMetricClient)();
16
- return metricsClient.createHistogram('runtime_http_requests_duration_milliseconds', {
17
- description: 'The incoming http requests total duration.',
18
- unit: 'ms'
19
- });
20
- };
21
- const createOtelTotalRequestsInstrument = async () => {
22
- const metricsClient = await (0, client_1.getMetricClient)();
23
- return metricsClient.createCounter('runtime_http_requests_total', {
24
- description: 'The total number of HTTP requests.',
25
- unit: '1'
26
- });
27
- };
28
- const createOtelRequestsResponseSizesInstrument = async () => {
29
- const metricsClient = await (0, client_1.getMetricClient)();
30
- return metricsClient.createHistogram('runtime_http_response_size_bytes', {
31
- description: 'The outgoing response sizes (only applicable when the response isn\'t a stream).',
32
- unit: 'bytes'
33
- });
34
- };
35
- const createOtelTotalAbortedRequestsInstrument = async () => {
36
- const metricsClient = await (0, client_1.getMetricClient)();
37
- return metricsClient.createCounter('runtime_http_aborted_requests_total', {
38
- description: 'The total number of HTTP requests aborted.',
39
- unit: '1'
40
- });
41
- };
42
- const getOtelInstruments = async () => {
43
- if (instruments) {
44
- return instruments;
45
- }
46
- if (initializingPromise) {
47
- return initializingPromise;
48
- }
49
- initializingPromise = initializeOtelInstruments();
50
- try {
51
- instruments = await initializingPromise;
52
- return instruments;
53
- }
54
- finally {
55
- initializingPromise = undefined;
56
- }
57
- };
58
- exports.getOtelInstruments = getOtelInstruments;
59
- const initializeOtelInstruments = async () => {
60
- const [concurrentRequests, requestTimings, totalRequests, responseSizes, abortedRequests] = await Promise.all([
61
- createOtelConcurrentRequestsInstrument(),
62
- createOtelRequestsTimingsInstrument(),
63
- createOtelTotalRequestsInstrument(),
64
- createOtelRequestsResponseSizesInstrument(),
65
- createOtelTotalAbortedRequestsInstrument()
66
- ]);
67
- return {
68
- concurrentRequests,
69
- requestTimings,
70
- totalRequests,
71
- responseSizes,
72
- abortedRequests
73
- };
74
- };
@@ -1,2 +0,0 @@
1
- import { ServiceContext } from '../worker/runtime/typings';
2
- export declare const addOtelRequestMetricsMiddleware: () => (ctx: ServiceContext, next: () => Promise<void>) => Promise<void>;
@@ -1,65 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.addOtelRequestMetricsMiddleware = void 0;
4
- const stream_1 = require("stream");
5
- const utils_1 = require("../../utils");
6
- const metrics_1 = require("./metrics");
7
- const INSTRUMENTS_INITIALIZATION_TIMEOUT = 500;
8
- const addOtelRequestMetricsMiddleware = () => {
9
- let instruments;
10
- return async function addOtelRequestMetrics(ctx, next) {
11
- if (!instruments) {
12
- try {
13
- instruments = await Promise.race([
14
- (0, metrics_1.getOtelInstruments)(),
15
- new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout waiting for OpenTelemetry instruments initialization')), INSTRUMENTS_INITIALIZATION_TIMEOUT))
16
- ]);
17
- }
18
- catch (error) {
19
- const errorMessage = error instanceof Error ? error.message : String(error);
20
- console.warn(`OpenTelemetry instruments not ready for request ${ctx.requestHandlerName}: ${errorMessage}`);
21
- await next();
22
- return;
23
- }
24
- }
25
- const start = process.hrtime();
26
- instruments.concurrentRequests.add(1);
27
- ctx.req.once('aborted', () => {
28
- if (instruments) {
29
- instruments.abortedRequests.add(1, { ["handler" /* RequestsMetricLabels.REQUEST_HANDLER */]: ctx.requestHandlerName });
30
- }
31
- });
32
- let responseClosed = false;
33
- ctx.res.once('close', () => (responseClosed = true));
34
- try {
35
- await next();
36
- }
37
- finally {
38
- const responseLength = ctx.response.length;
39
- if (responseLength && instruments) {
40
- instruments.responseSizes.record(responseLength, { ["handler" /* RequestsMetricLabels.REQUEST_HANDLER */]: ctx.requestHandlerName });
41
- }
42
- if (instruments) {
43
- instruments.totalRequests.add(1, {
44
- ["handler" /* RequestsMetricLabels.REQUEST_HANDLER */]: ctx.requestHandlerName,
45
- ["status_code" /* RequestsMetricLabels.STATUS_CODE */]: ctx.response.status,
46
- });
47
- }
48
- const onResFinished = () => {
49
- if (instruments) {
50
- instruments.requestTimings.record((0, utils_1.hrToMillisFloat)(process.hrtime(start)), {
51
- ["handler" /* RequestsMetricLabels.REQUEST_HANDLER */]: ctx.requestHandlerName,
52
- });
53
- instruments.concurrentRequests.subtract(1);
54
- }
55
- };
56
- if (responseClosed) {
57
- onResFinished();
58
- }
59
- else {
60
- (0, stream_1.finished)(ctx.res, onResFinished);
61
- }
62
- }
63
- };
64
- };
65
- exports.addOtelRequestMetricsMiddleware = addOtelRequestMetricsMiddleware;