n8n-nodes-caldav-pro 2.5.2 → 3.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.
- package/CHANGELOG.md +238 -0
- package/LICENSE +21 -0
- package/README.md +69 -26
- package/dist/credentials/CalDavApi.credentials.js +8 -0
- package/dist/credentials/CalDavApi.credentials.js.map +1 -1
- package/dist/nodes/CalDav/CalDav.node.js +208 -54
- package/dist/nodes/CalDav/CalDav.node.js.map +1 -1
- package/dist/nodes/CalDav/EventDescription.js +104 -13
- package/dist/nodes/CalDav/EventDescription.js.map +1 -1
- package/dist/nodes/CalDav/GenericFunctions.d.ts +26 -1
- package/dist/nodes/CalDav/GenericFunctions.js +504 -107
- package/dist/nodes/CalDav/GenericFunctions.js.map +1 -1
- package/package.json +16 -12
- package/dist/tsconfig.tsbuildinfo +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project
|
|
5
|
+
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [3.0.0]
|
|
8
|
+
|
|
9
|
+
The first release since 2.6.1. Versions 2.7.0 through 2.11.0 were developed but
|
|
10
|
+
never published; their entries are kept below for traceability. If you are
|
|
11
|
+
upgrading from 2.6.x, this section is what matters.
|
|
12
|
+
|
|
13
|
+
### BREAKING CHANGES
|
|
14
|
+
|
|
15
|
+
1. **`start` and `end` changed format.** Timed events previously reported a
|
|
16
|
+
local wall clock with no offset (`2026-04-20T14:00:00`), which downstream
|
|
17
|
+
nodes re-read in the n8n host's timezone. They are now explicit UTC instants
|
|
18
|
+
(`2026-04-20T12:00:00.000Z`); all-day events report a bare date
|
|
19
|
+
(`2026-04-20`). Both sort correctly as strings. Any expression that compares,
|
|
20
|
+
slices, or parses these values needs review.
|
|
21
|
+
|
|
22
|
+
2. **`raw` is no longer returned by default.** Read operations have a
|
|
23
|
+
**Simplify** toggle, on by default, which omits the full `VCALENDAR` source.
|
|
24
|
+
Turn it off where you depend on `raw`.
|
|
25
|
+
|
|
26
|
+
3. **Update no longer creates a missing event.** It reads the stored object
|
|
27
|
+
first in order to preserve fields you did not supply, so a missing event is
|
|
28
|
+
now an error instead of a silent create. Use Create for that.
|
|
29
|
+
|
|
30
|
+
4. **Events are written at different times than before — this is the fix, but
|
|
31
|
+
it will move existing workflows.** With **Timezone** set, 2.6.x emitted the
|
|
32
|
+
n8n host's wall clock under the requested `TZID`, shifting every event by the
|
|
33
|
+
host's UTC offset (two hours on a UTC host writing `Europe/Berlin`). All-day
|
|
34
|
+
events were written one calendar day early. If you compensated for either by
|
|
35
|
+
pre-shifting your input, remove that workaround or events will now be wrong
|
|
36
|
+
in the other direction.
|
|
37
|
+
|
|
38
|
+
5. **All-day `DTEND` is now the exclusive end RFC 5545 requires.** A same-day
|
|
39
|
+
or end-of-day range used to encode a zero-length event; it now produces a
|
|
40
|
+
one-day event.
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- Recurring series are expanded into the occurrences inside the queried window,
|
|
45
|
+
honouring `EXDATE` and `RECURRENCE-ID` overrides.
|
|
46
|
+
- Events can be addressed by **Event URL** as well as UID, and a UID is
|
|
47
|
+
resolved against the server — so events created in Thunderbird, Apple
|
|
48
|
+
Calendar, or a web UI can be reached at all.
|
|
49
|
+
- Calendars report `readOnly`, and read-only ones are marked 🔒 in the dropdown.
|
|
50
|
+
- `recurrenceId` and `timezone` on returned events.
|
|
51
|
+
- A test suite: 80 unit and integration tests, plus a smoke test that runs
|
|
52
|
+
against a real server and one that runs offline.
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
- Update preserves everything it was not asked to change, including properties
|
|
57
|
+
this node does not model (`CATEGORIES`, `ORGANIZER`, custom `X-` properties),
|
|
58
|
+
and is guarded by `If-Match` against concurrent edits.
|
|
59
|
+
- A `TZID` with no accompanying `VTIMEZONE` is resolved against the named IANA
|
|
60
|
+
zone instead of the host's.
|
|
61
|
+
- Writing to a read-only calendar explains itself instead of returning n8n's
|
|
62
|
+
generic "check your credentials".
|
|
63
|
+
|
|
64
|
+
### Security
|
|
65
|
+
|
|
66
|
+
- Advisories affecting installed users: **0**. `fast-xml-parser` moves 4 → 5.
|
|
67
|
+
|
|
68
|
+
## [2.11.0]
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
|
|
72
|
+
- Calendars report **`readOnly`**, taken from the server's
|
|
73
|
+
`current-user-privilege-set`. It rides along on the listing discovery already
|
|
74
|
+
performs, so it costs no extra request.
|
|
75
|
+
- Read-only calendars are marked `🔒 … (Read-Only)` in the Calendar dropdown
|
|
76
|
+
and sorted after the writable ones.
|
|
77
|
+
|
|
78
|
+
### Fixed
|
|
79
|
+
|
|
80
|
+
- Writing to a calendar you cannot write to produced n8n's generic
|
|
81
|
+
`Forbidden - perhaps check your credentials?`, which points at the wrong
|
|
82
|
+
cause entirely. Such a 403 now explains that the calendar is read-only —
|
|
83
|
+
typically one shared with you, or a subscribed feed — and how to find one
|
|
84
|
+
that is not.
|
|
85
|
+
|
|
86
|
+
### Notes
|
|
87
|
+
|
|
88
|
+
- A server that does not report privileges leaves `readOnly` undefined rather
|
|
89
|
+
than assuming read-only, so nothing is mislabelled or blocked on servers
|
|
90
|
+
without the property.
|
|
91
|
+
- Found by running the smoke test against a real account, where five of six
|
|
92
|
+
calendars turned out to be read-only while looking identical in the dropdown.
|
|
93
|
+
|
|
94
|
+
## [2.10.0]
|
|
95
|
+
|
|
96
|
+
### Changed
|
|
97
|
+
|
|
98
|
+
- **gulp removed.** A single task copied one SVG into the build output; gulp 4
|
|
99
|
+
is end-of-life and pulled in gulp-cli, liftoff, matchdep, chokidar, and
|
|
100
|
+
micromatch to do it. Replaced by `scripts/copy-icons.mjs`, which reproduces
|
|
101
|
+
the previous behaviour exactly.
|
|
102
|
+
- **ESLint 8 → 9**, with a flat config (`eslint.config.mjs`) replacing
|
|
103
|
+
`.eslintrc.js`. `@typescript-eslint/parser` moves 7 → 8.
|
|
104
|
+
- **`fast-xml-parser` 4 → 5** — a runtime dependency, and the only advisory
|
|
105
|
+
that reached installed users.
|
|
106
|
+
|
|
107
|
+
### Added
|
|
108
|
+
|
|
109
|
+
- `npm run lint:selftest`, which feeds a deliberate violation to each
|
|
110
|
+
eslint-plugin-n8n-nodes-base preset and fails if it goes unreported. Part of
|
|
111
|
+
`prepublishOnly`.
|
|
112
|
+
|
|
113
|
+
### Removed
|
|
114
|
+
|
|
115
|
+
- The plugin's `community` preset (19 rules against `package.json`) is no
|
|
116
|
+
longer configured. Its rules visit `ObjectExpression` while the JSON parser
|
|
117
|
+
emits `JSONObjectExpression`, so they never matched — verified inert under
|
|
118
|
+
ESLint 8 and 9 and under plugin 1.16.6 and 1.16.7. It was never enforcing
|
|
119
|
+
anything; the configuration only made it look as though it was.
|
|
120
|
+
|
|
121
|
+
### Security
|
|
122
|
+
|
|
123
|
+
- Advisories affecting installed users: **0** (was 1 moderate). Development
|
|
124
|
+
advisories drop from 24 to 5, all in ESLint's own `minimatch` chain. ESLint 10
|
|
125
|
+
would clear those but crashes eslint-plugin-n8n-nodes-base during traversal,
|
|
126
|
+
so the project stays on 9.
|
|
127
|
+
|
|
128
|
+
## [2.9.2]
|
|
129
|
+
|
|
130
|
+
### Added
|
|
131
|
+
|
|
132
|
+
- `LICENSE` file. The package declared MIT but shipped no licence text.
|
|
133
|
+
- `CHANGELOG.md` is now included in the published package.
|
|
134
|
+
|
|
135
|
+
### Fixed
|
|
136
|
+
|
|
137
|
+
- `dist/tsconfig.tsbuildinfo`, a 64 kB incremental build cache, was published
|
|
138
|
+
with every release. The package is now 37 kB instead of 54 kB.
|
|
139
|
+
|
|
140
|
+
## [2.9.1]
|
|
141
|
+
|
|
142
|
+
### Added
|
|
143
|
+
|
|
144
|
+
- Calendar discovery is memoised per execution. A batch of input items used to
|
|
145
|
+
repeat the full PROPFIND chain for every item; it now runs once.
|
|
146
|
+
- `Time Min` / `Time Max` are validated, so an unparseable date fails with a
|
|
147
|
+
message naming the field instead of an opaque `400` from the server.
|
|
148
|
+
- Integration tests covering the read operations end to end against a fake
|
|
149
|
+
CalDAV server.
|
|
150
|
+
|
|
151
|
+
### Changed
|
|
152
|
+
|
|
153
|
+
- Internal: `Get Many`, `Get Next`, and `Search` now share one implementation
|
|
154
|
+
and differ only in the time window and filter predicate.
|
|
155
|
+
|
|
156
|
+
## [2.9.0]
|
|
157
|
+
|
|
158
|
+
### Added
|
|
159
|
+
|
|
160
|
+
- **Event URL** field on `Get`, `Update`, `Delete`, and `Move`. Read operations
|
|
161
|
+
already return `url`; passing it through addresses the event directly.
|
|
162
|
+
- When only a UID is known, the event is located with a `calendar-query` on the
|
|
163
|
+
UID, falling back to the historical `<calendar>/<uid>.ics` convention.
|
|
164
|
+
- **Simplify** toggle on the read operations, on by default.
|
|
165
|
+
|
|
166
|
+
### Fixed
|
|
167
|
+
|
|
168
|
+
- `Get` / `Update` / `Delete` / `Move` could only reach events created by this
|
|
169
|
+
node. Events added in Thunderbird, Apple Calendar, or a web UI are stored
|
|
170
|
+
under a filename the server chose, so addressing them by UID returned `404`.
|
|
171
|
+
|
|
172
|
+
### Changed
|
|
173
|
+
|
|
174
|
+
- **Event UID** is no longer mandatory — either UID or URL identifies an event.
|
|
175
|
+
- `raw` is omitted by default. Turn **Simplify** off to restore it.
|
|
176
|
+
|
|
177
|
+
## [2.8.0]
|
|
178
|
+
|
|
179
|
+
### Added
|
|
180
|
+
|
|
181
|
+
- Recurring series are expanded into the individual occurrences that fall
|
|
182
|
+
inside the queried window, honouring `EXDATE` exclusions and `RECURRENCE-ID`
|
|
183
|
+
overrides.
|
|
184
|
+
- `recurrenceId` and `timezone` fields on returned events.
|
|
185
|
+
|
|
186
|
+
### Fixed
|
|
187
|
+
|
|
188
|
+
- A series reported its original `DTSTART` rather than the occurrence in the
|
|
189
|
+
requested window, and `Get Next` skipped recurring events entirely.
|
|
190
|
+
- A `TZID` without an accompanying `VTIMEZONE` was read in the n8n host's
|
|
191
|
+
timezone. Such times are now resolved against the named IANA zone.
|
|
192
|
+
- Reading an object whose overridden instance was serialised first returned the
|
|
193
|
+
override instead of the series master.
|
|
194
|
+
|
|
195
|
+
### Changed
|
|
196
|
+
|
|
197
|
+
- **`start` / `end` output format.** Timed events previously reported a local
|
|
198
|
+
wall clock with no offset (`2026-04-20T14:00:00`), which downstream nodes
|
|
199
|
+
re-read in the host's timezone. They are now explicit UTC instants
|
|
200
|
+
(`2026-04-20T12:00:00.000Z`); all-day events report a bare date
|
|
201
|
+
(`2026-04-20`). Both sort correctly as strings.
|
|
202
|
+
|
|
203
|
+
## [2.7.0]
|
|
204
|
+
|
|
205
|
+
### Fixed
|
|
206
|
+
|
|
207
|
+
- **Timed events were written at the wrong time.** With **Timezone** set, the
|
|
208
|
+
n8n host's wall clock was emitted under the requested `TZID`, shifting every
|
|
209
|
+
event by the host's UTC offset — two hours on a UTC host writing
|
|
210
|
+
`Europe/Berlin`. Events created with an earlier version should be re-checked.
|
|
211
|
+
- **All-day events were written one day early**, because the date was taken
|
|
212
|
+
from the instant's UTC components.
|
|
213
|
+
- All-day `DTEND` is now the exclusive end RFC 5545 requires. An inclusive
|
|
214
|
+
same-day end produces a one-day event instead of a zero-length one.
|
|
215
|
+
- **`Update` no longer discards data.** It rebuilt the event from the node's
|
|
216
|
+
own fields, dropping everything not restated — description, location,
|
|
217
|
+
attendees, reminders, recurrence — along with properties this node does not
|
|
218
|
+
model at all (`CATEGORIES`, `ORGANIZER`, custom `X-` properties). Updates are
|
|
219
|
+
now applied as a patch to the stored object.
|
|
220
|
+
|
|
221
|
+
### Added
|
|
222
|
+
|
|
223
|
+
- `If-Match` on update, so a concurrent edit is rejected rather than
|
|
224
|
+
overwritten.
|
|
225
|
+
- `SEQUENCE` is incremented and `LAST-MODIFIED` set on every update, so clients
|
|
226
|
+
recognise the change.
|
|
227
|
+
- Unit test suite (`npm test`, Vitest). Tests assert that output is identical
|
|
228
|
+
across several host timezones — the class of bug fixed in this release.
|
|
229
|
+
|
|
230
|
+
### Changed
|
|
231
|
+
|
|
232
|
+
- `Update` fails when the event does not exist instead of silently creating it.
|
|
233
|
+
- iCalendar is serialised through ical.js, which brings RFC-compliant line
|
|
234
|
+
folding and parameter quoting.
|
|
235
|
+
|
|
236
|
+
## [2.0.0]
|
|
237
|
+
|
|
238
|
+
Initial release.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Daisytwo
|
|
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
CHANGED
|
@@ -8,11 +8,13 @@ Drop it into a workflow to read, create, update, or delete calendar events — o
|
|
|
8
8
|
|
|
9
9
|
This node gives n8n a full CRUD interface to CalDAV calendars. In practical terms:
|
|
10
10
|
|
|
11
|
-
- **List your calendars** — auto-discovers every calendar on the server via CalDAV's well-known endpoints. No hard-coded URLs.
|
|
11
|
+
- **List your calendars** — auto-discovers every calendar on the server via CalDAV's well-known endpoints. No hard-coded URLs. Calendars you cannot write to — ones shared with you, or subscribed feeds like holiday calendars — are reported as `readOnly` and marked 🔒 in the dropdown, so a write does not fail with an unexplained 403.
|
|
12
12
|
- **Create events** with title, start/end (ISO 8601 with timezone), description, location, attendees, recurrence (RRULE), and multiple reminders (VALARM).
|
|
13
13
|
- **Fetch events** for any time window via server-side `REPORT` queries — fast even on calendars with thousands of events.
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
14
|
+
- **Expand recurring series** — a weekly meeting is returned as the individual occurrences that fall inside your window, with `EXDATE` exclusions and moved instances (`RECURRENCE-ID`) applied.
|
|
15
|
+
- **Update events** — change time, location, reminders, attendees. Updates are applied as a patch: fields you don't supply keep their stored value, including properties this node doesn't model (categories, organiser, custom `X-` properties).
|
|
16
|
+
- **Delete events** by UID or URL.
|
|
17
|
+
- **Address events written by other clients** — Get / Update / Delete / Move accept either the event's URL (as returned by every read operation) or its UID, which is resolved against the server. Events created in Thunderbird, Apple Calendar, or a web UI are stored under a filename the server chose, not under their UID.
|
|
16
18
|
- **Round-trip iCalendar** — events you write come back correctly parsed, including RRULE, TZID, and alarms.
|
|
17
19
|
- **Use it as an AI Agent tool** — every field has an LLM-readable description with examples, so an agent can call it cold and get it right on the first try.
|
|
18
20
|
|
|
@@ -28,8 +30,26 @@ This node gives n8n a full CRUD interface to CalDAV calendars. In practical term
|
|
|
28
30
|
|
|
29
31
|
| Resource | Operations | Notes |
|
|
30
32
|
| -------- | ----------------------------------------- | --------------------------------------------------- |
|
|
31
|
-
| Calendar | Get Many
|
|
32
|
-
| Event | Create · Get · Get Many · Update · Delete | Full CRUD
|
|
33
|
+
| Calendar | Get Many | Lists every calendar available to the user |
|
|
34
|
+
| Event | Create · Get · Get Many · Get Next · Search · Update · Move · Delete | Full CRUD, cross-calendar reads, and recurrence expansion |
|
|
35
|
+
|
|
36
|
+
### Event output format
|
|
37
|
+
|
|
38
|
+
Read operations (`Get`, `Get Many`, `Get Next`, `Search`) return:
|
|
39
|
+
|
|
40
|
+
| Field | Value |
|
|
41
|
+
| ---------------------- | ------------------------------------------------------------------------------------------- |
|
|
42
|
+
| `start` / `end` | All-day: `2026-04-20`. Timed: an ISO 8601 UTC instant, `2026-04-20T12:00:00.000Z`. |
|
|
43
|
+
| `timezone` | The `TZID` the event is stored under, when it has one (e.g. `Europe/Berlin`). |
|
|
44
|
+
| `allDay` | `true` for date-only events. |
|
|
45
|
+
| `recurrenceId` | Present only on an occurrence of a recurring series, identifying which slot it is. |
|
|
46
|
+
| `uid` / `url` | Shared by every occurrence of a series. |
|
|
47
|
+
| `rrule` | The series rule, repeated on each occurrence. |
|
|
48
|
+
| `raw` | The full `VCALENDAR` source — only when **Simplify** is turned off. |
|
|
49
|
+
|
|
50
|
+
> Changed in 2.9.0: read operations have a **Simplify** toggle, on by default, which omits `raw`. A recurring series repeats the same full `VCALENDAR` on every expanded occurrence, so leaving it in bloats the output and — when the node is used as an AI Agent tool — burns context. Turn Simplify off to get the old payload back.
|
|
51
|
+
|
|
52
|
+
> Changed in 2.8.0: timed events previously reported `start` as a local wall clock with no offset (`2026-04-20T14:00:00`), which downstream nodes re-read in the n8n host's timezone. Times are now emitted as explicit UTC instants and sort correctly.
|
|
33
53
|
|
|
34
54
|
### Event fields supported
|
|
35
55
|
|
|
@@ -41,6 +61,20 @@ This node gives n8n a full CRUD interface to CalDAV calendars. In practical term
|
|
|
41
61
|
- **Reminders (VALARM)**: multiple alarms per event, configurable minutes-before and action (Display / Email)
|
|
42
62
|
- **Custom UID**: override the auto-generated UUID on create if you need a deterministic identifier
|
|
43
63
|
|
|
64
|
+
## Upgrading from 2.6.x
|
|
65
|
+
|
|
66
|
+
3.0.0 fixes several bugs that silently produced wrong data, so events are now
|
|
67
|
+
written and reported differently. Read
|
|
68
|
+
[CHANGELOG.md](CHANGELOG.md) before upgrading a live workflow — in short:
|
|
69
|
+
|
|
70
|
+
- `start` / `end` are now UTC instants (`2026-04-20T12:00:00.000Z`) or bare
|
|
71
|
+
dates for all-day events, not offsetless local times.
|
|
72
|
+
- `raw` is omitted unless you turn **Simplify** off.
|
|
73
|
+
- **Update** no longer creates an event that does not exist.
|
|
74
|
+
- Events with a **Timezone** were previously written shifted by the n8n host's
|
|
75
|
+
UTC offset, and all-day events one day early. Both are fixed — if you worked
|
|
76
|
+
around either by adjusting your input, remove that adjustment.
|
|
77
|
+
|
|
44
78
|
## Installation
|
|
45
79
|
|
|
46
80
|
### n8n Community Nodes (recommended)
|
|
@@ -115,6 +149,8 @@ Name it `n8n-caldav`.
|
|
|
115
149
|
|
|
116
150
|
**4. "Event shows in wrong timezone (UTC / GMT+00:00)"** — set the **Timezone** field on the event (e.g. `Europe/Berlin`). Otherwise the event is stored as UTC and some clients display it literally.
|
|
117
151
|
|
|
152
|
+
> Versions before 2.7.0 additionally shifted timed events by the *n8n host's* UTC offset whenever **Timezone** was set, and wrote all-day events on the wrong calendar date. If you created events with an older version, re-check their times.
|
|
153
|
+
|
|
118
154
|
## AI Agent Usage
|
|
119
155
|
|
|
120
156
|
The node is declared `usableAsTool: true` with LLM-friendly descriptions on every parameter. An AI Agent can call it directly from a chat prompt. Example:
|
|
@@ -185,7 +221,8 @@ You are a calendar assistant with access to a CalDAV tool.
|
|
|
185
221
|
2. **No Free/Busy** (`calendar-availability`) — only the basic `calendar-query` REPORT.
|
|
186
222
|
3. **No attachments** (VEVENT ATTACH property).
|
|
187
223
|
4. **No scheduling / RSVP** — attendees are written as ATTENDEE lines, but no server-side `METHOD:REQUEST` invitation email is triggered.
|
|
188
|
-
5. **
|
|
224
|
+
5. **Recurrence is per-series, not per-occurrence** — reads expand a series into its occurrences, but all occurrences share one UID and one URL. Deleting or updating by UID therefore affects the whole series; there is no way to change a single occurrence.
|
|
225
|
+
6. **No `VTIMEZONE` is written** — events are stored with a `TZID` parameter but without the matching `VTIMEZONE` component. Clients resolve IANA identifiers from their own database, so this works in practice, but it is not strictly RFC 5545 compliant.
|
|
189
226
|
|
|
190
227
|
## Built with AI
|
|
191
228
|
|
|
@@ -202,31 +239,37 @@ If you find a bug or want a feature, open an issue — I'll fix it the same way.
|
|
|
202
239
|
## Development
|
|
203
240
|
|
|
204
241
|
```bash
|
|
205
|
-
npm run dev
|
|
206
|
-
npm run build
|
|
207
|
-
npm run lint
|
|
208
|
-
npm run
|
|
242
|
+
npm run dev # tsc --watch
|
|
243
|
+
npm run build # tsc + copy node icons into dist/
|
|
244
|
+
npm run lint # eslint (flat config, eslint.config.mjs)
|
|
245
|
+
npm run lint:selftest # assert the n8n lint presets actually enforce
|
|
246
|
+
npm run format # prettier
|
|
247
|
+
npm test # vitest — unit tests, no server needed
|
|
248
|
+
npm run test:watch # vitest in watch mode
|
|
209
249
|
```
|
|
210
250
|
|
|
211
|
-
|
|
251
|
+
The tests cover iCalendar generation, the update merge, recurrence expansion,
|
|
252
|
+
event lookup, and the read operations end to end against a fake CalDAV server —
|
|
253
|
+
no network and no credentials required.
|
|
212
254
|
|
|
213
|
-
|
|
255
|
+
They run the
|
|
256
|
+
same input under several host timezones (`UTC`, `Europe/Berlin`,
|
|
257
|
+
`America/New_York`, `Asia/Tokyo`) and assert the output is identical — the
|
|
258
|
+
timezone bugs fixed in 2.7.0 were only visible when the host's zone differed
|
|
259
|
+
from the event's, which is the normal case in Docker.
|
|
214
260
|
|
|
215
|
-
|
|
216
|
-
# bash / macOS / Linux
|
|
217
|
-
export CALDAV_SERVER=https://sync.infomaniak.com/
|
|
218
|
-
export CALDAV_USERNAME=your-short-username
|
|
219
|
-
export CALDAV_PASSWORD=your-app-password
|
|
220
|
-
node e2e-test.js
|
|
221
|
-
```
|
|
261
|
+
### Manual testing against your CalDAV server
|
|
222
262
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
263
|
+
Local test scripts (`e2e-test.js`, `smoke-test.js`) live in `.gitignore` so they
|
|
264
|
+
never end up in the published repo or npm package. To verify the build against
|
|
265
|
+
a real server during development, install the node into your local n8n custom
|
|
266
|
+
folder via `npm link` (see "Local development" above) and trigger the operations
|
|
267
|
+
through the n8n UI — that's the canonical integration path.
|
|
268
|
+
|
|
269
|
+
If you want a headless smoke check, write a small script that imports from
|
|
270
|
+
`dist/nodes/CalDav/GenericFunctions.js` and calls `discoverCalendars`,
|
|
271
|
+
`buildICalEvent`, `parseCalendarQueryResponse` directly. Read credentials
|
|
272
|
+
from environment variables — never hard-code them.
|
|
230
273
|
|
|
231
274
|
## License
|
|
232
275
|
|
|
@@ -33,6 +33,14 @@ class CalDavApi {
|
|
|
33
33
|
description: 'Your CalDAV password. If 2FA is enabled on your account (Infomaniak, iCloud, Google), you MUST generate an app-specific password at the provider manager. Regular login passwords will be rejected.',
|
|
34
34
|
required: true,
|
|
35
35
|
},
|
|
36
|
+
{
|
|
37
|
+
displayName: 'Default Calendar',
|
|
38
|
+
name: 'defaultCalendar',
|
|
39
|
+
type: 'string',
|
|
40
|
+
default: '',
|
|
41
|
+
placeholder: 'Privat or c8763b63 or https://sync…/calendars/user/uuid/',
|
|
42
|
+
description: 'Optional. The calendar used when an event operation has Calendar set to "Default Calendar (from credentials)". Accepts a full calendar URL, a UUID fragment, or a unique substring of the display name (case-insensitive). If you leave this empty, the AI Agent (or you) MUST always pick a specific calendar in the node.',
|
|
43
|
+
},
|
|
36
44
|
{
|
|
37
45
|
displayName: 'Calendar Allow-List',
|
|
38
46
|
name: 'calendarAllowList',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CalDavApi.credentials.js","sourceRoot":"","sources":["../../credentials/CalDavApi.credentials.ts"],"names":[],"mappings":";;;AAQA,MAAa,SAAS;IACrB,IAAI,GAAG,WAAW,CAAC;IAEnB,WAAW,GAAG,YAAY,CAAC;IAE3B,gBAAgB,GAAG,kDAAkD,CAAC;IAEtE,UAAU,GAAsB;QAC/B;YACC,WAAW,EAAE,YAAY;YACzB,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,8BAA8B;YACvC,WAAW,EAAE,8BAA8B;YAC3C,WAAW,EACV,0JAA0J;YAC3J,QAAQ,EAAE,IAAI;SACd;QACD;YACC,WAAW,EAAE,UAAU;YACvB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,UAAU;YACvB,WAAW,EACV,6OAA6O;YAC9O,QAAQ,EAAE,IAAI;SACd;QACD;YACC,WAAW,EAAE,UAAU;YACvB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC/B,OAAO,EAAE,EAAE;YACX,WAAW,EACV,qMAAqM;YACtM,QAAQ,EAAE,IAAI;SACd;QACD;YACC,WAAW,EAAE,qBAAqB;YAClC,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,0BAA0B;YACvC,WAAW,EACV,ibAAib;SAClb;QACD;YACC,WAAW,EAAE,qBAAqB;YAClC,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,iCAAiC;YAC9C,WAAW,EACV,iZAAiZ;SAClZ;KACD,CAAC;IAMF,KAAK,CAAC,YAAY,CACjB,WAA2C,EAC3C,cAAmC;QAEnC,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAkB,CAAC;QAChD,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAkB,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACxE,cAAc,CAAC,OAAO,GAAG;YACxB,GAAG,CAAC,cAAc,CAAC,OAAO,IAAI,EAAE,CAAC;YACjC,aAAa,EAAE,SAAS,KAAK,EAAE;SAC/B,CAAC;QACF,OAAO,cAAc,CAAC;IACvB,CAAC;IAOD,IAAI,GAA2B;QAC9B,OAAO,EAAE;YACR,MAAM,EAAE,UAAiB;YACzB,GAAG,EAAE,kDAAkD;YACvD,OAAO,EAAE;gBACR,KAAK,EAAE,GAAG;gBACV,cAAc,EAAE,gCAAgC;aAChD;YACD,IAAI,EAAE;;;;;;;cAOK;SACX;QACD,KAAK,EAAE;YACN;gBACC,IAAI,EAAE,cAAc;gBACpB,UAAU,EAAE;oBACX,KAAK,EAAE,GAAG;oBACV,OAAO,EACN,+LAA+L;iBAChM;aACD;YACD;gBACC,IAAI,EAAE,cAAc;gBACpB,UAAU,EAAE;oBACX,KAAK,EAAE,GAAG;oBACV,OAAO,EACN,gIAAgI;iBACjI;aACD;YACD;gBACC,IAAI,EAAE,cAAc;gBACpB,UAAU,EAAE;oBACX,KAAK,EAAE,GAAG;oBACV,OAAO,EACN,2GAA2G;iBAC5G;aACD;SACD;KACD,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"CalDavApi.credentials.js","sourceRoot":"","sources":["../../credentials/CalDavApi.credentials.ts"],"names":[],"mappings":";;;AAQA,MAAa,SAAS;IACrB,IAAI,GAAG,WAAW,CAAC;IAEnB,WAAW,GAAG,YAAY,CAAC;IAE3B,gBAAgB,GAAG,kDAAkD,CAAC;IAEtE,UAAU,GAAsB;QAC/B;YACC,WAAW,EAAE,YAAY;YACzB,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,8BAA8B;YACvC,WAAW,EAAE,8BAA8B;YAC3C,WAAW,EACV,0JAA0J;YAC3J,QAAQ,EAAE,IAAI;SACd;QACD;YACC,WAAW,EAAE,UAAU;YACvB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,UAAU;YACvB,WAAW,EACV,6OAA6O;YAC9O,QAAQ,EAAE,IAAI;SACd;QACD;YACC,WAAW,EAAE,UAAU;YACvB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC/B,OAAO,EAAE,EAAE;YACX,WAAW,EACV,qMAAqM;YACtM,QAAQ,EAAE,IAAI;SACd;QACD;YACC,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,kEAAkE;YAC/E,WAAW,EACV,6TAA6T;SAC9T;QACD;YACC,WAAW,EAAE,qBAAqB;YAClC,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,0BAA0B;YACvC,WAAW,EACV,ibAAib;SAClb;QACD;YACC,WAAW,EAAE,qBAAqB;YAClC,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,iCAAiC;YAC9C,WAAW,EACV,iZAAiZ;SAClZ;KACD,CAAC;IAMF,KAAK,CAAC,YAAY,CACjB,WAA2C,EAC3C,cAAmC;QAEnC,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAkB,CAAC;QAChD,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAkB,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACxE,cAAc,CAAC,OAAO,GAAG;YACxB,GAAG,CAAC,cAAc,CAAC,OAAO,IAAI,EAAE,CAAC;YACjC,aAAa,EAAE,SAAS,KAAK,EAAE;SAC/B,CAAC;QACF,OAAO,cAAc,CAAC;IACvB,CAAC;IAOD,IAAI,GAA2B;QAC9B,OAAO,EAAE;YACR,MAAM,EAAE,UAAiB;YACzB,GAAG,EAAE,kDAAkD;YACvD,OAAO,EAAE;gBACR,KAAK,EAAE,GAAG;gBACV,cAAc,EAAE,gCAAgC;aAChD;YACD,IAAI,EAAE;;;;;;;cAOK;SACX;QACD,KAAK,EAAE;YACN;gBACC,IAAI,EAAE,cAAc;gBACpB,UAAU,EAAE;oBACX,KAAK,EAAE,GAAG;oBACV,OAAO,EACN,+LAA+L;iBAChM;aACD;YACD;gBACC,IAAI,EAAE,cAAc;gBACpB,UAAU,EAAE;oBACX,KAAK,EAAE,GAAG;oBACV,OAAO,EACN,gIAAgI;iBACjI;aACD;YACD;gBACC,IAAI,EAAE,cAAc;gBACpB,UAAU,EAAE;oBACX,KAAK,EAAE,GAAG;oBACV,OAAO,EACN,2GAA2G;iBAC5G;aACD;SACD;KACD,CAAC;CACF;AAtID,8BAsIC"}
|