@yvhitxcel/opencode-remote 0.15.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/README.md +82 -0
- package/bin/opencode-remote.js +70 -0
- package/bin/opencode-weixin.js +10 -0
- package/dist/AGENTS.md +20 -0
- package/dist/MEMORY.md +21 -0
- package/dist/bot-runner.js +180 -0
- package/dist/cli.js +256 -0
- package/dist/core/approval.js +95 -0
- package/dist/core/auth.js +119 -0
- package/dist/core/config.js +61 -0
- package/dist/core/notifications.js +134 -0
- package/dist/core/qiniu.js +267 -0
- package/dist/core/registry.js +86 -0
- package/dist/core/router.js +344 -0
- package/dist/core/session.js +403 -0
- package/dist/core/setup.js +418 -0
- package/dist/core/types.js +16 -0
- package/dist/feishu/adapter.js +72 -0
- package/dist/feishu/bot.js +168 -0
- package/dist/feishu/commands.js +601 -0
- package/dist/feishu/handler.js +380 -0
- package/dist/index.js +60 -0
- package/dist/opencode/client.js +823 -0
- package/dist/package-lock.json +762 -0
- package/dist/patch_spawn.js +28 -0
- package/dist/plugins/agents/acp/acp-adapter.js +42 -0
- package/dist/plugins/agents/claude-code/index.js +69 -0
- package/dist/plugins/agents/codex/index.js +44 -0
- package/dist/plugins/agents/copilot/index.js +44 -0
- package/dist/plugins/agents/opencode/index.js +66 -0
- package/dist/telegram/bot.js +288 -0
- package/dist/utils/message-split.js +38 -0
- package/dist/web/code-viewer.js +266 -0
- package/dist/weixin/adapter.js +135 -0
- package/dist/weixin/api.js +179 -0
- package/dist/weixin/bot.js +183 -0
- package/dist/weixin/commands.js +758 -0
- package/dist/weixin/handler.js +577 -0
- package/dist/weixin/node_modules/encodeurl/LICENSE +22 -0
- package/dist/weixin/node_modules/encodeurl/README.md +109 -0
- package/dist/weixin/node_modules/encodeurl/index.js +60 -0
- package/dist/weixin/node_modules/encodeurl/package.json +40 -0
- package/dist/weixin/node_modules/qiniu/.claude/settings.local.json +7 -0
- package/dist/weixin/node_modules/qiniu/.github/workflows/ci-test.yml +36 -0
- package/dist/weixin/node_modules/qiniu/.github/workflows/npm-publish.yml +20 -0
- package/dist/weixin/node_modules/qiniu/.github/workflows/version-check.yml +19 -0
- package/dist/weixin/node_modules/qiniu/.idea/MarsCodeWorkspaceAppSettings.xml +7 -0
- package/dist/weixin/node_modules/qiniu/.idea/codeStyles/Project.xml +44 -0
- package/dist/weixin/node_modules/qiniu/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/dist/weixin/node_modules/qiniu/.idea/git_toolbox_blame.xml +6 -0
- package/dist/weixin/node_modules/qiniu/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/dist/weixin/node_modules/qiniu/.idea/jsLibraryMappings.xml +6 -0
- package/dist/weixin/node_modules/qiniu/.idea/modules.xml +8 -0
- package/dist/weixin/node_modules/qiniu/.idea/nodejs-sdk.iml +12 -0
- package/dist/weixin/node_modules/qiniu/.idea/vcs.xml +6 -0
- package/dist/weixin/node_modules/qiniu/CHANGELOG.md +292 -0
- package/dist/weixin/node_modules/qiniu/README.md +56 -0
- package/dist/weixin/node_modules/qiniu/StorageResponseInterface.d.ts +239 -0
- package/dist/weixin/node_modules/qiniu/codecov.yml +28 -0
- package/dist/weixin/node_modules/qiniu/index.d.ts +1995 -0
- package/dist/weixin/node_modules/qiniu/index.js +32 -0
- package/dist/weixin/node_modules/qiniu/node_modules/encodeurl/HISTORY.md +14 -0
- package/dist/weixin/node_modules/qiniu/node_modules/encodeurl/LICENSE +22 -0
- package/dist/weixin/node_modules/qiniu/node_modules/encodeurl/README.md +128 -0
- package/dist/weixin/node_modules/qiniu/node_modules/encodeurl/index.js +60 -0
- package/dist/weixin/node_modules/qiniu/node_modules/encodeurl/package.json +40 -0
- package/dist/weixin/node_modules/qiniu/package.json +80 -0
- package/dist/weixin/node_modules/qiniu/qiniu/auth/digest.js +13 -0
- package/dist/weixin/node_modules/qiniu/qiniu/cdn.js +149 -0
- package/dist/weixin/node_modules/qiniu/qiniu/conf.js +254 -0
- package/dist/weixin/node_modules/qiniu/qiniu/fop.js +112 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/client.js +253 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/endpoint.js +66 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/endpointsProvider.js +27 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/endpointsRetryPolicy.js +76 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/middleware/base.js +31 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/middleware/index.js +9 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/middleware/qiniuAuth.js +53 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/middleware/retryDomains.js +101 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/middleware/ua.js +36 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/region.js +349 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/regionsProvider.js +788 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/regionsRetryPolicy.js +242 -0
- package/dist/weixin/node_modules/qiniu/qiniu/httpc/responseWrapper.js +40 -0
- package/dist/weixin/node_modules/qiniu/qiniu/retry/index.js +4 -0
- package/dist/weixin/node_modules/qiniu/qiniu/retry/retrier.js +99 -0
- package/dist/weixin/node_modules/qiniu/qiniu/retry/retryPolicy.js +55 -0
- package/dist/weixin/node_modules/qiniu/qiniu/rpc.js +237 -0
- package/dist/weixin/node_modules/qiniu/qiniu/rtc/app.js +123 -0
- package/dist/weixin/node_modules/qiniu/qiniu/rtc/credentials.js +57 -0
- package/dist/weixin/node_modules/qiniu/qiniu/rtc/room.js +118 -0
- package/dist/weixin/node_modules/qiniu/qiniu/rtc/util.js +16 -0
- package/dist/weixin/node_modules/qiniu/qiniu/sms/message.js +58 -0
- package/dist/weixin/node_modules/qiniu/qiniu/storage/form.js +442 -0
- package/dist/weixin/node_modules/qiniu/qiniu/storage/internal.js +214 -0
- package/dist/weixin/node_modules/qiniu/qiniu/storage/resume.js +1272 -0
- package/dist/weixin/node_modules/qiniu/qiniu/storage/rs.js +1764 -0
- package/dist/weixin/node_modules/qiniu/qiniu/util.js +382 -0
- package/dist/weixin/node_modules/qiniu/qiniu/zone.js +230 -0
- package/dist/weixin/node_modules/qiniu/tsconfig.json +112 -0
- package/dist/weixin/types.js +25 -0
- package/package.json +56 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
const {
|
|
2
|
+
RetryPolicy
|
|
3
|
+
} = require('../retry');
|
|
4
|
+
const { Region } = require('./region');
|
|
5
|
+
const {
|
|
6
|
+
StaticRegionsProvider
|
|
7
|
+
} = require('./regionsProvider');
|
|
8
|
+
const {
|
|
9
|
+
StaticEndpointsProvider
|
|
10
|
+
} = require('./endpointsProvider');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {EndpointsRetryPolicyContext} RegionsRetryPolicyContext
|
|
14
|
+
* @property {Region} region
|
|
15
|
+
* @property {Region[]} alternativeRegions
|
|
16
|
+
* @property {SERVICE_NAME} serviceName
|
|
17
|
+
* @property {SERVICE_NAME[]} alternativeServiceNames
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @class
|
|
22
|
+
* @extends RetryPolicy
|
|
23
|
+
* @param {SERVICE_NAME} options.serviceName DEPRECATE: use options.serviceNames instead
|
|
24
|
+
* @param {SERVICE_NAME[]} options.serviceNames
|
|
25
|
+
* @param {Region[]} [options.regions]
|
|
26
|
+
* @param {RegionsProvider} [options.regionsProvider]
|
|
27
|
+
* @param {Endpoint[]} [options.preferredEndpoints]
|
|
28
|
+
* @param {EndpointsProvider} [options.preferredEndpointsProvider]
|
|
29
|
+
* @param {function(RegionsRetryPolicyContext): Promise<void>} [options.onChangedRegion]
|
|
30
|
+
* @constructor
|
|
31
|
+
*/
|
|
32
|
+
function RegionsRetryPolicy (options) {
|
|
33
|
+
/**
|
|
34
|
+
* @type {SERVICE_NAME[]}
|
|
35
|
+
*/
|
|
36
|
+
this.serviceNames = options.serviceNames || [];
|
|
37
|
+
if (!this.serviceNames.length) {
|
|
38
|
+
this.serviceNames = [options.serviceName];
|
|
39
|
+
}
|
|
40
|
+
if (!this.serviceNames.length) {
|
|
41
|
+
throw new TypeError('Must provide one service name at least');
|
|
42
|
+
}
|
|
43
|
+
// compatible, remove when make break changes
|
|
44
|
+
this.serviceName = this.serviceNames[0];
|
|
45
|
+
|
|
46
|
+
this.regions = options.regions || [];
|
|
47
|
+
this.regionsProvider = options.regionsProvider || new StaticRegionsProvider([]);
|
|
48
|
+
this.preferredEndpoints = options.preferredEndpoints || [];
|
|
49
|
+
this.preferredEndpointsProvider = options.preferredEndpointsProvider || new StaticEndpointsProvider([]);
|
|
50
|
+
this.onChangedRegion = options.onChangedRegion;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
RegionsRetryPolicy.prototype = Object.create(RetryPolicy.prototype);
|
|
54
|
+
RegionsRetryPolicy.prototype.constructor = RegionsRetryPolicy;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {RegionsRetryPolicyContext} context
|
|
58
|
+
* @returns {Promise<void>}
|
|
59
|
+
*/
|
|
60
|
+
RegionsRetryPolicy.prototype.initContext = function (context) {
|
|
61
|
+
const regionsPromise = this.regions.length > 0
|
|
62
|
+
? this.regions
|
|
63
|
+
: this.regionsProvider.getRegions();
|
|
64
|
+
const preferredEndpointsPromise = this.preferredEndpoints.length > 0
|
|
65
|
+
? this.preferredEndpoints
|
|
66
|
+
: this.preferredEndpointsProvider.getEndpoints();
|
|
67
|
+
return Promise.all([
|
|
68
|
+
regionsPromise,
|
|
69
|
+
preferredEndpointsPromise
|
|
70
|
+
])
|
|
71
|
+
.then(([regions, preferredEndpoints]) => this._initRegions({
|
|
72
|
+
context,
|
|
73
|
+
regions: regions.slice(),
|
|
74
|
+
preferredEndpoints: preferredEndpoints.slice()
|
|
75
|
+
}))
|
|
76
|
+
.then(() => this._prepareEndpoints(context));
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {RegionsRetryPolicyContext} context
|
|
81
|
+
* @returns {boolean}
|
|
82
|
+
*/
|
|
83
|
+
RegionsRetryPolicy.prototype.shouldRetry = function (context) {
|
|
84
|
+
return context.alternativeRegions.length > 0 || context.alternativeServiceNames.length > 0;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param {RegionsRetryPolicyContext} context
|
|
89
|
+
* @returns {Promise<void>}
|
|
90
|
+
*/
|
|
91
|
+
RegionsRetryPolicy.prototype.prepareRetry = function (context) {
|
|
92
|
+
let handleChangedRegionPromise = Promise.resolve();
|
|
93
|
+
if (context.alternativeServiceNames.length) {
|
|
94
|
+
context.serviceName = context.alternativeServiceNames.shift();
|
|
95
|
+
} else if (context.alternativeRegions.length) {
|
|
96
|
+
context.region = context.alternativeRegions.shift();
|
|
97
|
+
[context.serviceName, ...context.alternativeServiceNames] = this.serviceNames;
|
|
98
|
+
if (typeof this.onChangedRegion === 'function') {
|
|
99
|
+
handleChangedRegionPromise = this.onChangedRegion(context);
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
return Promise.reject(
|
|
103
|
+
new Error('There isn\'t available region or service for next try')
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
return handleChangedRegionPromise
|
|
107
|
+
.then(() => this._prepareEndpoints(context));
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @typedef GetPreferredRegionInfoResult
|
|
112
|
+
* @property {number} preferredServiceIndex
|
|
113
|
+
* @property {number} preferredRegionIndex
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @param {Region[]} options.regions
|
|
118
|
+
* @param {Endpoint[]} options.preferredEndpoints
|
|
119
|
+
* @returns {GetPreferredRegionInfoResult}
|
|
120
|
+
* @protected
|
|
121
|
+
*/
|
|
122
|
+
RegionsRetryPolicy.prototype._getPreferredRegionInfo = function (options) {
|
|
123
|
+
const {
|
|
124
|
+
regions,
|
|
125
|
+
preferredEndpoints
|
|
126
|
+
} = options;
|
|
127
|
+
|
|
128
|
+
const serviceNames = this.serviceNames.slice();
|
|
129
|
+
|
|
130
|
+
let preferredServiceIndex = -1;
|
|
131
|
+
const preferredRegionIndex = regions.findIndex(r =>
|
|
132
|
+
serviceNames.some((s, si) =>
|
|
133
|
+
r.services[s].some(e => {
|
|
134
|
+
const res = preferredEndpoints.some(pe => pe.host === e.host);
|
|
135
|
+
if (res) {
|
|
136
|
+
preferredServiceIndex = si;
|
|
137
|
+
}
|
|
138
|
+
return res;
|
|
139
|
+
})
|
|
140
|
+
)
|
|
141
|
+
);
|
|
142
|
+
return {
|
|
143
|
+
preferredServiceIndex,
|
|
144
|
+
preferredRegionIndex
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @param {RegionsRetryPolicyContext} options.context
|
|
150
|
+
* @param {Region[]} options.regions
|
|
151
|
+
* @param {Endpoint[]} options.preferredEndpoints
|
|
152
|
+
* @returns {Promise<void>}
|
|
153
|
+
* @private
|
|
154
|
+
*/
|
|
155
|
+
RegionsRetryPolicy.prototype._initRegions = function (options) {
|
|
156
|
+
const {
|
|
157
|
+
context,
|
|
158
|
+
regions,
|
|
159
|
+
preferredEndpoints
|
|
160
|
+
} = options;
|
|
161
|
+
// initial region and alternative regions
|
|
162
|
+
if (!regions.length && !preferredEndpoints.length) {
|
|
163
|
+
return Promise.reject(
|
|
164
|
+
new Error('There isn\'t available region or preferred endpoint')
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (!preferredEndpoints.length) {
|
|
169
|
+
[context.region, ...context.alternativeRegions] = regions;
|
|
170
|
+
[context.serviceName, ...context.alternativeServiceNames] = this.serviceNames;
|
|
171
|
+
return Promise.resolve();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// find preferred serviceName and region by preferred endpoints
|
|
175
|
+
const {
|
|
176
|
+
preferredRegionIndex,
|
|
177
|
+
preferredServiceIndex
|
|
178
|
+
} = this._getPreferredRegionInfo({
|
|
179
|
+
regions,
|
|
180
|
+
preferredEndpoints
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// initialize the order of serviceNames and regions
|
|
184
|
+
if (preferredRegionIndex < 0) {
|
|
185
|
+
// preferred endpoints is not a region, then make all regions alternative
|
|
186
|
+
[context.serviceName, ...context.alternativeServiceNames] = this.serviceNames;
|
|
187
|
+
// compatible, remove when make break changes
|
|
188
|
+
this.serviceName = context.serviceName;
|
|
189
|
+
|
|
190
|
+
context.region = new Region({
|
|
191
|
+
services: {
|
|
192
|
+
[context.serviceName]: preferredEndpoints
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
context.alternativeRegions = regions;
|
|
196
|
+
} else {
|
|
197
|
+
// preferred endpoints in a known region, then reorder the regions and services
|
|
198
|
+
context.alternativeRegions = regions;
|
|
199
|
+
[context.region] = context.alternativeRegions.splice(preferredRegionIndex, 1);
|
|
200
|
+
context.alternativeServiceNames = this.serviceNames.slice();
|
|
201
|
+
[context.serviceName] = context.alternativeServiceNames.splice(preferredServiceIndex, 1);
|
|
202
|
+
// compatible, remove when make break changes
|
|
203
|
+
this.serviceName = context.serviceName;
|
|
204
|
+
}
|
|
205
|
+
return Promise.resolve();
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @param {RegionsRetryPolicyContext} context
|
|
210
|
+
* @returns {Promise<void>}
|
|
211
|
+
* @protected
|
|
212
|
+
*/
|
|
213
|
+
RegionsRetryPolicy.prototype._prepareEndpoints = function (context) {
|
|
214
|
+
let handleChangedRegionsPromise = Promise.resolve();
|
|
215
|
+
[context.endpoint, ...context.alternativeEndpoints] = context.region.services[context.serviceName] || [];
|
|
216
|
+
while (!context.endpoint) {
|
|
217
|
+
if (context.alternativeServiceNames.length) {
|
|
218
|
+
context.serviceName = context.alternativeServiceNames.shift();
|
|
219
|
+
// compatible, remove when make break changes
|
|
220
|
+
this.serviceName = context.serviceName;
|
|
221
|
+
[context.endpoint, ...context.alternativeEndpoints] = context.region.services[context.serviceName] || [];
|
|
222
|
+
} else if (context.alternativeRegions.length) {
|
|
223
|
+
context.region = context.alternativeRegions.shift();
|
|
224
|
+
[context.serviceName, ...context.alternativeServiceNames] = this.serviceNames;
|
|
225
|
+
// compatible, remove when make break changes
|
|
226
|
+
this.serviceName = context.serviceName;
|
|
227
|
+
[context.endpoint, ...context.alternativeEndpoints] = context.region.services[context.serviceName] || [];
|
|
228
|
+
if (typeof this.onChangedRegion === 'function') {
|
|
229
|
+
handleChangedRegionsPromise = this.onChangedRegion(context);
|
|
230
|
+
}
|
|
231
|
+
} else {
|
|
232
|
+
return Promise.reject(new Error(
|
|
233
|
+
'There isn\'t available endpoint for ' +
|
|
234
|
+
this.serviceNames.join(', ') +
|
|
235
|
+
' service(s) in any available regions'
|
|
236
|
+
));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return handleChangedRegionsPromise;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
exports.RegionsRetryPolicy = RegionsRetryPolicy;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class
|
|
3
|
+
* @param {any} data
|
|
4
|
+
* @param {http.IncomingMessage} resp
|
|
5
|
+
* @constructor
|
|
6
|
+
*/
|
|
7
|
+
function ResponseWrapper ({
|
|
8
|
+
data,
|
|
9
|
+
resp
|
|
10
|
+
}) {
|
|
11
|
+
this.data = data;
|
|
12
|
+
this.resp = resp;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @returns {boolean}
|
|
17
|
+
*/
|
|
18
|
+
ResponseWrapper.prototype.ok = function () {
|
|
19
|
+
return this.resp && Math.floor(this.resp.statusCode / 100) === 2;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @returns {boolean}
|
|
24
|
+
*/
|
|
25
|
+
ResponseWrapper.prototype.needRetry = function () {
|
|
26
|
+
if (this.resp.statusCode > 0 && this.resp.statusCode < 500) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// https://developer.qiniu.com/fusion/kb/1352/the-http-request-return-a-status-code
|
|
31
|
+
if ([
|
|
32
|
+
501, 509, 573, 579, 608, 612, 614, 616, 618, 630, 631, 632, 640, 701
|
|
33
|
+
].includes(this.resp.statusCode)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return true;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
exports.ResponseWrapper = ResponseWrapper;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class
|
|
3
|
+
* @param {RetryPolicy[]} options.retryPolicies
|
|
4
|
+
* @param {function(RetryPolicyContext, RetryPolicy | undefined): Promise<boolean>} [options.onBeforeRetry]
|
|
5
|
+
* @constructor
|
|
6
|
+
*/
|
|
7
|
+
function Retrier (options) {
|
|
8
|
+
this.retryPolicies = options.retryPolicies || [];
|
|
9
|
+
this.onBeforeRetry = options.onBeforeRetry;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
Retrier.prototype.initContext = function () {
|
|
13
|
+
const context = {
|
|
14
|
+
error: null,
|
|
15
|
+
retried: false
|
|
16
|
+
};
|
|
17
|
+
return this.retryPolicies.reduce(
|
|
18
|
+
(promiseChain, retryPolicy) =>
|
|
19
|
+
promiseChain.then(() =>
|
|
20
|
+
retryPolicy.initContext(context))
|
|
21
|
+
,
|
|
22
|
+
Promise.resolve()
|
|
23
|
+
)
|
|
24
|
+
.then(() => context);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
Retrier.prototype._afterRetry = function (context) {
|
|
28
|
+
return this.retryPolicies.reduce(
|
|
29
|
+
(promiseChain, retryPolicy) =>
|
|
30
|
+
promiseChain.then(() =>
|
|
31
|
+
retryPolicy.afterRetry(context))
|
|
32
|
+
,
|
|
33
|
+
Promise.resolve()
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
Retrier.prototype.retry = function (options) {
|
|
38
|
+
const {
|
|
39
|
+
func,
|
|
40
|
+
context
|
|
41
|
+
} = options;
|
|
42
|
+
return func(context)
|
|
43
|
+
.then(result => {
|
|
44
|
+
context.result = result;
|
|
45
|
+
if (context.retried) {
|
|
46
|
+
return this._afterRetry(context);
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
.catch(error => {
|
|
50
|
+
context.error = error;
|
|
51
|
+
if (context.retried) {
|
|
52
|
+
return this._afterRetry(context);
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
.then(() => {
|
|
56
|
+
let retryPolicy = this.retryPolicies.find(p => p.isImportant(context));
|
|
57
|
+
if (retryPolicy && !retryPolicy.shouldRetry(context)) {
|
|
58
|
+
return [
|
|
59
|
+
false,
|
|
60
|
+
retryPolicy
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
if (!retryPolicy) {
|
|
64
|
+
retryPolicy = this.retryPolicies.find(p => p.shouldRetry(context));
|
|
65
|
+
}
|
|
66
|
+
const couldRetryPromise = this.onBeforeRetry
|
|
67
|
+
? this.onBeforeRetry(context, retryPolicy)
|
|
68
|
+
: retryPolicy !== undefined;
|
|
69
|
+
return Promise.all([
|
|
70
|
+
couldRetryPromise,
|
|
71
|
+
retryPolicy
|
|
72
|
+
]);
|
|
73
|
+
})
|
|
74
|
+
.then(([couldRetry, retryPolicy]) => {
|
|
75
|
+
if (!couldRetry || !retryPolicy) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
context.error = null;
|
|
79
|
+
context.retried = true;
|
|
80
|
+
delete context.result;
|
|
81
|
+
return retryPolicy.prepareRetry(context)
|
|
82
|
+
.catch(err => {
|
|
83
|
+
err.message = 'Retrier: prepare retry failed\n' + err.message;
|
|
84
|
+
if (context.error) {
|
|
85
|
+
err.cause = context.error;
|
|
86
|
+
}
|
|
87
|
+
return Promise.reject(err);
|
|
88
|
+
})
|
|
89
|
+
.then(() => this.retry(options));
|
|
90
|
+
})
|
|
91
|
+
.then(() => {
|
|
92
|
+
if (context.error) {
|
|
93
|
+
return Promise.reject(context.error);
|
|
94
|
+
}
|
|
95
|
+
return context.result;
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
exports.Retrier = Retrier;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef RetryPolicyContext
|
|
3
|
+
* @property {any} result
|
|
4
|
+
* @property {Error | null} error
|
|
5
|
+
* @property {boolean} retried
|
|
6
|
+
* @property {...any}
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @class
|
|
11
|
+
* @constructor
|
|
12
|
+
*/
|
|
13
|
+
function RetryPolicy () {
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {RetryPolicyContext} _context
|
|
18
|
+
* @returns {boolean}
|
|
19
|
+
*/
|
|
20
|
+
RetryPolicy.prototype.isImportant = function (_context) {
|
|
21
|
+
return false;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @abstract
|
|
26
|
+
* @param {RetryPolicyContext} _context
|
|
27
|
+
* @returns {Promise<void>}
|
|
28
|
+
*/
|
|
29
|
+
RetryPolicy.prototype.initContext = function (_context) {
|
|
30
|
+
throw new Error('Method not implemented.');
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @abstract
|
|
35
|
+
* @param {RetryPolicyContext} _context
|
|
36
|
+
* @returns {boolean}
|
|
37
|
+
*/
|
|
38
|
+
RetryPolicy.prototype.shouldRetry = function (_context) {
|
|
39
|
+
throw new Error('Method not implemented.');
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @abstract
|
|
44
|
+
* @param {RetryPolicyContext} _context
|
|
45
|
+
* @returns {Promise<void>}
|
|
46
|
+
*/
|
|
47
|
+
RetryPolicy.prototype.prepareRetry = function (_context) {
|
|
48
|
+
throw new Error('Method not implemented.');
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
RetryPolicy.prototype.afterRetry = function () {
|
|
52
|
+
return Promise.resolve();
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
exports.RetryPolicy = RetryPolicy;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
const urllib = require('urllib');
|
|
2
|
+
|
|
3
|
+
const pkg = require('../package.json');
|
|
4
|
+
const conf = require('./conf');
|
|
5
|
+
const digest = require('./auth/digest');
|
|
6
|
+
const util = require('./util');
|
|
7
|
+
const client = require('./httpc/client');
|
|
8
|
+
const middleware = require('./httpc/middleware');
|
|
9
|
+
|
|
10
|
+
let uaMiddleware = new middleware.UserAgentMiddleware(pkg.version);
|
|
11
|
+
uaMiddleware = Object.defineProperty(uaMiddleware, 'userAgent', {
|
|
12
|
+
get: function () {
|
|
13
|
+
return conf.USER_AGENT;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
exports.qnHttpClient = new client.HttpClient({
|
|
17
|
+
middlewares: [
|
|
18
|
+
uaMiddleware
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
exports.get = get;
|
|
22
|
+
exports.post = post;
|
|
23
|
+
exports.put = put;
|
|
24
|
+
exports.getWithOptions = getWithOptions;
|
|
25
|
+
exports.getWithToken = getWithToken;
|
|
26
|
+
exports.postWithOptions = postWithOptions;
|
|
27
|
+
exports.postMultipart = postMultipart;
|
|
28
|
+
exports.postWithForm = postWithForm;
|
|
29
|
+
exports.postWithoutForm = postWithoutForm;
|
|
30
|
+
|
|
31
|
+
function addAuthHeaders (headers, mac) {
|
|
32
|
+
const xQiniuDate = util.formatDateUTC(new Date(), 'YYYYMMDDTHHmmssZ');
|
|
33
|
+
if (mac.options.disableQiniuTimestampSignature !== null) {
|
|
34
|
+
if (!mac.options.disableQiniuTimestampSignature) {
|
|
35
|
+
headers['X-Qiniu-Date'] = xQiniuDate;
|
|
36
|
+
}
|
|
37
|
+
} else if (process.env.DISABLE_QINIU_TIMESTAMP_SIGNATURE) {
|
|
38
|
+
if (process.env.DISABLE_QINIU_TIMESTAMP_SIGNATURE.toLowerCase() !== 'true') {
|
|
39
|
+
headers['X-Qiniu-Date'] = xQiniuDate;
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
headers['X-Qiniu-Date'] = xQiniuDate;
|
|
43
|
+
}
|
|
44
|
+
return headers;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getWithOptions (requestURI, options, callbackFunc) {
|
|
48
|
+
let headers = options.headers || {};
|
|
49
|
+
const mac = options.mac || new digest.Mac();
|
|
50
|
+
|
|
51
|
+
if (!headers['Content-Type']) {
|
|
52
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
headers = addAuthHeaders(headers, mac);
|
|
56
|
+
|
|
57
|
+
// if there are V3, V4 token generator in the future, extends options with signVersion
|
|
58
|
+
const token = util.generateAccessTokenV2(
|
|
59
|
+
mac,
|
|
60
|
+
requestURI,
|
|
61
|
+
'GET',
|
|
62
|
+
headers['Content-Type'],
|
|
63
|
+
null,
|
|
64
|
+
headers
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
if (mac.accessKey) {
|
|
68
|
+
headers.Authorization = token;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return get(requestURI, headers, callbackFunc);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function getWithToken (requestUrl, token, callbackFunc) {
|
|
75
|
+
const headers = {
|
|
76
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
77
|
+
};
|
|
78
|
+
if (token) {
|
|
79
|
+
headers.Authorization = token;
|
|
80
|
+
}
|
|
81
|
+
return get(requestUrl, headers, callbackFunc);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function postWithOptions (requestURI, requestForm, options, callbackFunc) {
|
|
85
|
+
let headers = options.headers || {};
|
|
86
|
+
const mac = options.mac || new digest.Mac();
|
|
87
|
+
|
|
88
|
+
if (!headers['Content-Type']) {
|
|
89
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
headers = addAuthHeaders(headers, mac);
|
|
93
|
+
|
|
94
|
+
// if there are V3, V4 token generator in the future, extends options with signVersion
|
|
95
|
+
const token = util.generateAccessTokenV2(
|
|
96
|
+
mac,
|
|
97
|
+
requestURI,
|
|
98
|
+
'POST',
|
|
99
|
+
headers['Content-Type'],
|
|
100
|
+
requestForm,
|
|
101
|
+
headers
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
if (mac.accessKey) {
|
|
105
|
+
headers.Authorization = token;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return post(requestURI, requestForm, headers, callbackFunc);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function postMultipart (requestURI, requestForm, callbackFunc) {
|
|
112
|
+
return post(requestURI, requestForm, requestForm.headers(), callbackFunc);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function postWithForm (requestURI, requestForm, token, callbackFunc) {
|
|
116
|
+
const headers = {
|
|
117
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
118
|
+
};
|
|
119
|
+
if (token) {
|
|
120
|
+
headers.Authorization = token;
|
|
121
|
+
}
|
|
122
|
+
return post(requestURI, requestForm, headers, callbackFunc);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function postWithoutForm (requestURI, token, callbackFunc) {
|
|
126
|
+
const headers = {
|
|
127
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
128
|
+
};
|
|
129
|
+
if (token) {
|
|
130
|
+
headers.Authorization = token;
|
|
131
|
+
}
|
|
132
|
+
return post(requestURI, null, headers, callbackFunc);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function get (requestUrl, headers, callbackFunc) {
|
|
136
|
+
headers = headers || {};
|
|
137
|
+
headers['User-Agent'] = headers['User-Agent'] || conf.USER_AGENT;
|
|
138
|
+
headers.Connection = 'keep-alive';
|
|
139
|
+
|
|
140
|
+
const data = {
|
|
141
|
+
method: 'GET',
|
|
142
|
+
headers: headers,
|
|
143
|
+
dataType: 'json',
|
|
144
|
+
timeout: conf.RPC_TIMEOUT,
|
|
145
|
+
gzip: true
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
if (conf.RPC_HTTP_AGENT) {
|
|
149
|
+
data.agent = conf.RPC_HTTP_AGENT;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (conf.RPC_HTTPS_AGENT) {
|
|
153
|
+
data.httpsAgent = conf.RPC_HTTPS_AGENT;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return urllib.request(
|
|
157
|
+
requestUrl,
|
|
158
|
+
data,
|
|
159
|
+
callbackFunc
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function post (requestUrl, requestForm, headers, callbackFunc) {
|
|
164
|
+
// var start = parseInt(Date.now() / 1000);
|
|
165
|
+
headers = headers || {};
|
|
166
|
+
headers['User-Agent'] = headers['User-Agent'] || conf.USER_AGENT;
|
|
167
|
+
headers.Connection = 'keep-alive';
|
|
168
|
+
|
|
169
|
+
const data = {
|
|
170
|
+
headers: headers,
|
|
171
|
+
method: 'POST',
|
|
172
|
+
dataType: 'json',
|
|
173
|
+
timeout: conf.RPC_TIMEOUT,
|
|
174
|
+
gzip: true
|
|
175
|
+
// timing: true,
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
if (conf.RPC_HTTP_AGENT) {
|
|
179
|
+
data.agent = conf.RPC_HTTP_AGENT;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (conf.RPC_HTTPS_AGENT) {
|
|
183
|
+
data.httpsAgent = conf.RPC_HTTPS_AGENT;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (Buffer.isBuffer(requestForm) || typeof requestForm === 'string') {
|
|
187
|
+
data.content = requestForm;
|
|
188
|
+
} else if (requestForm) {
|
|
189
|
+
data.stream = requestForm;
|
|
190
|
+
} else {
|
|
191
|
+
data.headers['Content-Length'] = 0;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return urllib.request(
|
|
195
|
+
requestUrl,
|
|
196
|
+
data,
|
|
197
|
+
callbackFunc
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function put (requestUrl, requestForm, headers, callbackFunc) {
|
|
202
|
+
// var start = parseInt(Date.now() / 1000);
|
|
203
|
+
headers = headers || {};
|
|
204
|
+
headers['User-Agent'] = headers['User-Agent'] || conf.USER_AGENT;
|
|
205
|
+
headers.Connection = 'keep-alive';
|
|
206
|
+
|
|
207
|
+
const data = {
|
|
208
|
+
headers: headers,
|
|
209
|
+
method: 'PUT',
|
|
210
|
+
dataType: 'json',
|
|
211
|
+
timeout: conf.RPC_TIMEOUT,
|
|
212
|
+
gzip: true
|
|
213
|
+
// timing: true,
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
if (conf.RPC_HTTP_AGENT) {
|
|
217
|
+
data.agent = conf.RPC_HTTP_AGENT;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (conf.RPC_HTTPS_AGENT) {
|
|
221
|
+
data.httpsAgent = conf.RPC_HTTPS_AGENT;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (Buffer.isBuffer(requestForm) || typeof requestForm === 'string') {
|
|
225
|
+
data.content = requestForm;
|
|
226
|
+
} else if (requestForm) {
|
|
227
|
+
data.stream = requestForm;
|
|
228
|
+
} else {
|
|
229
|
+
data.headers['Content-Length'] = 0;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return urllib.request(
|
|
233
|
+
requestUrl,
|
|
234
|
+
data,
|
|
235
|
+
callbackFunc
|
|
236
|
+
);
|
|
237
|
+
}
|