n8n-nodes-base
Version:
Base nodes of n8n
173 lines • 7.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.description = void 0;
exports.execute = execute;
const n8n_workflow_1 = require("n8n-workflow");
const GenericFunctions_1 = require("../../GenericFunctions");
const properties = [
{
// 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: '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: 'Choose from the list, or specify the name using an <a href="https://docs.n8n.io/code/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/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: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Option',
default: {},
options: [
{
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'],
},
};
exports.description = (0, n8n_workflow_1.updateDisplayOptions)(displayOptions, properties);
async function execute(index) {
const uploadColumn = this.getNodeParameter('uploadColumn', index);
const uploadColumnType = uploadColumn.split(':::')[1];
const uploadColumnName = uploadColumn.split(':::')[0];
const dataPropertyName = this.getNodeParameter('dataPropertyName', index);
const tableName = this.getNodeParameter('tableName', index);
const rowId = this.getNodeParameter('rowId', index);
const uploadLink = (await GenericFunctions_1.seaTableApiRequest.call(this, {}, 'GET', '/api/v2.1/dtable/app-upload-link/'));
const relativePath = uploadColumnType === 'image' ? uploadLink.img_relative_path : uploadLink.file_relative_path;
const options = this.getNodeParameter('options', index);
// get server url
const credentials = await this.getCredentials('seaTableApi');
const serverURL = credentials.domain
? credentials.domain.replace(/\/$/, '')
: 'https://cloud.seatable.io';
// get workspaceId
const workspaceId = (await this.helpers.httpRequest({
headers: {
Authorization: `Token ${credentials.token}`,
},
url: `${serverURL}/api/v2.1/dtable/app-access-token/`,
json: true,
})).workspace_id;
// if there are already assets attached to the column
let existingAssetArray = [];
const append = options.append ?? true;
if (append) {
const rowToUpdate = await GenericFunctions_1.seaTableApiRequest.call(this, {}, 'GET', '/api-gateway/api/v2/dtables/{{dtable_uuid}}/rows/' + rowId, {}, {
table_name: tableName,
convert_keys: true,
});
existingAssetArray = rowToUpdate[uploadColumnName] ?? [];
}
// Get the binary data and prepare asset for upload
const fileBufferData = await this.helpers.getBinaryDataBuffer(index, dataPropertyName);
const binaryData = this.helpers.assertBinaryData(index, dataPropertyName);
const requestOptions = {
formData: {
file: {
value: fileBufferData,
options: {
filename: binaryData.fileName,
contentType: binaryData.mimeType,
},
},
parent_dir: uploadLink.parent_path,
replace: options.replace ? '1' : '0',
relative_path: relativePath,
},
};
// Send the upload request
const uploadAsset = await GenericFunctions_1.seaTableApiRequest.call(this, {}, 'POST', `/seafhttp/upload-api/${uploadLink.upload_link.split('seafhttp/upload-api/')[1]}?ret-json=true`, {}, {}, '', requestOptions);
// attach the asset to a column in a base
for (let c = 0; c < uploadAsset.length; c++) {
const rowInput = {};
const filePath = `${serverURL}/workspace/${workspaceId}${uploadLink.parent_path}/${relativePath}/${uploadAsset[c].name}`;
if (uploadColumnType === 'image') {
rowInput[uploadColumnName] = [filePath];
}
else if (uploadColumnType === 'file') {
rowInput[uploadColumnName] = uploadAsset;
uploadAsset[c].type = 'file';
uploadAsset[c].url = filePath;
}
// merge with existing assets in this column or with [] and remove duplicates
const mergedArray = existingAssetArray.concat(rowInput[uploadColumnName]);
// Remove duplicates from input, keeping the last one
const uniqueAssets = Array.from(new Set(mergedArray));
// Update the rowInput with the unique assets and store into body.row.
rowInput[uploadColumnName] = uniqueAssets;
const body = {
table_name: tableName,
updates: [
{
row_id: rowId,
row: rowInput,
},
],
};
// attach assets to table row
const responseData = await GenericFunctions_1.seaTableApiRequest.call(this, {}, 'PUT', '/api-gateway/api/v2/dtables/{{dtable_uuid}}/rows/', body);
uploadAsset[c].upload_successful = responseData.success;
}
return this.helpers.returnJsonArray(uploadAsset);
}
//# sourceMappingURL=upload.operation.js.map