@sockethub/platform-caldav 1.0.0-beta.5 → 1.0.0-beta.6
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/README.md +19 -3
- package/dist/dav.d.ts +6 -1
- package/dist/ical.d.ts +8 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +195 -18
- package/dist/index.js.map +9 -8
- package/dist/patch.d.ts +13 -0
- package/dist/schema.d.ts +60 -0
- package/dist/types.d.ts +5 -0
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -133,7 +133,10 @@ The collection contains calendar objects such as:
|
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
Each returned item contains its resource `id`, `uid`, `etag`, and
|
|
136
|
-
`updateSupported
|
|
136
|
+
`updateSupported`, plus `created` and `lastModified` (UTC) when the resource
|
|
137
|
+
records them; `lastModified` falls back to `DTSTAMP`. These two are output
|
|
138
|
+
only and ignored on create and update. Keep the ETag for later update or
|
|
139
|
+
delete requests. Use date
|
|
137
140
|
ranges for large calendars; responses larger than 10 MiB are rejected.
|
|
138
141
|
|
|
139
142
|
### Sync changes
|
|
@@ -185,6 +188,15 @@ When `truncated` is `true`, the server limited the result. The returned token
|
|
|
185
188
|
covers exactly the changes delivered, so store it and sync again until
|
|
186
189
|
`truncated` is `false`.
|
|
187
190
|
|
|
191
|
+
To track changes without downloading a calendar's history, start from the
|
|
192
|
+
current token instead of an initial sync. Send `"object": { "tokenOnly": true }`
|
|
193
|
+
to get the calendar's current `syncToken` with empty `items` and `removed`,
|
|
194
|
+
then `query` the date range you need, then `sync` with the token on later
|
|
195
|
+
passes. Read the token before the `query`, so nothing changed in between is
|
|
196
|
+
missed. Later syncs still report changes to any item in the calendar,
|
|
197
|
+
including old ones. A server that exposes no token returns
|
|
198
|
+
`caldav:sync-unsupported`.
|
|
199
|
+
|
|
188
200
|
Calendar resources that hold neither an event nor a task, such as journals, are
|
|
189
201
|
left out of `items`.
|
|
190
202
|
|
|
@@ -299,8 +311,12 @@ Update sends the complete event or task returned by `query`, including `id`,
|
|
|
299
311
|
`uid`, and `etag`. Increment `sequence` when changing scheduling information.
|
|
300
312
|
An update is rejected when `updateSupported` is false, which protects recurrence
|
|
301
313
|
exceptions, exclusion dates, and multi-component resources from being lost.
|
|
302
|
-
|
|
303
|
-
|
|
314
|
+
Update changes only the stored properties whose fields differ from the stored
|
|
315
|
+
item, plus `DTSTAMP` and `LAST-MODIFIED`. Everything else stays as it was,
|
|
316
|
+
including `CATEGORIES`, `X-` properties, `CREATED`, `VTIMEZONE` blocks, and
|
|
317
|
+
parameters on unchanged attendees and alarms. A field left out of the update
|
|
318
|
+
removes its property. A changed field is written from the item model, so
|
|
319
|
+
parameters the model does not carry are dropped from that property.
|
|
304
320
|
|
|
305
321
|
```json
|
|
306
322
|
{
|
package/dist/dav.d.ts
CHANGED
|
@@ -15,7 +15,12 @@ export declare class CalDavClient extends DavClient {
|
|
|
15
15
|
* task in the calendar; with one, lists only what changed since then.
|
|
16
16
|
*/
|
|
17
17
|
sync(calendar: CalendarDescription, syncToken?: string): Promise<CalendarSyncResult>;
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Replace a resource if its ETag still matches. `body` is either the new
|
|
20
|
+
* resource or a function that builds it from the stored one, so changes
|
|
21
|
+
* can be applied without losing what the item model does not carry.
|
|
22
|
+
*/
|
|
23
|
+
update(id: string, etag: string, body: string | ((stored: string) => string)): Promise<{
|
|
19
24
|
id: string;
|
|
20
25
|
etag?: string;
|
|
21
26
|
}>;
|
package/dist/ical.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { CalendarItem, CalendarObjectInput } from "./types.js";
|
|
2
2
|
/** Fold one iCalendar content line at 75 UTF-8 octets (74 after continuation). */
|
|
3
3
|
export declare function foldLine(line: string): string;
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Serialize an item as a single-component iCalendar resource. `created`
|
|
6
|
+
* stamps `CREATED` with `now`; pass it only for a new resource, so an update
|
|
7
|
+
* does not move the creation time.
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildICalendar(input: CalendarObjectInput, now?: Date, { created }?: {
|
|
10
|
+
created?: boolean;
|
|
11
|
+
}): {
|
|
5
12
|
uid: string;
|
|
6
13
|
body: string;
|
|
7
14
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -39,6 +39,11 @@ export default class CalDav implements PlatformInterface {
|
|
|
39
39
|
* the result being complete. `caldav:sync-token-invalid` means start
|
|
40
40
|
* over without a token; `caldav:sync-unsupported` means fall back to
|
|
41
41
|
* `query`.
|
|
42
|
+
*
|
|
43
|
+
* With `object.tokenOnly: true`, returns the calendar's current token
|
|
44
|
+
* and no items, so a client can start tracking changes without
|
|
45
|
+
* downloading history: get the token first, then `query` the range it
|
|
46
|
+
* needs, then `sync` with the token on later passes.
|
|
42
47
|
*/
|
|
43
48
|
sync(job: ActivityStream, credentials: CalDavCredentials, done: PlatformCallback): void;
|
|
44
49
|
update(job: ActivityStream, credentials: CalDavCredentials, done: PlatformCallback): void;
|
package/dist/index.js
CHANGED
|
@@ -66381,6 +66381,35 @@ class DavClient {
|
|
|
66381
66381
|
}
|
|
66382
66382
|
return this.readMultistatus(response);
|
|
66383
66383
|
}
|
|
66384
|
+
async currentSyncToken(collection) {
|
|
66385
|
+
const response = await this.request(collection, {
|
|
66386
|
+
method: "PROPFIND",
|
|
66387
|
+
headers: {
|
|
66388
|
+
depth: "0",
|
|
66389
|
+
"content-type": "application/xml; charset=utf-8"
|
|
66390
|
+
},
|
|
66391
|
+
body: `<?xml version="1.0" encoding="utf-8"?>
|
|
66392
|
+
<d:propfind xmlns:d="DAV:"><d:prop><d:sync-token/></d:prop></d:propfind>`
|
|
66393
|
+
});
|
|
66394
|
+
if (response.status === 404)
|
|
66395
|
+
return rejectDavResponse(response, `${this.errorPrefix}:not-found`);
|
|
66396
|
+
if (response.status !== 207) {
|
|
66397
|
+
await response.body?.cancel().catch(() => {});
|
|
66398
|
+
throw new DavFailure(`${this.errorPrefix}:invalid-response`);
|
|
66399
|
+
}
|
|
66400
|
+
let responses;
|
|
66401
|
+
try {
|
|
66402
|
+
responses = asArray(parseDavXml(await response.text(), {
|
|
66403
|
+
parseTagValue: false
|
|
66404
|
+
}).multistatus?.response);
|
|
66405
|
+
} catch {
|
|
66406
|
+
throw new DavFailure(`${this.errorPrefix}:invalid-response`);
|
|
66407
|
+
}
|
|
66408
|
+
const token = successfulProps(responses[0] ?? {})["sync-token"];
|
|
66409
|
+
if (typeof token !== "string" || token.trim() === "")
|
|
66410
|
+
throw new DavFailure(`${this.errorPrefix}:sync-unsupported`);
|
|
66411
|
+
return token.trim();
|
|
66412
|
+
}
|
|
66384
66413
|
async syncCollection(collection, prop, syncToken, namespaces = "") {
|
|
66385
66414
|
const response = await this.request(collection, {
|
|
66386
66415
|
method: "REPORT",
|
|
@@ -66819,7 +66848,7 @@ var ActivityStreamSchema = {
|
|
|
66819
66848
|
var package_default = {
|
|
66820
66849
|
name: "@sockethub/schemas",
|
|
66821
66850
|
description: "JSON schema files for validating Sockethub Activity Streams",
|
|
66822
|
-
version: "3.0.0-beta.
|
|
66851
|
+
version: "3.0.0-beta.6",
|
|
66823
66852
|
type: "module",
|
|
66824
66853
|
private: false,
|
|
66825
66854
|
author: "Nick Jennings <nick@silverbucket.net>",
|
|
@@ -66889,7 +66918,7 @@ var package_default = {
|
|
|
66889
66918
|
"ajv-formats": "^2.1.1",
|
|
66890
66919
|
"ajv-formats-draft2019": "^1.6.1"
|
|
66891
66920
|
},
|
|
66892
|
-
gitHead: "
|
|
66921
|
+
gitHead: "604f3da8850a19a4fd5f5e5dcec10bf283e9085e",
|
|
66893
66922
|
types: "./dist/index.d.ts"
|
|
66894
66923
|
};
|
|
66895
66924
|
|
|
@@ -68036,7 +68065,7 @@ function timeZoneRange(input, fallbackYear) {
|
|
|
68036
68065
|
const last = years.length ? Math.max(...years) : fallbackYear;
|
|
68037
68066
|
return [first - 1, Math.max(last + 1, first + 30)];
|
|
68038
68067
|
}
|
|
68039
|
-
function buildICalendar(input, now = new Date) {
|
|
68068
|
+
function buildICalendar(input, now = new Date, { created = false } = {}) {
|
|
68040
68069
|
const uid = input.uid ?? `${randomUUID()}@sockethub`;
|
|
68041
68070
|
if (/[\r\n%/\\]/.test(uid))
|
|
68042
68071
|
throw new Error("invalid uid");
|
|
@@ -68055,6 +68084,8 @@ function buildICalendar(input, now = new Date) {
|
|
|
68055
68084
|
`BEGIN:${component}`,
|
|
68056
68085
|
`UID:${escapeText(uid)}`,
|
|
68057
68086
|
`DTSTAMP:${utcDateTime(now.toISOString(), "now")}`,
|
|
68087
|
+
...created ? [`CREATED:${utcDateTime(now.toISOString(), "now")}`] : [],
|
|
68088
|
+
`LAST-MODIFIED:${utcDateTime(now.toISOString(), "now")}`,
|
|
68058
68089
|
`SUMMARY:${escapeText(input.name)}`
|
|
68059
68090
|
];
|
|
68060
68091
|
if (input.content)
|
|
@@ -68101,6 +68132,13 @@ function parseDate(value) {
|
|
|
68101
68132
|
return `${value.slice(0, 4)}-${value.slice(4, 6)}-${value.slice(6, 8)}T${value.slice(9, 11)}:${value.slice(11, 13)}:${value.slice(13, 15)}`;
|
|
68102
68133
|
return value;
|
|
68103
68134
|
}
|
|
68135
|
+
function utcTimestamp(value) {
|
|
68136
|
+
if (!value || !/^\d{8}T\d{6}Z$/.test(value))
|
|
68137
|
+
return;
|
|
68138
|
+
const iso = parseDate(value);
|
|
68139
|
+
const parsed = new Date(iso);
|
|
68140
|
+
return !Number.isNaN(parsed.getTime()) && parsed.toISOString().replace(".000Z", "Z") === iso ? iso : undefined;
|
|
68141
|
+
}
|
|
68104
68142
|
var STATUSES = {
|
|
68105
68143
|
event: ["tentative", "confirmed", "cancelled"],
|
|
68106
68144
|
task: ["needs-action", "in-process", "completed", "cancelled"]
|
|
@@ -68176,6 +68214,13 @@ function parseICalendar(body, id, etag) {
|
|
|
68176
68214
|
name: unescapeText(summary),
|
|
68177
68215
|
updateSupported: isUpdateSupported(body)
|
|
68178
68216
|
};
|
|
68217
|
+
const created = utcTimestamp(first("CREATED")?.value);
|
|
68218
|
+
const hasMethod = lines.slice(0, begin).some((line) => /^METHOD[;:]/i.test(line));
|
|
68219
|
+
const lastModified = utcTimestamp(first("LAST-MODIFIED")?.value) ?? (hasMethod ? undefined : utcTimestamp(first("DTSTAMP")?.value));
|
|
68220
|
+
if (created)
|
|
68221
|
+
item.created = created;
|
|
68222
|
+
if (lastModified)
|
|
68223
|
+
item.lastModified = lastModified;
|
|
68179
68224
|
if (first("DESCRIPTION"))
|
|
68180
68225
|
item.content = unescapeText(first("DESCRIPTION")?.value ?? "");
|
|
68181
68226
|
if (first("LOCATION"))
|
|
@@ -68460,7 +68505,8 @@ class CalDavClient extends DavClient {
|
|
|
68460
68505
|
return rejectDavResponse(current, "caldav:not-found");
|
|
68461
68506
|
if (!current.ok)
|
|
68462
68507
|
return rejectDavResponse(current, "caldav:update-failed");
|
|
68463
|
-
|
|
68508
|
+
const stored = await current.text();
|
|
68509
|
+
if (!isUpdateSupported(stored))
|
|
68464
68510
|
throw new CalDavFailure("caldav:unsupported-update");
|
|
68465
68511
|
const response = await this.request(resource, {
|
|
68466
68512
|
method: "PUT",
|
|
@@ -68468,7 +68514,7 @@ class CalDavClient extends DavClient {
|
|
|
68468
68514
|
"content-type": "text/calendar; charset=utf-8",
|
|
68469
68515
|
"if-match": etag
|
|
68470
68516
|
},
|
|
68471
|
-
body
|
|
68517
|
+
body: typeof body === "function" ? body(stored) : body
|
|
68472
68518
|
});
|
|
68473
68519
|
if (response.status === 412)
|
|
68474
68520
|
return rejectDavResponse(response, "caldav:conflict");
|
|
@@ -68678,11 +68724,126 @@ END:VCALENDAR\r
|
|
|
68678
68724
|
skipped
|
|
68679
68725
|
};
|
|
68680
68726
|
}
|
|
68727
|
+
|
|
68728
|
+
// src/patch.ts
|
|
68729
|
+
var GROUPS = [
|
|
68730
|
+
{ fields: ["name"], names: ["SUMMARY"] },
|
|
68731
|
+
{ fields: ["content"], names: ["DESCRIPTION"] },
|
|
68732
|
+
{ fields: ["location"], names: ["LOCATION"] },
|
|
68733
|
+
{ fields: ["url"], names: ["URL"] },
|
|
68734
|
+
{
|
|
68735
|
+
fields: ["startTime", "endTime", "due", "allDay", "timeZone"],
|
|
68736
|
+
names: ["DTSTART", "DTEND", "DUE"]
|
|
68737
|
+
},
|
|
68738
|
+
{ fields: ["status"], names: ["STATUS"] },
|
|
68739
|
+
{ fields: ["completedTime"], names: ["COMPLETED"] },
|
|
68740
|
+
{ fields: ["percentComplete"], names: ["PERCENT-COMPLETE"] },
|
|
68741
|
+
{ fields: ["sequence"], names: ["SEQUENCE"] },
|
|
68742
|
+
{ fields: ["recurrence"], names: ["RRULE"] },
|
|
68743
|
+
{ fields: ["organizer"], names: ["ORGANIZER"] },
|
|
68744
|
+
{ fields: ["attendees"], names: ["ATTENDEE"] },
|
|
68745
|
+
{ fields: ["attachments"], names: ["ATTACH"] },
|
|
68746
|
+
{ fields: ["reminders"], names: ["VALARM"] },
|
|
68747
|
+
{ fields: [], names: ["DTSTAMP", "LAST-MODIFIED"] }
|
|
68748
|
+
];
|
|
68749
|
+
function logicalLines(body) {
|
|
68750
|
+
const lines = [];
|
|
68751
|
+
for (const line of body.split(/\r?\n/)) {
|
|
68752
|
+
if (/^[ \t]/.test(line) && lines.length)
|
|
68753
|
+
lines[lines.length - 1].push(line);
|
|
68754
|
+
else
|
|
68755
|
+
lines.push([line]);
|
|
68756
|
+
}
|
|
68757
|
+
while (lines.length && lines[lines.length - 1].join("") === "")
|
|
68758
|
+
lines.pop();
|
|
68759
|
+
return lines;
|
|
68760
|
+
}
|
|
68761
|
+
var unfolded = (raw) => raw.map((line, index) => index ? line.slice(1) : line).join("");
|
|
68762
|
+
var propertyName = (raw) => (unfolded(raw).match(/^[^;:]*/)?.[0] ?? "").toUpperCase();
|
|
68763
|
+
function componentBounds(lines) {
|
|
68764
|
+
const begin = lines.findIndex((raw) => /^BEGIN:(?:VEVENT|VTODO)$/.test(unfolded(raw)));
|
|
68765
|
+
if (begin === -1)
|
|
68766
|
+
return;
|
|
68767
|
+
const name = unfolded(lines[begin]).slice("BEGIN:".length);
|
|
68768
|
+
const end = lines.findIndex((raw, index) => index > begin && unfolded(raw) === `END:${name}`);
|
|
68769
|
+
return end === -1 ? undefined : { begin, end, name };
|
|
68770
|
+
}
|
|
68771
|
+
function units(lines) {
|
|
68772
|
+
const result = [];
|
|
68773
|
+
let alarm;
|
|
68774
|
+
for (const raw of lines) {
|
|
68775
|
+
const text = unfolded(raw);
|
|
68776
|
+
if (alarm) {
|
|
68777
|
+
alarm.push(...raw);
|
|
68778
|
+
if (text === "END:VALARM") {
|
|
68779
|
+
result.push({ name: "VALARM", raw: alarm });
|
|
68780
|
+
alarm = undefined;
|
|
68781
|
+
}
|
|
68782
|
+
} else if (text === "BEGIN:VALARM")
|
|
68783
|
+
alarm = [...raw];
|
|
68784
|
+
else
|
|
68785
|
+
result.push({ name: propertyName(raw), raw });
|
|
68786
|
+
}
|
|
68787
|
+
if (alarm)
|
|
68788
|
+
result.push({ name: "", raw: alarm });
|
|
68789
|
+
return result;
|
|
68790
|
+
}
|
|
68791
|
+
function canonical(value) {
|
|
68792
|
+
return JSON.stringify(value, (_key, entry) => entry && typeof entry === "object" && !Array.isArray(entry) ? Object.fromEntries(Object.keys(entry).sort().map((key) => [key, entry[key]])) : entry);
|
|
68793
|
+
}
|
|
68794
|
+
function sameField(current, next, field) {
|
|
68795
|
+
if (field === "allDay")
|
|
68796
|
+
return current.allDay === true === (next.allDay === true);
|
|
68797
|
+
return canonical(current[field]) === canonical(next[field]);
|
|
68798
|
+
}
|
|
68799
|
+
function patchICalendar(stored, item, generated) {
|
|
68800
|
+
const current = parseICalendar(stored, "");
|
|
68801
|
+
if (current.type !== item.type)
|
|
68802
|
+
return { uid: item.uid ?? current.uid, body: generated };
|
|
68803
|
+
const lines = logicalLines(stored);
|
|
68804
|
+
const bounds = componentBounds(lines);
|
|
68805
|
+
const fresh = logicalLines(generated);
|
|
68806
|
+
const freshBounds = componentBounds(fresh);
|
|
68807
|
+
if (!bounds || !freshBounds)
|
|
68808
|
+
throw new Error("invalid calendar data");
|
|
68809
|
+
const freshUnits = units(fresh.slice(freshBounds.begin + 1, freshBounds.end));
|
|
68810
|
+
const replaced = new Set;
|
|
68811
|
+
for (const group of GROUPS)
|
|
68812
|
+
if (!group.fields.length || !group.fields.every((field) => sameField(current, item, field)))
|
|
68813
|
+
for (const name of group.names)
|
|
68814
|
+
replaced.add(name);
|
|
68815
|
+
const freshNames = new Set(freshUnits.map((unit) => unit.name));
|
|
68816
|
+
if (replaced.has("DTSTART") && (freshNames.has("DTEND") || freshNames.has("DUE")))
|
|
68817
|
+
replaced.add("DURATION");
|
|
68818
|
+
const kept = [];
|
|
68819
|
+
let insertAt;
|
|
68820
|
+
for (const unit of units(lines.slice(bounds.begin + 1, bounds.end))) {
|
|
68821
|
+
if (replaced.has(unit.name))
|
|
68822
|
+
insertAt ??= kept.length;
|
|
68823
|
+
else
|
|
68824
|
+
kept.push(unit);
|
|
68825
|
+
}
|
|
68826
|
+
const added = freshUnits.filter((unit) => replaced.has(unit.name));
|
|
68827
|
+
kept.splice(insertAt ?? kept.length, 0, ...added);
|
|
68828
|
+
const zone = item.timeZone;
|
|
68829
|
+
const freshZone = fresh.findIndex((raw) => unfolded(raw) === "BEGIN:VTIMEZONE");
|
|
68830
|
+
const zones = zone && replaced.has("DTSTART") && freshZone !== -1 && freshZone < freshBounds.begin && !lines.slice(0, bounds.begin).concat(lines.slice(bounds.end + 1)).some((raw) => unfolded(raw) === `TZID:${zone}`) ? fresh.slice(freshZone, freshBounds.begin) : [];
|
|
68831
|
+
const output = [
|
|
68832
|
+
...lines.slice(0, bounds.begin),
|
|
68833
|
+
...zones,
|
|
68834
|
+
lines[bounds.begin],
|
|
68835
|
+
...kept.map((unit) => unit.raw),
|
|
68836
|
+
...lines.slice(bounds.end)
|
|
68837
|
+
].flat();
|
|
68838
|
+
return { uid: current.uid, body: `${output.join(`\r
|
|
68839
|
+
`)}\r
|
|
68840
|
+
` };
|
|
68841
|
+
}
|
|
68681
68842
|
// package.json
|
|
68682
68843
|
var package_default2 = {
|
|
68683
68844
|
name: "@sockethub/platform-caldav",
|
|
68684
68845
|
description: "A Sockethub platform for synchronizing CalDAV calendars, events, and tasks",
|
|
68685
|
-
version: "1.0.0-beta.
|
|
68846
|
+
version: "1.0.0-beta.6",
|
|
68686
68847
|
type: "module",
|
|
68687
68848
|
private: false,
|
|
68688
68849
|
license: "LGPL-3.0+",
|
|
@@ -68716,16 +68877,16 @@ var package_default2 = {
|
|
|
68716
68877
|
test: "bun test src/"
|
|
68717
68878
|
},
|
|
68718
68879
|
dependencies: {
|
|
68719
|
-
"@sockethub/dav": "^1.0.0-beta.
|
|
68720
|
-
"@sockethub/schemas": "^3.0.0-beta.
|
|
68721
|
-
"@sockethub/util": "^1.0.0-beta.
|
|
68880
|
+
"@sockethub/dav": "^1.0.0-beta.6",
|
|
68881
|
+
"@sockethub/schemas": "^3.0.0-beta.6",
|
|
68882
|
+
"@sockethub/util": "^1.0.0-beta.6",
|
|
68722
68883
|
undici: "^7.30.0"
|
|
68723
68884
|
},
|
|
68724
68885
|
devDependencies: {
|
|
68725
68886
|
"@types/bun": "latest"
|
|
68726
68887
|
},
|
|
68727
68888
|
peerDependencies: {
|
|
68728
|
-
"@sockethub/server": "^5.0.0-beta.
|
|
68889
|
+
"@sockethub/server": "^5.0.0-beta.6"
|
|
68729
68890
|
},
|
|
68730
68891
|
peerDependenciesMeta: {
|
|
68731
68892
|
"@sockethub/server": {
|
|
@@ -68733,7 +68894,7 @@ var package_default2 = {
|
|
|
68733
68894
|
}
|
|
68734
68895
|
},
|
|
68735
68896
|
types: "./dist/index.d.ts",
|
|
68736
|
-
gitHead: "
|
|
68897
|
+
gitHead: "604f3da8850a19a4fd5f5e5dcec10bf283e9085e"
|
|
68737
68898
|
};
|
|
68738
68899
|
|
|
68739
68900
|
// src/schema.ts
|
|
@@ -68863,7 +69024,9 @@ var shared = {
|
|
|
68863
69024
|
attendees: { type: "array", maxItems: 1000, items: person },
|
|
68864
69025
|
reminders: { type: "array", maxItems: 100, items: reminder },
|
|
68865
69026
|
attachments: { type: "array", maxItems: 100, items: attachment },
|
|
68866
|
-
updateSupported: { type: "boolean" }
|
|
69027
|
+
updateSupported: { type: "boolean" },
|
|
69028
|
+
created: { type: "string", format: "date-time" },
|
|
69029
|
+
lastModified: { type: "string", format: "date-time" }
|
|
68867
69030
|
};
|
|
68868
69031
|
var eventObject = {
|
|
68869
69032
|
type: "object",
|
|
@@ -68934,7 +69097,8 @@ var syncToken = { type: "string", minLength: 1, maxLength: 4096 };
|
|
|
68934
69097
|
var syncObject = {
|
|
68935
69098
|
type: "object",
|
|
68936
69099
|
additionalProperties: false,
|
|
68937
|
-
properties: { syncToken }
|
|
69100
|
+
properties: { syncToken, tokenOnly: { const: true } },
|
|
69101
|
+
not: { required: ["syncToken", "tokenOnly"] }
|
|
68938
69102
|
};
|
|
68939
69103
|
var calendarItem2 = { oneOf: [eventObject, taskObject] };
|
|
68940
69104
|
var mutationObject = {
|
|
@@ -68977,7 +69141,8 @@ var PlatformCalDavSchema = {
|
|
|
68977
69141
|
taskObject,
|
|
68978
69142
|
deleteObject,
|
|
68979
69143
|
queryObject,
|
|
68980
|
-
{ ...syncObject, required: ["syncToken"] }
|
|
69144
|
+
{ ...syncObject, required: ["syncToken"] },
|
|
69145
|
+
{ ...syncObject, required: ["tokenOnly"] }
|
|
68981
69146
|
]
|
|
68982
69147
|
}
|
|
68983
69148
|
}
|
|
@@ -69286,7 +69451,9 @@ class CalDav {
|
|
|
69286
69451
|
if (!target.components.includes(input.type)) {
|
|
69287
69452
|
throw new CalDavFailure("caldav:unsupported-component");
|
|
69288
69453
|
}
|
|
69289
|
-
const calendarData = buildICalendar(input
|
|
69454
|
+
const calendarData = buildICalendar(input, new Date, {
|
|
69455
|
+
created: true
|
|
69456
|
+
});
|
|
69290
69457
|
const created = await client.create(target, calendarData.uid, calendarData.body);
|
|
69291
69458
|
done(null, {
|
|
69292
69459
|
"@context": CONTEXT,
|
|
@@ -69317,7 +69484,12 @@ class CalDav {
|
|
|
69317
69484
|
sync(job, credentials, done) {
|
|
69318
69485
|
const client = this.client(credentials);
|
|
69319
69486
|
const input = job.object ?? {};
|
|
69320
|
-
this.calendar(client, credentials, job.target?.id ?? "").then((calendar) => client.
|
|
69487
|
+
this.calendar(client, credentials, job.target?.id ?? "").then((calendar) => input.tokenOnly ? client.currentSyncToken(new URL(calendar.id)).then((syncToken) => ({
|
|
69488
|
+
items: [],
|
|
69489
|
+
removed: [],
|
|
69490
|
+
syncToken,
|
|
69491
|
+
truncated: false
|
|
69492
|
+
})) : client.sync(calendar, input.syncToken)).then((result) => done(null, {
|
|
69321
69493
|
"@context": CONTEXT,
|
|
69322
69494
|
...job.id ? { id: job.id } : {},
|
|
69323
69495
|
type: "collection",
|
|
@@ -69332,7 +69504,12 @@ class CalDav {
|
|
|
69332
69504
|
this.calendar(client, credentials, job.target?.id ?? "").then((calendar) => {
|
|
69333
69505
|
this.assertResource(calendar.id, input.id ?? "");
|
|
69334
69506
|
const generated = buildICalendar(input);
|
|
69335
|
-
|
|
69507
|
+
let uid = generated.uid;
|
|
69508
|
+
return client.update(input.id ?? "", input.etag ?? "", (stored) => {
|
|
69509
|
+
const patched = patchICalendar(stored, input, generated.body);
|
|
69510
|
+
uid = patched.uid;
|
|
69511
|
+
return patched.body;
|
|
69512
|
+
}).then((updated) => ({ updated, uid }));
|
|
69336
69513
|
}).then(({ updated, uid }) => done(null, this.mutationResponse(job, "update", updated.id, input.type, uid, updated.etag))).catch((error) => this.fail(job, error, done, credentials)).finally(() => client.close().catch(() => {}));
|
|
69337
69514
|
}
|
|
69338
69515
|
delete(job, credentials, done) {
|
|
@@ -69461,4 +69638,4 @@ export {
|
|
|
69461
69638
|
foldLine
|
|
69462
69639
|
};
|
|
69463
69640
|
|
|
69464
|
-
//# debugId=
|
|
69641
|
+
//# debugId=0BA1D0264BEB87B464756E2164756E21
|