|
| 1 | +"use strict"; |
| 2 | +Object.defineProperty(exports, "__esModule", { value: true }); |
| 3 | +exports.BatchPutOperation = void 0; |
| 4 | +const glob = require("@actions/glob"); |
| 5 | +const Joi = require("@hapi/joi"); |
| 6 | +const fs_1 = require("fs"); |
| 7 | +const helpers_1 = require("../helpers"); |
| 8 | +const BaseInputSchema = Joi.object({ |
| 9 | + operation: Joi.string().lowercase().valid("batch-put").required(), |
| 10 | + region: Joi.string().lowercase().required(), |
| 11 | + table: Joi.string().required(), |
| 12 | +}); |
| 13 | +const InputSchema = Joi.alternatives([ |
| 14 | + BaseInputSchema.append({ |
| 15 | + items: Joi.array().items(Joi.object().required()).min(1).required(), |
| 16 | + }), |
| 17 | + BaseInputSchema.append({ |
| 18 | + files: Joi.string().required(), |
| 19 | + }), |
| 20 | +]).required(); |
| 21 | +class BatchPutOperation { |
| 22 | + constructor() { |
| 23 | + this.name = "batch-put"; |
| 24 | + } |
| 25 | + async validate(input) { |
| 26 | + const validationResult = InputSchema.validate(input, { |
| 27 | + stripUnknown: true, |
| 28 | + }); |
| 29 | + if (validationResult.error) { |
| 30 | + throw validationResult.error; |
| 31 | + } |
| 32 | + return validationResult.value; |
| 33 | + } |
| 34 | + async execute(input) { |
| 35 | + var _a, _b; |
| 36 | + const ddb = helpers_1.createClient(input.region); |
| 37 | + const items = input.items || await this.read(input.files); |
| 38 | + const chunks = this.chunk(items, 20); |
| 39 | + for (const chunk of chunks) { |
| 40 | + const res = await ddb.batchWrite({ |
| 41 | + RequestItems: { |
| 42 | + [input.table]: chunk.map((item) => ({ |
| 43 | + PutRequest: { |
| 44 | + Item: item, |
| 45 | + }, |
| 46 | + })), |
| 47 | + }, |
| 48 | + }).promise(); |
| 49 | + const failedItems = (_b = (_a = res.UnprocessedItems) === null || _a === void 0 ? void 0 : _a[input.table]) !== null && _b !== void 0 ? _b : []; |
| 50 | + if (failedItems.length > 0) { |
| 51 | + console.error("UnprocessedItems: ", res.UnprocessedItems); // tslint:disable-line |
| 52 | + throw new Error("Got UnprocessedItems from DynamoDB"); |
| 53 | + } |
| 54 | + } |
| 55 | + } |
| 56 | + async read(globs) { |
| 57 | + const globber = await glob.create(globs); |
| 58 | + const files = await globber.glob(); |
| 59 | + if (files.length === 0) { |
| 60 | + throw new Error("Given glob does not match any files"); |
| 61 | + } |
| 62 | + return Promise.all(files.map(async (file) => { |
| 63 | + const content = await fs_1.promises.readFile(file, { encoding: "utf8" }); |
| 64 | + return JSON.parse(content); |
| 65 | + })); |
| 66 | + } |
| 67 | + chunk(items, size) { |
| 68 | + return items.reduce((collection, item) => { |
| 69 | + const lastChunk = collection[collection.length - 1]; |
| 70 | + if (lastChunk.length < 20) { |
| 71 | + lastChunk.push(item); |
| 72 | + } |
| 73 | + else { |
| 74 | + collection.push([item]); |
| 75 | + } |
| 76 | + return collection; |
| 77 | + }, [[]]); |
| 78 | + } |
| 79 | +} |
| 80 | +exports.BatchPutOperation = BatchPutOperation; |
0 commit comments