fix: Update operations to run per item (#8967)

Co-authored-by: Elias Meire <elias@meire.dev>
This commit is contained in:
Michael Kret
2024-05-22 15:28:09 +03:00
committed by GitHub
parent 870412f093
commit ef9d4aba90
12 changed files with 611 additions and 442 deletions

View File

@@ -28,7 +28,7 @@ export class GoogleFirebaseCloudFirestore implements INodeType {
// eslint-disable-next-line n8n-nodes-base/node-class-description-icon-not-svg
icon: 'file:googleFirebaseCloudFirestore.png',
group: ['input'],
version: 1,
version: [1, 1.1],
subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}',
description: 'Interact with Google Firebase - Cloud Firestore API',
defaults: {
@@ -94,15 +94,27 @@ export class GoogleFirebaseCloudFirestore implements INodeType {
const itemData = generatePairedItemData(items.length);
const returnData: INodeExecutionData[] = [];
let responseData;
const resource = this.getNodeParameter('resource', 0);
const operation = this.getNodeParameter('operation', 0);
const nodeVersion = this.getNode().typeVersion;
let itemsLength = items.length ? 1 : 0;
let fallbackPairedItems;
if (nodeVersion >= 1.1) {
itemsLength = items.length;
} else {
fallbackPairedItems = generatePairedItemData(items.length);
}
if (resource === 'document') {
if (operation === 'get') {
const projectId = this.getNodeParameter('projectId', 0) as string;
const database = this.getNodeParameter('database', 0) as string;
const simple = this.getNodeParameter('simple', 0) as boolean;
const documentList = items.map((item: IDataObject, i: number) => {
const documentList = items.map((_: IDataObject, i: number) => {
const collection = this.getNodeParameter('collection', i) as string;
const documentId = this.getNodeParameter('documentId', i) as string;
return `projects/${projectId}/databases/${database}/documents/${collection}/${documentId}`;
@@ -179,49 +191,64 @@ export class GoogleFirebaseCloudFirestore implements INodeType {
}),
);
} else if (operation === 'getAll') {
const projectId = this.getNodeParameter('projectId', 0) as string;
const database = this.getNodeParameter('database', 0) as string;
const collection = this.getNodeParameter('collection', 0) as string;
const returnAll = this.getNodeParameter('returnAll', 0);
const simple = this.getNodeParameter('simple', 0) as boolean;
for (let i = 0; i < itemsLength; i++) {
try {
const projectId = this.getNodeParameter('projectId', i) as string;
const database = this.getNodeParameter('database', i) as string;
const collection = this.getNodeParameter('collection', i) as string;
const returnAll = this.getNodeParameter('returnAll', i);
const simple = this.getNodeParameter('simple', i) as boolean;
if (returnAll) {
responseData = await googleApiRequestAllItems.call(
this,
'documents',
'GET',
`/${projectId}/databases/${database}/documents/${collection}`,
);
} else {
const limit = this.getNodeParameter('limit', 0);
const getAllResponse = (await googleApiRequest.call(
this,
'GET',
`/${projectId}/databases/${database}/documents/${collection}`,
{},
{ pageSize: limit },
)) as IDataObject;
responseData = getAllResponse.documents;
if (returnAll) {
responseData = await googleApiRequestAllItems.call(
this,
'documents',
'GET',
`/${projectId}/databases/${database}/documents/${collection}`,
);
} else {
const limit = this.getNodeParameter('limit', i);
const getAllResponse = (await googleApiRequest.call(
this,
'GET',
`/${projectId}/databases/${database}/documents/${collection}`,
{},
{ pageSize: limit },
)) as IDataObject;
responseData = getAllResponse.documents;
}
responseData = responseData.map((element: IDataObject) => {
element.id = (element.name as string).split('/').pop();
return element;
});
if (simple) {
responseData = responseData.map((element: IDataObject) =>
fullDocumentToJson(element),
);
}
const executionData = this.helpers.constructExecutionMetaData(
this.helpers.returnJsonArray(responseData as IDataObject[]),
{ itemData: fallbackPairedItems ?? [{ item: i }] },
);
returnData.push(...executionData);
} catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: { error: error.message },
pairedItem: fallbackPairedItems ?? [{ item: i }],
});
continue;
}
throw error;
}
}
responseData = responseData.map((element: IDataObject) => {
element.id = (element.name as string).split('/').pop();
return element;
});
if (simple) {
responseData = responseData.map((element: IDataObject) => fullDocumentToJson(element));
}
const executionData = this.helpers.constructExecutionMetaData(
this.helpers.returnJsonArray(responseData as IDataObject[]),
{ itemData },
);
returnData.push(...executionData);
} else if (operation === 'delete') {
await Promise.all(
items.map(async (item: IDataObject, i: number) => {
items.map(async (_: IDataObject, i: number) => {
const projectId = this.getNodeParameter('projectId', i) as string;
const database = this.getNodeParameter('database', i) as string;
const collection = this.getNodeParameter('collection', i) as string;
@@ -295,44 +322,13 @@ export class GoogleFirebaseCloudFirestore implements INodeType {
returnData.push(...executionData);
}
// } else if (operation === 'update') {
// const projectId = this.getNodeParameter('projectId', 0) as string;
// const database = this.getNodeParameter('database', 0) as string;
// const simple = this.getNodeParameter('simple', 0) as boolean;
// await Promise.all(items.map(async (item: IDataObject, i: number) => {
// const collection = this.getNodeParameter('collection', i) as string;
// const updateKey = this.getNodeParameter('updateKey', i) as string;
// // @ts-ignore
// const documentId = item['json'][updateKey] as string;
// const columns = this.getNodeParameter('columns', i) as string;
// const columnList = columns.split(',').map(column => column.trim()) as string[];
// const document = {};
// columnList.map(column => {
// // @ts-ignore
// document[column] = item['json'].hasOwnProperty(column) ? jsonToDocument(item['json'][column]) : jsonToDocument(null);
// });
// responseData = await googleApiRequest.call(
// this,
// 'PATCH',
// `/${projectId}/databases/${database}/documents/${collection}/${documentId}`,
// { fields: document },
// { [`updateMask.fieldPaths`]: columnList },
// );
// if (simple === false) {
// returnData.push(responseData);
// } else {
// returnData.push(fullDocumentToJson(responseData as IDataObject));
// }
// }));
} else if (operation === 'query') {
const projectId = this.getNodeParameter('projectId', 0) as string;
const database = this.getNodeParameter('database', 0) as string;
const simple = this.getNodeParameter('simple', 0) as boolean;
await Promise.all(
items.map(async (item: IDataObject, i: number) => {
items.map(async (_: IDataObject, i: number) => {
const query = this.getNodeParameter('query', i) as string;
responseData = await googleApiRequest.call(
this,
@@ -369,38 +365,51 @@ export class GoogleFirebaseCloudFirestore implements INodeType {
}
} else if (resource === 'collection') {
if (operation === 'getAll') {
const projectId = this.getNodeParameter('projectId', 0) as string;
const database = this.getNodeParameter('database', 0) as string;
const returnAll = this.getNodeParameter('returnAll', 0);
for (let i = 0; i < itemsLength; i++) {
try {
const projectId = this.getNodeParameter('projectId', i) as string;
const database = this.getNodeParameter('database', i) as string;
const returnAll = this.getNodeParameter('returnAll', i);
if (returnAll) {
const getAllResponse = await googleApiRequestAllItems.call(
this,
'collectionIds',
'POST',
`/${projectId}/databases/${database}/documents:listCollectionIds`,
);
// @ts-ignore
responseData = getAllResponse.map((o) => ({ name: o }));
} else {
const limit = this.getNodeParameter('limit', 0);
const getAllResponse = (await googleApiRequest.call(
this,
'POST',
`/${projectId}/databases/${database}/documents:listCollectionIds`,
{},
{ pageSize: limit },
)) as IDataObject;
// @ts-ignore
responseData = getAllResponse.collectionIds.map((o) => ({ name: o }));
if (returnAll) {
const getAllResponse = await googleApiRequestAllItems.call(
this,
'collectionIds',
'POST',
`/${projectId}/databases/${database}/documents:listCollectionIds`,
);
// @ts-ignore
responseData = getAllResponse.map((o) => ({ name: o }));
} else {
const limit = this.getNodeParameter('limit', i);
const getAllResponse = (await googleApiRequest.call(
this,
'POST',
`/${projectId}/databases/${database}/documents:listCollectionIds`,
{},
{ pageSize: limit },
)) as IDataObject;
// @ts-ignore
responseData = getAllResponse.collectionIds.map((o) => ({ name: o }));
}
const executionData = this.helpers.constructExecutionMetaData(
this.helpers.returnJsonArray(responseData as IDataObject[]),
{ itemData: fallbackPairedItems ?? [{ item: i }] },
);
returnData.push(...executionData);
} catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: { error: error.message },
pairedItem: fallbackPairedItems ?? [{ item: i }],
});
continue;
}
throw error;
}
}
const executionData = this.helpers.constructExecutionMetaData(
this.helpers.returnJsonArray(responseData as IDataObject[]),
{ itemData },
);
returnData.push(...executionData);
}
}