@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.
Files changed (102) hide show
  1. package/README.md +82 -0
  2. package/bin/opencode-remote.js +70 -0
  3. package/bin/opencode-weixin.js +10 -0
  4. package/dist/AGENTS.md +20 -0
  5. package/dist/MEMORY.md +21 -0
  6. package/dist/bot-runner.js +180 -0
  7. package/dist/cli.js +256 -0
  8. package/dist/core/approval.js +95 -0
  9. package/dist/core/auth.js +119 -0
  10. package/dist/core/config.js +61 -0
  11. package/dist/core/notifications.js +134 -0
  12. package/dist/core/qiniu.js +267 -0
  13. package/dist/core/registry.js +86 -0
  14. package/dist/core/router.js +344 -0
  15. package/dist/core/session.js +403 -0
  16. package/dist/core/setup.js +418 -0
  17. package/dist/core/types.js +16 -0
  18. package/dist/feishu/adapter.js +72 -0
  19. package/dist/feishu/bot.js +168 -0
  20. package/dist/feishu/commands.js +601 -0
  21. package/dist/feishu/handler.js +380 -0
  22. package/dist/index.js +60 -0
  23. package/dist/opencode/client.js +823 -0
  24. package/dist/package-lock.json +762 -0
  25. package/dist/patch_spawn.js +28 -0
  26. package/dist/plugins/agents/acp/acp-adapter.js +42 -0
  27. package/dist/plugins/agents/claude-code/index.js +69 -0
  28. package/dist/plugins/agents/codex/index.js +44 -0
  29. package/dist/plugins/agents/copilot/index.js +44 -0
  30. package/dist/plugins/agents/opencode/index.js +66 -0
  31. package/dist/telegram/bot.js +288 -0
  32. package/dist/utils/message-split.js +38 -0
  33. package/dist/web/code-viewer.js +266 -0
  34. package/dist/weixin/adapter.js +135 -0
  35. package/dist/weixin/api.js +179 -0
  36. package/dist/weixin/bot.js +183 -0
  37. package/dist/weixin/commands.js +758 -0
  38. package/dist/weixin/handler.js +577 -0
  39. package/dist/weixin/node_modules/encodeurl/LICENSE +22 -0
  40. package/dist/weixin/node_modules/encodeurl/README.md +109 -0
  41. package/dist/weixin/node_modules/encodeurl/index.js +60 -0
  42. package/dist/weixin/node_modules/encodeurl/package.json +40 -0
  43. package/dist/weixin/node_modules/qiniu/.claude/settings.local.json +7 -0
  44. package/dist/weixin/node_modules/qiniu/.github/workflows/ci-test.yml +36 -0
  45. package/dist/weixin/node_modules/qiniu/.github/workflows/npm-publish.yml +20 -0
  46. package/dist/weixin/node_modules/qiniu/.github/workflows/version-check.yml +19 -0
  47. package/dist/weixin/node_modules/qiniu/.idea/MarsCodeWorkspaceAppSettings.xml +7 -0
  48. package/dist/weixin/node_modules/qiniu/.idea/codeStyles/Project.xml +44 -0
  49. package/dist/weixin/node_modules/qiniu/.idea/codeStyles/codeStyleConfig.xml +5 -0
  50. package/dist/weixin/node_modules/qiniu/.idea/git_toolbox_blame.xml +6 -0
  51. package/dist/weixin/node_modules/qiniu/.idea/inspectionProfiles/Project_Default.xml +6 -0
  52. package/dist/weixin/node_modules/qiniu/.idea/jsLibraryMappings.xml +6 -0
  53. package/dist/weixin/node_modules/qiniu/.idea/modules.xml +8 -0
  54. package/dist/weixin/node_modules/qiniu/.idea/nodejs-sdk.iml +12 -0
  55. package/dist/weixin/node_modules/qiniu/.idea/vcs.xml +6 -0
  56. package/dist/weixin/node_modules/qiniu/CHANGELOG.md +292 -0
  57. package/dist/weixin/node_modules/qiniu/README.md +56 -0
  58. package/dist/weixin/node_modules/qiniu/StorageResponseInterface.d.ts +239 -0
  59. package/dist/weixin/node_modules/qiniu/codecov.yml +28 -0
  60. package/dist/weixin/node_modules/qiniu/index.d.ts +1995 -0
  61. package/dist/weixin/node_modules/qiniu/index.js +32 -0
  62. package/dist/weixin/node_modules/qiniu/node_modules/encodeurl/HISTORY.md +14 -0
  63. package/dist/weixin/node_modules/qiniu/node_modules/encodeurl/LICENSE +22 -0
  64. package/dist/weixin/node_modules/qiniu/node_modules/encodeurl/README.md +128 -0
  65. package/dist/weixin/node_modules/qiniu/node_modules/encodeurl/index.js +60 -0
  66. package/dist/weixin/node_modules/qiniu/node_modules/encodeurl/package.json +40 -0
  67. package/dist/weixin/node_modules/qiniu/package.json +80 -0
  68. package/dist/weixin/node_modules/qiniu/qiniu/auth/digest.js +13 -0
  69. package/dist/weixin/node_modules/qiniu/qiniu/cdn.js +149 -0
  70. package/dist/weixin/node_modules/qiniu/qiniu/conf.js +254 -0
  71. package/dist/weixin/node_modules/qiniu/qiniu/fop.js +112 -0
  72. package/dist/weixin/node_modules/qiniu/qiniu/httpc/client.js +253 -0
  73. package/dist/weixin/node_modules/qiniu/qiniu/httpc/endpoint.js +66 -0
  74. package/dist/weixin/node_modules/qiniu/qiniu/httpc/endpointsProvider.js +27 -0
  75. package/dist/weixin/node_modules/qiniu/qiniu/httpc/endpointsRetryPolicy.js +76 -0
  76. package/dist/weixin/node_modules/qiniu/qiniu/httpc/middleware/base.js +31 -0
  77. package/dist/weixin/node_modules/qiniu/qiniu/httpc/middleware/index.js +9 -0
  78. package/dist/weixin/node_modules/qiniu/qiniu/httpc/middleware/qiniuAuth.js +53 -0
  79. package/dist/weixin/node_modules/qiniu/qiniu/httpc/middleware/retryDomains.js +101 -0
  80. package/dist/weixin/node_modules/qiniu/qiniu/httpc/middleware/ua.js +36 -0
  81. package/dist/weixin/node_modules/qiniu/qiniu/httpc/region.js +349 -0
  82. package/dist/weixin/node_modules/qiniu/qiniu/httpc/regionsProvider.js +788 -0
  83. package/dist/weixin/node_modules/qiniu/qiniu/httpc/regionsRetryPolicy.js +242 -0
  84. package/dist/weixin/node_modules/qiniu/qiniu/httpc/responseWrapper.js +40 -0
  85. package/dist/weixin/node_modules/qiniu/qiniu/retry/index.js +4 -0
  86. package/dist/weixin/node_modules/qiniu/qiniu/retry/retrier.js +99 -0
  87. package/dist/weixin/node_modules/qiniu/qiniu/retry/retryPolicy.js +55 -0
  88. package/dist/weixin/node_modules/qiniu/qiniu/rpc.js +237 -0
  89. package/dist/weixin/node_modules/qiniu/qiniu/rtc/app.js +123 -0
  90. package/dist/weixin/node_modules/qiniu/qiniu/rtc/credentials.js +57 -0
  91. package/dist/weixin/node_modules/qiniu/qiniu/rtc/room.js +118 -0
  92. package/dist/weixin/node_modules/qiniu/qiniu/rtc/util.js +16 -0
  93. package/dist/weixin/node_modules/qiniu/qiniu/sms/message.js +58 -0
  94. package/dist/weixin/node_modules/qiniu/qiniu/storage/form.js +442 -0
  95. package/dist/weixin/node_modules/qiniu/qiniu/storage/internal.js +214 -0
  96. package/dist/weixin/node_modules/qiniu/qiniu/storage/resume.js +1272 -0
  97. package/dist/weixin/node_modules/qiniu/qiniu/storage/rs.js +1764 -0
  98. package/dist/weixin/node_modules/qiniu/qiniu/util.js +382 -0
  99. package/dist/weixin/node_modules/qiniu/qiniu/zone.js +230 -0
  100. package/dist/weixin/node_modules/qiniu/tsconfig.json +112 -0
  101. package/dist/weixin/types.js +25 -0
  102. package/package.json +56 -0
@@ -0,0 +1,254 @@
1
+ const os = require('os');
2
+ const pkg = require('../package.json');
3
+ const { Endpoint } = require('./httpc/endpoint');
4
+ const { Region } = require('./httpc/region');
5
+ const { StaticEndpointsProvider } = require('./httpc/endpointsProvider');
6
+ const crypto = require('crypto');
7
+ const {
8
+ CachedRegionsProvider,
9
+ QueryRegionsProvider
10
+ } = require('./httpc/regionsProvider');
11
+
12
+ exports.ACCESS_KEY = '<PLEASE APPLY YOUR ACCESS KEY>';
13
+ exports.SECRET_KEY = '<DONT SEND YOUR SECRET KEY TO ANYONE>';
14
+
15
+ const defaultUserAgent = function () {
16
+ return 'QiniuNodejs/' + pkg.version + ' (' + os.type() + '; ' + os.platform() +
17
+ '; ' + os.arch() + '; )';
18
+ };
19
+
20
+ exports.USER_AGENT = defaultUserAgent();
21
+ exports.BLOCK_SIZE = 4 * 1024 * 1024; // 4MB, never change
22
+
23
+ // define api form mime type
24
+ exports.FormMimeUrl = 'application/x-www-form-urlencoded';
25
+ exports.FormMimeJson = 'application/json';
26
+ exports.FormMimeRaw = 'application/octet-stream';
27
+ exports.RS_HOST = 'rs.qiniu.com';
28
+ exports.RPC_TIMEOUT = 600000; // 600s
29
+ let QUERY_REGION_BACKUP_HOSTS = [
30
+ 'kodo-config.qiniuapi.com',
31
+ 'uc.qbox.me'
32
+ ];
33
+ Object.defineProperty(exports, 'QUERY_REGION_BACKUP_HOSTS', {
34
+ get: () => QUERY_REGION_BACKUP_HOSTS,
35
+ set: v => {
36
+ QUERY_REGION_BACKUP_HOSTS = v;
37
+ }
38
+ });
39
+ let QUERY_REGION_HOST = 'uc.qiniuapi.com';
40
+ Object.defineProperty(exports, 'QUERY_REGION_HOST', {
41
+ get: () => QUERY_REGION_HOST,
42
+ set: v => {
43
+ QUERY_REGION_HOST = v;
44
+ QUERY_REGION_BACKUP_HOSTS = [];
45
+ }
46
+ });
47
+ let UC_BACKUP_HOSTS = QUERY_REGION_BACKUP_HOSTS.slice();
48
+ let UC_HOST = QUERY_REGION_HOST;
49
+ Object.defineProperty(exports, 'UC_HOST', {
50
+ get: () => UC_HOST,
51
+ set: v => {
52
+ UC_HOST = v;
53
+ UC_BACKUP_HOSTS = [];
54
+ QUERY_REGION_HOST = v;
55
+ QUERY_REGION_BACKUP_HOSTS = [];
56
+ }
57
+ });
58
+
59
+ // proxy
60
+ exports.RPC_HTTP_AGENT = null;
61
+ exports.RPC_HTTPS_AGENT = null;
62
+
63
+ const Config = (function () {
64
+ /**
65
+ * @class
66
+ * @constructor
67
+ * @param {Object} [options]
68
+ * @param {boolean} [options.useHttpsDomain]
69
+ * @param {boolean} [options.accelerateUploading] enable accelerate uploading. should active the domains in portal before using
70
+ * @param {EndpointsProvider} [options.ucEndpointsProvider]
71
+ * @param {EndpointsProvider} [options.queryRegionsEndpointsProvider]
72
+ * @param {RegionsProvider} [options.regionsProvider]
73
+ * @param {string} [options.regionsQueryResultCachePath]
74
+ *
75
+ * @param {boolean} [options.useCdnDomain] DEPRECATED: use accelerateUploading instead
76
+ * @param {Zone} [options.zone] DEPRECATED: use RegionsProvider instead
77
+ * @param {number} [options.zoneExpire] DEPRECATED
78
+ */
79
+ function Config (options) {
80
+ options = options || {};
81
+ // use http or https protocol
82
+ this.useHttpsDomain = !!(options.useHttpsDomain || false);
83
+
84
+ // use accelerate upload domains
85
+ this.accelerateUploading = !!(options.accelerateUploading || false);
86
+
87
+ // custom uc endpoints
88
+ this.ucEndpointsProvider = options.ucEndpointsProvider || null;
89
+ // custom query region endpoints
90
+ this.queryRegionsEndpointsProvider = options.queryRegionsEndpointsProvider || null;
91
+ // custom regions
92
+ this.regionsProvider = options.regionsProvider || null;
93
+ // custom cache persisting path for regions query result
94
+ // only worked with default CachedRegionsProvider
95
+ this.regionsQueryResultCachePath = options.regionsQueryResultCachePath;
96
+
97
+ // deprecated
98
+ // use cdn accelerated domains, this is not work with auto query region
99
+ this.useCdnDomain = !!(options.useCdnDomain && true);
100
+ // zone of the bucket
101
+ this.zone = options.zone || null;
102
+ this.zoneExpire = options.zoneExpire || -1;
103
+ }
104
+
105
+ /**
106
+ * @returns {EndpointsProvider}
107
+ */
108
+ Config.prototype.getUcEndpointsProvider = function () {
109
+ if (this.ucEndpointsProvider) {
110
+ return this.ucEndpointsProvider;
111
+ }
112
+
113
+ return new StaticEndpointsProvider(
114
+ [UC_HOST].concat(UC_BACKUP_HOSTS).map(h => new Endpoint(h, {
115
+ defaultScheme: this.useHttpsDomain ? 'https' : 'http'
116
+ }))
117
+ );
118
+ };
119
+
120
+ /**
121
+ * @private
122
+ * @returns {EndpointsProvider}
123
+ */
124
+ Config.prototype._getQueryRegionEndpointsProvider = function () {
125
+ if (this.queryRegionsEndpointsProvider) {
126
+ return this.queryRegionsEndpointsProvider;
127
+ }
128
+
129
+ if (this.ucEndpointsProvider) {
130
+ return this.ucEndpointsProvider;
131
+ }
132
+
133
+ const queryRegionsHosts = [QUERY_REGION_HOST].concat(QUERY_REGION_BACKUP_HOSTS);
134
+ return new StaticEndpointsProvider(queryRegionsHosts.map(h =>
135
+ new Endpoint(
136
+ h,
137
+ {
138
+ defaultScheme: this.useHttpsDomain ? 'https' : 'http'
139
+ }
140
+ )
141
+ ));
142
+ };
143
+
144
+ /**
145
+ * @param {Object} [options]
146
+ * @param {string} [options.bucketName]
147
+ * @param {string} [options.accessKey]
148
+ * @returns {Promise<RegionsProvider>}
149
+ */
150
+ Config.prototype.getRegionsProvider = function (options) {
151
+ // returns custom regions provider, if it's configured
152
+ if (this.regionsProvider) {
153
+ return Promise.resolve(this.regionsProvider);
154
+ }
155
+
156
+ // backward compatibility with custom zone configuration
157
+ const zoneProvider = getRegionsProviderFromZone.call(this);
158
+ if (zoneProvider) {
159
+ return Promise.resolve(zoneProvider);
160
+ }
161
+
162
+ // get default regions provider
163
+ const {
164
+ bucketName,
165
+ accessKey
166
+ } = options || {};
167
+ if (!bucketName || !accessKey) {
168
+ return Promise.reject(
169
+ new Error('bucketName and accessKey is required for query regions')
170
+ );
171
+ }
172
+ return getDefaultRegionsProvider.call(this, {
173
+ bucketName,
174
+ accessKey
175
+ });
176
+ };
177
+
178
+ /**
179
+ * @private
180
+ * @returns {RegionsProvider | undefined}
181
+ */
182
+ function getRegionsProviderFromZone () {
183
+ let zoneTTL;
184
+ let shouldUseZone;
185
+ if (this.zoneExpire > 0) {
186
+ zoneTTL = this.zoneExpire - Math.trunc(Date.now() / 1000);
187
+ shouldUseZone = this.zone && zoneTTL > 0;
188
+ } else {
189
+ zoneTTL = -1;
190
+ shouldUseZone = Boolean(this.zone);
191
+ }
192
+ if (!shouldUseZone) {
193
+ return;
194
+ }
195
+ return Region.fromZone(this.zone, {
196
+ ttl: zoneTTL,
197
+ isPreferCdnHost: this.useCdnDomain,
198
+ preferredScheme: this.useHttpsDomain ? 'https' : 'http'
199
+ });
200
+ }
201
+
202
+ /**
203
+ * @private
204
+ * @param {Object} options
205
+ * @param {string} options.bucketName
206
+ * @param {string} options.accessKey
207
+ * @returns {Promise<RegionsProvider>}
208
+ */
209
+ function getDefaultRegionsProvider (options) {
210
+ const {
211
+ bucketName,
212
+ accessKey
213
+ } = options;
214
+
215
+ const queryRegionsEndpointsProvider = this._getQueryRegionEndpointsProvider();
216
+ return queryRegionsEndpointsProvider
217
+ .getEndpoints()
218
+ .then(endpoints => {
219
+ const endpointsMd5 = endpoints
220
+ .map(e => e.host)
221
+ .sort()
222
+ .reduce(
223
+ (hash, host) => hash.update(host),
224
+ crypto.createHash('md5')
225
+ )
226
+ .digest('hex');
227
+ const cacheKey = [
228
+ endpointsMd5,
229
+ accessKey,
230
+ bucketName,
231
+ this.accelerateUploading.toString()
232
+ ].join(':');
233
+ return new CachedRegionsProvider({
234
+ persistPath: this.regionsQueryResultCachePath,
235
+ cacheKey,
236
+ baseRegionsProvider: new QueryRegionsProvider({
237
+ accessKey: accessKey,
238
+ bucketName: bucketName,
239
+ endpointsProvider: queryRegionsEndpointsProvider,
240
+ preferredScheme: this.useHttpsDomain ? 'https' : 'http'
241
+ })
242
+ });
243
+ });
244
+ }
245
+
246
+ return Config;
247
+ })();
248
+
249
+ exports.Config = Config;
250
+ /**
251
+ * backward compatibility
252
+ * @deprecated use qiniu/httpc/region.js instead
253
+ */
254
+ exports.Zone = require('./zone').Zone;
@@ -0,0 +1,112 @@
1
+ const util = require('./util');
2
+ const rpc = require('./rpc');
3
+ const conf = require('./conf');
4
+ const digest = require('./auth/digest');
5
+ const querystring = require('querystring');
6
+
7
+ exports.OperationManager = OperationManager;
8
+
9
+ function OperationManager (mac, config) {
10
+ this.mac = mac || new digest.Mac();
11
+ this.config = config || new conf.Config();
12
+ }
13
+
14
+ /**
15
+ * @typedef {function(Error, any, IncomingMessage)} OperationCallback
16
+ */
17
+
18
+ /**
19
+ * @param {string} bucket 空间名称
20
+ * @param {string} key 文件名称
21
+ * @param {string[]} fops 处理指令
22
+ * @param {string} [pipeline] 队列名称
23
+ * @param {object} options 可选参数
24
+ * @param {string} [options.notifyURL] 回调业务服务器,通知处理结果
25
+ * @param {boolean} [options.force] 是否强制覆盖已有的同名文件
26
+ * @param {string} [options.type] 为 `1` 时,开启闲时任务
27
+ * @param {string} [options.workflowTemplateID] 工作流模板 ID
28
+ * @param {OperationCallback} callbackFunc 回调函数
29
+ */
30
+ OperationManager.prototype.pfop = function (
31
+ bucket,
32
+ key,
33
+ fops,
34
+ pipeline,
35
+ options,
36
+ callbackFunc
37
+ ) {
38
+ options = options || {};
39
+ // 必须参数
40
+ const reqParams = {
41
+ bucket: bucket,
42
+ key: key
43
+ };
44
+ // `fops` is optional by could use `options.workflowTemplateID` to work
45
+ if (Array.isArray(fops)) {
46
+ reqParams.fops = fops.join(';');
47
+ }
48
+
49
+ // pipeline
50
+ if (pipeline) {
51
+ reqParams.pipeline = pipeline;
52
+ }
53
+
54
+ // notifyURL
55
+ if (options.notifyURL) {
56
+ reqParams.notifyURL = options.notifyURL;
57
+ }
58
+
59
+ // force
60
+ if (options.force) {
61
+ reqParams.force = 1;
62
+ }
63
+
64
+ // workflowTemplateID
65
+ if (options.workflowTemplateID) {
66
+ reqParams.workflowTemplateID = options.workflowTemplateID;
67
+ }
68
+
69
+ const persistentType = parseInt(options.type, 10);
70
+ if (!isNaN(persistentType)) {
71
+ reqParams.type = persistentType;
72
+ }
73
+
74
+ util.prepareZone(this, this.mac.accessKey, bucket, function (err, ctx) {
75
+ if (err) {
76
+ callbackFunc(err, null, null);
77
+ return;
78
+ }
79
+ pfopReq(ctx.mac, ctx.config, reqParams, callbackFunc);
80
+ });
81
+ };
82
+
83
+ function pfopReq (mac, config, reqParams, callbackFunc) {
84
+ const scheme = config.useHttpsDomain ? 'https://' : 'http://';
85
+ const requestURI = scheme + config.zone.apiHost + '/pfop/';
86
+ const reqBody = querystring.stringify(reqParams);
87
+ const auth = util.generateAccessToken(mac, requestURI, reqBody);
88
+ rpc.postWithForm(requestURI, reqBody, auth, callbackFunc);
89
+ }
90
+
91
+ /**
92
+ * 查询持久化数据处理进度
93
+ * @param {string} persistentId
94
+ * @param {OperationCallback} callbackFunc 回调函数
95
+ */
96
+ OperationManager.prototype.prefop = function (
97
+ persistentId,
98
+ callbackFunc
99
+ ) {
100
+ let apiHost = 'api.qiniu.com';
101
+ if (this.config.zone) {
102
+ apiHost = this.config.zone.apiHost;
103
+ }
104
+
105
+ const scheme = this.config.useHttpsDomain ? 'https://' : 'http://';
106
+ const requestURI = scheme + apiHost + '/status/get/prefop';
107
+ const reqParams = {
108
+ id: persistentId
109
+ };
110
+ const reqBody = querystring.stringify(reqParams);
111
+ rpc.postWithForm(requestURI, reqBody, null, callbackFunc);
112
+ };
@@ -0,0 +1,253 @@
1
+ const http = require('http');
2
+ const https = require('https');
3
+
4
+ const urllib = require('urllib');
5
+
6
+ const middleware = require('./middleware');
7
+ const { ResponseWrapper } = require('./responseWrapper');
8
+
9
+ /**
10
+ *
11
+ * @param {Object} options
12
+ * @param {http.Agent} [options.httpAgent]
13
+ * @param {https.Agent} [options.httpsAgent]
14
+ * @param {middleware.Middleware[]} [options.middlewares]
15
+ * @param {number | number[]} [options.timeout]
16
+ * @constructor
17
+ */
18
+ function HttpClient (options) {
19
+ this.httpAgent = options.httpAgent || http.globalAgent;
20
+ this.httpsAgent = options.httpsAgent || https.globalAgent;
21
+ this.middlewares = options.middlewares || [];
22
+ this.timeout = options.timeout;
23
+ }
24
+
25
+ HttpClient.prototype._handleRequest = function (req) {
26
+ return new Promise((resolve, reject) => {
27
+ try {
28
+ urllib.request(req.url, req.urllibOptions, (err, data, resp) => {
29
+ if (err) {
30
+ err.resp = resp;
31
+ reject(err);
32
+ return;
33
+ }
34
+ resolve(new ResponseWrapper({ data, resp }));
35
+ });
36
+ } catch (e) {
37
+ reject(e);
38
+ }
39
+ });
40
+ };
41
+
42
+ /**
43
+ * Options for request
44
+ * @typedef {Object} ReqOpts
45
+ * @property {http.Agent} [agent]
46
+ * @property {https.Agent} [httpsAgent]
47
+ * @property {string} url
48
+ * @property {middleware.Middleware[]} [middlewares]
49
+ * @property {urllib.Callback} [callback]
50
+ * @property {urllib.RequestOptions} urllibOptions
51
+ */
52
+
53
+ /**
54
+ *
55
+ * @param {ReqOpts} requestOptions
56
+ * @returns {Promise<ResponseWrapper>}
57
+ */
58
+ HttpClient.prototype.sendRequest = function (requestOptions) {
59
+ const mwList = this.middlewares.concat(requestOptions.middlewares || []);
60
+
61
+ if (!requestOptions.agent) {
62
+ requestOptions.agent = this.httpAgent;
63
+ }
64
+
65
+ if (!requestOptions.httpsAgent) {
66
+ requestOptions.httpsAgent = this.httpsAgent;
67
+ }
68
+
69
+ if (!requestOptions.urllibOptions.headers) {
70
+ requestOptions.urllibOptions.headers = {};
71
+ }
72
+
73
+ if (!requestOptions.urllibOptions.headers['Content-Type']) {
74
+ requestOptions.urllibOptions.headers['Content-Type'] = 'application/x-www-form-urlencoded';
75
+ }
76
+
77
+ const handle = middleware.composeMiddlewares(
78
+ mwList,
79
+ this._handleRequest
80
+ );
81
+
82
+ const resPromise = handle(requestOptions);
83
+
84
+ if (requestOptions.callback) {
85
+ // user should handle callback error outside.
86
+ // already wrapped callback for inner usage in storage.
87
+ resPromise.then(({ data, resp }) => {
88
+ requestOptions.callback(null, data, resp);
89
+ });
90
+ // no chained for preventing callback twice when callback errored.
91
+ resPromise.catch(err => {
92
+ requestOptions.callback(err, null, err.resp);
93
+ });
94
+ }
95
+
96
+ return resPromise;
97
+ };
98
+
99
+ /**
100
+ * @param {Object} reqOptions
101
+ * @param {string} reqOptions.url
102
+ * @param {http.Agent} [reqOptions.agent]
103
+ * @param {https.Agent} [reqOptions.httpsAgent]
104
+ * @param {Object} [reqOptions.params]
105
+ * @param {Object} [reqOptions.headers]
106
+ * @param {middleware.Middleware[]} [reqOptions.middlewares]
107
+ * @param {urllib.RequestOptions} [urllibOptions]
108
+ * @returns {Promise<ResponseWrapper>}
109
+ */
110
+ HttpClient.prototype.get = function (reqOptions, urllibOptions) {
111
+ const {
112
+ url,
113
+ params,
114
+ headers,
115
+ middlewares,
116
+ agent,
117
+ httpsAgent,
118
+ callback
119
+ } = reqOptions;
120
+
121
+ urllibOptions = urllibOptions || {};
122
+ urllibOptions.method = 'GET';
123
+ urllibOptions.headers = Object.assign(
124
+ {
125
+ Connection: 'keep-alive'
126
+ },
127
+ headers,
128
+ urllibOptions.headers || {}
129
+ );
130
+ urllibOptions.data = params;
131
+ urllibOptions.followRedirect = true;
132
+ urllibOptions.gzip = urllibOptions.gzip !== undefined ? urllibOptions.gzip : true;
133
+ urllibOptions.dataType = urllibOptions.dataType || 'json';
134
+ urllibOptions.timeout = urllibOptions.timeout || this.timeout;
135
+
136
+ return this.sendRequest({
137
+ url: url,
138
+ middlewares: middlewares,
139
+ agent: agent,
140
+ httpsAgent: httpsAgent,
141
+ callback: callback,
142
+ urllibOptions: urllibOptions
143
+ });
144
+ };
145
+
146
+ /**
147
+ * @param {Object} reqOptions
148
+ * @param {string} reqOptions.url
149
+ * @param {http.Agent} [reqOptions.agent]
150
+ * @param {https.Agent} [reqOptions.httpsAgent]
151
+ * @param {string | Buffer | Readable} [reqOptions.data]
152
+ * @param {Object} [reqOptions.headers]
153
+ * @param {middleware.Middleware[]} [reqOptions.middlewares]
154
+ * @param {function(err: Error | null, ret: any, info: IncomingMessage): void} [reqOptions.callback]
155
+ * @param {urllib.RequestOptions} [urllibOptions]
156
+ * @returns {Promise<ResponseWrapper>}
157
+ */
158
+ HttpClient.prototype.post = function (reqOptions, urllibOptions) {
159
+ const {
160
+ url,
161
+ data,
162
+ headers,
163
+ middlewares,
164
+ agent,
165
+ httpsAgent,
166
+ callback
167
+ } = reqOptions;
168
+
169
+ urllibOptions = urllibOptions || {};
170
+ urllibOptions.method = 'POST';
171
+ urllibOptions.headers = Object.assign(
172
+ {
173
+ Connection: 'keep-alive'
174
+ },
175
+ headers,
176
+ urllibOptions.headers || {}
177
+ );
178
+ urllibOptions.gzip = urllibOptions.gzip !== undefined ? urllibOptions.gzip : true;
179
+ urllibOptions.dataType = urllibOptions.dataType || 'json';
180
+ urllibOptions.timeout = urllibOptions.timeout || this.timeout;
181
+
182
+ if (Buffer.isBuffer(data) || typeof data === 'string') {
183
+ urllibOptions.content = data;
184
+ } else if (data) {
185
+ urllibOptions.stream = data;
186
+ } else {
187
+ urllibOptions.headers['Content-Length'] = '0';
188
+ }
189
+
190
+ return this.sendRequest({
191
+ url: url,
192
+ middlewares: middlewares,
193
+ agent: agent,
194
+ httpsAgent: httpsAgent,
195
+ callback: callback,
196
+ urllibOptions: urllibOptions
197
+ });
198
+ };
199
+
200
+ /**
201
+ * @param {Object} reqOptions
202
+ * @param {string} reqOptions.url
203
+ * @param {http.Agent} [reqOptions.agent]
204
+ * @param {https.Agent} [reqOptions.httpsAgent]
205
+ * @param {string | Buffer | ReadableStream} [reqOptions.data]
206
+ * @param {Object} [reqOptions.headers]
207
+ * @param {middleware.Middleware[]} [reqOptions.middlewares]
208
+ * @param {urllib.RequestOptions} [urllibOptions]
209
+ * @returns {Promise<ResponseWrapper>}
210
+ */
211
+ HttpClient.prototype.put = function (reqOptions, urllibOptions) {
212
+ const {
213
+ url,
214
+ data,
215
+ headers,
216
+ middlewares,
217
+ agent,
218
+ httpsAgent,
219
+ callback
220
+ } = reqOptions;
221
+
222
+ urllibOptions = urllibOptions || {};
223
+ urllibOptions.method = 'PUT';
224
+ urllibOptions.headers = Object.assign(
225
+ {
226
+ Connection: 'keep-alive'
227
+ },
228
+ headers,
229
+ urllibOptions.headers || {}
230
+ );
231
+ urllibOptions.gzip = urllibOptions.gzip !== undefined ? urllibOptions.gzip : true;
232
+ urllibOptions.dataType = urllibOptions.dataType || 'json';
233
+ urllibOptions.timeout = urllibOptions.timeout || this.timeout;
234
+
235
+ if (Buffer.isBuffer(data) || typeof data === 'string') {
236
+ urllibOptions.content = data;
237
+ } else if (data) {
238
+ urllibOptions.stream = data;
239
+ } else {
240
+ urllibOptions.headers['Content-Length'] = '0';
241
+ }
242
+
243
+ return this.sendRequest({
244
+ url: url,
245
+ middlewares: middlewares,
246
+ agent: agent,
247
+ httpsAgent: httpsAgent,
248
+ callback: callback,
249
+ urllibOptions: urllibOptions
250
+ });
251
+ };
252
+
253
+ exports.HttpClient = HttpClient;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @interface EndpointsProvider
3
+ */
4
+
5
+ /**
6
+ * @function
7
+ * @name EndpointsProvider#getEndpoints
8
+ * @returns {Promise<Endpoint[]>}
9
+ */
10
+
11
+ /**
12
+ * @interface MutableEndpointsProvider
13
+ * @extends EndpointsProvider
14
+ */
15
+
16
+ /**
17
+ * @function
18
+ * @name MutableEndpointsProvider#setEndpoints
19
+ * @param {endpoints: Endpoint[]} endpoints
20
+ * @returns {Promise<void>}
21
+ */
22
+
23
+ // --- could split to files if migrate to typescript --- //
24
+
25
+ /**
26
+ * @class
27
+ * @implements EndpointsProvider
28
+ * @param {string} host
29
+ * @param {Object} [options]
30
+ * @param {string} [options.defaultScheme]
31
+ * @constructor
32
+ */
33
+ function Endpoint (host, options) {
34
+ options = options || {};
35
+
36
+ this.host = host;
37
+ this.defaultScheme = options.defaultScheme || 'https';
38
+ }
39
+
40
+ /**
41
+ * @param {Object} [options]
42
+ * @param {string} [options.scheme]
43
+ */
44
+ Endpoint.prototype.getValue = function (options) {
45
+ options = options || {};
46
+
47
+ const scheme = options.scheme || this.defaultScheme;
48
+ const host = this.host;
49
+
50
+ return scheme + '://' + host;
51
+ };
52
+
53
+ /**
54
+ * @returns {Promise<Endpoint[]>}
55
+ */
56
+ Endpoint.prototype.getEndpoints = function () {
57
+ return Promise.resolve([this]);
58
+ };
59
+
60
+ Endpoint.prototype.clone = function () {
61
+ return new Endpoint(this.host, {
62
+ defaultScheme: this.defaultScheme
63
+ });
64
+ };
65
+
66
+ exports.Endpoint = Endpoint;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @class
3
+ * @implements EndpointsProvider
4
+ * @property {Endpoint[]} endpoints
5
+ * @constructor
6
+ * @param {Endpoint[]} endpoints
7
+ */
8
+ function StaticEndpointsProvider (endpoints) {
9
+ this.endpoints = endpoints;
10
+ }
11
+
12
+ /**
13
+ * @param {Region} region
14
+ * @param {string} serviceName
15
+ */
16
+ StaticEndpointsProvider.fromRegion = function (region, serviceName) {
17
+ return new StaticEndpointsProvider(region.services[serviceName]);
18
+ };
19
+
20
+ /**
21
+ * @returns {Promise<Endpoint[]>}
22
+ */
23
+ StaticEndpointsProvider.prototype.getEndpoints = function () {
24
+ return Promise.resolve(this.endpoints);
25
+ };
26
+
27
+ exports.StaticEndpointsProvider = StaticEndpointsProvider;