UNPKG

@apify/n8n-nodes-apify

Version:
221 lines 7.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.apiRequest = apiRequest; exports.retryWithExponentialBackoff = retryWithExponentialBackoff; exports.apiRequestAllItems = apiRequestAllItems; exports.pollRunStatus = pollRunStatus; exports.getActorOrTaskId = getActorOrTaskId; exports.getCondition = getCondition; exports.normalizeEventTypes = normalizeEventTypes; exports.generateIdempotencyKey = generateIdempotencyKey; exports.compose = compose; exports.customBodyParser = customBodyParser; exports.isUsedAsAiTool = isUsedAsAiTool; exports.executeAndLinkItems = executeAndLinkItems; const n8n_workflow_1 = require("n8n-workflow"); const consts_1 = require("../helpers/consts"); async function apiRequest(requestOptions) { const { method, qs, uri, ...rest } = requestOptions; const query = qs || {}; const endpoint = `https://api.apify.com${uri}`; const headers = { 'x-apify-integration-platform': 'n8n', }; if (isUsedAsAiTool(this.getNode().type)) { headers['x-apify-integration-ai-tool'] = 'true'; } const options = { json: true, ...rest, method, qs: query, url: endpoint, headers, }; if (method === 'GET') { delete options.body; } try { const authenticationMethod = this.getNodeParameter('authentication', 0); try { await this.getCredentials(authenticationMethod); } catch { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No valid credentials found for ${authenticationMethod}. Please configure them first.`); } return await retryWithExponentialBackoff(() => this.helpers.httpRequestWithAuthentication.call(this, authenticationMethod, options)); } catch (error) { if (error instanceof n8n_workflow_1.NodeApiError) throw error; if (error.response && error.response.body) { throw new n8n_workflow_1.NodeApiError(this.getNode(), error, { message: error.response.body, description: error.message, }); } throw new n8n_workflow_1.NodeApiError(this.getNode(), error); } } function isStatusCodeRetryable(statusCode) { if (Number.isNaN(statusCode)) return false; const RATE_LIMIT_EXCEEDED_STATUS_CODE = 429; const isRateLimitError = statusCode === RATE_LIMIT_EXCEEDED_STATUS_CODE; const isInternalError = statusCode >= 500; return isRateLimitError || isInternalError; } async function retryWithExponentialBackoff(fn, interval = consts_1.DEFAULT_EXP_BACKOFF_INTERVAL, exponential = consts_1.DEFAULT_EXP_BACKOFF_EXPONENTIAL, maxRetries = consts_1.DEFAULT_EXP_BACKOFF_RETRIES) { let lastError; for (let i = 0; i < maxRetries; i++) { try { return await fn(); } catch (error) { lastError = error; const status = Number(error === null || error === void 0 ? void 0 : error.httpCode); if (isStatusCodeRetryable(status)) { const sleepTimeSecs = interval * Math.pow(exponential, i); const sleepTimeMs = sleepTimeSecs * 1000; await (0, n8n_workflow_1.sleep)(sleepTimeMs); continue; } throw error; } } throw lastError; } async function apiRequestAllItems(requestOptions) { const returnData = []; if (!requestOptions.qs) requestOptions.qs = {}; requestOptions.qs.limit = requestOptions.qs.limit || 999; let responseData; do { responseData = await apiRequest.call(this, requestOptions); returnData.push(responseData); } while (requestOptions.qs.limit <= responseData.length); const combinedData = { data: { total: 0, count: 0, offset: 0, limit: 0, desc: false, items: [], }, }; for (const result of returnData) { combinedData.data.total += typeof result.total === 'number' ? result.total : 0; combinedData.data.count += typeof result.count === 'number' ? result.count : 0; combinedData.data.offset += typeof result.offset === 'number' ? result.offset : 0; combinedData.data.limit += typeof result.limit === 'number' ? result.limit : 0; if (result.data && typeof result.data === 'object' && 'items' in result.data && Array.isArray(result.data.items)) { combinedData.data.items = [ ...combinedData.data.items, ...result.data.items, ]; } } return combinedData; } async function pollRunStatus(runId) { var _a; let lastRunData; while (true) { try { const pollResult = await apiRequest.call(this, { method: 'GET', uri: `/v2/actor-runs/${runId}`, }); const status = (_a = pollResult === null || pollResult === void 0 ? void 0 : pollResult.data) === null || _a === void 0 ? void 0 : _a.status; lastRunData = pollResult === null || pollResult === void 0 ? void 0 : pollResult.data; if (['SUCCEEDED', 'FAILED', 'TIMED-OUT', 'ABORTED'].includes(status)) { break; } } catch (err) { throw new n8n_workflow_1.NodeApiError(this.getNode(), { message: `Error polling run status: ${err}`, }); } await (0, n8n_workflow_1.sleep)(1000); } return lastRunData; } function getActorOrTaskId() { const resource = this.getNodeParameter('resource', ''); const actorId = this.getNodeParameter('actorId', ''); const actorTaskId = this.getNodeParameter('actorTaskId', ''); if (resource === 'task') { return actorTaskId.value; } return actorId.value; } function getCondition(resource, id) { return resource === 'actor' ? { actorId: id } : { actorTaskId: id }; } function normalizeEventTypes(selected) { if (selected.includes('any')) { return ['ACTOR.RUN.SUCCEEDED', 'ACTOR.RUN.FAILED', 'ACTOR.RUN.TIMED_OUT', 'ACTOR.RUN.ABORTED']; } return selected; } function generateIdempotencyKey(resource, actorOrTaskId, eventTypes) { const sortedEventTypes = [...eventTypes].sort(); const raw = `${resource}:${actorOrTaskId}:${sortedEventTypes.join(',')}`; return Buffer.from(raw).toString('base64'); } function compose(...fns) { return (x) => fns.reduce((v, f) => f(v), x); } function customBodyParser(input) { if (!input) { return {}; } if (typeof input === 'string') { return input ? JSON.parse(input) : {}; } else { return input; } } function isUsedAsAiTool(nodeType) { const parts = nodeType.split('.'); return parts[parts.length - 1] === 'apifyTool'; } async function executeAndLinkItems(executeFn) { const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const addPairedItem = (item) => ({ ...item, pairedItem: { item: i }, }); const result = await executeFn.call(this); if (Array.isArray(result)) { returnData.push(...result.map(addPairedItem)); } else { returnData.push(addPairedItem(result)); } } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error.message || 'Unexpected error occured' }, pairedItem: { item: i }, }); } else { throw error; } } } return [returnData]; } //# sourceMappingURL=genericFunctions.js.map