diff --git a/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/MicrosoftExcelSharePoint.node.json b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/MicrosoftExcelSharePoint.node.json new file mode 100644 index 00000000000..39a44e0e262 --- /dev/null +++ b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/MicrosoftExcelSharePoint.node.json @@ -0,0 +1,19 @@ +{ + "node": "n8n-nodes-base.microsoftExcelSharePoint", + "nodeVersion": "1.0", + "codexVersion": "1.0", + "categories": ["Data & Storage", "Productivity"], + "resources": { + "credentialDocumentation": [ + { + "url": "https://docs.n8n.io/integrations/builtin/credentials/microsoft/" + } + ], + "primaryDocumentation": [ + { + "url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.microsoftexcelsharepoint/" + } + ] + }, + "alias": ["_Excel", "Excel", "Sheet", "CSV", "Spreadsheet", "SharePoint"] +} diff --git a/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/MicrosoftExcelSharePoint.node.ts b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/MicrosoftExcelSharePoint.node.ts new file mode 100644 index 00000000000..7c1e5e80baf --- /dev/null +++ b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/MicrosoftExcelSharePoint.node.ts @@ -0,0 +1,32 @@ +import type { + IExecuteFunctions, + INodeExecutionData, + INodeType, + INodeTypeDescription, +} from 'n8n-workflow'; +import { NodeConnectionTypes } from 'n8n-workflow'; + +// Shell for the Excel-on-SharePoint build. Registered but hidden: workflows +// using it always work; the launch ticket removes the `hidden` flag. +export class MicrosoftExcelSharePoint implements INodeType { + description: INodeTypeDescription = { + displayName: 'Microsoft Excel (SharePoint)', + name: 'microsoftExcelSharePoint', + icon: 'file:excelSharePoint.svg', + group: ['transform'], + version: 1, + description: 'Read and write Excel workbooks stored in SharePoint document libraries', + defaults: { + name: 'Microsoft Excel (SharePoint)', + }, + inputs: [NodeConnectionTypes.Main], + outputs: [NodeConnectionTypes.Main], + hidden: true, + properties: [], + }; + + // Pass-through until the first action arrives with the router. + async execute(this: IExecuteFunctions): Promise { + return [this.getInputData()]; + } +} diff --git a/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/excelSharePoint.svg b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/excelSharePoint.svg new file mode 100644 index 00000000000..58629f15d64 --- /dev/null +++ b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/excelSharePoint.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/test/MicrosoftExcelSharePoint.node.test.ts b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/test/MicrosoftExcelSharePoint.node.test.ts new file mode 100644 index 00000000000..b9fbcebcd08 --- /dev/null +++ b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/test/MicrosoftExcelSharePoint.node.test.ts @@ -0,0 +1,42 @@ +import type { IExecuteFunctions } from 'n8n-workflow'; +import { mock } from 'vitest-mock-extended'; + +import { MicrosoftExcelSharePoint } from '../MicrosoftExcelSharePoint.node'; +import { MicrosoftExcel } from '../../Excel/MicrosoftExcel.node'; + +describe('MicrosoftExcelSharePoint (hidden shell)', () => { + const node = new MicrosoftExcelSharePoint(); + + it('should be hidden from the nodes panel', () => { + // `hidden` is the flag the editor's visibleNodeTypes filters on + expect(node.description.hidden).toBe(true); + }); + + it('should not collide with the OneDrive Excel node', () => { + // Node registration is last-write-wins — a name clash would silently + // shadow one node, so compare against the real sibling. + const oneDriveNode = new MicrosoftExcel(); + + expect(node.description.name).toBe('microsoftExcelSharePoint'); + expect(node.description.name).not.toBe(oneDriveNode.description.name); + expect(node.description.displayName).toBe('Microsoft Excel (SharePoint)'); + expect(node.description.displayName).not.toBe(oneDriveNode.description.displayName); + }); + + it('should be a blank shell — no credentials, no properties', () => { + expect(node.description.version).toBe(1); + expect(node.description.properties).toHaveLength(0); + expect(node.description.credentials).toBeUndefined(); + expect(node.description.usableAsTool).toBeUndefined(); + }); + + it('should pass input through unchanged when executed', async () => { + const ctx = mock(); + const items = [{ json: { a: 1 } }, { json: { b: 2 } }]; + ctx.getInputData.mockReturnValue(items); + + const result = await node.execute.call(ctx); + + expect(result).toEqual([items]); + }); +}); diff --git a/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/test/noop.test.ts b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/test/noop.test.ts new file mode 100644 index 00000000000..40f6d167164 --- /dev/null +++ b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/test/noop.test.ts @@ -0,0 +1,8 @@ +import { NodeTestHarness } from '@nodes-testing/node-test-harness'; + +// A pasted workflow using the hidden node must load and execute (as a pass-through) +describe('Microsoft Excel (SharePoint) Node', () => { + new NodeTestHarness().setupTests({ + workflowFiles: ['noop.workflow.json'], + }); +}); diff --git a/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/test/noop.workflow.json b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/test/noop.workflow.json new file mode 100644 index 00000000000..2befdee4ed8 --- /dev/null +++ b/packages/nodes-base/nodes/Microsoft/ExcelSharePoint/test/noop.workflow.json @@ -0,0 +1,40 @@ +{ + "nodes": [ + { + "parameters": {}, + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [0, 0], + "id": "8f4a1c22-6e1d-4a35-9c40-1af2f9f70301", + "name": "When clicking ‘Test workflow’" + }, + { + "parameters": {}, + "type": "n8n-nodes-base.microsoftExcelSharePoint", + "typeVersion": 1, + "position": [200, 0], + "id": "4c9be7de-51f2-4633-8b0a-2f4f3f1f9d02", + "name": "Microsoft Excel (SharePoint)" + } + ], + "connections": { + "When clicking ‘Test workflow’": { + "main": [ + [ + { + "node": "Microsoft Excel (SharePoint)", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "pinData": { + "Microsoft Excel (SharePoint)": [ + { + "json": {} + } + ] + } +} diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index f4ef46e0e3e..814fc8a641d 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -682,6 +682,7 @@ "dist/nodes/Microsoft/Dynamics/MicrosoftDynamicsCrm.node.js", "dist/nodes/Microsoft/Entra/MicrosoftEntra.node.js", "dist/nodes/Microsoft/Excel/MicrosoftExcel.node.js", + "dist/nodes/Microsoft/ExcelSharePoint/MicrosoftExcelSharePoint.node.js", "dist/nodes/Microsoft/GraphSecurity/MicrosoftGraphSecurity.node.js", "dist/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.js", "dist/nodes/Microsoft/OneDrive/MicrosoftOneDriveTrigger.node.js",