1 | const ddb = require("./aws/ddb/internal");
|
2 | const utils = require("./utils");
|
3 | const Error = require("./Error");
|
4 | const ModelStore = require("./ModelStore");
|
5 |
|
6 | module.exports = (transactions, settings = {}, callback) => {
|
7 | if (typeof settings === "function") {
|
8 | callback = settings;
|
9 | settings = {};
|
10 | }
|
11 | if (typeof transactions === "function") {
|
12 | callback = transactions;
|
13 | transactions = null;
|
14 | }
|
15 |
|
16 | const promise = (async () => {
|
17 | if (!Array.isArray(transactions) || transactions.length <= 0) {
|
18 | throw new Error.InvalidParameter("You must pass in an array with items for the transactions parameter.");
|
19 | }
|
20 |
|
21 | const transactionObjects = await Promise.all(transactions);
|
22 |
|
23 | const transactionParams = {
|
24 | "TransactItems": transactionObjects
|
25 | };
|
26 |
|
27 | if (settings.return === "request") {
|
28 | return transactionParams;
|
29 | }
|
30 |
|
31 | let transactionType;
|
32 | if (settings.type) {
|
33 | switch (settings.type) {
|
34 | case "get":
|
35 | transactionType = "transactGetItems";
|
36 | break;
|
37 | case "write":
|
38 | transactionType = "transactWriteItems";
|
39 | break;
|
40 | default:
|
41 | throw new Error.InvalidParameter("Invalid type option, please pass in \"get\" or \"write\".");
|
42 | }
|
43 | } else {
|
44 | transactionType = transactionObjects.map((a) => Object.keys(a)[0]).every((key) => key === "Get") ? "transactGetItems" : "transactWriteItems";
|
45 | }
|
46 |
|
47 | const modelNames = transactionObjects.map((a) => Object.values(a)[0].TableName);
|
48 | const uniqueModelNames = utils.unique_array_elements(modelNames);
|
49 | const models = uniqueModelNames.map((name) => ModelStore(name));
|
50 | models.forEach((model, index) => {
|
51 | if (!model) {
|
52 | throw new Error.InvalidParameter(`Model "${uniqueModelNames[index]}" not found. Please register the model with dynamoose before using it in transactions.`);
|
53 | }
|
54 | });
|
55 | await Promise.all(models.map((model) => model.pendingTaskPromise()));
|
56 |
|
57 | const result = await ddb(transactionType, transactionParams);
|
58 | return result.Responses ? await Promise.all(result.Responses.map((item, index) => {
|
59 | const modelName = modelNames[index];
|
60 | const model = models.find((model) => model.name === modelName);
|
61 | return (new model.Document(item.Item, {"fromDynamo": true})).conformToSchema({"customTypesDynamo": true, "checkExpiredItem": true, "saveUnknown": true, "type": "fromDynamo"});
|
62 | })) : null;
|
63 | })();
|
64 |
|
65 | if (callback) {
|
66 | promise.then((result) => callback(null, result)).catch((error) => callback(error));
|
67 | } else {
|
68 | return promise;
|
69 | }
|
70 | };
|