ibm-cloud-sdk-core 4.0.2 → 4.0.4

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/.secrets.baseline CHANGED
@@ -3,7 +3,7 @@
3
3
  "files": "package-lock.json|^.secrets.baseline$",
4
4
  "lines": null
5
5
  },
6
- "generated_at": "2022-12-20T17:56:56Z",
6
+ "generated_at": "2023-01-19T23:27:48Z",
7
7
  "plugins_used": [
8
8
  {
9
9
  "name": "AWSKeyDetector"
@@ -91,6 +91,16 @@
91
91
  "verified_result": null
92
92
  }
93
93
  ],
94
+ "CHANGELOG.md": [
95
+ {
96
+ "hashed_secret": "bc2f74c22f98f7b6ffbc2f67453dbfa99bce9a32",
97
+ "is_secret": false,
98
+ "is_verified": false,
99
+ "line_number": 20,
100
+ "type": "Secret Keyword",
101
+ "verified_result": null
102
+ }
103
+ ],
94
104
  "README.md": [
95
105
  {
96
106
  "hashed_secret": "32e8612d8ca77c7ea8374aa7918db8e5df9252ed",
@@ -484,7 +494,7 @@
484
494
  "hashed_secret": "a7ef1be18bb8d37af79f3d87761a203378bf26a2",
485
495
  "is_secret": false,
486
496
  "is_verified": false,
487
- "line_number": 145,
497
+ "line_number": 146,
488
498
  "type": "Secret Keyword",
489
499
  "verified_result": null
490
500
  }
@@ -524,7 +534,7 @@
524
534
  }
525
535
  ]
526
536
  },
527
- "version": "0.13.1+ibm.55.dss",
537
+ "version": "0.13.1+ibm.56.dss",
528
538
  "word_list": {
529
539
  "file": null,
530
540
  "hash": null
package/Authentication.md CHANGED
@@ -6,15 +6,15 @@ The node-sdk-core project supports the following types of authentication:
6
6
  - Container Authentication
7
7
  - VPC Instance Authentication
8
8
  - Cloud Pak for Data Authentication
9
- - No Authentication
9
+ - No Authentication (for testing)
10
10
 
11
- The SDK user configures the appropriate type of authentication for use with service instances.
11
+ The SDK user configures the appropriate type of authentication for use with service instances.
12
12
  The authentication types that are appropriate for a particular service may vary from service to service,
13
13
  so it is important for the SDK user to consult with the appropriate service documentation to understand
14
14
  which authentication types are supported for that service.
15
15
 
16
16
  The node-sdk-core allows an authenticator to be specified in one of two ways:
17
- 1. programmatically - the SDK user invokes the appropriate function(s) to create an instance of the
17
+ 1. programmatically - the SDK user invokes the appropriate function(s) to create an instance of the
18
18
  desired authenticator and then passes the authenticator instance when constructing an instance of the service.
19
19
  2. configuration - the SDK user provides external configuration information (in the form of environment variables
20
20
  or a credentials file) to indicate the type of authenticator, along with the configuration of the necessary properties
@@ -143,15 +143,15 @@ const service = ExampleServiceV1.newInstance(options);
143
143
  Note that the use of external configuration is not as useful with the `BearerTokenAuthenticator` as it
144
144
  is for other authenticator types because bearer tokens typically need to be obtained and refreshed
145
145
  programmatically since they normally have a relatively short lifespan before they expire. This
146
- authenticator type is intended for situations in which the application will be managing the bearer
146
+ authenticator type is intended for situations in which the application will be managing the bearer
147
147
  token itself in terms of initial acquisition and refreshing as needed.
148
148
 
149
149
 
150
150
  ## Identity and Access Management Authentication (IAM)
151
151
  The `IamAuthenticator` will accept a user-supplied api key and will perform
152
152
  the necessary interactions with the IAM token service to obtain a suitable
153
- bearer token for the specified api key. The authenticator will also obtain
154
- a new bearer token when the current token expires. The bearer token is
153
+ bearer token for the specified api key. The authenticator will also obtain
154
+ a new bearer token when the current token expires. The bearer token is
155
155
  then added to each outbound request in the `Authorization` header in the
156
156
  form:
157
157
  ```
@@ -276,15 +276,15 @@ However, if your application is using an instance of a service in the "staging"
276
276
  then you would also need to configure the authenticator to use the IAM token service "staging"
277
277
  endpoint as well (`https://iam.test.cloud.ibm.com`).
278
278
 
279
- - clientId/clientSecret: (optional) The `clientId` and `clientSecret` fields are used to form a
280
- "basic auth" Authorization header for interactions with the IAM token service. If neither field
281
- is specified, then no Authorization header will be sent with token server requests. These fields
279
+ - clientId/clientSecret: (optional) The `clientId` and `clientSecret` fields are used to form a
280
+ "basic auth" Authorization header for interactions with the IAM token service. If neither field
281
+ is specified, then no Authorization header will be sent with token server requests. These fields
282
282
  are optional, but must be specified together.
283
283
 
284
284
  - scope: (optional) the scope to be associated with the IAM access token.
285
285
  If not specified, then no scope will be associated with the access token.
286
286
 
287
- - disableSslVerification: (optional) A flag that indicates whether verificaton of the server's SSL
287
+ - disableSslVerification: (optional) A flag that indicates whether verificaton of the server's SSL
288
288
  certificate should be disabled or not. The default value is `false`.
289
289
 
290
290
  - headers: (optional) A set of key/value pairs that will be sent as HTTP headers in requests
@@ -358,8 +358,9 @@ The IAM access token is added to each outbound request in the `Authorization` he
358
358
 
359
359
  - iamProfileId: (optional) the id of the linked trusted IAM profile to be used when obtaining the IAM access token.
360
360
 
361
- - url: (optional) The VPC Instance Metadata Service's base URL.
362
- The default value of this property is `http://169.254.169.254`, and should not need to be specified in normal situations.
361
+ - url: (optional) The VPC Instance Metadata Service's base URL.
362
+ The default value of this property is `http://169.254.169.254`. However, if the VPC Instance Metadata Service is configured
363
+ with the HTTP Secure Protocol setting (`https`), then you should configure this property to be `https://api.metadata.cloud.ibm.com`.
363
364
 
364
365
  Usage Notes:
365
366
  1. At most one of `iamProfileCrn` or `iamProfileId` may be specified. The specified value must map
@@ -367,7 +368,7 @@ to a trusted IAM profile that has been linked to the compute resource (virtual s
367
368
 
368
369
  2. If both `iamProfileCrn` and `iamProfileId` are specified, then an error occurs.
369
370
 
370
- 3. If neither `iamProfileCrn` nor `iamProfileId` are specified, then the default trusted profile linked to the
371
+ 3. If neither `iamProfileCrn` nor `iamProfileId` are specified, then the default trusted profile linked to the
371
372
  compute resource will be used to perform the IAM token exchange.
372
373
  If no default trusted profile is defined for the compute resource, then an error occurs.
373
374
 
@@ -412,7 +413,7 @@ const service = ExampleServiceV1.newInstance(options);
412
413
 
413
414
  ## Cloud Pak for Data Authentication
414
415
  The `CloudPakForDataAuthenticator` will accept a user-supplied username value, along with either a
415
- password or apikey, and will
416
+ password or apikey, and will
416
417
  perform the necessary interactions with the Cloud Pak for Data token service to obtain a suitable
417
418
  bearer token. The authenticator will also obtain a new bearer token when the current token expires.
418
419
  The bearer token is then added to each outbound request in the `Authorization` header in the
@@ -433,7 +434,7 @@ Exactly one of password or apikey should be specified.
433
434
  - url: (required) The URL representing the Cloud Pak for Data token service endpoint's base URL string.
434
435
  This value should not include the `/v1/authorize` path portion.
435
436
 
436
- - disableSslVerification: (optional) A flag that indicates whether verificaton of the server's SSL
437
+ - disableSslVerification: (optional) A flag that indicates whether verificaton of the server's SSL
437
438
  certificate should be disabled or not. The default value is `false`.
438
439
 
439
440
  - headers: (optional) A set of key/value pairs that will be sent as HTTP headers in requests
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [4.0.4](https://github.com/IBM/node-sdk-core/compare/v4.0.3...v4.0.4) (2023-02-27)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * return json error response body as object ([#238](https://github.com/IBM/node-sdk-core/issues/238)) ([6f201b7](https://github.com/IBM/node-sdk-core/commit/6f201b798df234510a6abf6baac96b81c72636bf))
7
+
8
+ ## [4.0.3](https://github.com/IBM/node-sdk-core/compare/v4.0.2...v4.0.3) (2023-01-09)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **VpcInstanceAuthenticator:** use correct version string ([4a1411a](https://github.com/IBM/node-sdk-core/commit/4a1411a76a09e9b1ade2c94bd98e63f79d845494))
14
+
1
15
  ## [4.0.2](https://github.com/IBM/node-sdk-core/compare/v4.0.1...v4.0.2) (2022-12-30)
2
16
 
3
17
 
package/MIGRATION-V4.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ## Breaking Changes
4
4
 
5
5
  ### Node Version
6
- Node versions 12 is longer supported - 14 is the minimum version supported.
6
+ Node version 12 is no longer supported - 14 is the minimum version supported.
7
7
 
8
8
  ### TypeScript Version
9
9
  The `typescript` development dependnecy is now required to be at least version 4.
package/README.md CHANGED
@@ -27,13 +27,14 @@ class YourSDK extends BaseService { ... }
27
27
  ```
28
28
 
29
29
  ## Authentication
30
- This library provides a set of Authenticators used to authenticate requests from an SDK. There are authenticators for the following authentication schemes:
31
- - No Auth
32
- - Basic
33
- - Bearer Token
34
- - IAM
35
- - CP4D
36
- - Container
30
+ The node-sdk-core project supports the following types of authentication:
31
+ - Basic Authentication
32
+ - Bearer Token Authentication
33
+ - Identity and Access Management (IAM) Authentication
34
+ - Container Authentication
35
+ - VPC Instance Authentication
36
+ - Cloud Pak for Data Authentication
37
+ - No Authentication (for testing)
37
38
 
38
39
  There are two ways to create an authenticator:
39
40
  1. Creating an instance and providing credentials programmatically
@@ -2,6 +2,7 @@
2
2
  <Targets>
3
3
  <Target path=".">
4
4
  <Exclude>scripts/</Exclude>
5
+ <Exclude>test/</Exclude>
5
6
  </Target>
6
7
  </Targets>
7
- </Configuration>
8
+ </Configuration>
@@ -1,5 +1,5 @@
1
1
  /**
2
- * (C) Copyright IBM Corp. 2021, 2022.
2
+ * (C) Copyright IBM Corp. 2021, 2023.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * (C) Copyright IBM Corp. 2021, 2022.
3
+ * (C) Copyright IBM Corp. 2021, 2023.
4
4
  *
5
5
  * Licensed under the Apache License, Version 2.0 (the "License");
6
6
  * you may not use this file except in compliance with the License.
@@ -74,7 +74,7 @@ var logger_1 = __importDefault(require("../../lib/logger"));
74
74
  var utils_1 = require("../utils");
75
75
  var jwt_token_manager_1 = require("./jwt-token-manager");
76
76
  var DEFAULT_IMS_ENDPOINT = 'http://169.254.169.254';
77
- var METADATA_SERVICE_VERSION = '2021-09-20';
77
+ var METADATA_SERVICE_VERSION = '2022-03-01';
78
78
  /**
79
79
  * Token Manager for VPC Instance Authentication.
80
80
  */
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## FileObject interface
6
6
 
7
- (C) Copyright IBM Corp. 2014, 2022.
7
+ (C) Copyright IBM Corp. 2014, 2023.
8
8
 
9
9
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
10
10
 
@@ -0,0 +1,26 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [ibm-cloud-sdk-core](./ibm-cloud-sdk-core.md) &gt; [isJsonMimeType](./ibm-cloud-sdk-core.isjsonmimetype.md)
4
+
5
+ ## isJsonMimeType() function
6
+
7
+ Returns true if and only if "mimeType" is a "JSON-like" mime type (e.g. "application/json; charset=utf-8").
8
+
9
+ <b>Signature:</b>
10
+
11
+ ```typescript
12
+ export declare function isJsonMimeType(mimeType: string): boolean;
13
+ ```
14
+
15
+ ## Parameters
16
+
17
+ | Parameter | Type | Description |
18
+ | --- | --- | --- |
19
+ | mimeType | string | the mimeType string |
20
+
21
+ <b>Returns:</b>
22
+
23
+ boolean
24
+
25
+ true if "mimeType" represents a JSON media type and false otherwise
26
+
@@ -50,6 +50,7 @@
50
50
  | [isFileData(obj)](./ibm-cloud-sdk-core.isfiledata.md) | |
51
51
  | [isFileWithMetadata(obj)](./ibm-cloud-sdk-core.isfilewithmetadata.md) | |
52
52
  | [isHTML(text)](./ibm-cloud-sdk-core.ishtml.md) | Return true if 'text' is html |
53
+ | [isJsonMimeType(mimeType)](./ibm-cloud-sdk-core.isjsonmimetype.md) | Returns true if and only if "mimeType" is a "JSON-like" mime type (e.g. "application/json; charset=utf-8"). |
53
54
  | [onlyOne(a, b)](./ibm-cloud-sdk-core.onlyone.md) | Checks for only one of two elements being defined. Returns true if a is defined and b is undefined, or vice versa. Returns false if both are defined or both are undefined. |
54
55
  | [readCredentialsFile()](./ibm-cloud-sdk-core.readcredentialsfile.md) | Return a config object based on a credentials file. Credentials files can be specified filepath via the environment variable: <code>IBM_CREDENTIALS_FILE</code>. |
55
56
  | [readCrTokenFile(filepath)](./ibm-cloud-sdk-core.readcrtokenfile.md) | |
@@ -66,7 +67,7 @@
66
67
  | Interface | Description |
67
68
  | --- | --- |
68
69
  | [AuthenticatorInterface](./ibm-cloud-sdk-core.authenticatorinterface.md) | This interface defines the common methods associated with an Authenticator implementation. |
69
- | [FileObject](./ibm-cloud-sdk-core.fileobject.md) | <p>(C) Copyright IBM Corp. 2014, 2022.</p><p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at</p><p>http://www.apache.org/licenses/LICENSE-2.0</p><p>Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</p> |
70
+ | [FileObject](./ibm-cloud-sdk-core.fileobject.md) | <p>(C) Copyright IBM Corp. 2014, 2023.</p><p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at</p><p>http://www.apache.org/licenses/LICENSE-2.0</p><p>Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</p> |
70
71
  | [FileOptions](./ibm-cloud-sdk-core.fileoptions.md) | |
71
72
  | [FileStream](./ibm-cloud-sdk-core.filestream.md) | |
72
73
  | [FileWithMetadata](./ibm-cloud-sdk-core.filewithmetadata.md) | |
@@ -2934,7 +2934,7 @@
2934
2934
  {
2935
2935
  "kind": "Interface",
2936
2936
  "canonicalReference": "ibm-cloud-sdk-core!FileObject:interface",
2937
- "docComment": "/**\n * (C) Copyright IBM Corp. 2014, 2022.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n",
2937
+ "docComment": "/**\n * (C) Copyright IBM Corp. 2014, 2023.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n",
2938
2938
  "excerptTokens": [
2939
2939
  {
2940
2940
  "kind": "Content",
@@ -4864,6 +4864,51 @@
4864
4864
  ],
4865
4865
  "name": "isHTML"
4866
4866
  },
4867
+ {
4868
+ "kind": "Function",
4869
+ "canonicalReference": "ibm-cloud-sdk-core!isJsonMimeType:function(1)",
4870
+ "docComment": "/**\n * Returns true if and only if \"mimeType\" is a \"JSON-like\" mime type (e.g. \"application/json; charset=utf-8\").\n *\n * @param mimeType - the mimeType string\n *\n * @returns true if \"mimeType\" represents a JSON media type and false otherwise\n */\n",
4871
+ "excerptTokens": [
4872
+ {
4873
+ "kind": "Content",
4874
+ "text": "export declare function isJsonMimeType(mimeType: "
4875
+ },
4876
+ {
4877
+ "kind": "Content",
4878
+ "text": "string"
4879
+ },
4880
+ {
4881
+ "kind": "Content",
4882
+ "text": "): "
4883
+ },
4884
+ {
4885
+ "kind": "Content",
4886
+ "text": "boolean"
4887
+ },
4888
+ {
4889
+ "kind": "Content",
4890
+ "text": ";"
4891
+ }
4892
+ ],
4893
+ "fileUrlPath": "dist/es/lib/helper.d.ts",
4894
+ "returnTypeTokenRange": {
4895
+ "startIndex": 3,
4896
+ "endIndex": 4
4897
+ },
4898
+ "releaseTag": "Public",
4899
+ "overloadIndex": 1,
4900
+ "parameters": [
4901
+ {
4902
+ "parameterName": "mimeType",
4903
+ "parameterTypeTokenRange": {
4904
+ "startIndex": 1,
4905
+ "endIndex": 2
4906
+ },
4907
+ "isOptional": false
4908
+ }
4909
+ ],
4910
+ "name": "isJsonMimeType"
4911
+ },
4867
4912
  {
4868
4913
  "kind": "Class",
4869
4914
  "canonicalReference": "ibm-cloud-sdk-core!JwtTokenManager:class",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * (C) Copyright IBM Corp. 2021, 2022.
2
+ * (C) Copyright IBM Corp. 2021, 2023.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * (C) Copyright IBM Corp. 2021, 2022.
2
+ * (C) Copyright IBM Corp. 2021, 2023.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import logger from '../../lib/logger';
26
26
  import { atMostOne } from '../utils';
27
27
  import { JwtTokenManager } from './jwt-token-manager';
28
28
  const DEFAULT_IMS_ENDPOINT = 'http://169.254.169.254';
29
- const METADATA_SERVICE_VERSION = '2021-09-20';
29
+ const METADATA_SERVICE_VERSION = '2022-03-01';
30
30
  /**
31
31
  * Token Manager for VPC Instance Authentication.
32
32
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * (C) Copyright IBM Corp. 2014, 2022.
2
+ * (C) Copyright IBM Corp. 2014, 2023.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -117,3 +117,10 @@ export declare function toLowerKeys(obj: Object): Object;
117
117
  * @returns the formatted URL with all variable placeholders replaced by values.
118
118
  */
119
119
  export declare function constructServiceUrl(parameterizedUrl: string, defaultUrlVariables: Map<string, string>, providedUrlVariables: Map<string, string> | null): string;
120
+ /**
121
+ * Returns true if and only if "mimeType" is a "JSON-like" mime type
122
+ * (e.g. "application/json; charset=utf-8").
123
+ * @param mimeType - the mimeType string
124
+ * @returns true if "mimeType" represents a JSON media type and false otherwise
125
+ */
126
+ export declare function isJsonMimeType(mimeType: string): boolean;
package/es/lib/helper.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * (C) Copyright IBM Corp. 2014, 2022.
2
+ * (C) Copyright IBM Corp. 2014, 2023.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -293,3 +293,13 @@ export function constructServiceUrl(parameterizedUrl, defaultUrlVariables, provi
293
293
  });
294
294
  return formattedUrl;
295
295
  }
296
+ /**
297
+ * Returns true if and only if "mimeType" is a "JSON-like" mime type
298
+ * (e.g. "application/json; charset=utf-8").
299
+ * @param mimeType - the mimeType string
300
+ * @returns true if "mimeType" represents a JSON media type and false otherwise
301
+ */
302
+ export function isJsonMimeType(mimeType) {
303
+ logger.debug(`Determining if the mime type '${mimeType}' specifies JSON content.`);
304
+ return !!mimeType && /^application\/json(\s*;.*)?$/i.test(mimeType);
305
+ }
@@ -31,7 +31,7 @@ import { Agent } from 'https';
31
31
  import isStream from 'isstream';
32
32
  import { stringify } from 'querystring';
33
33
  import { gzipSync } from 'zlib';
34
- import { buildRequestFileObject, isEmptyObject, isFileData, isFileWithMetadata, stripTrailingSlash, } from './helper';
34
+ import { buildRequestFileObject, isEmptyObject, isFileData, isFileWithMetadata, isJsonMimeType, stripTrailingSlash, } from './helper';
35
35
  import logger from './logger';
36
36
  import { streamToPromise } from './stream-to-promise';
37
37
  import { CookieInterceptor } from './cookie-support';
@@ -207,7 +207,7 @@ export class RequestWrapper {
207
207
  delete res.request;
208
208
  // the other sdks use the interface `result` for the body
209
209
  // eslint-disable-next-line @typescript-eslint/dot-notation
210
- res['result'] = res.data;
210
+ res['result'] = ensureJSONResponseBodyIsObject(res);
211
211
  delete res.data;
212
212
  // return another promise that resolves with 'res' to be handled in generated code
213
213
  return res;
@@ -239,20 +239,19 @@ export class RequestWrapper {
239
239
  error.status = axiosError.status;
240
240
  error.code = axiosError.status; // ** deprecated **
241
241
  error.message = parseServiceErrorMessage(axiosError.data) || axiosError.statusText;
242
- // some services bury the useful error message within 'data'
243
- // adding it to the error under the key 'body' as a string or object
242
+ // attach the error response body to the error
244
243
  let errorBody;
245
244
  try {
246
- // try/catch to handle objects with circular references
245
+ // try/catch to detect objects with circular references
247
246
  errorBody = JSON.stringify(axiosError.data);
248
247
  }
249
248
  catch (e) {
250
- // ignore the error, use the object, and tack on a warning
249
+ logger.warn('Error field `result` contains circular reference(s)');
250
+ logger.debug(`Failed to stringify error response body: ${e}`);
251
251
  errorBody = axiosError.data;
252
- errorBody.warning = 'Body contains circular reference';
253
- logger.error(`Failed to stringify axiosError: ${e}`);
254
252
  }
255
- error.body = errorBody;
253
+ error.result = ensureJSONResponseBodyIsObject(axiosError);
254
+ error.body = errorBody; // ** deprecated **
256
255
  // attach headers to error object
257
256
  error.headers = axiosError.headers;
258
257
  // print a more descriptive error message for auth issues
@@ -452,3 +451,33 @@ function parseServiceErrorMessage(response) {
452
451
  logger.info(`Parsing service error message: ${message}`);
453
452
  return message;
454
453
  }
454
+ /**
455
+ * Check response for a JSON content type and a string-formatted body. If those
456
+ * conditions are met, we want to return an object for the body to the user. If
457
+ * the JSON string coming from the service is invalid, we want to raise an
458
+ * exception.
459
+ *
460
+ * @param response - incoming response object
461
+ * @returns response body - as either an object or a string
462
+ * @throws error - if the content is meant as JSON but is malformed
463
+ */
464
+ function ensureJSONResponseBodyIsObject(response) {
465
+ if (typeof response.data !== 'string' || !isJsonMimeType(response.headers['content-type'])) {
466
+ return response.data;
467
+ }
468
+ // If the content is supposed to be JSON but axios gave us a string, it is most
469
+ // likely due to the fact that the service sent malformed JSON, which is an error.
470
+ //
471
+ // We'll try to parse the string and return a proper object to the user but if
472
+ // it fails, we'll log an error and raise an exception.
473
+ let dataAsObject = response.data;
474
+ try {
475
+ dataAsObject = JSON.parse(response.data);
476
+ }
477
+ catch (e) {
478
+ logger.error('Response body was supposed to have JSON content but JSON parsing failed.');
479
+ logger.error(`Malformed JSON string: ${response.data}`);
480
+ throw e;
481
+ }
482
+ return dataAsObject;
483
+ }
@@ -309,6 +309,9 @@ export function isFileWithMetadata(obj: any): obj is FileWithMetadata;
309
309
  // @public
310
310
  export function isHTML(text: string): boolean;
311
311
 
312
+ // @public
313
+ export function isJsonMimeType(mimeType: string): boolean;
314
+
312
315
  // @public
313
316
  export class JwtTokenManager extends TokenManager {
314
317
  constructor(options: JwtTokenManagerOptions);
@@ -615,7 +615,7 @@ declare function expectToBePromise(sdkPromise: any): void;
615
615
  export declare function fileExistsAtPath(filepath: string): boolean;
616
616
 
617
617
  /**
618
- * (C) Copyright IBM Corp. 2014, 2022.
618
+ * (C) Copyright IBM Corp. 2014, 2023.
619
619
  *
620
620
  * Licensed under the Apache License, Version 2.0 (the "License");
621
621
  * you may not use this file except in compliance with the License.
@@ -964,6 +964,14 @@ export declare function isFileWithMetadata(obj: any): obj is FileWithMetadata;
964
964
  */
965
965
  export declare function isHTML(text: string): boolean;
966
966
 
967
+ /**
968
+ * Returns true if and only if "mimeType" is a "JSON-like" mime type
969
+ * (e.g. "application/json; charset=utf-8").
970
+ * @param mimeType - the mimeType string
971
+ * @returns true if "mimeType" represents a JSON media type and false otherwise
972
+ */
973
+ export declare function isJsonMimeType(mimeType: string): boolean;
974
+
967
975
  /**
968
976
  * A class for shared functionality for parsing, storing, and requesting
969
977
  * JWT tokens. Intended to be used as a parent to be extended for token
package/lib/helper.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * (C) Copyright IBM Corp. 2014, 2022.
2
+ * (C) Copyright IBM Corp. 2014, 2023.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -117,3 +117,10 @@ export declare function toLowerKeys(obj: Object): Object;
117
117
  * @returns the formatted URL with all variable placeholders replaced by values.
118
118
  */
119
119
  export declare function constructServiceUrl(parameterizedUrl: string, defaultUrlVariables: Map<string, string>, providedUrlVariables: Map<string, string> | null): string;
120
+ /**
121
+ * Returns true if and only if "mimeType" is a "JSON-like" mime type
122
+ * (e.g. "application/json; charset=utf-8").
123
+ * @param mimeType - the mimeType string
124
+ * @returns true if "mimeType" represents a JSON media type and false otherwise
125
+ */
126
+ export declare function isJsonMimeType(mimeType: string): boolean;
package/lib/helper.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * (C) Copyright IBM Corp. 2014, 2022.
3
+ * (C) Copyright IBM Corp. 2014, 2023.
4
4
  *
5
5
  * Licensed under the Apache License, Version 2.0 (the "License");
6
6
  * you may not use this file except in compliance with the License.
@@ -63,7 +63,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
63
63
  return (mod && mod.__esModule) ? mod : { "default": mod };
64
64
  };
65
65
  Object.defineProperty(exports, "__esModule", { value: true });
66
- exports.constructServiceUrl = exports.toLowerKeys = exports.buildRequestFileObject = exports.getFormat = exports.isHTML = exports.validateParams = exports.getMissingParams = exports.getQueryParam = exports.stripTrailingSlash = exports.getContentType = exports.isEmptyObject = exports.isFileData = exports.isFileWithMetadata = void 0;
66
+ exports.isJsonMimeType = exports.constructServiceUrl = exports.toLowerKeys = exports.buildRequestFileObject = exports.getFormat = exports.isHTML = exports.validateParams = exports.getMissingParams = exports.getQueryParam = exports.stripTrailingSlash = exports.getContentType = exports.isEmptyObject = exports.isFileData = exports.isFileWithMetadata = void 0;
67
67
  var isstream_1 = require("isstream");
68
68
  var mime_types_1 = require("mime-types");
69
69
  var path_1 = require("path");
@@ -363,3 +363,14 @@ function constructServiceUrl(parameterizedUrl, defaultUrlVariables, providedUrlV
363
363
  return formattedUrl;
364
364
  }
365
365
  exports.constructServiceUrl = constructServiceUrl;
366
+ /**
367
+ * Returns true if and only if "mimeType" is a "JSON-like" mime type
368
+ * (e.g. "application/json; charset=utf-8").
369
+ * @param mimeType - the mimeType string
370
+ * @returns true if "mimeType" represents a JSON media type and false otherwise
371
+ */
372
+ function isJsonMimeType(mimeType) {
373
+ logger_1.default.debug("Determining if the mime type '".concat(mimeType, "' specifies JSON content."));
374
+ return !!mimeType && /^application\/json(\s*;.*)?$/i.test(mimeType);
375
+ }
376
+ exports.isJsonMimeType = isJsonMimeType;
@@ -295,7 +295,7 @@ var RequestWrapper = /** @class */ (function () {
295
295
  delete res.request;
296
296
  // the other sdks use the interface `result` for the body
297
297
  // eslint-disable-next-line @typescript-eslint/dot-notation
298
- res['result'] = res.data;
298
+ res['result'] = ensureJSONResponseBodyIsObject(res);
299
299
  delete res.data;
300
300
  // return another promise that resolves with 'res' to be handled in generated code
301
301
  return res;
@@ -329,20 +329,19 @@ var RequestWrapper = /** @class */ (function () {
329
329
  error.status = axiosError.status;
330
330
  error.code = axiosError.status; // ** deprecated **
331
331
  error.message = parseServiceErrorMessage(axiosError.data) || axiosError.statusText;
332
- // some services bury the useful error message within 'data'
333
- // adding it to the error under the key 'body' as a string or object
332
+ // attach the error response body to the error
334
333
  var errorBody = void 0;
335
334
  try {
336
- // try/catch to handle objects with circular references
335
+ // try/catch to detect objects with circular references
337
336
  errorBody = JSON.stringify(axiosError.data);
338
337
  }
339
338
  catch (e) {
340
- // ignore the error, use the object, and tack on a warning
339
+ logger_1.default.warn('Error field `result` contains circular reference(s)');
340
+ logger_1.default.debug("Failed to stringify error response body: ".concat(e));
341
341
  errorBody = axiosError.data;
342
- errorBody.warning = 'Body contains circular reference';
343
- logger_1.default.error("Failed to stringify axiosError: ".concat(e));
344
342
  }
345
- error.body = errorBody;
343
+ error.result = ensureJSONResponseBodyIsObject(axiosError);
344
+ error.body = errorBody; // ** deprecated **
346
345
  // attach headers to error object
347
346
  error.headers = axiosError.headers;
348
347
  // print a more descriptive error message for auth issues
@@ -555,3 +554,33 @@ function parseServiceErrorMessage(response) {
555
554
  logger_1.default.info("Parsing service error message: ".concat(message));
556
555
  return message;
557
556
  }
557
+ /**
558
+ * Check response for a JSON content type and a string-formatted body. If those
559
+ * conditions are met, we want to return an object for the body to the user. If
560
+ * the JSON string coming from the service is invalid, we want to raise an
561
+ * exception.
562
+ *
563
+ * @param response - incoming response object
564
+ * @returns response body - as either an object or a string
565
+ * @throws error - if the content is meant as JSON but is malformed
566
+ */
567
+ function ensureJSONResponseBodyIsObject(response) {
568
+ if (typeof response.data !== 'string' || !(0, helper_1.isJsonMimeType)(response.headers['content-type'])) {
569
+ return response.data;
570
+ }
571
+ // If the content is supposed to be JSON but axios gave us a string, it is most
572
+ // likely due to the fact that the service sent malformed JSON, which is an error.
573
+ //
574
+ // We'll try to parse the string and return a proper object to the user but if
575
+ // it fails, we'll log an error and raise an exception.
576
+ var dataAsObject = response.data;
577
+ try {
578
+ dataAsObject = JSON.parse(response.data);
579
+ }
580
+ catch (e) {
581
+ logger_1.default.error('Response body was supposed to have JSON content but JSON parsing failed.');
582
+ logger_1.default.error("Malformed JSON string: ".concat(response.data));
583
+ throw e;
584
+ }
585
+ return dataAsObject;
586
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ibm-cloud-sdk-core",
3
- "version": "4.0.2",
3
+ "version": "4.0.4",
4
4
  "description": "Core functionality to support SDKs generated with IBM's OpenAPI SDK Generator.",
5
5
  "main": "index.js",
6
6
  "typings": "./es/index.d.ts",
@@ -2934,7 +2934,7 @@
2934
2934
  {
2935
2935
  "kind": "Interface",
2936
2936
  "canonicalReference": "ibm-cloud-sdk-core!FileObject:interface",
2937
- "docComment": "/**\n * (C) Copyright IBM Corp. 2014, 2022.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n",
2937
+ "docComment": "/**\n * (C) Copyright IBM Corp. 2014, 2023.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n */\n",
2938
2938
  "excerptTokens": [
2939
2939
  {
2940
2940
  "kind": "Content",
@@ -4864,6 +4864,51 @@
4864
4864
  ],
4865
4865
  "name": "isHTML"
4866
4866
  },
4867
+ {
4868
+ "kind": "Function",
4869
+ "canonicalReference": "ibm-cloud-sdk-core!isJsonMimeType:function(1)",
4870
+ "docComment": "/**\n * Returns true if and only if \"mimeType\" is a \"JSON-like\" mime type (e.g. \"application/json; charset=utf-8\").\n *\n * @param mimeType - the mimeType string\n *\n * @returns true if \"mimeType\" represents a JSON media type and false otherwise\n */\n",
4871
+ "excerptTokens": [
4872
+ {
4873
+ "kind": "Content",
4874
+ "text": "export declare function isJsonMimeType(mimeType: "
4875
+ },
4876
+ {
4877
+ "kind": "Content",
4878
+ "text": "string"
4879
+ },
4880
+ {
4881
+ "kind": "Content",
4882
+ "text": "): "
4883
+ },
4884
+ {
4885
+ "kind": "Content",
4886
+ "text": "boolean"
4887
+ },
4888
+ {
4889
+ "kind": "Content",
4890
+ "text": ";"
4891
+ }
4892
+ ],
4893
+ "fileUrlPath": "dist/es/lib/helper.d.ts",
4894
+ "returnTypeTokenRange": {
4895
+ "startIndex": 3,
4896
+ "endIndex": 4
4897
+ },
4898
+ "releaseTag": "Public",
4899
+ "overloadIndex": 1,
4900
+ "parameters": [
4901
+ {
4902
+ "parameterName": "mimeType",
4903
+ "parameterTypeTokenRange": {
4904
+ "startIndex": 1,
4905
+ "endIndex": 2
4906
+ },
4907
+ "isOptional": false
4908
+ }
4909
+ ],
4910
+ "name": "isJsonMimeType"
4911
+ },
4867
4912
  {
4868
4913
  "kind": "Class",
4869
4914
  "canonicalReference": "ibm-cloud-sdk-core!JwtTokenManager:class",
@@ -309,6 +309,9 @@ export function isFileWithMetadata(obj: any): obj is FileWithMetadata;
309
309
  // @public
310
310
  export function isHTML(text: string): boolean;
311
311
 
312
+ // @public
313
+ export function isJsonMimeType(mimeType: string): boolean;
314
+
312
315
  // @public
313
316
  export class JwtTokenManager extends TokenManager {
314
317
  constructor(options: JwtTokenManagerOptions);