@faststore/api 1.12.41 → 1.12.43

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.
@@ -11,9 +11,18 @@ var crypto = _interopDefault(require('crypto'));
11
11
  var graphql = require('graphql');
12
12
  var language = require('graphql/language');
13
13
  var utils = require('@graphql-tools/utils');
14
+ var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
15
+ var resources = require('@opentelemetry/resources');
16
+ var exporterTraceOtlpGrpc = require('@opentelemetry/exporter-trace-otlp-grpc');
17
+ var sdkLogs = require('@opentelemetry/sdk-logs');
18
+ var exporterLogsOtlpGrpc = require('@opentelemetry/exporter-logs-otlp-grpc');
19
+ var core = require('@envelop/core');
20
+ var onResolve = require('@envelop/on-resolve');
21
+ var api = require('@opentelemetry/api');
22
+ var apiLogs = require('@opentelemetry/api-logs');
14
23
 
15
24
  var name = "@faststore/api";
16
- var version = "1.12.40";
25
+ var version = "1.12.42";
17
26
  var license = "MIT";
18
27
  var main = "dist/index.js";
19
28
  var typings = "dist/index.d.ts";
@@ -35,7 +44,12 @@ var scripts = {
35
44
  generate: "graphql-codegen --config codegen.yml"
36
45
  };
37
46
  var dependencies = {
47
+ "@envelop/on-resolve": "^2.0.6",
38
48
  "@graphql-tools/schema": "^8.2.0",
49
+ "@opentelemetry/exporter-logs-otlp-grpc": "^0.39.1",
50
+ "@opentelemetry/exporter-trace-otlp-grpc": "^0.39.1",
51
+ "@opentelemetry/sdk-logs": "^0.39.1",
52
+ "@opentelemetry/sdk-trace-base": "^1.13.0",
39
53
  "@rollup/plugin-graphql": "^1.0.0",
40
54
  dataloader: "^2.1.0",
41
55
  "fast-deep-equal": "^3.1.3",
@@ -43,6 +57,7 @@ var dependencies = {
43
57
  "p-limit": "^3.1.0"
44
58
  };
45
59
  var devDependencies = {
60
+ "@envelop/core": "^2.6.0",
46
61
  "@faststore/shared": "^1.12.37",
47
62
  "@graphql-codegen/cli": "2.2.0",
48
63
  "@graphql-codegen/typescript": "2.2.2",
@@ -57,6 +72,7 @@ var devDependencies = {
57
72
  typescript: "^4.4.2"
58
73
  };
59
74
  var peerDependencies = {
75
+ "@envelop/core": "^1 || ^2",
60
76
  graphql: "^15.6.0"
61
77
  };
62
78
  var packageJson = {
@@ -157,6 +173,14 @@ const VtexCommerce = ({
157
173
  id,
158
174
  body
159
175
  }) => {
176
+ if (body.selectedAddresses) {
177
+ body.selectedAddresses.forEach(address => {
178
+ if (address.geoCoordinates === null) {
179
+ address.geoCoordinates = [];
180
+ }
181
+ });
182
+ }
183
+
160
184
  return fetchAPI(`${base}/api/checkout/pub/orderForm/${id}/attachments/shippingData`, { ...BASE_INIT,
161
185
  body: JSON.stringify(body)
162
186
  });
@@ -2632,6 +2656,268 @@ const directive = {
2632
2656
  })
2633
2657
  };
2634
2658
 
2659
+ var AttributeName;
2660
+
2661
+ (function (AttributeName) {
2662
+ AttributeName["EXECUTION_ERROR"] = "graphql.error";
2663
+ AttributeName["EXECUTION_RESULT"] = "graphql.result";
2664
+ AttributeName["RESOLVER_EXECUTION_ERROR"] = "graphql.resolver.error";
2665
+ AttributeName["RESOLVER_EXCEPTION"] = "graphql.resolver.exception";
2666
+ AttributeName["RESOLVER_FIELD_NAME"] = "graphql.resolver.fieldName";
2667
+ AttributeName["RESOLVER_TYPE_NAME"] = "graphql.resolver.typeName";
2668
+ AttributeName["RESOLVER_RESULT_TYPE"] = "graphql.resolver.resultType";
2669
+ AttributeName["RESOLVER_ARGS"] = "graphql.resolver.args";
2670
+ AttributeName["EXECUTION_OPERATION_NAME"] = "graphql.operation.name";
2671
+ AttributeName["EXECUTION_OPERATION_TYPE"] = "graphql.operation.type";
2672
+ AttributeName["EXECUTION_OPERATION_DOCUMENT"] = "graphql.document";
2673
+ AttributeName["EXECUTION_VARIABLES"] = "graphql.variables";
2674
+ })(AttributeName || (AttributeName = {}));
2675
+
2676
+ const tracingSpanSymbol = /*#__PURE__*/Symbol('OPEN_TELEMETRY_GRAPHQL');
2677
+
2678
+ function getResolverSpanKey(path) {
2679
+ const nodes = []; // If the first node (after reversed, it will be the last one) is an integer, that is, identifies a list,
2680
+ // we don't want to include it in the key. Note that this will only happen when analysing .prev paths in
2681
+ // a list of elements. We just want to remove the initial node that is a integer, not all of them.
2682
+ //
2683
+ // Nodes with keys 6bc73341b2a183fc::product::image::0::url would not be able to find
2684
+ // parents with key 6bc73341b2a183fc::product::image because of the "0" list index -
2685
+ // it would search for 6bc73341b2a183fc::product::image::0
2686
+
2687
+ let currentPath = nodes.length === 0 && Number.isInteger(path.key) ? path.prev : path;
2688
+
2689
+ while (currentPath) {
2690
+ nodes.push(currentPath.key);
2691
+ currentPath = currentPath.prev;
2692
+ }
2693
+
2694
+ return [...nodes].reverse().join('.');
2695
+ }
2696
+
2697
+ const getFaststoreTelemetryPlugin = (tracingProvider, loggerProvider, serviceName, experimentalSendLogs) => {
2698
+ return function useFaststoreTelemetry() {
2699
+ const tracer = tracingProvider.getTracer(serviceName);
2700
+ const logger = loggerProvider.getLogger(serviceName);
2701
+ const resolverContextsByRootSpans = {};
2702
+ return {
2703
+ onPluginInit({
2704
+ addPlugin
2705
+ }) {
2706
+ addPlugin( // eslint-disable-next-line
2707
+ onResolve.useOnResolve(({
2708
+ info,
2709
+ context
2710
+ }) => {
2711
+ if (context && typeof context === 'object' && context[tracingSpanSymbol]) {
2712
+ var _path$prev, _path$prev2;
2713
+
2714
+ tracer.getActiveSpanProcessor();
2715
+ const rootContextSpanId = context[tracingSpanSymbol].spanContext().spanId;
2716
+ const {
2717
+ fieldName,
2718
+ returnType,
2719
+ parentType,
2720
+ path
2721
+ } = info;
2722
+ const previousResolverSpanKey = path.prev && getResolverSpanKey(path.prev);
2723
+ let ctx = null;
2724
+
2725
+ if (previousResolverSpanKey && resolverContextsByRootSpans[rootContextSpanId][previousResolverSpanKey]) {
2726
+ ctx = resolverContextsByRootSpans[rootContextSpanId][previousResolverSpanKey];
2727
+ } else {
2728
+ var _resolverContextsByRo;
2729
+
2730
+ ctx = api.trace.setSpan(api.context.active(), context[tracingSpanSymbol]);
2731
+ resolverContextsByRootSpans[rootContextSpanId] = (_resolverContextsByRo = resolverContextsByRootSpans[rootContextSpanId]) != null ? _resolverContextsByRo : {};
2732
+ }
2733
+
2734
+ const resolverIndexInList = Number.isInteger((_path$prev = path.prev) == null ? void 0 : _path$prev.key) ? `[${(_path$prev2 = path.prev) == null ? void 0 : _path$prev2.key}]` : '';
2735
+ const resolverSpan = tracer.startSpan(`${parentType.toString()}.${fieldName}${resolverIndexInList}`, {
2736
+ attributes: {
2737
+ [AttributeName.RESOLVER_FIELD_NAME]: fieldName,
2738
+ [AttributeName.RESOLVER_TYPE_NAME]: parentType.toString(),
2739
+ [AttributeName.RESOLVER_RESULT_TYPE]: returnType.toString(),
2740
+ 'meta.span.path': getResolverSpanKey(path)
2741
+ }
2742
+ }, ctx);
2743
+ const resolverCtx = api.trace.setSpan(ctx, resolverSpan);
2744
+ resolverContextsByRootSpans[rootContextSpanId][getResolverSpanKey(path)] = resolverCtx;
2745
+ return ({
2746
+ result
2747
+ }) => {
2748
+ if (result instanceof Error) {
2749
+ resolverSpan.setAttributes({
2750
+ error: true,
2751
+ 'exception.category': AttributeName.RESOLVER_EXECUTION_ERROR,
2752
+ 'exception.message': result.message,
2753
+ 'exception.type': result.name
2754
+ });
2755
+ resolverSpan.recordException(result);
2756
+ }
2757
+
2758
+ resolverSpan.end();
2759
+ };
2760
+ } // eslint-disable-next-line @typescript-eslint/no-empty-function
2761
+
2762
+
2763
+ return () => {};
2764
+ }));
2765
+ },
2766
+
2767
+ onExecute({
2768
+ args,
2769
+ extendContext
2770
+ }) {
2771
+ var _args$document$defini, _args$operationName;
2772
+
2773
+ const operationType = (_args$document$defini = args.document.definitions.filter(def => def.kind === graphql.Kind.OPERATION_DEFINITION).map(def => def.operation)) == null ? void 0 : _args$document$defini[0]; // Span name according to Semantic Conventions
2774
+ // https://github.com/open-telemetry/semantic-conventions
2775
+
2776
+ let spanName = 'GraphQL Operation';
2777
+
2778
+ if (operationType && args.operationName) {
2779
+ spanName = `${operationType} ${args.operationName}`;
2780
+ } else if (operationType && !args.operationName) {
2781
+ spanName = operationType;
2782
+ }
2783
+
2784
+ const executionSpan = tracer.startSpan(spanName, {
2785
+ kind: api.SpanKind.SERVER,
2786
+ attributes: {
2787
+ [AttributeName.EXECUTION_OPERATION_NAME]: (_args$operationName = args.operationName) != null ? _args$operationName : undefined,
2788
+ [AttributeName.EXECUTION_OPERATION_TYPE]: operationType != null ? operationType : undefined,
2789
+ [AttributeName.EXECUTION_OPERATION_DOCUMENT]: graphql.print(args.document)
2790
+ }
2791
+ });
2792
+ const executeContext = api.context.active();
2793
+ const resultCbs = {
2794
+ onExecuteDone({
2795
+ result
2796
+ }) {
2797
+ var _args$operationName2, _args$variableValues;
2798
+
2799
+ if (core.isAsyncIterable(result)) {
2800
+ executionSpan.end(); // eslint-disable-next-line no-console
2801
+
2802
+ console.warn(`Plugin "newrelic" encountered a AsyncIterator which is not supported yet, so tracing data is not available for the operation.`);
2803
+ return;
2804
+ }
2805
+
2806
+ const logRecord = {
2807
+ context: executeContext,
2808
+ attributes: {
2809
+ 'service.name': 'faststore-api',
2810
+ 'service.version': '1.12.38',
2811
+ 'service.name_and_version': 'faststore-api@1.12.38',
2812
+ 'vtex.search_index': 'faststore_beta_api',
2813
+ [AttributeName.EXECUTION_OPERATION_NAME]: (_args$operationName2 = args.operationName) != null ? _args$operationName2 : undefined,
2814
+ [AttributeName.EXECUTION_OPERATION_DOCUMENT]: graphql.print(args.document),
2815
+ [AttributeName.EXECUTION_VARIABLES]: JSON.stringify((_args$variableValues = args.variableValues) != null ? _args$variableValues : {})
2816
+ }
2817
+ };
2818
+
2819
+ if (typeof result.data !== 'undefined' && !(result.errors && result.errors.length > 0)) {
2820
+ logRecord.severityNumber = apiLogs.SeverityNumber.INFO;
2821
+ logRecord.severityText = 'Info';
2822
+ logRecord.attributes[AttributeName.EXECUTION_RESULT] = JSON.stringify(result);
2823
+ }
2824
+
2825
+ if (result.errors && result.errors.length > 0) {
2826
+ logRecord.severityNumber = apiLogs.SeverityNumber.ERROR;
2827
+ logRecord.severityText = 'Error';
2828
+ logRecord.attributes[AttributeName.EXECUTION_ERROR] = JSON.stringify(result.errors);
2829
+ executionSpan.setAttributes({
2830
+ error: true,
2831
+ 'exception.category': AttributeName.EXECUTION_ERROR,
2832
+ 'exception.message': JSON.stringify(result.errors)
2833
+ });
2834
+ }
2835
+
2836
+ if (experimentalSendLogs) {
2837
+ logger.emit(logRecord);
2838
+ }
2839
+
2840
+ executionSpan.end();
2841
+ }
2842
+
2843
+ };
2844
+ extendContext({
2845
+ [tracingSpanSymbol]: executionSpan
2846
+ });
2847
+ return resultCbs;
2848
+ }
2849
+
2850
+ };
2851
+ };
2852
+ };
2853
+
2854
+ const FASTSTORE_API_VERSION = packageJson.version; // TODO: These urls are hardcoded for now, but they should be configurable via ENV variables
2855
+ // They are only acessible from within the VTEX network, so they are not a security risk
2856
+
2857
+ const TRACE_COLLECTOR_URL = 'opentelemetry-collector.vtex.systems';
2858
+ const TRACE_COLLECTOR_URL_DEV = 'opentelemetry-collector-beta.vtex.systems';
2859
+ const LOG_COLLECTOR_URL = 'opentelemetry-collector.vtex.systems';
2860
+ function getTelemetry(APIOptions, telemetryOptions) {
2861
+ var _telemetryOptions$exp;
2862
+
2863
+ const honeycombCollectorOptions = {
2864
+ url: (telemetryOptions == null ? void 0 : telemetryOptions.mode) === 'dev' ? TRACE_COLLECTOR_URL_DEV : TRACE_COLLECTOR_URL
2865
+ };
2866
+ const openSearchCollectorOptions = {
2867
+ url: LOG_COLLECTOR_URL
2868
+ }; // Create a new tracer provider
2869
+
2870
+ const tracerProvider = new sdkTraceBase.BasicTracerProvider({
2871
+ resource: new resources.Resource({
2872
+ 'service.name': 'faststore-api',
2873
+ 'service.version': FASTSTORE_API_VERSION,
2874
+ 'service.name_and_version': `faststore-api@${FASTSTORE_API_VERSION}`,
2875
+ platform: APIOptions.platform,
2876
+ [`${APIOptions.platform}.account`]: APIOptions.account,
2877
+ [`${APIOptions.platform}.environment`]: APIOptions.environment,
2878
+ // TODO: include the following properties in the logs
2879
+ // [`${APIOptions.platform}.options.hideUnavailableItems`]:
2880
+ // APIOptions.hideUnavailableItems,
2881
+ // [`${APIOptions.platform}.flags.enableOrderFormSync`]:
2882
+ // APIOptions.flags?.enableOrderFormSync,
2883
+ // channel: APIOptions.channel,
2884
+ locale: APIOptions.locale
2885
+ })
2886
+ });
2887
+ const loggerProvider = new sdkLogs.LoggerProvider(); // Create trace exporter
2888
+
2889
+ const honeycombExporter = new exporterTraceOtlpGrpc.OTLPTraceExporter(honeycombCollectorOptions); // Create log exporter
2890
+
2891
+ const openSearchExporter = new exporterLogsOtlpGrpc.OTLPLogsExporter(openSearchCollectorOptions); // Set up a span processor to export spans to Honeycomb
2892
+
2893
+ const honeyCombSpanProcessor = new sdkTraceBase.SimpleSpanProcessor(honeycombExporter); // Set up a log record processor to export spans to OpenSearch
2894
+
2895
+ const openSearchLogProcessor = new sdkLogs.SimpleLogRecordProcessor(openSearchExporter); // Register the span processor with the tracer provider
2896
+
2897
+ tracerProvider.addSpanProcessor(honeyCombSpanProcessor); // Register the log record processor with the log provider
2898
+
2899
+ loggerProvider.addLogRecordProcessor(openSearchLogProcessor);
2900
+
2901
+ if ((telemetryOptions == null ? void 0 : telemetryOptions.mode) === 'verbose' || (telemetryOptions == null ? void 0 : telemetryOptions.mode) === 'dev') {
2902
+ // Set up a console exporter for verbose mode
2903
+ const consoleExporter = new sdkTraceBase.ConsoleSpanExporter();
2904
+ const verboseTraceProcessor = new sdkTraceBase.SimpleSpanProcessor(consoleExporter); // Set up processors for verbose mode
2905
+
2906
+ const consoleLogExporter = new sdkLogs.ConsoleLogRecordExporter();
2907
+ const veboseLogRecordExporter = new sdkLogs.SimpleLogRecordProcessor(consoleLogExporter);
2908
+ tracerProvider.addSpanProcessor(verboseTraceProcessor);
2909
+ loggerProvider.addLogRecordProcessor(veboseLogRecordExporter);
2910
+ }
2911
+
2912
+ const useFaststoreTelemetry = getFaststoreTelemetryPlugin( // The @opentelemetry/sdk-trace-base was renamed from @opentelemetry/tracing but the
2913
+ // envelop plugin doesn't support this change yet. This causes the class type to be incompatible,
2914
+ // even if they are the same. https://github.com/n1ru4l/envelop/issues/1610
2915
+ tracerProvider, loggerProvider, 'faststore-api', (_telemetryOptions$exp = telemetryOptions == null ? void 0 : telemetryOptions.experimentalSendLogs) != null ? _telemetryOptions$exp : false);
2916
+ return {
2917
+ useFaststoreTelemetry
2918
+ };
2919
+ }
2920
+
2635
2921
  const platforms = {
2636
2922
  vtex: {
2637
2923
  getResolvers: getResolvers,
@@ -2655,6 +2941,7 @@ exports.NotFoundError = NotFoundError;
2655
2941
  exports.getContextFactory = getContextFactory$1;
2656
2942
  exports.getResolvers = getResolvers$1;
2657
2943
  exports.getSchema = getSchema;
2944
+ exports.getTelemetry = getTelemetry;
2658
2945
  exports.getTypeDefs = getTypeDefs;
2659
2946
  exports.isBadRequestError = isBadRequestError;
2660
2947
  exports.isFastStoreError = isFastStoreError;