@verdaccio/proxy 9.0.0-next-9.3 → 9.0.0-next-9.5

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/build/proxy.js CHANGED
@@ -1,599 +1,411 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "FetchOptions", {
7
- enumerable: true,
8
- get: function get() {
9
- return _gotCjs.Options;
10
- }
11
- });
12
- exports.ProxyStorage = void 0;
13
- var _JSONStream = _interopRequireDefault(require("JSONStream"));
14
- var _debug = _interopRequireDefault(require("debug"));
15
- var _gotCjs = _interopRequireWildcard(require("got-cjs"));
16
- var _lodash = _interopRequireDefault(require("lodash"));
17
- var _nodeStream = require("node:stream");
18
- var _nodeUrl = require("node:url");
19
- var _core = require("@verdaccio/core");
20
- var _agent = _interopRequireDefault(require("./agent"));
21
- var _proxyUtils = require("./proxy-utils");
22
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t3 in e) "default" !== _t3 && {}.hasOwnProperty.call(e, _t3) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t3)) && (i.get || i.set) ? o(f, _t3, i) : f[_t3] = e[_t3]); return f; })(e, t); }
23
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
24
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
25
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
26
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
27
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
28
- function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
29
- function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
30
- function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
31
- function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
32
- function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
33
- function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
34
- function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
35
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
36
- function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
37
- var debug = (0, _debug["default"])('verdaccio:proxy');
38
- var encode = function encode(thing) {
39
- return encodeURIComponent(thing).replace(/^%40/, '@');
1
+ const require_runtime = require("./_virtual/_rolldown/runtime.js");
2
+ const require_agent = require("./agent.js");
3
+ const require_proxy_utils = require("./proxy-utils.js");
4
+ let JSONStream = require("JSONStream");
5
+ JSONStream = require_runtime.__toESM(JSONStream);
6
+ let debug = require("debug");
7
+ debug = require_runtime.__toESM(debug);
8
+ let got_cjs = require("got-cjs");
9
+ got_cjs = require_runtime.__toESM(got_cjs);
10
+ let lodash = require("lodash");
11
+ lodash = require_runtime.__toESM(lodash);
12
+ let node_stream = require("node:stream");
13
+ let node_url = require("node:url");
14
+ let _verdaccio_core = require("@verdaccio/core");
15
+ //#region src/proxy.ts
16
+ var debug$1 = (0, debug.default)("verdaccio:proxy");
17
+ var encode = function(thing) {
18
+ return encodeURIComponent(thing).replace(/^%40/, "@");
40
19
  };
41
- var jsonContentType = _core.HEADERS.JSON;
42
- var contentTypeAccept = "".concat(jsonContentType, ";");
43
-
20
+ var contentTypeAccept = `${_verdaccio_core.HEADERS.JSON};`;
44
21
  /**
45
- * Just a helper (`config[key] || default` doesn't work because of zeroes)
46
- */
47
- var setConfig = function setConfig(config, key, def) {
48
- return _lodash["default"].isNil(config[key]) === false ? config[key] : def;
22
+ * Just a helper (`config[key] || default` doesn't work because of zeroes)
23
+ */
24
+ var setConfig = (config, key, def) => {
25
+ return lodash.default.isNil(config[key]) === false ? config[key] : def;
49
26
  };
50
-
51
- // this type is need it by storage
52
27
  /**
53
- * Implements Storage interface
54
- * (same for storage.js, local-storage.js, up-storage.js)
55
- */
56
- var ProxyStorage = exports.ProxyStorage = /*#__PURE__*/function () {
57
- // @ts-ignore
58
-
59
- function ProxyStorage(uplinkName, config, mainConfig, logger, agent) {
60
- var _mainConfig$user_agen, _this$config$max_fail, _this$max_fails;
61
- _classCallCheck(this, ProxyStorage);
62
- this.uplinkName = uplinkName;
63
- this.config = config;
64
- this.failed_requests = 0;
65
- this.userAgent = (_mainConfig$user_agen = mainConfig.user_agent) !== null && _mainConfig$user_agen !== void 0 ? _mainConfig$user_agen : 'hidden';
66
- this.ca = config.ca;
67
- this.logger = logger;
68
- this.server_id = mainConfig.server_id;
69
- this.agent_options = setConfig(this.config, 'agent_options', {
70
- keepAlive: true,
71
- maxSockets: 40,
72
- maxFreeSockets: 10
73
- });
74
- this.url = new _nodeUrl.URL(this.config.url);
75
- var isHTTPS = this.url.protocol === 'https:';
76
- this._setupProxy(this.url.hostname, config, mainConfig, isHTTPS);
77
- this.agent = agent !== null && agent !== void 0 ? agent : this.getAgent();
78
- this.config.url = this.config.url.replace(/\/$/, '');
79
- if (this.config.timeout && Number(this.config.timeout) >= 1000) {
80
- this.logger.warn(['Too big timeout value: ' + this.config.timeout, 'We changed time format to nginx-like one', '(see http://nginx.org/en/docs/syntax.html)', 'so please update your config accordingly'].join('\n'));
81
- }
82
-
83
- // a bunch of different configurable timers
84
- this.maxage = (0, _proxyUtils.parseInterval)(setConfig(this.config, 'maxage', '2m'));
85
- // https://github.com/sindresorhus/got/blob/main/documentation/6-timeout.md
86
- this.timeout = {
87
- request: (0, _proxyUtils.parseInterval)(setConfig(this.config, 'timeout', '30s'))
88
- };
89
- debug('set timeout %s', this.timeout);
90
- this.max_fails = Number(setConfig(this.config, 'max_fails', (_this$config$max_fail = this.config.max_fails) !== null && _this$config$max_fail !== void 0 ? _this$config$max_fail : 2));
91
- this.fail_timeout = (0, _proxyUtils.parseInterval)(setConfig(this.config, 'fail_timeout', '5m'));
92
- this.strict_ssl = Boolean(setConfig(this.config, 'strict_ssl', true));
93
- this.retry = {
94
- limit: (_this$max_fails = this.max_fails) !== null && _this$max_fails !== void 0 ? _this$max_fails : 2
95
- };
96
- }
97
- return _createClass(ProxyStorage, [{
98
- key: "getAgent",
99
- value: function getAgent() {
100
- if (!this.agent) {
101
- // TODO: the config.ca (certificates) is not yet injected here
102
- var agentInstance = new _agent["default"](this.config.url, this.proxy, this.agent_options);
103
- return agentInstance.get();
104
- } else {
105
- return this.agent;
106
- }
107
- }
108
- }, {
109
- key: "getHeaders",
110
- value: function getHeaders() {
111
- var headers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
112
- var accept = _core.HEADERS.ACCEPT;
113
- var acceptEncoding = _core.HEADERS.ACCEPT_ENCODING;
114
- var userAgent = _core.HEADERS.USER_AGENT;
115
- headers[accept] = headers[accept] || contentTypeAccept;
116
- headers[acceptEncoding] = headers[acceptEncoding] || 'gzip';
117
- // registry.npmjs.org will only return search result if user-agent include string 'npm'
118
- headers[userAgent] = headers[userAgent] || "npm (".concat(this.userAgent, ")");
119
- return this.setAuthNext(headers);
120
- }
121
-
122
- /**
123
- * Validate configuration auth and assign Header authorization
124
- * @param {Object} headers
125
- * @return {Object}
126
- * @private
127
- */
128
- }, {
129
- key: "setAuthNext",
130
- value: function setAuthNext(headers) {
131
- var auth = this.config.auth;
132
- if (typeof auth === 'undefined' || typeof headers[_core.HEADERS.AUTHORIZATION] === 'string') {
133
- return headers;
134
- }
135
- if (_lodash["default"].isObject(auth) === false && _lodash["default"].isObject(auth.token) === false) {
136
- this._throwErrorAuth('Auth invalid');
137
- }
138
-
139
- // get NPM_TOKEN http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules
140
- // or get other variable export in env
141
- // https://github.com/verdaccio/verdaccio/releases/tag/v2.5.0
142
- var token;
143
- var tokenConf = auth;
144
- if (_lodash["default"].isNil(tokenConf.token) === false && _lodash["default"].isString(tokenConf.token)) {
145
- debug('use token from config');
146
- token = tokenConf.token;
147
- } else if (_lodash["default"].isNil(tokenConf.token_env) === false) {
148
- if (typeof tokenConf.token_env === 'string') {
149
- debug('use token from env %o', tokenConf.token_env);
150
- token = process.env[tokenConf.token_env];
151
- } else if (typeof tokenConf.token_env === 'boolean' && tokenConf.token_env) {
152
- debug('use token from env NPM_TOKEN');
153
- token = process.env.NPM_TOKEN;
154
- } else {
155
- this.logger.error(_core.constants.ERROR_CODE.token_required);
156
- this._throwErrorAuth(_core.constants.ERROR_CODE.token_required);
157
- }
158
- } else {
159
- debug('use token from env NPM_TOKEN');
160
- token = process.env.NPM_TOKEN;
161
- }
162
- if (typeof token === 'undefined') {
163
- this._throwErrorAuth(_core.constants.ERROR_CODE.token_required);
164
- }
165
-
166
- // define type Auth allow basic and bearer
167
- var type = tokenConf.type || _core.TOKEN_BASIC;
168
- debug('token type %o', type);
169
- this._setHeaderAuthorization(headers, type, token);
170
- return headers;
171
- }
172
-
173
- /**
174
- * @param {string} message
175
- * @throws {Error}
176
- * @private
177
- */
178
- }, {
179
- key: "_throwErrorAuth",
180
- value: function _throwErrorAuth(message) {
181
- this.logger.error(message);
182
- throw new Error(message);
183
- }
184
-
185
- /**
186
- * Assign Header authorization with type authentication
187
- * @param {Object} headers
188
- * @param {string} type
189
- * @param {string} token
190
- * @private
191
- */
192
- }, {
193
- key: "_setHeaderAuthorization",
194
- value: function _setHeaderAuthorization(headers, type, token) {
195
- var _type = type.toLowerCase();
196
- if (_type !== _core.TOKEN_BEARER.toLowerCase() && _type !== _core.TOKEN_BASIC.toLowerCase()) {
197
- this._throwErrorAuth("Auth type '".concat(_type, "' not allowed"));
198
- }
199
- headers[_core.HEADERS.AUTHORIZATION] = _core.authUtils.buildToken(type, token);
200
- }
201
-
202
- /**
203
- * It will add or override specified headers from config file.
204
- *
205
- * Eg:
206
- *
207
- * uplinks:
208
- npmjs:
209
- url: https://registry.npmjs.org/
210
- headers:
211
- Accept: "application/vnd.npm.install-v2+json; q=1.0"
212
- verdaccio-staging:
213
- url: https://mycompany.com/npm
214
- headers:
215
- Accept: "application/json"
216
- authorization: "Basic YourBase64EncodedCredentials=="
217
- * @param {Object} headers
218
- * @private
219
- */
220
- }, {
221
- key: "applyUplinkHeaders",
222
- value: function applyUplinkHeaders(headers) {
223
- if (!this.config.headers) {
224
- return headers;
225
- }
226
-
227
- // add/override headers specified in the config
228
- /* eslint guard-for-in: 0 */
229
- for (var _key in this.config.headers) {
230
- headers[_key] = this.config.headers[_key];
231
- }
232
- return headers;
233
- }
234
- }, {
235
- key: "getRemoteMetadata",
236
- value: function () {
237
- var _getRemoteMetadata = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(name, options) {
238
- var _this = this;
239
- var headers, method, uri, response, responseLength, _options$retry, _response, retry, etag, data, err, message, code, error, _t;
240
- return _regenerator().w(function (_context) {
241
- while (1) switch (_context.p = _context.n) {
242
- case 0:
243
- if (!this._ifRequestFailure()) {
244
- _context.n = 1;
245
- break;
246
- }
247
- throw _core.errorUtils.getInternalError(_core.API_ERROR.UPLINK_OFFLINE);
248
- case 1:
249
- // FUTURE: allow mix headers that comes from the client
250
- debug('getting metadata for package %s', name);
251
- headers = this.getHeaders(options === null || options === void 0 ? void 0 : options.headers);
252
- headers = this.addProxyHeaders(headers, options.remoteAddress);
253
- headers = this.applyUplinkHeaders(headers);
254
- // the following headers cannot be overwritten
255
- if (_lodash["default"].isNil(options.etag) === false) {
256
- headers[_core.HEADERS.NONE_MATCH] = options.etag;
257
- headers[_core.HEADERS.ACCEPT] = contentTypeAccept;
258
- }
259
- method = options.method || 'GET';
260
- uri = this.config.url + "/".concat(encode(name));
261
- debug('set retry limit is %s', this.retry.limit);
262
- responseLength = 0;
263
- _context.p = 2;
264
- retry = (_options$retry = options === null || options === void 0 ? void 0 : options.retry) !== null && _options$retry !== void 0 ? _options$retry : this.retry;
265
- debug('retry initial count %s', retry);
266
- _context.n = 3;
267
- return (0, _gotCjs["default"])(uri, {
268
- headers: headers,
269
- responseType: 'json',
270
- method: method,
271
- agent: this.agent,
272
- retry: retry,
273
- timeout: this.timeout,
274
- hooks: {
275
- afterResponse: [function (afterResponse) {
276
- var code = afterResponse.statusCode;
277
- debug('after response code is %s', code);
278
- if (code >= _core.HTTP_STATUS.OK && code < _core.HTTP_STATUS.MULTIPLE_CHOICES) {
279
- if (_this.failed_requests >= _this.max_fails) {
280
- _this.failed_requests = 0;
281
- _this.logger.warn({
282
- host: _this.url.host
283
- }, 'host @{host} is now online');
284
- }
285
- }
286
- return afterResponse;
287
- }],
288
- beforeRetry: [function (error, count) {
289
- debug('retry %s count: %s', uri, count);
290
- _this.failed_requests = count !== null && count !== void 0 ? count : 0;
291
- _this.logger.info({
292
- request: {
293
- method: method,
294
- url: uri
295
- },
296
- error: error.message,
297
- retryCount: _this.failed_requests
298
- }, "retry @{retryCount} req: '@{request.method} @{request.url}'");
299
- if (_this.failed_requests >= _this.max_fails) {
300
- _this.logger.warn({
301
- host: _this.url.host
302
- }, 'host @{host} is now offline');
303
- }
304
- }]
305
- }
306
- }).on('request', function () {
307
- _this.last_request_time = Date.now();
308
- }).on('response', function (eventResponse) {
309
- var message = "@{!status}, req: '@{request.method} @{request.url}' (streaming)";
310
- _this.logger.http({
311
- request: {
312
- method: method,
313
- url: uri
314
- },
315
- status: _lodash["default"].isNull(eventResponse) === false ? eventResponse.statusCode : 'ERR'
316
- }, message);
317
- }).on('downloadProgress', function (progress) {
318
- if (progress.total) {
319
- debug('responseLength %s', progress.total);
320
- responseLength = progress.total;
321
- }
322
- });
323
- case 3:
324
- response = _context.v;
325
- etag = response.headers.etag;
326
- data = response.body; // not modified status (304) registry does not return any payload
327
- // it is handled as an error with the original 304 status preserved
328
- if (!(((_response = response) === null || _response === void 0 ? void 0 : _response.statusCode) === _core.HTTP_STATUS.NOT_MODIFIED)) {
329
- _context.n = 4;
330
- break;
331
- }
332
- err = _core.errorUtils.getNotFound(_core.API_ERROR.NOT_MODIFIED_NO_DATA);
333
- err.code = _core.HTTP_STATUS.NOT_MODIFIED;
334
- throw err;
335
- case 4:
336
- debug('uri %s success', uri);
337
- message = "@{!status}, req: '@{request.method} @{request.url}'";
338
- this.logger.http({
339
- // if error is null/false change this to undefined so it wont log
340
- request: {
341
- method: method,
342
- url: uri
343
- },
344
- status: response.statusCode,
345
- bytes: {
346
- "in": options !== null && options !== void 0 && options.json ? JSON.stringify(options === null || options === void 0 ? void 0 : options.json).length : 0,
347
- out: responseLength || 0
348
- }
349
- }, message);
350
- return _context.a(2, [data, etag]);
351
- case 5:
352
- _context.p = 5;
353
- _t = _context.v;
354
- debug('error %s on uri %s', _t.code, uri);
355
- if (!(_t.code === 'ERR_NON_2XX_3XX_RESPONSE')) {
356
- _context.n = 8;
357
- break;
358
- }
359
- code = _t.response.statusCode;
360
- debug('error code %s', code);
361
- if (!(code === _core.HTTP_STATUS.NOT_FOUND)) {
362
- _context.n = 6;
363
- break;
364
- }
365
- throw _core.errorUtils.getNotFound(_core.API_ERROR.NOT_PACKAGE_UPLINK);
366
- case 6:
367
- if (code >= _core.HTTP_STATUS.OK && code < _core.HTTP_STATUS.MULTIPLE_CHOICES) {
368
- _context.n = 7;
369
- break;
370
- }
371
- error = _core.errorUtils.getInternalError("".concat(_core.API_ERROR.BAD_STATUS_CODE, ": ").concat(code)); // we need this code to identify outside which status code triggered the error
372
- error.remoteStatus = code;
373
- throw error;
374
- case 7:
375
- _context.n = 9;
376
- break;
377
- case 8:
378
- if (!this._isRequestTimeout(_t)) {
379
- _context.n = 9;
380
- break;
381
- }
382
- debug('error code timeout');
383
- throw _core.errorUtils.getServiceUnavailable(_core.API_ERROR.SERVER_TIME_OUT);
384
- case 9:
385
- throw _t;
386
- case 10:
387
- return _context.a(2);
388
- }
389
- }, _callee, this, [[2, 5]]);
390
- }));
391
- function getRemoteMetadata(_x, _x2) {
392
- return _getRemoteMetadata.apply(this, arguments);
393
- }
394
- return getRemoteMetadata;
395
- }() // FIXME: handle stream and retry
396
- }, {
397
- key: "fetchTarball",
398
- value: function fetchTarball(url, overrideOptions) {
399
- var _this$retry,
400
- _this2 = this;
401
- debug('fetching url for %s', url);
402
- var options = _objectSpread(_objectSpread({}, this.config), overrideOptions);
403
- var headers = this.getHeaders(options === null || options === void 0 ? void 0 : options.headers);
404
- headers = this.addProxyHeaders(headers, options.remoteAddress);
405
- headers = this.applyUplinkHeaders(headers);
406
- // the following headers cannot be overwritten
407
- if (_lodash["default"].isNil(options.etag) === false) {
408
- headers[_core.HEADERS.NONE_MATCH] = options.etag;
409
- headers[_core.HEADERS.ACCEPT] = contentTypeAccept;
410
- }
411
- var method = 'GET';
412
- // const uri = this.config.url + `/${encode(name)}`;
413
- debug('request uri for %s', url);
414
- var readStream = _gotCjs["default"].stream(url, {
415
- headers: headers,
416
- method: method,
417
- agent: this.agent,
418
- // FIXME: this should be taken from construtor as priority
419
- retry: (_this$retry = this.retry) !== null && _this$retry !== void 0 ? _this$retry : options === null || options === void 0 ? void 0 : options.retry,
420
- timeout: this.timeout
421
- }).on('request', function () {
422
- _this2.last_request_time = Date.now();
423
- });
424
- return readStream;
425
- }
426
-
427
- /**
428
- * Perform a stream search.
429
- * @param {*} options request options
430
- * @return {Stream}
431
- */
432
- }, {
433
- key: "search",
434
- value: (function () {
435
- var _search = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(_ref) {
436
- var url, abort, retry, uri, response, res, total, streamSearch, streamResponse, _t2;
437
- return _regenerator().w(function (_context2) {
438
- while (1) switch (_context2.p = _context2.n) {
439
- case 0:
440
- url = _ref.url, abort = _ref.abort, retry = _ref.retry;
441
- _context2.p = 1;
442
- // Incoming URL is relative ie /-/v1/search...
443
- uri = new _nodeUrl.URL(url, this.url).href;
444
- this.logger.http({
445
- uri: uri,
446
- uplink: this.uplinkName
447
- }, 'search request to uplink @{uplink} - @{uri}');
448
- debug('searching on %o', uri);
449
- response = (0, _gotCjs["default"])(uri, {
450
- signal: abort ? abort.signal : {},
451
- agent: this.agent,
452
- timeout: this.timeout,
453
- retry: retry !== null && retry !== void 0 ? retry : this.retry
454
- });
455
- _context2.n = 2;
456
- return response.text();
457
- case 2:
458
- res = _context2.v;
459
- total = JSON.parse(res).total;
460
- debug('number of packages found: %o', total);
461
- streamSearch = new _nodeStream.PassThrough({
462
- objectMode: true
463
- });
464
- streamResponse = _nodeStream.Readable.from(res); // objects is one of the properties on the body, it ignores date and total
465
- streamResponse.pipe(_JSONStream["default"].parse('objects')).pipe(streamSearch, {
466
- end: true
467
- });
468
- return _context2.a(2, streamSearch);
469
- case 3:
470
- _context2.p = 3;
471
- _t2 = _context2.v;
472
- debug('search error %s', _t2);
473
- if (!(_t2.response.statusCode === 409)) {
474
- _context2.n = 4;
475
- break;
476
- }
477
- throw _core.errorUtils.getInternalError("bad status code ".concat(_t2.response.statusCode, " from uplink"));
478
- case 4:
479
- this.logger.error({
480
- errorMessage: _t2 === null || _t2 === void 0 ? void 0 : _t2.message,
481
- name: this.uplinkName
482
- }, 'proxy uplink @{name} search error: @{errorMessage}');
483
- throw _t2;
484
- case 5:
485
- return _context2.a(2);
486
- }
487
- }, _callee2, this, [[1, 3]]);
488
- }));
489
- function search(_x3) {
490
- return _search.apply(this, arguments);
491
- }
492
- return search;
493
- }())
494
- }, {
495
- key: "addProxyHeaders",
496
- value: function addProxyHeaders(headers, remoteAddress) {
497
- // Only submit X-Forwarded-For field if we don't have a proxy selected
498
- // in the config file.
499
- //
500
- // Otherwise misconfigured proxy could return 407
501
- if (!this.proxy) {
502
- headers[_core.HEADERS.FORWARDED_FOR] = (headers['x-forwarded-for'] ? headers['x-forwarded-for'] + ', ' : '') + remoteAddress;
503
- }
504
-
505
- // always attach Via header to avoid loops, even if we're not proxying
506
- headers['via'] = headers['via'] ? headers['via'] + ', ' : '';
507
- headers['via'] += '1.1 ' + this.server_id + ' (Verdaccio)';
508
- return headers;
509
- }
510
-
511
- /**
512
- * If the request failure.
513
- * @return {boolean}
514
- * @private
515
- */
516
- }, {
517
- key: "_ifRequestFailure",
518
- value: function _ifRequestFailure() {
519
- return this.failed_requests >= this.max_fails && Math.abs(Date.now() - this.last_request_time) < this.fail_timeout;
520
- }
521
-
522
- /**
523
- * Check if the request timed out (network or http errors).
524
- * @param {RequestError} err
525
- * @return {boolean}
526
- */
527
- }, {
528
- key: "_isRequestTimeout",
529
- value: function _isRequestTimeout(err) {
530
- var _err$response;
531
- var code = err === null || err === void 0 || (_err$response = err.response) === null || _err$response === void 0 ? void 0 : _err$response.statusCode;
532
- return err.code === 'ETIMEDOUT' || err.code === 'ESOCKETTIMEDOUT' || err.code === 'ECONNRESET' || code === _core.HTTP_STATUS.REQUEST_TIMEOUT || code === _core.HTTP_STATUS.BAD_GATEWAY || code === _core.HTTP_STATUS.SERVICE_UNAVAILABLE || code === _core.HTTP_STATUS.GATEWAY_TIMEOUT;
533
- }
534
-
535
- /**
536
- * Set up a proxy.
537
- * @param {*} hostname
538
- * @param {*} config
539
- * @param {*} mainconfig
540
- * @param {*} isHTTPS
541
- */
542
- }, {
543
- key: "_setupProxy",
544
- value: function _setupProxy(hostname, config, mainconfig, isHTTPS) {
545
- var noProxyList;
546
- var proxy_key = isHTTPS ? 'https_proxy' : 'http_proxy';
547
- debug('looking for %o', proxy_key);
548
-
549
- // get http_proxy and no_proxy configs
550
- if (proxy_key in config) {
551
- this.proxy = config[proxy_key];
552
- debug('found %o in uplink config', this.proxy);
553
- } else if (proxy_key in mainconfig) {
554
- this.proxy = mainconfig[proxy_key];
555
- debug('found %o in main config', this.proxy);
556
- }
557
- if ('no_proxy' in config) {
558
- noProxyList = config.no_proxy;
559
- } else if ('no_proxy' in mainconfig) {
560
- noProxyList = mainconfig.no_proxy;
561
- }
28
+ * Implements Storage interface
29
+ * (same for storage.js, local-storage.js, up-storage.js)
30
+ */
31
+ var ProxyStorage = class {
32
+ uplinkName;
33
+ config;
34
+ failed_requests;
35
+ userAgent;
36
+ ca;
37
+ logger;
38
+ server_id;
39
+ url;
40
+ maxage;
41
+ timeout;
42
+ max_fails;
43
+ fail_timeout;
44
+ agent_options;
45
+ proxy;
46
+ agent;
47
+ last_request_time;
48
+ strict_ssl;
49
+ retry;
50
+ constructor(uplinkName, config, mainConfig, logger, agent) {
51
+ this.uplinkName = uplinkName;
52
+ this.config = config;
53
+ this.failed_requests = 0;
54
+ this.userAgent = mainConfig.user_agent ?? "hidden";
55
+ this.ca = config.ca;
56
+ this.logger = logger;
57
+ this.server_id = mainConfig.server_id;
58
+ this.agent_options = setConfig(this.config, "agent_options", {
59
+ keepAlive: true,
60
+ maxSockets: 40,
61
+ maxFreeSockets: 10
62
+ });
63
+ this.url = new node_url.URL(this.config.url);
64
+ const isHTTPS = this.url.protocol === "https:";
65
+ this._setupProxy(this.url.hostname, config, mainConfig, isHTTPS);
66
+ this.agent = agent ?? this.getAgent();
67
+ this.config.url = this.config.url.replace(/\/$/, "");
68
+ if (this.config.timeout && Number(this.config.timeout) >= 1e3) this.logger.warn([
69
+ "Too big timeout value: " + this.config.timeout,
70
+ "We changed time format to nginx-like one",
71
+ "(see http://nginx.org/en/docs/syntax.html)",
72
+ "so please update your config accordingly"
73
+ ].join("\n"));
74
+ this.maxage = require_proxy_utils.parseInterval(setConfig(this.config, "maxage", "2m"));
75
+ this.timeout = { request: require_proxy_utils.parseInterval(setConfig(this.config, "timeout", "30s")) };
76
+ debug$1("set timeout %s", this.timeout);
77
+ this.max_fails = Number(setConfig(this.config, "max_fails", this.config.max_fails ?? 2));
78
+ this.fail_timeout = require_proxy_utils.parseInterval(setConfig(this.config, "fail_timeout", "5m"));
79
+ this.strict_ssl = Boolean(setConfig(this.config, "strict_ssl", true));
80
+ this.retry = { limit: this.max_fails ?? 2 };
81
+ }
82
+ getAgent() {
83
+ if (!this.agent) return new require_agent.default(this.config.url, this.proxy, this.agent_options).get();
84
+ else return this.agent;
85
+ }
86
+ getHeaders(headers = {}) {
87
+ const accept = _verdaccio_core.HEADERS.ACCEPT;
88
+ const acceptEncoding = _verdaccio_core.HEADERS.ACCEPT_ENCODING;
89
+ const userAgent = _verdaccio_core.HEADERS.USER_AGENT;
90
+ headers[accept] = headers[accept] || contentTypeAccept;
91
+ headers[acceptEncoding] = headers[acceptEncoding] || "gzip";
92
+ headers[userAgent] = headers[userAgent] || `npm (${this.userAgent})`;
93
+ return this.setAuthNext(headers);
94
+ }
95
+ /**
96
+ * Validate configuration auth and assign Header authorization
97
+ * @param {Object} headers
98
+ * @return {Object}
99
+ * @private
100
+ */
101
+ setAuthNext(headers) {
102
+ const { auth } = this.config;
103
+ if (typeof auth === "undefined" || typeof headers[_verdaccio_core.HEADERS.AUTHORIZATION] === "string") return headers;
104
+ if (lodash.default.isObject(auth) === false && lodash.default.isObject(auth.token) === false) this._throwErrorAuth("Auth invalid");
105
+ let token;
106
+ const tokenConf = auth;
107
+ if (lodash.default.isNil(tokenConf.token) === false && lodash.default.isString(tokenConf.token)) {
108
+ debug$1("use token from config");
109
+ token = tokenConf.token;
110
+ } else if (lodash.default.isNil(tokenConf.token_env) === false) if (typeof tokenConf.token_env === "string") {
111
+ debug$1("use token from env %o", tokenConf.token_env);
112
+ token = process.env[tokenConf.token_env];
113
+ } else if (typeof tokenConf.token_env === "boolean" && tokenConf.token_env) {
114
+ debug$1("use token from env NPM_TOKEN");
115
+ token = process.env.NPM_TOKEN;
116
+ } else {
117
+ this.logger.error(_verdaccio_core.constants.ERROR_CODE.token_required);
118
+ this._throwErrorAuth(_verdaccio_core.constants.ERROR_CODE.token_required);
119
+ }
120
+ else {
121
+ debug$1("use token from env NPM_TOKEN");
122
+ token = process.env.NPM_TOKEN;
123
+ }
124
+ if (typeof token === "undefined") this._throwErrorAuth(_verdaccio_core.constants.ERROR_CODE.token_required);
125
+ const type = tokenConf.type || _verdaccio_core.TOKEN_BASIC;
126
+ debug$1("token type %o", type);
127
+ this._setHeaderAuthorization(headers, type, token);
128
+ return headers;
129
+ }
130
+ /**
131
+ * @param {string} message
132
+ * @throws {Error}
133
+ * @private
134
+ */
135
+ _throwErrorAuth(message) {
136
+ this.logger.error(message);
137
+ throw new Error(message);
138
+ }
139
+ /**
140
+ * Assign Header authorization with type authentication
141
+ * @param {Object} headers
142
+ * @param {string} type
143
+ * @param {string} token
144
+ * @private
145
+ */
146
+ _setHeaderAuthorization(headers, type, token) {
147
+ const _type = type.toLowerCase();
148
+ if (_type !== _verdaccio_core.TOKEN_BEARER.toLowerCase() && _type !== _verdaccio_core.TOKEN_BASIC.toLowerCase()) this._throwErrorAuth(`Auth type '${_type}' not allowed`);
149
+ headers[_verdaccio_core.HEADERS.AUTHORIZATION] = _verdaccio_core.authUtils.buildToken(type, token);
150
+ }
151
+ /**
152
+ * It will add or override specified headers from config file.
153
+ *
154
+ * Eg:
155
+ *
156
+ * uplinks:
157
+ npmjs:
158
+ url: https://registry.npmjs.org/
159
+ headers:
160
+ Accept: "application/vnd.npm.install-v2+json; q=1.0"
161
+ verdaccio-staging:
162
+ url: https://mycompany.com/npm
163
+ headers:
164
+ Accept: "application/json"
165
+ authorization: "Basic YourBase64EncodedCredentials=="
166
+
167
+ * @param {Object} headers
168
+ * @private
169
+ */
170
+ applyUplinkHeaders(headers) {
171
+ if (!this.config.headers) return headers;
172
+ for (const key in this.config.headers) headers[key] = this.config.headers[key];
173
+ return headers;
174
+ }
175
+ async getRemoteMetadata(name, options) {
176
+ if (this._ifRequestFailure()) throw _verdaccio_core.errorUtils.getInternalError(_verdaccio_core.API_ERROR.UPLINK_OFFLINE);
177
+ debug$1("getting metadata for package %s", name);
178
+ let headers = this.getHeaders(options?.headers);
179
+ headers = this.addProxyHeaders(headers, options.remoteAddress);
180
+ headers = this.applyUplinkHeaders(headers);
181
+ if (lodash.default.isNil(options.etag) === false) {
182
+ headers[_verdaccio_core.HEADERS.NONE_MATCH] = options.etag;
183
+ headers[_verdaccio_core.HEADERS.ACCEPT] = contentTypeAccept;
184
+ }
185
+ const method = options.method || "GET";
186
+ const uri = this.config.url + `/${encode(name)}`;
187
+ debug$1("set retry limit is %s", this.retry.limit);
188
+ let response;
189
+ let responseLength = 0;
190
+ try {
191
+ const retry = options?.retry ?? this.retry;
192
+ debug$1("retry initial count %s", retry);
193
+ response = await (0, got_cjs.default)(uri, {
194
+ headers,
195
+ responseType: "json",
196
+ method,
197
+ agent: this.agent,
198
+ retry,
199
+ timeout: this.timeout,
200
+ hooks: {
201
+ afterResponse: [(afterResponse) => {
202
+ const code = afterResponse.statusCode;
203
+ debug$1("after response code is %s", code);
204
+ if (code >= _verdaccio_core.HTTP_STATUS.OK && code < _verdaccio_core.HTTP_STATUS.MULTIPLE_CHOICES) {
205
+ if (this.failed_requests >= this.max_fails) {
206
+ this.failed_requests = 0;
207
+ this.logger.warn({ host: this.url.host }, "host @{host} is now online");
208
+ }
209
+ }
210
+ return afterResponse;
211
+ }],
212
+ beforeRetry: [(error, count) => {
213
+ debug$1("retry %s count: %s", uri, count);
214
+ this.failed_requests = count ?? 0;
215
+ this.logger.info({
216
+ request: {
217
+ method,
218
+ url: uri
219
+ },
220
+ error: error.message,
221
+ retryCount: this.failed_requests
222
+ }, "retry @{retryCount} req: '@{request.method} @{request.url}'");
223
+ if (this.failed_requests >= this.max_fails) this.logger.warn({ host: this.url.host }, "host @{host} is now offline");
224
+ }]
225
+ }
226
+ }).on("request", () => {
227
+ this.last_request_time = Date.now();
228
+ }).on("response", (eventResponse) => {
229
+ this.logger.http({
230
+ request: {
231
+ method,
232
+ url: uri
233
+ },
234
+ status: lodash.default.isNull(eventResponse) === false ? eventResponse.statusCode : "ERR"
235
+ }, "@{!status}, req: '@{request.method} @{request.url}' (streaming)");
236
+ }).on("downloadProgress", (progress) => {
237
+ if (progress.total) {
238
+ debug$1("responseLength %s", progress.total);
239
+ responseLength = progress.total;
240
+ }
241
+ });
242
+ const etag = response.headers.etag;
243
+ const data = response.body;
244
+ if (response?.statusCode === _verdaccio_core.HTTP_STATUS.NOT_MODIFIED) {
245
+ const err = _verdaccio_core.errorUtils.getNotFound(_verdaccio_core.API_ERROR.NOT_MODIFIED_NO_DATA);
246
+ err.code = _verdaccio_core.HTTP_STATUS.NOT_MODIFIED;
247
+ throw err;
248
+ }
249
+ debug$1("uri %s success", uri);
250
+ this.logger.http({
251
+ request: {
252
+ method,
253
+ url: uri
254
+ },
255
+ status: response.statusCode,
256
+ bytes: {
257
+ in: options?.json ? JSON.stringify(options?.json).length : 0,
258
+ out: responseLength || 0
259
+ }
260
+ }, "@{!status}, req: '@{request.method} @{request.url}'");
261
+ return [data, etag];
262
+ } catch (err) {
263
+ debug$1("error %s on uri %s", err.code, uri);
264
+ if (err.code === "ERR_NON_2XX_3XX_RESPONSE") {
265
+ const code = err.response.statusCode;
266
+ debug$1("error code %s", code);
267
+ if (code === _verdaccio_core.HTTP_STATUS.NOT_FOUND) throw _verdaccio_core.errorUtils.getNotFound(_verdaccio_core.API_ERROR.NOT_PACKAGE_UPLINK);
268
+ if (!(code >= _verdaccio_core.HTTP_STATUS.OK && code < _verdaccio_core.HTTP_STATUS.MULTIPLE_CHOICES)) {
269
+ const error = _verdaccio_core.errorUtils.getInternalError(`${_verdaccio_core.API_ERROR.BAD_STATUS_CODE}: ${code}`);
270
+ error.remoteStatus = code;
271
+ throw error;
272
+ }
273
+ } else if (this._isRequestTimeout(err)) {
274
+ debug$1("error code timeout");
275
+ throw _verdaccio_core.errorUtils.getServiceUnavailable(_verdaccio_core.API_ERROR.SERVER_TIME_OUT);
276
+ }
277
+ throw err;
278
+ }
279
+ }
280
+ fetchTarball(url, overrideOptions) {
281
+ debug$1("fetching url for %s", url);
282
+ const options = {
283
+ ...this.config,
284
+ ...overrideOptions
285
+ };
286
+ let headers = this.getHeaders(options?.headers);
287
+ headers = this.addProxyHeaders(headers, options.remoteAddress);
288
+ headers = this.applyUplinkHeaders(headers);
289
+ if (lodash.default.isNil(options.etag) === false) {
290
+ headers[_verdaccio_core.HEADERS.NONE_MATCH] = options.etag;
291
+ headers[_verdaccio_core.HEADERS.ACCEPT] = contentTypeAccept;
292
+ }
293
+ const method = "GET";
294
+ debug$1("request uri for %s", url);
295
+ return got_cjs.default.stream(url, {
296
+ headers,
297
+ method,
298
+ agent: this.agent,
299
+ retry: this.retry ?? options?.retry,
300
+ timeout: this.timeout
301
+ }).on("request", () => {
302
+ this.last_request_time = Date.now();
303
+ });
304
+ }
305
+ /**
306
+ * Perform a stream search.
307
+ * @param {*} options request options
308
+ * @return {Stream}
309
+ */
310
+ async search({ url, abort, retry }) {
311
+ try {
312
+ const uri = new node_url.URL(url, this.url).href;
313
+ this.logger.http({
314
+ uri,
315
+ uplink: this.uplinkName
316
+ }, "search request to uplink @{uplink} - @{uri}");
317
+ debug$1("searching on %o", uri);
318
+ const res = await (0, got_cjs.default)(uri, {
319
+ signal: abort ? abort.signal : {},
320
+ agent: this.agent,
321
+ timeout: this.timeout,
322
+ retry: retry ?? this.retry
323
+ }).text();
324
+ const total = JSON.parse(res).total;
325
+ debug$1("number of packages found: %o", total);
326
+ const streamSearch = new node_stream.PassThrough({ objectMode: true });
327
+ node_stream.Readable.from(res).pipe(JSONStream.default.parse("objects")).pipe(streamSearch, { end: true });
328
+ return streamSearch;
329
+ } catch (err) {
330
+ debug$1("search error %s", err);
331
+ if (err.response.statusCode === 409) throw _verdaccio_core.errorUtils.getInternalError(`bad status code ${err.response.statusCode} from uplink`);
332
+ this.logger.error({
333
+ errorMessage: err?.message,
334
+ name: this.uplinkName
335
+ }, "proxy uplink @{name} search error: @{errorMessage}");
336
+ throw err;
337
+ }
338
+ }
339
+ addProxyHeaders(headers, remoteAddress) {
340
+ if (!this.proxy) headers[_verdaccio_core.HEADERS.FORWARDED_FOR] = (headers["x-forwarded-for"] ? headers["x-forwarded-for"] + ", " : "") + remoteAddress;
341
+ headers["via"] = headers["via"] ? headers["via"] + ", " : "";
342
+ headers["via"] += "1.1 " + this.server_id + " (Verdaccio)";
343
+ return headers;
344
+ }
345
+ /**
346
+ * If the request failure.
347
+ * @return {boolean}
348
+ * @private
349
+ */
350
+ _ifRequestFailure() {
351
+ return this.failed_requests >= this.max_fails && Math.abs(Date.now() - this.last_request_time) < this.fail_timeout;
352
+ }
353
+ /**
354
+ * Check if the request timed out (network or http errors).
355
+ * @param {RequestError} err
356
+ * @return {boolean}
357
+ */
358
+ _isRequestTimeout(err) {
359
+ const code = err?.response?.statusCode;
360
+ return err.code === "ETIMEDOUT" || err.code === "ESOCKETTIMEDOUT" || err.code === "ECONNRESET" || code === _verdaccio_core.HTTP_STATUS.REQUEST_TIMEOUT || code === _verdaccio_core.HTTP_STATUS.BAD_GATEWAY || code === _verdaccio_core.HTTP_STATUS.SERVICE_UNAVAILABLE || code === _verdaccio_core.HTTP_STATUS.GATEWAY_TIMEOUT;
361
+ }
362
+ /**
363
+ * Set up a proxy.
364
+ * @param {*} hostname
365
+ * @param {*} config
366
+ * @param {*} mainconfig
367
+ * @param {*} isHTTPS
368
+ */
369
+ _setupProxy(hostname, config, mainconfig, isHTTPS) {
370
+ let noProxyList;
371
+ const proxy_key = isHTTPS ? "https_proxy" : "http_proxy";
372
+ debug$1("looking for %o", proxy_key);
373
+ if (proxy_key in config) {
374
+ this.proxy = config[proxy_key];
375
+ debug$1("found %o in uplink config", this.proxy);
376
+ } else if (proxy_key in mainconfig) {
377
+ this.proxy = mainconfig[proxy_key];
378
+ debug$1("found %o in main config", this.proxy);
379
+ }
380
+ if ("no_proxy" in config) noProxyList = config.no_proxy;
381
+ else if ("no_proxy" in mainconfig) noProxyList = mainconfig.no_proxy;
382
+ if (hostname[0] !== ".") hostname = "." + hostname;
383
+ if (lodash.default.isString(noProxyList) && noProxyList.length) noProxyList = noProxyList.split(",");
384
+ if (lodash.default.isArray(noProxyList)) for (let i = 0; i < noProxyList.length; i++) {
385
+ let noProxyItem = noProxyList[i];
386
+ if (noProxyItem[0] !== ".") noProxyItem = "." + noProxyItem;
387
+ if (hostname.endsWith(noProxyItem)) {
388
+ if (this.proxy) {
389
+ debug$1("not using proxy, excluded by @{rule}", noProxyItem);
390
+ this.logger.debug({
391
+ url: this.url.href,
392
+ rule: noProxyItem
393
+ }, "not using proxy for @{url}, excluded by @{rule} rule");
394
+ this.proxy = void 0;
395
+ }
396
+ break;
397
+ }
398
+ }
399
+ if (typeof this.proxy === "string") {
400
+ debug$1("using proxy @{proxy} for @{url}", this.proxy, this.url.href);
401
+ this.logger.debug({
402
+ url: this.url.href,
403
+ proxy: this.proxy
404
+ }, "using proxy @{proxy} for @{url}");
405
+ }
406
+ }
407
+ };
408
+ //#endregion
409
+ exports.ProxyStorage = ProxyStorage;
562
410
 
563
- // use wget-like algorithm to determine if proxy shouldn't be used
564
- if (hostname[0] !== '.') {
565
- hostname = '.' + hostname;
566
- }
567
- if (_lodash["default"].isString(noProxyList) && noProxyList.length) {
568
- noProxyList = noProxyList.split(',');
569
- }
570
- if (_lodash["default"].isArray(noProxyList)) {
571
- for (var i = 0; i < noProxyList.length; i++) {
572
- var noProxyItem = noProxyList[i];
573
- if (noProxyItem[0] !== '.') {
574
- noProxyItem = '.' + noProxyItem;
575
- }
576
- if (hostname.endsWith(noProxyItem)) {
577
- if (this.proxy) {
578
- debug('not using proxy, excluded by @{rule}', noProxyItem);
579
- this.logger.debug({
580
- url: this.url.href,
581
- rule: noProxyItem
582
- }, 'not using proxy for @{url}, excluded by @{rule} rule');
583
- this.proxy = undefined;
584
- }
585
- break;
586
- }
587
- }
588
- }
589
- if (typeof this.proxy === 'string') {
590
- debug('using proxy @{proxy} for @{url}', this.proxy, this.url.href);
591
- this.logger.debug({
592
- url: this.url.href,
593
- proxy: this.proxy
594
- }, 'using proxy @{proxy} for @{url}');
595
- }
596
- }
597
- }]);
598
- }();
599
411
  //# sourceMappingURL=proxy.js.map