mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
overhaul operation structure as requested by michael-radency
This commit is contained in:
parent
9ae72e8e8e
commit
2454db80de
|
@ -65,9 +65,8 @@ function endpointCtxExpr(ctx: ICtx, endpoint: string): string {
|
|||
endpointVariables.dtable_uuid = ctx?.base?.dtable_uuid;
|
||||
|
||||
return endpoint.replace(
|
||||
/({{ *(access_token|dtable_uuid|server) *}})/g,
|
||||
/{{ *(access_token|dtable_uuid|server) *}}/g,
|
||||
(match: string, name: TEndpointVariableName) => {
|
||||
// I need expr. Why?
|
||||
return (endpointVariables[name] as string) || match;
|
||||
},
|
||||
);
|
||||
|
@ -127,7 +126,7 @@ export async function seaTableApiRequest(
|
|||
}
|
||||
|
||||
// DEBUG-MODE OR API-REQUESTS
|
||||
// console.log(options);
|
||||
//console.log(options);
|
||||
|
||||
if (Object.keys(body).length === 0) {
|
||||
delete options.body;
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
|
||||
const properties: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Asset Path',
|
||||
name: 'assetPath',
|
||||
type: 'string',
|
||||
placeholder: '/images/2023-09/logo.png',
|
||||
required: true,
|
||||
default: '',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['asset'],
|
||||
operation: ['getPublicURL'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const assetPath = this.getNodeParameter('assetPath', index) as string;
|
||||
|
||||
let responseData = [] as IDataObject[];
|
||||
if (assetPath) {
|
||||
responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'GET',
|
||||
`/api/v2.1/dtable/app-download-link/?path=${assetPath}`,
|
||||
);
|
||||
}
|
||||
|
||||
return this.helpers.returnJsonArray(responseData);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import type { AssetProperties } from '../../Interfaces';
|
||||
|
||||
export const assetGetPublicURLDescription: AssetProperties = [
|
||||
{
|
||||
displayName: 'Asset Path',
|
||||
name: 'assetPath',
|
||||
type: 'string',
|
||||
placeholder: '/images/2023-09/logo.png',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['asset'],
|
||||
operation: ['getPublicURL'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
];
|
|
@ -1,21 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
|
||||
export async function getPublicURL(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const assetPath = this.getNodeParameter('assetPath', index) as string;
|
||||
|
||||
let responseData = [] as IDataObject[];
|
||||
if (assetPath) {
|
||||
responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'GET',
|
||||
`/api/v2.1/dtable/app-download-link/?path=${assetPath}`,
|
||||
);
|
||||
}
|
||||
|
||||
return this.helpers.returnJsonArray(responseData);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { getPublicURL as execute } from './execute';
|
||||
import { assetGetPublicURLDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -1,6 +1,6 @@
|
|||
import type { INodeProperties } from 'n8n-workflow';
|
||||
import * as upload from './upload';
|
||||
import * as getPublicURL from './getPublicURL';
|
||||
import * as upload from './upload.operation';
|
||||
import * as getPublicURL from './getPublicURL.operation';
|
||||
|
||||
export { upload, getPublicURL };
|
||||
|
||||
|
|
|
@ -1,8 +1,94 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
import type { IUploadLink, IRowObject } from '../../Interfaces';
|
||||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
import type { IUploadLink, IRowObject } from '../Interfaces';
|
||||
|
||||
export async function upload(
|
||||
const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
type: 'options',
|
||||
placeholder: 'Select a table',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'The name of SeaTable table to access. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Column Name',
|
||||
name: 'uploadColumn',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getAssetColumns',
|
||||
},
|
||||
required: true,
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'Select the column for the upload. Choose from the list, or specify the name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Row ID',
|
||||
name: 'rowId',
|
||||
type: 'options',
|
||||
description:
|
||||
'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getRowIds',
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Property Name',
|
||||
name: 'dataPropertyName',
|
||||
type: 'string',
|
||||
default: 'data',
|
||||
required: true,
|
||||
description: 'Name of the binary property which contains the data for the file to be written',
|
||||
},
|
||||
{
|
||||
displayName: 'Replace Existing File',
|
||||
name: 'replace',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description:
|
||||
'Whether to replace the existing asset with the same name (true). Otherwise, a new version with a different name (numeral in parentheses) will be uploaded (false).',
|
||||
},
|
||||
{
|
||||
displayName: 'Append to Column',
|
||||
name: 'append',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description:
|
||||
'Whether to keep existing files/images in the column and append the new asset (true). Otherwise, the existing files/images are removed from the column (false).',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['asset'],
|
||||
operation: ['upload'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
|
@ -1,108 +0,0 @@
|
|||
import type { AssetProperties } from '../../Interfaces';
|
||||
|
||||
export const assetUploadDescription: AssetProperties = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
type: 'options',
|
||||
placeholder: 'Select a table',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['asset'],
|
||||
operation: ['upload'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'The name of SeaTable table to access. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Column Name',
|
||||
name: 'uploadColumn',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['asset'],
|
||||
operation: ['upload'],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getAssetColumns',
|
||||
},
|
||||
required: true,
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'Select the column for the upload. Choose from the list, or specify the name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Row ID',
|
||||
name: 'rowId',
|
||||
type: 'options',
|
||||
description:
|
||||
'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getRowIds',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['asset'],
|
||||
operation: ['upload'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Property Name',
|
||||
name: 'dataPropertyName',
|
||||
type: 'string',
|
||||
default: 'data',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['asset'],
|
||||
operation: ['upload'],
|
||||
},
|
||||
},
|
||||
description: 'Name of the binary property which contains the data for the file to be written',
|
||||
},
|
||||
{
|
||||
displayName: 'Replace Existing File',
|
||||
name: 'replace',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['asset'],
|
||||
operation: ['upload'],
|
||||
},
|
||||
},
|
||||
description:
|
||||
'Whether to replace the existing asset with the same name (true). Otherwise, a new version with a different name (numeral in parentheses) will be uploaded (false).',
|
||||
},
|
||||
{
|
||||
displayName: 'Append to Column',
|
||||
name: 'append',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['asset'],
|
||||
operation: ['upload'],
|
||||
},
|
||||
},
|
||||
description:
|
||||
'Whether to keep existing files/images in the column and append the new asset (true). Otherwise, the existing files/images are removed from the column (false).',
|
||||
},
|
||||
];
|
|
@ -1,4 +0,0 @@
|
|||
import { upload as execute } from './execute';
|
||||
import { assetUploadDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -1,6 +1,14 @@
|
|||
import type { BaseProperties } from '../../Interfaces';
|
||||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
import type { APITypes } from '../../types';
|
||||
|
||||
export const baseApiCallDescription: BaseProperties = [
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'HTTP Method',
|
||||
name: 'apiMethod',
|
||||
|
@ -23,12 +31,6 @@ export const baseApiCallDescription: BaseProperties = [
|
|||
value: 'DELETE',
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['base'],
|
||||
operation: ['apiCall'],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
default: 'POST',
|
||||
},
|
||||
|
@ -37,22 +39,11 @@ export const baseApiCallDescription: BaseProperties = [
|
|||
name: 'notice',
|
||||
type: 'notice',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['base'],
|
||||
operation: ['apiCall'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'URL',
|
||||
name: 'apiEndpoint',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
operation: ['apiCall'],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
default: '',
|
||||
placeholder: '/dtable-server/...',
|
||||
|
@ -88,23 +79,11 @@ export const baseApiCallDescription: BaseProperties = [
|
|||
],
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['base'],
|
||||
operation: ['apiCall'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Body',
|
||||
name: 'apiBody',
|
||||
type: 'json',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['base'],
|
||||
operation: ['apiCall'],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
rows: 4,
|
||||
},
|
||||
|
@ -117,14 +96,51 @@ export const baseApiCallDescription: BaseProperties = [
|
|||
name: 'responseObjectName',
|
||||
type: 'string',
|
||||
placeholder: 'Leave it empty or use a value like "rows", "metadata", "views" etc.',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['base'],
|
||||
operation: ['apiCall'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
description:
|
||||
'When using the SeaTable API, you can specify a parameter to retrieve either the entire array of objects or a specific object within it. This allows you to choose whether to fetch the complete output or only the object related to the provided parameter.',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['base'],
|
||||
operation: ['apiCall'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const apiMethod = this.getNodeParameter('apiMethod', index) as APITypes;
|
||||
const apiEndpoint = this.getNodeParameter('apiEndpoint', index) as APITypes;
|
||||
const responseObjectName = this.getNodeParameter('responseObjectName', index) as string;
|
||||
|
||||
// body params
|
||||
const apiBody = this.getNodeParameter('apiBody', index) as any;
|
||||
|
||||
// query params
|
||||
const apiParams: IDataObject = {};
|
||||
const params = this.getNodeParameter('apiParams.apiParamsValues', index, []) as any;
|
||||
for (const param of params) {
|
||||
apiParams[`${param.key}`] = param.value;
|
||||
}
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
apiMethod,
|
||||
apiEndpoint,
|
||||
apiBody,
|
||||
apiParams,
|
||||
);
|
||||
|
||||
if (responseObjectName) {
|
||||
return this.helpers.returnJsonArray(responseData[responseObjectName] as IDataObject[]);
|
||||
} else {
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
import type { APITypes } from '../../../types';
|
||||
|
||||
export async function apiCall(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const apiMethod = this.getNodeParameter('apiMethod', index) as APITypes;
|
||||
const apiEndpoint = this.getNodeParameter('apiEndpoint', index) as APITypes;
|
||||
const responseObjectName = this.getNodeParameter('responseObjectName', index) as string;
|
||||
|
||||
// body params
|
||||
const apiBody = this.getNodeParameter('apiBody', index) as any;
|
||||
|
||||
// query params
|
||||
const apiParams: IDataObject = {};
|
||||
const params = this.getNodeParameter('apiParams.apiParamsValues', index, []) as any;
|
||||
for (const param of params) {
|
||||
apiParams[`${param.key}`] = param.value;
|
||||
}
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
apiMethod,
|
||||
apiEndpoint,
|
||||
apiBody,
|
||||
apiParams,
|
||||
);
|
||||
|
||||
if (responseObjectName) {
|
||||
return this.helpers.returnJsonArray(responseData[responseObjectName] as IDataObject[]);
|
||||
} else {
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { apiCall as execute } from './execute';
|
||||
import { baseApiCallDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -0,0 +1,53 @@
|
|||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
import type { ICollaborator } from '../Interfaces';
|
||||
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'Name or email of the collaborator',
|
||||
name: 'searchString',
|
||||
type: 'string',
|
||||
placeholder: 'Enter the name or the email or the collaborator',
|
||||
required: true,
|
||||
default: '',
|
||||
description:
|
||||
'SeaTable identifies users with a unique username like 244b43hr6fy54bb4afa2c2cb7369d244@auth.local. Get this username from an email or the name of a collaborator.',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['base'],
|
||||
operation: ['collaborator'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const searchString = this.getNodeParameter('searchString', index) as string;
|
||||
|
||||
const collaboratorsResult = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'GET',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/related-users/',
|
||||
);
|
||||
const collaborators = collaboratorsResult.user_list || [];
|
||||
|
||||
const data = collaborators.filter(
|
||||
(col: ICollaborator) =>
|
||||
col.contact_email.includes(searchString) || col.name.includes(searchString),
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(data as IDataObject[]);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import type { BaseProperties } from '../../Interfaces';
|
||||
|
||||
export const baseCollaboratorDescription: BaseProperties = [
|
||||
{
|
||||
displayName: 'Name or email of the collaborator',
|
||||
name: 'searchString',
|
||||
type: 'string',
|
||||
placeholder: 'Enter the name or the email or the collaborator',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['base'],
|
||||
operation: ['collaborator'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
description:
|
||||
'SeaTable identifies users with a unique username like 244b43hr6fy54bb4afa2c2cb7369d244@auth.local. Get this username from an email or the name of a collaborator.',
|
||||
},
|
||||
];
|
|
@ -1,25 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
import type { ICollaborator } from '../../Interfaces';
|
||||
|
||||
export async function collaborator(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const searchString = this.getNodeParameter('searchString', index) as string;
|
||||
|
||||
const collaboratorsResult = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'GET',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/related-users/',
|
||||
);
|
||||
const collaborators = collaboratorsResult.user_list || [];
|
||||
|
||||
const data = collaborators.filter(
|
||||
(col: ICollaborator) =>
|
||||
col.contact_email.includes(searchString) || col.name.includes(searchString),
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(data as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { collaborator as execute } from './execute';
|
||||
import { baseCollaboratorDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -1,8 +1,8 @@
|
|||
import type { INodeProperties } from 'n8n-workflow';
|
||||
import * as snapshot from './snapshot';
|
||||
import * as metadata from './metadata';
|
||||
import * as apiCall from './apiCall';
|
||||
import * as collaborator from './collaborator';
|
||||
import * as snapshot from './snapshot.operation';
|
||||
import * as metadata from './metadata.operation';
|
||||
import * as apiCall from './apiCall.operation';
|
||||
import * as collaborator from './collaborator.operation';
|
||||
|
||||
export { snapshot, metadata, apiCall, collaborator };
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
|
||||
export const properties: INodeProperties[] = [];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['base'],
|
||||
operation: ['metadata'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(this: IExecuteFunctions): Promise<INodeExecutionData[]> {
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'GET',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/metadata/',
|
||||
);
|
||||
return this.helpers.returnJsonArray(responseData.metadata as IDataObject[]);
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
import type { BaseProperties } from '../../Interfaces';
|
||||
|
||||
export const baseMetadataDescription: BaseProperties = [];
|
|
@ -1,12 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
|
||||
export async function metadata(this: IExecuteFunctions): Promise<INodeExecutionData[]> {
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'GET',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/metadata/',
|
||||
);
|
||||
return this.helpers.returnJsonArray(responseData.metadata as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { metadata as execute } from './execute';
|
||||
import { baseMetadataDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -0,0 +1,31 @@
|
|||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
|
||||
export const properties: INodeProperties[] = [];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['base'],
|
||||
operation: ['snapshot'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(this: IExecuteFunctions): Promise<INodeExecutionData[]> {
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/snapshot/',
|
||||
{ dtable_name: 'snapshot' },
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
import type { BaseProperties } from '../../Interfaces';
|
||||
|
||||
export const baseSnapshotDescription: BaseProperties = [];
|
|
@ -1,14 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
|
||||
export async function snapshot(this: IExecuteFunctions): Promise<INodeExecutionData[]> {
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/snapshot/',
|
||||
{ dtable_name: 'snapshot' },
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { snapshot as execute } from './execute';
|
||||
import { baseSnapshotDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -1,6 +1,13 @@
|
|||
import type { LinkProperties } from '../../Interfaces';
|
||||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
|
||||
export const linkAddDescription: LinkProperties = [
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name (Source)',
|
||||
|
@ -11,12 +18,6 @@ export const linkAddDescription: LinkProperties = [
|
|||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNameAndId',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['add'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
|
@ -27,12 +28,6 @@ export const linkAddDescription: LinkProperties = [
|
|||
displayName: 'Link Column',
|
||||
name: 'linkColumn',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['add'],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getLinkColumns',
|
||||
|
@ -47,12 +42,6 @@ export const linkAddDescription: LinkProperties = [
|
|||
displayName: 'Row ID From the Source Table',
|
||||
name: 'linkColumnSourceId',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['add'],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
default: '',
|
||||
description: 'Provide the row ID of table you selected',
|
||||
|
@ -61,14 +50,46 @@ export const linkAddDescription: LinkProperties = [
|
|||
displayName: 'Row ID From the Target',
|
||||
name: 'linkColumnTargetId',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['add'],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
default: '',
|
||||
description: 'Provide the row ID of table you want to link',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['add'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const linkColumn = this.getNodeParameter('linkColumn', index) as any;
|
||||
const linkColumnSourceId = this.getNodeParameter('linkColumnSourceId', index) as string;
|
||||
const linkColumnTargetId = this.getNodeParameter('linkColumnTargetId', index) as string;
|
||||
|
||||
const body = {
|
||||
link_id: linkColumn.split(':::')[1],
|
||||
table_id: tableName.split(':::')[1],
|
||||
other_table_id: linkColumn.split(':::')[2],
|
||||
other_rows_ids_map: {
|
||||
[linkColumnSourceId]: [linkColumnTargetId],
|
||||
},
|
||||
};
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-db/api/v1/base/{{dtable_uuid}}/links/',
|
||||
body,
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
|
||||
export async function add(this: IExecuteFunctions, index: number): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const linkColumn = this.getNodeParameter('linkColumn', index) as any;
|
||||
const linkColumnSourceId = this.getNodeParameter('linkColumnSourceId', index) as string;
|
||||
const linkColumnTargetId = this.getNodeParameter('linkColumnTargetId', index) as string;
|
||||
|
||||
const body = {
|
||||
link_id: linkColumn.split(':::')[1],
|
||||
table_id: tableName.split(':::')[1],
|
||||
other_table_id: linkColumn.split(':::')[2],
|
||||
other_rows_ids_map: {
|
||||
[linkColumnSourceId]: [linkColumnTargetId],
|
||||
},
|
||||
};
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-db/api/v1/base/{{dtable_uuid}}/links/',
|
||||
body,
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { add as execute } from './execute';
|
||||
import { linkAddDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -1,7 +1,7 @@
|
|||
import type { INodeProperties } from 'n8n-workflow';
|
||||
import * as add from './add';
|
||||
import * as list from './list';
|
||||
import * as remove from './remove';
|
||||
import * as add from './add.operation';
|
||||
import * as list from './list.operation';
|
||||
import * as remove from './remove.operation';
|
||||
|
||||
export { add, list, remove };
|
||||
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
import type { LinkProperties } from '../../Interfaces';
|
||||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
|
||||
export const listLinkDescription: LinkProperties = [
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name 32',
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
type: 'options',
|
||||
placeholder: 'Select a table',
|
||||
|
@ -11,12 +18,6 @@ export const listLinkDescription: LinkProperties = [
|
|||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNameAndId',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['list'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
|
@ -27,12 +28,6 @@ export const listLinkDescription: LinkProperties = [
|
|||
displayName: 'Link Column',
|
||||
name: 'linkColumn',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['list'],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getLinkColumnsWithColumnKey',
|
||||
|
@ -55,12 +50,45 @@ export const listLinkDescription: LinkProperties = [
|
|||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getRowIds',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['list'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['list'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
// get parameters
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const linkColumn = this.getNodeParameter('linkColumn', index) as string;
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
|
||||
// get rows
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-db/api/v1/linked-records/{{dtable_uuid}}/',
|
||||
{
|
||||
table_id: tableName.split(':::')[1],
|
||||
link_column: linkColumn.split(':::')[3],
|
||||
rows: [
|
||||
{
|
||||
row_id: rowId,
|
||||
offset: 0,
|
||||
limit: 100,
|
||||
},
|
||||
],
|
||||
},
|
||||
);
|
||||
return this.helpers.returnJsonArray(responseData[rowId] as IDataObject[]);
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
|
||||
export async function list(this: IExecuteFunctions, index: number): Promise<INodeExecutionData[]> {
|
||||
// get parameters
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const linkColumn = this.getNodeParameter('linkColumn', index) as string;
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
|
||||
// get rows
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-db/api/v1/linked-records/{{dtable_uuid}}/',
|
||||
{
|
||||
table_id: tableName.split(':::')[1],
|
||||
link_column: linkColumn.split(':::')[3],
|
||||
rows: [
|
||||
{
|
||||
row_id: rowId,
|
||||
offset: 0,
|
||||
limit: 100,
|
||||
},
|
||||
],
|
||||
},
|
||||
);
|
||||
return this.helpers.returnJsonArray(responseData[rowId] as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { list as execute } from './execute';
|
||||
import { listLinkDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -1,6 +1,13 @@
|
|||
import type { LinkProperties } from '../../Interfaces';
|
||||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
|
||||
export const linkRemoveDescription: LinkProperties = [
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name (Source)',
|
||||
|
@ -11,12 +18,6 @@ export const linkRemoveDescription: LinkProperties = [
|
|||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNameAndId',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['remove'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
|
@ -27,12 +28,6 @@ export const linkRemoveDescription: LinkProperties = [
|
|||
displayName: 'Link Column',
|
||||
name: 'linkColumn',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['remove'],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getLinkColumns',
|
||||
|
@ -47,12 +42,6 @@ export const linkRemoveDescription: LinkProperties = [
|
|||
displayName: 'Row ID From the Source Table',
|
||||
name: 'linkColumnSourceId',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['remove'],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
default: '',
|
||||
description: 'Provide the row ID of table you selected',
|
||||
|
@ -61,14 +50,46 @@ export const linkRemoveDescription: LinkProperties = [
|
|||
displayName: 'Row ID From the Target Table',
|
||||
name: 'linkColumnTargetId',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['remove'],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
default: '',
|
||||
description: 'Provide the row ID of table you want to link',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['link'],
|
||||
operation: ['remove'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const linkColumn = this.getNodeParameter('linkColumn', index) as any;
|
||||
const linkColumnSourceId = this.getNodeParameter('linkColumnSourceId', index) as string;
|
||||
const linkColumnTargetId = this.getNodeParameter('linkColumnTargetId', index) as string;
|
||||
|
||||
const body = {
|
||||
link_id: linkColumn.split(':::')[1],
|
||||
table_id: tableName.split(':::')[1],
|
||||
other_table_id: linkColumn.split(':::')[2],
|
||||
other_rows_ids_map: {
|
||||
[linkColumnSourceId]: [linkColumnTargetId],
|
||||
},
|
||||
};
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'DELETE',
|
||||
'/dtable-db/api/v1/base/{{dtable_uuid}}/links/',
|
||||
body,
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
|
||||
export async function remove(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const linkColumn = this.getNodeParameter('linkColumn', index) as any;
|
||||
const linkColumnSourceId = this.getNodeParameter('linkColumnSourceId', index) as string;
|
||||
const linkColumnTargetId = this.getNodeParameter('linkColumnTargetId', index) as string;
|
||||
|
||||
const body = {
|
||||
link_id: linkColumn.split(':::')[1],
|
||||
table_id: tableName.split(':::')[1],
|
||||
other_table_id: linkColumn.split(':::')[2],
|
||||
other_rows_ids_map: {
|
||||
[linkColumnSourceId]: [linkColumnTargetId],
|
||||
},
|
||||
};
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'DELETE',
|
||||
'/dtable-db/api/v1/base/{{dtable_uuid}}/links/',
|
||||
body,
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { remove as execute } from './execute';
|
||||
import { linkRemoveDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -0,0 +1,215 @@
|
|||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import {
|
||||
seaTableApiRequest,
|
||||
getTableColumns,
|
||||
split,
|
||||
rowExport,
|
||||
updateAble,
|
||||
splitStringColumnsToArrays,
|
||||
} from '../../GenericFunctions';
|
||||
import type { IRowObject } from '../Interfaces';
|
||||
import type { TColumnValue, TColumnsUiValues } from '../../types';
|
||||
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
type: 'options',
|
||||
placeholder: 'Select a table',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'The name of SeaTable table to access. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Data to Send',
|
||||
name: 'fieldsToSend',
|
||||
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',
|
||||
},
|
||||
],
|
||||
default: 'defineBelow',
|
||||
description: 'Whether to insert the input data this node receives in the new row',
|
||||
},
|
||||
{
|
||||
displayName:
|
||||
'In this mode, make sure the incoming data fields are named the same as the columns in SeaTable. (Use an "Edit Fields" node before this node to change them if required.)',
|
||||
name: 'notice',
|
||||
type: 'notice',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
'/fieldsToSend': ['autoMapInputData'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Inputs to Ignore',
|
||||
name: 'inputsToIgnore',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description:
|
||||
'List of input properties to avoid sending, separated by commas. Leave empty to send all properties.',
|
||||
placeholder: 'Enter properties...',
|
||||
displayOptions: {
|
||||
show: {
|
||||
'/fieldsToSend': ['autoMapInputData'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Columns to Send',
|
||||
name: 'columnsUi',
|
||||
placeholder: 'Add Column',
|
||||
type: 'fixedCollection',
|
||||
typeOptions: {
|
||||
multipleValueButtonText: 'Add Column to Send',
|
||||
multipleValues: true,
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
'/fieldsToSend': ['defineBelow'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Column',
|
||||
name: 'columnValues',
|
||||
values: [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Column Name',
|
||||
name: 'columnName',
|
||||
type: 'options',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'Choose from the list, or specify the column name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getTableUpdateAbleColumns',
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Column Value',
|
||||
name: 'columnValue',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
default: {},
|
||||
description:
|
||||
'Add destination column with its value. Provide the value in this way. Date: YYYY-MM-DD or YYYY-MM-DD hh:mm. Duration: time in seconds. Checkbox: true, on or 1. Multi-Select: comma-separated list.',
|
||||
},
|
||||
{
|
||||
displayName: 'Save to "Big Data" Backend',
|
||||
name: 'bigdata',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description:
|
||||
'Whether write to Big Data backend (true) or not (false). True requires the activation of the Big Data backend in the base.',
|
||||
},
|
||||
{
|
||||
displayName:
|
||||
'Hint: Link, files, images or digital signatures have to be added separately. These column types cannot be set with this node.',
|
||||
name: 'notice',
|
||||
type: 'notice',
|
||||
default: '',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['create'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const tableColumns = await getTableColumns.call(this, tableName);
|
||||
const fieldsToSend = this.getNodeParameter('fieldsToSend', index) as
|
||||
| 'defineBelow'
|
||||
| 'autoMapInputData';
|
||||
const bigdata = this.getNodeParameter('bigdata', index) as string;
|
||||
|
||||
const body = {
|
||||
table_name: tableName,
|
||||
row: {},
|
||||
} as IDataObject;
|
||||
let rowInput = {} as IRowObject;
|
||||
|
||||
// get rowInput, an object of key:value pairs like { Name: 'Promo Action 1', Status: "Draft" }.
|
||||
if (fieldsToSend === 'autoMapInputData') {
|
||||
const items = this.getInputData();
|
||||
const incomingKeys = Object.keys(items[index].json);
|
||||
const inputDataToIgnore = split(this.getNodeParameter('inputsToIgnore', index, '') as string);
|
||||
for (const key of incomingKeys) {
|
||||
if (inputDataToIgnore.includes(key)) continue;
|
||||
rowInput[key] = items[index].json[key] as TColumnValue;
|
||||
}
|
||||
} else {
|
||||
const columns = this.getNodeParameter('columnsUi.columnValues', index, []) as TColumnsUiValues;
|
||||
for (const column of columns) {
|
||||
rowInput[column.columnName] = column.columnValue;
|
||||
}
|
||||
}
|
||||
|
||||
// only keep key:value pairs for columns that are allowed to update.
|
||||
rowInput = rowExport(rowInput, updateAble(tableColumns));
|
||||
|
||||
// string to array: multi-select and collaborators
|
||||
rowInput = splitStringColumnsToArrays(rowInput, tableColumns);
|
||||
|
||||
// save to big data backend
|
||||
if (bigdata) {
|
||||
body.rows = [rowInput];
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-db/api/v1/insert-rows/{{dtable_uuid}}/',
|
||||
body,
|
||||
);
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
||||
// save to normal backend
|
||||
else {
|
||||
body.row = rowInput;
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/',
|
||||
body,
|
||||
);
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
import type { RowProperties } from '../../Interfaces';
|
||||
|
||||
export const rowCreateDescription: RowProperties = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
type: 'options',
|
||||
placeholder: 'Select a table',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'The name of SeaTable table to access. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Data to Send',
|
||||
name: 'fieldsToSend',
|
||||
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: {
|
||||
resource: ['row'],
|
||||
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: ['row'],
|
||||
operation: ['create'],
|
||||
fieldsToSend: ['autoMapInputData'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
description:
|
||||
'List of input properties to avoid sending, separated by commas. Leave empty to send all properties.',
|
||||
placeholder: 'Enter properties...',
|
||||
},
|
||||
{
|
||||
displayName: 'Columns to Send',
|
||||
name: 'columnsUi',
|
||||
placeholder: 'Add Column',
|
||||
type: 'fixedCollection',
|
||||
typeOptions: {
|
||||
multipleValueButtonText: 'Add Column to Send',
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
displayName: 'Column',
|
||||
name: 'columnValues',
|
||||
values: [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Column Name',
|
||||
name: 'columnName',
|
||||
type: 'options',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'Choose from the list, or specify the column name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getTableUpdateAbleColumns',
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Column Value',
|
||||
name: 'columnValue',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['create'],
|
||||
fieldsToSend: ['defineBelow'],
|
||||
},
|
||||
},
|
||||
default: {},
|
||||
description:
|
||||
'Add destination column with its value. Provide the value in this way. Date: YYYY-MM-DD or YYYY-MM-DD hh:mm. Duration: time in seconds. Checkbox: true, on or 1. Multi-Select: comma-separated list.',
|
||||
},
|
||||
{
|
||||
displayName: 'Save to "Big Data" Backend',
|
||||
name: 'bigdata',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
default: false,
|
||||
description:
|
||||
'Whether write to Big Data backend (true) or not (false). True requires the activation of the Big Data backend in the base.',
|
||||
},
|
||||
{
|
||||
displayName: 'Hint: Link, files, images or digital signatures have to be added separately.',
|
||||
name: 'notice',
|
||||
type: 'notice',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['create'],
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
|
@ -1,76 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import {
|
||||
seaTableApiRequest,
|
||||
getTableColumns,
|
||||
split,
|
||||
rowExport,
|
||||
updateAble,
|
||||
splitStringColumnsToArrays,
|
||||
} from '../../../GenericFunctions';
|
||||
import type { IRowObject } from '../../Interfaces';
|
||||
import type { TColumnValue, TColumnsUiValues } from '../../../types';
|
||||
|
||||
export async function create(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const tableColumns = await getTableColumns.call(this, tableName);
|
||||
const fieldsToSend = this.getNodeParameter('fieldsToSend', index) as
|
||||
| 'defineBelow'
|
||||
| 'autoMapInputData';
|
||||
const bigdata = this.getNodeParameter('bigdata', index) as string;
|
||||
|
||||
const body = {
|
||||
table_name: tableName,
|
||||
row: {},
|
||||
} as IDataObject;
|
||||
let rowInput = {} as IRowObject;
|
||||
|
||||
// get rowInput, an object of key:value pairs like { Name: 'Promo Action 1', Status: "Draft" }.
|
||||
if (fieldsToSend === 'autoMapInputData') {
|
||||
const items = this.getInputData();
|
||||
const incomingKeys = Object.keys(items[index].json);
|
||||
const inputDataToIgnore = split(this.getNodeParameter('inputsToIgnore', index, '') as string);
|
||||
for (const key of incomingKeys) {
|
||||
if (inputDataToIgnore.includes(key)) continue;
|
||||
rowInput[key] = items[index].json[key] as TColumnValue;
|
||||
}
|
||||
} else {
|
||||
const columns = this.getNodeParameter('columnsUi.columnValues', index, []) as TColumnsUiValues;
|
||||
for (const column of columns) {
|
||||
rowInput[column.columnName] = column.columnValue;
|
||||
}
|
||||
}
|
||||
|
||||
// only keep key:value pairs for columns that are allowed to update.
|
||||
rowInput = rowExport(rowInput, updateAble(tableColumns));
|
||||
|
||||
// string to array: multi-select and collaborators
|
||||
rowInput = splitStringColumnsToArrays(rowInput, tableColumns);
|
||||
|
||||
// save to big data backend
|
||||
if (bigdata) {
|
||||
body.rows = [rowInput];
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-db/api/v1/insert-rows/{{dtable_uuid}}/',
|
||||
body,
|
||||
);
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
||||
// save to normal backend
|
||||
else {
|
||||
body.row = rowInput;
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/',
|
||||
body,
|
||||
);
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { create as execute } from './execute';
|
||||
import { rowCreateDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -0,0 +1,99 @@
|
|||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import {
|
||||
seaTableApiRequest,
|
||||
enrichColumns,
|
||||
simplify_new,
|
||||
getBaseCollaborators,
|
||||
} from '../../GenericFunctions';
|
||||
import type { IRowResponse, IDtableMetadataColumn } from '../Interfaces';
|
||||
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
type: 'options',
|
||||
placeholder: 'Select a table',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'The name of SeaTable table to access. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Row ID',
|
||||
name: 'rowId',
|
||||
type: 'options',
|
||||
description:
|
||||
'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getRowIds',
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Simplify',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['get'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
// get parameters
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
const simple = this.getNodeParameter('simple', index) as boolean;
|
||||
|
||||
// get collaborators
|
||||
const collaborators = await getBaseCollaborators.call(this);
|
||||
|
||||
// get rows
|
||||
const sqlResult = (await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-db/api/v1/query/{{dtable_uuid}}/',
|
||||
{
|
||||
sql: `SELECT * FROM \`${tableName}\` WHERE _id = '${rowId}'`,
|
||||
convert_keys: true,
|
||||
},
|
||||
)) as IRowResponse;
|
||||
const metadata = sqlResult.metadata as IDtableMetadataColumn[];
|
||||
const rows = sqlResult.results;
|
||||
|
||||
// hide columns like button
|
||||
rows.map((row) => enrichColumns(row, metadata, collaborators));
|
||||
|
||||
// remove columns starting with _ if simple;
|
||||
if (simple) {
|
||||
rows.map((row) => simplify_new(row));
|
||||
}
|
||||
|
||||
return this.helpers.returnJsonArray(rows as IDataObject[]);
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import {
|
||||
seaTableApiRequest,
|
||||
enrichColumns,
|
||||
simplify_new,
|
||||
getBaseCollaborators,
|
||||
} from '../../../GenericFunctions';
|
||||
import type { IRowResponse, IDtableMetadataColumn } from './../../Interfaces';
|
||||
|
||||
export async function get(this: IExecuteFunctions, index: number): Promise<INodeExecutionData[]> {
|
||||
// get parameters
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
const simple = this.getNodeParameter('simple', index) as boolean;
|
||||
|
||||
// get collaborators
|
||||
const collaborators = await getBaseCollaborators.call(this);
|
||||
|
||||
// get rows
|
||||
const sqlResult = (await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-db/api/v1/query/{{dtable_uuid}}/',
|
||||
{
|
||||
sql: `SELECT * FROM \`${tableName}\` WHERE _id = '${rowId}'`,
|
||||
convert_keys: true,
|
||||
},
|
||||
)) as IRowResponse;
|
||||
const metadata = sqlResult.metadata as IDtableMetadataColumn[];
|
||||
const rows = sqlResult.results;
|
||||
|
||||
// hide columns like button
|
||||
rows.map((row) => enrichColumns(row, metadata, collaborators));
|
||||
|
||||
// remove columns starting with _ if simple;
|
||||
if (simple) {
|
||||
rows.map((row) => simplify_new(row));
|
||||
}
|
||||
|
||||
return this.helpers.returnJsonArray(rows as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { get as execute } from './execute';
|
||||
import { rowGetDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -1,12 +1,12 @@
|
|||
import type { INodeProperties } from 'n8n-workflow';
|
||||
import * as create from './create';
|
||||
import * as get from './get';
|
||||
import * as list from './list';
|
||||
import * as search from './search';
|
||||
import * as update from './update';
|
||||
import * as remove from './remove';
|
||||
import * as lock from './lock';
|
||||
import * as unlock from './unlock';
|
||||
import * as create from './create.operation';
|
||||
import * as get from './get.operation';
|
||||
import * as list from './list.operation';
|
||||
import * as search from './search.operation';
|
||||
import * as update from './update.operation';
|
||||
import * as remove from './remove.operation';
|
||||
import * as lock from './lock.operation';
|
||||
import * as unlock from './unlock.operation';
|
||||
|
||||
export { create, get, search, update, remove, lock, unlock, list };
|
||||
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import {
|
||||
seaTableApiRequest,
|
||||
enrichColumns,
|
||||
simplify_new,
|
||||
getBaseCollaborators,
|
||||
} from '../../GenericFunctions';
|
||||
import type { IRow } from '../Interfaces';
|
||||
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
type: 'options',
|
||||
placeholder: 'Select a table',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNameAndId',
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'Choose from the list, or specify by using an expression. Provide it in the way "table_name:::table_id".',
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'View Name',
|
||||
name: 'viewName',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getTableViews',
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'The name of SeaTable view to access, or specify by using an expression. Provide it in the way "col.name:::col.type".',
|
||||
},
|
||||
{
|
||||
displayName: 'Simplify',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['list'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
// get parameters
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const viewName = this.getNodeParameter('viewName', index) as string;
|
||||
const simple = this.getNodeParameter('simple', index) as boolean;
|
||||
|
||||
// get collaborators
|
||||
const collaborators = await getBaseCollaborators.call(this);
|
||||
|
||||
// get rows
|
||||
const requestMeta = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'GET',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/metadata/',
|
||||
);
|
||||
|
||||
const requestRows = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'GET',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/',
|
||||
{},
|
||||
{
|
||||
table_name: tableName,
|
||||
view_name: viewName,
|
||||
limit: 1000,
|
||||
},
|
||||
);
|
||||
|
||||
const metadata =
|
||||
requestMeta.metadata.tables.find((table: { name: string }) => table.name === tableName)
|
||||
?.columns ?? [];
|
||||
const rows = requestRows.rows as IRow[];
|
||||
|
||||
// hide columns like button
|
||||
rows.map((row) => enrichColumns(row, metadata, collaborators));
|
||||
|
||||
// remove columns starting with _ if simple;
|
||||
if (simple) {
|
||||
rows.map((row) => simplify_new(row));
|
||||
}
|
||||
|
||||
return this.helpers.returnJsonArray(rows as IDataObject[]);
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
import type { RowProperties } from '../../Interfaces';
|
||||
|
||||
export const rowListDescription: RowProperties = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
type: 'options',
|
||||
placeholder: 'Select a table',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNameAndId',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['list'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'Choose from the list, or specify by using an expression. Provide it in the way "table_name:::table_id".',
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'View Name',
|
||||
name: 'viewName',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['list'],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getTableViews',
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'The name of SeaTable view to access, or specify by using an expression. Provide it in the way "col.name:::col.type".',
|
||||
},
|
||||
{
|
||||
displayName: 'Simplify',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['list'],
|
||||
},
|
||||
},
|
||||
default: true,
|
||||
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||
},
|
||||
];
|
|
@ -1,54 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import {
|
||||
seaTableApiRequest,
|
||||
enrichColumns,
|
||||
simplify_new,
|
||||
getBaseCollaborators,
|
||||
} from '../../../GenericFunctions';
|
||||
import type { IRow } from './../../Interfaces';
|
||||
|
||||
export async function list(this: IExecuteFunctions, index: number): Promise<INodeExecutionData[]> {
|
||||
// get parameters
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const viewName = this.getNodeParameter('viewName', index) as string;
|
||||
const simple = this.getNodeParameter('simple', index) as boolean;
|
||||
|
||||
// get collaborators
|
||||
const collaborators = await getBaseCollaborators.call(this);
|
||||
|
||||
// get rows
|
||||
const requestMeta = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'GET',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/metadata/',
|
||||
);
|
||||
|
||||
const requestRows = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'GET',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/',
|
||||
{},
|
||||
{
|
||||
table_name: tableName,
|
||||
view_name: viewName,
|
||||
limit: 1000,
|
||||
},
|
||||
);
|
||||
|
||||
const metadata =
|
||||
requestMeta.metadata.tables.find((table: { name: string }) => table.name === tableName)
|
||||
?.columns ?? [];
|
||||
const rows = requestRows.rows as IRow[];
|
||||
|
||||
// hide columns like button
|
||||
rows.map((row) => enrichColumns(row, metadata, collaborators));
|
||||
|
||||
// remove columns starting with _ if simple;
|
||||
if (simple) {
|
||||
rows.map((row) => simplify_new(row));
|
||||
}
|
||||
|
||||
return this.helpers.returnJsonArray(rows as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { list as execute } from './execute';
|
||||
import { rowListDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -1,6 +1,13 @@
|
|||
import type { RowProperties } from '../../Interfaces';
|
||||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
|
||||
export const rowLockDescription: RowProperties = [
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
|
@ -11,12 +18,6 @@ export const rowLockDescription: RowProperties = [
|
|||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['lock'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
|
@ -35,12 +36,36 @@ export const rowLockDescription: RowProperties = [
|
|||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getRowIds',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['lock'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['lock'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'PUT',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/lock-rows/',
|
||||
{
|
||||
table_name: tableName,
|
||||
row_ids: [rowId],
|
||||
},
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
|
||||
export async function lock(this: IExecuteFunctions, index: number): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'PUT',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/lock-rows/',
|
||||
{
|
||||
table_name: tableName,
|
||||
row_ids: [rowId],
|
||||
},
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { lock as execute } from './execute';
|
||||
import { rowLockDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -1,6 +1,13 @@
|
|||
import type { RowProperties } from '../../Interfaces';
|
||||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
|
||||
export const rowRemoveDescription: RowProperties = [
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
|
@ -11,12 +18,6 @@ export const rowRemoveDescription: RowProperties = [
|
|||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['remove'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
|
@ -32,15 +33,41 @@ export const rowRemoveDescription: RowProperties = [
|
|||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getRowIds',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['remove'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'Remove any row from the normal or big data backend based on its unique row ID. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['remove'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
|
||||
const requestBody: IDataObject = {
|
||||
table_name: tableName,
|
||||
row_ids: [rowId],
|
||||
};
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'DELETE',
|
||||
'/dtable-db/api/v1/delete-rows/{{dtable_uuid}}/',
|
||||
requestBody,
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
|
||||
export async function remove(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
|
||||
const requestBody: IDataObject = {
|
||||
table_name: tableName,
|
||||
row_ids: [rowId],
|
||||
};
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'DELETE',
|
||||
'/dtable-db/api/v1/delete-rows/{{dtable_uuid}}/',
|
||||
requestBody,
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { remove as execute } from './execute';
|
||||
import { rowRemoveDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -0,0 +1,137 @@
|
|||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import {
|
||||
seaTableApiRequest,
|
||||
enrichColumns,
|
||||
simplify_new,
|
||||
getBaseCollaborators,
|
||||
} from '../../GenericFunctions';
|
||||
import type { IDtableMetadataColumn, IRowResponse } from '../Interfaces';
|
||||
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
type: 'options',
|
||||
placeholder: 'Select a table',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'The name of SeaTable table to access. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Column Name',
|
||||
name: 'searchColumn',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getSearchableColumns',
|
||||
},
|
||||
required: true,
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'Select the column to be searched. Not all column types are supported for search. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Search Term',
|
||||
name: 'searchTerm',
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: '',
|
||||
description: 'What to look for?',
|
||||
},
|
||||
{
|
||||
displayName: 'Case Insensitive Search',
|
||||
name: 'insensitive',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description:
|
||||
'Whether the search ignores case sensitivity (true). Otherwise, it distinguishes between uppercase and lowercase characters.',
|
||||
},
|
||||
{
|
||||
displayName: 'Activate Wildcard Search',
|
||||
name: 'wildcard',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
description:
|
||||
'Whether the search only results perfect matches (true). Otherwise, it finds a row even if the search value is part of a string (false).',
|
||||
},
|
||||
{
|
||||
displayName: 'Simplify',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['search'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const searchColumn = this.getNodeParameter('searchColumn', index) as string;
|
||||
const searchTerm = this.getNodeParameter('searchTerm', index) as string | number;
|
||||
let searchTermString = String(searchTerm);
|
||||
const insensitive = this.getNodeParameter('insensitive', index) as boolean;
|
||||
const wildcard = this.getNodeParameter('wildcard', index) as boolean;
|
||||
const simple = this.getNodeParameter('simple', index) as boolean;
|
||||
|
||||
// get collaborators
|
||||
const collaborators = await getBaseCollaborators.call(this);
|
||||
|
||||
// this is the base query. The WHERE has to be finalized...
|
||||
let sqlQuery = `SELECT * FROM \`${tableName}\` WHERE \`${searchColumn}\``;
|
||||
|
||||
if (insensitive) {
|
||||
searchTermString = searchTermString.toLowerCase();
|
||||
sqlQuery = `SELECT * FROM \`${tableName}\` WHERE lower(\`${searchColumn}\`)`;
|
||||
}
|
||||
|
||||
if (wildcard) sqlQuery = sqlQuery + ' LIKE "%' + searchTermString + '%"';
|
||||
else if (!wildcard) sqlQuery = sqlQuery + ' = "' + searchTermString + '"';
|
||||
|
||||
const sqlResult = (await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-db/api/v1/query/{{dtable_uuid}}/',
|
||||
{
|
||||
sql: sqlQuery,
|
||||
convert_keys: true,
|
||||
},
|
||||
)) as IRowResponse;
|
||||
const metadata = sqlResult.metadata as IDtableMetadataColumn[];
|
||||
const rows = sqlResult.results;
|
||||
|
||||
// hide columns like button
|
||||
rows.map((row) => enrichColumns(row, metadata, collaborators));
|
||||
|
||||
// remove columns starting with _;
|
||||
if (simple) {
|
||||
rows.map((row) => simplify_new(row));
|
||||
}
|
||||
|
||||
return this.helpers.returnJsonArray(rows as IDataObject[]);
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
import type { RowProperties } from '../../Interfaces';
|
||||
|
||||
export const rowSearchDescription: RowProperties = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
type: 'options',
|
||||
placeholder: 'Select a table',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['search'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'The name of SeaTable table to access. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Column Name',
|
||||
name: 'searchColumn',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['search'],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getSearchableColumns',
|
||||
},
|
||||
required: true,
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'Select the column to be searched. Not all column types are supported for search. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
displayName: 'Search Term',
|
||||
name: 'searchTerm',
|
||||
type: 'string',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['search'],
|
||||
},
|
||||
},
|
||||
required: true,
|
||||
default: '',
|
||||
description: 'What to look for?',
|
||||
},
|
||||
{
|
||||
displayName: 'Case Insensitive Search',
|
||||
name: 'insensitive',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['search'],
|
||||
},
|
||||
},
|
||||
default: false,
|
||||
description:
|
||||
'Whether the search ignores case sensitivity (true). Otherwise, it distinguishes between uppercase and lowercase characters.',
|
||||
},
|
||||
{
|
||||
displayName: 'Activate Wildcard Search',
|
||||
name: 'wildcard',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['search'],
|
||||
},
|
||||
},
|
||||
default: false,
|
||||
description:
|
||||
'Whether the search only results perfect matches (true). Otherwise, it finds a row even if the search value is part of a string (false).',
|
||||
},
|
||||
{
|
||||
displayName: 'Simplify',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['search'],
|
||||
},
|
||||
},
|
||||
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||
},
|
||||
];
|
|
@ -1,58 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import {
|
||||
seaTableApiRequest,
|
||||
enrichColumns,
|
||||
simplify_new,
|
||||
getBaseCollaborators,
|
||||
} from '../../../GenericFunctions';
|
||||
import type { IDtableMetadataColumn, IRowResponse } from '../../Interfaces';
|
||||
|
||||
export async function search(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const searchColumn = this.getNodeParameter('searchColumn', index) as string;
|
||||
const searchTerm = this.getNodeParameter('searchTerm', index) as string | number;
|
||||
let searchTermString = String(searchTerm);
|
||||
const insensitive = this.getNodeParameter('insensitive', index) as boolean;
|
||||
const wildcard = this.getNodeParameter('wildcard', index) as boolean;
|
||||
const simple = this.getNodeParameter('simple', index) as boolean;
|
||||
|
||||
// get collaborators
|
||||
const collaborators = await getBaseCollaborators.call(this);
|
||||
|
||||
// this is the base query. The WHERE has to be finalized...
|
||||
let sqlQuery = `SELECT * FROM \`${tableName}\` WHERE \`${searchColumn}\``;
|
||||
|
||||
if (insensitive) {
|
||||
searchTermString = searchTermString.toLowerCase();
|
||||
sqlQuery = `SELECT * FROM \`${tableName}\` WHERE lower(\`${searchColumn}\`)`;
|
||||
}
|
||||
|
||||
if (wildcard) sqlQuery = sqlQuery + ' LIKE "%' + searchTermString + '%"';
|
||||
else if (!wildcard) sqlQuery = sqlQuery + ' = "' + searchTermString + '"';
|
||||
|
||||
const sqlResult = (await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'POST',
|
||||
'/dtable-db/api/v1/query/{{dtable_uuid}}/',
|
||||
{
|
||||
sql: sqlQuery,
|
||||
convert_keys: true,
|
||||
},
|
||||
)) as IRowResponse;
|
||||
const metadata = sqlResult.metadata as IDtableMetadataColumn[];
|
||||
const rows = sqlResult.results;
|
||||
|
||||
// hide columns like button
|
||||
rows.map((row) => enrichColumns(row, metadata, collaborators));
|
||||
|
||||
// remove columns starting with _;
|
||||
if (simple) {
|
||||
rows.map((row) => simplify_new(row));
|
||||
}
|
||||
|
||||
return this.helpers.returnJsonArray(rows as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { search as execute } from './execute';
|
||||
import { rowSearchDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -1,6 +1,13 @@
|
|||
import type { RowProperties } from '../../Interfaces';
|
||||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../GenericFunctions';
|
||||
|
||||
export const rowGetDescription: RowProperties = [
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
|
@ -11,12 +18,6 @@ export const rowGetDescription: RowProperties = [
|
|||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
|
@ -34,25 +35,36 @@ export const rowGetDescription: RowProperties = [
|
|||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getRowIds',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Simplify',
|
||||
name: 'simple',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['get'],
|
||||
},
|
||||
},
|
||||
default: true,
|
||||
description: 'Whether to return a simplified version of the response instead of the raw data',
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['unlock'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'PUT',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/unlock-rows/',
|
||||
{
|
||||
table_name: tableName,
|
||||
row_ids: [rowId],
|
||||
},
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
import type { RowProperties } from '../../Interfaces';
|
||||
|
||||
export const rowUnlockDescription: RowProperties = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
name: 'tableName',
|
||||
type: 'options',
|
||||
placeholder: 'Select a table',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['unlock'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
'The name of SeaTable table to access. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
||||
},
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Row ID',
|
||||
name: 'rowId',
|
||||
type: 'options',
|
||||
description:
|
||||
'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
|
||||
required: true,
|
||||
typeOptions: {
|
||||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getRowIds',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['unlock'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
];
|
|
@ -1,23 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import { seaTableApiRequest } from '../../../GenericFunctions';
|
||||
|
||||
export async function unlock(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'PUT',
|
||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/unlock-rows/',
|
||||
{
|
||||
table_name: tableName,
|
||||
row_ids: [rowId],
|
||||
},
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { unlock as execute } from './execute';
|
||||
import { rowUnlockDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
|
@ -1,6 +1,22 @@
|
|||
import type { RowProperties } from '../../Interfaces';
|
||||
import {
|
||||
type IDataObject,
|
||||
type INodeExecutionData,
|
||||
type INodeProperties,
|
||||
type IExecuteFunctions,
|
||||
updateDisplayOptions,
|
||||
} from 'n8n-workflow';
|
||||
import {
|
||||
seaTableApiRequest,
|
||||
getTableColumns,
|
||||
split,
|
||||
rowExport,
|
||||
updateAble,
|
||||
splitStringColumnsToArrays,
|
||||
} from '../../GenericFunctions';
|
||||
import type { IRowObject } from '../Interfaces';
|
||||
import type { TColumnsUiValues, TColumnValue } from '../../types';
|
||||
|
||||
export const rowUpdateDescription: RowProperties = [
|
||||
export const properties: INodeProperties[] = [
|
||||
{
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options
|
||||
displayName: 'Table Name',
|
||||
|
@ -11,12 +27,6 @@ export const rowUpdateDescription: RowProperties = [
|
|||
typeOptions: {
|
||||
loadOptionsMethod: 'getTableNames',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
||||
description:
|
||||
|
@ -35,12 +45,6 @@ export const rowUpdateDescription: RowProperties = [
|
|||
loadOptionsDependsOn: ['tableName'],
|
||||
loadOptionsMethod: 'getRowIds',
|
||||
},
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
|
@ -59,12 +63,6 @@ export const rowUpdateDescription: RowProperties = [
|
|||
description: 'Set the value for each destination column',
|
||||
},
|
||||
],
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
default: 'defineBelow',
|
||||
description: 'Whether to insert the input data this node receives in the new row',
|
||||
},
|
||||
|
@ -137,11 +135,70 @@ export const rowUpdateDescription: RowProperties = [
|
|||
name: 'notice',
|
||||
type: 'notice',
|
||||
default: '',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['update'],
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const displayOptions = {
|
||||
show: {
|
||||
resource: ['row'],
|
||||
operation: ['update'],
|
||||
},
|
||||
};
|
||||
|
||||
export const description = updateDisplayOptions(displayOptions, properties);
|
||||
|
||||
export async function execute(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const tableColumns = await getTableColumns.call(this, tableName);
|
||||
const fieldsToSend = this.getNodeParameter('fieldsToSend', index) as
|
||||
| 'defineBelow'
|
||||
| 'autoMapInputData';
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
|
||||
let rowInput = {} as IRowObject;
|
||||
|
||||
// get rowInput, an object of key:value pairs like { Name: 'Promo Action 1', Status: "Draft" }.
|
||||
if (fieldsToSend === 'autoMapInputData') {
|
||||
const items = this.getInputData();
|
||||
const incomingKeys = Object.keys(items[index].json);
|
||||
const inputDataToIgnore = split(this.getNodeParameter('inputsToIgnore', index, '') as string);
|
||||
for (const key of incomingKeys) {
|
||||
if (inputDataToIgnore.includes(key)) continue;
|
||||
rowInput[key] = items[index].json[key] as TColumnValue;
|
||||
}
|
||||
} else {
|
||||
const columns = this.getNodeParameter('columnsUi.columnValues', index, []) as TColumnsUiValues;
|
||||
for (const column of columns) {
|
||||
rowInput[column.columnName] = column.columnValue;
|
||||
}
|
||||
}
|
||||
|
||||
// only keep key:value pairs for columns that are allowed to update.
|
||||
rowInput = rowExport(rowInput, updateAble(tableColumns));
|
||||
|
||||
// string to array: multi-select and collaborators
|
||||
rowInput = splitStringColumnsToArrays(rowInput, tableColumns);
|
||||
|
||||
const body = {
|
||||
table_name: tableName,
|
||||
updates: [
|
||||
{
|
||||
row_id: rowId,
|
||||
row: rowInput,
|
||||
},
|
||||
],
|
||||
} as IDataObject;
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'PUT',
|
||||
'/dtable-db/api/v1/update-rows/{{dtable_uuid}}/',
|
||||
body,
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
import type { IExecuteFunctions, IDataObject, INodeExecutionData } from 'n8n-workflow';
|
||||
import {
|
||||
seaTableApiRequest,
|
||||
getTableColumns,
|
||||
split,
|
||||
rowExport,
|
||||
updateAble,
|
||||
splitStringColumnsToArrays,
|
||||
} from '../../../GenericFunctions';
|
||||
import type { IRowObject } from '../../Interfaces';
|
||||
import type { TColumnsUiValues, TColumnValue } from '../../../types';
|
||||
|
||||
export async function update(
|
||||
this: IExecuteFunctions,
|
||||
index: number,
|
||||
): Promise<INodeExecutionData[]> {
|
||||
const tableName = this.getNodeParameter('tableName', index) as string;
|
||||
const tableColumns = await getTableColumns.call(this, tableName);
|
||||
const fieldsToSend = this.getNodeParameter('fieldsToSend', index) as
|
||||
| 'defineBelow'
|
||||
| 'autoMapInputData';
|
||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||
|
||||
let rowInput = {} as IRowObject;
|
||||
|
||||
// get rowInput, an object of key:value pairs like { Name: 'Promo Action 1', Status: "Draft" }.
|
||||
if (fieldsToSend === 'autoMapInputData') {
|
||||
const items = this.getInputData();
|
||||
const incomingKeys = Object.keys(items[index].json);
|
||||
const inputDataToIgnore = split(this.getNodeParameter('inputsToIgnore', index, '') as string);
|
||||
for (const key of incomingKeys) {
|
||||
if (inputDataToIgnore.includes(key)) continue;
|
||||
rowInput[key] = items[index].json[key] as TColumnValue;
|
||||
}
|
||||
} else {
|
||||
const columns = this.getNodeParameter('columnsUi.columnValues', index, []) as TColumnsUiValues;
|
||||
for (const column of columns) {
|
||||
rowInput[column.columnName] = column.columnValue;
|
||||
}
|
||||
}
|
||||
|
||||
// only keep key:value pairs for columns that are allowed to update.
|
||||
rowInput = rowExport(rowInput, updateAble(tableColumns));
|
||||
|
||||
// string to array: multi-select and collaborators
|
||||
rowInput = splitStringColumnsToArrays(rowInput, tableColumns);
|
||||
|
||||
const body = {
|
||||
table_name: tableName,
|
||||
updates: [
|
||||
{
|
||||
row_id: rowId,
|
||||
row: rowInput,
|
||||
},
|
||||
],
|
||||
} as IDataObject;
|
||||
|
||||
const responseData = await seaTableApiRequest.call(
|
||||
this,
|
||||
{},
|
||||
'PUT',
|
||||
'/dtable-db/api/v1/update-rows/{{dtable_uuid}}/',
|
||||
body,
|
||||
);
|
||||
|
||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import { update as execute } from './execute';
|
||||
import { rowUpdateDescription as description } from './description';
|
||||
|
||||
export { description, execute };
|
Loading…
Reference in a new issue