mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
n8n-3867-progressively-apply-prettier-to-all (#3873)
* 🔨 formatting nodes with prettier
This commit is contained in:
@@ -1,7 +1,4 @@
|
||||
import {
|
||||
IExecuteFunctions,
|
||||
ILoadOptionsFunctions,
|
||||
} from 'n8n-core';
|
||||
import { IExecuteFunctions, ILoadOptionsFunctions } from 'n8n-core';
|
||||
|
||||
import {
|
||||
IDataObject,
|
||||
@@ -14,7 +11,11 @@ import {
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
export async function koBoToolboxApiRequest(this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||
export async function koBoToolboxApiRequest(
|
||||
this: IExecuteFunctions | IWebhookFunctions | IHookFunctions | ILoadOptionsFunctions,
|
||||
option: IDataObject = {},
|
||||
// tslint:disable-next-line:no-any
|
||||
): Promise<any> {
|
||||
const credentials = await this.getCredentials('koBoToolboxApi');
|
||||
|
||||
// Set up pagination / scrolling
|
||||
@@ -29,7 +30,7 @@ export async function koBoToolboxApiRequest(this: IExecuteFunctions | IWebhookFu
|
||||
const options: IHttpRequestOptions = {
|
||||
url: '',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
Accept: 'application/json',
|
||||
},
|
||||
json: true,
|
||||
};
|
||||
@@ -43,13 +44,16 @@ export async function koBoToolboxApiRequest(this: IExecuteFunctions | IWebhookFu
|
||||
let results = null;
|
||||
let keepLooking = true;
|
||||
while (keepLooking) {
|
||||
const response = await this.helpers.httpRequestWithAuthentication.call(this, 'koBoToolboxApi', options);
|
||||
const response = await this.helpers.httpRequestWithAuthentication.call(
|
||||
this,
|
||||
'koBoToolboxApi',
|
||||
options,
|
||||
);
|
||||
// Append or set results
|
||||
results = response.results ? _.concat(results || [], response.results) : response;
|
||||
if (returnAll && response.next) {
|
||||
options.url = response.next;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
keepLooking = false;
|
||||
}
|
||||
}
|
||||
@@ -61,12 +65,12 @@ function parseGeoPoint(geoPoint: string): null | number[] {
|
||||
// Check if it looks like a "lat lon z precision" flat string e.g. "-1.931161 30.079811 0 0" (lat, lon, elevation, precision)
|
||||
// NOTE: we are discarding the elevation and precision values since they're not (well) supported in GeoJSON
|
||||
const coordinates = _.split(geoPoint, ' ');
|
||||
if (coordinates.length >= 2 && _.every(coordinates, coord => coord && /^-?\d+(?:\.\d+)?$/.test(_.toString(coord)))) {
|
||||
if (
|
||||
coordinates.length >= 2 &&
|
||||
_.every(coordinates, (coord) => coord && /^-?\d+(?:\.\d+)?$/.test(_.toString(coord)))
|
||||
) {
|
||||
// NOTE: GeoJSON uses lon, lat, while most common systems use lat, lon order!
|
||||
return [
|
||||
_.toNumber(coordinates[1]),
|
||||
_.toNumber(coordinates[0]),
|
||||
];
|
||||
return [_.toNumber(coordinates[1]), _.toNumber(coordinates[0])];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -80,7 +84,8 @@ const matchWildcard = (value: string, pattern: string): boolean => {
|
||||
return regex.test(value);
|
||||
};
|
||||
|
||||
const formatValue = (value: any, format: string): any => { //tslint:disable-line:no-any
|
||||
// tslint:disable-next-line:no-any
|
||||
const formatValue = (value: any, format: string): any => {
|
||||
if (_.isString(value)) {
|
||||
// Sanitize value
|
||||
value = _.toString(value);
|
||||
@@ -102,15 +107,14 @@ const formatValue = (value: any, format: string): any => { //tslint:disable-line
|
||||
// Only return if all values are properly parsed
|
||||
if (coordinates.length === points.length) {
|
||||
// If the shape is closed, declare it as Polygon, otherwise as LineString
|
||||
return _.first(points) === _.last(points)
|
||||
? {
|
||||
if (_.first(points) === _.last(points)) {
|
||||
return {
|
||||
type: 'Polygon',
|
||||
coordinates: [coordinates],
|
||||
}
|
||||
: {
|
||||
type: 'LineString',
|
||||
coordinates,
|
||||
};
|
||||
}
|
||||
|
||||
return { type: 'LineString', coordinates };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,20 +132,27 @@ const formatValue = (value: any, format: string): any => { //tslint:disable-line
|
||||
return value;
|
||||
};
|
||||
|
||||
export function formatSubmission(submission: IDataObject, selectMasks: string[] = [], numberMasks: string[] = []): IDataObject {
|
||||
export function formatSubmission(
|
||||
submission: IDataObject,
|
||||
selectMasks: string[] = [],
|
||||
numberMasks: string[] = [],
|
||||
): IDataObject {
|
||||
// Create a shallow copy of the submission
|
||||
const response = {} as IDataObject;
|
||||
|
||||
for (const key of Object.keys(submission)) {
|
||||
let value = _.clone(submission[key]);
|
||||
// Sanitize key names: split by group, trim _
|
||||
const sanitizedKey = key.split('/').map(k => _.trim(k, ' _')).join('.');
|
||||
const sanitizedKey = key
|
||||
.split('/')
|
||||
.map((k) => _.trim(k, ' _'))
|
||||
.join('.');
|
||||
const leafKey = sanitizedKey.split('.').pop() || '';
|
||||
let format = 'string';
|
||||
if (_.some(numberMasks, mask => matchWildcard(leafKey, mask))) {
|
||||
if (_.some(numberMasks, (mask) => matchWildcard(leafKey, mask))) {
|
||||
format = 'number';
|
||||
}
|
||||
if (_.some(selectMasks, mask => matchWildcard(leafKey, mask))) {
|
||||
if (_.some(selectMasks, (mask) => matchWildcard(leafKey, mask))) {
|
||||
format = 'multiSelect';
|
||||
}
|
||||
|
||||
@@ -151,7 +162,12 @@ export function formatSubmission(submission: IDataObject, selectMasks: string[]
|
||||
}
|
||||
|
||||
// Reformat _geolocation
|
||||
if (_.isArray(response.geolocation) && response.geolocation.length === 2 && response.geolocation[0] && response.geolocation[1]) {
|
||||
if (
|
||||
_.isArray(response.geolocation) &&
|
||||
response.geolocation.length === 2 &&
|
||||
response.geolocation[0] &&
|
||||
response.geolocation[1]
|
||||
) {
|
||||
response.geolocation = {
|
||||
type: 'Point',
|
||||
coordinates: [response.geolocation[1], response.geolocation[0]],
|
||||
@@ -161,7 +177,11 @@ export function formatSubmission(submission: IDataObject, selectMasks: string[]
|
||||
return response;
|
||||
}
|
||||
|
||||
export async function downloadAttachments(this: IExecuteFunctions | IWebhookFunctions, submission: IDataObject, options: IDataObject): Promise<INodeExecutionData> {
|
||||
export async function downloadAttachments(
|
||||
this: IExecuteFunctions | IWebhookFunctions,
|
||||
submission: IDataObject,
|
||||
options: IDataObject,
|
||||
): Promise<INodeExecutionData> {
|
||||
// Initialize return object with the original submission JSON content
|
||||
const binaryItem: INodeExecutionData = {
|
||||
json: {
|
||||
@@ -173,20 +193,20 @@ export async function downloadAttachments(this: IExecuteFunctions | IWebhookFunc
|
||||
const credentials = await this.getCredentials('koBoToolboxApi');
|
||||
|
||||
// Look for attachment links - there can be more than one
|
||||
const attachmentList = (submission['_attachments'] || submission['attachments']) as any[]; // tslint:disable-line:no-any
|
||||
const attachmentList = (submission['_attachments'] || submission['attachments']) as any[]; // tslint:disable-line:no-any
|
||||
if (attachmentList && attachmentList.length) {
|
||||
for (const [index, attachment] of attachmentList.entries()) {
|
||||
// look for the question name linked to this attachment
|
||||
const fileName = attachment.filename;
|
||||
const sanitizedFileName = _.toString(fileName).replace(/_[^_]+(?=\.\w+)/,''); // strip suffix
|
||||
const sanitizedFileName = _.toString(fileName).replace(/_[^_]+(?=\.\w+)/, ''); // strip suffix
|
||||
|
||||
let relatedQuestion = null;
|
||||
if('question' === options.binaryNamingScheme) {
|
||||
for(const question of Object.keys(submission)) {
|
||||
if ('question' === options.binaryNamingScheme) {
|
||||
for (const question of Object.keys(submission)) {
|
||||
// The logic to map attachments to question is sometimes ambiguous:
|
||||
// - If the attachment is linked to a question, the question's value is the same as the attachment's filename (with spaces replaced by underscores)
|
||||
// - BUT sometimes the attachment's filename has an extra suffix, e.g. "My_Picture_0OdlaKJ.jpg", would map to the question "picture": "My Picture.jpg"
|
||||
const sanitizedQuestionValue = _.toString(submission[question]).replace(/\s/g, '_'); // replace spaces with underscores
|
||||
const sanitizedQuestionValue = _.toString(submission[question]).replace(/\s/g, '_'); // replace spaces with underscores
|
||||
if (sanitizedFileName === sanitizedQuestionValue) {
|
||||
relatedQuestion = question;
|
||||
// Just use the first match...
|
||||
@@ -199,14 +219,16 @@ export async function downloadAttachments(this: IExecuteFunctions | IWebhookFunc
|
||||
// NOTE: this needs to follow redirects (possibly across domains), while keeping Authorization headers
|
||||
// The Axios client will not propagate the Authorization header on redirects (see https://github.com/axios/axios/issues/3607), so we need to follow ourselves...
|
||||
let response = null;
|
||||
const attachmentUrl = attachment[options.version as string] || attachment.download_url as string;
|
||||
let final = false, redir = 0;
|
||||
const attachmentUrl =
|
||||
attachment[options.version as string] || (attachment.download_url as string);
|
||||
let final = false,
|
||||
redir = 0;
|
||||
|
||||
const axiosOptions: IHttpRequestOptions = {
|
||||
url: attachmentUrl,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Token ${credentials.token}`,
|
||||
Authorization: `Token ${credentials.token}`,
|
||||
},
|
||||
ignoreHttpStatusErrors: true,
|
||||
returnFullResponse: true,
|
||||
@@ -229,14 +251,16 @@ export async function downloadAttachments(this: IExecuteFunctions | IWebhookFunc
|
||||
if (response && response.body) {
|
||||
// Use the provided prefix if any, otherwise try to use the original question name
|
||||
let binaryName;
|
||||
if('question' === options.binaryNamingScheme && relatedQuestion) {
|
||||
if ('question' === options.binaryNamingScheme && relatedQuestion) {
|
||||
binaryName = relatedQuestion;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
binaryName = `${options.dataPropertyAttachmentsPrefixName || 'attachment_'}${index}`;
|
||||
}
|
||||
|
||||
binaryItem.binary![binaryName] = await this.helpers.prepareBinaryData(response.body, fileName);
|
||||
binaryItem.binary![binaryName] = await this.helpers.prepareBinaryData(
|
||||
response.body,
|
||||
fileName,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -257,5 +281,5 @@ export async function loadForms(this: ILoadOptionsFunctions): Promise<INodePrope
|
||||
scroll: true,
|
||||
});
|
||||
|
||||
return responseData?.map((survey: any) => ({ name: survey.name, value: survey.uid })) || []; // tslint:disable-line:no-any
|
||||
return responseData?.map((survey: any) => ({ name: survey.name, value: survey.uid })) || []; // tslint:disable-line:no-any
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user