@webex/webex-core 3.12.0-llmrefactor.7 → 3.12.0-llmrefactor.9

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/dist/config.js CHANGED
@@ -123,6 +123,11 @@ var _default = exports.default = {
123
123
  cacheU2C: false
124
124
  },
125
125
  payloadTransformer: {
126
+ /**
127
+ * When true, inbound payload transforms run at most once for the same successful response object.
128
+ * This supports request flows that pass a response through more than one interceptor pipeline.
129
+ */
130
+ skipRepeatedInboundTransforms: false,
126
131
  predicates: [],
127
132
  transforms: []
128
133
  },
@@ -1 +1 @@
1
- {"version":3,"names":["_storage","require","_credentialsConfig","_interopRequireDefault","_default","exports","default","maxAppLevelRedirects","maxLocusRedirects","maxAuthenticationReplays","maxReconnectAttempts","onBeforeLogout","trackingIdPrefix","trackingIdSuffix","AlternateLogger","undefined","credentials","CredentialsConfig","fedramp","process","env","ENABLE_FEDRAMP","services","useUserOnboardingServiceForActivations","useCatalogOverride","skipPreauthCatalogOnUnauthenticated","catalogInitTimeout","discovery","hydra","HYDRA_SERVICE_URL","sqdiscovery","SQDISCOVERY_SERVICE_URL","u2c","U2C_SERVICE_URL","validateDomains","validateCatalogUrls","servicesNotNeedValidation","allowedDomains","device","preDiscoveryServices","hydraServiceUrl","metrics","type","calling","cacheU2C","payloadTransformer","predicates","transforms","storage","boundedAdapter","MemoryStoreAdapter","unboundedAdapter"],"sources":["config.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint camelcase: [0] */\n\nimport {MemoryStoreAdapter} from './lib/storage';\nimport CredentialsConfig from './credentials-config';\n\nexport default {\n maxAppLevelRedirects: 10,\n maxLocusRedirects: 5,\n maxAuthenticationReplays: 1,\n maxReconnectAttempts: 1,\n onBeforeLogout: [],\n trackingIdPrefix: 'webex-js-sdk',\n trackingIdSuffix: '',\n AlternateLogger: undefined,\n credentials: new CredentialsConfig(),\n fedramp: process.env.ENABLE_FEDRAMP || false,\n services: {\n /**\n * When true, uses the user-onboarding service for user activation.\n * When false (default), uses the license service.\n *\n * @type {boolean}\n */\n useUserOnboardingServiceForActivations: false,\n\n /**\n * When true, requests the U2C catalog override.\n *\n * @type {boolean}\n */\n useCatalogOverride: false,\n\n /**\n * When true, skips fetching the preauth catalog during initialization\n * while the user is unauthenticated (no existing token). The catalog is\n * expected to be collected manually later instead. When false (default),\n * the preauth catalog is collected automatically during init.\n *\n * @type {boolean}\n */\n skipPreauthCatalogOnUnauthenticated: false,\n\n /**\n * Maximum time (in milliseconds) to wait for the initial service catalog\n * collection when `waitForCatalogInit` is enabled, before letting\n * `services.ready` (and therefore `webex.ready`) fire anyway. Prevents a\n * hung catalog request from leaving the app on a permanent spinner.\n *\n * @type {number}\n */\n catalogInitTimeout: 15000,\n\n /**\n * A list of services that are available prior to catalog collection.\n *\n * @type {Object}\n */\n discovery: {\n /**\n * The hydra discovery url.\n *\n * @type {string}\n */\n hydra: process.env.HYDRA_SERVICE_URL || 'https://api.ciscospark.com/v1',\n\n /**\n * load balanced region info url\n */\n sqdiscovery: process.env.SQDISCOVERY_SERVICE_URL || 'https://ds.ciscospark.com/v1/region',\n\n /**\n * The u2c discovery url\n *\n * @type {string}\n */\n u2c: process.env.U2C_SERVICE_URL || 'https://u2c.wbx2.com/u2c/api/v1',\n },\n\n /**\n * When true, considers all urls in `allowedDomains` as safe for auth tokens\n *\n * @type {boolean}\n */\n validateDomains: true,\n\n /**\n * When true, enables the CatalogUrlInterceptor which validates that all\n * outbound request URLs are in the service catalog or allowed domains.\n * This prevents SSRF attacks where attacker-controlled URLs could be\n * sent to the SDK.\n *\n * @type {boolean}\n */\n validateCatalogUrls: false,\n\n /**\n * services that don't need auth validation\n */\n\n servicesNotNeedValidation: ['webex-appapi-service'],\n\n /**\n * Contains a list of allowed domain host addresses.\n *\n * @type {Array<string>}\n */\n allowedDomains: [],\n },\n device: {\n preDiscoveryServices: {\n hydra: process.env.HYDRA_SERVICE_URL || 'https://api.ciscospark.com/v1',\n hydraServiceUrl: process.env.HYDRA_SERVICE_URL || 'https://api.ciscospark.com/v1',\n },\n validateDomains: true,\n },\n metrics: {\n type: ['behavioral', 'operational'],\n },\n calling: {\n /**\n * Controls whether U2C service catalogs should be cached and warmed from cache.\n * When false, the services layer will skip reading and writing the U2C cache.\n */\n cacheU2C: false,\n },\n payloadTransformer: {\n predicates: [],\n transforms: [],\n },\n storage: {\n boundedAdapter: MemoryStoreAdapter,\n unboundedAdapter: MemoryStoreAdapter,\n },\n};\n"],"mappings":";;;;;;;;AAMA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,kBAAA,GAAAC,sBAAA,CAAAF,OAAA;AAPA;AACA;AACA;AAEA;AAAA,IAAAG,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAKe;EACbC,oBAAoB,EAAE,EAAE;EACxBC,iBAAiB,EAAE,CAAC;EACpBC,wBAAwB,EAAE,CAAC;EAC3BC,oBAAoB,EAAE,CAAC;EACvBC,cAAc,EAAE,EAAE;EAClBC,gBAAgB,EAAE,cAAc;EAChCC,gBAAgB,EAAE,EAAE;EACpBC,eAAe,EAAEC,SAAS;EAC1BC,WAAW,EAAE,IAAIC,0BAAiB,CAAC,CAAC;EACpCC,OAAO,EAAEC,OAAO,CAACC,GAAG,CAACC,cAAc,IAAI,KAAK;EAC5CC,QAAQ,EAAE;IACR;AACJ;AACA;AACA;AACA;AACA;IACIC,sCAAsC,EAAE,KAAK;IAE7C;AACJ;AACA;AACA;AACA;IACIC,kBAAkB,EAAE,KAAK;IAEzB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIC,mCAAmC,EAAE,KAAK;IAE1C;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIC,kBAAkB,EAAE,KAAK;IAEzB;AACJ;AACA;AACA;AACA;IACIC,SAAS,EAAE;MACT;AACN;AACA;AACA;AACA;MACMC,KAAK,EAAET,OAAO,CAACC,GAAG,CAACS,iBAAiB,IAAI,+BAA+B;MAEvE;AACN;AACA;MACMC,WAAW,EAAEX,OAAO,CAACC,GAAG,CAACW,uBAAuB,IAAI,qCAAqC;MAEzF;AACN;AACA;AACA;AACA;MACMC,GAAG,EAAEb,OAAO,CAACC,GAAG,CAACa,eAAe,IAAI;IACtC,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIC,eAAe,EAAE,IAAI;IAErB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIC,mBAAmB,EAAE,KAAK;IAE1B;AACJ;AACA;;IAEIC,yBAAyB,EAAE,CAAC,sBAAsB,CAAC;IAEnD;AACJ;AACA;AACA;AACA;IACIC,cAAc,EAAE;EAClB,CAAC;EACDC,MAAM,EAAE;IACNC,oBAAoB,EAAE;MACpBX,KAAK,EAAET,OAAO,CAACC,GAAG,CAACS,iBAAiB,IAAI,+BAA+B;MACvEW,eAAe,EAAErB,OAAO,CAACC,GAAG,CAACS,iBAAiB,IAAI;IACpD,CAAC;IACDK,eAAe,EAAE;EACnB,CAAC;EACDO,OAAO,EAAE;IACPC,IAAI,EAAE,CAAC,YAAY,EAAE,aAAa;EACpC,CAAC;EACDC,OAAO,EAAE;IACP;AACJ;AACA;AACA;IACIC,QAAQ,EAAE;EACZ,CAAC;EACDC,kBAAkB,EAAE;IAClBC,UAAU,EAAE,EAAE;IACdC,UAAU,EAAE;EACd,CAAC;EACDC,OAAO,EAAE;IACPC,cAAc,EAAEC,2BAAkB;IAClCC,gBAAgB,EAAED;EACpB;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_storage","require","_credentialsConfig","_interopRequireDefault","_default","exports","default","maxAppLevelRedirects","maxLocusRedirects","maxAuthenticationReplays","maxReconnectAttempts","onBeforeLogout","trackingIdPrefix","trackingIdSuffix","AlternateLogger","undefined","credentials","CredentialsConfig","fedramp","process","env","ENABLE_FEDRAMP","services","useUserOnboardingServiceForActivations","useCatalogOverride","skipPreauthCatalogOnUnauthenticated","catalogInitTimeout","discovery","hydra","HYDRA_SERVICE_URL","sqdiscovery","SQDISCOVERY_SERVICE_URL","u2c","U2C_SERVICE_URL","validateDomains","validateCatalogUrls","servicesNotNeedValidation","allowedDomains","device","preDiscoveryServices","hydraServiceUrl","metrics","type","calling","cacheU2C","payloadTransformer","skipRepeatedInboundTransforms","predicates","transforms","storage","boundedAdapter","MemoryStoreAdapter","unboundedAdapter"],"sources":["config.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint camelcase: [0] */\n\nimport {MemoryStoreAdapter} from './lib/storage';\nimport CredentialsConfig from './credentials-config';\n\nexport default {\n maxAppLevelRedirects: 10,\n maxLocusRedirects: 5,\n maxAuthenticationReplays: 1,\n maxReconnectAttempts: 1,\n onBeforeLogout: [],\n trackingIdPrefix: 'webex-js-sdk',\n trackingIdSuffix: '',\n AlternateLogger: undefined,\n credentials: new CredentialsConfig(),\n fedramp: process.env.ENABLE_FEDRAMP || false,\n services: {\n /**\n * When true, uses the user-onboarding service for user activation.\n * When false (default), uses the license service.\n *\n * @type {boolean}\n */\n useUserOnboardingServiceForActivations: false,\n\n /**\n * When true, requests the U2C catalog override.\n *\n * @type {boolean}\n */\n useCatalogOverride: false,\n\n /**\n * When true, skips fetching the preauth catalog during initialization\n * while the user is unauthenticated (no existing token). The catalog is\n * expected to be collected manually later instead. When false (default),\n * the preauth catalog is collected automatically during init.\n *\n * @type {boolean}\n */\n skipPreauthCatalogOnUnauthenticated: false,\n\n /**\n * Maximum time (in milliseconds) to wait for the initial service catalog\n * collection when `waitForCatalogInit` is enabled, before letting\n * `services.ready` (and therefore `webex.ready`) fire anyway. Prevents a\n * hung catalog request from leaving the app on a permanent spinner.\n *\n * @type {number}\n */\n catalogInitTimeout: 15000,\n\n /**\n * A list of services that are available prior to catalog collection.\n *\n * @type {Object}\n */\n discovery: {\n /**\n * The hydra discovery url.\n *\n * @type {string}\n */\n hydra: process.env.HYDRA_SERVICE_URL || 'https://api.ciscospark.com/v1',\n\n /**\n * load balanced region info url\n */\n sqdiscovery: process.env.SQDISCOVERY_SERVICE_URL || 'https://ds.ciscospark.com/v1/region',\n\n /**\n * The u2c discovery url\n *\n * @type {string}\n */\n u2c: process.env.U2C_SERVICE_URL || 'https://u2c.wbx2.com/u2c/api/v1',\n },\n\n /**\n * When true, considers all urls in `allowedDomains` as safe for auth tokens\n *\n * @type {boolean}\n */\n validateDomains: true,\n\n /**\n * When true, enables the CatalogUrlInterceptor which validates that all\n * outbound request URLs are in the service catalog or allowed domains.\n * This prevents SSRF attacks where attacker-controlled URLs could be\n * sent to the SDK.\n *\n * @type {boolean}\n */\n validateCatalogUrls: false,\n\n /**\n * services that don't need auth validation\n */\n\n servicesNotNeedValidation: ['webex-appapi-service'],\n\n /**\n * Contains a list of allowed domain host addresses.\n *\n * @type {Array<string>}\n */\n allowedDomains: [],\n },\n device: {\n preDiscoveryServices: {\n hydra: process.env.HYDRA_SERVICE_URL || 'https://api.ciscospark.com/v1',\n hydraServiceUrl: process.env.HYDRA_SERVICE_URL || 'https://api.ciscospark.com/v1',\n },\n validateDomains: true,\n },\n metrics: {\n type: ['behavioral', 'operational'],\n },\n calling: {\n /**\n * Controls whether U2C service catalogs should be cached and warmed from cache.\n * When false, the services layer will skip reading and writing the U2C cache.\n */\n cacheU2C: false,\n },\n payloadTransformer: {\n /**\n * When true, inbound payload transforms run at most once for the same successful response object.\n * This supports request flows that pass a response through more than one interceptor pipeline.\n */\n skipRepeatedInboundTransforms: false,\n predicates: [],\n transforms: [],\n },\n storage: {\n boundedAdapter: MemoryStoreAdapter,\n unboundedAdapter: MemoryStoreAdapter,\n },\n};\n"],"mappings":";;;;;;;;AAMA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,kBAAA,GAAAC,sBAAA,CAAAF,OAAA;AAPA;AACA;AACA;AAEA;AAAA,IAAAG,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAKe;EACbC,oBAAoB,EAAE,EAAE;EACxBC,iBAAiB,EAAE,CAAC;EACpBC,wBAAwB,EAAE,CAAC;EAC3BC,oBAAoB,EAAE,CAAC;EACvBC,cAAc,EAAE,EAAE;EAClBC,gBAAgB,EAAE,cAAc;EAChCC,gBAAgB,EAAE,EAAE;EACpBC,eAAe,EAAEC,SAAS;EAC1BC,WAAW,EAAE,IAAIC,0BAAiB,CAAC,CAAC;EACpCC,OAAO,EAAEC,OAAO,CAACC,GAAG,CAACC,cAAc,IAAI,KAAK;EAC5CC,QAAQ,EAAE;IACR;AACJ;AACA;AACA;AACA;AACA;IACIC,sCAAsC,EAAE,KAAK;IAE7C;AACJ;AACA;AACA;AACA;IACIC,kBAAkB,EAAE,KAAK;IAEzB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIC,mCAAmC,EAAE,KAAK;IAE1C;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIC,kBAAkB,EAAE,KAAK;IAEzB;AACJ;AACA;AACA;AACA;IACIC,SAAS,EAAE;MACT;AACN;AACA;AACA;AACA;MACMC,KAAK,EAAET,OAAO,CAACC,GAAG,CAACS,iBAAiB,IAAI,+BAA+B;MAEvE;AACN;AACA;MACMC,WAAW,EAAEX,OAAO,CAACC,GAAG,CAACW,uBAAuB,IAAI,qCAAqC;MAEzF;AACN;AACA;AACA;AACA;MACMC,GAAG,EAAEb,OAAO,CAACC,GAAG,CAACa,eAAe,IAAI;IACtC,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIC,eAAe,EAAE,IAAI;IAErB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIC,mBAAmB,EAAE,KAAK;IAE1B;AACJ;AACA;;IAEIC,yBAAyB,EAAE,CAAC,sBAAsB,CAAC;IAEnD;AACJ;AACA;AACA;AACA;IACIC,cAAc,EAAE;EAClB,CAAC;EACDC,MAAM,EAAE;IACNC,oBAAoB,EAAE;MACpBX,KAAK,EAAET,OAAO,CAACC,GAAG,CAACS,iBAAiB,IAAI,+BAA+B;MACvEW,eAAe,EAAErB,OAAO,CAACC,GAAG,CAACS,iBAAiB,IAAI;IACpD,CAAC;IACDK,eAAe,EAAE;EACnB,CAAC;EACDO,OAAO,EAAE;IACPC,IAAI,EAAE,CAAC,YAAY,EAAE,aAAa;EACpC,CAAC;EACDC,OAAO,EAAE;IACP;AACJ;AACA;AACA;IACIC,QAAQ,EAAE;EACZ,CAAC;EACDC,kBAAkB,EAAE;IAClB;AACJ;AACA;AACA;IACIC,6BAA6B,EAAE,KAAK;IACpCC,UAAU,EAAE,EAAE;IACdC,UAAU,EAAE;EACd,CAAC;EACDC,OAAO,EAAE;IACPC,cAAc,EAAEC,2BAAkB;IAClCC,gBAAgB,EAAED;EACpB;AACF,CAAC","ignoreList":[]}
@@ -1,23 +1,28 @@
1
1
  "use strict";
2
2
 
3
3
  var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
4
- var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
4
+ var _Object$defineProperty2 = require("@babel/runtime-corejs2/core-js/object/define-property");
5
5
  var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
6
- _Object$defineProperty(exports, "__esModule", {
6
+ _Object$defineProperty2(exports, "__esModule", {
7
7
  value: true
8
8
  });
9
9
  exports.default = void 0;
10
- var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
11
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
12
11
  var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
13
12
  var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
14
13
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
15
14
  var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
15
+ var _symbol = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/symbol"));
16
+ var _deleteProperty = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/delete-property"));
17
+ var _defineProperty = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/define-property"));
18
+ var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
16
19
  var _httpCore = require("@webex/http-core");
17
20
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
18
21
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /*!
19
22
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
20
23
  */
24
+ var inboundTransformPromise = (0, _symbol.default)('inboundTransformPromise');
25
+
21
26
  /**
22
27
  * @class
23
28
  */
@@ -54,7 +59,23 @@ var PayloadTransformerInterceptor = exports.default = /*#__PURE__*/function (_In
54
59
  if (options.disableTransform) {
55
60
  return response;
56
61
  }
57
- return this.webex.transform('inbound', response);
62
+ if (!this.webex.config.payloadTransformer.skipRepeatedInboundTransforms) {
63
+ return this.webex.transform('inbound', response);
64
+ }
65
+ if (response[inboundTransformPromise]) {
66
+ return response[inboundTransformPromise];
67
+ }
68
+ var transformPromise = this.webex.transform('inbound', response).catch(function (error) {
69
+ (0, _deleteProperty.default)(response, inboundTransformPromise);
70
+ throw error;
71
+ });
72
+
73
+ // Store the in-flight promise so concurrent interceptor pipelines share the same transform.
74
+ (0, _defineProperty.default)(response, inboundTransformPromise, {
75
+ configurable: true,
76
+ value: transformPromise
77
+ });
78
+ return transformPromise;
58
79
  }
59
80
 
60
81
  /**
@@ -1 +1 @@
1
- {"version":3,"names":["_httpCore","require","_callSuper","t","o","e","_getPrototypeOf2","default","_possibleConstructorReturn2","_isNativeReflectConstruct","_Reflect$construct","constructor","apply","Boolean","prototype","valueOf","call","PayloadTransformerInterceptor","exports","_Interceptor","_classCallCheck2","arguments","_inherits2","_createClass2","key","value","onRequest","options","noTransform","webex","transform","onResponse","response","disableTransform","onResponseError","reason","then","r","_promise","reject","create","Interceptor"],"sources":["payload-transformer.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {Interceptor} from '@webex/http-core';\n\n/**\n * @class\n */\nexport default class PayloadTransformerInterceptor extends Interceptor {\n /**\n * @param {Object} options\n * @returns {PayloadTransformerInterceptor}\n */\n static create() {\n return new PayloadTransformerInterceptor({webex: this});\n }\n\n /**\n * @see Interceptor#onRequest\n * @param {Object} options\n * @returns {Object}\n */\n onRequest(options) {\n if (options.noTransform) {\n return options;\n }\n\n return this.webex.transform('outbound', options);\n }\n\n /**\n * @see Interceptor#onResponse\n * @param {Object} options\n * @param {HttpResponse} response\n * @returns {Object}\n */\n onResponse(options, response) {\n if (options.disableTransform) {\n return response;\n }\n\n return this.webex.transform('inbound', response);\n }\n\n /**\n * @see Interceptor#onResponseError\n * @param {Object} options\n * @param {Error} reason\n * @returns {Object}\n */\n onResponseError(options, reason) {\n return this.webex.transform('inbound', reason).then((r) => Promise.reject(r || reason));\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAIA,IAAAA,SAAA,GAAAC,OAAA;AAA6C,SAAAC,WAAAC,CAAA,EAAAC,CAAA,EAAAC,CAAA,WAAAD,CAAA,OAAAE,gBAAA,CAAAC,OAAA,EAAAH,CAAA,OAAAI,2BAAA,CAAAD,OAAA,EAAAJ,CAAA,EAAAM,yBAAA,KAAAC,kBAAA,CAAAN,CAAA,EAAAC,CAAA,YAAAC,gBAAA,CAAAC,OAAA,EAAAJ,CAAA,EAAAQ,WAAA,IAAAP,CAAA,CAAAQ,KAAA,CAAAT,CAAA,EAAAE,CAAA;AAAA,SAAAI,0BAAA,cAAAN,CAAA,IAAAU,OAAA,CAAAC,SAAA,CAAAC,OAAA,CAAAC,IAAA,CAAAN,kBAAA,CAAAG,OAAA,iCAAAV,CAAA,aAAAM,yBAAA,YAAAA,0BAAA,aAAAN,CAAA,UAJ7C;AACA;AACA;AAIA;AACA;AACA;AAFA,IAGqBc,6BAA6B,GAAAC,OAAA,CAAAX,OAAA,0BAAAY,YAAA;EAAA,SAAAF,8BAAA;IAAA,IAAAG,gBAAA,CAAAb,OAAA,QAAAU,6BAAA;IAAA,OAAAf,UAAA,OAAAe,6BAAA,EAAAI,SAAA;EAAA;EAAA,IAAAC,UAAA,CAAAf,OAAA,EAAAU,6BAAA,EAAAE,YAAA;EAAA,WAAAI,aAAA,CAAAhB,OAAA,EAAAU,6BAAA;IAAAO,GAAA;IAAAC,KAAA;IAShD;AACF;AACA;AACA;AACA;IACE,SAAAC,SAASA,CAACC,OAAO,EAAE;MACjB,IAAIA,OAAO,CAACC,WAAW,EAAE;QACvB,OAAOD,OAAO;MAChB;MAEA,OAAO,IAAI,CAACE,KAAK,CAACC,SAAS,CAAC,UAAU,EAAEH,OAAO,CAAC;IAClD;;IAEA;AACF;AACA;AACA;AACA;AACA;EALE;IAAAH,GAAA;IAAAC,KAAA,EAMA,SAAAM,UAAUA,CAACJ,OAAO,EAAEK,QAAQ,EAAE;MAC5B,IAAIL,OAAO,CAACM,gBAAgB,EAAE;QAC5B,OAAOD,QAAQ;MACjB;MAEA,OAAO,IAAI,CAACH,KAAK,CAACC,SAAS,CAAC,SAAS,EAAEE,QAAQ,CAAC;IAClD;;IAEA;AACF;AACA;AACA;AACA;AACA;EALE;IAAAR,GAAA;IAAAC,KAAA,EAMA,SAAAS,eAAeA,CAACP,OAAO,EAAEQ,MAAM,EAAE;MAC/B,OAAO,IAAI,CAACN,KAAK,CAACC,SAAS,CAAC,SAAS,EAAEK,MAAM,CAAC,CAACC,IAAI,CAAC,UAACC,CAAC;QAAA,OAAKC,QAAA,CAAA/B,OAAA,CAAQgC,MAAM,CAACF,CAAC,IAAIF,MAAM,CAAC;MAAA,EAAC;IACzF;EAAC;IAAAX,GAAA;IAAAC,KAAA;IA3CD;AACF;AACA;AACA;IACE,SAAOe,MAAMA,CAAA,EAAG;MACd,OAAO,IAAIvB,6BAA6B,CAAC;QAACY,KAAK,EAAE;MAAI,CAAC,CAAC;IACzD;EAAC;AAAA,EAPwDY,qBAAW","ignoreList":[]}
1
+ {"version":3,"names":["_httpCore","require","_callSuper","t","o","e","_getPrototypeOf2","default","_possibleConstructorReturn2","_isNativeReflectConstruct","_Reflect$construct","constructor","apply","Boolean","prototype","valueOf","call","inboundTransformPromise","_symbol","PayloadTransformerInterceptor","exports","_Interceptor","_classCallCheck2","arguments","_inherits2","_createClass2","key","value","onRequest","options","noTransform","webex","transform","onResponse","response","disableTransform","config","payloadTransformer","skipRepeatedInboundTransforms","transformPromise","catch","error","_deleteProperty","_defineProperty","configurable","onResponseError","reason","then","r","_promise","reject","create","Interceptor"],"sources":["payload-transformer.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {Interceptor} from '@webex/http-core';\n\nconst inboundTransformPromise = Symbol('inboundTransformPromise');\n\n/**\n * @class\n */\nexport default class PayloadTransformerInterceptor extends Interceptor {\n /**\n * @param {Object} options\n * @returns {PayloadTransformerInterceptor}\n */\n static create() {\n return new PayloadTransformerInterceptor({webex: this});\n }\n\n /**\n * @see Interceptor#onRequest\n * @param {Object} options\n * @returns {Object}\n */\n onRequest(options) {\n if (options.noTransform) {\n return options;\n }\n\n return this.webex.transform('outbound', options);\n }\n\n /**\n * @see Interceptor#onResponse\n * @param {Object} options\n * @param {HttpResponse} response\n * @returns {Object}\n */\n onResponse(options, response) {\n if (options.disableTransform) {\n return response;\n }\n\n if (!this.webex.config.payloadTransformer.skipRepeatedInboundTransforms) {\n return this.webex.transform('inbound', response);\n }\n\n if (response[inboundTransformPromise]) {\n return response[inboundTransformPromise];\n }\n\n const transformPromise = this.webex.transform('inbound', response).catch((error) => {\n Reflect.deleteProperty(response, inboundTransformPromise);\n\n throw error;\n });\n\n // Store the in-flight promise so concurrent interceptor pipelines share the same transform.\n Object.defineProperty(response, inboundTransformPromise, {\n configurable: true,\n value: transformPromise,\n });\n\n return transformPromise;\n }\n\n /**\n * @see Interceptor#onResponseError\n * @param {Object} options\n * @param {Error} reason\n * @returns {Object}\n */\n onResponseError(options, reason) {\n return this.webex.transform('inbound', reason).then((r) => Promise.reject(r || reason));\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -302,7 +302,7 @@ var Batcher = _webexPlugin.default.extend({
302
302
  fingerprintResponse: function fingerprintResponse(item) {
303
303
  throw new Error('fingerprintResponse() must be implemented');
304
304
  },
305
- version: "3.12.0-llmrefactor.7"
305
+ version: "3.12.0-llmrefactor.9"
306
306
  });
307
307
  var _default2 = exports.default = Batcher;
308
308
  //# sourceMappingURL=batcher.js.map
@@ -655,7 +655,7 @@ var Credentials = _webexPlugin.default.extend((_dec = (0, _common.oneFlight)({
655
655
  this.refresh();
656
656
  }
657
657
  },
658
- version: "3.12.0-llmrefactor.7"
658
+ version: "3.12.0-llmrefactor.9"
659
659
  }, (0, _applyDecoratedDescriptor2.default)(_obj, "getUserToken", [_dec, _dec2], (0, _getOwnPropertyDescriptor.default)(_obj, "getUserToken"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "initialize", [_dec3], (0, _getOwnPropertyDescriptor.default)(_obj, "initialize"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "invalidate", [_common.oneFlight, _dec4], (0, _getOwnPropertyDescriptor.default)(_obj, "invalidate"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "refresh", [_common.oneFlight, _dec5, _dec6], (0, _getOwnPropertyDescriptor.default)(_obj, "refresh"), _obj), _obj));
660
660
  var _default = exports.default = Credentials;
661
661
  //# sourceMappingURL=credentials.js.map
@@ -532,7 +532,7 @@ var Token = _webexPlugin.default.extend((_dec = (0, _common.oneFlight)({
532
532
  return res.body;
533
533
  });
534
534
  },
535
- version: "3.12.0-llmrefactor.7"
535
+ version: "3.12.0-llmrefactor.9"
536
536
  }, (0, _applyDecoratedDescriptor2.default)(_obj, "downscope", [_dec], (0, _getOwnPropertyDescriptor.default)(_obj, "downscope"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "refresh", [_common.oneFlight], (0, _getOwnPropertyDescriptor.default)(_obj, "refresh"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "revoke", [_common.oneFlight], (0, _getOwnPropertyDescriptor.default)(_obj, "revoke"), _obj), _obj));
537
537
  var _default = exports.default = Token;
538
538
  //# sourceMappingURL=token.js.map
@@ -1641,7 +1641,7 @@ var Services = _webexPlugin.default.extend({
1641
1641
  }, _callee6);
1642
1642
  })));
1643
1643
  },
1644
- version: "3.12.0-llmrefactor.7"
1644
+ version: "3.12.0-llmrefactor.9"
1645
1645
  });
1646
1646
  /* eslint-enable no-underscore-dangle */
1647
1647
  var _default = exports.default = Services;
@@ -1577,7 +1577,7 @@ var Services = _webexPlugin.default.extend({
1577
1577
  }, _callee5);
1578
1578
  })));
1579
1579
  },
1580
- version: "3.12.0-llmrefactor.7"
1580
+ version: "3.12.0-llmrefactor.9"
1581
1581
  });
1582
1582
  /* eslint-enable no-underscore-dangle */
1583
1583
  var _default = exports.default = Services;
@@ -57,7 +57,7 @@ var Logger = _webexPlugin.default.extend({
57
57
  info: wrapConsoleMethod('info'),
58
58
  debug: wrapConsoleMethod('debug'),
59
59
  trace: wrapConsoleMethod('trace'),
60
- version: "3.12.0-llmrefactor.7"
60
+ version: "3.12.0-llmrefactor.9"
61
61
  });
62
62
  (0, _webexCore.registerPlugin)('logger', Logger);
63
63
  var _default = exports.default = Logger;
@@ -98,7 +98,7 @@ var MAX_FILE_SIZE_IN_MB = 2048;
98
98
  * @class
99
99
  */
100
100
  var WebexCore = _ampersandState.default.extend((_obj = {
101
- version: "3.12.0-llmrefactor.7",
101
+ version: "3.12.0-llmrefactor.9",
102
102
  children: {
103
103
  internal: _webexInternalCore.default
104
104
  },
@@ -642,7 +642,7 @@ var WebexCore = _ampersandState.default.extend((_obj = {
642
642
  });
643
643
  }
644
644
  }, (0, _applyDecoratedDescriptor2.default)(_obj, "_uploadPhaseUpload", [_common.retry], (0, _getOwnPropertyDescriptor.default)(_obj, "_uploadPhaseUpload"), _obj), _obj));
645
- WebexCore.version = "3.12.0-llmrefactor.7";
645
+ WebexCore.version = "3.12.0-llmrefactor.9";
646
646
  (0, _webexInternalCorePluginMixin.default)(_webexInternalCore.default, _config.default, interceptors);
647
647
  (0, _webexCorePluginMixin.default)(WebexCore, _config.default, interceptors);
648
648
  var _default = exports.default = WebexCore;
package/package.json CHANGED
@@ -33,16 +33,16 @@
33
33
  "@sinonjs/fake-timers": "^6.0.1",
34
34
  "@webex/babel-config-legacy": "0.0.0",
35
35
  "@webex/eslint-config-legacy": "0.0.0",
36
- "@webex/internal-plugin-device": "3.12.0-llmrefactor.7",
36
+ "@webex/internal-plugin-device": "3.12.0-llmrefactor.9",
37
37
  "@webex/jest-config-legacy": "0.0.0",
38
38
  "@webex/legacy-tools": "0.0.0",
39
- "@webex/plugin-logger": "3.12.0-llmrefactor.7",
40
- "@webex/test-helper-chai": "3.12.0-llmrefactor.2",
41
- "@webex/test-helper-make-local-url": "3.12.0-llmrefactor.2",
42
- "@webex/test-helper-mocha": "3.12.0-llmrefactor.2",
43
- "@webex/test-helper-mock-webex": "3.12.0-llmrefactor.1",
44
- "@webex/test-helper-refresh-callback": "3.12.0-llmrefactor.1",
45
- "@webex/test-helper-test-users": "3.12.0-llmrefactor.0",
39
+ "@webex/plugin-logger": "3.12.0-llmrefactor.9",
40
+ "@webex/test-helper-chai": "3.12.0-llmrefactor.3",
41
+ "@webex/test-helper-make-local-url": "3.12.0-llmrefactor.3",
42
+ "@webex/test-helper-mocha": "3.12.0-llmrefactor.3",
43
+ "@webex/test-helper-mock-webex": "3.12.0-llmrefactor.2",
44
+ "@webex/test-helper-refresh-callback": "3.12.0-llmrefactor.2",
45
+ "@webex/test-helper-test-users": "3.12.0-llmrefactor.1",
46
46
  "chai": "^4.3.4",
47
47
  "chai-as-promised": "^7.1.1",
48
48
  "eslint": "^8.24.0",
@@ -50,10 +50,10 @@
50
50
  "sinon": "^9.2.4"
51
51
  },
52
52
  "dependencies": {
53
- "@webex/common": "3.12.0-llmrefactor.2",
54
- "@webex/common-timers": "3.12.0-llmrefactor.2",
55
- "@webex/http-core": "3.12.0-llmrefactor.2",
56
- "@webex/storage-adapter-spec": "3.12.0-llmrefactor.2",
53
+ "@webex/common": "3.12.0-llmrefactor.3",
54
+ "@webex/common-timers": "3.12.0-llmrefactor.3",
55
+ "@webex/http-core": "3.12.0-llmrefactor.3",
56
+ "@webex/storage-adapter-spec": "3.12.0-llmrefactor.3",
57
57
  "ampersand-collection": "^2.0.2",
58
58
  "ampersand-events": "^2.0.2",
59
59
  "ampersand-state": "^5.0.3",
@@ -73,5 +73,5 @@
73
73
  "test:style": "eslint ./src/**/*.*",
74
74
  "test:unit": "webex-legacy-tools test --unit --runner jest"
75
75
  },
76
- "version": "3.12.0-llmrefactor.7"
76
+ "version": "3.12.0-llmrefactor.9"
77
77
  }
package/src/config.js CHANGED
@@ -128,6 +128,11 @@ export default {
128
128
  cacheU2C: false,
129
129
  },
130
130
  payloadTransformer: {
131
+ /**
132
+ * When true, inbound payload transforms run at most once for the same successful response object.
133
+ * This supports request flows that pass a response through more than one interceptor pipeline.
134
+ */
135
+ skipRepeatedInboundTransforms: false,
131
136
  predicates: [],
132
137
  transforms: [],
133
138
  },
@@ -4,6 +4,8 @@
4
4
 
5
5
  import {Interceptor} from '@webex/http-core';
6
6
 
7
+ const inboundTransformPromise = Symbol('inboundTransformPromise');
8
+
7
9
  /**
8
10
  * @class
9
11
  */
@@ -40,7 +42,27 @@ export default class PayloadTransformerInterceptor extends Interceptor {
40
42
  return response;
41
43
  }
42
44
 
43
- return this.webex.transform('inbound', response);
45
+ if (!this.webex.config.payloadTransformer.skipRepeatedInboundTransforms) {
46
+ return this.webex.transform('inbound', response);
47
+ }
48
+
49
+ if (response[inboundTransformPromise]) {
50
+ return response[inboundTransformPromise];
51
+ }
52
+
53
+ const transformPromise = this.webex.transform('inbound', response).catch((error) => {
54
+ Reflect.deleteProperty(response, inboundTransformPromise);
55
+
56
+ throw error;
57
+ });
58
+
59
+ // Store the in-flight promise so concurrent interceptor pipelines share the same transform.
60
+ Object.defineProperty(response, inboundTransformPromise, {
61
+ configurable: true,
62
+ value: transformPromise,
63
+ });
64
+
65
+ return transformPromise;
44
66
  }
45
67
 
46
68
  /**
@@ -4,7 +4,8 @@
4
4
 
5
5
  import {assert} from '@webex/test-helper-chai';
6
6
  import {capitalize} from 'lodash';
7
- import WebexCore from '@webex/webex-core';
7
+ import sinon from 'sinon';
8
+ import WebexCore, {PayloadTransformerInterceptor} from '@webex/webex-core';
8
9
  // TODO: fix circular dependency core->metrics->core https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-515520
9
10
  require('@webex/internal-plugin-metrics');
10
11
 
@@ -153,5 +154,122 @@ describe('webex-core', () => {
153
154
  ));
154
155
  });
155
156
  });
157
+
158
+ describe('PayloadTransformerInterceptor repeated inbound transforms', () => {
159
+ const createInterceptor = (skipRepeatedInboundTransforms) => {
160
+ const transform = sinon.stub().callsFake((direction, value) => Promise.resolve(value));
161
+ const interceptor = new PayloadTransformerInterceptor({
162
+ webex: {
163
+ config: {payloadTransformer: {skipRepeatedInboundTransforms}},
164
+ transform,
165
+ },
166
+ });
167
+
168
+ return {interceptor, transform};
169
+ };
170
+
171
+ describe('#onResponse()', () => {
172
+ it('transforms the same response every time when skipping repeated transforms is disabled', async () => {
173
+ const {interceptor, transform} = createInterceptor(false);
174
+ const response = {};
175
+
176
+ await interceptor.onResponse({}, response);
177
+ await interceptor.onResponse({}, response);
178
+
179
+ assert.calledTwice(transform);
180
+ });
181
+
182
+ it('transforms the same response only once when repeated transforms are skipped', async () => {
183
+ const {interceptor, transform} = createInterceptor(true);
184
+ const response = {};
185
+
186
+ assert.equal(await interceptor.onResponse({}, response), response);
187
+ assert.equal(await interceptor.onResponse({}, response), response);
188
+ assert.calledOnceWithExactly(transform, 'inbound', response);
189
+ });
190
+
191
+ it('shares an in-flight transform for concurrent calls with the same response', async () => {
192
+ const {interceptor, transform} = createInterceptor(true);
193
+ const response = {};
194
+ let resolveTransform;
195
+
196
+ transform.callsFake(
197
+ (direction, value) =>
198
+ new Promise((resolve) => {
199
+ resolveTransform = () => resolve(value);
200
+ })
201
+ );
202
+
203
+ const firstTransform = interceptor.onResponse({}, response);
204
+ const secondTransform = interceptor.onResponse({}, response);
205
+
206
+ assert.equal(firstTransform, secondTransform);
207
+ assert.calledOnceWithExactly(transform, 'inbound', response);
208
+
209
+ resolveTransform();
210
+
211
+ assert.equal(await firstTransform, response);
212
+ assert.equal(await secondTransform, response);
213
+ });
214
+
215
+ it('transforms distinct response objects independently', async () => {
216
+ const {interceptor, transform} = createInterceptor(true);
217
+ const firstResponse = {};
218
+ const secondResponse = {};
219
+
220
+ await interceptor.onResponse({}, firstResponse);
221
+ await interceptor.onResponse({}, secondResponse);
222
+
223
+ assert.calledTwice(transform);
224
+ assert.isTrue(transform.firstCall.calledWithExactly('inbound', firstResponse));
225
+ assert.isTrue(transform.secondCall.calledWithExactly('inbound', secondResponse));
226
+ });
227
+
228
+ it('retries transformation after a failed transform', async () => {
229
+ const {interceptor, transform} = createInterceptor(true);
230
+ const response = {};
231
+
232
+ transform.onFirstCall().rejects(new Error('transform failed'));
233
+
234
+ await assert.isRejected(interceptor.onResponse({}, response), 'transform failed');
235
+ assert.equal(await interceptor.onResponse({}, response), response);
236
+ assert.calledTwice(transform);
237
+ });
238
+
239
+ it('stores transform state as non-enumerable response metadata', async () => {
240
+ const {interceptor} = createInterceptor(true);
241
+ const response = {body: {value: true}};
242
+
243
+ await interceptor.onResponse({}, response);
244
+
245
+ const [marker] = Object.getOwnPropertySymbols(response);
246
+
247
+ assert.isDefined(marker);
248
+ assert.isFalse(Object.getOwnPropertyDescriptor(response, marker).enumerable);
249
+ assert.deepEqual(JSON.parse(JSON.stringify(response)), {body: {value: true}});
250
+ });
251
+
252
+ it('does not mark a response when transforms are disabled for that request', async () => {
253
+ const {interceptor, transform} = createInterceptor(true);
254
+ const response = {};
255
+
256
+ assert.equal(await interceptor.onResponse({disableTransform: true}, response), response);
257
+ assert.equal(await interceptor.onResponse({}, response), response);
258
+ assert.calledOnceWithExactly(transform, 'inbound', response);
259
+ });
260
+ });
261
+
262
+ describe('#onResponseError()', () => {
263
+ it('continues transforming repeated error objects independently', async () => {
264
+ const {interceptor, transform} = createInterceptor(true);
265
+ const reason = new Error('request failed');
266
+
267
+ await assert.isRejected(interceptor.onResponseError({}, reason), 'request failed');
268
+ await assert.isRejected(interceptor.onResponseError({}, reason), 'request failed');
269
+ assert.calledTwice(transform);
270
+ assert.alwaysCalledWithExactly(transform, 'inbound', reason);
271
+ });
272
+ });
273
+ });
156
274
  });
157
275
  });