balena-sdk
Version:
The Balena JavaScript SDK
109 lines (108 loc) • 5.25 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.batchResourceOperationFactory = batchResourceOperationFactory;
const tslib_1 = require("tslib");
const errors = tslib_1.__importStar(require("balena-errors"));
const chunk_1 = tslib_1.__importDefault(require("lodash/chunk"));
const _1 = require(".");
const NUMERIC_ID_CHUNK_SIZE = 200;
const STRING_ID_CHUNK_SIZE = 50;
function batchResourceOperationFactory({ getAll, NotFoundError, AmbiguousResourceError, chunkSize: chunkSizeParam, }) {
var _a, _b;
const chunkSize = typeof chunkSizeParam === 'number'
? {
numericId: chunkSizeParam,
stringId: chunkSizeParam,
}
: {
numericId: (_a = chunkSizeParam === null || chunkSizeParam === void 0 ? void 0 : chunkSizeParam.numericId) !== null && _a !== void 0 ? _a : NUMERIC_ID_CHUNK_SIZE,
stringId: (_b = chunkSizeParam === null || chunkSizeParam === void 0 ? void 0 : chunkSizeParam.stringId) !== null && _b !== void 0 ? _b : STRING_ID_CHUNK_SIZE,
};
async function batchResourceOperation({ uuidOrIdOrArray, parameterName = 'uuidOrIdOrArray', options, groupByNavigationPoperty, fn, }) {
if (uuidOrIdOrArray === '') {
throw new errors.BalenaInvalidParameterError(parameterName, uuidOrIdOrArray);
}
if (Array.isArray(uuidOrIdOrArray)) {
if (!uuidOrIdOrArray.length) {
throw new errors.BalenaInvalidParameterError(parameterName, uuidOrIdOrArray);
}
let lastType = typeof uuidOrIdOrArray[0];
for (const param of uuidOrIdOrArray) {
const type = typeof param;
if (type !== 'number' && type !== 'string') {
throw new errors.BalenaInvalidParameterError('uuidOrIdOrArray', uuidOrIdOrArray);
}
if (lastType !== type) {
throw new errors.BalenaInvalidParameterError('uuidOrIdOrArray', uuidOrIdOrArray);
}
if (typeof param === 'string' &&
param.length !== 32 &&
param.length !== 62) {
throw new errors.BalenaInvalidParameterError('uuidOrIdOrArray', uuidOrIdOrArray);
}
lastType = type;
}
}
// create a list of UUIDs or chunks of IDs
const chunks = !Array.isArray(uuidOrIdOrArray)
? [uuidOrIdOrArray]
: typeof uuidOrIdOrArray[0] === 'string'
? (0, chunk_1.default)(uuidOrIdOrArray, chunkSize.stringId)
: (0, chunk_1.default)(uuidOrIdOrArray, chunkSize.numericId);
const items = [];
for (const uuidOrIdOrArrayChunk of chunks) {
const resourceFilter = Array.isArray(uuidOrIdOrArrayChunk)
? typeof uuidOrIdOrArrayChunk[0] === 'string'
? {
uuid: { $in: uuidOrIdOrArrayChunk },
}
: {
id: { $in: uuidOrIdOrArrayChunk },
}
: typeof uuidOrIdOrArrayChunk === 'string'
? {
uuid: { $startswith: uuidOrIdOrArrayChunk },
}
: {
id: uuidOrIdOrArrayChunk,
};
const combinedOptions = (0, _1.mergePineOptions)({
$select: [
'id',
...(Array.isArray(uuidOrIdOrArrayChunk) &&
typeof uuidOrIdOrArrayChunk[0] === 'string'
? ['uuid']
: []),
...(groupByNavigationPoperty ? [groupByNavigationPoperty] : []),
],
$filter: resourceFilter,
}, options);
items.push(...(await getAll(combinedOptions)));
}
if (!items.length) {
throw new NotFoundError(uuidOrIdOrArray.toString());
}
const itemsByAccosiactedResource = groupByNavigationPoperty
? (0, _1.groupByMap)(items, (item) => item[groupByNavigationPoperty].__id)
: new Map([[undefined, items]]);
if (typeof uuidOrIdOrArray === 'string' && items.length > 1) {
throw new AmbiguousResourceError(uuidOrIdOrArray);
}
else if (Array.isArray(uuidOrIdOrArray)) {
const identifierProperty = typeof uuidOrIdOrArray[0] === 'string' ? 'uuid' : 'id';
const resourceIdentifiers = items.map((item) => item[identifierProperty]);
const resourceIdsSet = new Set(resourceIdentifiers);
for (const identifier of uuidOrIdOrArray) {
if (!resourceIdsSet.has(identifier)) {
throw new NotFoundError(identifier);
}
}
}
for (const [associatedResourceId, associatedItems,] of itemsByAccosiactedResource.entries()) {
for (const chunkedAssociatedItems of (0, chunk_1.default)(associatedItems, chunkSize.numericId)) {
await fn(chunkedAssociatedItems, associatedResourceId);
}
}
}
return batchResourceOperation;
}