Skip to content

Commit 64a2b28

Browse files
authored
add support for array splitting in action responses and improve logging (#47)
add support for array splitting in action responses and improve logging
1 parent 96ee159 commit 64a2b28

1 file changed

Lines changed: 69 additions & 15 deletions

File tree

templates/lib/actions/action.js

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@
1212
*/
1313

1414
const spec = require("../spec.json");
15-
const { mapFieldNames, getMetadata, mapFormDataBody, putAdditionalParamsInBody, executeCall, formatApiKey } = require("../utils/helpers");
15+
const {
16+
mapFieldNames,
17+
getMetadata,
18+
mapFormDataBody,
19+
putAdditionalParamsInBody,
20+
executeCall,
21+
formatApiKey,
22+
} = require("../utils/helpers");
1623
const componentJson = require("../../component.json");
1724

1825
async function processAction(msg, cfg, snapshot, incomingMessageHeaders, tokenData) {
@@ -23,7 +30,6 @@ async function processAction(msg, cfg, snapshot, incomingMessageHeaders, tokenDa
2330
if (cfg && cfg.nodeSettings && cfg.nodeSettings.continueOnError) continueOnError = true;
2431

2532
try {
26-
2733
if (["fatal", "error", "warn", "info", "debug", "trace"].includes(logLevel)) {
2834
logger = this.logger.child({});
2935
logger.level && logger.level(logLevel);
@@ -114,31 +120,79 @@ async function processAction(msg, cfg, snapshot, incomingMessageHeaders, tokenDa
114120
delete callParams.requestBody;
115121
}
116122

117-
118123
const resp = await executeCall.call(this, callParams);
119124

120125
// Wait for rate limit if specified
121-
const rateLimit = cfg.nodeSettings && cfg.nodeSettings.rateLimit ? parseInt(cfg.nodeSettings.rateLimit) : (Number.isInteger(componentJson.rateLimit) ? componentJson.rateLimit : 0);
126+
const rateLimit =
127+
cfg.nodeSettings && cfg.nodeSettings.rateLimit
128+
? parseInt(cfg.nodeSettings.rateLimit)
129+
: Number.isInteger(componentJson.rateLimit)
130+
? componentJson.rateLimit
131+
: 0;
122132
if (rateLimit > 0) {
123133
this.logger.info(`Waiting for rate limit: ${rateLimit} ms`);
124-
await new Promise(resolve => setTimeout(resolve, rateLimit));
134+
await new Promise((resolve) => setTimeout(resolve, rateLimit));
125135
}
126136

127-
const newElement = {};
128-
newElement.metadata = getMetadata(msg.metadata);
129-
newElement.data = resp.body;
137+
const responseBody = resp.body;
138+
const { arraySplittingKey } = cfg.nodeSettings;
139+
140+
if (arraySplittingKey && !cfg.returnResult) {
141+
if (Array.isArray(responseBody)) {
142+
logger.info(`Response is an array with ${responseBody.length} items. Emitting each element separately.`);
143+
responseBody.forEach((item, index) => {
144+
this.emit("data", {
145+
data: item,
146+
metadata: getMetadata(msg.metadata),
147+
});
148+
logger.info(`Emitted array item at index ${index}`);
149+
});
150+
} else if (responseBody && typeof responseBody === "object") {
151+
logger.info(`Response is an object. Resolving nested path "${arraySplittingKey}".`);
152+
const splitArray = arraySplittingKey
153+
.split(".")
154+
.reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : null), responseBody);
155+
156+
if (Array.isArray(splitArray)) {
157+
logger.info(`Found array at "${arraySplittingKey}" with ${splitArray.length} items. Emitting each element.`);
158+
splitArray.forEach((item, index) => {
159+
this.emit("data", {
160+
data: item,
161+
metadata: getMetadata(msg.metadata),
162+
});
163+
logger.info(`Emitted nested array item at index ${index}`);
164+
});
165+
} else {
166+
if (splitArray === null) {
167+
logger.info(`Path "${arraySplittingKey}" not found in response object. Emitting full response instead.`);
168+
} else {
169+
logger.info(`Path "${arraySplittingKey}" resolved, but value is not an array (type: ${typeof splitArray}). Emitting full response instead.`);
170+
}
171+
this.emit("data", { data: responseBody, metadata: getMetadata(msg.metadata) });
172+
}
173+
} else {
174+
logger.info(`Array splitting key "${arraySplittingKey}" was specified, but response is neither an array nor an object. Type: ${typeof responseBody}. Emitting full response.`);
175+
this.emit("data", { data: responseBody, metadata: getMetadata(msg.metadata) });
176+
}
177+
} else {
178+
const outputMessage = {
179+
metadata: getMetadata(msg.metadata),
180+
data: responseBody,
181+
};
182+
183+
if (cfg.returnResult) {
184+
logger.info(`returnResult flag is true. Returning output message instead of emitting.`);
185+
return outputMessage;
186+
}
130187

131-
if (cfg.returnResult) {
132-
return newElement;
188+
this.emit("data", outputMessage);
189+
this.logger.info("Execution finished: emitted single message.");
133190
}
134-
135-
this.emit("data", newElement);
136-
this.logger.info("Execution finished");
137191
} catch (e) {
138192
if (continueOnError === true) {
139-
this.emit('data', { data: {}, metadata: {} });
193+
this.emit("data", { data: {}, metadata: {} });
140194
} else {
141-
this.emit('error', e);
195+
this.emit("error", e);
142196
}
143197
logger.error(e);
144198
}

0 commit comments

Comments
 (0)