google-ads-node
Version:
Google Ads gRPC Client Library for Node
219 lines • 16.9 kB
JavaScript
;
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const protobufHelpers = __importStar(require("google-protobuf/google/protobuf/field_mask_pb"));
const lodash_camelcase_1 = __importDefault(require("lodash.camelcase"));
const lodash_get_1 = __importDefault(require("lodash.get"));
const lodash_set_1 = __importDefault(require("lodash.set"));
const structs = __importStar(require("./struct"));
// Based on https://github.com/leaves4j/grpc-promisify/blob/master/src/index.js
function promisifyServiceClient(client) {
Object.keys(Object.getPrototypeOf(client)).forEach((functionName) => {
if (functionName.charAt(0) === "$" || functionName.charAt(0) === "_") {
return;
}
const originalFunction = client[functionName];
client[functionName] = (request, callback) => {
if (callback && typeof callback === "function") {
return originalFunction.call(client, request, (error, response) => {
callback(error, response);
});
}
return new Promise((resolve, reject) => {
originalFunction.call(client, request, (error, response) => {
if (error) {
reject(error);
}
else {
resolve(response);
}
});
});
};
});
}
exports.promisifyServiceClient = promisifyServiceClient;
function formatCallResults(resultsList, fieldMask) {
const parsedResults = [];
if (fieldMask) {
const { pathsList } = fieldMask;
for (const result of resultsList) {
const parsedRow = parseNestedEntities(result, pathsList);
parsedResults.push(parsedRow);
}
}
else {
for (const result of resultsList) {
const parsedRow = parseNestedEntitiesNoPath(result);
parsedResults.push(parsedRow);
}
}
return parsedResults;
}
exports.formatCallResults = formatCallResults;
function convertToProtoFormat(data, type, resource_name, nested_path = "") {
const pb = {};
const struct = structs[resource_name];
if (!struct) {
throw new Error(`Key "${nested_path.replace(".", "")}" not found in resource "${resource_name}"`);
}
for (const key of Object.keys(data)) {
const displayKey = lodash_camelcase_1.default(key);
const value = data[key];
/* Resource names are string values, not a protobuf string instance, so just set the string value */
if (displayKey === "resourceName") {
pb[displayKey] = value;
continue;
}
/* Build array of proto values */
if (Array.isArray(value)) {
pb[displayKey] = value.map((v) => {
return unroll(v);
});
continue;
}
pb[displayKey] = unroll(value);
function unroll(v) {
return typeof v === "object"
? convertToProtoFormat(v, type, resource_name, `${nested_path}.${key}`)
: toProtoValueFormat(v, struct, `${nested_path}.${key}`.replace(".", ""));
}
}
return pb;
}
exports.convertToProtoFormat = convertToProtoFormat;
function toProtoValueFormat(value, struct, nested_path) {
const valueType = lodash_get_1.default(struct, nested_path);
if (!valueType) {
throw new Error(`Attempted to set value "${value}" on invalid path "${nested_path}" in resource`);
}
if (valueType.startsWith("enum_")) {
return value;
}
return {
value,
};
}
/* This is different to lodash.camelCase as it leaves any periods (".") */
function convertPathToCamelCase(str) {
return str.replace(/([-_][a-z])/gi, $1 => {
return $1
.toUpperCase()
.replace("-", "")
.replace("_", "");
});
}
function parseNestedEntitiesNoPath(data) {
if (typeof data === "string" || typeof data === "number" || typeof data === "boolean") {
return data;
}
const finalObject = {};
Object.keys(data).map(key => {
let displayKey = key;
if (key.endsWith("List")) {
displayKey = key.split("List")[0];
}
const entity = data[key];
const isObject = typeof entity === "object";
const isUndefined = typeof entity === "undefined";
const isArray = Array.isArray(entity);
const isValue = isObject ? entity.hasOwnProperty("value") : false;
if (isUndefined) {
return;
}
if (isArray) {
finalObject[displayKey] = entity.map((item) => {
const parsed = parseNestedEntitiesNoPath({ item });
return parsed.item;
});
}
else if (isValue) {
finalObject[displayKey] = entity.value;
}
else if (isObject) {
finalObject[displayKey] = parseNestedEntitiesNoPath(entity);
}
else {
finalObject[displayKey] = entity;
}
});
return finalObject;
}
// This function first parses the data without regard for the passed props,
// then plucks out the props that it actually cares about.
function parseNestedEntities(data, props) {
const parsed_data = parseNestedEntitiesNoPath(data);
const final_object = {};
for (let path of props) {
path = convertPathToCamelCase(path);
// Pluck resource name if available
const path_elements_trimmed = path.split(".");
while (path_elements_trimmed.pop()) {
path_elements_trimmed.push("resourceName");
const rn_path = path_elements_trimmed.join(".");
path_elements_trimmed.pop();
if (lodash_get_1.default(parsed_data, rn_path)) {
lodash_set_1.default(final_object, rn_path, lodash_get_1.default(parsed_data, rn_path));
}
}
// And pluck the field specified in path
const plucked_value = lodash_get_1.default(parsed_data, path);
if (typeof plucked_value !== "undefined") {
lodash_set_1.default(final_object, path, plucked_value);
}
}
return final_object;
}
function recursiveFieldMaskSearch(data) {
const paths = [];
for (const key of Object.keys(data)) {
if (key === "resource_name") {
continue;
}
const value = data[key];
if (typeof value === "object" && !Array.isArray(value)) {
const children = recursiveFieldMaskSearch(value);
for (const child of children) {
paths.push(`${key}.${child}`);
}
continue;
}
paths.push(key);
}
return paths;
}
function getFieldMask(data) {
const fieldMask = new protobufHelpers.FieldMask();
const paths = recursiveFieldMaskSearch(data);
fieldMask.setPathsList(paths);
return fieldMask;
}
exports.getFieldMask = getFieldMask;
function getErrorLocationPath(location) {
if (!location || !location.hasOwnProperty("fieldPathElementsList")) {
return "";
}
if (!Array.isArray(location.fieldPathElementsList) && location.fieldPathElementsList.length < 1) {
return "";
}
const { fieldPathElementsList } = location;
const paths = fieldPathElementsList.map((field) => {
let path = field.fieldName;
if (field.index && field.index.hasOwnProperty("value")) {
path += `[${field.index.value}]`;
}
return path;
});
return paths.join(".");
}
exports.getErrorLocationPath = getErrorLocationPath;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLCtGQUFpRjtBQUVqRix3RUFBeUM7QUFDekMsNERBQTZCO0FBQzdCLDREQUE2QjtBQUU3QixrREFBb0M7QUFFcEMsK0VBQStFO0FBQy9FLFNBQWdCLHNCQUFzQixDQUFDLE1BQWM7SUFDbkQsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsWUFBb0IsRUFBRSxFQUFFO1FBQzFFLElBQUksWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUU7WUFDcEUsT0FBTztTQUNSO1FBQ0QsTUFBTSxnQkFBZ0IsR0FBSSxNQUFjLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFdEQsTUFBYyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsT0FBWSxFQUFFLFFBQWEsRUFBRSxFQUFFO1lBQzlELElBQUksUUFBUSxJQUFJLE9BQU8sUUFBUSxLQUFLLFVBQVUsRUFBRTtnQkFDOUMsT0FBTyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDLEtBQVUsRUFBRSxRQUFhLEVBQUUsRUFBRTtvQkFDMUUsUUFBUSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDNUIsQ0FBQyxDQUFDLENBQUM7YUFDSjtZQUVELE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQ3JDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUMsS0FBVSxFQUFFLFFBQWEsRUFBRSxFQUFFO29CQUNuRSxJQUFJLEtBQUssRUFB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