@aiteza/n8n-nodes-aiteza 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ import type { IDataObject, IExecuteFunctions, IHttpRequestMethods, IHttpRequestOptions, ILoadOptionsFunctions, INodePropertyOptions } from 'n8n-workflow';
2
+ export declare function aitezaApiRequest(this: IExecuteFunctions | ILoadOptionsFunctions, method: IHttpRequestMethods, endpoint: string, body?: IDataObject | IDataObject[], qs?: IDataObject, extraOpts?: Partial<IHttpRequestOptions>): Promise<any>;
3
+ export declare function aitezaApiRequestFullResponse(this: IExecuteFunctions, method: IHttpRequestMethods, endpoint: string, body?: IDataObject, qs?: IDataObject, extraOpts?: Partial<IHttpRequestOptions>): Promise<{
4
+ body: any;
5
+ headers: Record<string, string>;
6
+ }>;
7
+ export declare function loadDatarooms(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
8
+ /** Same as loadDatarooms but with a leading "None" option for optional fields. */
9
+ export declare function loadDataroomsOptional(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
10
+ export declare function loadModels(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
11
+ export declare function loadChats(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
12
+ export declare function loadFilesInDataroom(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
13
+ export declare function loadImagesInDataroom(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
14
+ export declare function loadWebSourcesInDataroom(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
15
+ export declare function loadStandaloneFiles(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
16
+ export declare function loadStandaloneImages(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
17
+ export declare function validateRequiredField(ef: IExecuteFunctions, value: unknown, fieldName: string): void;
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.aitezaApiRequest = aitezaApiRequest;
4
+ exports.aitezaApiRequestFullResponse = aitezaApiRequestFullResponse;
5
+ exports.loadDatarooms = loadDatarooms;
6
+ exports.loadDataroomsOptional = loadDataroomsOptional;
7
+ exports.loadModels = loadModels;
8
+ exports.loadChats = loadChats;
9
+ exports.loadFilesInDataroom = loadFilesInDataroom;
10
+ exports.loadImagesInDataroom = loadImagesInDataroom;
11
+ exports.loadWebSourcesInDataroom = loadWebSourcesInDataroom;
12
+ exports.loadStandaloneFiles = loadStandaloneFiles;
13
+ exports.loadStandaloneImages = loadStandaloneImages;
14
+ exports.validateRequiredField = validateRequiredField;
15
+ const n8n_workflow_1 = require("n8n-workflow");
16
+ // ---------------------------------------------------------------------------
17
+ // Generic authenticated request helper
18
+ // ---------------------------------------------------------------------------
19
+ async function aitezaApiRequest(method, endpoint, body = {}, qs = {}, extraOpts = {}) {
20
+ const credentials = await this.getCredentials('aitezaOAuth2Api');
21
+ const baseUrl = credentials.baseUrl.replace(/\/+$/, '');
22
+ const options = {
23
+ method,
24
+ url: `${baseUrl}${endpoint}`,
25
+ json: true,
26
+ ...extraOpts,
27
+ };
28
+ // Only set qs when there are actual query-string values.
29
+ // Setting qs: {} can cause n8n to strip query params already in the URL.
30
+ if (Object.keys(qs).length > 0) {
31
+ options.qs = qs;
32
+ }
33
+ if (method !== 'GET' && method !== 'DELETE') {
34
+ options.body = body;
35
+ }
36
+ else if (method === 'DELETE' && Object.keys(body).length > 0) {
37
+ // Some AITEZA DELETE endpoints accept a body
38
+ options.body = body;
39
+ }
40
+ try {
41
+ return await this.helpers.httpRequestWithAuthentication.call(this, 'aitezaOAuth2Api', options);
42
+ }
43
+ catch (error) {
44
+ const statusCode = error?.statusCode ?? error?.httpCode ?? error?.response?.status;
45
+ let message = error.message ?? 'Unknown error';
46
+ if (statusCode === 401) {
47
+ message = 'OAuth2 token expired or invalid – check your AITEZA credentials';
48
+ }
49
+ else if (statusCode === 403) {
50
+ message = 'Insufficient permissions for this resource';
51
+ }
52
+ else if (statusCode === 404) {
53
+ message = 'Resource not found';
54
+ }
55
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error, { message });
56
+ }
57
+ }
58
+ // ---------------------------------------------------------------------------
59
+ // Full-response variant (gives access to response headers, e.g. X-Chat-Id)
60
+ // ---------------------------------------------------------------------------
61
+ async function aitezaApiRequestFullResponse(method, endpoint, body = {}, qs = {}, extraOpts = {}) {
62
+ const credentials = await this.getCredentials('aitezaOAuth2Api');
63
+ const baseUrl = credentials.baseUrl.replace(/\/+$/, '');
64
+ const options = {
65
+ method,
66
+ url: `${baseUrl}${endpoint}`,
67
+ qs,
68
+ json: true,
69
+ returnFullResponse: true,
70
+ ...extraOpts,
71
+ };
72
+ if (method !== 'GET') {
73
+ options.body = body;
74
+ }
75
+ try {
76
+ return (await this.helpers.httpRequestWithAuthentication.call(this, 'aitezaOAuth2Api', options));
77
+ }
78
+ catch (error) {
79
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
80
+ }
81
+ }
82
+ // ---------------------------------------------------------------------------
83
+ // loadOptions helpers
84
+ // ---------------------------------------------------------------------------
85
+ async function loadDatarooms() {
86
+ try {
87
+ // Embed query params directly in the URL because empty-string qs values
88
+ // are silently stripped by n8n's HTTP library.
89
+ const data = await aitezaApiRequest.call(this, 'GET', '/api/dataroom/search?name=&sortBy=recentlyUsed');
90
+ const items = Array.isArray(data) ? data : data?.content ?? [];
91
+ if (items.length === 0) {
92
+ return [{ name: '(No datarooms found)', value: '' }];
93
+ }
94
+ return items.map((d) => ({
95
+ name: d.name ?? d.id,
96
+ value: d.id,
97
+ }));
98
+ }
99
+ catch (error) {
100
+ return [{ name: `Error loading datarooms: ${error.message ?? 'unknown'}`, value: '' }];
101
+ }
102
+ }
103
+ /** Same as loadDatarooms but with a leading "None" option for optional fields. */
104
+ async function loadDataroomsOptional() {
105
+ const options = await loadDatarooms.call(this);
106
+ return [{ name: '— None —', value: '' }, ...options];
107
+ }
108
+ async function loadModels() {
109
+ const data = await aitezaApiRequest.call(this, 'GET', '/api/models');
110
+ const items = Array.isArray(data) ? data : [];
111
+ return items.map((m) => ({
112
+ name: m.name ?? m.id,
113
+ value: m.id,
114
+ }));
115
+ }
116
+ async function loadChats() {
117
+ const data = await aitezaApiRequest.call(this, 'GET', '/api/chat', {}, { size: 100 });
118
+ const items = Array.isArray(data) ? data : data?.content ?? [];
119
+ return items.map((c) => ({
120
+ name: c.name ?? c.id,
121
+ value: c.id,
122
+ }));
123
+ }
124
+ async function loadFilesInDataroom() {
125
+ const dataroomId = this.getCurrentNodeParameter('dataroomId');
126
+ if (!dataroomId)
127
+ return [];
128
+ const data = await aitezaApiRequest.call(this, 'GET', `/api/dataroom/${dataroomId}/files`, {}, { size: 100 });
129
+ const items = Array.isArray(data) ? data : data?.content ?? [];
130
+ return items.map((f) => ({
131
+ name: f.name ?? f.id,
132
+ value: f.id,
133
+ }));
134
+ }
135
+ async function loadImagesInDataroom() {
136
+ const dataroomId = this.getCurrentNodeParameter('dataroomId');
137
+ if (!dataroomId)
138
+ return [];
139
+ const data = await aitezaApiRequest.call(this, 'GET', `/api/dataroom/${dataroomId}/images`, {}, { size: 100 });
140
+ const items = Array.isArray(data) ? data : data?.content ?? [];
141
+ return items.map((img) => ({
142
+ name: img.name ?? img.id,
143
+ value: img.id,
144
+ }));
145
+ }
146
+ async function loadWebSourcesInDataroom() {
147
+ const dataroomId = this.getCurrentNodeParameter('dataroomId');
148
+ if (!dataroomId)
149
+ return [];
150
+ const data = await aitezaApiRequest.call(this, 'GET', `/api/dataroom/${dataroomId}/websites`, {}, { size: 100 });
151
+ const items = Array.isArray(data) ? data : data?.content ?? [];
152
+ return items.map((ws) => ({
153
+ name: (ws.name || ws.url) ?? ws.id,
154
+ value: ws.id,
155
+ }));
156
+ }
157
+ async function loadStandaloneFiles() {
158
+ const data = await aitezaApiRequest.call(this, 'GET', '/api/files', {}, { size: 100 });
159
+ const items = Array.isArray(data) ? data : data?.content ?? [];
160
+ return items.map((f) => ({
161
+ name: f.name ?? f.id,
162
+ value: f.id,
163
+ }));
164
+ }
165
+ async function loadStandaloneImages() {
166
+ const data = await aitezaApiRequest.call(this, 'GET', '/api/images', {}, { size: 100 });
167
+ const items = Array.isArray(data) ? data : data?.content ?? [];
168
+ return items.map((img) => ({
169
+ name: img.name ?? img.id,
170
+ value: img.id,
171
+ }));
172
+ }
173
+ // ---------------------------------------------------------------------------
174
+ // Validation helpers
175
+ // ---------------------------------------------------------------------------
176
+ function validateRequiredField(ef, value, fieldName) {
177
+ if (value === undefined || value === null || value === '') {
178
+ throw new n8n_workflow_1.NodeOperationError(ef.getNode(), `"${fieldName}" is required but was not provided`);
179
+ }
180
+ }
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Ebene_2" data-name="Ebene 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 114.46 100.31">
3
+ <defs>
4
+ <style>
5
+ .cls-1 {
6
+ fill: #0769b3;
7
+ }
8
+ </style>
9
+ </defs>
10
+ <g id="Ebene_1-2" data-name="Ebene 1">
11
+ <path class="cls-1" d="M113.88,52.37l-16.51,28.61h-16.2c-1.19,0-2.34-.49-3.17-1.34l-9.48-9.73c.45-1.28.71-2.64.71-4.06,0-6.62-5.37-11.98-11.98-11.98s-11.98,5.37-11.98,11.98,5.37,11.99,11.98,11.99c1.65,0,3.22-.33,4.65-.93l12.04,12.37c.83.85,1.98,1.33,3.17,1.33h14.71l-4.34,7.51c-.8,1.36-2.25,2.21-3.83,2.21H30.82c-1.58,0-3.03-.85-3.83-2.21L.59,52.37c-.78-1.36-.78-3.06,0-4.42l16.17-28h15.99c1.19,0,2.34.48,3.17,1.34l10.07,10.34c-.45,1.26-.71,2.63-.71,4.05,0,6.62,5.37,11.98,11.99,11.98s11.98-5.37,11.98-11.98-5.37-11.99-11.98-11.99c-1.65,0-3.23.33-4.66.93l-12.65-12.97c-.82-.86-1.97-1.34-3.16-1.34h-14.51l4.68-8.1c.8-1.36,2.25-2.21,3.83-2.21h52.82c1.58,0,3.03.85,3.83,2.21l26.41,45.74c.78,1.36.78,3.06,0,4.42Z"/>
12
+ </g>
13
+ </svg>
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@aiteza/n8n-nodes-aiteza",
3
+ "version": "0.1.1",
4
+ "description": "n8n Community Node for the AITEZA REST API (Datarooms, Files, Chat, Search, Workflows)",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "n8n",
8
+ "aiteza",
9
+ "ai",
10
+ "dataroom",
11
+ "chat"
12
+ ],
13
+ "license": "MIT",
14
+ "homepage": "",
15
+ "author": {
16
+ "name": "AITEZA"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": ""
21
+ },
22
+ "engines": {
23
+ "node": ">=18.10",
24
+ "pnpm": ">=9.1"
25
+ },
26
+ "main": "index.js",
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "n8n": {
31
+ "n8nNodesApiVersion": 1,
32
+ "credentials": [
33
+ "dist/credentials/AitezaOAuth2Api.credentials.js"
34
+ ],
35
+ "nodes": [
36
+ "dist/nodes/Aiteza/Aiteza.node.js"
37
+ ]
38
+ },
39
+ "devDependencies": {
40
+ "@typescript-eslint/parser": "~7.18.0",
41
+ "eslint": "~8.57.0",
42
+ "gulp": "^4.0.2",
43
+ "n8n-workflow": "*",
44
+ "prettier": "~3.3.2",
45
+ "typescript": "~5.5.3"
46
+ },
47
+ "peerDependencies": {
48
+ "n8n-workflow": "*"
49
+ },
50
+ "scripts": {
51
+ "preinstall": "npx only-allow pnpm",
52
+ "build": "tsc && gulp build:icons",
53
+ "dev": "tsc --watch",
54
+ "format": "prettier nodes credentials --write",
55
+ "lint": "eslint nodes credentials --ext .ts",
56
+ "lintfix": "eslint nodes credentials --ext .ts --fix"
57
+ }
58
+ }