Worked on pagination function

This commit is contained in:
Adina Totorean 2024-11-28 21:07:25 +02:00
parent f09091a0cb
commit e4088ca9a8
3 changed files with 24 additions and 127 deletions

View file

@ -116,45 +116,8 @@ export async function processAttributes(
return requestOptions; return requestOptions;
} }
/* Helper function to process Group/User Response */
export async function processGroupsResponse(
this: IExecuteSingleFunctions,
items: INodeExecutionData[],
response: IN8nHttpFullResponse,
): Promise<INodeExecutionData[]> {
const responseBody = response.body as { Groups: IDataObject[] };
if (!responseBody || !Array.isArray(responseBody.Groups)) {
throw new ApplicationError('Unexpected response format: No groups found.');
}
const executionData: INodeExecutionData[] = responseBody.Groups.map((group) => ({
json: group,
}));
return executionData;
}
export async function processUsersResponse(
this: IExecuteSingleFunctions,
items: INodeExecutionData[],
response: IN8nHttpFullResponse,
): Promise<INodeExecutionData[]> {
const responseBody = response.body as { Users: IDataObject[] };
if (!responseBody || !Array.isArray(responseBody.Users)) {
throw new ApplicationError('Unexpected response format: No users found.');
}
const executionData: INodeExecutionData[] = responseBody.Users.map((user) => ({
json: user,
}));
return executionData;
}
/* Helper function to handle pagination */ /* Helper function to handle pagination */
const possibleRootProperties = ['Attributes']; const possibleRootProperties = ['Users', 'Groups'];
// ToDo: Test if pagination works // ToDo: Test if pagination works
export async function handlePagination( export async function handlePagination(
this: IExecutePaginationFunctions, this: IExecutePaginationFunctions,
@ -163,9 +126,7 @@ export async function handlePagination(
const aggregatedResult: IDataObject[] = []; const aggregatedResult: IDataObject[] = [];
let nextPageToken: string | undefined; let nextPageToken: string | undefined;
const returnAll = this.getNodeParameter('returnAll') as boolean; const returnAll = this.getNodeParameter('returnAll') as boolean;
let limit = 60; let limit = 100;
// Update limit if 'returnAll' is not selected
if (!returnAll) { if (!returnAll) {
limit = this.getNodeParameter('limit') as number; limit = this.getNodeParameter('limit') as number;
resultOptions.maxResults = limit; resultOptions.maxResults = limit;
@ -173,49 +134,32 @@ export async function handlePagination(
resultOptions.paginate = true; resultOptions.paginate = true;
do { do {
console.log('----> TOKEN', nextPageToken);
if (nextPageToken) { if (nextPageToken) {
// Append PaginationToken to the request body resultOptions.options.qs = { ...resultOptions.options.qs, PaginationToken: nextPageToken };
const body = console.log('----> GOT HERE');
typeof resultOptions.options.body === 'object' && resultOptions.options.body !== null
? resultOptions.options.body
: {};
resultOptions.options.body = {
...body,
PaginationToken: nextPageToken,
} as IDataObject;
console.log('Updated request body with PaginationToken:', resultOptions.options.body);
} }
// Make the request
console.log('Sending request with options:', resultOptions);
const responseData = await this.makeRoutingRequest(resultOptions); const responseData = await this.makeRoutingRequest(resultOptions);
// Process response data
for (const page of responseData) { for (const page of responseData) {
console.log('Processing page:', page.json);
// Iterate over possible root properties (e.g., "Users")
for (const prop of possibleRootProperties) { for (const prop of possibleRootProperties) {
if (page.json[prop]) { if (page.json[prop]) {
const currentData = page.json[prop] as IDataObject[]; const currentData = page.json[prop] as IDataObject[];
console.log(`Extracted data from property "${prop}":`, currentData);
aggregatedResult.push(...currentData); aggregatedResult.push(...currentData);
} }
} }
// Check if the limit has been reached
if (!returnAll && aggregatedResult.length >= limit) { if (!returnAll && aggregatedResult.length >= limit) {
console.log('Limit reached. Returning results.');
return aggregatedResult.slice(0, limit).map((item) => ({ json: item })); return aggregatedResult.slice(0, limit).map((item) => ({ json: item }));
} }
// Update the nextPageToken for the next request
nextPageToken = page.json.PaginationToken as string | undefined; nextPageToken = page.json.PaginationToken as string | undefined;
console.log('Next Page Token:', nextPageToken);
} }
} while (nextPageToken); } while (nextPageToken);
console.log('----> Array with results', aggregatedResult);
console.log('Final Aggregated Results:', aggregatedResult);
return aggregatedResult.map((item) => ({ json: item })); return aggregatedResult.map((item) => ({ json: item }));
} }

View file

@ -1,7 +1,7 @@
import type { IExecuteSingleFunctions, IHttpRequestOptions, INodeProperties } from 'n8n-workflow'; import type { IExecuteSingleFunctions, IHttpRequestOptions, INodeProperties } from 'n8n-workflow';
import { NodeOperationError } from 'n8n-workflow'; import { NodeOperationError } from 'n8n-workflow';
import { handleErrorPostReceive, processGroupsResponse } from '../GenericFunctions'; import { handleErrorPostReceive, handlePagination } from '../GenericFunctions';
export const groupOperations: INodeProperties[] = [ export const groupOperations: INodeProperties[] = [
{ {
@ -83,9 +83,8 @@ export const groupOperations: INodeProperties[] = [
value: 'getAll', value: 'getAll',
description: 'Retrieve a list of groups', description: 'Retrieve a list of groups',
routing: { routing: {
send: { send: { paginate: true },
paginate: true, operations: { pagination: handlePagination },
},
request: { request: {
method: 'POST', method: 'POST',
headers: { headers: {
@ -98,7 +97,7 @@ export const groupOperations: INodeProperties[] = [
ignoreHttpStatusErrors: true, ignoreHttpStatusErrors: true,
}, },
output: { output: {
postReceive: [handleErrorPostReceive, processGroupsResponse], postReceive: [handleErrorPostReceive],
}, },
}, },
action: 'Get many groups', action: 'Get many groups',
@ -580,38 +579,20 @@ const getAllFields: INodeProperties[] = [
name: 'returnAll', name: 'returnAll',
default: false, default: false,
description: 'Whether to return all results or only up to a given limit', description: 'Whether to return all results or only up to a given limit',
displayOptions: { displayOptions: { show: { resource: ['group'], operation: ['getAll'] } },
show: {
resource: ['group'],
operation: ['getAll'],
},
},
type: 'boolean', type: 'boolean',
}, },
{ {
displayName: 'Limit', displayName: 'Limit',
name: 'limit', name: 'limit',
default: 50, required: true,
description: 'Max number of results to return',
displayOptions: {
show: {
resource: ['group'],
operation: ['getAll'],
returnAll: [false],
},
},
routing: {
send: {
property: '$top',
type: 'query',
value: '={{ $value }}',
},
},
type: 'number', type: 'number',
typeOptions: { typeOptions: {
minValue: 1, minValue: 1,
}, },
validateType: 'number', default: 20,
description: 'Max number of results to return',
displayOptions: { show: { resource: ['group'], operation: ['getAll'], returnAll: [false] } },
}, },
{ {
displayName: 'User Pool ID', displayName: 'User Pool ID',

View file

@ -5,7 +5,6 @@ import {
handlePagination, handlePagination,
presendFilter, presendFilter,
processAttributes, processAttributes,
processUsersResponse,
} from '../GenericFunctions'; } from '../GenericFunctions';
export const userOperations: INodeProperties[] = [ export const userOperations: INodeProperties[] = [
@ -106,9 +105,8 @@ export const userOperations: INodeProperties[] = [
value: 'getAll', value: 'getAll',
description: 'Retrieve a list of users', description: 'Retrieve a list of users',
routing: { routing: {
send: { send: { paginate: true },
paginate: true, operations: { pagination: handlePagination },
},
request: { request: {
method: 'POST', method: 'POST',
headers: { headers: {
@ -121,7 +119,7 @@ export const userOperations: INodeProperties[] = [
ignoreHttpStatusErrors: true, ignoreHttpStatusErrors: true,
}, },
output: { output: {
postReceive: [handleErrorPostReceive, processUsersResponse], postReceive: [handleErrorPostReceive],
}, },
}, },
action: 'Get many users', action: 'Get many users',
@ -627,46 +625,20 @@ const getAllFields: INodeProperties[] = [
name: 'returnAll', name: 'returnAll',
default: false, default: false,
description: 'Whether to return all results or only up to a given limit', description: 'Whether to return all results or only up to a given limit',
displayOptions: { displayOptions: { show: { resource: ['user'], operation: ['getAll'] } },
show: {
resource: ['user'],
operation: ['getAll'],
},
},
routing: {
send: {
paginate: '={{ $value }}',
},
operations: {
pagination: handlePagination,
},
},
type: 'boolean', type: 'boolean',
}, },
{ {
displayName: 'Limit', displayName: 'Limit',
name: 'limit', name: 'limit',
default: 50, required: true,
description: 'Max number of results to return',
displayOptions: {
show: {
resource: ['user'],
operation: ['getAll'],
returnAll: [false],
},
},
routing: {
send: {
property: 'limit',
type: 'body',
value: '={{ $value }}',
},
},
type: 'number', type: 'number',
typeOptions: { typeOptions: {
minValue: 1, minValue: 1,
}, },
validateType: 'number', default: 20,
description: 'Max number of results to return',
displayOptions: { show: { resource: ['user'], operation: ['getAll'], returnAll: [false] } },
}, },
{ {
displayName: 'Additional Fields', // ToDo: Test additional parameters with the API displayName: 'Additional Fields', // ToDo: Test additional parameters with the API