@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,76 @@
|
|
|
1
|
+
const {
|
|
2
|
+
RetryPolicy
|
|
3
|
+
} = require('../retry');
|
|
4
|
+
const {
|
|
5
|
+
StaticEndpointsProvider
|
|
6
|
+
} = require('./endpointsProvider');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {RetryPolicyContext} EndpointsRetryPolicyContext
|
|
10
|
+
* @property {Endpoint} endpoint
|
|
11
|
+
* @property {Endpoint[]} alternativeEndpoints
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @class
|
|
16
|
+
* @extends RetryPolicy
|
|
17
|
+
* @param {boolean} [options.skipInitContext]
|
|
18
|
+
* @param {Endpoint[]} [options.endpoints]
|
|
19
|
+
* @param {EndpointsProvider} [options.endpointsProvider]
|
|
20
|
+
* @constructor
|
|
21
|
+
*/
|
|
22
|
+
function EndpointsRetryPolicy (options) {
|
|
23
|
+
this.skipInitContext = options.skipInitContext || false;
|
|
24
|
+
this.endpoints = options.endpoints || [];
|
|
25
|
+
this.endpointsProvider = options.endpointsProvider || new StaticEndpointsProvider([]);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
EndpointsRetryPolicy.prototype = Object.create(RetryPolicy.prototype);
|
|
29
|
+
EndpointsRetryPolicy.prototype.constructor = EndpointsRetryPolicy;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param {EndpointsRetryPolicyContext} context
|
|
33
|
+
* @returns {Promise<void>}
|
|
34
|
+
*/
|
|
35
|
+
EndpointsRetryPolicy.prototype.initContext = function (context) {
|
|
36
|
+
if (this.skipInitContext) {
|
|
37
|
+
return Promise.resolve();
|
|
38
|
+
}
|
|
39
|
+
if (this.endpoints.length > 0) {
|
|
40
|
+
[context.endpoint, ...context.alternativeEndpoints] = this.endpoints.slice();
|
|
41
|
+
return Promise.resolve();
|
|
42
|
+
}
|
|
43
|
+
return this.endpointsProvider.getEndpoints()
|
|
44
|
+
.then(endpoints => {
|
|
45
|
+
if (endpoints.length < 0) {
|
|
46
|
+
return Promise.reject(
|
|
47
|
+
new Error('There isn\'t available endpoint')
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
[context.endpoint, ...context.alternativeEndpoints] = endpoints.slice();
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param {EndpointsRetryPolicyContext} context
|
|
56
|
+
* @returns {boolean}
|
|
57
|
+
*/
|
|
58
|
+
EndpointsRetryPolicy.prototype.shouldRetry = function (context) {
|
|
59
|
+
return context.alternativeEndpoints.length > 0;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @param {EndpointsRetryPolicyContext} context
|
|
64
|
+
* @returns {Promise<void>}
|
|
65
|
+
*/
|
|
66
|
+
EndpointsRetryPolicy.prototype.prepareRetry = function (context) {
|
|
67
|
+
context.endpoint = context.alternativeEndpoints.shift();
|
|
68
|
+
if (!context.endpoint) {
|
|
69
|
+
return Promise.reject(
|
|
70
|
+
new Error('There isn\'t available endpoint for next try')
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
return Promise.resolve();
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
exports.EndpointsRetryPolicy = EndpointsRetryPolicy;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware could be an interface if migrate to typescript
|
|
3
|
+
* @class
|
|
4
|
+
* @constructor
|
|
5
|
+
*/
|
|
6
|
+
function Middleware () {
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @memberOf Middleware
|
|
11
|
+
* @param _request
|
|
12
|
+
* @param _next
|
|
13
|
+
*/
|
|
14
|
+
Middleware.prototype.send = function (_request, _next) {
|
|
15
|
+
throw new Error('The Middleware NOT be Implemented');
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
exports.Middleware = Middleware;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {Middleware[]} middlewares
|
|
22
|
+
* @param {function(ReqOpts):Promise<ResponseWrapper>} handler
|
|
23
|
+
* @returns {function(ReqOpts):Promise<ResponseWrapper>}
|
|
24
|
+
*/
|
|
25
|
+
exports.composeMiddlewares = function (middlewares, handler) {
|
|
26
|
+
return middlewares.reverse()
|
|
27
|
+
.reduce(
|
|
28
|
+
(h, mw) => request => mw.send(request, h),
|
|
29
|
+
handler
|
|
30
|
+
);
|
|
31
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const base = require('./base');
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
composeMiddlewares: base.composeMiddlewares,
|
|
5
|
+
Middleware: base.Middleware,
|
|
6
|
+
RetryDomainsMiddleware: require('./retryDomains').RetryDomainsMiddleware,
|
|
7
|
+
UserAgentMiddleware: require('./ua').UserAgentMiddleware,
|
|
8
|
+
QiniuAuthMiddleware: require('./qiniuAuth').QiniuAuthMiddleware
|
|
9
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const middleware = require('./base');
|
|
2
|
+
const util = require('../../util');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @class
|
|
6
|
+
* @extends middleware.Middleware
|
|
7
|
+
* @param {Object} qiniuAuthOptions
|
|
8
|
+
* @param {Mac} qiniuAuthOptions.mac
|
|
9
|
+
* @constructor
|
|
10
|
+
*/
|
|
11
|
+
function QiniuAuthMiddleware (qiniuAuthOptions) {
|
|
12
|
+
this.mac = qiniuAuthOptions.mac;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
QiniuAuthMiddleware.prototype = Object.create(middleware.Middleware.prototype);
|
|
16
|
+
QiniuAuthMiddleware.prototype.constructor = QiniuAuthMiddleware;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @memberOf QiniuAuthMiddleware
|
|
20
|
+
* @param {ReqOpts} reqOpts
|
|
21
|
+
* @param {function(ReqOpts):Promise<ResponseWrapper>} next
|
|
22
|
+
* @returns {Promise<ResponseWrapper>}
|
|
23
|
+
*/
|
|
24
|
+
QiniuAuthMiddleware.prototype.send = function (reqOpts, next) {
|
|
25
|
+
const headers = reqOpts.urllibOptions.headers;
|
|
26
|
+
if (this._shouldSignTime()) {
|
|
27
|
+
headers['X-Qiniu-Date'] = util.formatDateUTC(new Date(), 'YYYYMMDDTHHmmssZ');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (this.mac.accessKey) {
|
|
31
|
+
headers.Authorization = util.generateAccessTokenV2(
|
|
32
|
+
this.mac,
|
|
33
|
+
reqOpts.url,
|
|
34
|
+
reqOpts.urllibOptions.method,
|
|
35
|
+
reqOpts.urllibOptions.contentType,
|
|
36
|
+
reqOpts.urllibOptions.content,
|
|
37
|
+
headers
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return next(reqOpts);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
QiniuAuthMiddleware.prototype._shouldSignTime = function () {
|
|
45
|
+
let shouldDisable = this.mac.options.disableQiniuTimestampSignature;
|
|
46
|
+
if (shouldDisable === null) {
|
|
47
|
+
const envDisable = process.env.DISABLE_QINIU_TIMESTAMP_SIGNATURE || '';
|
|
48
|
+
shouldDisable = envDisable.toLowerCase() === 'true';
|
|
49
|
+
}
|
|
50
|
+
return !shouldDisable;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
exports.QiniuAuthMiddleware = QiniuAuthMiddleware;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const middleware = require('./base');
|
|
2
|
+
|
|
3
|
+
const URL = require('url').URL;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @class
|
|
7
|
+
* @extends middleware.Middleware
|
|
8
|
+
* @param {Object} retryDomainsOptions
|
|
9
|
+
* @param {string[]} retryDomainsOptions.backupDomains
|
|
10
|
+
* @param {number} [retryDomainsOptions.maxRetryTimes]
|
|
11
|
+
* @param {function(Error || null, ResponseWrapper || null, ReqOpts):boolean} [retryDomainsOptions.retryCondition]
|
|
12
|
+
* @constructor
|
|
13
|
+
*/
|
|
14
|
+
function RetryDomainsMiddleware (retryDomainsOptions) {
|
|
15
|
+
this.backupDomains = retryDomainsOptions.backupDomains;
|
|
16
|
+
this.maxRetryTimes = retryDomainsOptions.maxRetryTimes || 2;
|
|
17
|
+
this.retryCondition = retryDomainsOptions.retryCondition;
|
|
18
|
+
|
|
19
|
+
this._retriedTimes = 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
RetryDomainsMiddleware.prototype = Object.create(middleware.Middleware.prototype);
|
|
23
|
+
RetryDomainsMiddleware.prototype.constructor = RetryDomainsMiddleware;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @memberOf RetryDomainsMiddleware
|
|
27
|
+
* @param {Error || null} err
|
|
28
|
+
* @param {ResponseWrapper || null} respWrapper
|
|
29
|
+
* @param {ReqOpts} reqOpts
|
|
30
|
+
* @returns {boolean}
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
RetryDomainsMiddleware.prototype._shouldRetry = function (err, respWrapper, reqOpts) {
|
|
34
|
+
if (typeof this.retryCondition === 'function') {
|
|
35
|
+
return this.retryCondition(err, respWrapper, reqOpts);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return !respWrapper || respWrapper.needRetry();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @memberOf RetryDomainsMiddleware
|
|
43
|
+
* @param {ReqOpts} reqOpts
|
|
44
|
+
* @param {function(ReqOpts):Promise<ResponseWrapper>} next
|
|
45
|
+
* @returns {Promise<ResponseWrapper>}
|
|
46
|
+
*/
|
|
47
|
+
RetryDomainsMiddleware.prototype.send = function (reqOpts, next) {
|
|
48
|
+
const url = new URL(reqOpts.url);
|
|
49
|
+
const domains = this.backupDomains.slice(); // copy for late pop
|
|
50
|
+
|
|
51
|
+
const couldRetry = () => {
|
|
52
|
+
// the reason `this.maxRetryTimes - 1` is request send first then add retriedTimes
|
|
53
|
+
// and `this.maxRetryTimes` means max request times per domain
|
|
54
|
+
if (this._retriedTimes < this.maxRetryTimes - 1) {
|
|
55
|
+
this._retriedTimes += 1;
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (domains.length) {
|
|
60
|
+
this._retriedTimes = 0;
|
|
61
|
+
const domain = domains.shift();
|
|
62
|
+
const [hostname, port] = domain.split(':');
|
|
63
|
+
url.hostname = hostname;
|
|
64
|
+
url.port = port || url.port;
|
|
65
|
+
reqOpts.url = url.toString();
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return false;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const tryNext = () => {
|
|
73
|
+
return next(reqOpts)
|
|
74
|
+
.then(respWrapper => {
|
|
75
|
+
if (!this._shouldRetry(null, respWrapper, reqOpts)) {
|
|
76
|
+
return respWrapper;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (couldRetry()) {
|
|
80
|
+
return tryNext();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return respWrapper;
|
|
84
|
+
})
|
|
85
|
+
.catch(err => {
|
|
86
|
+
if (!this._shouldRetry(err, null, reqOpts)) {
|
|
87
|
+
return Promise.reject(err);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (couldRetry()) {
|
|
91
|
+
return tryNext();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return Promise.reject(err);
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
return tryNext();
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
exports.RetryDomainsMiddleware = RetryDomainsMiddleware;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const os = require('os');
|
|
2
|
+
|
|
3
|
+
const middleware = require('./base');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @class
|
|
7
|
+
* @extends middleware.Middleware
|
|
8
|
+
* @param {string} sdkVersion
|
|
9
|
+
* @constructor
|
|
10
|
+
*/
|
|
11
|
+
function UserAgentMiddleware (sdkVersion) {
|
|
12
|
+
this.userAgent = 'QiniuNodejs/' + sdkVersion +
|
|
13
|
+
' (' +
|
|
14
|
+
os.type() + '; ' +
|
|
15
|
+
os.platform() + '; ' +
|
|
16
|
+
os.arch() + '; ' +
|
|
17
|
+
'Node.js ' + process.version + '; )';
|
|
18
|
+
}
|
|
19
|
+
UserAgentMiddleware.prototype = Object.create(middleware.Middleware.prototype);
|
|
20
|
+
UserAgentMiddleware.prototype.constructor = UserAgentMiddleware;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @memberOf UserAgentMiddleware
|
|
24
|
+
* @param {ReqOpts} reqOpts
|
|
25
|
+
* @param {function(ReqOpts):Promise<ResponseWrapper>} next
|
|
26
|
+
* @returns {Promise<ResponseWrapper>}
|
|
27
|
+
*/
|
|
28
|
+
UserAgentMiddleware.prototype.send = function (reqOpts, next) {
|
|
29
|
+
if (!reqOpts.urllibOptions.headers) {
|
|
30
|
+
reqOpts.urllibOptions.headers = {};
|
|
31
|
+
}
|
|
32
|
+
reqOpts.urllibOptions.headers['User-Agent'] = this.userAgent;
|
|
33
|
+
return next(reqOpts);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
exports.UserAgentMiddleware = UserAgentMiddleware;
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
const { Endpoint } = require('./endpoint');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @interface RegionsProvider
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @function
|
|
9
|
+
* @name RegionsProvider#getRegions
|
|
10
|
+
* @returns {Promise<Region[]>}
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @interface MutableRegionsProvider
|
|
15
|
+
* @extends RegionsProvider
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @function
|
|
20
|
+
* @name MutableRegionsProvider#setRegions
|
|
21
|
+
* @param {Region[]} regions
|
|
22
|
+
* @returns {Promise<void>}
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// --- could split to files if migrate to typescript --- //
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @readonly
|
|
29
|
+
* @enum {string}
|
|
30
|
+
*/
|
|
31
|
+
const SERVICE_NAME = {
|
|
32
|
+
UC: 'uc',
|
|
33
|
+
UP: 'up',
|
|
34
|
+
UP_ACC: 'up_acc',
|
|
35
|
+
IO: 'io',
|
|
36
|
+
RS: 'rs',
|
|
37
|
+
RSF: 'rsf',
|
|
38
|
+
API: 'api',
|
|
39
|
+
S3: 's3'
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// --- could split to files if migrate to typescript --- //
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {SERVICE_NAME | string} ServiceKey
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @class
|
|
50
|
+
* @implements RegionsProvider
|
|
51
|
+
* @param {Object} options
|
|
52
|
+
* @param {string} [options.regionId]
|
|
53
|
+
* @param {string} [options.s3RegionId]
|
|
54
|
+
* @param {Object.<ServiceKey, Endpoint[]>} [options.services]
|
|
55
|
+
* @param {number} [options.ttl] seconds. default 1 day.
|
|
56
|
+
* @param {Date} [options.createTime]
|
|
57
|
+
* @constructor
|
|
58
|
+
*/
|
|
59
|
+
function Region (options) {
|
|
60
|
+
this.regionId = options.regionId;
|
|
61
|
+
this.s3RegionId = options.s3RegionId || options.regionId;
|
|
62
|
+
|
|
63
|
+
this.services = options.services || {};
|
|
64
|
+
// use Object.values when min version of Node.js update to ≥ v7.5.0
|
|
65
|
+
Object.keys(SERVICE_NAME).map(k => {
|
|
66
|
+
const v = SERVICE_NAME[k];
|
|
67
|
+
if (!Array.isArray(this.services[v])) {
|
|
68
|
+
this.services[v] = [];
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
this.ttl = options.ttl || 86400;
|
|
73
|
+
this.createTime = options.createTime || new Date();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* This is used to be compatible with Zone.
|
|
78
|
+
* So this function will be removed after remove Zone.
|
|
79
|
+
* NOTE: The Region instance obtained using this method
|
|
80
|
+
* can only be used for the following services: up, io, rs, rsf, api.
|
|
81
|
+
* Because the Zone not support other services.
|
|
82
|
+
* @param {conf.Zone} zone
|
|
83
|
+
* @param {Object} [options]
|
|
84
|
+
* @param {string} [options.regionId]
|
|
85
|
+
* @param {string} [options.s3RegionId]
|
|
86
|
+
* @param {number} [options.ttl]
|
|
87
|
+
* @param {boolean} [options.isPreferCdnHost]
|
|
88
|
+
* @param {string} [options.preferredScheme]
|
|
89
|
+
*/
|
|
90
|
+
Region.fromZone = function (zone, options) {
|
|
91
|
+
options = options || {};
|
|
92
|
+
options.ttl = options.ttl || -1;
|
|
93
|
+
|
|
94
|
+
const upHosts = options.isPreferCdnHost
|
|
95
|
+
? zone.cdnUpHosts.concat(zone.srcUpHosts)
|
|
96
|
+
: zone.srcUpHosts.concat(zone.cdnUpHosts);
|
|
97
|
+
|
|
98
|
+
const endpointOptions = {};
|
|
99
|
+
if (options.preferredScheme) {
|
|
100
|
+
endpointOptions.defaultScheme = options.preferredScheme;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const services = {
|
|
104
|
+
// use array destructure if migrate to typescript
|
|
105
|
+
[SERVICE_NAME.UP]: upHosts.map(
|
|
106
|
+
h => new Endpoint(h, endpointOptions)
|
|
107
|
+
),
|
|
108
|
+
[SERVICE_NAME.IO]: [
|
|
109
|
+
new Endpoint(zone.ioHost, endpointOptions)
|
|
110
|
+
],
|
|
111
|
+
[SERVICE_NAME.RS]: [
|
|
112
|
+
new Endpoint(zone.rsHost, endpointOptions)
|
|
113
|
+
],
|
|
114
|
+
[SERVICE_NAME.RSF]: [
|
|
115
|
+
new Endpoint(zone.rsfHost, endpointOptions)
|
|
116
|
+
],
|
|
117
|
+
[SERVICE_NAME.API]: [
|
|
118
|
+
new Endpoint(zone.apiHost, endpointOptions)
|
|
119
|
+
]
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return new Region({
|
|
123
|
+
regionId: options.regionId,
|
|
124
|
+
s3RegionId: options.s3RegionId || options.regionId,
|
|
125
|
+
services: services,
|
|
126
|
+
ttl: options.ttl
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @param {string} regionId
|
|
132
|
+
* @param {Object} [options]
|
|
133
|
+
* @param {string} [options.s3RegionId]
|
|
134
|
+
* @param {number} [options.ttl]
|
|
135
|
+
* @param {Date} [options.createTime]
|
|
136
|
+
* @param {string} [options.preferredScheme]
|
|
137
|
+
* @param {boolean} [options.isPreferCdnUpHost]
|
|
138
|
+
* @param {Object.<ServiceKey, Endpoint[]>} [options.extendedServices]
|
|
139
|
+
* @returns {Region}
|
|
140
|
+
*/
|
|
141
|
+
Region.fromRegionId = function (regionId, options) {
|
|
142
|
+
options = options || {};
|
|
143
|
+
|
|
144
|
+
const s3RegionId = options.s3RegionId || regionId;
|
|
145
|
+
const ttl = options.ttl;
|
|
146
|
+
const createTime = options.createTime;
|
|
147
|
+
const isPreferCdnUpHost = typeof options.isPreferCdnUpHost === 'boolean'
|
|
148
|
+
? options.isPreferCdnUpHost
|
|
149
|
+
: true;
|
|
150
|
+
|
|
151
|
+
const endpointOptions = {};
|
|
152
|
+
if (options.preferredScheme) {
|
|
153
|
+
endpointOptions.defaultScheme = options.preferredScheme;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const isZ0 = regionId === 'z0';
|
|
157
|
+
let upCdnEndpoints;
|
|
158
|
+
let upSourceEndpoints;
|
|
159
|
+
if (isZ0) {
|
|
160
|
+
upCdnEndpoints = [
|
|
161
|
+
new Endpoint(
|
|
162
|
+
'upload.qiniup.com',
|
|
163
|
+
endpointOptions
|
|
164
|
+
)
|
|
165
|
+
];
|
|
166
|
+
upSourceEndpoints = [
|
|
167
|
+
new Endpoint(
|
|
168
|
+
'up.qiniup.com',
|
|
169
|
+
endpointOptions
|
|
170
|
+
),
|
|
171
|
+
new Endpoint(
|
|
172
|
+
'up.qbox.me',
|
|
173
|
+
endpointOptions
|
|
174
|
+
)
|
|
175
|
+
];
|
|
176
|
+
} else {
|
|
177
|
+
upCdnEndpoints = [
|
|
178
|
+
new Endpoint(
|
|
179
|
+
'upload-' + regionId + '.qiniup.com',
|
|
180
|
+
endpointOptions
|
|
181
|
+
)
|
|
182
|
+
];
|
|
183
|
+
upSourceEndpoints = [
|
|
184
|
+
new Endpoint(
|
|
185
|
+
'up-' + regionId + '.qiniup.com',
|
|
186
|
+
endpointOptions
|
|
187
|
+
),
|
|
188
|
+
new Endpoint(
|
|
189
|
+
'up-' + regionId + '.qbox.me',
|
|
190
|
+
endpointOptions
|
|
191
|
+
)
|
|
192
|
+
];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @type {Object.<ServiceKey, Endpoint[]>}
|
|
197
|
+
*/
|
|
198
|
+
let services = {
|
|
199
|
+
[SERVICE_NAME.UC]: [
|
|
200
|
+
new Endpoint(
|
|
201
|
+
'uc.qiniuapi.com',
|
|
202
|
+
endpointOptions
|
|
203
|
+
)
|
|
204
|
+
],
|
|
205
|
+
[SERVICE_NAME.UP]: isPreferCdnUpHost
|
|
206
|
+
? upCdnEndpoints.concat(upSourceEndpoints)
|
|
207
|
+
: upSourceEndpoints.concat(upCdnEndpoints),
|
|
208
|
+
[SERVICE_NAME.IO]: isZ0
|
|
209
|
+
? [
|
|
210
|
+
new Endpoint(
|
|
211
|
+
'iovip.qiniuio.com',
|
|
212
|
+
endpointOptions
|
|
213
|
+
),
|
|
214
|
+
new Endpoint(
|
|
215
|
+
'iovip.qbox.me',
|
|
216
|
+
endpointOptions
|
|
217
|
+
)
|
|
218
|
+
]
|
|
219
|
+
: [
|
|
220
|
+
new Endpoint(
|
|
221
|
+
'iovip-' + regionId + '.qiniuio.com',
|
|
222
|
+
endpointOptions
|
|
223
|
+
),
|
|
224
|
+
new Endpoint(
|
|
225
|
+
'iovip-' + regionId + '.qbox.me',
|
|
226
|
+
endpointOptions
|
|
227
|
+
)
|
|
228
|
+
],
|
|
229
|
+
[SERVICE_NAME.RS]: [
|
|
230
|
+
new Endpoint(
|
|
231
|
+
'rs-' + regionId + '.qiniuapi.com',
|
|
232
|
+
endpointOptions
|
|
233
|
+
),
|
|
234
|
+
new Endpoint(
|
|
235
|
+
'rs-' + regionId + '.qbox.me',
|
|
236
|
+
endpointOptions
|
|
237
|
+
)
|
|
238
|
+
],
|
|
239
|
+
[SERVICE_NAME.RSF]: [
|
|
240
|
+
new Endpoint(
|
|
241
|
+
'rsf-' + regionId + '.qiniuapi.com',
|
|
242
|
+
endpointOptions
|
|
243
|
+
),
|
|
244
|
+
new Endpoint(
|
|
245
|
+
'rsf-' + regionId + '.qbox.me',
|
|
246
|
+
endpointOptions
|
|
247
|
+
)
|
|
248
|
+
],
|
|
249
|
+
[SERVICE_NAME.API]: [
|
|
250
|
+
new Endpoint(
|
|
251
|
+
'api-' + regionId + '.qiniuapi.com',
|
|
252
|
+
endpointOptions
|
|
253
|
+
),
|
|
254
|
+
new Endpoint(
|
|
255
|
+
'api-' + regionId + '.qbox.me',
|
|
256
|
+
endpointOptions
|
|
257
|
+
)
|
|
258
|
+
],
|
|
259
|
+
[SERVICE_NAME.S3]: [
|
|
260
|
+
new Endpoint(
|
|
261
|
+
's3.' + s3RegionId + '.qiniucs.com',
|
|
262
|
+
endpointOptions
|
|
263
|
+
)
|
|
264
|
+
]
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
services = Object.assign(services, options.extendedServices || {});
|
|
268
|
+
|
|
269
|
+
return new Region({
|
|
270
|
+
regionId: regionId,
|
|
271
|
+
s3RegionId: s3RegionId,
|
|
272
|
+
services: services,
|
|
273
|
+
ttl: ttl,
|
|
274
|
+
createTime: createTime
|
|
275
|
+
});
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* @param {Region} regions
|
|
280
|
+
* @returns {Region}
|
|
281
|
+
*/
|
|
282
|
+
Region.merge = function (...regions) {
|
|
283
|
+
const [source, ...rest] = regions;
|
|
284
|
+
const target = source.clone();
|
|
285
|
+
rest.forEach(s => {
|
|
286
|
+
// use Object.values when min version of Node.js update to ≥ v7.5.0
|
|
287
|
+
Object.keys(s.services).forEach(n => {
|
|
288
|
+
if (!target.services[n]) {
|
|
289
|
+
target.services[n] = s.services[n].map(endpoint => endpoint.clone());
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
s.services[n].forEach(endpoint => {
|
|
293
|
+
if (!target.services[n].some(existsEndpoint => existsEndpoint.getValue() === endpoint.getValue())) {
|
|
294
|
+
target.services[n].push(endpoint.clone());
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
return target;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* @returns {Promise<Region[]>}
|
|
304
|
+
*/
|
|
305
|
+
Region.prototype.getRegions = function () {
|
|
306
|
+
return Promise.resolve([this]);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
Region.prototype.clone = function () {
|
|
310
|
+
// use Object.entries when min version of Node.js update to ≥ v7.5.0
|
|
311
|
+
const services = Object.keys(this.services).reduce((s, n) => {
|
|
312
|
+
s[n] = this.services[n].map(endpoint => endpoint.clone());
|
|
313
|
+
return s;
|
|
314
|
+
}, {});
|
|
315
|
+
return new Region({
|
|
316
|
+
regionId: this.regionId,
|
|
317
|
+
s3RegionId: this.s3RegionId,
|
|
318
|
+
services: services,
|
|
319
|
+
ttl: this.ttl,
|
|
320
|
+
createTime: this.createTime
|
|
321
|
+
});
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* @param {Region} regions
|
|
326
|
+
* @returns {Region}
|
|
327
|
+
*/
|
|
328
|
+
Region.prototype.merge = function (...regions) {
|
|
329
|
+
return Region.merge(this, ...regions);
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
Object.defineProperty(Region.prototype, 'isLive', {
|
|
333
|
+
/**
|
|
334
|
+
* @returns {boolean}
|
|
335
|
+
*/
|
|
336
|
+
get: function () {
|
|
337
|
+
if (this.ttl < 0) {
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
// convert ms to s
|
|
341
|
+
const liveTime = Math.round((Date.now() - this.createTime) / 1000);
|
|
342
|
+
return liveTime < this.ttl;
|
|
343
|
+
},
|
|
344
|
+
enumerable: false,
|
|
345
|
+
configurable: true
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
exports.SERVICE_NAME = SERVICE_NAME;
|
|
349
|
+
exports.Region = Region;
|