@jsforce/jsforce-node 3.0.0-next.3 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/core.d.ts +0 -1
- package/lib/core.js +0 -1
- package/lib/jsforce.d.ts +0 -2
- package/lib/jsforce.js +0 -2
- package/lib/request.js +89 -22
- package/lib/types/common.d.ts +3 -0
- package/package.json +1 -1
- package/lib/jwtOAuth2.d.ts +0 -8
- package/lib/jwtOAuth2.js +0 -23
package/lib/core.d.ts
CHANGED
|
@@ -6,7 +6,6 @@ import VERSION from './VERSION';
|
|
|
6
6
|
import RecordReference from './record-reference';
|
|
7
7
|
import RecordStream from './record-stream';
|
|
8
8
|
export * from './oauth2';
|
|
9
|
-
export * from './jwtOAuth2';
|
|
10
9
|
export * from './connection';
|
|
11
10
|
export * from './query';
|
|
12
11
|
export * from './quick-action';
|
package/lib/core.js
CHANGED
|
@@ -46,7 +46,6 @@ exports.RecordReference = record_reference_1.default;
|
|
|
46
46
|
const record_stream_1 = __importDefault(require("./record-stream"));
|
|
47
47
|
exports.RecordStream = record_stream_1.default;
|
|
48
48
|
__exportStar(require("./oauth2"), exports);
|
|
49
|
-
__exportStar(require("./jwtOAuth2"), exports);
|
|
50
49
|
__exportStar(require("./connection"), exports);
|
|
51
50
|
__exportStar(require("./query"), exports);
|
|
52
51
|
__exportStar(require("./quick-action"), exports);
|
package/lib/jsforce.d.ts
CHANGED
|
@@ -6,7 +6,6 @@ import OAuth2 from './oauth2';
|
|
|
6
6
|
import SfDate from './date';
|
|
7
7
|
import { Registry } from './registry';
|
|
8
8
|
import { BrowserClient } from './browser/client';
|
|
9
|
-
import { JwtOAuth2 } from './jwtOAuth2';
|
|
10
9
|
/**
|
|
11
10
|
*
|
|
12
11
|
*/
|
|
@@ -14,7 +13,6 @@ declare class JSforce extends EventEmitter {
|
|
|
14
13
|
VERSION: typeof VERSION;
|
|
15
14
|
Connection: typeof Connection;
|
|
16
15
|
OAuth2: typeof OAuth2;
|
|
17
|
-
JwtOAuth2: typeof JwtOAuth2;
|
|
18
16
|
SfDate: typeof SfDate;
|
|
19
17
|
Date: typeof SfDate;
|
|
20
18
|
BrowserClient: typeof BrowserClient;
|
package/lib/jsforce.js
CHANGED
|
@@ -34,7 +34,6 @@ const oauth2_1 = __importDefault(require("./oauth2"));
|
|
|
34
34
|
const date_1 = __importDefault(require("./date"));
|
|
35
35
|
const registry_1 = __importDefault(require("./registry"));
|
|
36
36
|
const client_1 = __importStar(require("./browser/client"));
|
|
37
|
-
const jwtOAuth2_1 = require("./jwtOAuth2");
|
|
38
37
|
/**
|
|
39
38
|
*
|
|
40
39
|
*/
|
|
@@ -42,7 +41,6 @@ class JSforce extends events_1.EventEmitter {
|
|
|
42
41
|
VERSION = VERSION_1.default;
|
|
43
42
|
Connection = connection_1.default;
|
|
44
43
|
OAuth2 = oauth2_1.default;
|
|
45
|
-
JwtOAuth2 = jwtOAuth2_1.JwtOAuth2;
|
|
46
44
|
SfDate = date_1.default;
|
|
47
45
|
Date = date_1.default;
|
|
48
46
|
BrowserClient = client_1.BrowserClient;
|
package/lib/request.js
CHANGED
|
@@ -1,11 +1,34 @@
|
|
|
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
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
29
|
exports.setDefaults = void 0;
|
|
7
30
|
const stream_1 = require("stream");
|
|
8
|
-
const node_fetch_1 =
|
|
31
|
+
const node_fetch_1 = __importStar(require("node-fetch"));
|
|
9
32
|
const abort_controller_1 = __importDefault(require("abort-controller"));
|
|
10
33
|
const https_proxy_agent_1 = __importDefault(require("https-proxy-agent"));
|
|
11
34
|
const request_helper_1 = require("./request-helper");
|
|
@@ -33,7 +56,10 @@ async function startFetchRequest(request, options, input, output, emitter, count
|
|
|
33
56
|
const controller = new abort_controller_1.default();
|
|
34
57
|
let retryCount = 0;
|
|
35
58
|
const retryOpts = {
|
|
59
|
+
statusCodes: options.retry?.statusCodes ?? [429, 500, 502, 503, 504],
|
|
36
60
|
maxRetries: options.retry?.maxRetries ?? 5,
|
|
61
|
+
minTimeout: options.retry?.minTimeout ?? 500,
|
|
62
|
+
timeoutFactor: options.retry?.timeoutFactor ?? 2,
|
|
37
63
|
errorCodes: options.retry?.errorCodes ?? [
|
|
38
64
|
'ECONNRESET',
|
|
39
65
|
'ECONNREFUSED',
|
|
@@ -53,6 +79,40 @@ async function startFetchRequest(request, options, input, output, emitter, count
|
|
|
53
79
|
'DELETE',
|
|
54
80
|
],
|
|
55
81
|
};
|
|
82
|
+
const shouldRetryRequest = (maxRetry, resOrErr) => {
|
|
83
|
+
if (!retryOpts.methods.includes(request.method))
|
|
84
|
+
return false;
|
|
85
|
+
if (resOrErr instanceof node_fetch_1.Response) {
|
|
86
|
+
if (retryOpts.statusCodes.includes(resOrErr.status)) {
|
|
87
|
+
if (maxRetry === retryCount) {
|
|
88
|
+
const err = new Error('Request failed');
|
|
89
|
+
err.name = 'RequestRetryError';
|
|
90
|
+
throw err;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
if (maxRetry === retryCount)
|
|
100
|
+
return false;
|
|
101
|
+
// only retry on operational errors
|
|
102
|
+
// https://github.com/node-fetch/node-fetch/blob/2.x/ERROR-HANDLING.md#error-handling-with-node-fetch
|
|
103
|
+
if (resOrErr.name != 'FetchError')
|
|
104
|
+
return false;
|
|
105
|
+
if (is_1.default.nodeStream(body) && stream_1.Readable.isDisturbed(body)) {
|
|
106
|
+
logger.debug('Body of type stream was read, unable to retry request.');
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
if ('code' in resOrErr &&
|
|
110
|
+
resOrErr.code &&
|
|
111
|
+
retryOpts?.errorCodes?.includes(resOrErr.code))
|
|
112
|
+
return true;
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
56
116
|
const fetchWithRetries = async (maxRetry = retryOpts?.maxRetries) => {
|
|
57
117
|
const fetchOpts = {
|
|
58
118
|
...rrequest,
|
|
@@ -64,7 +124,21 @@ async function startFetchRequest(request, options, input, output, emitter, count
|
|
|
64
124
|
agent,
|
|
65
125
|
};
|
|
66
126
|
try {
|
|
67
|
-
|
|
127
|
+
const res = await (0, node_fetch_1.default)(url, fetchOpts);
|
|
128
|
+
if (shouldRetryRequest(retryOpts.maxRetries, res)) {
|
|
129
|
+
logger.debug(`retrying for the ${retryCount + 1} time`);
|
|
130
|
+
logger.debug(`reason: statusCode match`);
|
|
131
|
+
await sleep(retryCount === 0
|
|
132
|
+
? retryOpts.minTimeout
|
|
133
|
+
: retryOpts.minTimeout * retryOpts.timeoutFactor ** retryCount);
|
|
134
|
+
// NOTE: this event is only used by tests and will be removed at any time.
|
|
135
|
+
// jsforce may switch to node's fetch which doesn't emit this event on retries.
|
|
136
|
+
emitter.emit('retry', retryCount);
|
|
137
|
+
retryCount++;
|
|
138
|
+
return await fetchWithRetries(maxRetry);
|
|
139
|
+
}
|
|
140
|
+
// should we throw here if the maxRetry already happened and still got the same statusCode?
|
|
141
|
+
return res;
|
|
68
142
|
}
|
|
69
143
|
catch (err) {
|
|
70
144
|
logger.debug(`Request failed`);
|
|
@@ -73,27 +147,12 @@ async function startFetchRequest(request, options, input, output, emitter, count
|
|
|
73
147
|
if (error.name === 'AbortError') {
|
|
74
148
|
throw error;
|
|
75
149
|
}
|
|
76
|
-
|
|
77
|
-
// only retry on operational errors
|
|
78
|
-
if (error.name != 'FetchError')
|
|
79
|
-
return false;
|
|
80
|
-
if (retryCount === maxRetry)
|
|
81
|
-
return false;
|
|
82
|
-
if (!retryOpts?.methods?.includes(request.method))
|
|
83
|
-
return false;
|
|
84
|
-
if (is_1.default.nodeStream(body) && stream_1.Readable.isDisturbed(body)) {
|
|
85
|
-
logger.debug('Body of type stream was read, unable to retry request.');
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
if ('code' in error &&
|
|
89
|
-
error.code &&
|
|
90
|
-
retryOpts?.errorCodes?.includes(error.code))
|
|
91
|
-
return true;
|
|
92
|
-
return false;
|
|
93
|
-
};
|
|
94
|
-
if (shouldRetry()) {
|
|
150
|
+
if (shouldRetryRequest(retryOpts.maxRetries, error)) {
|
|
95
151
|
logger.debug(`retrying for the ${retryCount + 1} time`);
|
|
96
152
|
logger.debug(`Error: ${error}`);
|
|
153
|
+
await sleep(retryCount === 0
|
|
154
|
+
? retryOpts.minTimeout
|
|
155
|
+
: retryOpts.minTimeout * retryOpts.timeoutFactor ** retryCount);
|
|
97
156
|
// NOTE: this event is only used by tests and will be removed at any time.
|
|
98
157
|
// jsforce may switch to node's fetch which doesn't emit this event on retries.
|
|
99
158
|
emitter.emit('retry', retryCount);
|
|
@@ -101,7 +160,14 @@ async function startFetchRequest(request, options, input, output, emitter, count
|
|
|
101
160
|
return await fetchWithRetries(maxRetry);
|
|
102
161
|
}
|
|
103
162
|
logger.debug('Skipping retry...');
|
|
104
|
-
|
|
163
|
+
if (maxRetry === retryCount) {
|
|
164
|
+
const error = new Error('Request failed', { cause: err });
|
|
165
|
+
error.name = 'RequestRetryError';
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
throw err;
|
|
170
|
+
}
|
|
105
171
|
}
|
|
106
172
|
};
|
|
107
173
|
let res;
|
|
@@ -142,3 +208,4 @@ function request(req, options_ = {}) {
|
|
|
142
208
|
return stream;
|
|
143
209
|
}
|
|
144
210
|
exports.default = request;
|
|
211
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
package/lib/types/common.d.ts
CHANGED
|
@@ -21,8 +21,11 @@ export type HttpRequest = {
|
|
|
21
21
|
export type HttpRequestOptions = {
|
|
22
22
|
retry?: {
|
|
23
23
|
maxRetries?: number;
|
|
24
|
+
minTimeout?: number;
|
|
25
|
+
timeoutFactor?: number;
|
|
24
26
|
errorCodes?: string[];
|
|
25
27
|
methods?: HttpMethods[];
|
|
28
|
+
statusCodes?: number[];
|
|
26
29
|
};
|
|
27
30
|
httpProxy?: string;
|
|
28
31
|
timeout?: number;
|
package/package.json
CHANGED
package/lib/jwtOAuth2.d.ts
DELETED
package/lib/jwtOAuth2.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.JwtOAuth2 = void 0;
|
|
7
|
-
const oauth2_1 = __importDefault(require("./oauth2"));
|
|
8
|
-
/**
|
|
9
|
-
* @deprecated
|
|
10
|
-
*/
|
|
11
|
-
class JwtOAuth2 extends oauth2_1.default {
|
|
12
|
-
constructor(config) {
|
|
13
|
-
console.warn('JwtOAuth2 is deprecated and will be removed in next stable release, please use OAuth2 instead.');
|
|
14
|
-
super(config);
|
|
15
|
-
}
|
|
16
|
-
jwtAuthorize(innerToken) {
|
|
17
|
-
return super._postParams({
|
|
18
|
-
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
19
|
-
assertion: innerToken,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
exports.JwtOAuth2 = JwtOAuth2;
|