Firebase Update
This commit is contained in:
51
express-server/node_modules/@google-cloud/common/src/index.js
generated
vendored
Normal file
51
express-server/node_modules/@google-cloud/common/src/index.js
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*!
|
||||
* Copyright 2016 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {module:common/logger}
|
||||
* @private
|
||||
*/
|
||||
exports.logger = require('./logger.js');
|
||||
|
||||
/**
|
||||
* @type {module:common/operation}
|
||||
* @private
|
||||
*/
|
||||
exports.Operation = require('./operation.js');
|
||||
|
||||
/**
|
||||
* @type {module:common/paginator}
|
||||
* @private
|
||||
*/
|
||||
exports.paginator = require('./paginator.js');
|
||||
|
||||
/**
|
||||
* @type {module:common/service}
|
||||
* @private
|
||||
*/
|
||||
exports.Service = require('./service.js');
|
||||
|
||||
/**
|
||||
* @type {module:common/serviceObject}
|
||||
* @private
|
||||
*/
|
||||
exports.ServiceObject = require('./service-object.js');
|
||||
|
||||
/**
|
||||
* @type {module:common/util}
|
||||
* @private
|
||||
*/
|
||||
exports.util = require('./util.js');
|
71
express-server/node_modules/@google-cloud/common/src/logger.js
generated
vendored
Normal file
71
express-server/node_modules/@google-cloud/common/src/logger.js
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
/*!
|
||||
* Copyright 2016 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* @module common/logger
|
||||
*/
|
||||
|
||||
const format = require('string-format-obj');
|
||||
const is = require('is');
|
||||
const logDriver = require('log-driver');
|
||||
|
||||
/**
|
||||
* The default list of log levels.
|
||||
* @type {string[]}
|
||||
*/
|
||||
const LEVELS = ['silent', 'error', 'warn', 'info', 'debug', 'silly'];
|
||||
|
||||
/**
|
||||
* Create a logger to print output to the console.
|
||||
*
|
||||
* @param {string=|object=} options - Configuration object. If a string, it is
|
||||
* treated as `options.level`.
|
||||
* @param {string=} options.level - The minimum log level that will print to the
|
||||
* console. (Default: `error`)
|
||||
* @param {Array.<string>=} options.levels - The list of levels to use. (Default:
|
||||
* logger.LEVELS)
|
||||
* @param {string=} options.tag - A tag to use in log messages.
|
||||
*/
|
||||
function logger(options) {
|
||||
if (is.string(options)) {
|
||||
options = {
|
||||
level: options,
|
||||
};
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
return logDriver({
|
||||
levels: options.levels || LEVELS,
|
||||
|
||||
level: options.level || 'error',
|
||||
|
||||
format: function() {
|
||||
const args = [].slice.call(arguments);
|
||||
|
||||
return format('{level}{tag} {message}', {
|
||||
level: args.shift().toUpperCase(),
|
||||
tag: options.tag ? ':' + options.tag + ':' : '',
|
||||
message: args.join(' '),
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = logger;
|
||||
module.exports.LEVELS = LEVELS;
|
193
express-server/node_modules/@google-cloud/common/src/operation.js
generated
vendored
Normal file
193
express-server/node_modules/@google-cloud/common/src/operation.js
generated
vendored
Normal file
@ -0,0 +1,193 @@
|
||||
/*!
|
||||
* Copyright 2016 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @module common/operation
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const events = require('events');
|
||||
const extend = require('extend');
|
||||
const modelo = require('modelo');
|
||||
|
||||
/**
|
||||
* @type {module:common/serviceObject}
|
||||
* @private
|
||||
*/
|
||||
const ServiceObject = require('./service-object.js');
|
||||
|
||||
// jscs:disable maximumLineLength
|
||||
/**
|
||||
* An Operation object allows you to interact with APIs that take longer to
|
||||
* process things.
|
||||
*
|
||||
* @constructor
|
||||
* @alias module:common/operation
|
||||
*
|
||||
* @param {object} config - Configuration object.
|
||||
* @param {module:common/service|module:common/serviceObject|module:common/grpcService|module:common/grpcServiceObject} config.parent - The
|
||||
* parent object.
|
||||
* @param {string} id - The operation ID.
|
||||
*/
|
||||
// jscs:enable maximumLineLength
|
||||
function Operation(config) {
|
||||
const methods = {
|
||||
/**
|
||||
* Checks to see if an operation exists.
|
||||
*/
|
||||
exists: true,
|
||||
|
||||
/**
|
||||
* Retrieves the operation.
|
||||
*/
|
||||
get: true,
|
||||
|
||||
/**
|
||||
* Retrieves metadata for the operation.
|
||||
*/
|
||||
getMetadata: {
|
||||
reqOpts: {
|
||||
name: config.id,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
config = extend(
|
||||
{
|
||||
baseUrl: '',
|
||||
},
|
||||
config
|
||||
);
|
||||
|
||||
config.methods = config.methods || methods;
|
||||
|
||||
ServiceObject.call(this, config);
|
||||
events.EventEmitter.call(this);
|
||||
|
||||
this.completeListeners = 0;
|
||||
this.hasActiveListeners = false;
|
||||
|
||||
this.listenForEvents_();
|
||||
}
|
||||
|
||||
modelo.inherits(Operation, ServiceObject, events.EventEmitter);
|
||||
|
||||
/**
|
||||
* Wraps the `complete` and `error` events in a Promise.
|
||||
*
|
||||
* @return {promise}
|
||||
*/
|
||||
Operation.prototype.promise = function() {
|
||||
const self = this;
|
||||
|
||||
return new self.Promise(function(resolve, reject) {
|
||||
self.on('error', reject).on('complete', function(metadata) {
|
||||
resolve([metadata]);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Begin listening for events on the operation. This method keeps track of how
|
||||
* many "complete" listeners are registered and removed, making sure polling is
|
||||
* handled automatically.
|
||||
*
|
||||
* As long as there is one active "complete" listener, the connection is open.
|
||||
* When there are no more listeners, the polling stops.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
Operation.prototype.listenForEvents_ = function() {
|
||||
const self = this;
|
||||
|
||||
this.on('newListener', function(event) {
|
||||
if (event === 'complete') {
|
||||
self.completeListeners++;
|
||||
|
||||
if (!self.hasActiveListeners) {
|
||||
self.hasActiveListeners = true;
|
||||
self.startPolling_();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.on('removeListener', function(event) {
|
||||
if (event === 'complete' && --self.completeListeners === 0) {
|
||||
self.hasActiveListeners = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Poll for a status update. Execute the callback:
|
||||
*
|
||||
* - callback(err): Operation failed
|
||||
* - callback(): Operation incomplete
|
||||
* - callback(null, metadata): Operation complete
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {function} callback
|
||||
*/
|
||||
Operation.prototype.poll_ = function(callback) {
|
||||
this.getMetadata(function(err, resp) {
|
||||
if (err || resp.error) {
|
||||
callback(err || resp.error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!resp.done) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, resp);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Poll `getMetadata` to check the operation's status. This runs a loop to ping
|
||||
* the API on an interval.
|
||||
*
|
||||
* Note: This method is automatically called once a "complete" event handler is
|
||||
* registered on the operation.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
Operation.prototype.startPolling_ = function() {
|
||||
const self = this;
|
||||
|
||||
if (!this.hasActiveListeners) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.poll_(function(err, metadata) {
|
||||
if (err) {
|
||||
self.emit('error', err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!metadata) {
|
||||
setTimeout(self.startPolling_.bind(self), 500);
|
||||
return;
|
||||
}
|
||||
|
||||
self.emit('complete', metadata);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = Operation;
|
267
express-server/node_modules/@google-cloud/common/src/paginator.js
generated
vendored
Normal file
267
express-server/node_modules/@google-cloud/common/src/paginator.js
generated
vendored
Normal file
@ -0,0 +1,267 @@
|
||||
/*!
|
||||
* Copyright 2015 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @module common/paginator
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const arrify = require('arrify');
|
||||
const concat = require('concat-stream');
|
||||
const extend = require('extend');
|
||||
const is = require('is');
|
||||
const split = require('split-array-stream');
|
||||
|
||||
/**
|
||||
* @type {module:common/util}
|
||||
* @private
|
||||
*/
|
||||
const util = require('./util.js');
|
||||
|
||||
/*! Developer Documentation
|
||||
*
|
||||
* paginator is used to auto-paginate `nextQuery` methods as well as
|
||||
* streamifying them.
|
||||
*
|
||||
* Before:
|
||||
*
|
||||
* search.query('done=true', function(err, results, nextQuery) {
|
||||
* search.query(nextQuery, function(err, results, nextQuery) {});
|
||||
* });
|
||||
*
|
||||
* After:
|
||||
*
|
||||
* search.query('done=true', function(err, results) {});
|
||||
*
|
||||
* Methods to extend should be written to accept callbacks and return a
|
||||
* `nextQuery`.
|
||||
*/
|
||||
const paginator = {};
|
||||
|
||||
/**
|
||||
* Cache the original method, then overwrite it on the Class's prototype.
|
||||
*
|
||||
* @param {function} Class - The parent class of the methods to extend.
|
||||
* @param {string|string[]} methodNames - Name(s) of the methods to extend.
|
||||
*/
|
||||
paginator.extend = function(Class, methodNames) {
|
||||
methodNames = arrify(methodNames);
|
||||
|
||||
methodNames.forEach(function(methodName) {
|
||||
const originalMethod = Class.prototype[methodName];
|
||||
|
||||
// map the original method to a private member
|
||||
Class.prototype[methodName + '_'] = originalMethod;
|
||||
|
||||
// overwrite the original to auto-paginate
|
||||
Class.prototype[methodName] = function() {
|
||||
const parsedArguments = paginator.parseArguments_(arguments);
|
||||
return paginator.run_(parsedArguments, originalMethod.bind(this));
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps paginated API calls in a readable object stream.
|
||||
*
|
||||
* This method simply calls the nextQuery recursively, emitting results to a
|
||||
* stream. The stream ends when `nextQuery` is null.
|
||||
*
|
||||
* `maxResults` will act as a cap for how many results are fetched and emitted
|
||||
* to the stream.
|
||||
*
|
||||
* @param {string} methodName - Name of the method to streamify.
|
||||
* @return {function} - Wrapped function.
|
||||
*/
|
||||
paginator.streamify = function(methodName) {
|
||||
return function() {
|
||||
const parsedArguments = paginator.parseArguments_(arguments);
|
||||
const originalMethod = this[methodName + '_'] || this[methodName];
|
||||
|
||||
return paginator.runAsStream_(parsedArguments, originalMethod.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse a pseudo-array `arguments` for a query and callback.
|
||||
*
|
||||
* @param {array} args - The original `arguments` pseduo-array that the original
|
||||
* method received.
|
||||
*/
|
||||
paginator.parseArguments_ = function(args) {
|
||||
let query;
|
||||
let autoPaginate = true;
|
||||
let maxApiCalls = -1;
|
||||
let maxResults = -1;
|
||||
let callback;
|
||||
|
||||
const firstArgument = args[0];
|
||||
const lastArgument = args[args.length - 1];
|
||||
|
||||
if (is.fn(firstArgument)) {
|
||||
callback = firstArgument;
|
||||
} else {
|
||||
query = firstArgument;
|
||||
}
|
||||
|
||||
if (is.fn(lastArgument)) {
|
||||
callback = lastArgument;
|
||||
}
|
||||
|
||||
if (is.object(query)) {
|
||||
query = extend(true, {}, query);
|
||||
|
||||
// Check if the user only asked for a certain amount of results.
|
||||
if (is.number(query.maxResults)) {
|
||||
// `maxResults` is used API-wide.
|
||||
maxResults = query.maxResults;
|
||||
} else if (is.number(query.pageSize)) {
|
||||
// `pageSize` is Pub/Sub's `maxResults`.
|
||||
maxResults = query.pageSize;
|
||||
}
|
||||
|
||||
if (is.number(query.maxApiCalls)) {
|
||||
maxApiCalls = query.maxApiCalls;
|
||||
delete query.maxApiCalls;
|
||||
}
|
||||
|
||||
if (
|
||||
callback &&
|
||||
(maxResults !== -1 || // The user specified a limit.
|
||||
query.autoPaginate === false)
|
||||
) {
|
||||
autoPaginate = false;
|
||||
}
|
||||
}
|
||||
|
||||
const parsedArguments = {
|
||||
query: query || {},
|
||||
autoPaginate: autoPaginate,
|
||||
maxApiCalls: maxApiCalls,
|
||||
maxResults: maxResults,
|
||||
callback: callback,
|
||||
};
|
||||
|
||||
parsedArguments.streamOptions = extend(true, {}, parsedArguments.query);
|
||||
delete parsedArguments.streamOptions.autoPaginate;
|
||||
delete parsedArguments.streamOptions.maxResults;
|
||||
delete parsedArguments.streamOptions.pageSize;
|
||||
|
||||
return parsedArguments;
|
||||
};
|
||||
|
||||
/**
|
||||
* This simply checks to see if `autoPaginate` is set or not, if it's true
|
||||
* then we buffer all results, otherwise simply call the original method.
|
||||
*
|
||||
* @param {array} parsedArguments - Parsed arguments from the original method
|
||||
* call.
|
||||
* @param {object=|string=} parsedArguments.query - Query object. This is most
|
||||
* commonly an object, but to make the API more simple, it can also be a
|
||||
* string in some places.
|
||||
* @param {function=} parsedArguments.callback - Callback function.
|
||||
* @param {boolean} parsedArguments.autoPaginate - Auto-pagination enabled.
|
||||
* @param {boolean} parsedArguments.maxApiCalls - Maximum API calls to make.
|
||||
* @param {number} parsedArguments.maxResults - Maximum results to return.
|
||||
* @param {function} originalMethod - The cached method that accepts a callback
|
||||
* and returns `nextQuery` to receive more results.
|
||||
*/
|
||||
paginator.run_ = function(parsedArguments, originalMethod) {
|
||||
const query = parsedArguments.query;
|
||||
const callback = parsedArguments.callback;
|
||||
const autoPaginate = parsedArguments.autoPaginate;
|
||||
|
||||
if (autoPaginate) {
|
||||
this.runAsStream_(parsedArguments, originalMethod)
|
||||
.on('error', callback)
|
||||
.pipe(
|
||||
concat(function(results) {
|
||||
callback(null, results);
|
||||
})
|
||||
);
|
||||
} else {
|
||||
originalMethod(query, callback);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This method simply calls the nextQuery recursively, emitting results to a
|
||||
* stream. The stream ends when `nextQuery` is null.
|
||||
*
|
||||
* `maxResults` will act as a cap for how many results are fetched and emitted
|
||||
* to the stream.
|
||||
*
|
||||
* @param {object=|string=} parsedArguments.query - Query object. This is most
|
||||
* commonly an object, but to make the API more simple, it can also be a
|
||||
* string in some places.
|
||||
* @param {function=} parsedArguments.callback - Callback function.
|
||||
* @param {boolean} parsedArguments.autoPaginate - Auto-pagination enabled.
|
||||
* @param {boolean} parsedArguments.maxApiCalls - Maximum API calls to make.
|
||||
* @param {number} parsedArguments.maxResults - Maximum results to return.
|
||||
* @param {function} originalMethod - The cached method that accepts a callback
|
||||
* and returns `nextQuery` to receive more results.
|
||||
* @return {stream} - Readable object stream.
|
||||
*/
|
||||
paginator.runAsStream_ = function(parsedArguments, originalMethod) {
|
||||
let query = parsedArguments.query;
|
||||
let resultsToSend = parsedArguments.maxResults;
|
||||
|
||||
const limiter = util.createLimiter(makeRequest, {
|
||||
maxApiCalls: parsedArguments.maxApiCalls,
|
||||
streamOptions: parsedArguments.streamOptions,
|
||||
});
|
||||
|
||||
const stream = limiter.stream;
|
||||
|
||||
stream.once('reading', function() {
|
||||
makeRequest(query);
|
||||
});
|
||||
|
||||
function makeRequest(query) {
|
||||
originalMethod(query, onResultSet);
|
||||
}
|
||||
|
||||
function onResultSet(err, results, nextQuery) {
|
||||
if (err) {
|
||||
stream.destroy(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (resultsToSend >= 0 && results.length > resultsToSend) {
|
||||
results = results.splice(0, resultsToSend);
|
||||
}
|
||||
|
||||
resultsToSend -= results.length;
|
||||
|
||||
split(results, stream, function(streamEnded) {
|
||||
if (streamEnded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextQuery && resultsToSend !== 0) {
|
||||
limiter.makeRequest(nextQuery);
|
||||
return;
|
||||
}
|
||||
|
||||
stream.push(null);
|
||||
});
|
||||
}
|
||||
|
||||
return limiter.stream;
|
||||
};
|
||||
|
||||
module.exports = paginator;
|
392
express-server/node_modules/@google-cloud/common/src/service-object.js
generated
vendored
Normal file
392
express-server/node_modules/@google-cloud/common/src/service-object.js
generated
vendored
Normal file
@ -0,0 +1,392 @@
|
||||
/*!
|
||||
* Copyright 2015 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @module common/service-object
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const arrify = require('arrify');
|
||||
const exec = require('methmeth');
|
||||
const extend = require('extend');
|
||||
const is = require('is');
|
||||
|
||||
/**
|
||||
* @type {module:common/util}
|
||||
* @private
|
||||
*/
|
||||
const util = require('./util.js');
|
||||
|
||||
/**
|
||||
* ServiceObject is a base class, meant to be inherited from by a "service
|
||||
* object," like a BigQuery dataset or Storage bucket.
|
||||
*
|
||||
* Most of the time, these objects share common functionality; they can be
|
||||
* created or deleted, and you can get or set their metadata.
|
||||
*
|
||||
* By inheriting from this class, a service object will be extended with these
|
||||
* shared behaviors. Note that any method can be overridden when the service
|
||||
* object requires specific behavior.
|
||||
*
|
||||
* @constructor
|
||||
* @alias module:common/service-object
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {object} config - Configuration object.
|
||||
* @param {string} config.baseUrl - The base URL to make API requests to.
|
||||
* @param {string} config.createMethod - The method which creates this object.
|
||||
* @param {string=} config.id - The identifier of the object. For example, the
|
||||
* name of a Storage bucket or Pub/Sub topic.
|
||||
* @param {object=} config.methods - A map of each method name that should be
|
||||
* inherited.
|
||||
* @param {object} config.methods[].reqOpts - Default request options for this
|
||||
* particular method. A common use case is when `setMetadata` requires a
|
||||
* `PUT` method to override the default `PATCH`.
|
||||
* @param {object} config.parent - The parent service instance. For example, an
|
||||
* instance of Storage if the object is Bucket.
|
||||
*/
|
||||
function ServiceObject(config) {
|
||||
const self = this;
|
||||
|
||||
util.privatize(this, 'metadata', {});
|
||||
|
||||
util.privatize(this, 'baseUrl', config.baseUrl);
|
||||
util.privatize(this, 'parent', config.parent); // Parent class.
|
||||
util.privatize(this, 'id', config.id); // Name or ID (e.g. dataset ID, bucket name, etc.)
|
||||
util.privatize(this, 'createMethod', config.createMethod);
|
||||
util.privatize(this, 'methods', config.methods || {});
|
||||
util.privatize(this, 'interceptors', []);
|
||||
util.privatize(this, 'Promise', this.parent.Promise);
|
||||
|
||||
if (config.methods) {
|
||||
const allMethodNames = Object.keys(ServiceObject.prototype);
|
||||
allMethodNames
|
||||
.filter(function(methodName) {
|
||||
return (
|
||||
// All ServiceObjects need `request`.
|
||||
!/^request/.test(methodName) &&
|
||||
// The ServiceObject didn't redefine the method.
|
||||
self[methodName] === ServiceObject.prototype[methodName] &&
|
||||
// This method isn't wanted.
|
||||
!config.methods[methodName]
|
||||
);
|
||||
})
|
||||
.forEach(function(methodName) {
|
||||
self[methodName] = undefined;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object.
|
||||
*
|
||||
* @param {object=} options - Configuration object.
|
||||
* @param {function} callback - The callback function.
|
||||
* @param {?error} callback.err - An error returned while making this request.
|
||||
* @param {object} callback.instance - The instance.
|
||||
* @param {object} callback.apiResponse - The full API response.
|
||||
*/
|
||||
ServiceObject.prototype.create = function(options, callback) {
|
||||
const self = this;
|
||||
const args = [this.id];
|
||||
|
||||
if (is.fn(options)) {
|
||||
callback = options;
|
||||
}
|
||||
|
||||
if (is.object(options)) {
|
||||
args.push(options);
|
||||
}
|
||||
|
||||
// Wrap the callback to return *this* instance of the object, not the newly-
|
||||
// created one.
|
||||
function onCreate(err, instance) {
|
||||
const args = [].slice.call(arguments);
|
||||
|
||||
if (!err) {
|
||||
self.metadata = instance.metadata;
|
||||
args[1] = self; // replace the created `instance` with this one.
|
||||
}
|
||||
|
||||
callback.apply(null, args);
|
||||
}
|
||||
|
||||
args.push(onCreate);
|
||||
|
||||
this.createMethod.apply(null, args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete the object.
|
||||
*
|
||||
* @param {function=} callback - The callback function.
|
||||
* @param {?error} callback.err - An error returned while making this request.
|
||||
* @param {object} callback.apiResponse - The full API response.
|
||||
*/
|
||||
ServiceObject.prototype.delete = function(callback) {
|
||||
const methodConfig = this.methods.delete || {};
|
||||
callback = callback || util.noop;
|
||||
|
||||
const reqOpts = extend(
|
||||
{
|
||||
method: 'DELETE',
|
||||
uri: '',
|
||||
},
|
||||
methodConfig.reqOpts
|
||||
);
|
||||
|
||||
// The `request` method may have been overridden to hold any special behavior.
|
||||
// Ensure we call the original `request` method.
|
||||
ServiceObject.prototype.request.call(this, reqOpts, function(err, resp) {
|
||||
callback(err, resp);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the object exists.
|
||||
*
|
||||
* @param {function} callback - The callback function.
|
||||
* @param {?error} callback.err - An error returned while making this request.
|
||||
* @param {boolean} callback.exists - Whether the object exists or not.
|
||||
*/
|
||||
ServiceObject.prototype.exists = function(callback) {
|
||||
this.get(function(err) {
|
||||
if (err) {
|
||||
if (err.code === 404) {
|
||||
callback(null, false);
|
||||
} else {
|
||||
callback(err);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, true);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the object if it exists. Optionally have the object created if an options
|
||||
* object is provided with `autoCreate: true`.
|
||||
*
|
||||
* @param {object=} config - The configuration object that will be used to
|
||||
* create the object if necessary.
|
||||
* @param {boolean} config.autoCreate - Create the object if it doesn't already
|
||||
* exist.
|
||||
* @param {function} callback - The callback function.
|
||||
* @param {?error} callback.err - An error returned while making this request.
|
||||
* @param {object} callback.instance - The instance.
|
||||
* @param {object} callback.apiResponse - The full API response.
|
||||
*/
|
||||
ServiceObject.prototype.get = function(config, callback) {
|
||||
const self = this;
|
||||
|
||||
if (is.fn(config)) {
|
||||
callback = config;
|
||||
config = {};
|
||||
}
|
||||
|
||||
config = config || {};
|
||||
|
||||
const autoCreate = config.autoCreate && is.fn(this.create);
|
||||
delete config.autoCreate;
|
||||
|
||||
function onCreate(err, instance, apiResponse) {
|
||||
if (err) {
|
||||
if (err.code === 409) {
|
||||
self.get(config, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(err, null, apiResponse);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, instance, apiResponse);
|
||||
}
|
||||
|
||||
this.getMetadata(function(err, metadata) {
|
||||
if (err) {
|
||||
if (err.code === 404 && autoCreate) {
|
||||
const args = [];
|
||||
|
||||
if (!is.empty(config)) {
|
||||
args.push(config);
|
||||
}
|
||||
|
||||
args.push(onCreate);
|
||||
|
||||
self.create.apply(self, args);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(err, null, metadata);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, self, metadata);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the metadata of this object.
|
||||
*
|
||||
* @param {function} callback - The callback function.
|
||||
* @param {?error} callback.err - An error returned while making this request.
|
||||
* @param {object} callback.metadata - The metadata for this object.
|
||||
* @param {object} callback.apiResponse - The full API response.
|
||||
*/
|
||||
ServiceObject.prototype.getMetadata = function(callback) {
|
||||
const self = this;
|
||||
|
||||
const methodConfig = this.methods.getMetadata || {};
|
||||
|
||||
const reqOpts = extend(
|
||||
{
|
||||
uri: '',
|
||||
},
|
||||
methodConfig.reqOpts
|
||||
);
|
||||
|
||||
// The `request` method may have been overridden to hold any special behavior.
|
||||
// Ensure we call the original `request` method.
|
||||
ServiceObject.prototype.request.call(this, reqOpts, function(err, resp) {
|
||||
if (err) {
|
||||
callback(err, null, resp);
|
||||
return;
|
||||
}
|
||||
|
||||
self.metadata = resp;
|
||||
|
||||
callback(null, self.metadata, resp);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the metadata for this object.
|
||||
*
|
||||
* @param {object} metadata - The metadata to set on this object.
|
||||
* @param {function=} callback - The callback function.
|
||||
* @param {?error} callback.err - An error returned while making this request.
|
||||
* @param {object} callback.instance - The instance.
|
||||
* @param {object} callback.apiResponse - The full API response.
|
||||
*/
|
||||
ServiceObject.prototype.setMetadata = function(metadata, callback) {
|
||||
const self = this;
|
||||
|
||||
callback = callback || util.noop;
|
||||
|
||||
const methodConfig = this.methods.setMetadata || {};
|
||||
|
||||
const reqOpts = extend(
|
||||
true,
|
||||
{
|
||||
method: 'PATCH',
|
||||
uri: '',
|
||||
json: metadata,
|
||||
},
|
||||
methodConfig.reqOpts
|
||||
);
|
||||
|
||||
// The `request` method may have been overridden to hold any special behavior.
|
||||
// Ensure we call the original `request` method.
|
||||
ServiceObject.prototype.request.call(this, reqOpts, function(err, resp) {
|
||||
if (err) {
|
||||
callback(err, resp);
|
||||
return;
|
||||
}
|
||||
|
||||
self.metadata = resp;
|
||||
|
||||
callback(null, resp);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Make an authenticated API request.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {object} reqOpts - Request options that are passed to `request`.
|
||||
* @param {string} reqOpts.uri - A URI relative to the baseUrl.
|
||||
* @param {function} callback - The callback function passed to `request`.
|
||||
*/
|
||||
ServiceObject.prototype.request_ = function(reqOpts, callback) {
|
||||
reqOpts = extend(true, {}, reqOpts);
|
||||
|
||||
const isAbsoluteUrl = reqOpts.uri.indexOf('http') === 0;
|
||||
|
||||
const uriComponents = [this.baseUrl, this.id || '', reqOpts.uri];
|
||||
|
||||
if (isAbsoluteUrl) {
|
||||
uriComponents.splice(0, uriComponents.indexOf(reqOpts.uri));
|
||||
}
|
||||
|
||||
reqOpts.uri = uriComponents
|
||||
.filter(exec('trim')) // Limit to non-empty strings.
|
||||
.map(function(uriComponent) {
|
||||
const trimSlashesRegex = /^\/*|\/*$/g;
|
||||
return uriComponent.replace(trimSlashesRegex, '');
|
||||
})
|
||||
.join('/');
|
||||
|
||||
const childInterceptors = arrify(reqOpts.interceptors_);
|
||||
const localInterceptors = [].slice.call(this.interceptors);
|
||||
|
||||
reqOpts.interceptors_ = childInterceptors.concat(localInterceptors);
|
||||
|
||||
if (!callback) {
|
||||
return this.parent.requestStream(reqOpts);
|
||||
}
|
||||
|
||||
this.parent.request(reqOpts, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Make an authenticated API request.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {object} reqOpts - Request options that are passed to `request`.
|
||||
* @param {string} reqOpts.uri - A URI relative to the baseUrl.
|
||||
* @param {function} callback - The callback function passed to `request`.
|
||||
*/
|
||||
ServiceObject.prototype.request = function(reqOpts, callback) {
|
||||
ServiceObject.prototype.request_.call(this, reqOpts, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Make an authenticated API request.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {object} reqOpts - Request options that are passed to `request`.
|
||||
* @param {string} reqOpts.uri - A URI relative to the baseUrl.
|
||||
*/
|
||||
ServiceObject.prototype.requestStream = function(reqOpts) {
|
||||
return ServiceObject.prototype.request_.call(this, reqOpts);
|
||||
};
|
||||
|
||||
/*! Developer Documentation
|
||||
*
|
||||
* All async methods (except for streams) will return a Promise in the event
|
||||
* that a callback is omitted.
|
||||
*/
|
||||
util.promisifyAll(ServiceObject);
|
||||
|
||||
module.exports = ServiceObject;
|
200
express-server/node_modules/@google-cloud/common/src/service.js
generated
vendored
Normal file
200
express-server/node_modules/@google-cloud/common/src/service.js
generated
vendored
Normal file
@ -0,0 +1,200 @@
|
||||
/*!
|
||||
* Copyright 2015 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @module common/service
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const arrify = require('arrify');
|
||||
const extend = require('extend');
|
||||
|
||||
/**
|
||||
* @type {module:common/util}
|
||||
* @private
|
||||
*/
|
||||
const util = require('./util.js');
|
||||
|
||||
const PROJECT_ID_TOKEN = '{{projectId}}';
|
||||
|
||||
/**
|
||||
* Service is a base class, meant to be inherited from by a "service," like
|
||||
* BigQuery or Storage.
|
||||
*
|
||||
* This handles making authenticated requests by exposing a `makeReq_` function.
|
||||
*
|
||||
* @constructor
|
||||
* @alias module:common/service
|
||||
*
|
||||
* @param {object} config - Configuration object.
|
||||
* @param {string} config.baseUrl - The base URL to make API requests to.
|
||||
* @param {string[]} config.scopes - The scopes required for the request.
|
||||
* @param {object=} options - [Configuration object](#/docs).
|
||||
*/
|
||||
function Service(config, options) {
|
||||
options = options || {};
|
||||
|
||||
util.privatize(this, 'baseUrl', config.baseUrl);
|
||||
util.privatize(this, 'globalInterceptors', arrify(options.interceptors_));
|
||||
util.privatize(this, 'interceptors', []);
|
||||
util.privatize(this, 'packageJson', config.packageJson);
|
||||
util.privatize(this, 'projectId', options.projectId || PROJECT_ID_TOKEN);
|
||||
util.privatize(this, 'projectIdRequired', config.projectIdRequired !== false);
|
||||
util.privatize(this, 'Promise', options.promise || Promise);
|
||||
|
||||
const reqCfg = extend({}, config, {
|
||||
projectIdRequired: this.projectIdRequired,
|
||||
projectId: this.projectId,
|
||||
credentials: options.credentials,
|
||||
keyFile: options.keyFilename,
|
||||
email: options.email,
|
||||
token: options.token,
|
||||
});
|
||||
|
||||
util.privatize(
|
||||
this,
|
||||
'makeAuthenticatedRequest',
|
||||
util.makeAuthenticatedRequestFactory(reqCfg)
|
||||
);
|
||||
util.privatize(this, 'authClient', this.makeAuthenticatedRequest.authClient);
|
||||
util.privatize(
|
||||
this,
|
||||
'getCredentials',
|
||||
this.makeAuthenticatedRequest.getCredentials
|
||||
);
|
||||
|
||||
const isCloudFunctionEnv = !!process.env.FUNCTION_NAME;
|
||||
|
||||
if (isCloudFunctionEnv) {
|
||||
this.interceptors.push({
|
||||
request: function(reqOpts) {
|
||||
reqOpts.forever = false;
|
||||
return reqOpts;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and update the Service's project ID.
|
||||
*
|
||||
* @param {function} callback - The callback function.
|
||||
*/
|
||||
Service.prototype.getProjectId = function(callback) {
|
||||
const self = this;
|
||||
|
||||
this.authClient.getProjectId(function(err, projectId) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.projectId === PROJECT_ID_TOKEN && projectId) {
|
||||
self.projectId = projectId;
|
||||
}
|
||||
|
||||
callback(null, self.projectId);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Make an authenticated API request.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {object} reqOpts - Request options that are passed to `request`.
|
||||
* @param {string} reqOpts.uri - A URI relative to the baseUrl.
|
||||
* @param {function} callback - The callback function passed to `request`.
|
||||
*/
|
||||
Service.prototype.request_ = function(reqOpts, callback) {
|
||||
reqOpts = extend(true, {}, reqOpts);
|
||||
|
||||
const isAbsoluteUrl = reqOpts.uri.indexOf('http') === 0;
|
||||
|
||||
const uriComponents = [this.baseUrl];
|
||||
|
||||
if (this.projectIdRequired) {
|
||||
uriComponents.push('projects');
|
||||
uriComponents.push(this.projectId);
|
||||
}
|
||||
|
||||
uriComponents.push(reqOpts.uri);
|
||||
|
||||
if (isAbsoluteUrl) {
|
||||
uriComponents.splice(0, uriComponents.indexOf(reqOpts.uri));
|
||||
}
|
||||
|
||||
reqOpts.uri = uriComponents
|
||||
.map(function(uriComponent) {
|
||||
const trimSlashesRegex = /^\/*|\/*$/g;
|
||||
return uriComponent.replace(trimSlashesRegex, '');
|
||||
})
|
||||
.join('/')
|
||||
// Some URIs have colon separators.
|
||||
// Bad: https://.../projects/:list
|
||||
// Good: https://.../projects:list
|
||||
.replace(/\/:/g, ':');
|
||||
|
||||
// Interceptors should be called in the order they were assigned.
|
||||
const combinedInterceptors = [].slice
|
||||
.call(this.globalInterceptors)
|
||||
.concat(this.interceptors)
|
||||
.concat(arrify(reqOpts.interceptors_));
|
||||
|
||||
let interceptor;
|
||||
|
||||
while ((interceptor = combinedInterceptors.shift()) && interceptor.request) {
|
||||
reqOpts = interceptor.request(reqOpts);
|
||||
}
|
||||
|
||||
delete reqOpts.interceptors_;
|
||||
|
||||
const pkg = this.packageJson;
|
||||
reqOpts.headers = extend({}, reqOpts.headers, {
|
||||
'User-Agent': util.getUserAgentFromPackageJson(pkg),
|
||||
'x-goog-api-client': `gl-node/${process.versions.node} gccl/${pkg.version}`,
|
||||
});
|
||||
|
||||
return this.makeAuthenticatedRequest(reqOpts, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Make an authenticated API request.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {object} reqOpts - Request options that are passed to `request`.
|
||||
* @param {string} reqOpts.uri - A URI relative to the baseUrl.
|
||||
* @param {function} callback - The callback function passed to `request`.
|
||||
*/
|
||||
Service.prototype.request = function(reqOpts, callback) {
|
||||
Service.prototype.request_.call(this, reqOpts, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Make an authenticated API request.
|
||||
*
|
||||
* @private
|
||||
*
|
||||
* @param {object} reqOpts - Request options that are passed to `request`.
|
||||
* @param {string} reqOpts.uri - A URI relative to the baseUrl.
|
||||
*/
|
||||
Service.prototype.requestStream = function(reqOpts) {
|
||||
return Service.prototype.request_.call(this, reqOpts);
|
||||
};
|
||||
|
||||
module.exports = Service;
|
830
express-server/node_modules/@google-cloud/common/src/util.js
generated
vendored
Normal file
830
express-server/node_modules/@google-cloud/common/src/util.js
generated
vendored
Normal file
@ -0,0 +1,830 @@
|
||||
/**
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @module common/util
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const createErrorClass = require('create-error-class');
|
||||
const duplexify = require('duplexify');
|
||||
const ent = require('ent');
|
||||
const extend = require('extend');
|
||||
const googleAuth = require('google-auto-auth');
|
||||
const is = require('is');
|
||||
const request = require('request').defaults({
|
||||
timeout: 60000,
|
||||
gzip: true,
|
||||
forever: true,
|
||||
pool: {
|
||||
maxSockets: Infinity,
|
||||
},
|
||||
});
|
||||
const retryRequest = require('retry-request');
|
||||
const streamEvents = require('stream-events');
|
||||
const through = require('through2');
|
||||
const uniq = require('array-uniq');
|
||||
|
||||
const util = module.exports;
|
||||
|
||||
/**
|
||||
* Custom error type for missing project ID errors.
|
||||
*/
|
||||
util.MissingProjectIdError = createErrorClass(
|
||||
'MissingProjectIdError',
|
||||
function() {
|
||||
this.message = `Sorry, we cannot connect to Cloud Services without a project
|
||||
ID. You may specify one with an environment variable named
|
||||
"GOOGLE_CLOUD_PROJECT".`.replace(/ +/g, ' ');
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* No op.
|
||||
*
|
||||
* @example
|
||||
* function doSomething(callback) {
|
||||
* callback = callback || noop;
|
||||
* }
|
||||
*/
|
||||
function noop() {}
|
||||
|
||||
util.noop = noop;
|
||||
|
||||
/**
|
||||
* Custom error type for API errors.
|
||||
*
|
||||
* @param {object} errorBody - Error object.
|
||||
*/
|
||||
util.ApiError = createErrorClass('ApiError', function(errorBody) {
|
||||
this.code = errorBody.code;
|
||||
this.errors = errorBody.errors;
|
||||
this.response = errorBody.response;
|
||||
|
||||
try {
|
||||
this.errors = JSON.parse(this.response.body).error.errors;
|
||||
} catch (e) {
|
||||
this.errors = errorBody.errors;
|
||||
}
|
||||
|
||||
const messages = [];
|
||||
|
||||
if (errorBody.message) {
|
||||
messages.push(errorBody.message);
|
||||
}
|
||||
|
||||
if (this.errors && this.errors.length === 1) {
|
||||
messages.push(this.errors[0].message);
|
||||
} else if (this.response && this.response.body) {
|
||||
messages.push(ent.decode(errorBody.response.body.toString()));
|
||||
} else if (!errorBody.message) {
|
||||
messages.push('Error during request.');
|
||||
}
|
||||
|
||||
this.message = uniq(messages).join(' - ');
|
||||
});
|
||||
|
||||
/**
|
||||
* Custom error type for partial errors returned from the API.
|
||||
*
|
||||
* @param {object} b - Error object.
|
||||
*/
|
||||
util.PartialFailureError = createErrorClass('PartialFailureError', function(b) {
|
||||
const errorObject = b;
|
||||
|
||||
this.errors = errorObject.errors;
|
||||
this.response = errorObject.response;
|
||||
|
||||
const defaultErrorMessage = 'A failure occurred during this request.';
|
||||
this.message = errorObject.message || defaultErrorMessage;
|
||||
});
|
||||
|
||||
/**
|
||||
* Uniformly process an API response.
|
||||
*
|
||||
* @param {*} err - Error value.
|
||||
* @param {*} resp - Response value.
|
||||
* @param {*} body - Body value.
|
||||
* @param {function} callback - The callback function.
|
||||
*/
|
||||
function handleResp(err, resp, body, callback) {
|
||||
callback = callback || util.noop;
|
||||
|
||||
const parsedResp = extend(
|
||||
true,
|
||||
{err: err || null},
|
||||
resp && util.parseHttpRespMessage(resp),
|
||||
body && util.parseHttpRespBody(body)
|
||||
);
|
||||
|
||||
callback(parsedResp.err, parsedResp.body, parsedResp.resp);
|
||||
}
|
||||
|
||||
util.handleResp = handleResp;
|
||||
|
||||
/**
|
||||
* Sniff an incoming HTTP response message for errors.
|
||||
*
|
||||
* @param {object} httpRespMessage - An incoming HTTP response message from
|
||||
* `request`.
|
||||
* @return {object} parsedHttpRespMessage - The parsed response.
|
||||
* @param {?error} parsedHttpRespMessage.err - An error detected.
|
||||
* @param {object} parsedHttpRespMessage.resp - The original response object.
|
||||
*/
|
||||
function parseHttpRespMessage(httpRespMessage) {
|
||||
const parsedHttpRespMessage = {
|
||||
resp: httpRespMessage,
|
||||
};
|
||||
|
||||
if (httpRespMessage.statusCode < 200 || httpRespMessage.statusCode > 299) {
|
||||
// Unknown error. Format according to ApiError standard.
|
||||
parsedHttpRespMessage.err = new util.ApiError({
|
||||
errors: [],
|
||||
code: httpRespMessage.statusCode,
|
||||
message: httpRespMessage.statusMessage,
|
||||
response: httpRespMessage,
|
||||
});
|
||||
}
|
||||
|
||||
return parsedHttpRespMessage;
|
||||
}
|
||||
|
||||
util.parseHttpRespMessage = parseHttpRespMessage;
|
||||
|
||||
/**
|
||||
* Parse the response body from an HTTP request.
|
||||
*
|
||||
* @param {object} body - The response body.
|
||||
* @return {object} parsedHttpRespMessage - The parsed response.
|
||||
* @param {?error} parsedHttpRespMessage.err - An error detected.
|
||||
* @param {object} parsedHttpRespMessage.body - The original body value provided
|
||||
* will try to be JSON.parse'd. If it's successful, the parsed value will be
|
||||
* returned here, otherwise the original value.
|
||||
*/
|
||||
function parseHttpRespBody(body) {
|
||||
const parsedHttpRespBody = {
|
||||
body: body,
|
||||
};
|
||||
|
||||
if (is.string(body)) {
|
||||
try {
|
||||
parsedHttpRespBody.body = JSON.parse(body);
|
||||
} catch (err) {
|
||||
parsedHttpRespBody.err = new util.ApiError('Cannot parse JSON response');
|
||||
}
|
||||
}
|
||||
|
||||
if (parsedHttpRespBody.body && parsedHttpRespBody.body.error) {
|
||||
// Error from JSON API.
|
||||
parsedHttpRespBody.err = new util.ApiError(parsedHttpRespBody.body.error);
|
||||
}
|
||||
|
||||
return parsedHttpRespBody;
|
||||
}
|
||||
|
||||
util.parseHttpRespBody = parseHttpRespBody;
|
||||
|
||||
/**
|
||||
* Take a Duplexify stream, fetch an authenticated connection header, and create
|
||||
* an outgoing writable stream.
|
||||
*
|
||||
* @param {Duplexify} dup - Duplexify stream.
|
||||
* @param {object} options - Configuration object.
|
||||
* @param {module:common/connection} options.connection - A connection instance,
|
||||
* used to get a token with and send the request through.
|
||||
* @param {object} options.metadata - Metadata to send at the head of the
|
||||
* request.
|
||||
* @param {object} options.request - Request object, in the format of a standard
|
||||
* Node.js http.request() object.
|
||||
* @param {string=} options.request.method - Default: "POST".
|
||||
* @param {string=} options.request.qs.uploadType - Default: "multipart".
|
||||
* @param {string=} options.streamContentType - Default:
|
||||
* "application/octet-stream".
|
||||
* @param {function} onComplete - Callback, executed after the writable Request
|
||||
* stream has completed.
|
||||
*/
|
||||
function makeWritableStream(dup, options, onComplete) {
|
||||
onComplete = onComplete || util.noop;
|
||||
|
||||
const writeStream = through();
|
||||
dup.setWritable(writeStream);
|
||||
|
||||
const defaultReqOpts = {
|
||||
method: 'POST',
|
||||
qs: {
|
||||
uploadType: 'multipart',
|
||||
},
|
||||
};
|
||||
|
||||
const metadata = options.metadata || {};
|
||||
|
||||
const reqOpts = extend(true, defaultReqOpts, options.request, {
|
||||
multipart: [
|
||||
{
|
||||
'Content-Type': 'application/json',
|
||||
body: JSON.stringify(metadata),
|
||||
},
|
||||
{
|
||||
'Content-Type': metadata.contentType || 'application/octet-stream',
|
||||
body: writeStream,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
options.makeAuthenticatedRequest(reqOpts, {
|
||||
onAuthenticated: function(err, authenticatedReqOpts) {
|
||||
if (err) {
|
||||
dup.destroy(err);
|
||||
return;
|
||||
}
|
||||
|
||||
request(authenticatedReqOpts, function(err, resp, body) {
|
||||
util.handleResp(err, resp, body, function(err, data) {
|
||||
if (err) {
|
||||
dup.destroy(err);
|
||||
return;
|
||||
}
|
||||
|
||||
dup.emit('response', resp);
|
||||
onComplete(data);
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
util.makeWritableStream = makeWritableStream;
|
||||
|
||||
/**
|
||||
* Returns true if the API request should be retried, given the error that was
|
||||
* given the first time the request was attempted. This is used for rate limit
|
||||
* related errors as well as intermittent server errors.
|
||||
*
|
||||
* @param {error} err - The API error to check if it is appropriate to retry.
|
||||
* @return {boolean} True if the API request should be retried, false otherwise.
|
||||
*/
|
||||
function shouldRetryRequest(err) {
|
||||
if (err) {
|
||||
if ([429, 500, 502, 503].indexOf(err.code) !== -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (err.errors) {
|
||||
for (const i in err.errors) {
|
||||
const reason = err.errors[i].reason;
|
||||
if (reason === 'rateLimitExceeded') {
|
||||
return true;
|
||||
}
|
||||
if (reason === 'userRateLimitExceeded') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
util.shouldRetryRequest = shouldRetryRequest;
|
||||
|
||||
/**
|
||||
* Get a function for making authenticated requests.
|
||||
*
|
||||
* @throws {Error} If a projectId is requested, but not able to be detected.
|
||||
*
|
||||
* @param {object} config - Configuration object.
|
||||
* @param {boolean=} config.autoRetry - Automatically retry requests if the
|
||||
* response is related to rate limits or certain intermittent server errors.
|
||||
* We will exponentially backoff subsequent requests by default. (default:
|
||||
* true)
|
||||
* @param {object=} config.credentials - Credentials object.
|
||||
* @param {boolean=} config.customEndpoint - If true, just return the provided
|
||||
* request options. Default: false.
|
||||
* @param {string=} config.email - Account email address, required for PEM/P12
|
||||
* usage.
|
||||
* @param {number=} config.maxRetries - Maximum number of automatic retries
|
||||
* attempted before returning the error. (default: 3)
|
||||
* @param {string=} config.keyFile - Path to a .json, .pem, or .p12 keyfile.
|
||||
* @param {array} config.scopes - Array of scopes required for the API.
|
||||
*/
|
||||
function makeAuthenticatedRequestFactory(config) {
|
||||
config = config || {};
|
||||
|
||||
const googleAutoAuthConfig = extend({}, config);
|
||||
|
||||
if (googleAutoAuthConfig.projectId === '{{projectId}}') {
|
||||
delete googleAutoAuthConfig.projectId;
|
||||
}
|
||||
|
||||
const authClient = googleAuth(googleAutoAuthConfig);
|
||||
|
||||
/**
|
||||
* The returned function that will make an authenticated request.
|
||||
*
|
||||
* @param {type} reqOpts - Request options in the format `request` expects.
|
||||
* @param {object|function} options - Configuration object or callback
|
||||
* function.
|
||||
* @param {function=} options.onAuthenticated - If provided, a request will
|
||||
* not be made. Instead, this function is passed the error & authenticated
|
||||
* request options.
|
||||
*/
|
||||
function makeAuthenticatedRequest(reqOpts, options) {
|
||||
let stream;
|
||||
const reqConfig = extend({}, config);
|
||||
let activeRequest_;
|
||||
|
||||
if (!options) {
|
||||
stream = duplexify();
|
||||
reqConfig.stream = stream;
|
||||
}
|
||||
|
||||
function onAuthenticated(err, authenticatedReqOpts) {
|
||||
const autoAuthFailed =
|
||||
err &&
|
||||
err.message.indexOf('Could not load the default credentials') > -1;
|
||||
|
||||
if (autoAuthFailed) {
|
||||
// Even though authentication failed, the API might not actually care.
|
||||
authenticatedReqOpts = reqOpts;
|
||||
}
|
||||
|
||||
if (!err || autoAuthFailed) {
|
||||
let projectId = authClient.projectId;
|
||||
|
||||
if (config.projectId && config.projectId !== '{{projectId}}') {
|
||||
projectId = config.projectId;
|
||||
}
|
||||
|
||||
try {
|
||||
authenticatedReqOpts = util.decorateRequest(
|
||||
authenticatedReqOpts,
|
||||
projectId
|
||||
);
|
||||
err = null;
|
||||
} catch (e) {
|
||||
// A projectId was required, but we don't have one.
|
||||
// Re-use the "Could not load the default credentials error" if auto
|
||||
// auth failed.
|
||||
err = err || e;
|
||||
}
|
||||
}
|
||||
|
||||
if (err) {
|
||||
if (stream) {
|
||||
stream.destroy(err);
|
||||
} else {
|
||||
(options.onAuthenticated || options)(err);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (options && options.onAuthenticated) {
|
||||
options.onAuthenticated(null, authenticatedReqOpts);
|
||||
} else {
|
||||
activeRequest_ = util.makeRequest(
|
||||
authenticatedReqOpts,
|
||||
reqConfig,
|
||||
options
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (reqConfig.customEndpoint) {
|
||||
// Using a custom API override. Do not use `google-auto-auth` for
|
||||
// authentication. (ex: connecting to a local Datastore server)
|
||||
onAuthenticated(null, reqOpts);
|
||||
} else {
|
||||
authClient.authorizeRequest(reqOpts, onAuthenticated);
|
||||
}
|
||||
|
||||
if (stream) {
|
||||
return stream;
|
||||
}
|
||||
|
||||
return {
|
||||
abort: function() {
|
||||
if (activeRequest_) {
|
||||
activeRequest_.abort();
|
||||
activeRequest_ = null;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
makeAuthenticatedRequest.getCredentials = authClient.getCredentials.bind(
|
||||
authClient
|
||||
);
|
||||
|
||||
makeAuthenticatedRequest.authClient = authClient;
|
||||
|
||||
return makeAuthenticatedRequest;
|
||||
}
|
||||
|
||||
util.makeAuthenticatedRequestFactory = makeAuthenticatedRequestFactory;
|
||||
|
||||
/**
|
||||
* Make a request through the `retryRequest` module with built-in error handling
|
||||
* and exponential back off.
|
||||
*
|
||||
* @param {object} reqOpts - Request options in the format `request` expects.
|
||||
* @param {object=} config - Configuration object.
|
||||
* @param {boolean=} config.autoRetry - Automatically retry requests if the
|
||||
* response is related to rate limits or certain intermittent server errors.
|
||||
* We will exponentially backoff subsequent requests by default. (default:
|
||||
* true)
|
||||
* @param {number=} config.maxRetries - Maximum number of automatic retries
|
||||
* attempted before returning the error. (default: 3)
|
||||
* @param {function} callback - The callback function.
|
||||
*/
|
||||
function makeRequest(reqOpts, config, callback) {
|
||||
if (is.fn(config)) {
|
||||
callback = config;
|
||||
config = {};
|
||||
}
|
||||
|
||||
config = config || {};
|
||||
|
||||
const options = {
|
||||
request: request,
|
||||
|
||||
retries: config.autoRetry !== false ? config.maxRetries || 3 : 0,
|
||||
|
||||
shouldRetryFn: function(httpRespMessage) {
|
||||
const err = util.parseHttpRespMessage(httpRespMessage).err;
|
||||
return err && util.shouldRetryRequest(err);
|
||||
},
|
||||
};
|
||||
|
||||
if (config.stream) {
|
||||
const dup = config.stream;
|
||||
let requestStream;
|
||||
const isGetRequest = (reqOpts.method || 'GET').toUpperCase() === 'GET';
|
||||
|
||||
if (isGetRequest) {
|
||||
requestStream = retryRequest(reqOpts, options);
|
||||
dup.setReadable(requestStream);
|
||||
} else {
|
||||
// Streaming writable HTTP requests cannot be retried.
|
||||
requestStream = request(reqOpts);
|
||||
dup.setWritable(requestStream);
|
||||
}
|
||||
|
||||
// Replay the Request events back to the stream.
|
||||
requestStream
|
||||
.on('error', dup.destroy.bind(dup))
|
||||
.on('response', dup.emit.bind(dup, 'response'))
|
||||
.on('complete', dup.emit.bind(dup, 'complete'));
|
||||
|
||||
dup.abort = requestStream.abort;
|
||||
} else {
|
||||
return retryRequest(reqOpts, options, function(err, response, body) {
|
||||
util.handleResp(err, response, body, callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
util.makeRequest = makeRequest;
|
||||
|
||||
/**
|
||||
* Decorate the options about to be made in a request.
|
||||
*
|
||||
* @param {object} reqOpts - The options to be passed to `request`.
|
||||
* @param {string} projectId - The project ID.
|
||||
* @return {object} reqOpts - The decorated reqOpts.
|
||||
*/
|
||||
function decorateRequest(reqOpts, projectId) {
|
||||
delete reqOpts.autoPaginate;
|
||||
delete reqOpts.autoPaginateVal;
|
||||
delete reqOpts.objectMode;
|
||||
|
||||
if (is.object(reqOpts.qs)) {
|
||||
delete reqOpts.qs.autoPaginate;
|
||||
delete reqOpts.qs.autoPaginateVal;
|
||||
reqOpts.qs = util.replaceProjectIdToken(reqOpts.qs, projectId);
|
||||
}
|
||||
|
||||
if (is.object(reqOpts.json)) {
|
||||
delete reqOpts.json.autoPaginate;
|
||||
delete reqOpts.json.autoPaginateVal;
|
||||
reqOpts.json = util.replaceProjectIdToken(reqOpts.json, projectId);
|
||||
}
|
||||
|
||||
reqOpts.uri = util.replaceProjectIdToken(reqOpts.uri, projectId);
|
||||
|
||||
return reqOpts;
|
||||
}
|
||||
|
||||
util.decorateRequest = decorateRequest;
|
||||
|
||||
/**
|
||||
* Populate the `{{projectId}}` placeholder.
|
||||
*
|
||||
* @throws {Error} If a projectId is required, but one is not provided.
|
||||
*
|
||||
* @param {*} - Any input value that may contain a placeholder. Arrays and
|
||||
* objects will be looped.
|
||||
* @param {string} projectId - A projectId. If not provided
|
||||
* @return {*} - The original argument with all placeholders populated.
|
||||
*/
|
||||
function replaceProjectIdToken(value, projectId) {
|
||||
if (is.array(value)) {
|
||||
value = value.map(function(val) {
|
||||
return replaceProjectIdToken(val, projectId);
|
||||
});
|
||||
}
|
||||
|
||||
if (is.object(value) && is.fn(value.hasOwnProperty)) {
|
||||
for (const opt in value) {
|
||||
if (value.hasOwnProperty(opt)) {
|
||||
value[opt] = replaceProjectIdToken(value[opt], projectId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is.string(value) && value.indexOf('{{projectId}}') > -1) {
|
||||
if (!projectId || projectId === '{{projectId}}') {
|
||||
throw new util.MissingProjectIdError();
|
||||
}
|
||||
value = value.replace(/{{projectId}}/g, projectId);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
util.replaceProjectIdToken = replaceProjectIdToken;
|
||||
|
||||
/**
|
||||
* Extend a global configuration object with user options provided at the time
|
||||
* of sub-module instantiation.
|
||||
*
|
||||
* Connection details currently come in two ways: `credentials` or
|
||||
* `keyFilename`. Because of this, we have a special exception when overriding a
|
||||
* global configuration object. If a user provides either to the global
|
||||
* configuration, then provides another at submodule instantiation-time, the
|
||||
* latter is preferred.
|
||||
*
|
||||
* @param {object} globalConfig - The global configuration object.
|
||||
* @param {object=} overrides - The instantiation-time configuration object.
|
||||
* @return {object}
|
||||
*/
|
||||
function extendGlobalConfig(globalConfig, overrides) {
|
||||
globalConfig = globalConfig || {};
|
||||
overrides = overrides || {};
|
||||
|
||||
const defaultConfig = {};
|
||||
|
||||
if (process.env.GCLOUD_PROJECT) {
|
||||
defaultConfig.projectId = process.env.GCLOUD_PROJECT;
|
||||
}
|
||||
|
||||
const options = extend({}, globalConfig);
|
||||
|
||||
const hasGlobalConnection = options.credentials || options.keyFilename;
|
||||
const isOverridingConnection = overrides.credentials || overrides.keyFilename;
|
||||
|
||||
if (hasGlobalConnection && isOverridingConnection) {
|
||||
delete options.credentials;
|
||||
delete options.keyFilename;
|
||||
}
|
||||
|
||||
const extendedConfig = extend(true, defaultConfig, options, overrides);
|
||||
|
||||
// Preserve the original (not cloned) interceptors.
|
||||
extendedConfig.interceptors_ = globalConfig.interceptors_;
|
||||
|
||||
return extendedConfig;
|
||||
}
|
||||
|
||||
util.extendGlobalConfig = extendGlobalConfig;
|
||||
|
||||
/**
|
||||
* Merge and validate API configurations.
|
||||
*
|
||||
* @param {object} globalContext - gcloud-level context.
|
||||
* @param {object} globalContext.config_ - gcloud-level configuration.
|
||||
* @param {object} localConfig - Service-level configurations.
|
||||
* @return {object} config - Merged and validated configuration.
|
||||
*/
|
||||
function normalizeArguments(globalContext, localConfig) {
|
||||
const globalConfig = globalContext && globalContext.config_;
|
||||
|
||||
return util.extendGlobalConfig(globalConfig, localConfig);
|
||||
}
|
||||
|
||||
util.normalizeArguments = normalizeArguments;
|
||||
|
||||
/**
|
||||
* Limit requests according to a `maxApiCalls` limit.
|
||||
*
|
||||
* @param {function} makeRequestFn - The function that will be called.
|
||||
* @param {object=} options - Configuration object.
|
||||
* @param {number} options.maxApiCalls - The maximum number of API calls to
|
||||
* make.
|
||||
* @param {object} options.streamOptions - Options to pass to the Stream
|
||||
* constructor.
|
||||
*/
|
||||
function createLimiter(makeRequestFn, options) {
|
||||
options = options || {};
|
||||
|
||||
const stream = streamEvents(through.obj(options.streamOptions));
|
||||
|
||||
let requestsMade = 0;
|
||||
let requestsToMake = -1;
|
||||
|
||||
if (is.number(options.maxApiCalls)) {
|
||||
requestsToMake = options.maxApiCalls;
|
||||
}
|
||||
|
||||
return {
|
||||
makeRequest: function() {
|
||||
requestsMade++;
|
||||
|
||||
if (requestsToMake >= 0 && requestsMade > requestsToMake) {
|
||||
stream.push(null);
|
||||
return;
|
||||
}
|
||||
|
||||
makeRequestFn.apply(null, arguments);
|
||||
|
||||
return stream;
|
||||
},
|
||||
|
||||
stream: stream,
|
||||
};
|
||||
}
|
||||
|
||||
util.createLimiter = createLimiter;
|
||||
|
||||
function isCustomType(unknown, module) {
|
||||
function getConstructorName(obj) {
|
||||
return obj.constructor && obj.constructor.name.toLowerCase();
|
||||
}
|
||||
|
||||
const moduleNameParts = module.split('/');
|
||||
|
||||
const parentModuleName =
|
||||
moduleNameParts[0] && moduleNameParts[0].toLowerCase();
|
||||
const subModuleName = moduleNameParts[1] && moduleNameParts[1].toLowerCase();
|
||||
|
||||
if (subModuleName && getConstructorName(unknown) !== subModuleName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let walkingModule = unknown;
|
||||
do {
|
||||
if (getConstructorName(walkingModule) === parentModuleName) {
|
||||
return true;
|
||||
}
|
||||
} while ((walkingModule = walkingModule.parent));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
util.isCustomType = isCustomType;
|
||||
|
||||
/**
|
||||
* Create a properly-formatted User-Agent string from a package.json file.
|
||||
*
|
||||
* @param {object} packageJson - A module's package.json file.
|
||||
* @return {string} userAgent - The formatted User-Agent string.
|
||||
*/
|
||||
function getUserAgentFromPackageJson(packageJson) {
|
||||
const hyphenatedPackageName = packageJson.name
|
||||
.replace('@google-cloud', 'gcloud-node') // For legacy purposes.
|
||||
.replace('/', '-'); // For UA spec-compliance purposes.
|
||||
|
||||
return hyphenatedPackageName + '/' + packageJson.version;
|
||||
}
|
||||
|
||||
util.getUserAgentFromPackageJson = getUserAgentFromPackageJson;
|
||||
|
||||
/**
|
||||
* Wraps a callback style function to conditionally return a promise.
|
||||
*
|
||||
* @param {function} originalMethod - The method to promisify.
|
||||
* @param {object=} options - Promise options.
|
||||
* @param {boolean} options.singular - Resolve the promise with single arg
|
||||
* instead of an array.
|
||||
* @return {function} wrapped
|
||||
*/
|
||||
function promisify(originalMethod, options) {
|
||||
if (originalMethod.promisified_) {
|
||||
return originalMethod;
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
const slice = Array.prototype.slice;
|
||||
|
||||
const wrapper = function() {
|
||||
const context = this;
|
||||
let last;
|
||||
|
||||
for (last = arguments.length - 1; last >= 0; last--) {
|
||||
const arg = arguments[last];
|
||||
|
||||
if (is.undefined(arg)) {
|
||||
continue; // skip trailing undefined.
|
||||
}
|
||||
|
||||
if (!is.fn(arg)) {
|
||||
break; // non-callback last argument found.
|
||||
}
|
||||
|
||||
return originalMethod.apply(context, arguments);
|
||||
}
|
||||
|
||||
// peel trailing undefined.
|
||||
const args = slice.call(arguments, 0, last + 1);
|
||||
|
||||
let PromiseCtor = Promise;
|
||||
|
||||
// Because dedupe will likely create a single install of
|
||||
// @google-cloud/common to be shared amongst all modules, we need to
|
||||
// localize it at the Service level.
|
||||
if (context && context.Promise) {
|
||||
PromiseCtor = context.Promise;
|
||||
}
|
||||
|
||||
return new PromiseCtor(function(resolve, reject) {
|
||||
args.push(function() {
|
||||
const callbackArgs = slice.call(arguments);
|
||||
const err = callbackArgs.shift();
|
||||
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
if (options.singular && callbackArgs.length === 1) {
|
||||
resolve(callbackArgs[0]);
|
||||
} else {
|
||||
resolve(callbackArgs);
|
||||
}
|
||||
});
|
||||
|
||||
originalMethod.apply(context, args);
|
||||
});
|
||||
};
|
||||
|
||||
wrapper.promisified_ = true;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
util.promisify = promisify;
|
||||
|
||||
/**
|
||||
* Promisifies certain Class methods. This will not promisify private or
|
||||
* streaming methods.
|
||||
*
|
||||
* @param {module:common/service} Class - Service class.
|
||||
* @param {object=} options - Configuration object.
|
||||
*/
|
||||
function promisifyAll(Class, options) {
|
||||
const exclude = (options && options.exclude) || [];
|
||||
|
||||
const methods = Object.keys(Class.prototype).filter(function(methodName) {
|
||||
return (
|
||||
is.fn(Class.prototype[methodName]) && // is it a function?
|
||||
!/(^_|(Stream|_)|promise$)/.test(methodName) && // is it promisable?
|
||||
exclude.indexOf(methodName) === -1
|
||||
); // is it blacklisted?
|
||||
});
|
||||
|
||||
methods.forEach(function(methodName) {
|
||||
const originalMethod = Class.prototype[methodName];
|
||||
|
||||
if (!originalMethod.promisified_) {
|
||||
Class.prototype[methodName] = util.promisify(originalMethod, options);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
util.promisifyAll = promisifyAll;
|
||||
|
||||
/**
|
||||
* This will mask properties of an object from console.log.
|
||||
*
|
||||
* @param {object} object - The object to assign the property to.
|
||||
* @param {string} propName - Property name.
|
||||
* @param {*} value - Value.
|
||||
*/
|
||||
function privatize(object, propName, value) {
|
||||
Object.defineProperty(object, propName, {value, writable: true});
|
||||
}
|
||||
|
||||
util.privatize = privatize;
|
Reference in New Issue
Block a user