@google-cloud/logging
Version:
Cloud Logging Client Library for Node.js
255 lines • 7.93 kB
JavaScript
;
/*!
* 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.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ObjectToStructConverter = void 0;
exports.objToStruct = objToStruct;
exports.structToObj = structToObj;
exports.decodeValue = decodeValue;
exports.zuluToDateObj = zuluToDateObj;
exports.toNanosAndSecondsObj = toNanosAndSecondsObj;
function objToStruct(obj, options) {
return new ObjectToStructConverter(options).convert(obj);
}
class ObjectToStructConverter {
/**
* A class that can be used to convert an object to a struct. Optionally this
* class can be used to erase/throw on circular references during conversion.
*
* @private
*
* @param {object=} options - Configuration object.
* @param {boolean} options.removeCircular - Remove circular references in the
* object with a placeholder string. (Default: `false`)
* @param {boolean} options.stringify - Stringify un-recognized types. (Default:
* `false`)
*/
constructor(options) {
options = options || {};
this.seenObjects = new Set();
this.removeCircular = options.removeCircular === true;
this.stringify = options.stringify === true;
}
/**
* Begin the conversion process from a JS object to an encoded gRPC Value
* message.
*
* @param {*} value - The input value.
* @return {object} - The encoded value.
*
* @example
* ```
* ObjectToStructConverter.convert({
* aString: 'Hi'
* });
* // {
* // fields: {
* // aString: {
* // stringValue: 'Hello!'
* // }
* // }
* // }
* ```
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
convert(obj) {
const convertedObject = {
fields: {},
};
this.seenObjects.add(obj);
for (const prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
const value = obj[prop];
if (value === undefined) {
continue;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
convertedObject.fields[prop] = this.encodeValue_(value);
}
}
this.seenObjects.delete(obj);
return convertedObject;
}
/**
* Convert a raw value to a type-denoted protobuf message-friendly object.
*
* @private
*
* @param {*} value - The input value.
* @return {*} - The encoded value.
*
* @example
* ```
* ObjectToStructConverter.encodeValue('Hi');
* // {
* // stringValue: 'Hello!'
* // }
* ```
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
encodeValue_(value) {
let convertedValue;
if (value === null) {
convertedValue = {
nullValue: 0,
};
}
else if (typeof value === 'number') {
convertedValue = {
numberValue: value,
};
}
else if (typeof value === 'string') {
convertedValue = {
stringValue: value,
};
}
else if (typeof value === 'boolean') {
convertedValue = {
boolValue: value,
};
}
else if (Buffer.isBuffer(value)) {
convertedValue = {
blobValue: value,
};
}
else if (Array.isArray(value)) {
convertedValue = {
listValue: {
values: value.map(this.encodeValue_.bind(this)),
},
};
}
else if (Object.prototype.toString.call(value) === '[object Object]') {
if (this.seenObjects.has(value)) {
// Circular reference.
if (!this.removeCircular) {
throw new Error([
'This object contains a circular reference. To automatically',
'remove it, set the `removeCircular` option to true.',
].join(' '));
}
convertedValue = {
stringValue: '[Circular]',
};
}
else {
convertedValue = {
structValue: this.convert(value),
};
}
}
else {
if (!this.stringify) {
throw new Error('Value of type ' + typeof value + ' not recognized.');
}
convertedValue = {
stringValue: String(value),
};
}
return convertedValue;
}
}
exports.ObjectToStructConverter = ObjectToStructConverter;
/**
* Condense a protobuf Struct into an object of only its values.
*
* @private
*
* @param {object} struct - A protobuf Struct message.
* @return {object} - The simplified object.
*
* @example
* ```
* GrpcService.structToObj_({
* fields: {
* name: {
* kind: 'stringValue',
* stringValue: 'Stephen'
* }
* }
* });
* // {
* // name: 'Stephen'
* // }
* ```
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function structToObj(struct) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const convertedObject = {};
for (const prop in struct.fields) {
// eslint-disable-next-line no-prototype-builtins
if (struct.fields.hasOwnProperty(prop)) {
const value = struct.fields[prop];
convertedObject[prop] = decodeValue(value);
}
}
return convertedObject;
}
/**
* Decode a protobuf Struct's value.
*
* @param {object} value - A Struct's Field message.
* @return {*} - The decoded value.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function decodeValue(value) {
switch (value.kind) {
case 'structValue': {
return structToObj(value.structValue);
}
case 'nullValue': {
return null;
}
case 'listValue': {
return value.listValue.values.map(decodeValue);
}
default: {
return value[value.kind];
}
}
}
/**
* zuluToDateObj RFC3339 "Zulu" timestamp into a format that can be parsed to
* a JS Date Object.
* @param zuluTime
*/
function zuluToDateObj(zuluTime) {
var _a;
const ms = Date.parse(zuluTime.split(/[.,Z]/)[0] + 'Z');
const reNano = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.(\d{0,9})Z$/;
const nanoSecs = (_a = zuluTime.match(reNano)) === null || _a === void 0 ? void 0 : _a[1];
return {
seconds: ms ? Math.floor(ms / 1000) : 0,
nanos: nanoSecs ? Number(nanoSecs.padEnd(9, '0')) : 0,
};
}
/**
* Converts Date to nanoseconds format suported by Logging.
* See https://cloud.google.com/logging/docs/agent/logging/configuration#timestamp-processing for more details
* @param date The date to be converted to Logging nanos and seconds format
*/
function toNanosAndSecondsObj(date) {
const seconds = date.getTime() / 1000;
const secondsRounded = Math.floor(seconds);
return {
seconds: secondsRounded,
nanos: Math.floor((seconds - secondsRounded) * 1e9),
};
}
//# sourceMappingURL=common.js.map