mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
Merge branch 'master' of github.com:rgeorgel/n8n
This commit is contained in:
commit
d35fc0bd43
8
.github/workflows/test-workflows.yml
vendored
8
.github/workflows/test-workflows.yml
vendored
|
@ -31,6 +31,14 @@ jobs:
|
|||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
-
|
||||
name: Install dependencies
|
||||
run: |
|
||||
apt update -y
|
||||
echo 'tzdata tzdata/Areas select Europe' | debconf-set-selections
|
||||
echo 'tzdata tzdata/Zones/Europe select Paris' | debconf-set-selections
|
||||
DEBIAN_FRONTEND="noninteractive" apt-get install -y graphicsmagick
|
||||
shell: bash
|
||||
-
|
||||
name: npm install and build
|
||||
run: |
|
||||
|
|
|
@ -2,6 +2,16 @@
|
|||
|
||||
This list shows all the versions which include breaking changes and how to upgrade.
|
||||
|
||||
## 0.131.0
|
||||
|
||||
### What changed?
|
||||
|
||||
For the Pipedrive regular node, the `deal:create` operation now requires an organization ID or person ID, in line with upcoming changes to the Pipedrive API.
|
||||
|
||||
### When is action necessary?
|
||||
|
||||
If you are using the `deal:create` operation in the Pipedrive regular node, set an organization ID or a person ID.
|
||||
|
||||
## 0.130.0
|
||||
|
||||
### What changed?
|
||||
|
|
1
packages/cli/commands/Interfaces.d.ts
vendored
1
packages/cli/commands/Interfaces.d.ts
vendored
|
@ -42,6 +42,7 @@ interface INodeSpecialCases {
|
|||
interface INodeSpecialCase {
|
||||
ignoredProperties?: string[];
|
||||
capResults?: number;
|
||||
keepOnlyProperties?: string[];
|
||||
}
|
||||
|
||||
type ExecutionStatus = 'success' | 'error' | 'warning' | 'running';
|
||||
|
|
|
@ -45,6 +45,10 @@ import {
|
|||
LoggerProxy,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
pick,
|
||||
} from 'lodash';
|
||||
|
||||
export class ExecuteBatch extends Command {
|
||||
static description = '\nExecutes multiple workflows once';
|
||||
|
||||
|
@ -166,6 +170,8 @@ export class ExecuteBatch extends Command {
|
|||
'429',
|
||||
'econnrefused',
|
||||
'missing a required parameter',
|
||||
'insufficient credit balance',
|
||||
'request timed out',
|
||||
];
|
||||
|
||||
errorMessage = errorMessage.toLowerCase();
|
||||
|
@ -600,6 +606,8 @@ export class ExecuteBatch extends Command {
|
|||
nodeEdgeCases[node.name].capResults = parseInt(parts[1], 10);
|
||||
} else if (parts[0] === 'IGNORED_PROPERTIES') {
|
||||
nodeEdgeCases[node.name].ignoredProperties = parts[1].split(',').map(property => property.trim());
|
||||
} else if (parts[0] === 'KEEP_ONLY_PROPERTIES') {
|
||||
nodeEdgeCases[node.name].keepOnlyProperties = parts[1].split(',').map(property => property.trim());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -701,6 +709,11 @@ export class ExecuteBatch extends Command {
|
|||
nodeEdgeCases[nodeName].ignoredProperties!.forEach(ignoredProperty => delete executionData.json[ignoredProperty]);
|
||||
}
|
||||
|
||||
let keepOnlyFields = [] as string[];
|
||||
if (nodeEdgeCases[nodeName] !== undefined && nodeEdgeCases[nodeName].keepOnlyProperties !== undefined) {
|
||||
keepOnlyFields = nodeEdgeCases[nodeName].keepOnlyProperties!;
|
||||
}
|
||||
executionData.json = keepOnlyFields.length > 0 ? pick(executionData.json, keepOnlyFields) : executionData.json;
|
||||
const jsonProperties = executionData.json;
|
||||
|
||||
const nodeOutputAttributes = Object.keys(jsonProperties);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "n8n",
|
||||
"version": "0.129.0",
|
||||
"version": "0.130.0",
|
||||
"description": "n8n Workflow Automation Tool",
|
||||
"license": "SEE LICENSE IN LICENSE.md",
|
||||
"homepage": "https://n8n.io",
|
||||
|
@ -109,8 +109,8 @@
|
|||
"lodash.get": "^4.4.2",
|
||||
"mysql2": "~2.2.0",
|
||||
"n8n-core": "~0.77.0",
|
||||
"n8n-editor-ui": "~0.98.0",
|
||||
"n8n-nodes-base": "~0.126.0",
|
||||
"n8n-editor-ui": "~0.99.0",
|
||||
"n8n-nodes-base": "~0.127.0",
|
||||
"n8n-workflow": "~0.63.0",
|
||||
"oauth-1.0a": "^2.2.6",
|
||||
"open": "^7.0.0",
|
||||
|
|
|
@ -927,6 +927,7 @@ class App {
|
|||
|
||||
// Returns the node icon
|
||||
this.app.get([`/${this.restEndpoint}/node-icon/:nodeType`, `/${this.restEndpoint}/node-icon/:scope/:nodeType`], async (req: express.Request, res: express.Response): Promise<void> => {
|
||||
try {
|
||||
const nodeTypeName = `${req.params.scope ? `${req.params.scope}/` : ''}${req.params.nodeType}`;
|
||||
|
||||
const nodeTypes = NodeTypes();
|
||||
|
@ -953,6 +954,10 @@ class App {
|
|||
res.setHeader('Cache-control', `private max-age=${maxAge}`);
|
||||
|
||||
res.sendFile(filepath);
|
||||
} catch (error) {
|
||||
// Error response
|
||||
return ResponseHelper.sendErrorResponse(res, error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
@ -1316,6 +1321,7 @@ class App {
|
|||
|
||||
// Verify and store app code. Generate access tokens and store for respective credential.
|
||||
this.app.get(`/${this.restEndpoint}/oauth1-credential/callback`, async (req: express.Request, res: express.Response) => {
|
||||
try {
|
||||
const { oauth_verifier, oauth_token, cid } = req.query;
|
||||
|
||||
if (oauth_verifier === undefined || oauth_token === undefined) {
|
||||
|
@ -1380,6 +1386,10 @@ class App {
|
|||
await Db.collections.Credentials!.update(cid as any, newCredentialsData); // tslint:disable-line:no-any
|
||||
|
||||
res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html'));
|
||||
} catch (error) {
|
||||
// Error response
|
||||
return ResponseHelper.sendErrorResponse(res, error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
@ -1478,6 +1488,7 @@ class App {
|
|||
|
||||
// Verify and store app code. Generate access tokens and store for respective credential.
|
||||
this.app.get(`/${this.restEndpoint}/oauth2-credential/callback`, async (req: express.Request, res: express.Response) => {
|
||||
try {
|
||||
|
||||
// realmId it's currently just use for the quickbook OAuth2 flow
|
||||
const { code, state: stateEncoded } = req.query;
|
||||
|
@ -1583,6 +1594,10 @@ class App {
|
|||
await Db.collections.Credentials!.update(state.cid, newCredentialsData);
|
||||
|
||||
res.sendFile(pathResolve(__dirname, '../../templates/oauth-callback.html'));
|
||||
} catch (error) {
|
||||
// Error response
|
||||
return ResponseHelper.sendErrorResponse(res, error);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "n8n-editor-ui",
|
||||
"version": "0.98.0",
|
||||
"version": "0.99.0",
|
||||
"description": "Workflow Editor UI for n8n",
|
||||
"license": "SEE LICENSE IN LICENSE.md",
|
||||
"homepage": "https://n8n.io",
|
||||
|
|
|
@ -395,6 +395,7 @@ export default mixins(
|
|||
this.$showError(error, 'Problem deleting the workflow', 'There was a problem deleting the workflow:');
|
||||
return;
|
||||
}
|
||||
this.$store.commit('setStateDirty', false);
|
||||
// Reset tab title since workflow is deleted.
|
||||
this.$titleReset();
|
||||
this.$showMessage({
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import {
|
||||
ICredentialType,
|
||||
NodePropertyTypes,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
export class ElasticsearchApi implements ICredentialType {
|
||||
name = 'elasticsearchApi';
|
||||
displayName = 'Elasticsearch API';
|
||||
documentationUrl = 'elasticsearch';
|
||||
properties = [
|
||||
{
|
||||
displayName: 'Username',
|
||||
name: 'username',
|
||||
type: 'string' as NodePropertyTypes,
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Password',
|
||||
name: 'password',
|
||||
type: 'string' as NodePropertyTypes,
|
||||
typeOptions: {
|
||||
password: true,
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Base URL',
|
||||
name: 'baseUrl',
|
||||
type: 'string' as NodePropertyTypes,
|
||||
default: '',
|
||||
placeholder: 'https://abc.elastic-cloud.com:9243',
|
||||
description: 'Referred to as \'endpoint\' in the Elasticsearch dashboard.',
|
||||
},
|
||||
];
|
||||
}
|
|
@ -333,6 +333,8 @@ export class ActiveCampaign implements INodeType {
|
|||
let dataKey: string | undefined;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
|
||||
dataKey = undefined;
|
||||
resource = this.getNodeParameter('resource', 0) as string;
|
||||
operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
@ -1184,6 +1186,13 @@ export class ActiveCampaign implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -162,6 +162,7 @@ export class Affinity implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'list') {
|
||||
//https://api-docs.affinity.co/#get-a-specific-list
|
||||
if (operation === 'get') {
|
||||
|
@ -353,6 +354,13 @@ export class Affinity implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -489,6 +489,7 @@ export class Airtable implements INodeType {
|
|||
let bulkSize = 10;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
addAllFields = this.getNodeParameter('addAllFields', i) as boolean;
|
||||
options = this.getNodeParameter('options', i, {}) as IDataObject;
|
||||
bulkSize = options.bulkSize as number || bulkSize;
|
||||
|
@ -527,6 +528,13 @@ export class Airtable implements INodeType {
|
|||
// empty rows
|
||||
rows.length = 0;
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (operation === 'delete') {
|
||||
|
@ -537,6 +545,7 @@ export class Airtable implements INodeType {
|
|||
const bulkSize = options.bulkSize as number || 10;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
let id: string;
|
||||
|
||||
id = this.getNodeParameter('id', i) as string;
|
||||
|
@ -560,13 +569,20 @@ export class Airtable implements INodeType {
|
|||
// empty rows
|
||||
rows.length = 0;
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (operation === 'list') {
|
||||
// ----------------------------------
|
||||
// list
|
||||
// ----------------------------------
|
||||
|
||||
try {
|
||||
requestMethod = 'GET';
|
||||
endpoint = `${application}/${table}`;
|
||||
|
||||
|
@ -598,6 +614,13 @@ export class Airtable implements INodeType {
|
|||
const data = await downloadRecordAttachments.call(this, responseData.records, downloadFieldNames);
|
||||
return [data];
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (operation === 'read') {
|
||||
// ----------------------------------
|
||||
|
@ -619,10 +642,17 @@ export class Airtable implements INodeType {
|
|||
// functionality in core should make it easy to make requests
|
||||
// according to specific rules like not more than 5 requests
|
||||
// per seconds.
|
||||
|
||||
try {
|
||||
responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs);
|
||||
|
||||
returnData.push(responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (operation === 'update') {
|
||||
|
@ -640,6 +670,7 @@ export class Airtable implements INodeType {
|
|||
let bulkSize = 10;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
updateAllFields = this.getNodeParameter('updateAllFields', i) as boolean;
|
||||
options = this.getNodeParameter('options', i, {}) as IDataObject;
|
||||
bulkSize = options.bulkSize as number || bulkSize;
|
||||
|
@ -695,6 +726,13 @@ export class Airtable implements INodeType {
|
|||
// empty rows
|
||||
rows.length = 0;
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -97,6 +97,7 @@ export class Amqp implements INodeType {
|
|||
};
|
||||
|
||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||
try {
|
||||
const credentials = this.getCredentials('amqp');
|
||||
if (!credentials) {
|
||||
throw new NodeOperationError(this.getNode(), 'Credentials are mandatory!');
|
||||
|
@ -176,5 +177,12 @@ export class Amqp implements INodeType {
|
|||
conn.close();
|
||||
|
||||
return [this.helpers.returnJsonArray(responseData)];
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return [this.helpers.returnJsonArray({ error: error.message })];
|
||||
}else{
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -420,10 +420,17 @@ export class ApiTemplateIo implements INodeType {
|
|||
// ----------------------------------
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
try {
|
||||
responseData = await apiTemplateIoApiRequest.call(this, 'GET', '/account-information');
|
||||
|
||||
returnData.push(responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({json:{ error: error.message }});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -442,6 +449,7 @@ export class ApiTemplateIo implements INodeType {
|
|||
|
||||
// https://docs.apitemplate.io/reference/api-reference.html#create-an-image-jpeg-and-png
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean;
|
||||
|
||||
const options = this.getNodeParameter('options', i) as IDataObject;
|
||||
|
@ -488,6 +496,13 @@ export class ApiTemplateIo implements INodeType {
|
|||
};
|
||||
}
|
||||
returnData.push(responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({json:{ error: error.message }});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
if (download === true) {
|
||||
|
@ -511,6 +526,7 @@ export class ApiTemplateIo implements INodeType {
|
|||
const download = this.getNodeParameter('download', 0) as boolean;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean;
|
||||
|
||||
const options = this.getNodeParameter('options', i) as IDataObject;
|
||||
|
@ -550,6 +566,13 @@ export class ApiTemplateIo implements INodeType {
|
|||
};
|
||||
}
|
||||
returnData.push(responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({json:{ error: error.message }});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
if (download === true) {
|
||||
return this.prepareOutputData(returnData as unknown as INodeExecutionData[]);
|
||||
|
|
|
@ -1842,6 +1842,7 @@ export class Asana implements INodeType {
|
|||
let responseData;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
body = {};
|
||||
qs = {};
|
||||
|
||||
|
@ -2254,6 +2255,13 @@ export class Asana implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -172,6 +172,7 @@ export class AwsLambda implements INodeType {
|
|||
const returnData: IDataObject[] = [];
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const params = {
|
||||
FunctionName: this.getNodeParameter('function', i) as string,
|
||||
InvocationType: this.getNodeParameter('invocationType', i) as string,
|
||||
|
@ -204,7 +205,13 @@ export class AwsLambda implements INodeType {
|
|||
result: responseData,
|
||||
} as IDataObject);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -140,6 +140,7 @@ export class AwsSns implements INodeType {
|
|||
const returnData: IDataObject[] = [];
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const params = [
|
||||
'TopicArn=' + this.getNodeParameter('topic', i) as string,
|
||||
'Subject=' + this.getNodeParameter('subject', i) as string,
|
||||
|
@ -149,6 +150,13 @@ export class AwsSns implements INodeType {
|
|||
|
||||
const responseData = await awsApiRequestSOAP.call(this, 'sns', 'GET', '/?Action=Publish&' + params.join('&'));
|
||||
returnData.push({MessageId: responseData.PublishResponse.PublishResult.MessageId} as IDataObject);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -213,6 +213,7 @@ export class AwsComprehend implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
if (resource === 'text') {
|
||||
//https://docs.aws.amazon.com/comprehend/latest/dg/API_DetectDominantLanguage.html
|
||||
if (operation === 'detectDominantLanguage') {
|
||||
|
@ -271,6 +272,13 @@ export class AwsComprehend implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
374
packages/nodes-base/nodes/Aws/DynamoDB/AwsDynamoDB.node.ts
Normal file
374
packages/nodes-base/nodes/Aws/DynamoDB/AwsDynamoDB.node.ts
Normal file
|
@ -0,0 +1,374 @@
|
|||
import {
|
||||
IExecuteFunctions,
|
||||
} from 'n8n-core';
|
||||
|
||||
import {
|
||||
IDataObject,
|
||||
ILoadOptionsFunctions,
|
||||
INodeExecutionData,
|
||||
INodeType,
|
||||
INodeTypeDescription,
|
||||
NodeParameterValue,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
awsApiRequest,
|
||||
awsApiRequestAllItems,
|
||||
} from './GenericFunctions';
|
||||
|
||||
import {
|
||||
itemFields,
|
||||
itemOperations,
|
||||
} from './ItemDescription';
|
||||
|
||||
import {
|
||||
FieldsUiValues,
|
||||
IAttributeNameUi,
|
||||
IAttributeValueUi,
|
||||
IRequestBody,
|
||||
PutItemUi,
|
||||
} from './types';
|
||||
|
||||
import {
|
||||
adjustExpressionAttributeName,
|
||||
adjustExpressionAttributeValues,
|
||||
adjustPutItem,
|
||||
decodeItem,
|
||||
simplify,
|
||||
} from './utils';
|
||||
|
||||
export class AwsDynamoDB implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'AWS DynamoDB',
|
||||
name: 'awsDynamoDb',
|
||||
icon: 'file:dynamodb.svg',
|
||||
group: ['transform'],
|
||||
version: 1,
|
||||
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||
description: 'Consume the AWS DynamoDB API',
|
||||
defaults: {
|
||||
name: 'AWS DynamoDB',
|
||||
color: '#2273b9',
|
||||
},
|
||||
inputs: ['main'],
|
||||
outputs: ['main'],
|
||||
credentials: [
|
||||
{
|
||||
name: 'aws',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Resource',
|
||||
name: 'resource',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Item',
|
||||
value: 'item',
|
||||
},
|
||||
],
|
||||
default: 'item',
|
||||
},
|
||||
...itemOperations,
|
||||
...itemFields,
|
||||
],
|
||||
};
|
||||
|
||||
methods = {
|
||||
loadOptions: {
|
||||
async getTables(this: ILoadOptionsFunctions) {
|
||||
const headers = {
|
||||
'Content-Type': 'application/x-amz-json-1.0',
|
||||
'X-Amz-Target': 'DynamoDB_20120810.ListTables',
|
||||
};
|
||||
|
||||
const responseData = await awsApiRequest.call(this, 'dynamodb', 'POST', '/', {}, headers);
|
||||
|
||||
return responseData.TableNames.map((table: string) => ({ name: table, value: table }));
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||
const items = this.getInputData();
|
||||
|
||||
const resource = this.getNodeParameter('resource', 0);
|
||||
const operation = this.getNodeParameter('operation', 0);
|
||||
|
||||
let responseData;
|
||||
const returnData: IDataObject[] = [];
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
|
||||
try {
|
||||
|
||||
if (resource === 'item') {
|
||||
|
||||
if (operation === 'upsert') {
|
||||
|
||||
// ----------------------------------
|
||||
// upsert
|
||||
// ----------------------------------
|
||||
|
||||
// https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html
|
||||
|
||||
const eavUi = this.getNodeParameter('additionalFields.eavUi.eavValues', i, []) as IAttributeValueUi[];
|
||||
const conditionExpession = this.getNodeParameter('conditionExpression', i, '') as string;
|
||||
const eanUi = this.getNodeParameter('additionalFields.eanUi.eanValues', i, []) as IAttributeNameUi[];
|
||||
|
||||
const body: IRequestBody = {
|
||||
TableName: this.getNodeParameter('tableName', i) as string,
|
||||
};
|
||||
|
||||
const expressionAttributeValues = adjustExpressionAttributeValues(eavUi);
|
||||
|
||||
if (Object.keys(expressionAttributeValues).length) {
|
||||
body.ExpressionAttributeValues = expressionAttributeValues;
|
||||
}
|
||||
|
||||
const expressionAttributeName = adjustExpressionAttributeName(eanUi);
|
||||
|
||||
if (Object.keys(expressionAttributeName).length) {
|
||||
body.expressionAttributeNames = expressionAttributeName;
|
||||
}
|
||||
|
||||
if (conditionExpession) {
|
||||
body.ConditionExpression = conditionExpession;
|
||||
}
|
||||
|
||||
const dataToSend = this.getNodeParameter('dataToSend', 0) as 'defineBelow' | 'autoMapInputData';
|
||||
const item: { [key: string]: string } = {};
|
||||
|
||||
if (dataToSend === 'autoMapInputData') {
|
||||
|
||||
const incomingKeys = Object.keys(items[i].json);
|
||||
const rawInputsToIgnore = this.getNodeParameter('inputsToIgnore', i) as string;
|
||||
const inputsToIgnore = rawInputsToIgnore.split(',').map(c => c.trim());
|
||||
|
||||
for (const key of incomingKeys) {
|
||||
if (inputsToIgnore.includes(key)) continue;
|
||||
item[key] = items[i].json[key] as string;
|
||||
}
|
||||
|
||||
body.Item = adjustPutItem(item as PutItemUi);
|
||||
|
||||
} else {
|
||||
|
||||
const fields = this.getNodeParameter('fieldsUi.fieldValues', i, []) as FieldsUiValues;
|
||||
fields.forEach(({ fieldId, fieldValue }) => item[fieldId] = fieldValue);
|
||||
body.Item = adjustPutItem(item as PutItemUi);
|
||||
|
||||
}
|
||||
|
||||
const headers = {
|
||||
'Content-Type': 'application/x-amz-json-1.0',
|
||||
'X-Amz-Target': 'DynamoDB_20120810.PutItem',
|
||||
};
|
||||
|
||||
responseData = await awsApiRequest.call(this, 'dynamodb', 'POST', '/', body, headers);
|
||||
responseData = item;
|
||||
|
||||
} else if (operation === 'delete') {
|
||||
|
||||
// ----------------------------------
|
||||
// delete
|
||||
// ----------------------------------
|
||||
|
||||
// https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
const body: { [key: string]: any } = {
|
||||
TableName: this.getNodeParameter('tableName', i) as string,
|
||||
Key: {},
|
||||
ReturnValues: this.getNodeParameter('returnValues', 0) as string,
|
||||
};
|
||||
|
||||
const eavUi = this.getNodeParameter('additionalFields.eavUi.eavValues', i, []) as IAttributeValueUi[];
|
||||
const eanUi = this.getNodeParameter('additionalFields.eanUi.eanValues', i, []) as IAttributeNameUi[];
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
const simple = this.getNodeParameter('simple', 0, false) as boolean;
|
||||
|
||||
const items = this.getNodeParameter('keysUi.keyValues', i, []) as [{ key: string, type: string, value: string }];
|
||||
|
||||
for (const item of items) {
|
||||
let value = item.value as NodeParameterValue;
|
||||
// All data has to get send as string even numbers
|
||||
// @ts-ignore
|
||||
value = ![null, undefined].includes(value) ? value?.toString() : '';
|
||||
body.Key[item.key as string] = { [item.type as string]: value };
|
||||
}
|
||||
|
||||
const expressionAttributeValues = adjustExpressionAttributeValues(eavUi);
|
||||
|
||||
if (Object.keys(expressionAttributeValues).length) {
|
||||
body.ExpressionAttributeValues = expressionAttributeValues;
|
||||
}
|
||||
|
||||
const expressionAttributeName = adjustExpressionAttributeName(eanUi);
|
||||
|
||||
if (Object.keys(expressionAttributeName).length) {
|
||||
body.expressionAttributeNames = expressionAttributeName;
|
||||
}
|
||||
|
||||
const headers = {
|
||||
'Content-Type': 'application/x-amz-json-1.0',
|
||||
'X-Amz-Target': 'DynamoDB_20120810.DeleteItem',
|
||||
};
|
||||
|
||||
if (additionalFields.conditionExpression) {
|
||||
body.ConditionExpression = additionalFields.conditionExpression as string;
|
||||
}
|
||||
|
||||
responseData = await awsApiRequest.call(this, 'dynamodb', 'POST', '/', body, headers);
|
||||
|
||||
if (!Object.keys(responseData).length) {
|
||||
responseData = { success: true };
|
||||
} else if (simple === true) {
|
||||
responseData = decodeItem(responseData.Attributes);
|
||||
}
|
||||
|
||||
} else if (operation === 'get') {
|
||||
|
||||
// ----------------------------------
|
||||
// get
|
||||
// ----------------------------------
|
||||
|
||||
// https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html
|
||||
|
||||
const tableName = this.getNodeParameter('tableName', 0) as string;
|
||||
const simple = this.getNodeParameter('simple', 0, false) as boolean;
|
||||
const select = this.getNodeParameter('select', 0) as string;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
const eanUi = this.getNodeParameter('additionalFields.eanUi.eanValues', i, []) as IAttributeNameUi[];
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
const body: { [key: string]: any } = {
|
||||
TableName: tableName,
|
||||
Key: {},
|
||||
Select: select,
|
||||
};
|
||||
|
||||
Object.assign(body, additionalFields);
|
||||
|
||||
const expressionAttributeName = adjustExpressionAttributeName(eanUi);
|
||||
|
||||
if (Object.keys(expressionAttributeName).length) {
|
||||
body.expressionAttributeNames = expressionAttributeName;
|
||||
}
|
||||
|
||||
if (additionalFields.readType) {
|
||||
body.ConsistentRead = additionalFields.readType === 'stronglyConsistentRead';
|
||||
}
|
||||
|
||||
if (additionalFields.projectionExpression) {
|
||||
body.ProjectionExpression = additionalFields.projectionExpression as string;
|
||||
}
|
||||
|
||||
const items = this.getNodeParameter('keysUi.keyValues', i, []) as IDataObject[];
|
||||
|
||||
for (const item of items) {
|
||||
let value = item.value as NodeParameterValue;
|
||||
// All data has to get send as string even numbers
|
||||
// @ts-ignore
|
||||
value = ![null, undefined].includes(value) ? value?.toString() : '';
|
||||
body.Key[item.key as string] = { [item.type as string]: value };
|
||||
}
|
||||
|
||||
const headers = {
|
||||
'X-Amz-Target': 'DynamoDB_20120810.GetItem',
|
||||
'Content-Type': 'application/x-amz-json-1.0',
|
||||
};
|
||||
|
||||
responseData = await awsApiRequest.call(this, 'dynamodb', 'POST', '/', body, headers);
|
||||
|
||||
responseData = responseData.Item;
|
||||
|
||||
if (simple && responseData) {
|
||||
responseData = decodeItem(responseData);
|
||||
}
|
||||
|
||||
} else if (operation === 'getAll') {
|
||||
|
||||
// ----------------------------------
|
||||
// getAll
|
||||
// ----------------------------------
|
||||
|
||||
// https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html
|
||||
|
||||
const eavUi = this.getNodeParameter('eavUi.eavValues', i, []) as IAttributeValueUi[];
|
||||
const simple = this.getNodeParameter('simple', 0, false) as boolean;
|
||||
const select = this.getNodeParameter('select', 0) as string;
|
||||
const returnAll = this.getNodeParameter('returnAll', 0) as boolean;
|
||||
const eanUi = this.getNodeParameter('additionalFields.eanUi.eanValues', i, []) as IAttributeNameUi[];
|
||||
|
||||
const body: IRequestBody = {
|
||||
TableName: this.getNodeParameter('tableName', i) as string,
|
||||
KeyConditionExpression: this.getNodeParameter('keyConditionExpression', i) as string,
|
||||
ExpressionAttributeValues: adjustExpressionAttributeValues(eavUi),
|
||||
};
|
||||
|
||||
const {
|
||||
indexName,
|
||||
projectionExpression,
|
||||
} = this.getNodeParameter('options', i) as {
|
||||
indexName: string;
|
||||
projectionExpression: string;
|
||||
};
|
||||
|
||||
const expressionAttributeName = adjustExpressionAttributeName(eanUi);
|
||||
|
||||
if (Object.keys(expressionAttributeName).length) {
|
||||
body.expressionAttributeNames = expressionAttributeName;
|
||||
}
|
||||
|
||||
if (indexName) {
|
||||
body.IndexName = indexName;
|
||||
}
|
||||
|
||||
if (projectionExpression && select !== 'COUNT') {
|
||||
body.ProjectionExpression = projectionExpression;
|
||||
}
|
||||
|
||||
if (select) {
|
||||
body.Select = select;
|
||||
}
|
||||
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Amz-Target': 'DynamoDB_20120810.Query',
|
||||
};
|
||||
|
||||
if (returnAll === true && select !== 'COUNT') {
|
||||
responseData = await awsApiRequestAllItems.call(this, 'dynamodb', 'POST', '/', body, headers);
|
||||
} else {
|
||||
body.Limit = this.getNodeParameter('limit', 0, 1) as number;
|
||||
responseData = await awsApiRequest.call(this, 'dynamodb', 'POST', '/', body, headers);
|
||||
if (select !== 'COUNT') {
|
||||
responseData = responseData.Items;
|
||||
}
|
||||
}
|
||||
if (simple === true) {
|
||||
responseData = responseData.map(simplify);
|
||||
}
|
||||
}
|
||||
|
||||
Array.isArray(responseData)
|
||||
? returnData.push(...responseData)
|
||||
: returnData.push(responseData);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
}
|
108
packages/nodes-base/nodes/Aws/DynamoDB/GenericFunctions.ts
Normal file
108
packages/nodes-base/nodes/Aws/DynamoDB/GenericFunctions.ts
Normal file
|
@ -0,0 +1,108 @@
|
|||
import {
|
||||
URL,
|
||||
} from 'url';
|
||||
|
||||
import {
|
||||
sign,
|
||||
} from 'aws4';
|
||||
|
||||
import {
|
||||
IExecuteFunctions,
|
||||
IHookFunctions,
|
||||
ILoadOptionsFunctions,
|
||||
IWebhookFunctions,
|
||||
} from 'n8n-core';
|
||||
|
||||
import {
|
||||
ICredentialDataDecryptedObject,
|
||||
IDataObject,
|
||||
INodeExecutionData,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
IRequestBody,
|
||||
} from './types';
|
||||
|
||||
function getEndpointForService(service: string, credentials: ICredentialDataDecryptedObject): string {
|
||||
let endpoint;
|
||||
if (service === 'lambda' && credentials.lambdaEndpoint) {
|
||||
endpoint = credentials.lambdaEndpoint;
|
||||
} else if (service === 'sns' && credentials.snsEndpoint) {
|
||||
endpoint = credentials.snsEndpoint;
|
||||
} else {
|
||||
endpoint = `https://${service}.${credentials.region}.amazonaws.com`;
|
||||
}
|
||||
return (endpoint as string).replace('{region}', credentials.region as string);
|
||||
}
|
||||
|
||||
export async function awsApiRequest(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: object | IRequestBody, headers?: object): Promise<any> { // tslint:disable-line:no-any
|
||||
const credentials = this.getCredentials('aws');
|
||||
if (credentials === undefined) {
|
||||
throw new Error('No credentials got returned!');
|
||||
}
|
||||
|
||||
// Concatenate path and instantiate URL object so it parses correctly query strings
|
||||
const endpoint = new URL(getEndpointForService(service, credentials) + path);
|
||||
|
||||
const options = sign({
|
||||
uri: endpoint,
|
||||
service,
|
||||
region: credentials.region,
|
||||
method,
|
||||
path: '/',
|
||||
headers: { ...headers },
|
||||
body: JSON.stringify(body),
|
||||
}, {
|
||||
accessKeyId: credentials.accessKeyId,
|
||||
secretAccessKey: credentials.secretAccessKey,
|
||||
});
|
||||
|
||||
try {
|
||||
return JSON.parse(await this.helpers.request!(options));
|
||||
} catch (error) {
|
||||
const errorMessage = (error.response && error.response.body.message) || (error.response && error.response.body.Message) || error.message;
|
||||
if (error.statusCode === 403) {
|
||||
if (errorMessage === 'The security token included in the request is invalid.') {
|
||||
throw new Error('The AWS credentials are not valid!');
|
||||
} else if (errorMessage.startsWith('The request signature we calculated does not match the signature you provided')) {
|
||||
throw new Error('The AWS credentials are not valid!');
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`AWS error response [${error.statusCode}]: ${errorMessage}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function awsApiRequestAllItems(this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions | IWebhookFunctions, service: string, method: string, path: string, body?: IRequestBody, headers?: object): Promise<any> { // tslint:disable-line:no-any
|
||||
|
||||
const returnData: IDataObject[] = [];
|
||||
|
||||
let responseData;
|
||||
|
||||
do {
|
||||
responseData = await awsApiRequest.call(this, service, method, path, body, headers);
|
||||
if (responseData.LastEvaluatedKey) {
|
||||
body!.ExclusiveStartKey = responseData.LastEvaluatedKey;
|
||||
}
|
||||
returnData.push(...responseData.Items);
|
||||
} while (
|
||||
responseData.LastEvaluatedKey !== undefined
|
||||
);
|
||||
|
||||
return returnData;
|
||||
}
|
||||
|
||||
export function copyInputItem(item: INodeExecutionData, properties: string[]): IDataObject {
|
||||
// Prepare the data to insert and copy it to be returned
|
||||
let newItem: IDataObject;
|
||||
newItem = {};
|
||||
for (const property of properties) {
|
||||
if (item.json[property] === undefined) {
|
||||
newItem[property] = null;
|
||||
} else {
|
||||
newItem[property] = JSON.parse(JSON.stringify(item.json[property]));
|
||||
}
|
||||
}
|
||||
return newItem;
|
||||
}
|
920
packages/nodes-base/nodes/Aws/DynamoDB/ItemDescription.ts
Normal file
920
packages/nodes-base/nodes/Aws/DynamoDB/ItemDescription.ts
Normal file
|
@ -0,0 +1,920 @@
|
|||
import {
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
export const itemOperations = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create or Update',
|
||||
value: 'upsert',
|
||||
description: 'Create a new record, or update the current one if it already exists (upsert/put)',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
description: 'Delete an item',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
description: 'Get an item',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
value: 'getAll',
|
||||
description: 'Get all items',
|
||||
},
|
||||
],
|
||||
default: 'upsert',
|
||||
},
|
||||
] as INodeProperties[];
|
||||
|
||||
export const itemFields = [
|
||||
// ----------------------------------
|
||||
// all
|
||||
// ----------------------------------
|
||||
{
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
description: 'Table to operate on',
|
||||
type: 'options',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: [],
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTables',
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------
|
||||
// upsert
|
||||
// ----------------------------------
|
||||
{
|
||||
displayName: 'Data to Send',
|
||||
name: 'dataToSend',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Auto-map Input Data to Columns',
|
||||
value: 'autoMapInputData',
|
||||
description: 'Use when node input properties match destination column names',
|
||||
},
|
||||
{
|
||||
name: 'Define Below for Each Column',
|
||||
value: 'defineBelow',
|
||||
description: 'Set the value for each destination column',
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'upsert',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: 'defineBelow',
|
||||
description: 'Whether to insert the input data this node receives in the new row',
|
||||
},
|
||||
{
|
||||
displayName: 'Inputs to Ignore',
|
||||
name: 'inputsToIgnore',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'upsert',
|
||||
],
|
||||
dataToSend: [
|
||||
'autoMapInputData',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
required: false,
|
||||
description: 'List of input properties to avoid sending, separated by commas. Leave empty to send all properties.',
|
||||
placeholder: 'Enter properties...',
|
||||
},
|
||||
{
|
||||
displayName: 'Fields to Send',
|
||||
name: 'fieldsUi',
|
||||
placeholder: 'Add Field',
|
||||
type: 'fixedCollection',
|
||||
typeOptions: {
|
||||
multipleValueButtonText: 'Add Field to Send',
|
||||
multipleValues: true,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'upsert',
|
||||
],
|
||||
dataToSend: [
|
||||
'defineBelow',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Field',
|
||||
name: 'fieldValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Field ID',
|
||||
name: 'fieldId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Field Value',
|
||||
name: 'fieldValue',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'upsert',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Expression Attribute Values',
|
||||
name: 'eavUi',
|
||||
description: 'Substitution tokens for attribute names in an expression.<br>Only needed when the parameter "condition expression" is set',
|
||||
placeholder: 'Add Attribute Value',
|
||||
type: 'fixedCollection',
|
||||
default: '',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
minValue: 1,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'eavValues',
|
||||
displayName: 'Expression Attribute Vaue',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Attribute',
|
||||
name: 'attribute',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Number',
|
||||
value: 'N',
|
||||
},
|
||||
{
|
||||
name: 'String',
|
||||
value: 'S',
|
||||
},
|
||||
],
|
||||
default: 'S',
|
||||
},
|
||||
{
|
||||
displayName: 'Value',
|
||||
name: 'value',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Condition Expression',
|
||||
name: 'conditionExpression',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'A condition that must be satisfied in order for a conditional upsert to succeed. <a target="_blank" href="https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html">View details</a>',
|
||||
},
|
||||
{
|
||||
displayName: 'Expression Attribute Names',
|
||||
name: 'eanUi',
|
||||
placeholder: 'Add Expression',
|
||||
type: 'fixedCollection',
|
||||
default: '',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'eanValues',
|
||||
displayName: 'Expression',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Key',
|
||||
name: 'key',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Value',
|
||||
name: 'value',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
description: 'One or more substitution tokens for attribute names in an expression. <a target="_blank" href="https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html">View details</a>',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------
|
||||
// delete
|
||||
// ----------------------------------
|
||||
{
|
||||
displayName: 'Return',
|
||||
name: 'returnValues',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'delete',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Attribute Values',
|
||||
value: 'ALL_OLD',
|
||||
description: 'The content of the old item is returned',
|
||||
},
|
||||
{
|
||||
name: 'Nothing',
|
||||
value: 'NONE',
|
||||
description: 'Nothing is returned',
|
||||
},
|
||||
],
|
||||
default: 'NONE',
|
||||
description: 'Use ReturnValues if you want to get the item attributes as they appeared before they were deleted',
|
||||
},
|
||||
{
|
||||
displayName: 'Keys',
|
||||
name: 'keysUi',
|
||||
type: 'fixedCollection',
|
||||
placeholder: 'Add Key',
|
||||
default: {},
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'delete',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Key',
|
||||
name: 'keyValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Key',
|
||||
name: 'key',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Binary',
|
||||
value: 'B',
|
||||
},
|
||||
{
|
||||
name: 'Number',
|
||||
value: 'N',
|
||||
},
|
||||
{
|
||||
name: 'String',
|
||||
value: 'S',
|
||||
},
|
||||
],
|
||||
default: 'S',
|
||||
},
|
||||
{
|
||||
displayName: 'Value',
|
||||
name: 'value',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
description: 'Item\'s primary key. For example, with a simple primary key, you only need to provide a value for the partition key.<br>For a composite primary key, you must provide values for both the partition key and the sort key',
|
||||
},
|
||||
{
|
||||
displayName: 'Simple',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'delete',
|
||||
],
|
||||
returnValues: [
|
||||
'ALL_OLD',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: true,
|
||||
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'delete',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Condition Expression',
|
||||
name: 'conditionExpression',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'A condition that must be satisfied in order for a conditional delete to succeed',
|
||||
},
|
||||
{
|
||||
displayName: 'Expression Attribute Names',
|
||||
name: 'eanUi',
|
||||
placeholder: 'Add Expression',
|
||||
type: 'fixedCollection',
|
||||
default: '',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'eanValues',
|
||||
displayName: 'Expression',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Key',
|
||||
name: 'key',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Value',
|
||||
name: 'value',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
description: 'One or more substitution tokens for attribute names in an expression. Check <a href="https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html" target="_blank">Info</a>',
|
||||
},
|
||||
{
|
||||
displayName: 'Expression Attribute Values',
|
||||
name: 'expressionAttributeUi',
|
||||
description: 'Substitution tokens for attribute names in an expression.<br>Only needed when the parameter "condition expression" is set',
|
||||
placeholder: 'Add Attribute Value',
|
||||
type: 'fixedCollection',
|
||||
default: '',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
minValue: 1,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'expressionAttributeValues',
|
||||
displayName: 'Expression Attribute Vaue',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Attribute',
|
||||
name: 'attribute',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Number',
|
||||
value: 'N',
|
||||
},
|
||||
{
|
||||
name: 'String',
|
||||
value: 'S',
|
||||
},
|
||||
],
|
||||
default: 'S',
|
||||
},
|
||||
{
|
||||
displayName: 'Value',
|
||||
name: 'value',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------
|
||||
// get
|
||||
// ----------------------------------
|
||||
{
|
||||
displayName: 'Select',
|
||||
name: 'select',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'All Attributes',
|
||||
value: 'ALL_ATTRIBUTES',
|
||||
},
|
||||
{
|
||||
name: 'All Projected Attributes',
|
||||
value: 'ALL_PROJECTED_ATTRIBUTES',
|
||||
},
|
||||
{
|
||||
name: 'Specific Attributes',
|
||||
value: 'SPECIFIC_ATTRIBUTES',
|
||||
description: 'Select them in Attributes to Select under Additional Fields',
|
||||
},
|
||||
],
|
||||
default: 'ALL_ATTRIBUTES',
|
||||
},
|
||||
{
|
||||
displayName: 'Simple',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
select: [
|
||||
'ALL_PROJECTED_ATTRIBUTES',
|
||||
'ALL_ATTRIBUTES',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: true,
|
||||
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||
},
|
||||
{
|
||||
displayName: 'Keys',
|
||||
name: 'keysUi',
|
||||
type: 'fixedCollection',
|
||||
placeholder: 'Add Key',
|
||||
default: {},
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Key',
|
||||
name: 'keyValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Key',
|
||||
name: 'key',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Binary',
|
||||
value: 'B',
|
||||
},
|
||||
{
|
||||
name: 'Number',
|
||||
value: 'N',
|
||||
},
|
||||
{
|
||||
name: 'String',
|
||||
value: 'S',
|
||||
},
|
||||
],
|
||||
default: 'S',
|
||||
},
|
||||
{
|
||||
displayName: 'Value',
|
||||
name: 'value',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
description: 'Item\'s primary key. For example, with a simple primary key, you only need to provide a value for the partition key.<br>For a composite primary key, you must provide values for both the partition key and the sort key',
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Attributes to Select',
|
||||
name: 'projectionExpression',
|
||||
type: 'string',
|
||||
placeholder: 'id, name',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Expression Attribute Names',
|
||||
name: 'eanUi',
|
||||
placeholder: 'Add Expression',
|
||||
type: 'fixedCollection',
|
||||
default: '',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'eanValues',
|
||||
displayName: 'Expression',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Key',
|
||||
name: 'key',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Value',
|
||||
name: 'value',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
description: 'One or more substitution tokens for attribute names in an expression. <a href="https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html" target="_blank">View details</a>',
|
||||
},
|
||||
{
|
||||
displayName: 'Read Type',
|
||||
name: 'readType',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Strongly consistent read',
|
||||
value: 'stronglyConsistentRead',
|
||||
},
|
||||
{
|
||||
name: 'Eventually consistent read',
|
||||
value: 'eventuallyConsistentRead',
|
||||
},
|
||||
],
|
||||
default: 'eventuallyConsistentRead',
|
||||
description: 'Type of read to perform on the table. <a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html" target="_blank">View details</a>',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------
|
||||
// Get All
|
||||
// ----------------------------------
|
||||
{
|
||||
displayName: 'Key Condition Expression',
|
||||
name: 'keyConditionExpression',
|
||||
description: 'Condition to determine the items to be retrieved. The condition must perform an equality test<br>on a single partition key value, in this format: <code>partitionKeyName = :partitionkeyval</code>',
|
||||
placeholder: 'id = :id',
|
||||
default: '',
|
||||
type: 'string',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Expression Attribute Values',
|
||||
name: 'eavUi',
|
||||
description: 'Substitution tokens for attribute names in an expression',
|
||||
placeholder: 'Add Attribute Value',
|
||||
type: 'fixedCollection',
|
||||
default: '',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
minValue: 1,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'eavValues',
|
||||
displayName: 'Expression Attribute Vaue',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Attribute',
|
||||
name: 'attribute',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Type',
|
||||
name: 'type',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Number',
|
||||
value: 'N',
|
||||
},
|
||||
{
|
||||
name: 'String',
|
||||
value: 'S',
|
||||
},
|
||||
],
|
||||
default: 'S',
|
||||
},
|
||||
{
|
||||
displayName: 'Value',
|
||||
name: 'value',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
returnAll: [
|
||||
false,
|
||||
],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 100,
|
||||
},
|
||||
default: 50,
|
||||
description: 'How many results to return',
|
||||
},
|
||||
{
|
||||
displayName: 'Select',
|
||||
name: 'select',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'All Attributes',
|
||||
value: 'ALL_ATTRIBUTES',
|
||||
},
|
||||
{
|
||||
name: 'All Projected Attributes',
|
||||
value: 'ALL_PROJECTED_ATTRIBUTES',
|
||||
},
|
||||
{
|
||||
name: 'Count',
|
||||
value: 'COUNT',
|
||||
},
|
||||
{
|
||||
name: 'Specific Attributes',
|
||||
value: 'SPECIFIC_ATTRIBUTES',
|
||||
description: 'Select them in Attributes to Select under Additional Fields',
|
||||
},
|
||||
],
|
||||
default: 'ALL_ATTRIBUTES',
|
||||
},
|
||||
{
|
||||
displayName: 'Simple',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
select: [
|
||||
'ALL_PROJECTED_ATTRIBUTES',
|
||||
'ALL_ATTRIBUTES',
|
||||
'SPECIFIC_ATTRIBUTES',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: true,
|
||||
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||
},
|
||||
{
|
||||
displayName: 'Options',
|
||||
name: 'options',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'item',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Index Name',
|
||||
name: 'indexName',
|
||||
description: 'Name of the index to query. It can be any <br>secondary local or global index on the table.',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Attributes to Select',
|
||||
name: 'projectionExpression',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Text that identifies one or more attributes to retrieve from the table.<br>These attributes can include scalars, sets, or elements of a JSON document. The attributes<br>in the expression must be separated by commas',
|
||||
},
|
||||
{
|
||||
displayName: 'Filter Expression',
|
||||
name: 'filterExpression',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Text that contains conditions that DynamoDB applies after the Query operation,<br>but before the data is returned. Items that do not satisfy the FilterExpression criteria</br>are not returned',
|
||||
},
|
||||
{
|
||||
displayName: 'Expression Attribute Names',
|
||||
name: 'eanUi',
|
||||
placeholder: 'Add Expression',
|
||||
type: 'fixedCollection',
|
||||
default: '',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'eanValues',
|
||||
displayName: 'Expression',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Key',
|
||||
name: 'key',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Value',
|
||||
name: 'value',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
description: 'One or more substitution tokens for attribute names in an expression. Check <a target="_blank" href="https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html">Info</a>',
|
||||
},
|
||||
],
|
||||
},
|
||||
] as INodeProperties[];
|
13
packages/nodes-base/nodes/Aws/DynamoDB/dynamodb.svg
Normal file
13
packages/nodes-base/nodes/Aws/DynamoDB/dynamodb.svg
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg viewBox="-40 -35 340 340" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
||||
<g>
|
||||
<path d="M165.258,288.501 L168.766,288.501 L226.027,259.867 L226.98,258.52 L226.98,29.964 L226.027,28.61 L168.766,0 L165.215,0 L165.258,288.501" fill="#5294CF"/>
|
||||
<path d="M90.741,288.501 L87.184,288.501 L29.972,259.867 L28.811,257.87 L28.222,31.128 L29.972,28.61 L87.184,0 L90.785,0 L90.741,288.501" fill="#1F5B98"/>
|
||||
<path d="M87.285,0 L168.711,0 L168.711,288.501 L87.285,288.501 L87.285,0 Z" fill="#2D72B8"/>
|
||||
<path d="M256,137.769 L254.065,137.34 L226.437,134.764 L226.027,134.968 L168.715,132.676 L87.285,132.676 L29.972,134.968 L29.972,91.264 L29.912,91.296 L29.972,91.168 L87.285,77.888 L168.715,77.888 L226.027,91.168 L247.096,102.367 L247.096,95.167 L256,94.193 L255.078,92.395 L226.886,72.236 L226.027,72.515 L168.715,54.756 L87.285,54.756 L29.972,72.515 L29.972,28.61 L0,63.723 L0,94.389 L0.232,94.221 L8.904,95.167 L8.904,102.515 L0,107.28 L0,137.793 L0.232,137.769 L8.904,137.897 L8.904,150.704 L1.422,150.816 L0,150.68 L0,181.205 L8.904,185.993 L8.904,193.426 L0.373,194.368 L0,194.088 L0,224.749 L29.972,259.867 L29.972,215.966 L87.285,233.725 L168.715,233.725 L226.196,215.914 L226.96,216.249 L254.781,196.387 L256,194.408 L247.096,193.426 L247.096,186.142 L245.929,185.676 L226.886,195.941 L226.196,197.381 L168.715,210.584 L168.715,210.6 L87.285,210.6 L87.285,210.584 L29.972,197.325 L29.972,153.461 L87.285,155.745 L87.285,155.801 L168.715,155.801 L226.027,153.461 L227.332,154.061 L254.111,151.755 L256,150.832 L247.096,150.704 L247.096,137.897 L256,137.769" fill="#1A476F"/>
|
||||
<path d="M226.027,215.966 L226.027,259.867 L256,224.749 L256,194.288 L226.2,215.914 L226.027,215.966" fill="#2D72B8"/>
|
||||
<path d="M226.027,197.421 L226.2,197.381 L256,181.353 L256,150.704 L226.027,153.461 L226.027,197.421" fill="#2D72B8"/>
|
||||
<path d="M226.2,91.208 L226.027,91.168 L226.027,134.968 L256,137.769 L256,107.135 L226.2,91.208" fill="#2D72B8"/>
|
||||
<path d="M226.2,72.687 L256,94.193 L256,63.731 L226.027,28.61 L226.027,72.515 L226.2,72.575 L226.2,72.687" fill="#2D72B8"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
79
packages/nodes-base/nodes/Aws/DynamoDB/types.d.ts
vendored
Normal file
79
packages/nodes-base/nodes/Aws/DynamoDB/types.d.ts
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
export interface IRequestBody {
|
||||
[key: string]: string | IAttributeValue | undefined | boolean | object | number;
|
||||
TableName: string;
|
||||
Key?: object;
|
||||
IndexName?: string;
|
||||
ProjectionExpression?: string;
|
||||
KeyConditionExpression?: string;
|
||||
ExpressionAttributeValues?: IAttributeValue;
|
||||
ConsistentRead?: boolean;
|
||||
FilterExpression?: string;
|
||||
Limit?: number;
|
||||
ExclusiveStartKey?: IAttributeValue;
|
||||
}
|
||||
|
||||
export interface IAttributeValue {
|
||||
[attribute: string]: IAttributeValueValue;
|
||||
}
|
||||
|
||||
interface IAttributeValueValue {
|
||||
[type: string]: string | string[] | IAttributeValue[];
|
||||
}
|
||||
|
||||
export interface IAttributeValueUi {
|
||||
attribute: string;
|
||||
type: AttributeValueType;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface IAttributeNameUi {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
type AttributeValueType =
|
||||
| 'B' // binary
|
||||
| 'BOOL' // boolean
|
||||
| 'BS' // binary set
|
||||
| 'L' // list
|
||||
| 'M' // map
|
||||
| 'N' // number
|
||||
| 'NULL'
|
||||
| 'NS' // number set
|
||||
| 'S' // string
|
||||
| 'SS'; // string set
|
||||
|
||||
export type PartitionKey = {
|
||||
details: {
|
||||
name: string;
|
||||
type: string;
|
||||
value: string;
|
||||
},
|
||||
};
|
||||
|
||||
export enum EAttributeValueType {
|
||||
S = 'S', SS = 'SS', M = 'M', L = 'L', NS = 'NS', N = 'N', BOOL = 'BOOL', B = 'B', BS = 'BS', NULL = 'NULL',
|
||||
}
|
||||
|
||||
export interface IExpressionAttributeValue {
|
||||
attribute: string;
|
||||
type: EAttributeValueType;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export type FieldsUiValues = Array<{
|
||||
fieldId: string;
|
||||
fieldValue: string;
|
||||
}>;
|
||||
|
||||
export type PutItemUi = {
|
||||
attribute: string;
|
||||
type: 'S' | 'N';
|
||||
value: string;
|
||||
};
|
||||
|
||||
export type AdjustedPutItem = {
|
||||
[attribute: string]: {
|
||||
[type: string]: string
|
||||
}
|
||||
};
|
134
packages/nodes-base/nodes/Aws/DynamoDB/utils.ts
Normal file
134
packages/nodes-base/nodes/Aws/DynamoDB/utils.ts
Normal file
|
@ -0,0 +1,134 @@
|
|||
import {
|
||||
IDataObject,
|
||||
INodeExecutionData,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
AdjustedPutItem,
|
||||
AttributeValueType,
|
||||
EAttributeValueType,
|
||||
IAttributeNameUi,
|
||||
IAttributeValue,
|
||||
IAttributeValueUi,
|
||||
IAttributeValueValue,
|
||||
PutItemUi,
|
||||
} from './types';
|
||||
|
||||
const addColon = (attribute: string) => attribute = attribute.charAt(0) === ':' ? attribute : `:${attribute}`;
|
||||
|
||||
const addPound = (key: string) => key = key.charAt(0) === '#' ? key : `#${key}`;
|
||||
|
||||
export function adjustExpressionAttributeValues(eavUi: IAttributeValueUi[]) {
|
||||
const eav: IAttributeValue = {};
|
||||
|
||||
eavUi.forEach(({ attribute, type, value }) => {
|
||||
eav[addColon(attribute)] = { [type]: value } as IAttributeValueValue;
|
||||
});
|
||||
|
||||
return eav;
|
||||
}
|
||||
|
||||
export function adjustExpressionAttributeName(eanUi: IAttributeNameUi[]) {
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
const ean: { [key: string]: any } = {};
|
||||
|
||||
eanUi.forEach(({ key, value }) => {
|
||||
ean[addPound(key)] = { value } as IAttributeValueValue;
|
||||
});
|
||||
|
||||
return ean;
|
||||
}
|
||||
|
||||
export function adjustPutItem(putItemUi: PutItemUi) {
|
||||
const adjustedPutItem: AdjustedPutItem = {};
|
||||
|
||||
Object.entries(putItemUi).forEach(([attribute, value]) => {
|
||||
let type: string;
|
||||
|
||||
if (typeof value === 'boolean') {
|
||||
type = 'BOOL';
|
||||
} else if (typeof value === 'object' && !Array.isArray(value) && value !== null) {
|
||||
type = 'M';
|
||||
// @ts-ignore
|
||||
} else if (isNaN(value)) {
|
||||
type = 'S';
|
||||
} else {
|
||||
type = 'N';
|
||||
}
|
||||
|
||||
adjustedPutItem[attribute] = { [type]: value.toString() };
|
||||
});
|
||||
|
||||
return adjustedPutItem;
|
||||
}
|
||||
|
||||
export function simplify(item: IAttributeValue): IDataObject {
|
||||
const output: IDataObject = {};
|
||||
|
||||
for (const [attribute, value] of Object.entries(item)) {
|
||||
const [type, content] = Object.entries(value)[0] as [AttributeValueType, string];
|
||||
output[attribute] = decodeAttribute(type, content);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
function decodeAttribute(type: AttributeValueType, attribute: string) {
|
||||
switch (type) {
|
||||
case 'BOOL':
|
||||
return Boolean(attribute);
|
||||
case 'N':
|
||||
return Number(attribute);
|
||||
case 'S':
|
||||
return String(attribute);
|
||||
case 'SS':
|
||||
case 'NS':
|
||||
return attribute;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: no-any
|
||||
export function validateJSON(input: any): object {
|
||||
try {
|
||||
return JSON.parse(input);
|
||||
} catch (error) {
|
||||
throw new Error('Items must be a valid JSON');
|
||||
}
|
||||
}
|
||||
|
||||
export function copyInputItem(item: INodeExecutionData, properties: string[]): IDataObject {
|
||||
// Prepare the data to insert and copy it to be returned
|
||||
let newItem: IDataObject;
|
||||
newItem = {};
|
||||
for (const property of properties) {
|
||||
if (item.json[property] === undefined) {
|
||||
newItem[property] = null;
|
||||
} else {
|
||||
newItem[property] = JSON.parse(JSON.stringify(item.json[property]));
|
||||
}
|
||||
}
|
||||
return newItem;
|
||||
}
|
||||
|
||||
export function mapToAttributeValues(item: IDataObject): void {
|
||||
for (const key of Object.keys(item)) {
|
||||
if (!key.startsWith(':')) {
|
||||
item[`:${key}`] = item[key];
|
||||
delete item[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function decodeItem(item: IAttributeValue): IDataObject {
|
||||
const _item: IDataObject = {};
|
||||
for (const entry of Object.entries(item)) {
|
||||
const [attribute, value]: [string, object] = entry;
|
||||
const [type, content]: [string, object] = Object.entries(value)[0];
|
||||
_item[attribute] = decodeAttribute(type as EAttributeValueType, content as unknown as string);
|
||||
}
|
||||
|
||||
return _item;
|
||||
}
|
|
@ -383,6 +383,7 @@ export class AwsRekognition implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
if (resource === 'image') {
|
||||
//https://docs.aws.amazon.com/rekognition/latest/dg/API_DetectModerationLabels.html#API_DetectModerationLabels_RequestSyntax
|
||||
if (operation === 'analyze') {
|
||||
|
@ -507,6 +508,13 @@ export class AwsRekognition implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@ export class AwsS3 implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const headers: IDataObject = {};
|
||||
try {
|
||||
if (resource === 'bucket') {
|
||||
//https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html
|
||||
if (operation === 'create') {
|
||||
|
@ -630,6 +631,13 @@ export class AwsS3 implements INodeType {
|
|||
returnData.push({ success: true });
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
if (resource === 'file' && operation === 'download') {
|
||||
// For file downloads the files get attached to the existing items
|
||||
|
|
|
@ -934,7 +934,7 @@ export class AwsSes implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
|
||||
try {
|
||||
if (resource === 'customVerificationEmail') {
|
||||
|
||||
if (operation === 'create') {
|
||||
|
@ -1305,6 +1305,13 @@ export class AwsSes implements INodeType {
|
|||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -316,6 +316,7 @@ export class AwsSqs implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const queueUrl = this.getNodeParameter('queue', i) as string;
|
||||
const queuePath = new URL(queueUrl).pathname;
|
||||
|
||||
|
@ -394,6 +395,13 @@ export class AwsSqs implements INodeType {
|
|||
|
||||
const result = responseData.SendMessageResponse.SendMessageResult;
|
||||
returnData.push(result as IDataObject);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.description });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -340,7 +340,7 @@ export class Beeminder implements INodeType {
|
|||
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
try {
|
||||
if (resource === 'datapoint') {
|
||||
const goalName = this.getNodeParameter('goalName', i) as string;
|
||||
if (operation === 'create') {
|
||||
|
@ -393,7 +393,13 @@ export class Beeminder implements INodeType {
|
|||
results = await deleteDatapoint.call(this, data);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (Array.isArray(results)) {
|
||||
returnData.push.apply(returnData, results as IDataObject[]);
|
||||
} else {
|
||||
|
|
|
@ -141,6 +141,7 @@ export class Bitly implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'link') {
|
||||
if (operation === 'create') {
|
||||
const longUrl = this.getNodeParameter('longUrl', i) as string;
|
||||
|
@ -217,6 +218,13 @@ export class Bitly implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@ export class Box implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'file') {
|
||||
// https://developer.box.com/reference/post-files-id-copy
|
||||
if (operation === 'copy') {
|
||||
|
@ -480,6 +481,13 @@ export class Box implements INodeType {
|
|||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
if (resource === 'file' && operation === 'download') {
|
||||
// For file downloads the files get attached to the existing items
|
||||
|
|
|
@ -167,6 +167,7 @@ export class Brandfetch implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
const responseData = [];
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (operation === 'logo') {
|
||||
const domain = this.getNodeParameter('domain', i) as string;
|
||||
const download = this.getNodeParameter('download', i) as boolean;
|
||||
|
@ -259,6 +260,13 @@ export class Brandfetch implements INodeType {
|
|||
const response = await brandfetchApiRequest.call(this, 'POST', `/industry`, body);
|
||||
responseData.push.apply(responseData, response.response);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
responseData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
if (operation === 'logo' && this.getNodeParameter('download', 0) === true) {
|
||||
|
|
|
@ -502,7 +502,7 @@ export class Chargebee implements INodeType {
|
|||
let qs: IDataObject;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
|
||||
try {
|
||||
item = items[i];
|
||||
const resource = this.getNodeParameter('resource', i) as string;
|
||||
const operation = this.getNodeParameter('operation', i) as string;
|
||||
|
@ -636,6 +636,13 @@ export class Chargebee implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -69,6 +69,7 @@ export class CircleCi implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'pipeline') {
|
||||
if (operation === 'get') {
|
||||
const vcs = this.getNodeParameter('vcs', i) as string;
|
||||
|
@ -134,6 +135,13 @@ export class CircleCi implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ export class Clearbit implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'person') {
|
||||
if (operation === 'enrich') {
|
||||
const email = this.getNodeParameter('email', i) as string;
|
||||
|
@ -146,6 +147,13 @@ export class Clearbit implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -482,6 +482,7 @@ export class ClickUp implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'checklist') {
|
||||
if (operation === 'create') {
|
||||
const taskId = this.getNodeParameter('task', i) as string;
|
||||
|
@ -1427,6 +1428,13 @@ export class ClickUp implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -233,6 +233,7 @@ export class Clockify implements INodeType {
|
|||
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
try {
|
||||
if (resource === 'project') {
|
||||
|
||||
if (operation === 'create') {
|
||||
|
@ -570,7 +571,6 @@ export class Clockify implements INodeType {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(responseData)) {
|
||||
|
||||
|
@ -580,6 +580,14 @@ export class Clockify implements INodeType {
|
|||
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -120,6 +120,7 @@ export class Cockpit implements INodeType {
|
|||
let responseData;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'collection') {
|
||||
const collectionName = this.getNodeParameter('collection', i) as string;
|
||||
|
||||
|
@ -163,6 +164,13 @@ export class Cockpit implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -231,6 +231,7 @@ export class Coda implements INodeType {
|
|||
if (resource === 'table') {
|
||||
// https://coda.io/developers/apis/v1beta1#operation/upsertRows
|
||||
if (operation === 'createRow') {
|
||||
try {
|
||||
const sendData = {} as IDataObject;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
qs = {};
|
||||
|
@ -273,13 +274,19 @@ export class Coda implements INodeType {
|
|||
for (const endpoint of Object.keys(sendData)) {
|
||||
await codaApiRequest.call(this, 'POST', endpoint, sendData[endpoint], (sendData[endpoint]! as IDataObject).qs! as IDataObject);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return [this.helpers.returnJsonArray({ error: error.message })];
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
// Return the incoming data
|
||||
return [items];
|
||||
}
|
||||
// https://coda.io/developers/apis/v1beta1#operation/getRow
|
||||
if (operation === 'getRow') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const tableId = this.getNodeParameter('tableId', i) as string;
|
||||
const rowId = this.getNodeParameter('rowId', i) as string;
|
||||
|
@ -304,6 +311,13 @@ export class Coda implements INodeType {
|
|||
...responseData.values,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
@ -341,6 +355,9 @@ export class Coda implements INodeType {
|
|||
responseData = responseData.items;
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return [this.helpers.returnJsonArray({ error: error.message })];
|
||||
}
|
||||
throw new NodeApiError(this.getNode(), error);
|
||||
}
|
||||
|
||||
|
@ -358,6 +375,7 @@ export class Coda implements INodeType {
|
|||
}
|
||||
// https://coda.io/developers/apis/v1beta1#operation/deleteRows
|
||||
if (operation === 'deleteRow') {
|
||||
try {
|
||||
const sendData = {} as IDataObject;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
|
@ -377,13 +395,19 @@ export class Coda implements INodeType {
|
|||
for (const endpoint of Object.keys(sendData)) {
|
||||
await codaApiRequest.call(this, 'DELETE', endpoint, { rowIds: sendData[endpoint]}, qs);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return [this.helpers.returnJsonArray({ error: error.message })];
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
// Return the incoming data
|
||||
return [items];
|
||||
}
|
||||
// https://coda.io/developers/apis/v1beta1#operation/pushButton
|
||||
if (operation === 'pushButton') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const tableId = this.getNodeParameter('tableId', i) as string;
|
||||
const rowId = this.getNodeParameter('rowId', i) as string;
|
||||
|
@ -391,24 +415,40 @@ export class Coda implements INodeType {
|
|||
const endpoint = `/docs/${docId}/tables/${tableId}/rows/${rowId}/buttons/${columnId}`;
|
||||
responseData = await codaApiRequest.call(this, 'POST', endpoint, {});
|
||||
returnData.push(responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
//https://coda.io/developers/apis/v1beta1#operation/getColumn
|
||||
if (operation === 'getColumn') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const tableId = this.getNodeParameter('tableId', i) as string;
|
||||
const columnId = this.getNodeParameter('columnId', i) as string;
|
||||
const endpoint = `/docs/${docId}/tables/${tableId}/columns/${columnId}`;
|
||||
responseData = await codaApiRequest.call(this, 'GET', endpoint, {});
|
||||
returnData.push(responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
//https://coda.io/developers/apis/v1beta1#operation/listColumns
|
||||
if (operation === 'getAllColumns') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const returnAll = this.getNodeParameter('returnAll', 0) as boolean;
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const tableId = this.getNodeParameter('tableId', i) as string;
|
||||
|
@ -421,6 +461,13 @@ export class Coda implements INodeType {
|
|||
responseData = responseData.items;
|
||||
}
|
||||
returnData.push.apply(returnData,responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
@ -429,17 +476,26 @@ export class Coda implements INodeType {
|
|||
//https://coda.io/developers/apis/v1beta1#operation/getFormula
|
||||
if (operation === 'get') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const formulaId = this.getNodeParameter('formulaId', i) as string;
|
||||
const endpoint = `/docs/${docId}/formulas/${formulaId}`;
|
||||
responseData = await codaApiRequest.call(this, 'GET', endpoint, {});
|
||||
returnData.push(responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
//https://coda.io/developers/apis/v1beta1#operation/listFormulas
|
||||
if (operation === 'getAll') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const returnAll = this.getNodeParameter('returnAll', 0) as boolean;
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const endpoint = `/docs/${docId}/formulas`;
|
||||
|
@ -451,6 +507,13 @@ export class Coda implements INodeType {
|
|||
responseData = responseData.items;
|
||||
}
|
||||
returnData.push.apply(returnData,responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
@ -459,17 +522,26 @@ export class Coda implements INodeType {
|
|||
//https://coda.io/developers/apis/v1beta1#operation/getControl
|
||||
if (operation === 'get') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const controlId = this.getNodeParameter('controlId', i) as string;
|
||||
const endpoint = `/docs/${docId}/controls/${controlId}`;
|
||||
responseData = await codaApiRequest.call(this, 'GET', endpoint, {});
|
||||
returnData.push(responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
//https://coda.io/developers/apis/v1beta1#operation/listControls
|
||||
if (operation === 'getAll') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const returnAll = this.getNodeParameter('returnAll', 0) as boolean;
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const endpoint = `/docs/${docId}/controls`;
|
||||
|
@ -481,6 +553,13 @@ export class Coda implements INodeType {
|
|||
responseData = responseData.items;
|
||||
}
|
||||
returnData.push.apply(returnData,responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
@ -500,6 +579,7 @@ export class Coda implements INodeType {
|
|||
//https://coda.io/developers/apis/v1beta1#operation/listViews
|
||||
if (operation === 'getAll') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const returnAll = this.getNodeParameter('returnAll', 0) as boolean;
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const endpoint = `/docs/${docId}/tables?tableTypes=view`;
|
||||
|
@ -511,6 +591,13 @@ export class Coda implements INodeType {
|
|||
responseData = responseData.items;
|
||||
}
|
||||
returnData.push.apply(returnData,responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
@ -543,6 +630,9 @@ export class Coda implements INodeType {
|
|||
responseData = responseData.items;
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return [this.helpers.returnJsonArray({ error: error.message })];
|
||||
}
|
||||
throw new NodeApiError(this.getNode(), error);
|
||||
}
|
||||
|
||||
|
@ -561,18 +651,27 @@ export class Coda implements INodeType {
|
|||
//https://coda.io/developers/apis/v1beta1#operation/deleteViewRow
|
||||
if (operation === 'deleteViewRow') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const viewId = this.getNodeParameter('viewId', i) as string;
|
||||
const rowId = this.getNodeParameter('rowId', i) as string;
|
||||
const endpoint = `/docs/${docId}/tables/${viewId}/rows/${rowId}`;
|
||||
responseData = await codaApiRequest.call(this, 'DELETE', endpoint);
|
||||
returnData.push.apply(returnData,responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
//https://coda.io/developers/apis/v1beta1#operation/pushViewButton
|
||||
if (operation === 'pushViewButton') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const viewId = this.getNodeParameter('viewId', i) as string;
|
||||
const rowId = this.getNodeParameter('rowId', i) as string;
|
||||
|
@ -580,11 +679,19 @@ export class Coda implements INodeType {
|
|||
const endpoint = `/docs/${docId}/tables/${viewId}/rows/${rowId}/buttons/${columnId}`;
|
||||
responseData = await codaApiRequest.call(this, 'POST', endpoint);
|
||||
returnData.push.apply(returnData,responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
if (operation === 'getAllViewColumns') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const returnAll = this.getNodeParameter('returnAll', 0) as boolean;
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const viewId = this.getNodeParameter('viewId', i) as string;
|
||||
|
@ -597,12 +704,20 @@ export class Coda implements INodeType {
|
|||
responseData = responseData.items;
|
||||
}
|
||||
returnData.push.apply(returnData,responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
//https://coda.io/developers/apis/v1beta1#operation/updateViewRow
|
||||
if (operation === 'updateViewRow') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
qs = {};
|
||||
const docId = this.getNodeParameter('docId', i) as string;
|
||||
const viewId = this.getNodeParameter('viewId', i) as string;
|
||||
|
@ -629,6 +744,13 @@ export class Coda implements INodeType {
|
|||
cells,
|
||||
};
|
||||
await codaApiRequest.call(this, 'PUT', endpoint, body, qs);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
items[i].json = { error: error.message };
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [items];
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ export class CoinGecko implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
try {
|
||||
if (resource === 'coin') {
|
||||
//https://www.coingecko.com/api/documentations/v3#/coins/get_coins__id_
|
||||
//https://www.coingecko.com/api/documentations/v3#/contract/get_coins__id__contract__contract_address_
|
||||
|
@ -531,6 +531,13 @@ export class CoinGecko implements INodeType {
|
|||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -205,6 +205,7 @@ export class Compression implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
|
||||
if (operation === 'decompress') {
|
||||
const binaryPropertyNames = (this.getNodeParameter('binaryPropertyName', 0) as string).split(',').map(key => key.trim());
|
||||
|
@ -322,6 +323,14 @@ export class Compression implements INodeType {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({json:{ error: error.message }});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return this.prepareOutputData(returnData);
|
||||
|
|
|
@ -101,6 +101,7 @@ export class Contentful implements INodeType {
|
|||
const qs: Record<string, string | number> = {};
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
if (resource === 'space') {
|
||||
if (operation === 'get') {
|
||||
|
||||
|
@ -320,6 +321,13 @@ export class Contentful implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -185,6 +185,8 @@ export class ConvertKit implements INodeType {
|
|||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
|
||||
try {
|
||||
|
||||
if (resource === 'customField') {
|
||||
if (operation === 'create') {
|
||||
|
||||
|
@ -479,6 +481,14 @@ export class ConvertKit implements INodeType {
|
|||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -204,6 +204,8 @@ export class Cortex implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
|
||||
if (resource === 'analyzer') {
|
||||
//https://github.com/TheHive-Project/CortexDocs/blob/master/api/api-guide.md#run
|
||||
if (operation === 'execute') {
|
||||
|
@ -463,6 +465,14 @@ export class Cortex implements INodeType {
|
|||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -364,6 +364,9 @@ export class Crypto implements INodeType {
|
|||
|
||||
let item: INodeExecutionData;
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
try {
|
||||
|
||||
item = items[i];
|
||||
const dataPropertyName = this.getNodeParameter('dataPropertyName', i) as string;
|
||||
const value = this.getNodeParameter('value', i) as string;
|
||||
|
@ -410,6 +413,14 @@ export class Crypto implements INodeType {
|
|||
set(newItem, `json.${dataPropertyName}`, newValue);
|
||||
|
||||
returnData.push(newItem);
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({json:{ error: error.message }});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return this.prepareOutputData(returnData);
|
||||
}
|
||||
|
|
|
@ -102,6 +102,8 @@ export class CustomerIo implements INodeType {
|
|||
let responseData;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
|
||||
try {
|
||||
|
||||
if (resource === 'campaign') {
|
||||
if (operation === 'get') {
|
||||
const campaignId = this.getNodeParameter('campaignId', i) as number;
|
||||
|
@ -336,6 +338,14 @@ export class CustomerIo implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as unknown as IDataObject);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -393,6 +393,8 @@ export class DateTime implements INodeType {
|
|||
let item: INodeExecutionData;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
|
||||
const action = this.getNodeParameter('action', 0) as string;
|
||||
item = items[i];
|
||||
|
||||
|
@ -498,6 +500,14 @@ export class DateTime implements INodeType {
|
|||
|
||||
returnData.push(newItem);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({json:{ error: error.message }});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return this.prepareOutputData(returnData);
|
||||
|
|
|
@ -108,7 +108,7 @@ export class DeepL implements INodeType {
|
|||
const responseData = [];
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
try {
|
||||
const resource = this.getNodeParameter('resource', i) as string;
|
||||
const operation = this.getNodeParameter('operation', i) as string;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
|
@ -131,6 +131,13 @@ export class DeepL implements INodeType {
|
|||
responseData.push(response.translations[0]);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
responseData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(responseData)];
|
||||
|
|
|
@ -139,6 +139,7 @@ export class Demio implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'event') {
|
||||
if (operation === 'get') {
|
||||
const id = this.getNodeParameter('eventId', i) as string;
|
||||
|
@ -205,6 +206,13 @@ export class Demio implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -150,6 +150,7 @@ export class Discourse implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'category') {
|
||||
//https://docs.discourse.org/#tag/Categories/paths/~1categories.json/post
|
||||
if (operation === 'create') {
|
||||
|
@ -489,12 +490,19 @@ export class Discourse implements INodeType {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Array.isArray(responseData)) {
|
||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -647,6 +647,7 @@ export class Disqus implements INodeType {
|
|||
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
body = {};
|
||||
qs = {};
|
||||
|
||||
|
@ -778,6 +779,13 @@ export class Disqus implements INodeType {
|
|||
} else {
|
||||
throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -102,6 +102,7 @@ export class Drift implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'contact') {
|
||||
//https://devdocs.drift.com/docs/creating-a-contact
|
||||
if (operation === 'create') {
|
||||
|
@ -159,6 +160,13 @@ export class Drift implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -811,6 +811,7 @@ export class Dropbox implements INodeType {
|
|||
}
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
body = {};
|
||||
|
||||
if (resource === 'file') {
|
||||
|
@ -1064,6 +1065,17 @@ export class Dropbox implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
if (resource === 'file' && operation === 'download'){
|
||||
items[i].json = { error: error.message };
|
||||
}else{
|
||||
returnData.push({ error: error.message });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
if (resource === 'file' && operation === 'download') {
|
||||
|
|
|
@ -957,6 +957,9 @@ export class EditImage implements INodeType {
|
|||
let item: INodeExecutionData;
|
||||
|
||||
for (let itemIndex = 0; itemIndex < length; itemIndex++) {
|
||||
|
||||
try {
|
||||
|
||||
item = items[itemIndex];
|
||||
|
||||
|
||||
|
@ -1243,6 +1246,13 @@ export class EditImage implements INodeType {
|
|||
});
|
||||
})));
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({json:{ error: error.message }});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return this.prepareOutputData(returnData);
|
||||
}
|
||||
|
|
364
packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts
Normal file
364
packages/nodes-base/nodes/Elasticsearch/Elasticsearch.node.ts
Normal file
|
@ -0,0 +1,364 @@
|
|||
import {
|
||||
IExecuteFunctions,
|
||||
} from 'n8n-core';
|
||||
|
||||
import {
|
||||
IDataObject,
|
||||
INodeExecutionData,
|
||||
INodeType,
|
||||
INodeTypeDescription,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
elasticsearchApiRequest,
|
||||
} from './GenericFunctions';
|
||||
|
||||
import {
|
||||
documentFields,
|
||||
documentOperations,
|
||||
indexFields,
|
||||
indexOperations,
|
||||
} from './descriptions';
|
||||
|
||||
import {
|
||||
DocumentGetAllOptions,
|
||||
FieldsUiValues,
|
||||
} from './types';
|
||||
|
||||
import {
|
||||
omit,
|
||||
} from 'lodash';
|
||||
|
||||
export class Elasticsearch implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'Elasticsearch',
|
||||
name: 'elasticsearch',
|
||||
icon: 'file:elasticsearch.svg',
|
||||
group: ['transform'],
|
||||
version: 1,
|
||||
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||
description: 'Consume the Elasticsearch API',
|
||||
defaults: {
|
||||
name: 'Elasticsearch',
|
||||
color: '#f3d337',
|
||||
},
|
||||
inputs: ['main'],
|
||||
outputs: ['main'],
|
||||
credentials: [
|
||||
{
|
||||
name: 'elasticsearchApi',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Resource',
|
||||
name: 'resource',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Document',
|
||||
value: 'document',
|
||||
},
|
||||
{
|
||||
name: 'Index',
|
||||
value: 'index',
|
||||
},
|
||||
],
|
||||
default: 'document',
|
||||
description: 'Resource to consume',
|
||||
},
|
||||
...documentOperations,
|
||||
...documentFields,
|
||||
...indexOperations,
|
||||
...indexFields,
|
||||
],
|
||||
};
|
||||
|
||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||
const items = this.getInputData();
|
||||
const returnData: IDataObject[] = [];
|
||||
|
||||
const resource = this.getNodeParameter('resource', 0) as 'document' | 'index';
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
||||
let responseData;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
|
||||
if (resource === 'document') {
|
||||
|
||||
// **********************************************************************
|
||||
// document
|
||||
// **********************************************************************
|
||||
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html
|
||||
|
||||
if (operation === 'delete') {
|
||||
|
||||
// ----------------------------------------
|
||||
// document: delete
|
||||
// ----------------------------------------
|
||||
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete.html
|
||||
|
||||
const indexId = this.getNodeParameter('indexId', i);
|
||||
const documentId = this.getNodeParameter('documentId', i);
|
||||
|
||||
const endpoint = `/${indexId}/_doc/${documentId}`;
|
||||
responseData = await elasticsearchApiRequest.call(this, 'DELETE', endpoint);
|
||||
|
||||
} else if (operation === 'get') {
|
||||
|
||||
// ----------------------------------------
|
||||
// document: get
|
||||
// ----------------------------------------
|
||||
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html
|
||||
|
||||
const indexId = this.getNodeParameter('indexId', i);
|
||||
const documentId = this.getNodeParameter('documentId', i);
|
||||
|
||||
const qs = {} as IDataObject;
|
||||
const options = this.getNodeParameter('options', i) as IDataObject;
|
||||
|
||||
if (Object.keys(options).length) {
|
||||
Object.assign(qs, options);
|
||||
qs._source = true;
|
||||
}
|
||||
|
||||
const endpoint = `/${indexId}/_doc/${documentId}`;
|
||||
responseData = await elasticsearchApiRequest.call(this, 'GET', endpoint, {}, qs);
|
||||
|
||||
const simple = this.getNodeParameter('simple', i) as IDataObject;
|
||||
|
||||
if (simple) {
|
||||
responseData = {
|
||||
_id: responseData._id,
|
||||
...responseData._source,
|
||||
};
|
||||
}
|
||||
|
||||
} else if (operation === 'getAll') {
|
||||
|
||||
// ----------------------------------------
|
||||
// document: getAll
|
||||
// ----------------------------------------
|
||||
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html
|
||||
|
||||
const indexId = this.getNodeParameter('indexId', i);
|
||||
|
||||
const body = {} as IDataObject;
|
||||
const qs = {} as IDataObject;
|
||||
const options = this.getNodeParameter('options', i) as DocumentGetAllOptions;
|
||||
|
||||
if (Object.keys(options).length) {
|
||||
const { query, ...rest } = options;
|
||||
if (query) Object.assign(body, JSON.parse(query));
|
||||
Object.assign(qs, rest);
|
||||
qs._source = true;
|
||||
}
|
||||
|
||||
const returnAll = this.getNodeParameter('returnAll', 0);
|
||||
|
||||
if (!returnAll) {
|
||||
qs.size = this.getNodeParameter('limit', 0);
|
||||
}
|
||||
|
||||
responseData = await elasticsearchApiRequest.call(this, 'GET', `/${indexId}/_search`, body, qs);
|
||||
responseData = responseData.hits.hits;
|
||||
|
||||
const simple = this.getNodeParameter('simple', 0) as IDataObject;
|
||||
|
||||
if (simple) {
|
||||
responseData = responseData.map((item: IDataObject) => {
|
||||
return {
|
||||
_id: item._id,
|
||||
...(item._source as {}),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
} else if (operation === 'create') {
|
||||
|
||||
// ----------------------------------------
|
||||
// document: create
|
||||
// ----------------------------------------
|
||||
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html
|
||||
|
||||
const body: IDataObject = {};
|
||||
|
||||
const dataToSend = this.getNodeParameter('dataToSend', 0) as 'defineBelow' | 'autoMapInputData';
|
||||
|
||||
if (dataToSend === 'defineBelow') {
|
||||
|
||||
const fields = this.getNodeParameter('fieldsUi.fieldValues', i, []) as FieldsUiValues;
|
||||
fields.forEach(({ fieldId, fieldValue }) => body[fieldId] = fieldValue);
|
||||
|
||||
} else {
|
||||
|
||||
const inputData = items[i].json;
|
||||
const rawInputsToIgnore = this.getNodeParameter('inputsToIgnore', i) as string;
|
||||
const inputsToIgnore = rawInputsToIgnore.split(',').map(c => c.trim());
|
||||
|
||||
for (const key of Object.keys(inputData)) {
|
||||
if (inputsToIgnore.includes(key)) continue;
|
||||
body[key] = inputData[key];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const qs = {} as IDataObject;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
|
||||
if (Object.keys(additionalFields).length) {
|
||||
Object.assign(qs, omit(additionalFields, ['documentId']));
|
||||
}
|
||||
|
||||
const indexId = this.getNodeParameter('indexId', i);
|
||||
const { documentId } = additionalFields;
|
||||
|
||||
if (documentId) {
|
||||
const endpoint = `/${indexId}/_doc/${documentId}`;
|
||||
responseData = await elasticsearchApiRequest.call(this, 'PUT', endpoint, body);
|
||||
} else {
|
||||
const endpoint = `/${indexId}/_doc`;
|
||||
responseData = await elasticsearchApiRequest.call(this, 'POST', endpoint, body);
|
||||
}
|
||||
|
||||
} else if (operation === 'update') {
|
||||
|
||||
// ----------------------------------------
|
||||
// document: update
|
||||
// ----------------------------------------
|
||||
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html
|
||||
|
||||
const body = { doc: {} } as { doc: { [key: string]: string } };
|
||||
|
||||
const dataToSend = this.getNodeParameter('dataToSend', 0) as 'defineBelow' | 'autoMapInputData';
|
||||
|
||||
if (dataToSend === 'defineBelow') {
|
||||
|
||||
const fields = this.getNodeParameter('fieldsUi.fieldValues', i, []) as FieldsUiValues;
|
||||
fields.forEach(({ fieldId, fieldValue }) => body.doc[fieldId] = fieldValue);
|
||||
|
||||
} else {
|
||||
|
||||
const inputData = items[i].json;
|
||||
const rawInputsToIgnore = this.getNodeParameter('inputsToIgnore', i) as string;
|
||||
const inputsToIgnore = rawInputsToIgnore.split(',').map(c => c.trim());
|
||||
|
||||
for (const key of Object.keys(inputData)) {
|
||||
if (inputsToIgnore.includes(key)) continue;
|
||||
body.doc[key] = inputData[key] as string;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const indexId = this.getNodeParameter('indexId', i);
|
||||
const documentId = this.getNodeParameter('documentId', i);
|
||||
|
||||
const endpoint = `/${indexId}/_update/${documentId}`;
|
||||
responseData = await elasticsearchApiRequest.call(this, 'POST', endpoint, body);
|
||||
|
||||
}
|
||||
|
||||
} else if (resource === 'index') {
|
||||
|
||||
// **********************************************************************
|
||||
// index
|
||||
// **********************************************************************
|
||||
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/indices.html
|
||||
|
||||
if (operation === 'create') {
|
||||
|
||||
// ----------------------------------------
|
||||
// index: create
|
||||
// ----------------------------------------
|
||||
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html
|
||||
|
||||
const indexId = this.getNodeParameter('indexId', i);
|
||||
|
||||
const body = {} as IDataObject;
|
||||
const qs = {} as IDataObject;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
|
||||
if (Object.keys(additionalFields).length) {
|
||||
const { aliases, mappings, settings, ...rest } = additionalFields;
|
||||
Object.assign(body, aliases, mappings, settings);
|
||||
Object.assign(qs, rest);
|
||||
}
|
||||
|
||||
responseData = await elasticsearchApiRequest.call(this, 'PUT', `/${indexId}`);
|
||||
responseData = { id: indexId, ...responseData };
|
||||
delete responseData.index;
|
||||
|
||||
} else if (operation === 'delete') {
|
||||
|
||||
// ----------------------------------------
|
||||
// index: delete
|
||||
// ----------------------------------------
|
||||
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-delete-index.html
|
||||
|
||||
const indexId = this.getNodeParameter('indexId', i);
|
||||
|
||||
responseData = await elasticsearchApiRequest.call(this, 'DELETE', `/${indexId}`);
|
||||
responseData = { success: true };
|
||||
|
||||
} else if (operation === 'get') {
|
||||
|
||||
// ----------------------------------------
|
||||
// index: get
|
||||
// ----------------------------------------
|
||||
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-index.html
|
||||
|
||||
const indexId = this.getNodeParameter('indexId', i) as string;
|
||||
|
||||
const qs = {} as IDataObject;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
|
||||
if (Object.keys(additionalFields).length) {
|
||||
Object.assign(qs, additionalFields);
|
||||
}
|
||||
|
||||
responseData = await elasticsearchApiRequest.call(this, 'GET', `/${indexId}`, {}, qs);
|
||||
responseData = { id: indexId, ...responseData[indexId] };
|
||||
|
||||
} else if (operation === 'getAll') {
|
||||
|
||||
// ----------------------------------------
|
||||
// index: getAll
|
||||
// ----------------------------------------
|
||||
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html
|
||||
|
||||
responseData = await elasticsearchApiRequest.call(this, 'GET', '/_aliases');
|
||||
responseData = Object.keys(responseData).map(i => ({ indexId: i }));
|
||||
|
||||
const returnAll = this.getNodeParameter('returnAll', i);
|
||||
|
||||
if (!returnAll) {
|
||||
const limit = this.getNodeParameter('limit', i) as number;
|
||||
responseData = responseData.slice(0, limit);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Array.isArray(responseData)
|
||||
? returnData.push(...responseData)
|
||||
: returnData.push(responseData);
|
||||
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
}
|
58
packages/nodes-base/nodes/Elasticsearch/GenericFunctions.ts
Normal file
58
packages/nodes-base/nodes/Elasticsearch/GenericFunctions.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
import {
|
||||
OptionsWithUri,
|
||||
} from 'request';
|
||||
|
||||
import {
|
||||
IExecuteFunctions,
|
||||
} from 'n8n-core';
|
||||
|
||||
import {
|
||||
IDataObject,
|
||||
NodeApiError,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
ElasticsearchApiCredentials,
|
||||
} from './types';
|
||||
|
||||
export async function elasticsearchApiRequest(
|
||||
this: IExecuteFunctions,
|
||||
method: 'GET' | 'PUT' | 'POST' | 'DELETE',
|
||||
endpoint: string,
|
||||
body: IDataObject = {},
|
||||
qs: IDataObject = {},
|
||||
) {
|
||||
const {
|
||||
username,
|
||||
password,
|
||||
baseUrl,
|
||||
} = this.getCredentials('elasticsearchApi') as ElasticsearchApiCredentials;
|
||||
|
||||
const token = Buffer.from(`${username}:${password}`).toString('base64');
|
||||
|
||||
const options: OptionsWithUri = {
|
||||
headers: {
|
||||
Authorization: `Basic ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
method,
|
||||
body,
|
||||
qs,
|
||||
uri: `${baseUrl}${endpoint}`,
|
||||
json: true,
|
||||
};
|
||||
|
||||
if (!Object.keys(body).length) {
|
||||
delete options.body;
|
||||
}
|
||||
|
||||
if (!Object.keys(qs).length) {
|
||||
delete options.qs;
|
||||
}
|
||||
|
||||
try {
|
||||
return await this.helpers.request(options);
|
||||
} catch (error) {
|
||||
throw new NodeApiError(this.getNode(), error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,788 @@
|
|||
import {
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import * as placeholders from './placeholders';
|
||||
|
||||
export const documentOperations = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
description: 'Create a document',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
description: 'Delete a document',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
description: 'Get a document',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
value: 'getAll',
|
||||
description: 'Get all documents',
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
value: 'update',
|
||||
description: 'Update a document',
|
||||
},
|
||||
],
|
||||
default: 'get',
|
||||
description: 'Operation to perform',
|
||||
},
|
||||
] as INodeProperties[];
|
||||
|
||||
export const documentFields = [
|
||||
// ----------------------------------------
|
||||
// document: delete
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Index ID',
|
||||
name: 'indexId',
|
||||
description: 'ID of the index containing the document to delete',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'delete',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Document ID',
|
||||
name: 'documentId',
|
||||
description: 'ID of the document to delete',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'delete',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// document: get
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Index ID',
|
||||
name: 'indexId',
|
||||
description: 'ID of the index containing the document to retrieve',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Document ID',
|
||||
name: 'documentId',
|
||||
description: 'ID of the document to retrieve',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Simple',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Options',
|
||||
name: 'options',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Option',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Source Excludes',
|
||||
name: '_source_excludes',
|
||||
description: 'Comma-separated list of source fields to exclude from the response',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Source Includes',
|
||||
name: '_source_includes',
|
||||
description: 'Comma-separated list of source fields to include in the response',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Stored Fields',
|
||||
name: 'stored_fields',
|
||||
description: 'If true, retrieve the document fields stored in the index rather than the document <code>_source</code>. Defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// document: getAll
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Index ID',
|
||||
name: 'indexId',
|
||||
description: 'ID of the index containing the documents to retrieve',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
default: 50,
|
||||
description: 'How many results to return',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
returnAll: [
|
||||
false,
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Simple',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Options',
|
||||
name: 'options',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Option',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Allow No Indices',
|
||||
name: 'allow_no_indices',
|
||||
description: 'If false, return an error if any of the following targets only missing/closed indices: wildcard expression, index alias, or <code>_all</code> value. Defaults to true',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
displayName: 'Allow Partial Search Results',
|
||||
name: 'allow_partial_search_results',
|
||||
description: 'If true, return partial results if there are shard request timeouts or shard failures.<br>If false, returns an error with no partial results. Defaults to true',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
displayName: 'Batched Reduce Size',
|
||||
name: 'batched_reduce_size',
|
||||
description: 'Number of shard results that should be reduced at once on the coordinating node. Defaults to 512',
|
||||
type: 'number',
|
||||
typeOptions: {
|
||||
minValue: 2,
|
||||
},
|
||||
default: 512,
|
||||
},
|
||||
{
|
||||
displayName: 'CCS Minimize Roundtrips',
|
||||
name: 'ccs_minimize_roundtrips',
|
||||
description: 'If true, network round-trips between the coordinating node and the remote clusters are minimized when executing cross-cluster search (CCS) requests. Defaults to true',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
displayName: 'Doc Value Fields',
|
||||
name: 'docvalue_fields',
|
||||
description: 'Comma-separated list of fields to return as the docvalue representation of a field for each hit',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Expand Wildcards',
|
||||
name: 'expand_wildcards',
|
||||
description: 'Type of index that wildcard expressions can match. Defaults to <code>open</code>',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'All',
|
||||
value: 'all',
|
||||
},
|
||||
{
|
||||
name: 'Closed',
|
||||
value: 'closed',
|
||||
},
|
||||
{
|
||||
name: 'Hidden',
|
||||
value: 'hidden',
|
||||
},
|
||||
{
|
||||
name: 'None',
|
||||
value: 'none',
|
||||
},
|
||||
{
|
||||
name: 'Open',
|
||||
value: 'open',
|
||||
},
|
||||
],
|
||||
default: 'open',
|
||||
},
|
||||
{
|
||||
displayName: 'Explain',
|
||||
name: 'explain',
|
||||
description: 'If true, return detailed information about score computation as part of a hit. Defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName: 'Ignore Throttled',
|
||||
name: 'ignore_throttled',
|
||||
description: 'If true, concrete, expanded or aliased indices are ignored when frozen. Defaults to true',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
displayName: 'Ignore Unavailable',
|
||||
name: 'ignore_unavailable',
|
||||
description: 'If true, missing or closed indices are not included in the response. Defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName: 'Max Concurrent Shard Requests',
|
||||
name: 'max_concurrent_shard_requests',
|
||||
description: 'Define the number of shard requests per node this search executes concurrently. Defaults to 5',
|
||||
type: 'number',
|
||||
default: 5,
|
||||
},
|
||||
{
|
||||
displayName: 'Pre-Filter Shard Size',
|
||||
name: 'pre_filter_shard_size',
|
||||
description: 'Define a threshold that enforces a pre-filter roundtrip to prefilter search shards based on query rewriting.<br>Only used if the number of shards the search request expands to exceeds the threshold',
|
||||
type: 'number',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
},
|
||||
default: 1,
|
||||
},
|
||||
{
|
||||
displayName: 'Query',
|
||||
name: 'query',
|
||||
description: 'Query in the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html" target="_blank">Elasticsearch Query DSL</a>',
|
||||
type: 'json',
|
||||
typeOptions: {
|
||||
alwaysOpenEditWindow: true,
|
||||
},
|
||||
default: '',
|
||||
placeholder: placeholders.query,
|
||||
},
|
||||
{
|
||||
displayName: 'Request Cache',
|
||||
name: 'request_cache',
|
||||
description: 'If true, the caching of search results is enabled for requests where size is 0. See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/shard-request-cache.html" target="_blank">Elasticsearch shard request cache settings</a>',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName: 'Routing',
|
||||
name: 'routing',
|
||||
description: 'Target this primary shard',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Search Type',
|
||||
name: 'search_type',
|
||||
description: 'How distributed term frequencies are calculated for relevance scoring. Defaults to Query then Fetch',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'DFS Query Then Fetch',
|
||||
value: 'dfs_query_then_fetch',
|
||||
},
|
||||
{
|
||||
name: 'Query Then Fetch',
|
||||
value: 'query_then_fetch',
|
||||
},
|
||||
],
|
||||
default: 'query_then_fetch',
|
||||
},
|
||||
{
|
||||
displayName: 'Sequence Number and Primary Term',
|
||||
name: 'seq_no_primary_term',
|
||||
description: 'If true, return the sequence number and primary term of the last modification of each hit. See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/optimistic-concurrency-control.html" target="_blank">Optimistic concurrency control</a>',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName: 'Sort',
|
||||
name: 'sort',
|
||||
description: 'Comma-separated list of <code>field:direction</code> pairs',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Stats',
|
||||
name: 'stats',
|
||||
description: 'Tag of the request for logging and statistical purposes',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Stored Fields',
|
||||
name: 'stored_fields',
|
||||
description: 'If true, retrieve the document fields stored in the index rather than the document <code>_source</code>. Defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName: 'Terminate After',
|
||||
name: 'terminate_after',
|
||||
description: 'Max number of documents to collect for each shard',
|
||||
type: 'number',
|
||||
default: 0,
|
||||
},
|
||||
{
|
||||
displayName: 'Timeout',
|
||||
name: 'timeout',
|
||||
description: 'Period to wait for active shards. Defaults to <code>1m</code> (one minute). See the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#time-units" target="_blank">Elasticsearch time units reference</a>',
|
||||
type: 'string',
|
||||
default: '1m',
|
||||
},
|
||||
{
|
||||
displayName: 'Track Scores',
|
||||
name: 'track_scores',
|
||||
description: 'If true, calculate and return document scores, even if the scores are not used for sorting. Defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName: 'Track Total Hits',
|
||||
name: 'track_total_hits',
|
||||
description: 'Number of hits matching the query to count accurately. Defaults to 10000',
|
||||
type: 'number',
|
||||
default: 10000,
|
||||
},
|
||||
{
|
||||
displayName: 'Version',
|
||||
name: 'version',
|
||||
description: 'If true, return document version as part of a hit. Defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// document: create
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Index ID',
|
||||
name: 'indexId',
|
||||
description: 'ID of the index to add the document to',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Data to Send',
|
||||
name: 'dataToSend',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Define Below for Each Column',
|
||||
value: 'defineBelow',
|
||||
description: 'Set the value for each destination column',
|
||||
},
|
||||
{
|
||||
name: 'Auto-map Input Data to Columns',
|
||||
value: 'autoMapInputData',
|
||||
description: 'Use when node input properties match destination column names',
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: 'defineBelow',
|
||||
description: 'Whether to insert the input data this node receives in the new row',
|
||||
},
|
||||
{
|
||||
displayName: 'Inputs to Ignore',
|
||||
name: 'inputsToIgnore',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
dataToSend: [
|
||||
'autoMapInputData',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
required: false,
|
||||
description: 'List of input properties to avoid sending, separated by commas. Leave empty to send all properties',
|
||||
placeholder: 'Enter properties...',
|
||||
},
|
||||
{
|
||||
displayName: 'Fields to Send',
|
||||
name: 'fieldsUi',
|
||||
placeholder: 'Add Field',
|
||||
type: 'fixedCollection',
|
||||
typeOptions: {
|
||||
multipleValueButtonText: 'Add Field to Send',
|
||||
multipleValues: true,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
dataToSend: [
|
||||
'defineBelow',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Field',
|
||||
name: 'fieldValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Field Name',
|
||||
name: 'fieldId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Field Value',
|
||||
name: 'fieldValue',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Document ID',
|
||||
name: 'documentId',
|
||||
description: 'ID of the document to create and add to the index',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Routing',
|
||||
name: 'routing',
|
||||
description: 'Target this primary shard',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Timeout',
|
||||
name: 'timeout',
|
||||
description: 'Period to wait for active shards. Defaults to <code>1m</code> (one minute). See the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#time-units" target="_blank">Elasticsearch time units reference</a>',
|
||||
type: 'string',
|
||||
default: '1m',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// document: update
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Index ID',
|
||||
name: 'indexId',
|
||||
description: 'ID of the document to update',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'update',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Document ID',
|
||||
name: 'documentId',
|
||||
description: 'ID of the document to update',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'update',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Data to Send',
|
||||
name: 'dataToSend',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'Define Below for Each Column',
|
||||
value: 'defineBelow',
|
||||
description: 'Set the value for each destination column',
|
||||
},
|
||||
{
|
||||
name: 'Auto-map Input Data to Columns',
|
||||
value: 'autoMapInputData',
|
||||
description: 'Use when node input properties match destination column names',
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'update',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: 'defineBelow',
|
||||
description: 'Whether to insert the input data this node receives in the new row',
|
||||
},
|
||||
{
|
||||
displayName: 'Inputs to Ignore',
|
||||
name: 'inputsToIgnore',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'update',
|
||||
],
|
||||
dataToSend: [
|
||||
'autoMapInputData',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
required: false,
|
||||
description: 'List of input properties to avoid sending, separated by commas. Leave empty to send all properties',
|
||||
placeholder: 'Enter properties...',
|
||||
},
|
||||
{
|
||||
displayName: 'Fields to Send',
|
||||
name: 'fieldsUi',
|
||||
placeholder: 'Add Field',
|
||||
type: 'fixedCollection',
|
||||
typeOptions: {
|
||||
multipleValueButtonText: 'Add Field to Send',
|
||||
multipleValues: true,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'document',
|
||||
],
|
||||
operation: [
|
||||
'update',
|
||||
],
|
||||
dataToSend: [
|
||||
'defineBelow',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Field',
|
||||
name: 'fieldValues',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Field Name',
|
||||
name: 'fieldId',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Field Value',
|
||||
name: 'fieldValue',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
] as INodeProperties[];
|
|
@ -0,0 +1,322 @@
|
|||
import {
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import * as placeholders from './placeholders';
|
||||
|
||||
export const indexOperations = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'index',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Create',
|
||||
value: 'create',
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
value: 'delete',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
value: 'getAll',
|
||||
},
|
||||
],
|
||||
default: 'create',
|
||||
description: 'Operation to perform',
|
||||
},
|
||||
] as INodeProperties[];
|
||||
|
||||
export const indexFields = [
|
||||
// ----------------------------------------
|
||||
// index: create
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Index ID',
|
||||
name: 'indexId',
|
||||
description: 'ID of the index to create',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'index',
|
||||
],
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'index',
|
||||
],
|
||||
operation: [
|
||||
'create',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Aliases',
|
||||
name: 'aliases',
|
||||
description: 'Index aliases which include the index, as an <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html" target="_blank">alias object</a>',
|
||||
type: 'json',
|
||||
typeOptions: {
|
||||
alwaysOpenEditWindow: true,
|
||||
},
|
||||
default: '',
|
||||
placeholder: placeholders.aliases,
|
||||
},
|
||||
{
|
||||
displayName: 'Include Type Name',
|
||||
name: 'include_type_name',
|
||||
description: 'If true, a mapping type is expected in the body of mappings. Defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName: 'Mappings',
|
||||
name: 'mappings',
|
||||
description: 'Mapping for fields in the index, as <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html" target="_blank">mapping object</a>',
|
||||
type: 'json',
|
||||
typeOptions: {
|
||||
alwaysOpenEditWindow: true,
|
||||
},
|
||||
default: '',
|
||||
placeholder: placeholders.mappings,
|
||||
},
|
||||
{
|
||||
displayName: 'Master Timeout',
|
||||
name: 'master_timeout',
|
||||
description: 'Period to wait for a connection to the master node. If no response is received before the timeout expires,<br>the request fails and returns an error. Defaults to <code>1m</code>. See the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#time-units" target="_blank">Elasticsearch time units reference</a>',
|
||||
type: 'string',
|
||||
default: '1m',
|
||||
},
|
||||
{
|
||||
displayName: 'Settings',
|
||||
name: 'settings',
|
||||
description: 'Configuration options for the index, as an <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#index-modules-settings" target="_blank">index settings object</a>',
|
||||
type: 'json',
|
||||
typeOptions: {
|
||||
alwaysOpenEditWindow: true,
|
||||
},
|
||||
default: '',
|
||||
placeholder: placeholders.indexSettings,
|
||||
},
|
||||
{
|
||||
displayName: 'Timeout',
|
||||
name: 'timeout',
|
||||
description: 'Period to wait for a response. If no response is received before the timeout expires, the request<br>fails and returns an error. Defaults to <code>30s</code>. See the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#time-units" target="_blank">Elasticsearch time units reference</a>',
|
||||
type: 'string',
|
||||
default: '30s',
|
||||
},
|
||||
{
|
||||
displayName: 'Wait for Active Shards',
|
||||
name: 'wait_for_active_shards',
|
||||
description: 'The number of shard copies that must be active before proceeding with the operation. Set to <code>all</code><br>or any positive integer up to the total number of shards in the index. Default: 1, the primary shard',
|
||||
type: 'string',
|
||||
default: '1',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// index: delete
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Index ID',
|
||||
name: 'indexId',
|
||||
description: 'ID of the index to delete',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'index',
|
||||
],
|
||||
operation: [
|
||||
'delete',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// index: get
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Index ID',
|
||||
name: 'indexId',
|
||||
description: 'ID of the index to retrieve',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'index',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Additional Fields',
|
||||
name: 'additionalFields',
|
||||
type: 'collection',
|
||||
placeholder: 'Add Field',
|
||||
default: {},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'index',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Allow No Indices',
|
||||
name: 'allow_no_indices',
|
||||
description: 'If false, return an error if any of the following targets only missing/closed indices: wildcard expression, index alias, or <code>_all</code> value. Defaults to true',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
displayName: 'Expand Wildcards',
|
||||
name: 'expand_wildcards',
|
||||
description: 'Type of index that wildcard expressions can match. Defaults to <code>open</code>',
|
||||
type: 'options',
|
||||
options: [
|
||||
{
|
||||
name: 'All',
|
||||
value: 'all',
|
||||
},
|
||||
{
|
||||
name: 'Closed',
|
||||
value: 'closed',
|
||||
},
|
||||
{
|
||||
name: 'Hidden',
|
||||
value: 'hidden',
|
||||
},
|
||||
{
|
||||
name: 'None',
|
||||
value: 'none',
|
||||
},
|
||||
{
|
||||
name: 'Open',
|
||||
value: 'open',
|
||||
},
|
||||
],
|
||||
default: 'all',
|
||||
},
|
||||
{
|
||||
displayName: 'Flat Settings',
|
||||
name: 'flat_settings',
|
||||
description: 'If true, return settings in flat format. Defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName: 'Ignore Unavailable',
|
||||
name: 'ignore_unavailable',
|
||||
description: 'If false, requests that target a missing index return an error. Defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName: 'Include Defaults',
|
||||
name: 'include_defaults',
|
||||
description: 'If true, return all default settings in the response. Defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName: 'Local',
|
||||
name: 'local',
|
||||
description: 'If true, retrieve information from the local node only. Defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
displayName: 'Master Timeout',
|
||||
name: 'master_timeout',
|
||||
description: 'Period to wait for a connection to the master node. If no response is received before the timeout expires,<br>the request fails and returns an error. Defaults to <code>1m</code>. See the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#time-units" target="_blank">Elasticsearch time units reference</a>',
|
||||
type: 'string',
|
||||
default: '1m',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// ----------------------------------------
|
||||
// index: getAll
|
||||
// ----------------------------------------
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description: 'Whether to return all results or only up to a given limit',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'index',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Limit',
|
||||
name: 'limit',
|
||||
type: 'number',
|
||||
default: 50,
|
||||
description: 'How many results to return',
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'index',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
returnAll: [
|
||||
false,
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
] as INodeProperties[];
|
|
@ -0,0 +1,2 @@
|
|||
export * from './DocumentDescription';
|
||||
export * from './IndexDescription';
|
|
@ -0,0 +1,43 @@
|
|||
export const indexSettings = `{
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_shards": 3,
|
||||
"number_of_replicas": 2
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
export const mappings = `{
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"field1": { "type": "text" }
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
export const aliases = `{
|
||||
"aliases": {
|
||||
"alias_1": {},
|
||||
"alias_2": {
|
||||
"filter": {
|
||||
"term": { "user.id": "kimchy" }
|
||||
},
|
||||
"routing": "shard-1"
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
export const query = `{
|
||||
"query": {
|
||||
"term": {
|
||||
"user.id": "john"
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
export const document = `{
|
||||
"timestamp": "2099-05-06T16:21:15.000Z",
|
||||
"event": {
|
||||
"original": "192.0.2.42 - - [06/May/2099:16:21:15 +0000] \"GET /images/bg.jpg HTTP/1.0\" 200 24736"
|
||||
}
|
||||
}`;
|
14
packages/nodes-base/nodes/Elasticsearch/elasticsearch.svg
Normal file
14
packages/nodes-base/nodes/Elasticsearch/elasticsearch.svg
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="64px" height="64px" viewBox="6 5 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 63.1 (92452) - https://sketch.com -->
|
||||
<title>elastic-search-logo-color-64px</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="elastic-search-logo-color-64px" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="bounding-box" x="0" y="0" width="64" height="64"></rect>
|
||||
<g id="group" transform="translate(8.000000, 4.999500)">
|
||||
<path d="M47.7246,9.708 L47.7276,9.702 C42.7746,3.774 35.3286,0 26.9996,0 C16.4006,0 7.2326,6.112 2.8136,15 L38.0056,15 C40.5306,15 42.9886,14.13 44.9206,12.504 C45.9246,11.659 46.8636,10.739 47.7246,9.708" id="Fill-1" fill="#FEC514"></path>
|
||||
<path d="M0,27.0005 C0,29.4225 0.324,31.7675 0.922,34.0005 L34,34.0005 C37.866,34.0005 41,30.8665 41,27.0005 C41,23.1345 37.866,20.0005 34,20.0005 L0.922,20.0005 C0.324,22.2335 0,24.5785 0,27.0005" id="Fill-4" fill="#343741"></path>
|
||||
<path d="M47.7246,44.293 L47.7276,44.299 C42.7746,50.227 35.3286,54.001 26.9996,54.001 C16.4006,54.001 7.2326,47.889 2.8136,39.001 L38.0056,39.001 C40.5306,39.001 42.9886,39.871 44.9206,41.497 C45.9246,42.342 46.8636,43.262 47.7246,44.293" id="Fill-6" fill="#00BFB3"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
40
packages/nodes-base/nodes/Elasticsearch/types.d.ts
vendored
Normal file
40
packages/nodes-base/nodes/Elasticsearch/types.d.ts
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
export type ElasticsearchApiCredentials = {
|
||||
username: string;
|
||||
password: string;
|
||||
baseUrl: string;
|
||||
};
|
||||
|
||||
export type DocumentGetAllOptions = Partial<{
|
||||
allow_no_indices: boolean;
|
||||
allow_partial_search_results: boolean;
|
||||
batched_reduce_size: number;
|
||||
ccs_minimize_roundtrips: boolean;
|
||||
docvalue_fields: string;
|
||||
expand_wildcards: 'All' | 'Closed' | 'Hidden' | 'None' | 'Open';
|
||||
explain: boolean;
|
||||
ignore_throttled: boolean;
|
||||
ignore_unavailable: boolean;
|
||||
max_concurrent_shard_requests: number;
|
||||
pre_filter_shard_size: number;
|
||||
query: string;
|
||||
request_cache: boolean;
|
||||
routing: string;
|
||||
search_type: 'query_then_fetch' | 'dfs_query_then_fetch';
|
||||
seq_no_primary_term: boolean;
|
||||
sort: string;
|
||||
_source: boolean;
|
||||
_source_excludes: string;
|
||||
_source_includes: string;
|
||||
stats: string;
|
||||
stored_fields: boolean;
|
||||
terminate_after: boolean;
|
||||
timeout: number;
|
||||
track_scores: boolean;
|
||||
track_total_hits: string;
|
||||
version: boolean;
|
||||
}>;
|
||||
|
||||
export type FieldsUiValues = Array<{
|
||||
fieldId: string;
|
||||
fieldValue: string;
|
||||
}>;
|
|
@ -133,6 +133,7 @@ export class EmailSend implements INodeType {
|
|||
let item: INodeExecutionData;
|
||||
|
||||
for (let itemIndex = 0; itemIndex < length; itemIndex++) {
|
||||
try {
|
||||
|
||||
item = items[itemIndex];
|
||||
|
||||
|
@ -211,6 +212,14 @@ export class EmailSend implements INodeType {
|
|||
const info = await transporter.sendMail(mailOptions);
|
||||
|
||||
returnData.push({ json: info as unknown as IDataObject });
|
||||
|
||||
}catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({json:{ error: error.message }});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return this.prepareOutputData(returnData);
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
INodeExecutionData,
|
||||
INodeType,
|
||||
INodeTypeDescription,
|
||||
NodeOperationError
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import { exec } from 'child_process';
|
||||
|
@ -24,6 +25,7 @@ export interface IExecReturnData {
|
|||
*/
|
||||
function execPromise(command: string): Promise<IExecReturnData> {
|
||||
const returnData: IExecReturnData = {
|
||||
error: undefined,
|
||||
exitCode: 0,
|
||||
stderr: '',
|
||||
stdout: '',
|
||||
|
@ -94,15 +96,22 @@ export class ExecuteCommand implements INodeType {
|
|||
|
||||
const returnItems: INodeExecutionData[] = [];
|
||||
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
||||
|
||||
try{
|
||||
|
||||
command = this.getNodeParameter('command', itemIndex) as string;
|
||||
|
||||
const {
|
||||
// error, TODO: Later make it possible to select if it should fail on error or not
|
||||
error,
|
||||
exitCode,
|
||||
stdout,
|
||||
stderr,
|
||||
} = await execPromise(command);
|
||||
|
||||
if (error !== undefined) {
|
||||
throw new NodeOperationError(this.getNode(), error.message);
|
||||
}
|
||||
|
||||
returnItems.push(
|
||||
{
|
||||
json: {
|
||||
|
@ -112,6 +121,14 @@ export class ExecuteCommand implements INodeType {
|
|||
},
|
||||
},
|
||||
);
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnItems.push({json:{ error: error.message }});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return this.prepareOutputData(returnItems);
|
||||
|
|
|
@ -149,6 +149,9 @@ export class ExecuteWorkflow implements INodeType {
|
|||
const source = this.getNodeParameter('source', 0) as string;
|
||||
|
||||
const workflowInfo: IExecuteWorkflowInfo = {};
|
||||
|
||||
try {
|
||||
|
||||
if (source === 'database') {
|
||||
// Read workflow from database
|
||||
workflowInfo.id = this.getNodeParameter('workflowId', 0) as string;
|
||||
|
@ -197,5 +200,13 @@ export class ExecuteWorkflow implements INodeType {
|
|||
const receivedData = await this.executeWorkflow(workflowInfo, items);
|
||||
|
||||
return receivedData;
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return this.prepareOutputData([{json:{ error: error.message }}]);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1148,6 +1148,7 @@ export class Freshdesk implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
if (resource === 'ticket') {
|
||||
//https://developers.freshdesk.com/api/#create_ticket
|
||||
if (operation === 'create') {
|
||||
|
@ -1426,6 +1427,13 @@ export class Freshdesk implements INodeType {
|
|||
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -378,6 +378,7 @@ export class Ftp implements INodeType {
|
|||
} else {
|
||||
credentials = this.getCredentials('ftp');
|
||||
}
|
||||
try {
|
||||
|
||||
if (credentials === undefined) {
|
||||
throw new NodeOperationError(this.getNode(), 'Failed to get credentials!');
|
||||
|
@ -635,6 +636,13 @@ export class Ftp implements INodeType {
|
|||
await ftp!.end();
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return this.prepareOutputData([{json:{ error: error.message }}]);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
return [returnItems];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,11 +102,6 @@ return items;`,
|
|||
try {
|
||||
// Execute the function code
|
||||
items = (await vm.run(`module.exports = async function() {${functionCode}}()`, __dirname));
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
|
||||
// Do very basic validation of the data
|
||||
if (items === undefined) {
|
||||
throw new NodeOperationError(this.getNode(), 'No data got returned. Always return an Array of items!');
|
||||
|
@ -127,6 +122,16 @@ return items;`,
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
items=[{json:{ error: error.message }}];
|
||||
} else {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return this.prepareOutputData(items);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ return item;`,
|
|||
let item: INodeExecutionData;
|
||||
|
||||
for (let itemIndex = 0; itemIndex < length; itemIndex++) {
|
||||
|
||||
try {
|
||||
item = items[itemIndex];
|
||||
|
||||
// Copy the items as they may get changed in the functions
|
||||
|
@ -115,8 +115,13 @@ return item;`,
|
|||
// Execute the function code
|
||||
jsonData = await vm.run(`module.exports = async function() {${functionCode}}()`, __dirname);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({json:{ error: error.message }});
|
||||
continue;
|
||||
} else {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Do very basic validation of the data
|
||||
if (jsonData === undefined) {
|
||||
|
@ -132,6 +137,13 @@ return item;`,
|
|||
}
|
||||
|
||||
returnData.push(returnItem);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({json:{ error: error.message }});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return this.prepareOutputData(returnData);
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ export class GetResponse implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
try {
|
||||
if (resource === 'contact') {
|
||||
//https://apireference.getresponse.com/#operation/createContact
|
||||
if (operation === 'create') {
|
||||
|
@ -314,6 +314,13 @@ export class GetResponse implements INodeType {
|
|||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -156,11 +156,12 @@ export class Ghost implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
const source = this.getNodeParameter('source', 0) as string;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (source === 'contentApi') {
|
||||
if (resource === 'post') {
|
||||
if (operation === 'get') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
|
||||
const by = this.getNodeParameter('by', i) as string;
|
||||
|
||||
const identifier = this.getNodeParameter('identifier', i) as string;
|
||||
|
@ -179,11 +180,10 @@ export class Ghost implements INodeType {
|
|||
responseData = await ghostApiRequest.call(this, 'GET', endpoint, {}, qs);
|
||||
|
||||
returnData.push.apply(returnData, responseData.posts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (operation === 'getAll') {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
|
||||
const returnAll = this.getNodeParameter('returnAll', 0) as boolean;
|
||||
|
||||
|
@ -200,7 +200,7 @@ export class Ghost implements INodeType {
|
|||
}
|
||||
|
||||
returnData.push.apply(returnData, responseData);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ export class Ghost implements INodeType {
|
|||
if (source === 'adminApi') {
|
||||
if (resource === 'post') {
|
||||
if (operation === 'create') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
const title = this.getNodeParameter('title', i) as string;
|
||||
|
||||
const contentFormat = this.getNodeParameter('contentFormat', i) as string;
|
||||
|
@ -247,21 +247,21 @@ export class Ghost implements INodeType {
|
|||
responseData = await ghostApiRequest.call(this, 'POST', '/admin/posts', { posts: [post] }, qs);
|
||||
|
||||
returnData.push.apply(returnData, responseData.posts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (operation === 'delete') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
const postId = this.getNodeParameter('postId', i) as string;
|
||||
|
||||
responseData = await ghostApiRequest.call(this, 'DELETE', `/admin/posts/${postId}`);
|
||||
|
||||
returnData.push({ success: true });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (operation === 'get') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
const by = this.getNodeParameter('by', i) as string;
|
||||
|
||||
const identifier = this.getNodeParameter('identifier', i) as string;
|
||||
|
@ -280,11 +280,11 @@ export class Ghost implements INodeType {
|
|||
responseData = await ghostApiRequest.call(this, 'GET', endpoint, {}, qs);
|
||||
|
||||
returnData.push.apply(returnData, responseData.posts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (operation === 'getAll') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
|
||||
const returnAll = this.getNodeParameter('returnAll', 0) as boolean;
|
||||
|
||||
|
@ -301,11 +301,11 @@ export class Ghost implements INodeType {
|
|||
}
|
||||
|
||||
returnData.push.apply(returnData, responseData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (operation === 'update') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
const postId = this.getNodeParameter('postId', i) as string;
|
||||
|
||||
const contentFormat = this.getNodeParameter('contentFormat', i) as string;
|
||||
|
@ -344,9 +344,17 @@ export class Ghost implements INodeType {
|
|||
responseData = await ghostApiRequest.call(this, 'PUT', `/admin/posts/${postId}`, { posts: [post] }, qs);
|
||||
|
||||
returnData.push.apply(returnData, responseData.posts);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -1754,6 +1754,7 @@ export class Github implements INodeType {
|
|||
const fullOperation = `${resource}:${operation}`;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
// Reset all values
|
||||
requestMethod = 'GET';
|
||||
endpoint = '';
|
||||
|
@ -2170,6 +2171,18 @@ export class Github implements INodeType {
|
|||
} else if (overwriteDataOperationsArray.includes(fullOperation)) {
|
||||
returnData.push.apply(returnData, responseData);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
if (overwriteDataOperations.includes(fullOperation) || overwriteDataOperationsArray.includes(fullOperation)) {
|
||||
returnData.push({ error: error.message });
|
||||
} else {
|
||||
items[i].json = { error: error.message };
|
||||
}
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
if (overwriteDataOperations.includes(fullOperation) || overwriteDataOperationsArray.includes(fullOperation)) {
|
||||
|
|
|
@ -1114,6 +1114,9 @@ export class Gitlab implements INodeType {
|
|||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return [this.helpers.returnJsonArray([{ error: error.message }])];
|
||||
}
|
||||
throw new NodeOperationError(this.getNode(), error);
|
||||
}
|
||||
|
||||
|
@ -1152,6 +1155,7 @@ export class Gitlab implements INodeType {
|
|||
const fullOperation = `${resource}:${operation}`;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
// Reset all values
|
||||
requestMethod = 'GET';
|
||||
endpoint = '';
|
||||
|
@ -1365,6 +1369,17 @@ export class Gitlab implements INodeType {
|
|||
} else if (overwriteDataOperationsArray.includes(fullOperation)) {
|
||||
returnData.push.apply(returnData, responseData);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
if (overwriteDataOperations.includes(fullOperation) || overwriteDataOperationsArray.includes(fullOperation)) {
|
||||
returnData.push({ error: error.message });
|
||||
} else {
|
||||
items[i].json = { error: error.message };
|
||||
}
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
if (overwriteDataOperations.includes(fullOperation) || overwriteDataOperationsArray.includes(fullOperation)) {
|
||||
|
|
|
@ -162,8 +162,9 @@ export class GoogleAnalytics implements INodeType {
|
|||
let endpoint = '';
|
||||
let responseData;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (resource === 'report') {
|
||||
if (operation === 'get') {
|
||||
try {
|
||||
if(resource === 'report') {
|
||||
if(operation === 'get') {
|
||||
//https://developers.google.com/analytics/devguides/reporting/core/v4/rest/v4/reports/batchGet
|
||||
method = 'POST';
|
||||
endpoint = '/v4/reports:batchGet';
|
||||
|
@ -280,6 +281,13 @@ export class GoogleAnalytics implements INodeType {
|
|||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -385,6 +385,8 @@ export class GoogleBooks implements INodeType {
|
|||
let responseData;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
|
||||
if (resource === 'volume') {
|
||||
if (operation === 'get') {
|
||||
const volumeId = this.getNodeParameter('volumeId', i) as string;
|
||||
|
@ -495,6 +497,14 @@ export class GoogleBooks implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(responseData)];
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ export async function googleApiRequest(this: IExecuteFunctions | IExecuteSingleF
|
|||
if (Object.keys(body).length === 0) {
|
||||
delete options.body;
|
||||
}
|
||||
console.log(options);
|
||||
//@ts-ignore
|
||||
return await this.helpers.requestOAuth2.call(this, 'googleCalendarOAuth2Api', options);
|
||||
} catch (error) {
|
||||
|
|
|
@ -606,6 +606,12 @@ export class GoogleCalendar implements INodeType {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(responseData)) {
|
||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail() !== true) {
|
||||
throw error;
|
||||
|
@ -619,12 +625,6 @@ export class GoogleCalendar implements INodeType {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(responseData)) {
|
||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -101,6 +101,7 @@ export class GoogleContacts implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'contact') {
|
||||
//https://developers.google.com/calendar/v3/reference/events/insert
|
||||
if (operation === 'create') {
|
||||
|
@ -485,12 +486,19 @@ export class GoogleContacts implements INodeType {
|
|||
responseData.contactId = responseData.resourceName.split('/')[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Array.isArray(responseData)) {
|
||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1996,6 +1996,7 @@ export class GoogleDrive implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
const options = this.getNodeParameter('options', i, {}) as IDataObject;
|
||||
|
||||
let queryFields = 'id, name';
|
||||
|
@ -2427,6 +2428,17 @@ export class GoogleDrive implements INodeType {
|
|||
returnData.push(response as IDataObject);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
if (resource === 'file' && operation === 'download') {
|
||||
items[i].json = { error: error.message };
|
||||
} else {
|
||||
returnData.push({ error: error.message });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
if (resource === 'file' && operation === 'download') {
|
||||
// For file downloads the files get attached to the existing items
|
||||
|
|
|
@ -150,6 +150,7 @@ export class RealtimeDatabase implements INodeType {
|
|||
}
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
const projectId = this.getNodeParameter('projectId', i) as string;
|
||||
let method = 'GET', attributes = '';
|
||||
const document: IDataObject = {};
|
||||
|
@ -192,7 +193,13 @@ export class RealtimeDatabase implements INodeType {
|
|||
responseData = { success: true };
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (Array.isArray(responseData)) {
|
||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||
} else if (typeof responseData === 'string' || typeof responseData === 'number') {
|
||||
|
|
|
@ -206,6 +206,7 @@ export class Gmail implements INodeType {
|
|||
let responseData;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
if (resource === 'label') {
|
||||
if (operation === 'create') {
|
||||
//https://developers.google.com/gmail/api/v1/reference/users/labels/create
|
||||
|
@ -330,6 +331,7 @@ export class Gmail implements INodeType {
|
|||
if (attachmentsUi.hasOwnProperty('attachmentsBinary')
|
||||
&& !isEmpty(attachmentsUi.attachmentsBinary)
|
||||
&& items[i].binary) {
|
||||
// @ts-ignore
|
||||
for (const { property } of attachmentsUi.attachmentsBinary as IDataObject[]) {
|
||||
for (const binaryProperty of (property as string).split(',')) {
|
||||
if (items[i].binary![binaryProperty] !== undefined) {
|
||||
|
@ -414,6 +416,7 @@ export class Gmail implements INodeType {
|
|||
if (attachmentsUi.hasOwnProperty('attachmentsBinary')
|
||||
&& !isEmpty(attachmentsUi.attachmentsBinary)
|
||||
&& items[i].binary) {
|
||||
// @ts-ignore
|
||||
for (const { property } of attachmentsUi.attachmentsBinary as IDataObject[]) {
|
||||
for (const binaryProperty of (property as string).split(',')) {
|
||||
if (items[i].binary![binaryProperty] !== undefined) {
|
||||
|
@ -630,6 +633,7 @@ export class Gmail implements INodeType {
|
|||
if (additionalFields.attachmentsUi) {
|
||||
const attachmentsUi = additionalFields.attachmentsUi as IDataObject;
|
||||
const attachmentsBinary = [];
|
||||
if (!isEmpty(attachmentsUi)) {
|
||||
if (!isEmpty(attachmentsUi)) {
|
||||
if (attachmentsUi.hasOwnProperty('attachmentsBinary')
|
||||
&& !isEmpty(attachmentsUi.attachmentsBinary)
|
||||
|
@ -647,11 +651,13 @@ export class Gmail implements INodeType {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qs = {
|
||||
userId: 'me',
|
||||
uploadType: 'media',
|
||||
};
|
||||
|
||||
attachmentsList = attachmentsBinary;
|
||||
}
|
||||
}
|
||||
|
@ -800,6 +806,13 @@ export class Gmail implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
if (['draft', 'message'].includes(resource) && ['get', 'getAll'].includes(operation)) {
|
||||
//@ts-ignore
|
||||
|
|
|
@ -1034,6 +1034,7 @@ export class GoogleSheets implements INodeType {
|
|||
// ----------------------------------
|
||||
// append
|
||||
// ----------------------------------
|
||||
try {
|
||||
const keyRow = parseInt(this.getNodeParameter('keyRow', 0) as string, 10);
|
||||
|
||||
const items = this.getInputData();
|
||||
|
@ -1050,21 +1051,34 @@ export class GoogleSheets implements INodeType {
|
|||
// TODO: Should have something like add metadata which does not get passed through
|
||||
|
||||
return this.prepareOutputData(items);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return this.prepareOutputData([{json:{ error: error.message }}]);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
} else if (operation === 'clear') {
|
||||
// ----------------------------------
|
||||
// clear
|
||||
// ----------------------------------
|
||||
|
||||
try {
|
||||
await sheet.clearData(sheet.encodeRange(range));
|
||||
|
||||
const items = this.getInputData();
|
||||
return this.prepareOutputData(items);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return this.prepareOutputData([{json:{ error: error.message }}]);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
} else if (operation === 'create') {
|
||||
const returnData: IDataObject[] = [];
|
||||
|
||||
let responseData;
|
||||
for (let i = 0; i < this.getInputData().length; i++) {
|
||||
try {
|
||||
const spreadsheetId = this.getNodeParameter('sheetId', i) as string;
|
||||
const options = this.getNodeParameter('options', i, {}) as IDataObject;
|
||||
const simple = this.getNodeParameter('simple', 0) as boolean;
|
||||
|
@ -1088,6 +1102,13 @@ export class GoogleSheets implements INodeType {
|
|||
delete responseData.replies;
|
||||
}
|
||||
returnData.push(responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
@ -1096,7 +1117,7 @@ export class GoogleSheets implements INodeType {
|
|||
// ----------------------------------
|
||||
// delete
|
||||
// ----------------------------------
|
||||
|
||||
try {
|
||||
const requests: IDataObject[] = [];
|
||||
|
||||
const toDelete = this.getNodeParameter('toDelete', 0) as IToDelete;
|
||||
|
@ -1127,11 +1148,17 @@ export class GoogleSheets implements INodeType {
|
|||
|
||||
const items = this.getInputData();
|
||||
return this.prepareOutputData(items);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return this.prepareOutputData([{json:{ error: error.message }}]);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
} else if (operation === 'lookup') {
|
||||
// ----------------------------------
|
||||
// lookup
|
||||
// ----------------------------------
|
||||
|
||||
try {
|
||||
const sheetData = await sheet.getData(sheet.encodeRange(range), valueRenderMode);
|
||||
|
||||
if (sheetData === undefined) {
|
||||
|
@ -1160,11 +1187,17 @@ export class GoogleSheets implements INodeType {
|
|||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return [this.helpers.returnJsonArray({ error: error.message })];
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
} else if (operation === 'read') {
|
||||
// ----------------------------------
|
||||
// read
|
||||
// ----------------------------------
|
||||
|
||||
try {
|
||||
const rawData = this.getNodeParameter('rawData', 0) as boolean;
|
||||
|
||||
const sheetData = await sheet.getData(sheet.encodeRange(range), valueRenderMode);
|
||||
|
@ -1191,12 +1224,19 @@ export class GoogleSheets implements INodeType {
|
|||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return [this.helpers.returnJsonArray({ error: error.message })];
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
} else if (operation === 'remove') {
|
||||
const returnData: IDataObject[] = [];
|
||||
|
||||
let responseData;
|
||||
for (let i = 0; i < this.getInputData().length; i++) {
|
||||
try {
|
||||
const sheetId = this.getNodeParameter('id', i) as string;
|
||||
const spreadsheetId = this.getNodeParameter('sheetId', i) as string;
|
||||
|
||||
|
@ -1209,6 +1249,13 @@ export class GoogleSheets implements INodeType {
|
|||
responseData = await googleApiRequest.call(this, 'POST', `/v4/spreadsheets/${spreadsheetId}:batchUpdate`, { requests });
|
||||
delete responseData.replies;
|
||||
returnData.push(responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
@ -1216,7 +1263,7 @@ export class GoogleSheets implements INodeType {
|
|||
// ----------------------------------
|
||||
// update
|
||||
// ----------------------------------
|
||||
|
||||
try {
|
||||
const rawData = this.getNodeParameter('rawData', 0) as boolean;
|
||||
|
||||
const items = this.getInputData();
|
||||
|
@ -1250,6 +1297,12 @@ export class GoogleSheets implements INodeType {
|
|||
|
||||
|
||||
return this.prepareOutputData(items);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return this.prepareOutputData([{json:{ error: error.message }}]);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1267,7 +1320,7 @@ export class GoogleSheets implements INodeType {
|
|||
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/create
|
||||
|
||||
for (let i = 0; i < this.getInputData().length; i++) {
|
||||
|
||||
try {
|
||||
const title = this.getNodeParameter('title', i) as string;
|
||||
const sheetsUi = this.getNodeParameter('sheetsUi', i, {}) as IDataObject;
|
||||
|
||||
|
@ -1300,6 +1353,13 @@ export class GoogleSheets implements INodeType {
|
|||
responseData = await googleApiRequest.call(this, 'POST', `/v4/spreadsheets`, body);
|
||||
|
||||
returnData.push(responseData);
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -416,6 +416,8 @@ export class GoogleSlides implements INodeType {
|
|||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
|
||||
try {
|
||||
|
||||
if (resource === 'page') {
|
||||
|
||||
// *********************************************************************
|
||||
|
@ -547,6 +549,14 @@ export class GoogleSlides implements INodeType {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({json:{ error: error.message }});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [returnData];
|
||||
|
|
|
@ -97,6 +97,7 @@ export class GoogleTasks implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
let body: IDataObject = {};
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'task') {
|
||||
if (operation === 'create') {
|
||||
body = {};
|
||||
|
@ -273,6 +274,13 @@ export class GoogleTasks implements INodeType {
|
|||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -221,6 +221,7 @@ export class YouTube implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'channel') {
|
||||
if (operation === 'get') {
|
||||
//https://developers.google.com/youtube/v3/docs/channels/list
|
||||
|
@ -1149,6 +1150,13 @@ export class YouTube implements INodeType {
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
if (Array.isArray(responseData)) {
|
||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||
|
|
|
@ -194,6 +194,7 @@ export class Gotify implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'message') {
|
||||
if (operation === 'create') {
|
||||
|
||||
|
@ -256,6 +257,13 @@ export class Gotify implements INodeType {
|
|||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -236,6 +236,7 @@ export class GraphQL implements INodeType {
|
|||
|
||||
const returnItems: INodeExecutionData[] = [];
|
||||
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
||||
try {
|
||||
const requestMethod = this.getNodeParameter('requestMethod', itemIndex, 'POST') as string;
|
||||
const endpoint = this.getNodeParameter('endpoint', itemIndex, '') as string;
|
||||
const requestFormat = this.getNodeParameter('requestFormat', itemIndex, 'graphql') as string;
|
||||
|
@ -312,6 +313,13 @@ export class GraphQL implements INodeType {
|
|||
returnItems.push({ json: response });
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnItems.push({ json: { error: error.message } });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return this.prepareOutputData(returnItems);
|
||||
|
|
|
@ -303,7 +303,7 @@ export class HackerNews implements INodeType {
|
|||
let returnAll = false;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
|
||||
try {
|
||||
let qs: IDataObject = {};
|
||||
let endpoint = '';
|
||||
let includeComments = false;
|
||||
|
@ -376,7 +376,13 @@ export class HackerNews implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -245,6 +245,7 @@ export class Harvest implements INodeType {
|
|||
let qs: IDataObject;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
body = {};
|
||||
qs = {};
|
||||
|
||||
|
@ -946,6 +947,13 @@ export class Harvest implements INodeType {
|
|||
} else {
|
||||
throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -172,6 +172,7 @@ export class HelpScout implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'conversation') {
|
||||
//https://developer.helpscout.com/mailbox-api/endpoints/conversations/create
|
||||
if (operation === 'create') {
|
||||
|
@ -429,6 +430,13 @@ export class HelpScout implements INodeType {
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (Array.isArray(responseData)) {
|
||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||
} else if (responseData !== undefined) {
|
||||
|
|
|
@ -219,6 +219,7 @@ export class HtmlExtract implements INodeType {
|
|||
|
||||
let item: INodeExecutionData;
|
||||
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
||||
try {
|
||||
const dataPropertyName = this.getNodeParameter('dataPropertyName', itemIndex) as string;
|
||||
const extractionValues = this.getNodeParameter('extractionValues', itemIndex) as IDataObject;
|
||||
const options = this.getNodeParameter('options', itemIndex, {}) as IDataObject;
|
||||
|
@ -273,6 +274,13 @@ export class HtmlExtract implements INodeType {
|
|||
}
|
||||
returnData.push(newItem);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ json: { error: error.message } });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return this.prepareOutputData(returnData);
|
||||
|
|
|
@ -874,6 +874,7 @@ export class Hubspot implements INodeType {
|
|||
|
||||
//https://legacydocs.hubspot.com/docs/methods/lists/contact-lists-overview
|
||||
if (resource === 'contactList') {
|
||||
try {
|
||||
//https://legacydocs.hubspot.com/docs/methods/lists/add_contact_to_list
|
||||
if (operation === 'add') {
|
||||
const listId = this.getNodeParameter('listId', 0) as string;
|
||||
|
@ -902,8 +903,16 @@ export class Hubspot implements INodeType {
|
|||
responseData = await hubspotApiRequest.call(this, 'POST', `/contacts/v1/lists/${listId}/remove`, body);
|
||||
returnData.push(responseData);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
//https://developers.hubspot.com/docs/methods/contacts/create_or_update
|
||||
if (resource === 'contact') {
|
||||
//https://developers.hubspot.com/docs/methods/companies/create_company
|
||||
|
@ -2407,6 +2416,13 @@ export class Hubspot implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -292,6 +292,7 @@ export class Hunter implements INodeType {
|
|||
const qs: IDataObject = {};
|
||||
let responseData;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
//https://hunter.io/api-documentation/v2#domain-search
|
||||
if (operation === 'domainSearch') {
|
||||
|
@ -372,6 +373,13 @@ export class Hunter implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -127,6 +127,7 @@ export class Intercom implements INodeType {
|
|||
let qs: IDataObject;
|
||||
let responseData;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
qs = {};
|
||||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
@ -551,6 +552,13 @@ export class Intercom implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -250,6 +250,7 @@ export class InvoiceNinja implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
//Routes: https://github.com/invoiceninja/invoiceninja/blob/ff455c8ed9fd0c0326956175ecd509efa8bad263/routes/api.php
|
||||
try {
|
||||
if (resource === 'client') {
|
||||
if (operation === 'create') {
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
|
@ -801,6 +802,13 @@ export class InvoiceNinja implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
|
@ -207,6 +207,7 @@ export class Kafka implements INodeType {
|
|||
|
||||
let responseData: IDataObject[];
|
||||
|
||||
try {
|
||||
const options = this.getNodeParameter('options', 0) as IDataObject;
|
||||
const sendInputData = this.getNodeParameter('sendInputData', 0) as boolean;
|
||||
|
||||
|
@ -328,5 +329,12 @@ export class Kafka implements INodeType {
|
|||
await producer.disconnect();
|
||||
|
||||
return [this.helpers.returnJsonArray(responseData)];
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
return [this.helpers.returnJsonArray({ error: error.message })];
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ export class Line implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
|
||||
try {
|
||||
if (resource === 'notification') {
|
||||
//https://notify-bot.line.me/doc/en/
|
||||
if (operation === 'send') {
|
||||
|
@ -133,13 +134,20 @@ export class Line implements INodeType {
|
|||
responseData = await lineApiRequest.call(this, 'POST', '', {}, {}, 'https://notify-api.line.me/api/notify', { formData: body });
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Array.isArray(responseData)) {
|
||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||
|
||||
} else if (responseData !== undefined) {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ export class LinkedIn implements INodeType {
|
|||
let body = {};
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
try {
|
||||
if (resource === 'post') {
|
||||
if (operation === 'create') {
|
||||
const text = this.getNodeParameter('text', i) as string;
|
||||
|
@ -249,6 +250,13 @@ export class LinkedIn implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
|
|
@ -95,12 +95,20 @@ export class Mailcheck implements INodeType {
|
|||
const resource = this.getNodeParameter('resource', 0) as string;
|
||||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'email') {
|
||||
if (operation === 'check') {
|
||||
const email = this.getNodeParameter('email', i) as string;
|
||||
responseData = await mailCheckApiRequest.call(this, 'POST', '/singleEmail:check', { email });
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (Array.isArray(responseData)) {
|
||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||
} else {
|
||||
|
|
|
@ -1862,6 +1862,7 @@ export class Mailchimp implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
try {
|
||||
if (resource === 'listGroup') {
|
||||
//https://mailchimp.com/developer/reference/lists/interest-categories/#get_/lists/-list_id-/interest-categories/-interest_category_id-
|
||||
if (operation === 'getAll') {
|
||||
|
@ -2267,6 +2268,13 @@ export class Mailchimp implements INodeType {
|
|||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.continueOnFail()) {
|
||||
returnData.push({ error: error.message });
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue