UNPKG

googleapis

Version:
270 lines 13.7 kB
"use strict"; // Copyright 2014-2016, Google, Inc. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [0, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var google_auth_library_1 = require("google-auth-library"); var qs = require("qs"); var stream = require("stream"); var urlTemplate = require("url-template"); var uuid = require("uuid"); var maxContentLength = Math.pow(2, 31); // tslint:disable-next-line no-var-requires var pkg = require('../../../package.json'); var USER_AGENT = "google-api-nodejs-client/" + pkg.version + " (gzip)"; function isReadableStream(obj) { return obj instanceof stream.Readable && typeof obj._read === 'function'; } function getMissingParams(params, required) { var missing = new Array(); required.forEach(function (param) { // Is the required param in the params object? if (params[param] === undefined) { missing.push(param); } }); // If there are any required params missing, return their names in array, // otherwise return null return missing.length > 0 ? missing : null; } function createAPIRequest(parameters, callback) { if (callback) { createAPIRequestAsync(parameters) .then(function (r) { return callback(null, r); }) .catch(function (e) { return callback(e); }); } else { return createAPIRequestAsync(parameters); } } exports.createAPIRequest = createAPIRequest; function createAPIRequestAsync(parameters) { return __awaiter(this, void 0, void 0, function () { var params, options, media, resource, authClient, defaultMime, headers, missingParams, multipart, boundary, finale_1, rStream_1, pStream, isStream, _i, multipart_1, part, preamble, mergedOptions; return __generator(this, function (_a) { params = parameters.params; options = Object.assign({}, parameters.options); // Create a new params object so it can no longer be modified from outside // code Also support global and per-client params, but allow them to be // overriden per-request params = Object.assign({}, // New base object parameters.context.google._options.params, // Global params parameters.context._options.params, // Per-client params params // API call params ); media = params.media || {}; resource = params.resource; authClient = params.auth || parameters.context._options.auth || parameters.context.google._options.auth; defaultMime = typeof media.body === 'string' ? 'text/plain' : 'application/octet-stream'; delete params.media; delete params.resource; delete params.auth; headers = params.headers || {}; delete params.headers; // Un-alias parameters that were modified due to conflicts with reserved names Object.keys(params).forEach(function (key) { if (key.slice(-1) === '_') { var newKey = key.slice(0, -1); params[newKey] = params[key]; delete params[key]; } }); missingParams = getMissingParams(params, parameters.requiredParams); if (missingParams) { // Some params are missing - stop further operations and inform the // developer which required params are not included in the request throw new Error('Missing required parameters: ' + missingParams.join(', ')); } // Parse urls if (options.url) { options.url = urlTemplate.parse(options.url).expand(params); } if (parameters.mediaUrl) { parameters.mediaUrl = urlTemplate.parse(parameters.mediaUrl).expand(params); } // When forming the querystring, override the serializer so that array // values are serialized like this: // myParams: ['one', 'two'] ---> 'myParams=one&myParams=two' // This serializer also encodes spaces in the querystring as `%20`, // whereas the default serializer in axios encodes to a `+`. options.paramsSerializer = function (params) { return qs.stringify(params, { arrayFormat: 'repeat' }); }; // delete path parameters from the params object so they do not end up in // query parameters.pathParams.forEach(function (param) { delete params[param]; }); // if authClient is actually a string, use it as an API KEY if (typeof authClient === 'string') { params.key = params.key || authClient; authClient = undefined; } if (parameters.mediaUrl && media.body) { options.url = parameters.mediaUrl; if (resource) { // Axios doesn't support multipart/related uploads, so it has to // be implemented here. params.uploadType = 'multipart'; multipart = [ { 'Content-Type': 'application/json', body: JSON.stringify(resource) }, { 'Content-Type': media.mimeType || (resource && resource.mimeType) || defaultMime, body: media.body // can be a readable stream or raw string! } ]; boundary = uuid.v4(); finale_1 = "--" + boundary + "--"; rStream_1 = new stream.PassThrough(); pStream = new ProgressStream(); isStream = isReadableStream(multipart[1].body); headers['Content-Type'] = "multipart/related; boundary=" + boundary; for (_i = 0, multipart_1 = multipart; _i < multipart_1.length; _i++) { part = multipart_1[_i]; preamble = "--" + boundary + "\r\nContent-Type: " + part['Content-Type'] + "\r\n\r\n"; rStream_1.push(preamble); if (typeof part.body === 'string') { rStream_1.push(part.body); rStream_1.push('\r\n'); } else { // Axios does not natively support onUploadProgress in node.js. // Pipe through the pStream first to read the number of bytes read // for the purpose of tracking progress. pStream.on('progress', function (bytesRead) { if (options.onUploadProgress) { options.onUploadProgress({ bytesRead: bytesRead }); } }); part.body.pipe(pStream).pipe(rStream_1, { end: false }); part.body.on('end', function () { rStream_1.push('\r\n'); rStream_1.push(finale_1); rStream_1.push(null); }); } } if (!isStream) { rStream_1.push(finale_1); rStream_1.push(null); } options.data = rStream_1; } else { params.uploadType = 'media'; Object.assign(headers, { 'Content-Type': media.mimeType || defaultMime }); options.data = media.body; } } else { options.data = resource || undefined; } options.headers = headers; options.params = params; // We need to set a default content size, or the max defaults // to 10MB. Setting to 2GB by default. // https://github.com/google/google-api-nodejs-client/issues/991 options.maxContentLength = options.maxContentLength || maxContentLength; options.headers['Accept-Encoding'] = 'gzip'; options.headers['User-Agent'] = USER_AGENT; // By default Axios treats any 2xx as valid, and all non 2xx status // codes as errors. This is a problem for HTTP 304s when used along // with an eTag. if (!options.validateStatus) { options.validateStatus = function (status) { return (status >= 200 && status < 300) || status === 304; }; } mergedOptions = Object.assign({}, parameters.context.google._options, parameters.context._options, options); delete mergedOptions.auth; // is overridden by our auth code // Perform the HTTP request. NOTE: this function used to return a // mikeal/request object. Since the transition to Axios, the method is // now void. This may be a source of confusion for users upgrading from // version 24.0 -> 25.0 or up. if (authClient && typeof authClient === 'object') { return [2 /*return*/, authClient.request(mergedOptions)]; } else { return [2 /*return*/, (new google_auth_library_1.DefaultTransporter()).request(mergedOptions)]; } return [2 /*return*/]; }); }); } /** * Basic Passthrough Stream that records the number of bytes read * every time the cursor is moved. */ var ProgressStream = /** @class */ (function (_super) { __extends(ProgressStream, _super); function ProgressStream() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.bytesRead = 0; return _this; } // tslint:disable-next-line: no-any ProgressStream.prototype._transform = function (chunk, encoding, callback) { this.bytesRead += chunk.length; this.emit('progress', this.bytesRead); this.push(chunk); callback(); }; return ProgressStream; }(stream.Transform)); //# sourceMappingURL=apirequest.js.map