1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
18 | if (k2 === undefined) k2 = k;
|
19 | var desc = Object.getOwnPropertyDescriptor(m, k);
|
20 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
21 | desc = { enumerable: true, get: function() { return m[k]; } };
|
22 | }
|
23 | Object.defineProperty(o, k2, desc);
|
24 | }) : (function(o, m, k, k2) {
|
25 | if (k2 === undefined) k2 = k;
|
26 | o[k2] = m[k];
|
27 | }));
|
28 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
29 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
30 | }) : function(o, v) {
|
31 | o["default"] = v;
|
32 | });
|
33 | var __importStar = (this && this.__importStar) || function (mod) {
|
34 | if (mod && mod.__esModule) return mod;
|
35 | var result = {};
|
36 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
37 | __setModuleDefault(result, mod);
|
38 | return result;
|
39 | };
|
40 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
41 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
42 | };
|
43 | Object.defineProperty(exports, "__esModule", { value: true });
|
44 | exports.util = exports.Util = exports.PartialFailureError = exports.ApiError = exports.GCCL_GCS_CMD_KEY = void 0;
|
45 |
|
46 |
|
47 |
|
48 | const projectify_1 = require("@google-cloud/projectify");
|
49 | const htmlEntities = __importStar(require("html-entities"));
|
50 | const google_auth_library_1 = require("google-auth-library");
|
51 | const retry_request_1 = __importDefault(require("retry-request"));
|
52 | const stream_1 = require("stream");
|
53 | const teeny_request_1 = require("teeny-request");
|
54 | const uuid = __importStar(require("uuid"));
|
55 | const service_js_1 = require("./service.js");
|
56 | const util_js_1 = require("../util.js");
|
57 | const duplexify_1 = __importDefault(require("duplexify"));
|
58 |
|
59 |
|
60 | const package_json_helper_cjs_1 = require("../package-json-helper.cjs");
|
61 | const packageJson = (0, package_json_helper_cjs_1.getPackageJSON)();
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 | exports.GCCL_GCS_CMD_KEY = Symbol.for('GCCL_GCS_CMD');
|
69 | const requestDefaults = {
|
70 | timeout: 60000,
|
71 | gzip: true,
|
72 | forever: true,
|
73 | pool: {
|
74 | maxSockets: Infinity,
|
75 | },
|
76 | };
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 | const AUTO_RETRY_DEFAULT = true;
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 | const MAX_RETRY_DEFAULT = 3;
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 | class ApiError extends Error {
|
97 | constructor(errorBodyOrMessage) {
|
98 | super();
|
99 | if (typeof errorBodyOrMessage !== 'object') {
|
100 | this.message = errorBodyOrMessage || '';
|
101 | return;
|
102 | }
|
103 | const errorBody = errorBodyOrMessage;
|
104 | this.code = errorBody.code;
|
105 | this.errors = errorBody.errors;
|
106 | this.response = errorBody.response;
|
107 | try {
|
108 | this.errors = JSON.parse(this.response.body).error.errors;
|
109 | }
|
110 | catch (e) {
|
111 | this.errors = errorBody.errors;
|
112 | }
|
113 | this.message = ApiError.createMultiErrorMessage(errorBody, this.errors);
|
114 | Error.captureStackTrace(this);
|
115 | }
|
116 | |
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 | static createMultiErrorMessage(err, errors) {
|
127 | const messages = new Set();
|
128 | if (err.message) {
|
129 | messages.add(err.message);
|
130 | }
|
131 | if (errors && errors.length) {
|
132 | errors.forEach(({ message }) => messages.add(message));
|
133 | }
|
134 | else if (err.response && err.response.body) {
|
135 | messages.add(htmlEntities.decode(err.response.body.toString()));
|
136 | }
|
137 | else if (!err.message) {
|
138 | messages.add('A failure occurred during this request.');
|
139 | }
|
140 | let messageArr = Array.from(messages);
|
141 | if (messageArr.length > 1) {
|
142 | messageArr = messageArr.map((message, i) => ` ${i + 1}. ${message}`);
|
143 | messageArr.unshift('Multiple errors occurred during the request. Please see the `errors` array for complete details.\n');
|
144 | messageArr.push('\n');
|
145 | }
|
146 | return messageArr.join('\n');
|
147 | }
|
148 | }
|
149 | exports.ApiError = ApiError;
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 | class PartialFailureError extends Error {
|
156 | constructor(b) {
|
157 | super();
|
158 | const errorObject = b;
|
159 | this.errors = errorObject.errors;
|
160 | this.name = 'PartialFailureError';
|
161 | this.response = errorObject.response;
|
162 | this.message = ApiError.createMultiErrorMessage(errorObject, this.errors);
|
163 | }
|
164 | }
|
165 | exports.PartialFailureError = PartialFailureError;
|
166 | class Util {
|
167 | constructor() {
|
168 | this.ApiError = ApiError;
|
169 | this.PartialFailureError = PartialFailureError;
|
170 | }
|
171 | |
172 |
|
173 |
|
174 |
|
175 |
|
176 |
|
177 |
|
178 |
|
179 | noop() { }
|
180 | |
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 | handleResp(err, resp, body, callback) {
|
189 | callback = callback || util.noop;
|
190 | const parsedResp = {
|
191 | err: err || null,
|
192 | ...(resp && util.parseHttpRespMessage(resp)),
|
193 | ...(body && util.parseHttpRespBody(body)),
|
194 | };
|
195 |
|
196 |
|
197 |
|
198 | if (!parsedResp.err && resp && typeof parsedResp.body === 'object') {
|
199 | parsedResp.resp.body = parsedResp.body;
|
200 | }
|
201 | if (parsedResp.err && resp) {
|
202 | parsedResp.err.response = resp;
|
203 | }
|
204 | callback(parsedResp.err, parsedResp.body, parsedResp.resp);
|
205 | }
|
206 | |
207 |
|
208 |
|
209 |
|
210 |
|
211 |
|
212 |
|
213 |
|
214 | parseHttpRespMessage(httpRespMessage) {
|
215 | const parsedHttpRespMessage = {
|
216 | resp: httpRespMessage,
|
217 | };
|
218 | if (httpRespMessage.statusCode < 200 || httpRespMessage.statusCode > 299) {
|
219 |
|
220 | parsedHttpRespMessage.err = new ApiError({
|
221 | errors: new Array(),
|
222 | code: httpRespMessage.statusCode,
|
223 | message: httpRespMessage.statusMessage,
|
224 | response: httpRespMessage,
|
225 | });
|
226 | }
|
227 | return parsedHttpRespMessage;
|
228 | }
|
229 | |
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 | parseHttpRespBody(body) {
|
240 | const parsedHttpRespBody = {
|
241 | body,
|
242 | };
|
243 | if (typeof body === 'string') {
|
244 | try {
|
245 | parsedHttpRespBody.body = JSON.parse(body);
|
246 | }
|
247 | catch (err) {
|
248 | parsedHttpRespBody.body = body;
|
249 | }
|
250 | }
|
251 | if (parsedHttpRespBody.body && parsedHttpRespBody.body.error) {
|
252 |
|
253 | parsedHttpRespBody.err = new ApiError(parsedHttpRespBody.body.error);
|
254 | }
|
255 | return parsedHttpRespBody;
|
256 | }
|
257 | |
258 |
|
259 |
|
260 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 |
|
266 |
|
267 |
|
268 |
|
269 |
|
270 |
|
271 | makeWritableStream(dup, options, onComplete) {
|
272 | var _a;
|
273 | onComplete = onComplete || util.noop;
|
274 | const writeStream = new ProgressStream();
|
275 | writeStream.on('progress', evt => dup.emit('progress', evt));
|
276 | dup.setWritable(writeStream);
|
277 | const defaultReqOpts = {
|
278 | method: 'POST',
|
279 | qs: {
|
280 | uploadType: 'multipart',
|
281 | },
|
282 | timeout: 0,
|
283 | maxRetries: 0,
|
284 | };
|
285 | const metadata = options.metadata || {};
|
286 | const reqOpts = {
|
287 | ...defaultReqOpts,
|
288 | ...options.request,
|
289 | qs: {
|
290 | ...defaultReqOpts.qs,
|
291 | ...(_a = options.request) === null || _a === void 0 ? void 0 : _a.qs,
|
292 | },
|
293 | multipart: [
|
294 | {
|
295 | 'Content-Type': 'application/json',
|
296 | body: JSON.stringify(metadata),
|
297 | },
|
298 | {
|
299 | 'Content-Type': metadata.contentType || 'application/octet-stream',
|
300 | body: writeStream,
|
301 | },
|
302 | ],
|
303 | };
|
304 | options.makeAuthenticatedRequest(reqOpts, {
|
305 | onAuthenticated(err, authenticatedReqOpts) {
|
306 | if (err) {
|
307 | dup.destroy(err);
|
308 | return;
|
309 | }
|
310 | requestDefaults.headers = util._getDefaultHeaders(reqOpts[exports.GCCL_GCS_CMD_KEY]);
|
311 | const request = teeny_request_1.teenyRequest.defaults(requestDefaults);
|
312 | request(authenticatedReqOpts, (err, resp, body) => {
|
313 | util.handleResp(err, resp, body, (err, data) => {
|
314 | if (err) {
|
315 | dup.destroy(err);
|
316 | return;
|
317 | }
|
318 | dup.emit('response', resp);
|
319 | onComplete(data);
|
320 | });
|
321 | });
|
322 | },
|
323 | });
|
324 | }
|
325 | |
326 |
|
327 |
|
328 |
|
329 |
|
330 |
|
331 |
|
332 |
|
333 | shouldRetryRequest(err) {
|
334 | if (err) {
|
335 | if ([408, 429, 500, 502, 503, 504].indexOf(err.code) !== -1) {
|
336 | return true;
|
337 | }
|
338 | if (err.errors) {
|
339 | for (const e of err.errors) {
|
340 | const reason = e.reason;
|
341 | if (reason === 'rateLimitExceeded') {
|
342 | return true;
|
343 | }
|
344 | if (reason === 'userRateLimitExceeded') {
|
345 | return true;
|
346 | }
|
347 | if (reason && reason.includes('EAI_AGAIN')) {
|
348 | return true;
|
349 | }
|
350 | }
|
351 | }
|
352 | }
|
353 | return false;
|
354 | }
|
355 | |
356 |
|
357 |
|
358 |
|
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 | makeAuthenticatedRequestFactory(config) {
|
372 | const googleAutoAuthConfig = { ...config };
|
373 | if (googleAutoAuthConfig.projectId === service_js_1.DEFAULT_PROJECT_ID_TOKEN) {
|
374 | delete googleAutoAuthConfig.projectId;
|
375 | }
|
376 | let authClient;
|
377 | if (googleAutoAuthConfig.authClient instanceof google_auth_library_1.GoogleAuth) {
|
378 |
|
379 | authClient = googleAutoAuthConfig.authClient;
|
380 | }
|
381 | else {
|
382 |
|
383 | authClient = new google_auth_library_1.GoogleAuth({
|
384 | ...googleAutoAuthConfig,
|
385 | authClient: googleAutoAuthConfig.authClient,
|
386 | clientOptions: googleAutoAuthConfig.clientOptions,
|
387 | });
|
388 | }
|
389 | function makeAuthenticatedRequest(reqOpts, optionsOrCallback) {
|
390 | let stream;
|
391 | let projectId;
|
392 | const reqConfig = { ...config };
|
393 | let activeRequest_;
|
394 | if (!optionsOrCallback) {
|
395 | stream = (0, duplexify_1.default)();
|
396 | reqConfig.stream = stream;
|
397 | }
|
398 | const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : undefined;
|
399 | const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : undefined;
|
400 | async function setProjectId() {
|
401 | projectId = await authClient.getProjectId();
|
402 | }
|
403 | const onAuthenticated = async (err, authenticatedReqOpts) => {
|
404 | const authLibraryError = err;
|
405 | const autoAuthFailed = err &&
|
406 | typeof err.message === 'string' &&
|
407 | err.message.indexOf('Could not load the default credentials') > -1;
|
408 | if (autoAuthFailed) {
|
409 |
|
410 |
|
411 | authenticatedReqOpts = reqOpts;
|
412 | }
|
413 | if (!err || autoAuthFailed) {
|
414 | try {
|
415 |
|
416 | authenticatedReqOpts = util.decorateRequest(authenticatedReqOpts, projectId);
|
417 | err = null;
|
418 | }
|
419 | catch (e) {
|
420 | if (e instanceof projectify_1.MissingProjectIdError) {
|
421 |
|
422 | try {
|
423 |
|
424 | await setProjectId();
|
425 | authenticatedReqOpts = util.decorateRequest(authenticatedReqOpts, projectId);
|
426 | err = null;
|
427 | }
|
428 | catch (e) {
|
429 |
|
430 |
|
431 | err = err || e;
|
432 | }
|
433 | }
|
434 | else {
|
435 |
|
436 | err = err || e;
|
437 | }
|
438 | }
|
439 | }
|
440 | if (err) {
|
441 | if (stream) {
|
442 | stream.destroy(err);
|
443 | }
|
444 | else {
|
445 | const fn = options && options.onAuthenticated
|
446 | ? options.onAuthenticated
|
447 | : callback;
|
448 | fn(err);
|
449 | }
|
450 | return;
|
451 | }
|
452 | if (options && options.onAuthenticated) {
|
453 | options.onAuthenticated(null, authenticatedReqOpts);
|
454 | }
|
455 | else {
|
456 | activeRequest_ = util.makeRequest(authenticatedReqOpts, reqConfig, (apiResponseError, ...params) => {
|
457 | if (apiResponseError &&
|
458 | apiResponseError.code === 401 &&
|
459 | authLibraryError) {
|
460 |
|
461 |
|
462 | apiResponseError = authLibraryError;
|
463 | }
|
464 | callback(apiResponseError, ...params);
|
465 | });
|
466 | }
|
467 | };
|
468 | const prepareRequest = async () => {
|
469 | try {
|
470 | const getProjectId = async () => {
|
471 | if (config.projectId &&
|
472 | config.projectId !== service_js_1.DEFAULT_PROJECT_ID_TOKEN) {
|
473 |
|
474 |
|
475 | return config.projectId;
|
476 | }
|
477 | if (config.projectIdRequired === false) {
|
478 |
|
479 | return service_js_1.DEFAULT_PROJECT_ID_TOKEN;
|
480 | }
|
481 | return setProjectId();
|
482 | };
|
483 | const authorizeRequest = async () => {
|
484 | if (reqConfig.customEndpoint &&
|
485 | !reqConfig.useAuthWithCustomEndpoint) {
|
486 |
|
487 |
|
488 | return reqOpts;
|
489 | }
|
490 | else {
|
491 | return authClient.authorizeRequest(reqOpts);
|
492 | }
|
493 | };
|
494 | const [_projectId, authorizedReqOpts] = await Promise.all([
|
495 | getProjectId(),
|
496 | authorizeRequest(),
|
497 | ]);
|
498 | if (_projectId) {
|
499 | projectId = _projectId;
|
500 | }
|
501 | return onAuthenticated(null, authorizedReqOpts);
|
502 | }
|
503 | catch (e) {
|
504 | return onAuthenticated(e);
|
505 | }
|
506 | };
|
507 | prepareRequest();
|
508 | if (stream) {
|
509 | return stream;
|
510 | }
|
511 | return {
|
512 | abort() {
|
513 | setImmediate(() => {
|
514 | if (activeRequest_) {
|
515 | activeRequest_.abort();
|
516 | activeRequest_ = null;
|
517 | }
|
518 | });
|
519 | },
|
520 | };
|
521 | }
|
522 | const mar = makeAuthenticatedRequest;
|
523 | mar.getCredentials = authClient.getCredentials.bind(authClient);
|
524 | mar.authClient = authClient;
|
525 | return mar;
|
526 | }
|
527 | |
528 |
|
529 |
|
530 |
|
531 |
|
532 |
|
533 |
|
534 |
|
535 |
|
536 |
|
537 |
|
538 |
|
539 |
|
540 |
|
541 |
|
542 | makeRequest(reqOpts, config, callback) {
|
543 | var _a, _b, _c, _d, _e;
|
544 | let autoRetryValue = AUTO_RETRY_DEFAULT;
|
545 | if (config.autoRetry !== undefined) {
|
546 | autoRetryValue = config.autoRetry;
|
547 | }
|
548 | else if (((_a = config.retryOptions) === null || _a === void 0 ? void 0 : _a.autoRetry) !== undefined) {
|
549 | autoRetryValue = config.retryOptions.autoRetry;
|
550 | }
|
551 | let maxRetryValue = MAX_RETRY_DEFAULT;
|
552 | if (config.maxRetries !== undefined) {
|
553 | maxRetryValue = config.maxRetries;
|
554 | }
|
555 | else if (((_b = config.retryOptions) === null || _b === void 0 ? void 0 : _b.maxRetries) !== undefined) {
|
556 | maxRetryValue = config.retryOptions.maxRetries;
|
557 | }
|
558 | requestDefaults.headers = this._getDefaultHeaders(reqOpts[exports.GCCL_GCS_CMD_KEY]);
|
559 | const options = {
|
560 | request: teeny_request_1.teenyRequest.defaults(requestDefaults),
|
561 | retries: autoRetryValue !== false ? maxRetryValue : 0,
|
562 | noResponseRetries: autoRetryValue !== false ? maxRetryValue : 0,
|
563 | shouldRetryFn(httpRespMessage) {
|
564 | var _a, _b;
|
565 | const err = util.parseHttpRespMessage(httpRespMessage).err;
|
566 | if ((_a = config.retryOptions) === null || _a === void 0 ? void 0 : _a.retryableErrorFn) {
|
567 | return err && ((_b = config.retryOptions) === null || _b === void 0 ? void 0 : _b.retryableErrorFn(err));
|
568 | }
|
569 | return err && util.shouldRetryRequest(err);
|
570 | },
|
571 | maxRetryDelay: (_c = config.retryOptions) === null || _c === void 0 ? void 0 : _c.maxRetryDelay,
|
572 | retryDelayMultiplier: (_d = config.retryOptions) === null || _d === void 0 ? void 0 : _d.retryDelayMultiplier,
|
573 | totalTimeout: (_e = config.retryOptions) === null || _e === void 0 ? void 0 : _e.totalTimeout,
|
574 | };
|
575 | if (typeof reqOpts.maxRetries === 'number') {
|
576 | options.retries = reqOpts.maxRetries;
|
577 | options.noResponseRetries = reqOpts.maxRetries;
|
578 | }
|
579 | if (!config.stream) {
|
580 | return (0, retry_request_1.default)(reqOpts, options,
|
581 |
|
582 | (err, response, body) => {
|
583 | util.handleResp(err, response, body, callback);
|
584 | });
|
585 | }
|
586 | const dup = config.stream;
|
587 |
|
588 | let requestStream;
|
589 | const isGetRequest = (reqOpts.method || 'GET').toUpperCase() === 'GET';
|
590 | if (isGetRequest) {
|
591 | requestStream = (0, retry_request_1.default)(reqOpts, options);
|
592 | dup.setReadable(requestStream);
|
593 | }
|
594 | else {
|
595 |
|
596 | requestStream = options.request(reqOpts);
|
597 | dup.setWritable(requestStream);
|
598 | }
|
599 |
|
600 | requestStream
|
601 | .on('error', dup.destroy.bind(dup))
|
602 | .on('response', dup.emit.bind(dup, 'response'))
|
603 | .on('complete', dup.emit.bind(dup, 'complete'));
|
604 | dup.abort = requestStream.abort;
|
605 | return dup;
|
606 | }
|
607 | |
608 |
|
609 |
|
610 |
|
611 |
|
612 |
|
613 |
|
614 | decorateRequest(reqOpts, projectId) {
|
615 | delete reqOpts.autoPaginate;
|
616 | delete reqOpts.autoPaginateVal;
|
617 | delete reqOpts.objectMode;
|
618 | if (reqOpts.qs !== null && typeof reqOpts.qs === 'object') {
|
619 | delete reqOpts.qs.autoPaginate;
|
620 | delete reqOpts.qs.autoPaginateVal;
|
621 | reqOpts.qs = (0, projectify_1.replaceProjectIdToken)(reqOpts.qs, projectId);
|
622 | }
|
623 | if (Array.isArray(reqOpts.multipart)) {
|
624 | reqOpts.multipart = reqOpts.multipart.map(part => {
|
625 | return (0, projectify_1.replaceProjectIdToken)(part, projectId);
|
626 | });
|
627 | }
|
628 | if (reqOpts.json !== null && typeof reqOpts.json === 'object') {
|
629 | delete reqOpts.json.autoPaginate;
|
630 | delete reqOpts.json.autoPaginateVal;
|
631 | reqOpts.json = (0, projectify_1.replaceProjectIdToken)(reqOpts.json, projectId);
|
632 | }
|
633 | reqOpts.uri = (0, projectify_1.replaceProjectIdToken)(reqOpts.uri, projectId);
|
634 | return reqOpts;
|
635 | }
|
636 |
|
637 | isCustomType(unknown, module) {
|
638 | function getConstructorName(obj) {
|
639 | return obj.constructor && obj.constructor.name.toLowerCase();
|
640 | }
|
641 | const moduleNameParts = module.split('/');
|
642 | const parentModuleName = moduleNameParts[0] && moduleNameParts[0].toLowerCase();
|
643 | const subModuleName = moduleNameParts[1] && moduleNameParts[1].toLowerCase();
|
644 | if (subModuleName && getConstructorName(unknown) !== subModuleName) {
|
645 | return false;
|
646 | }
|
647 | let walkingModule = unknown;
|
648 |
|
649 | while (true) {
|
650 | if (getConstructorName(walkingModule) === parentModuleName) {
|
651 | return true;
|
652 | }
|
653 | walkingModule = walkingModule.parent;
|
654 | if (!walkingModule) {
|
655 | return false;
|
656 | }
|
657 | }
|
658 | }
|
659 | |
660 |
|
661 |
|
662 |
|
663 |
|
664 |
|
665 |
|
666 | maybeOptionsOrCallback(optionsOrCallback, cb) {
|
667 | return typeof optionsOrCallback === 'function'
|
668 | ? [{}, optionsOrCallback]
|
669 | : [optionsOrCallback, cb];
|
670 | }
|
671 | _getDefaultHeaders(gcclGcsCmd) {
|
672 | const headers = {
|
673 | 'User-Agent': (0, util_js_1.getUserAgentString)(),
|
674 | 'x-goog-api-client': `${(0, util_js_1.getRuntimeTrackingString)()} gccl/${packageJson.version}-${(0, util_js_1.getModuleFormat)()} gccl-invocation-id/${uuid.v4()}`,
|
675 | };
|
676 | if (gcclGcsCmd) {
|
677 | headers['x-goog-api-client'] += ` gccl-gcs-cmd/${gcclGcsCmd}`;
|
678 | }
|
679 | return headers;
|
680 | }
|
681 | }
|
682 | exports.Util = Util;
|
683 |
|
684 |
|
685 |
|
686 |
|
687 | class ProgressStream extends stream_1.Transform {
|
688 | constructor() {
|
689 | super(...arguments);
|
690 | this.bytesRead = 0;
|
691 | }
|
692 |
|
693 | _transform(chunk, encoding, callback) {
|
694 | this.bytesRead += chunk.length;
|
695 | this.emit('progress', { bytesWritten: this.bytesRead, contentLength: '*' });
|
696 | this.push(chunk);
|
697 | callback();
|
698 | }
|
699 | }
|
700 | const util = new Util();
|
701 | exports.util = util;
|