first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled

This commit is contained in:
2026-03-17 16:22:57 +03:30
commit 3d5eaf9445
15349 changed files with 2847338 additions and 0 deletions
@@ -0,0 +1,2 @@
export * as loadOptions from './loadOptions';
export * as listSearch from './listSearch';
@@ -0,0 +1,155 @@
import type {
IDataObject,
ILoadOptionsFunctions,
INodeListSearchItems,
INodeListSearchResult,
} from 'n8n-workflow';
import { microsoftApiRequest } from '../transport';
export async function searchWorkbooks(
this: ILoadOptionsFunctions,
filter?: string,
paginationToken?: string,
): Promise<INodeListSearchResult> {
const fileExtensions = ['.xlsx', '.xlsm', '.xlst'];
const extensionFilter = fileExtensions.join(' OR ');
const q = filter || extensionFilter;
let response: IDataObject = {};
if (paginationToken) {
response = await microsoftApiRequest.call(
this,
'GET',
'',
undefined,
undefined,
paginationToken, // paginationToken contains the full URL
);
} else {
response = await microsoftApiRequest.call(
this,
'GET',
`/drive/root/search(q='${q}')`,
undefined,
{
select: 'id,name,webUrl',
$top: 100,
},
);
}
if (response.value && filter) {
response.value = (response.value as IDataObject[]).filter((workbook: IDataObject) => {
return fileExtensions.some((extension) => (workbook.name as string).includes(extension));
});
}
return {
results: (response.value as IDataObject[]).map((workbook: IDataObject) => {
for (const extension of fileExtensions) {
if ((workbook.name as string).includes(extension)) {
workbook.name = (workbook.name as string).replace(extension, '');
break;
}
}
return {
name: workbook.name as string,
value: workbook.id as string,
url: workbook.webUrl as string,
};
}),
paginationToken: response['@odata.nextLink'],
};
}
export async function getWorksheetsList(
this: ILoadOptionsFunctions,
): Promise<INodeListSearchResult> {
const workbookRLC = this.getNodeParameter('workbook') as IDataObject;
const workbookId = workbookRLC.value as string;
let workbookURL = (workbookRLC.cachedResultUrl as string) ?? '';
if (workbookURL.includes('1drv.ms')) {
workbookURL = `https://onedrive.live.com/edit.aspx?resid=${workbookId}`;
}
let response: IDataObject = {};
response = await microsoftApiRequest.call(
this,
'GET',
`/drive/items/${workbookId}/workbook/worksheets`,
undefined,
{
select: 'id,name',
},
);
return {
results: (response.value as IDataObject[]).map((worksheet: IDataObject) => ({
name: worksheet.name as string,
value: worksheet.id as string,
url: workbookURL
? `${workbookURL}&activeCell=${encodeURIComponent(worksheet.name as string)}!A1`
: undefined,
})),
};
}
export async function getWorksheetTables(
this: ILoadOptionsFunctions,
): Promise<INodeListSearchResult> {
const workbookRLC = this.getNodeParameter('workbook') as IDataObject;
const workbookId = workbookRLC.value as string;
let workbookURL = (workbookRLC.cachedResultUrl as string) ?? '';
if (workbookURL.includes('1drv.ms')) {
workbookURL = `https://onedrive.live.com/edit.aspx?resid=${workbookId}`;
}
const worksheetId = this.getNodeParameter('worksheet', undefined, {
extractValue: true,
}) as string;
let response: IDataObject = {};
response = await microsoftApiRequest.call(
this,
'GET',
`/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables`,
undefined,
);
const results: INodeListSearchItems[] = [];
for (const table of response.value as IDataObject[]) {
const name = table.name as string;
const value = table.id as string;
const { address } = await microsoftApiRequest.call(
this,
'GET',
`/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${value}/range`,
undefined,
{
select: 'address',
},
);
const [sheetName, sheetRange] = address.split('!' as string);
let url;
if (workbookURL) {
url = `${workbookURL}&activeCell=${encodeURIComponent(sheetName as string)}${
sheetRange ? '!' + (sheetRange as string) : ''
}`;
}
results.push({ name, value, url });
}
return { results };
}
@@ -0,0 +1,88 @@
import type { IDataObject, ILoadOptionsFunctions, INodePropertyOptions } from 'n8n-workflow';
import { microsoftApiRequest } from '../transport';
import { parseAddress } from '../helpers/utils';
export async function getWorksheetColumnRow(
this: ILoadOptionsFunctions,
): Promise<INodePropertyOptions[]> {
const workbookId = this.getNodeParameter('workbook', undefined, {
extractValue: true,
}) as string;
const worksheetId = this.getNodeParameter('worksheet', undefined, {
extractValue: true,
}) as string;
let range = this.getNodeParameter('range', '') as string;
let columns: string[] = [];
if (range === '') {
const worksheetData = await microsoftApiRequest.call(
this,
'GET',
`/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/usedRange`,
undefined,
{ select: 'values' },
);
columns = worksheetData.values[0] as string[];
} else {
const { cellFrom, cellTo } = parseAddress(range);
range = `${cellFrom.value}:${cellTo.column}${cellFrom.row}`;
const worksheetData = await microsoftApiRequest.call(
this,
'PATCH',
`/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/range(address='${range}')`,
{ select: 'values' },
);
columns = worksheetData.values[0] as string[];
}
const returnData: INodePropertyOptions[] = [];
for (const column of columns) {
returnData.push({
name: column,
value: column,
});
}
return returnData;
}
export async function getWorksheetColumnRowSkipColumnToMatchOn(
this: ILoadOptionsFunctions,
): Promise<INodePropertyOptions[]> {
const returnData = await getWorksheetColumnRow.call(this);
const columnToMatchOn = this.getNodeParameter('columnToMatchOn', 0) as string;
return returnData.filter((column) => column.value !== columnToMatchOn);
}
export async function getTableColumns(
this: ILoadOptionsFunctions,
): Promise<INodePropertyOptions[]> {
const workbookId = this.getNodeParameter('workbook', undefined, {
extractValue: true,
}) as string;
const worksheetId = this.getNodeParameter('worksheet', undefined, {
extractValue: true,
}) as string;
const tableId = this.getNodeParameter('table', undefined, {
extractValue: true,
}) as string;
const response = await microsoftApiRequest.call(
this,
'GET',
`/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/tables/${tableId}/columns`,
{},
);
return (response.value as IDataObject[]).map((column) => ({
name: column.name as string,
value: column.name as string,
}));
}