n8n-nodes-caldav-pro 1.0.0

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.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +313 -0
  3. package/dist/credentials/CalDavApi.credentials.d.ts +9 -0
  4. package/dist/credentials/CalDavApi.credentials.js +70 -0
  5. package/dist/credentials/CalDavApi.credentials.js.map +1 -0
  6. package/dist/nodes/CalDav/CalDav.node.d.ts +5 -0
  7. package/dist/nodes/CalDav/CalDav.node.js +96 -0
  8. package/dist/nodes/CalDav/CalDav.node.js.map +1 -0
  9. package/dist/nodes/CalDav/CalDavTool.node.d.ts +6 -0
  10. package/dist/nodes/CalDav/CalDavTool.node.js +155 -0
  11. package/dist/nodes/CalDav/CalDavTool.node.js.map +1 -0
  12. package/dist/nodes/CalDav/descriptions/SharedDescriptions.d.ts +11 -0
  13. package/dist/nodes/CalDav/descriptions/SharedDescriptions.js +232 -0
  14. package/dist/nodes/CalDav/descriptions/SharedDescriptions.js.map +1 -0
  15. package/dist/nodes/CalDav/helpers/CalDavClient.d.ts +40 -0
  16. package/dist/nodes/CalDav/helpers/CalDavClient.js +246 -0
  17. package/dist/nodes/CalDav/helpers/CalDavClient.js.map +1 -0
  18. package/dist/nodes/CalDav/helpers/ICal.d.ts +48 -0
  19. package/dist/nodes/CalDav/helpers/ICal.js +216 -0
  20. package/dist/nodes/CalDav/helpers/ICal.js.map +1 -0
  21. package/dist/nodes/CalDav/helpers/Operations.d.ts +14 -0
  22. package/dist/nodes/CalDav/helpers/Operations.js +425 -0
  23. package/dist/nodes/CalDav/helpers/Operations.js.map +1 -0
  24. package/dist/nodes/CalDav/helpers/Recurrence.d.ts +29 -0
  25. package/dist/nodes/CalDav/helpers/Recurrence.js +204 -0
  26. package/dist/nodes/CalDav/helpers/Recurrence.js.map +1 -0
  27. package/dist/nodes/CalDav/helpers/Timezone.d.ts +11 -0
  28. package/dist/nodes/CalDav/helpers/Timezone.js +142 -0
  29. package/dist/nodes/CalDav/helpers/Timezone.js.map +1 -0
  30. package/dist/nodes/CalDav/helpers/Utils.d.ts +17 -0
  31. package/dist/nodes/CalDav/helpers/Utils.js +129 -0
  32. package/dist/nodes/CalDav/helpers/Utils.js.map +1 -0
  33. package/dist/nodes/CalDav/icons/caldav.svg +10 -0
  34. package/dist/package.json +76 -0
  35. package/dist/tsconfig.tsbuildinfo +1 -0
  36. package/index.js +3 -0
  37. package/package.json +76 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 n8n Community
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,313 @@
1
+ # n8n-nodes-caldav-pro
2
+
3
+ [![npm](https://img.shields.io/badge/n8n-community%20node-FF6D5A.svg)](https://www.npmjs.com/) [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
+
5
+ Two n8n community nodes for working with any CalDAV calendar server:
6
+
7
+ - **CalDAV** – standard node for workflows (triggers, schedulers, HTTP, etc.).
8
+ - **CalDAV Tool** – AI-Agent tool variant with `$fromAI()` support, tolerant
9
+ parameter casing, and error-as-JSON default behaviour.
10
+
11
+ Tested against Infomaniak kMeet/Calendar, Nextcloud, Apple iCloud, Radicale,
12
+ Baikal, SOGo and generic RFC 4791 servers.
13
+
14
+ ---
15
+
16
+ ## Features
17
+
18
+ | Operation | Standard | AI Tool | Notes |
19
+ |------------------|:--------:|:-------:|-------|
20
+ | Get Events | ✅ | ✅ | Single date or date range. Recurring events are expanded. Empty result = empty array (never an error). |
21
+ | Create Event | ✅ | ✅ | VTIMEZONE, VALARM, RRULE. |
22
+ | Update Event | ✅ | ✅ | Partial update by UID (If-Match / ETag). |
23
+ | Delete Event | ✅ | ✅ | By UID. 404 = `deleted:false` (no throw). |
24
+ | Get Free/Busy | ✅ | ✅ | Free-busy REPORT with automatic fallback to calendar-query. |
25
+
26
+ Additional guarantees:
27
+
28
+ - **Timezones:** pulled from `this.getTimezone()`. VTIMEZONE is generated
29
+ dynamically with proper DAYLIGHT + STANDARD components and correct DST
30
+ rules for Europe, North America, Australia, New Zealand, Chile.
31
+ `DTSTART;TZID=Europe/Berlin:20260414T120000` – never UTC literals for
32
+ timed events.
33
+ - **RFC 5545 compliance:** CRLF line endings, line folding at 75 octets,
34
+ escape sequences in TEXT properties, UTC DTSTAMP/CREATED/LAST-MODIFIED.
35
+ - **Security:** UID sanitization (`/[^\w\-.@]/g → '_'`), path-traversal
36
+ guard, XML-safe response parsing, no credential or body logging.
37
+ - **AI-friendly:** every enum is a free-form string with allowed values in
38
+ the description, and parameters accept camelCase, snake_case, UPPER_CASE
39
+ and kebab-case interchangeably.
40
+
41
+ ---
42
+
43
+ ## Installation
44
+
45
+ ### From the n8n UI (self-hosted)
46
+
47
+ `Settings → Community Nodes → Install` and enter:
48
+
49
+ ```
50
+ n8n-nodes-caldav-pro
51
+ ```
52
+
53
+ ### From npm (CLI install)
54
+
55
+ ```bash
56
+ npm install n8n-nodes-caldav-pro
57
+ ```
58
+
59
+ In Docker:
60
+
61
+ ```bash
62
+ docker exec -u 0 -it n8n \
63
+ npm install -g n8n-nodes-caldav-pro
64
+ ```
65
+
66
+ The two nodes show up in the palette as **CalDAV** and **CalDAV Tool**.
67
+
68
+ ---
69
+
70
+ ## Credentials setup
71
+
72
+ The same credential type (`CalDAV API`) is used by both nodes.
73
+
74
+ | Field | Value |
75
+ |--------------|-------|
76
+ | Server URL | Full CalDAV collection URL (must end with `/`) |
77
+ | Username | Your account username |
78
+ | Password | Account or app-specific password |
79
+
80
+ The connection test runs a `PROPFIND` against the collection URL.
81
+
82
+ ### Infomaniak example
83
+
84
+ 1. Log into [Infomaniak mail.infomaniak.com](https://mail.infomaniak.com) and
85
+ open **Calendar → ⚙ Settings → Synchronize → CalDAV**.
86
+ 2. Copy the CalDAV URL. It looks like:
87
+
88
+ ```
89
+ https://caldav.infomaniak.com/calendar/<user-id>/<calendar-id>/
90
+ ```
91
+
92
+ 3. Under **Security settings → Application passwords**, create an
93
+ app password for n8n.
94
+ 4. In n8n create a new `CalDAV API` credential with:
95
+ - **Server URL:** paste the CalDAV URL above (keep the trailing `/`).
96
+ - **Username:** your Infomaniak login (email).
97
+ - **Password:** the app password.
98
+
99
+ ### Nextcloud
100
+
101
+ ```
102
+ https://cloud.example.com/remote.php/dav/calendars/<user>/<calendar-id>/
103
+ ```
104
+
105
+ Use an app-token rather than your main password (Settings → Security →
106
+ Devices & sessions).
107
+
108
+ ### Apple iCloud
109
+
110
+ ```
111
+ https://caldav.icloud.com/<principal-id>/calendars/<calendar-id>/
112
+ ```
113
+
114
+ Requires an **app-specific password**.
115
+
116
+ ### Radicale / Baikal / SOGo
117
+
118
+ Use the calendar collection URL that the server admin gave you.
119
+ Radicale default layout: `https://host/<user>/<calendar>/`.
120
+
121
+ ---
122
+
123
+ ## AI Agent setup (CalDAV Tool)
124
+
125
+ Drop the **CalDAV Tool** node into an **AI Agent** subtree. Nothing else is
126
+ required – every field can be supplied by the model via `$fromAI()`.
127
+
128
+ ### Suggested system prompt
129
+
130
+ ```
131
+ You are a scheduling assistant. You can use the "caldav" tool to read,
132
+ create, update and delete events on the user's calendar, and to check
133
+ free/busy for specific time windows.
134
+
135
+ Rules:
136
+ - All datetimes MUST be ISO-8601 with a timezone offset, e.g.
137
+ "2026-04-14T12:00:00+02:00". Never emit "Z" for local events.
138
+ - Before creating an event, call getFreeBusy for the requested window.
139
+ If the window is busy, propose the next free slot instead.
140
+ - For recurring events: set Recurring_Event to true and fill in
141
+ Recurrence_Frequency (DAILY/WEEKLY/MONTHLY/YEARLY), Recurrence_Interval,
142
+ Recurrence_End_Type (count/until/never), Recurrence_Count or
143
+ Recurrence_Until, and Recurrence_By_Day when relevant
144
+ (e.g. "MO,WE,FR").
145
+ - If the tool returns {success:false, error:...}, tell the user what went
146
+ wrong and ask for a correction; do not retry identical input.
147
+ - Today's date: {{$today}}. User timezone: {{$now.zoneName}}.
148
+ ```
149
+
150
+ ### End-to-end example: "Schedule a meeting with Jane next Tuesday 3pm"
151
+
152
+ 1. Agent calls `caldav` with:
153
+ ```json
154
+ {
155
+ "operation": "getFreeBusy",
156
+ "Start_Date": "2026-04-21T15:00:00+02:00",
157
+ "End_Date": "2026-04-21T16:00:00+02:00"
158
+ }
159
+ ```
160
+ Response: `{ success: true, isBusy: false, free: [...], busy: [] }`.
161
+
162
+ 2. Agent calls `caldav` with:
163
+ ```json
164
+ {
165
+ "operation": "createEvent",
166
+ "Event_Title": "Meeting with Jane",
167
+ "Start_Date_and_Time": "2026-04-21T15:00:00+02:00",
168
+ "End_Date_and_Time": "2026-04-21T16:00:00+02:00",
169
+ "Location": "Office",
170
+ "Reminder": 15
171
+ }
172
+ ```
173
+ Response:
174
+ ```json
175
+ {
176
+ "success": true,
177
+ "operation": "createEvent",
178
+ "uid": "c4b1c9de-...@n8n-caldav",
179
+ "etag": "\"f00\"",
180
+ "timezone": "Europe/Berlin",
181
+ "event": { ... }
182
+ }
183
+ ```
184
+
185
+ ---
186
+
187
+ ## Operations
188
+
189
+ ### Get Events
190
+
191
+ Inputs (all optional; at least one date must be resolvable):
192
+
193
+ | Field | Type | Description |
194
+ |--------------|--------|-------------|
195
+ | Date | string | Single day as `YYYY-MM-DD`. |
196
+ | Start Date | string | Range start (ISO-8601). |
197
+ | End Date | string | Range end (ISO-8601). |
198
+
199
+ Output (never throws on empty):
200
+
201
+ ```json
202
+ {
203
+ "success": true,
204
+ "operation": "getEvents",
205
+ "rangeStart": "2026-04-14T00:00:00.000Z",
206
+ "rangeEnd": "2026-04-15T00:00:00.000Z",
207
+ "count": 2,
208
+ "events": [
209
+ {
210
+ "uid": "...",
211
+ "summary": "Standup",
212
+ "start": "2026-04-14T07:00:00.000Z",
213
+ "end": "2026-04-14T07:15:00.000Z",
214
+ "allDay": false,
215
+ "recurring": true,
216
+ "rrule": "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR"
217
+ }
218
+ ]
219
+ }
220
+ ```
221
+
222
+ ### Create Event
223
+
224
+ | Field | Type | Notes |
225
+ |-----------------------|---------|-------|
226
+ | UID (optional) | string | Empty → UUID generated. |
227
+ | Event_Title | string | **required**. |
228
+ | Start_Date_and_Time | string | **required** – ISO-8601 with offset. |
229
+ | End_Date_and_Time | string | Default start + 1h. |
230
+ | Location | string | |
231
+ | Description | string | |
232
+ | All_Day_Event | boolean | If true, emits `DTSTART;VALUE=DATE:YYYYMMDD`. |
233
+ | Reminder | number | Minutes before start. 0 → no VALARM. |
234
+ | Recurring_Event | boolean | Enables RRULE. |
235
+ | Recurrence_Frequency | string | `DAILY` / `WEEKLY` / `MONTHLY` / `YEARLY`. |
236
+ | Recurrence_Interval | number | Default `1`. |
237
+ | Recurrence_End_Type | string | `count` / `until` / `never`. |
238
+ | Recurrence_Count | number | When `end_type=count`. |
239
+ | Recurrence_Until | string | When `end_type=until`. |
240
+ | Recurrence_By_Day | string | Comma-separated BYDAY tokens: `MO,TU,WE,TH,FR,SA,SU` (ordinals allowed: `2MO`, `-1FR`). |
241
+
242
+ ### Update Event
243
+
244
+ All fields optional except **UID**. Omitted fields keep their existing
245
+ values. Uses `If-Match` with the current ETag.
246
+
247
+ ### Delete Event
248
+
249
+ | Field | Type |
250
+ |-------|--------|
251
+ | UID | string (required) |
252
+
253
+ HTTP 404 → `deleted:false` (no error thrown).
254
+
255
+ ### Get Free/Busy
256
+
257
+ | Field | Type |
258
+ |--------------|--------|
259
+ | Start_Date | string (required) |
260
+ | End_Date | string (required) |
261
+
262
+ Output:
263
+
264
+ ```json
265
+ {
266
+ "success": true,
267
+ "operation": "getFreeBusy",
268
+ "method": "freebusy-query",
269
+ "rangeStart": "2026-04-14T08:00:00.000Z",
270
+ "rangeEnd": "2026-04-14T18:00:00.000Z",
271
+ "busy": [ { "start": "...", "end": "..." } ],
272
+ "free": [ { "start": "...", "end": "..." } ],
273
+ "isBusy": true
274
+ }
275
+ ```
276
+
277
+ ---
278
+
279
+ ## Error handling
280
+
281
+ Both nodes return structured JSON on failure (and on success):
282
+
283
+ ```json
284
+ {
285
+ "success": false,
286
+ "error": "CalDAV PUT failed: HTTP 412 Precondition Failed",
287
+ "operation": "updateEvent",
288
+ "timestamp": "2026-04-19T10:12:34.567Z"
289
+ }
290
+ ```
291
+
292
+ - **CalDAV Tool** defaults to `returnError` (the Agent never aborts on a
293
+ tool error). Switch to `throwError` to propagate the error.
294
+ - **CalDAV** throws by default. Enable "Continue On Fail" in the node
295
+ settings to get the JSON error payload instead.
296
+
297
+ ---
298
+
299
+ ## Development
300
+
301
+ ```bash
302
+ npm install
303
+ npm run build # tsc + gulp (icons)
304
+ npm run lint # eslint
305
+ npm test # jest (all suites)
306
+ npm run pack # builds + emits n8n-nodes-caldav-pro-1.0.0.tgz
307
+ ```
308
+
309
+ ---
310
+
311
+ ## License
312
+
313
+ MIT – see [LICENSE](LICENSE).
@@ -0,0 +1,9 @@
1
+ import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class CalDavApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ authenticate: IAuthenticateGeneric;
8
+ test: ICredentialTestRequest;
9
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CalDavApi = void 0;
4
+ class CalDavApi {
5
+ constructor() {
6
+ this.name = 'calDavApi';
7
+ this.displayName = 'CalDAV API';
8
+ this.documentationUrl = 'https://github.com/n8n-community/n8n-nodes-caldav-pro';
9
+ this.properties = [
10
+ {
11
+ displayName: 'Server URL',
12
+ name: 'serverUrl',
13
+ type: 'string',
14
+ default: '',
15
+ required: true,
16
+ placeholder: 'https://caldav.infomaniak.com/calendar/<user>/<calendar-id>/',
17
+ description: 'Full URL of the CalDAV calendar collection. Must end with a trailing slash. Examples:\n' +
18
+ '- Infomaniak: https://caldav.infomaniak.com/calendar/<user>/<calendar-id>/\n' +
19
+ '- Nextcloud: https://cloud.example.com/remote.php/dav/calendars/<user>/<calendar>/\n' +
20
+ '- iCloud: https://caldav.icloud.com/<principal-id>/calendars/<calendar>/\n' +
21
+ '- Radicale/Baikal/SOGo: use the calendar collection URL',
22
+ },
23
+ {
24
+ displayName: 'Username',
25
+ name: 'username',
26
+ type: 'string',
27
+ default: '',
28
+ required: true,
29
+ },
30
+ {
31
+ displayName: 'Password',
32
+ name: 'password',
33
+ type: 'string',
34
+ typeOptions: {
35
+ password: true,
36
+ },
37
+ default: '',
38
+ required: true,
39
+ description: 'Account password or app-specific password (recommended for Infomaniak / iCloud / Google).',
40
+ },
41
+ ];
42
+ this.authenticate = {
43
+ type: 'generic',
44
+ properties: {
45
+ auth: {
46
+ username: '={{ $credentials.username }}',
47
+ password: '={{ $credentials.password }}',
48
+ },
49
+ headers: {
50
+ 'User-Agent': 'n8n-nodes-caldav-pro/1.0.0',
51
+ },
52
+ },
53
+ };
54
+ this.test = {
55
+ request: {
56
+ baseURL: '={{ $credentials.serverUrl }}',
57
+ url: '',
58
+ method: 'PROPFIND',
59
+ headers: {
60
+ Depth: '0',
61
+ 'Content-Type': 'application/xml; charset=utf-8',
62
+ },
63
+ body: '<?xml version="1.0" encoding="utf-8" ?>' +
64
+ '<d:propfind xmlns:d="DAV:"><d:prop><d:resourcetype/><d:displayname/></d:prop></d:propfind>',
65
+ },
66
+ };
67
+ }
68
+ }
69
+ exports.CalDavApi = CalDavApi;
70
+ //# sourceMappingURL=CalDavApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalDavApi.credentials.js","sourceRoot":"","sources":["../../credentials/CalDavApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,SAAS;IAAtB;QACC,SAAI,GAAG,WAAW,CAAC;QACnB,gBAAW,GAAG,YAAY,CAAC;QAC3B,qBAAgB,GAAG,uDAAuD,CAAC;QAE3E,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,8DAA8D;gBAC3E,WAAW,EACV,yFAAyF;oBACzF,8EAA8E;oBAC9E,sFAAsF;oBACtF,4EAA4E;oBAC5E,yDAAyD;aAC1D;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;aACd;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACZ,QAAQ,EAAE,IAAI;iBACd;gBACD,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EACV,2FAA2F;aAC5F;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,IAAI,EAAE;oBACL,QAAQ,EAAE,8BAA8B;oBACxC,QAAQ,EAAE,8BAA8B;iBACxC;gBACD,OAAO,EAAE;oBACR,YAAY,EAAE,4BAA4B;iBAC1C;aACD;SACD,CAAC;QAKF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,+BAA+B;gBACxC,GAAG,EAAE,EAAE;gBACP,MAAM,EAAE,UAAyD;gBACjE,OAAO,EAAE;oBACR,KAAK,EAAE,GAAG;oBACV,cAAc,EAAE,gCAAgC;iBAChD;gBACD,IAAI,EACH,yCAAyC;oBACzC,4FAA4F;aAC7F;SACD,CAAC;IACH,CAAC;CAAA;AAvED,8BAuEC"}
@@ -0,0 +1,5 @@
1
+ import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class CalDav implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CalDav = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const Operations_1 = require("./helpers/Operations");
6
+ const Utils_1 = require("./helpers/Utils");
7
+ const SharedDescriptions_1 = require("./descriptions/SharedDescriptions");
8
+ class CalDav {
9
+ constructor() {
10
+ this.description = {
11
+ displayName: 'CalDAV',
12
+ name: 'caldav',
13
+ icon: 'file:icons/caldav.svg',
14
+ group: ['transform'],
15
+ version: 1,
16
+ subtitle: '={{$parameter["operation"]}}',
17
+ description: 'Read and write events on a CalDAV calendar (Infomaniak, Nextcloud, iCloud, Radicale, Baikal, SOGo).',
18
+ defaults: { name: 'CalDAV' },
19
+ inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
20
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
21
+ credentials: [{ name: 'calDavApi', required: true }],
22
+ properties: (0, SharedDescriptions_1.buildCalDavProperties)({ asTool: false }),
23
+ };
24
+ }
25
+ async execute() {
26
+ const items = this.getInputData();
27
+ const results = [];
28
+ const credentials = (await this.getCredentials('calDavApi'));
29
+ const tzid = this.getTimezone() || 'UTC';
30
+ for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
31
+ try {
32
+ const operation = this.getNodeParameter('operation', itemIndex);
33
+ const params = collectParams(this, itemIndex);
34
+ const normalized = (0, Utils_1.normalizeParams)(params);
35
+ const output = await (0, Operations_1.runOperation)(this, credentials, operation, normalized, tzid);
36
+ results.push({ json: output, pairedItem: { item: itemIndex } });
37
+ }
38
+ catch (error) {
39
+ const operation = (() => {
40
+ try {
41
+ return this.getNodeParameter('operation', itemIndex);
42
+ }
43
+ catch {
44
+ return 'unknown';
45
+ }
46
+ })();
47
+ if (this.continueOnFail()) {
48
+ results.push({
49
+ json: (0, Utils_1.buildErrorPayload)(error, operation),
50
+ pairedItem: { item: itemIndex },
51
+ });
52
+ continue;
53
+ }
54
+ if (error instanceof n8n_workflow_1.NodeOperationError)
55
+ throw error;
56
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, { itemIndex });
57
+ }
58
+ }
59
+ return [results];
60
+ }
61
+ }
62
+ exports.CalDav = CalDav;
63
+ function collectParams(ctx, itemIndex) {
64
+ const fields = [
65
+ 'date',
66
+ 'startDate',
67
+ 'endDate',
68
+ 'uid',
69
+ 'eventTitle',
70
+ 'startDateAndTime',
71
+ 'endDateAndTime',
72
+ 'location',
73
+ 'description',
74
+ 'allDayEvent',
75
+ 'reminder',
76
+ 'recurringEvent',
77
+ 'recurrenceFrequency',
78
+ 'recurrenceInterval',
79
+ 'recurrenceEndType',
80
+ 'recurrenceCount',
81
+ 'recurrenceUntil',
82
+ 'recurrenceByDay',
83
+ ];
84
+ const out = {};
85
+ for (const f of fields) {
86
+ try {
87
+ const v = ctx.getNodeParameter(f, itemIndex, undefined);
88
+ if (v !== undefined && v !== '')
89
+ out[f] = v;
90
+ }
91
+ catch {
92
+ }
93
+ }
94
+ return out;
95
+ }
96
+ //# sourceMappingURL=CalDav.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalDav.node.js","sourceRoot":"","sources":["../../../nodes/CalDav/CalDav.node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, ISupplyDataFunctions, SupplyData } from 'n8n-workflow';
2
+ export declare class CalDavTool implements INodeType {
3
+ description: INodeTypeDescription;
4
+ supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData>;
5
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
6
+ }