mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
Worked on requests
This commit is contained in:
parent
e488e6c0bb
commit
704f9aa81a
|
@ -71,7 +71,6 @@ export class MicrosoftCosmosDbSharedKeyApi implements ICredentialType {
|
||||||
...requestOptions.headers,
|
...requestOptions.headers,
|
||||||
'x-ms-date': date,
|
'x-ms-date': date,
|
||||||
'x-ms-version': '2018-12-31',
|
'x-ms-version': '2018-12-31',
|
||||||
'x-ms-partitionkey': '[]',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (credentials.sessionToken) {
|
if (credentials.sessionToken) {
|
||||||
|
@ -80,6 +79,7 @@ export class MicrosoftCosmosDbSharedKeyApi implements ICredentialType {
|
||||||
|
|
||||||
// This shouldn't be the full url
|
// This shouldn't be the full url
|
||||||
// Refer to https://stackoverflow.com/questions/45645389/documentdb-rest-api-authorization-token-error
|
// Refer to https://stackoverflow.com/questions/45645389/documentdb-rest-api-authorization-token-error
|
||||||
|
// const url = new URL (requestOptions.uri);
|
||||||
|
|
||||||
const url = new URL(requestOptions.baseURL + requestOptions.url);
|
const url = new URL(requestOptions.baseURL + requestOptions.url);
|
||||||
const pathSegments = url.pathname.split('/').filter((segment) => segment);
|
const pathSegments = url.pathname.split('/').filter((segment) => segment);
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { NodeConnectionType } from 'n8n-workflow';
|
||||||
|
|
||||||
import { containerFields, containerOperations } from './descriptions/ContainerDescription';
|
import { containerFields, containerOperations } from './descriptions/ContainerDescription';
|
||||||
import { itemFields, itemOperations } from './descriptions/ItemDescription';
|
import { itemFields, itemOperations } from './descriptions/ItemDescription';
|
||||||
import { presendStringifyBody, searchCollections } from './GenericFunctions';
|
import { searchCollections, searchItems } from './GenericFunctions';
|
||||||
|
|
||||||
export class CosmosDb implements INodeType {
|
export class CosmosDb implements INodeType {
|
||||||
description: INodeTypeDescription = {
|
description: INodeTypeDescription = {
|
||||||
|
@ -59,9 +59,9 @@ export class CosmosDb implements INodeType {
|
||||||
type: 'options',
|
type: 'options',
|
||||||
noDataExpression: true,
|
noDataExpression: true,
|
||||||
routing: {
|
routing: {
|
||||||
send: {
|
// send: {
|
||||||
preSend: [presendStringifyBody],
|
// preSend: [presendStringifyBody],
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
|
@ -85,6 +85,7 @@ export class CosmosDb implements INodeType {
|
||||||
methods = {
|
methods = {
|
||||||
listSearch: {
|
listSearch: {
|
||||||
searchCollections,
|
searchCollections,
|
||||||
|
searchItems,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,3 +231,235 @@ export async function searchCollections(
|
||||||
results,
|
results,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function searchItems(
|
||||||
|
this: ILoadOptionsFunctions,
|
||||||
|
filter?: string,
|
||||||
|
): Promise<INodeListSearchResult> {
|
||||||
|
const collection = this.getNodeParameter('collId') as { mode: string; value: string };
|
||||||
|
|
||||||
|
if (!collection?.value) {
|
||||||
|
throw new ApplicationError('Collection ID is required.');
|
||||||
|
}
|
||||||
|
const opts: IHttpRequestOptions = {
|
||||||
|
method: 'GET',
|
||||||
|
url: `/colls/${collection.value}/docs`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const responseData: IDataObject = await microsoftCosmosDbRequest.call(this, opts);
|
||||||
|
|
||||||
|
const responseBody = responseData as {
|
||||||
|
Documents: IDataObject[];
|
||||||
|
};
|
||||||
|
const items = responseBody.Documents;
|
||||||
|
|
||||||
|
if (!items) {
|
||||||
|
return { results: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
const results: INodeListSearchItems[] = items
|
||||||
|
.map((item) => {
|
||||||
|
return {
|
||||||
|
name: String(item.id),
|
||||||
|
value: String(item.id),
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter((item) => !filter || item.name.includes(filter))
|
||||||
|
.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
|
||||||
|
return {
|
||||||
|
results,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function validateQueryParameters(
|
||||||
|
this: IExecuteSingleFunctions,
|
||||||
|
requestOptions: IHttpRequestOptions,
|
||||||
|
): Promise<IHttpRequestOptions> {
|
||||||
|
const params = this.getNodeParameter('parameters', {}) as {
|
||||||
|
parameters: Array<{ name: string; value: string }>;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!params || !Array.isArray(params.parameters)) {
|
||||||
|
throw new ApplicationError(
|
||||||
|
'The "parameters" field cannot be empty. Please add at least one parameter.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const parameters = params.parameters;
|
||||||
|
|
||||||
|
for (const parameter of parameters) {
|
||||||
|
if (!parameter.name || parameter.name.trim() === '') {
|
||||||
|
throw new ApplicationError('Each parameter must have a non-empty "name".');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parameter.value) {
|
||||||
|
throw new ApplicationError(`The parameter "${parameter.name}" must have a valid "value".`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function validateOperations(
|
||||||
|
this: IExecuteSingleFunctions,
|
||||||
|
requestOptions: IHttpRequestOptions,
|
||||||
|
): Promise<IHttpRequestOptions> {
|
||||||
|
const rawOperations = this.getNodeParameter('operations', []) as IDataObject;
|
||||||
|
console.log('Operations', rawOperations);
|
||||||
|
if (!rawOperations || !Array.isArray(rawOperations.operations)) {
|
||||||
|
throw new ApplicationError('The "operations" field must contain at least one operation.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const operations = rawOperations.operations as Array<{
|
||||||
|
op: string;
|
||||||
|
path: string;
|
||||||
|
value?: string;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
for (const operation of operations) {
|
||||||
|
if (!['add', 'increment', 'move', 'remove', 'replace', 'set'].includes(operation.op)) {
|
||||||
|
throw new ApplicationError(
|
||||||
|
`Invalid operation type "${operation.op}". Allowed values are "add", "increment", "move", "remove", "replace", and "set".`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!operation.path || operation.path.trim() === '') {
|
||||||
|
throw new ApplicationError('Each operation must have a valid "path".');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
['set', 'replace', 'add', 'increment'].includes(operation.op) &&
|
||||||
|
(operation.value === undefined || operation.value === null)
|
||||||
|
) {
|
||||||
|
throw new ApplicationError(`The operation "${operation.op}" must include a valid "value".`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function formatCustomProperties(
|
||||||
|
this: IExecuteSingleFunctions,
|
||||||
|
requestOptions: IHttpRequestOptions,
|
||||||
|
): Promise<IHttpRequestOptions> {
|
||||||
|
const rawCustomProperties = this.getNodeParameter('customProperties', '{}') as string;
|
||||||
|
|
||||||
|
let parsedProperties: Record<string, unknown>;
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
|
parsedProperties = JSON.parse(rawCustomProperties);
|
||||||
|
} catch (error) {
|
||||||
|
throw new ApplicationError(
|
||||||
|
'Invalid JSON format in "Custom Properties". Please provide a valid JSON object.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof parsedProperties !== 'object' ||
|
||||||
|
parsedProperties === null ||
|
||||||
|
Array.isArray(parsedProperties)
|
||||||
|
) {
|
||||||
|
throw new ApplicationError('The "Custom Properties" field must be a valid JSON object.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!requestOptions.body ||
|
||||||
|
typeof requestOptions.body !== 'object' ||
|
||||||
|
requestOptions.body === null
|
||||||
|
) {
|
||||||
|
requestOptions.body = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(requestOptions.body as Record<string, unknown>, parsedProperties);
|
||||||
|
|
||||||
|
return requestOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function formatJSONFields(
|
||||||
|
this: IExecuteSingleFunctions,
|
||||||
|
requestOptions: IHttpRequestOptions,
|
||||||
|
): Promise<IHttpRequestOptions> {
|
||||||
|
const rawPartitionKey = this.getNodeParameter('partitionKey', '{}') as string;
|
||||||
|
const additionalFields = this.getNodeParameter('additionalFields', {}) as IDataObject;
|
||||||
|
const indexingPolicy = additionalFields.indexingPolicy as string;
|
||||||
|
|
||||||
|
let parsedPartitionKey: Record<string, unknown>;
|
||||||
|
let parsedIndexPolicy: Record<string, unknown> | undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
|
parsedPartitionKey = JSON.parse(rawPartitionKey);
|
||||||
|
|
||||||
|
if (indexingPolicy) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
|
parsedIndexPolicy = JSON.parse(indexingPolicy);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
throw new ApplicationError(
|
||||||
|
'Invalid JSON format in either "Partition Key" or "Indexing Policy". Please provide valid JSON objects.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!requestOptions.body ||
|
||||||
|
typeof requestOptions.body !== 'object' ||
|
||||||
|
requestOptions.body === null
|
||||||
|
) {
|
||||||
|
requestOptions.body = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
(requestOptions.body as Record<string, unknown>).partitionKey = parsedPartitionKey;
|
||||||
|
|
||||||
|
if (parsedIndexPolicy) {
|
||||||
|
(requestOptions.body as Record<string, unknown>).indexingPolicy = parsedIndexPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function mapOperationsToRequest(
|
||||||
|
this: IExecuteSingleFunctions,
|
||||||
|
requestOptions: IHttpRequestOptions,
|
||||||
|
): Promise<IHttpRequestOptions> {
|
||||||
|
const rawOperations = this.getNodeParameter('operations', []) as {
|
||||||
|
operations: Array<{
|
||||||
|
op: string;
|
||||||
|
path: string;
|
||||||
|
from?: string;
|
||||||
|
value?: string | number;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!rawOperations || !Array.isArray(rawOperations.operations)) {
|
||||||
|
throw new ApplicationError('Invalid operations format. Expected an array.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map and validate operations
|
||||||
|
const formattedOperations = rawOperations.operations.map((operation) => {
|
||||||
|
const { op, path, from, value } = operation;
|
||||||
|
|
||||||
|
// Validate required fields
|
||||||
|
if (!op || !path) {
|
||||||
|
throw new ApplicationError('Each operation must include "op" and "path".');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct operation object
|
||||||
|
const formattedOperation: Record<string, unknown> = { op, path };
|
||||||
|
|
||||||
|
// Add optional fields if they exist
|
||||||
|
if (from && op === 'move') {
|
||||||
|
formattedOperation.from = from;
|
||||||
|
}
|
||||||
|
if (value !== undefined && op !== 'remove') {
|
||||||
|
formattedOperation.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return formattedOperation;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assign the formatted operations to the request body
|
||||||
|
requestOptions.body = { operations: formattedOperations };
|
||||||
|
|
||||||
|
return requestOptions;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import type { INodeProperties } from 'n8n-workflow';
|
import type { INodeProperties } from 'n8n-workflow';
|
||||||
|
|
||||||
|
import { formatJSONFields } from '../GenericFunctions';
|
||||||
|
|
||||||
export const containerOperations: INodeProperties[] = [
|
export const containerOperations: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
displayName: 'Operation',
|
displayName: 'Operation',
|
||||||
|
@ -17,13 +19,13 @@ export const containerOperations: INodeProperties[] = [
|
||||||
value: 'create',
|
value: 'create',
|
||||||
description: 'Create a container',
|
description: 'Create a container',
|
||||||
routing: {
|
routing: {
|
||||||
|
send: {
|
||||||
|
preSend: [formatJSONFields],
|
||||||
|
},
|
||||||
request: {
|
request: {
|
||||||
ignoreHttpStatusErrors: true,
|
ignoreHttpStatusErrors: true,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: '/colls',
|
url: '/colls',
|
||||||
headers: {
|
|
||||||
headers: {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
action: 'Create container',
|
action: 'Create container',
|
||||||
|
@ -75,7 +77,7 @@ export const containerOperations: INodeProperties[] = [
|
||||||
export const createFields: INodeProperties[] = [
|
export const createFields: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
displayName: 'ID',
|
displayName: 'ID',
|
||||||
name: 'id',
|
name: 'newid',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: '',
|
default: '',
|
||||||
placeholder: 'e.g. AndersenFamily',
|
placeholder: 'e.g. AndersenFamily',
|
||||||
|
@ -109,13 +111,6 @@ export const createFields: INodeProperties[] = [
|
||||||
operation: ['create'],
|
operation: ['create'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
routing: {
|
|
||||||
send: {
|
|
||||||
type: 'body',
|
|
||||||
property: 'partitionKey',
|
|
||||||
value: '={{$value}}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Additional Fields',
|
displayName: 'Additional Fields',
|
||||||
|
@ -136,13 +131,6 @@ export const createFields: INodeProperties[] = [
|
||||||
placeholder:
|
placeholder:
|
||||||
'"automatic": true, "indexingMode": "Consistent", "includedPaths": [{ "path": "/*", "indexes": [{ "dataType": "String", "precision": -1, "kind": "Range" }]}]',
|
'"automatic": true, "indexingMode": "Consistent", "includedPaths": [{ "path": "/*", "indexes": [{ "dataType": "String", "precision": -1, "kind": "Range" }]}]',
|
||||||
description: 'This value is used to configure indexing policy',
|
description: 'This value is used to configure indexing policy',
|
||||||
routing: {
|
|
||||||
send: {
|
|
||||||
type: 'body',
|
|
||||||
property: 'indexingPolicy',
|
|
||||||
value: '={{$value}}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Max RU/s (for Autoscale)',
|
displayName: 'Max RU/s (for Autoscale)',
|
||||||
|
@ -191,7 +179,7 @@ export const createFields: INodeProperties[] = [
|
||||||
|
|
||||||
export const getFields: INodeProperties[] = [
|
export const getFields: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
displayName: 'Container ID',
|
displayName: 'Container',
|
||||||
name: 'collId',
|
name: 'collId',
|
||||||
type: 'resourceLocator',
|
type: 'resourceLocator',
|
||||||
required: true,
|
required: true,
|
||||||
|
@ -240,7 +228,7 @@ export const getAllFields: INodeProperties[] = [];
|
||||||
|
|
||||||
export const deleteFields: INodeProperties[] = [
|
export const deleteFields: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
displayName: 'Container ID',
|
displayName: 'Container',
|
||||||
name: 'collId',
|
name: 'collId',
|
||||||
type: 'resourceLocator',
|
type: 'resourceLocator',
|
||||||
required: true,
|
required: true,
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
import type { IExecuteSingleFunctions, IHttpRequestOptions, INodeProperties } from 'n8n-workflow';
|
import type { INodeProperties } from 'n8n-workflow';
|
||||||
|
|
||||||
import { handlePagination } from '../GenericFunctions';
|
import {
|
||||||
|
formatCustomProperties,
|
||||||
|
handlePagination,
|
||||||
|
validateOperations,
|
||||||
|
validateQueryParameters,
|
||||||
|
} from '../GenericFunctions';
|
||||||
|
|
||||||
export const itemOperations: INodeProperties[] = [
|
export const itemOperations: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
|
@ -19,12 +24,17 @@ export const itemOperations: INodeProperties[] = [
|
||||||
value: 'create',
|
value: 'create',
|
||||||
description: 'Create a new item',
|
description: 'Create a new item',
|
||||||
routing: {
|
routing: {
|
||||||
|
send: {
|
||||||
|
preSend: [formatCustomProperties],
|
||||||
|
},
|
||||||
request: {
|
request: {
|
||||||
ignoreHttpStatusErrors: true,
|
ignoreHttpStatusErrors: true,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: '=/colls/{{ $parameter["collId"] }}/docs',
|
url: '=/colls/{{ $parameter["collId"] }}/docs',
|
||||||
headers: {
|
headers: {
|
||||||
// 'x-ms-documentdb-partitionkey': '={{$parameter["partitionKey"]}}',
|
// 'x-ms-partitionkey': '=["{{$parameter["newId"]}}"]',
|
||||||
|
// 'x-ms-documentdb-partitionkey': '=["{{$parameter["newId"]}}"]',
|
||||||
|
'x-ms-documentdb-is-upsert': 'True',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -48,16 +58,6 @@ export const itemOperations: INodeProperties[] = [
|
||||||
value: 'get',
|
value: 'get',
|
||||||
description: 'Retrieve an item',
|
description: 'Retrieve an item',
|
||||||
routing: {
|
routing: {
|
||||||
send: {
|
|
||||||
preSend: [
|
|
||||||
async function (
|
|
||||||
this: IExecuteSingleFunctions,
|
|
||||||
requestOptions: IHttpRequestOptions,
|
|
||||||
): Promise<IHttpRequestOptions> {
|
|
||||||
return requestOptions;
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
request: {
|
request: {
|
||||||
ignoreHttpStatusErrors: true,
|
ignoreHttpStatusErrors: true,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
@ -82,6 +82,16 @@ export const itemOperations: INodeProperties[] = [
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '=/colls/{{ $parameter["collId"] }}/docs',
|
url: '=/colls/{{ $parameter["collId"] }}/docs',
|
||||||
},
|
},
|
||||||
|
output: {
|
||||||
|
postReceive: [
|
||||||
|
{
|
||||||
|
type: 'rootProperty',
|
||||||
|
properties: {
|
||||||
|
property: 'json',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
action: 'Get many items',
|
action: 'Get many items',
|
||||||
},
|
},
|
||||||
|
@ -90,6 +100,9 @@ export const itemOperations: INodeProperties[] = [
|
||||||
value: 'query',
|
value: 'query',
|
||||||
description: 'Query items',
|
description: 'Query items',
|
||||||
routing: {
|
routing: {
|
||||||
|
send: {
|
||||||
|
preSend: [validateQueryParameters],
|
||||||
|
},
|
||||||
request: {
|
request: {
|
||||||
ignoreHttpStatusErrors: true,
|
ignoreHttpStatusErrors: true,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -107,12 +120,17 @@ export const itemOperations: INodeProperties[] = [
|
||||||
value: 'update',
|
value: 'update',
|
||||||
description: 'Update an existing item',
|
description: 'Update an existing item',
|
||||||
routing: {
|
routing: {
|
||||||
|
send: {
|
||||||
|
preSend: [validateOperations],
|
||||||
|
},
|
||||||
request: {
|
request: {
|
||||||
ignoreHttpStatusErrors: true,
|
ignoreHttpStatusErrors: true,
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
url: '=/colls/{{ $parameter["collId"] }}/docs/{{ $parameter["id"] }}',
|
url: '=/colls/{{ $parameter["collId"] }}/docs/{{ $parameter["id"] }}',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json-patch+json',
|
'Content-Type': 'application/json-patch+json',
|
||||||
|
'x-ms-partitionkey': '=["{{$parameter["id"]}}"]',
|
||||||
|
'x-ms-documentdb-partitionkey': '=["{{$parameter["id"]}}"]',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -170,7 +188,7 @@ export const createFields: INodeProperties[] = [
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// displayName: 'ID',
|
// displayName: 'ID',
|
||||||
// name: 'id',
|
// name: 'newId',
|
||||||
// type: 'string',
|
// type: 'string',
|
||||||
// default: '',
|
// default: '',
|
||||||
// placeholder: 'e.g. AndersenFamily',
|
// placeholder: 'e.g. AndersenFamily',
|
||||||
|
@ -260,19 +278,48 @@ export const deleteFields: INodeProperties[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'ID',
|
displayName: 'Item',
|
||||||
name: 'id',
|
name: 'id',
|
||||||
type: 'string',
|
type: 'resourceLocator',
|
||||||
default: '',
|
|
||||||
placeholder: 'e.g. AndersenFamily',
|
|
||||||
description: 'Unique ID for the item',
|
|
||||||
required: true,
|
required: true,
|
||||||
|
default: {
|
||||||
|
mode: 'list',
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
description: "Select the item's ID",
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['item'],
|
resource: ['item'],
|
||||||
operation: ['delete'],
|
operation: ['delete'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
modes: [
|
||||||
|
{
|
||||||
|
displayName: 'From list',
|
||||||
|
name: 'list',
|
||||||
|
type: 'list',
|
||||||
|
typeOptions: {
|
||||||
|
searchListMethod: 'searchItems',
|
||||||
|
searchable: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'By Name',
|
||||||
|
name: 'itemName',
|
||||||
|
type: 'string',
|
||||||
|
hint: 'Enter the item name',
|
||||||
|
validation: [
|
||||||
|
{
|
||||||
|
type: 'regex',
|
||||||
|
properties: {
|
||||||
|
regex: '^[\\w+=,.@-]+$',
|
||||||
|
errorMessage: 'The item name must follow the allowed pattern.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
placeholder: 'e.g. AndersenFamily',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -322,19 +369,48 @@ export const getFields: INodeProperties[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'ID',
|
displayName: 'Item',
|
||||||
name: 'id',
|
name: 'id',
|
||||||
type: 'string',
|
type: 'resourceLocator',
|
||||||
default: '',
|
|
||||||
placeholder: 'e.g. AndersenFamily',
|
|
||||||
description: "Item's ID",
|
|
||||||
required: true,
|
required: true,
|
||||||
|
default: {
|
||||||
|
mode: 'list',
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
description: "Select the item's ID",
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['item'],
|
resource: ['item'],
|
||||||
operation: ['get'],
|
operation: ['get'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
modes: [
|
||||||
|
{
|
||||||
|
displayName: 'From list',
|
||||||
|
name: 'list',
|
||||||
|
type: 'list',
|
||||||
|
typeOptions: {
|
||||||
|
searchListMethod: 'searchItems',
|
||||||
|
searchable: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'By Name',
|
||||||
|
name: 'itemName',
|
||||||
|
type: 'string',
|
||||||
|
hint: 'Enter the item name',
|
||||||
|
validation: [
|
||||||
|
{
|
||||||
|
type: 'regex',
|
||||||
|
properties: {
|
||||||
|
regex: '^[\\w+=,.@-]+$',
|
||||||
|
errorMessage: 'The item name must follow the allowed pattern.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
placeholder: 'e.g. AndersenFamily',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -474,7 +550,6 @@ export const queryFields: INodeProperties[] = [
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: '',
|
default: '',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'The SQL query text to execute',
|
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['item'],
|
resource: ['item'],
|
||||||
|
@ -532,7 +607,8 @@ export const queryFields: INodeProperties[] = [
|
||||||
send: {
|
send: {
|
||||||
type: 'body',
|
type: 'body',
|
||||||
property: 'parameters',
|
property: 'parameters',
|
||||||
value: '={{$value}}',
|
value:
|
||||||
|
'={{$parameter["parameters"] && $parameter["parameters"].parameters ? $parameter["parameters"].parameters : []}}',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -584,56 +660,110 @@ export const updateFields: INodeProperties[] = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'ID',
|
displayName: 'Item',
|
||||||
name: 'id',
|
name: 'id',
|
||||||
type: 'string',
|
type: 'resourceLocator',
|
||||||
default: '',
|
|
||||||
placeholder: 'e.g. AndersenFamily',
|
|
||||||
description: 'Unique ID for the document',
|
|
||||||
required: true,
|
required: true,
|
||||||
|
default: {
|
||||||
|
mode: 'list',
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
description: "Select the item's ID",
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['item'],
|
resource: ['item'],
|
||||||
operation: ['update'],
|
operation: ['update'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
modes: [
|
||||||
|
{
|
||||||
|
displayName: 'From list',
|
||||||
|
name: 'list',
|
||||||
|
type: 'list',
|
||||||
|
typeOptions: {
|
||||||
|
searchListMethod: 'searchItems',
|
||||||
|
searchable: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'By Name',
|
||||||
|
name: 'itemName',
|
||||||
|
type: 'string',
|
||||||
|
hint: 'Enter the item name',
|
||||||
|
validation: [
|
||||||
|
{
|
||||||
|
type: 'regex',
|
||||||
|
properties: {
|
||||||
|
regex: '^[\\w+=,.@-]+$',
|
||||||
|
errorMessage: 'The item name must follow the allowed pattern.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
placeholder: 'e.g. AndersenFamily',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
//TO-DO-check-this
|
|
||||||
{
|
{
|
||||||
displayName: 'Operations',
|
displayName: 'Operations',
|
||||||
name: 'operations',
|
name: 'operations',
|
||||||
type: 'resourceMapper',
|
type: 'fixedCollection',
|
||||||
default: {
|
placeholder: 'Add Operation',
|
||||||
mappingMode: 'defineBelow',
|
description: 'Patch operations to apply to the document',
|
||||||
value: null,
|
|
||||||
},
|
|
||||||
required: true,
|
required: true,
|
||||||
|
default: [],
|
||||||
typeOptions: {
|
typeOptions: {
|
||||||
resourceMapper: {
|
multipleValues: true,
|
||||||
resourceMapperMethod: 'getMappingColumns',
|
|
||||||
mode: 'update',
|
|
||||||
fieldWords: {
|
|
||||||
singular: 'operation',
|
|
||||||
plural: 'operations',
|
|
||||||
},
|
},
|
||||||
addAllFields: true,
|
|
||||||
multiKeyMatch: false,
|
|
||||||
supportAutoMap: true,
|
|
||||||
matchingFieldsLabels: {
|
|
||||||
title: 'Custom Matching Operations',
|
|
||||||
description: 'Define the operations to perform, such as "set", "delete", or "add".',
|
|
||||||
hint: 'Map input data to the expected structure of the operations array.',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: 'Define the operations to perform, such as setting or updating document fields',
|
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['item'],
|
resource: ['item'],
|
||||||
operation: ['update'],
|
operation: ['update'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
//TO-DO-presend-function
|
options: [
|
||||||
|
{
|
||||||
|
name: 'operations',
|
||||||
|
displayName: 'Operation',
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'op',
|
||||||
|
type: 'options',
|
||||||
|
options: [
|
||||||
|
{ name: 'Add', value: 'add' },
|
||||||
|
{ name: 'Increment', value: 'increment' },
|
||||||
|
{ name: 'Move', value: 'move' },
|
||||||
|
{ name: 'Remove', value: 'remove' },
|
||||||
|
{ name: 'Replace', value: 'replace' },
|
||||||
|
{ name: 'Set', value: 'set' },
|
||||||
|
],
|
||||||
|
default: 'set',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Path',
|
||||||
|
name: 'path',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: '/Parents/0/FamilyName',
|
||||||
|
description: 'The path to the document field to be updated',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Value',
|
||||||
|
name: 'value',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'The value to set (if applicable)',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
routing: {
|
||||||
|
send: {
|
||||||
|
type: 'body',
|
||||||
|
property: 'operations',
|
||||||
|
value: '={{ $parameter["operations"].operations }}',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue