Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 1x 1x 1x 1x 98x 78x 78x 78x 78x 1x 77x 29x 1x 5x 4x 3x 3x 2x 2x 2x 4x 1x 1x 3x 2x 6x 12x 12x 12x | const google = require('./adapters/google');
const utils = require('./utils');
const processors = exports;
// Simplifies manipulating deep object paths
/**
* @template T
* @param {T} object
* @returns {Promise<T>}
*/
processors.processPath = async (
/** @type {T} */ object,
/** @type {string} */ path,
/** @type {(value: any) => Promise<any>} */ processor,
) => {
if (object == null) return object;
const [firstKey, ...remainingKeys] = path.split('.');
const isMapOperation = firstKey.endsWith('[]');
const normalizedKey = firstKey.replace('[]', '');
if (remainingKeys.length === 0) {
return {
...object[normalizedKey],
[normalizedKey]: await processor(object[normalizedKey]),
};
}
return {
...object,
[normalizedKey]: await (object[normalizedKey] && isMapOperation
? Promise.all(
object[normalizedKey].map((value) =>
processors.processPath(value, remainingKeys.join('.'), processor),
),
)
: processors.processPath(
object[normalizedKey],
remainingKeys.join('.'),
processor,
)),
};
};
processors.processData = async (
/** @type {Record<string, import('./types').Datasource>} */ datasources,
) => {
if (!datasources) return {};
const data = await Promise.all(
Object.keys(datasources).map(async (key) => {
const datasource = datasources[key];
if (utils.isGoogleSheet(datasource.url)) {
// NOTE: If we ever need to support multiple ranges we can use `spreadsheets.values.batchGet`
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchGet
// We can build an object with sparse fields based on the longest of the resulting arrays
const result = await google.sheets.spreadsheets.values.get({
spreadsheetId: utils.getSheetIdByUrl(datasource.url),
range: datasource.options.range,
});
const [columns, ...rowsOfCells] = result.data.values;
return {
[key]: rowsOfCells.map(
toRowObject(
columns.map(
(column) => (datasource.options.columns || {})[column] || column,
),
),
),
};
} else {
throw {
response: {
status: 400,
body: `Unsupported datasource URL: ${datasource.url}`,
},
toString() {
return this.response.body;
},
};
}
}),
);
return Object.assign({}, ...data); // Merges the array of objects into each other - `{ ...data }` is not the same!
};
function toRowObject(/** @type {string[]} */ columns) {
return (/** @type {string[]} */ cells) => {
return columns.reduce(
(row, column, index) => ({ ...row, [column]: parseValue(cells[index]) }),
{},
);
};
}
function parseValue(value) {
const valueAsNumber = Number(value);
return isNaN(valueAsNumber) || value === '' ? value : valueAsNumber;
}
|