@miguelarios/pim-core 0.4.1 → 0.6.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/dist/ics/_shared.d.ts +11 -0
- package/dist/ics/_shared.d.ts.map +1 -0
- package/dist/ics/_shared.js +150 -0
- package/dist/ics/_shared.js.map +1 -0
- package/dist/ics/_tz-init.d.ts +2 -0
- package/dist/ics/_tz-init.d.ts.map +1 -0
- package/dist/ics/_tz-init.js +29 -0
- package/dist/ics/_tz-init.js.map +1 -0
- package/dist/ics/components.d.ts +26 -0
- package/dist/ics/components.d.ts.map +1 -0
- package/dist/ics/components.js +178 -0
- package/dist/ics/components.js.map +1 -0
- package/dist/ics/errors.d.ts +7 -0
- package/dist/ics/errors.d.ts.map +1 -0
- package/dist/ics/errors.js +13 -0
- package/dist/ics/errors.js.map +1 -0
- package/dist/ics/generate.d.ts +4 -0
- package/dist/ics/generate.d.ts.map +1 -0
- package/dist/ics/generate.js +101 -0
- package/dist/ics/generate.js.map +1 -0
- package/dist/ics/index.d.ts +11 -0
- package/dist/ics/index.d.ts.map +1 -0
- package/dist/ics/index.js +12 -0
- package/dist/ics/index.js.map +1 -0
- package/dist/ics/parse-events.d.ts +4 -0
- package/dist/ics/parse-events.d.ts.map +1 -0
- package/dist/ics/parse-events.js +223 -0
- package/dist/ics/parse-events.js.map +1 -0
- package/dist/ics/parse-journals.d.ts +4 -0
- package/dist/ics/parse-journals.d.ts.map +1 -0
- package/dist/ics/parse-journals.js +54 -0
- package/dist/ics/parse-journals.js.map +1 -0
- package/dist/ics/parse-todos.d.ts +4 -0
- package/dist/ics/parse-todos.d.ts.map +1 -0
- package/dist/ics/parse-todos.js +55 -0
- package/dist/ics/parse-todos.js.map +1 -0
- package/dist/ics/rrule.d.ts +2 -0
- package/dist/ics/rrule.d.ts.map +1 -0
- package/dist/ics/rrule.js +23 -0
- package/dist/ics/rrule.js.map +1 -0
- package/dist/ics/types.d.ts +100 -0
- package/dist/ics/types.d.ts.map +1 -0
- package/dist/ics/types.js +3 -0
- package/dist/ics/types.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/vcard.d.ts +16 -0
- package/dist/vcard.d.ts.map +1 -1
- package/dist/vcard.js +143 -20
- package/dist/vcard.js.map +1 -1
- package/package.json +7 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import ICAL from "ical.js";
|
|
2
|
+
import type { ParsedAlarm, ParsedAttendee, ParsedGeo, ParsedOrganizer } from "./types.js";
|
|
3
|
+
export declare function parseAttendees(component: ICAL.Component): ParsedAttendee[];
|
|
4
|
+
export declare function parseOrganizer(component: ICAL.Component): ParsedOrganizer | null;
|
|
5
|
+
export declare function parseCategories(component: ICAL.Component): string[];
|
|
6
|
+
export declare function parseGeo(component: ICAL.Component): ParsedGeo | null;
|
|
7
|
+
export declare function parseDurationToSeconds(duration: string): number;
|
|
8
|
+
export declare function formatTriggerHuman(seconds: number): string;
|
|
9
|
+
export declare function parseAlarms(component: ICAL.Component): ParsedAlarm[];
|
|
10
|
+
export declare function timeToIso(time: ICAL.Time): string;
|
|
11
|
+
//# sourceMappingURL=_shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../src/ics/_shared.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAa1F,wBAAgB,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,GAAG,cAAc,EAAE,CAsB1E;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,GAAG,eAAe,GAAG,IAAI,CAShF;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,GAAG,MAAM,EAAE,CAUnE;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,GAAG,SAAS,GAAG,IAAI,CAepE;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgB/D;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAe1D;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,GAAG,WAAW,EAAE,CAwBpE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,MAAM,CAKjD"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import ICAL from "ical.js";
|
|
2
|
+
const CUTYPE_MAP = {
|
|
3
|
+
INDIVIDUAL: "person",
|
|
4
|
+
ROOM: "room",
|
|
5
|
+
RESOURCE: "resource",
|
|
6
|
+
GROUP: "group",
|
|
7
|
+
};
|
|
8
|
+
function stripMailto(value) {
|
|
9
|
+
return value.replace(/^mailto:/i, "");
|
|
10
|
+
}
|
|
11
|
+
export function parseAttendees(component) {
|
|
12
|
+
const properties = component.getAllProperties("attendee");
|
|
13
|
+
return properties.map((prop) => {
|
|
14
|
+
const value = prop.getFirstValue();
|
|
15
|
+
const email = typeof value === "string" ? stripMailto(value) : "";
|
|
16
|
+
const cnRaw = prop.getParameter("cn");
|
|
17
|
+
const cn = typeof cnRaw === "string" ? cnRaw : null;
|
|
18
|
+
const partstatRaw = prop.getParameter("partstat");
|
|
19
|
+
const partstat = typeof partstatRaw === "string" ? partstatRaw : undefined;
|
|
20
|
+
const roleRaw = prop.getParameter("role");
|
|
21
|
+
const role = typeof roleRaw === "string" ? roleRaw : undefined;
|
|
22
|
+
const cutypeRaw = prop.getParameter("cutype");
|
|
23
|
+
// RFC 5545 §3.2.3: CUTYPE defaults to INDIVIDUAL when absent.
|
|
24
|
+
const cutype = typeof cutypeRaw === "string" && cutypeRaw.length > 0 ? cutypeRaw : "INDIVIDUAL";
|
|
25
|
+
return {
|
|
26
|
+
email,
|
|
27
|
+
name: cn,
|
|
28
|
+
status: partstat ? partstat.toLowerCase() : null,
|
|
29
|
+
role: role ? role.toLowerCase() : null,
|
|
30
|
+
type: CUTYPE_MAP[cutype] ?? "unknown",
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export function parseOrganizer(component) {
|
|
35
|
+
const prop = component.getFirstProperty("organizer");
|
|
36
|
+
if (!prop)
|
|
37
|
+
return null;
|
|
38
|
+
const value = prop.getFirstValue();
|
|
39
|
+
const email = typeof value === "string" ? stripMailto(value) : "";
|
|
40
|
+
if (!email)
|
|
41
|
+
return null;
|
|
42
|
+
const cnRaw = prop.getParameter("cn");
|
|
43
|
+
const name = typeof cnRaw === "string" ? cnRaw : null;
|
|
44
|
+
return { email, name };
|
|
45
|
+
}
|
|
46
|
+
export function parseCategories(component) {
|
|
47
|
+
const properties = component.getAllProperties("categories");
|
|
48
|
+
const out = [];
|
|
49
|
+
for (const prop of properties) {
|
|
50
|
+
const values = prop.getValues();
|
|
51
|
+
for (const v of values) {
|
|
52
|
+
if (typeof v === "string" && v.length > 0)
|
|
53
|
+
out.push(v);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
export function parseGeo(component) {
|
|
59
|
+
const prop = component.getFirstProperty("geo");
|
|
60
|
+
if (!prop)
|
|
61
|
+
return null;
|
|
62
|
+
const value = prop.getFirstValue();
|
|
63
|
+
if (!Array.isArray(value) || value.length !== 2)
|
|
64
|
+
return null;
|
|
65
|
+
const [lat, lon] = value;
|
|
66
|
+
if (typeof lat !== "number" || typeof lon !== "number")
|
|
67
|
+
return null;
|
|
68
|
+
if (Number.isNaN(lat) || Number.isNaN(lon))
|
|
69
|
+
return null;
|
|
70
|
+
// Reject GEO:; sentinel: ical.js parses `GEO:;` (empty value) as [0, 0]
|
|
71
|
+
// (verified). The 0,0 false-rejection at Gulf-of-Guinea (0°N 0°E) is a known
|
|
72
|
+
// edge case — preferred over surfacing corrupted-GEO data as a real location.
|
|
73
|
+
// If you genuinely need 0,0, a future change can disambiguate by inspecting
|
|
74
|
+
// the raw property string for "GEO:;" vs "GEO:0;0".
|
|
75
|
+
if (lat === 0 && lon === 0)
|
|
76
|
+
return null;
|
|
77
|
+
return { latitude: lat, longitude: lon };
|
|
78
|
+
}
|
|
79
|
+
export function parseDurationToSeconds(duration) {
|
|
80
|
+
const negative = duration.startsWith("-");
|
|
81
|
+
// RFC 5545 §3.3.6: PnW (weeks-only) is mutually exclusive with the date/time form.
|
|
82
|
+
const weekMatch = duration.match(/P(\d+)W$/);
|
|
83
|
+
if (weekMatch) {
|
|
84
|
+
const weeks = Number.parseInt(weekMatch[1], 10);
|
|
85
|
+
return (negative ? -1 : 1) * weeks * 604800;
|
|
86
|
+
}
|
|
87
|
+
const match = duration.match(/P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?/);
|
|
88
|
+
if (!match)
|
|
89
|
+
return 0;
|
|
90
|
+
const days = Number.parseInt(match[1] || "0", 10);
|
|
91
|
+
const hours = Number.parseInt(match[2] || "0", 10);
|
|
92
|
+
const minutes = Number.parseInt(match[3] || "0", 10);
|
|
93
|
+
const seconds = Number.parseInt(match[4] || "0", 10);
|
|
94
|
+
const total = days * 86400 + hours * 3600 + minutes * 60 + seconds;
|
|
95
|
+
return negative ? -total : total;
|
|
96
|
+
}
|
|
97
|
+
export function formatTriggerHuman(seconds) {
|
|
98
|
+
if (seconds === 0)
|
|
99
|
+
return "At time of event";
|
|
100
|
+
const abs = Math.abs(seconds);
|
|
101
|
+
const suffix = seconds < 0 ? "before" : "after";
|
|
102
|
+
const parts = [];
|
|
103
|
+
const days = Math.floor(abs / 86400);
|
|
104
|
+
const hours = Math.floor((abs % 86400) / 3600);
|
|
105
|
+
const minutes = Math.floor((abs % 3600) / 60);
|
|
106
|
+
if (days > 0)
|
|
107
|
+
parts.push(`${days} ${days === 1 ? "day" : "days"}`);
|
|
108
|
+
if (hours > 0)
|
|
109
|
+
parts.push(`${hours} ${hours === 1 ? "hour" : "hours"}`);
|
|
110
|
+
if (minutes > 0)
|
|
111
|
+
parts.push(`${minutes} ${minutes === 1 ? "minute" : "minutes"}`);
|
|
112
|
+
if (parts.length === 0) {
|
|
113
|
+
parts.push(`${abs} ${abs === 1 ? "second" : "seconds"}`);
|
|
114
|
+
}
|
|
115
|
+
return `${parts.join(", ")} ${suffix}`;
|
|
116
|
+
}
|
|
117
|
+
export function parseAlarms(component) {
|
|
118
|
+
const valarms = component.getAllSubcomponents("valarm");
|
|
119
|
+
const out = [];
|
|
120
|
+
for (const valarm of valarms) {
|
|
121
|
+
const triggerProp = valarm.getFirstProperty("trigger");
|
|
122
|
+
if (!triggerProp)
|
|
123
|
+
continue;
|
|
124
|
+
const value = triggerProp.getFirstValue();
|
|
125
|
+
if (value instanceof ICAL.Time) {
|
|
126
|
+
const date = value.toJSDate();
|
|
127
|
+
out.push({
|
|
128
|
+
type: "absolute",
|
|
129
|
+
trigger: date.toISOString(),
|
|
130
|
+
trigger_human: date.toISOString(),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
else if (value instanceof ICAL.Duration) {
|
|
134
|
+
const seconds = value.toSeconds();
|
|
135
|
+
out.push({
|
|
136
|
+
type: "relative",
|
|
137
|
+
trigger: seconds,
|
|
138
|
+
trigger_human: formatTriggerHuman(seconds),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
export function timeToIso(time) {
|
|
145
|
+
// Convert to UTC then to JS Date then to ISO. Floating times resolve as-if-UTC
|
|
146
|
+
// unless the caller is providing context via a viewer timezone (handled at the
|
|
147
|
+
// parse-events layer where the timezone param is known).
|
|
148
|
+
return time.toJSDate().toISOString();
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=_shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_shared.js","sourceRoot":"","sources":["../../src/ics/_shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_tz-init.d.ts","sourceRoot":"","sources":["../../src/ics/_tz-init.ts"],"names":[],"mappings":"AAMA,wBAAgB,mBAAmB,IAAI,IAAI,CAqB1C"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getVtimezone } from "@touch4it/ical-timezones";
|
|
2
|
+
import zones from "@touch4it/ical-timezones/zones.js";
|
|
3
|
+
import ICAL from "ical.js";
|
|
4
|
+
let initialized = false;
|
|
5
|
+
export function initializeTimezones() {
|
|
6
|
+
if (initialized)
|
|
7
|
+
return;
|
|
8
|
+
initialized = true;
|
|
9
|
+
for (const tzid of Object.keys(zones)) {
|
|
10
|
+
if (ICAL.TimezoneService.has(tzid))
|
|
11
|
+
continue;
|
|
12
|
+
const vtimezoneBlock = getVtimezone(tzid);
|
|
13
|
+
if (!vtimezoneBlock || typeof vtimezoneBlock !== "string")
|
|
14
|
+
continue;
|
|
15
|
+
try {
|
|
16
|
+
const root = ICAL.Component.fromString(vtimezoneBlock);
|
|
17
|
+
const vtz = root.getFirstSubcomponent("vtimezone");
|
|
18
|
+
if (vtz) {
|
|
19
|
+
const tz = new ICAL.Timezone({ component: vtz });
|
|
20
|
+
ICAL.TimezoneService.register(tz, tzid);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// Skip any malformed entries silently — vendor data, not user input.
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
initializeTimezones();
|
|
29
|
+
//# sourceMappingURL=_tz-init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_tz-init.js","sourceRoot":"","sources":["../../src/ics/_tz-init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,MAAM,mCAAmC,CAAC;AACtD,OAAO,IAAI,MAAM,SAAS,CAAC;AAE3B,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,MAAM,UAAU,mBAAmB;IACjC,IAAI,WAAW;QAAE,OAAO;IACxB,WAAW,GAAG,IAAI,CAAC;IAEnB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAE7C,MAAM,cAAc,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,cAAc,IAAI,OAAO,cAAc,KAAK,QAAQ;YAAE,SAAS;QAEpE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YACvD,MAAM,GAAG,GAAG,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;YACnD,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;gBACjD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,qEAAqE;QACvE,CAAC;IACH,CAAC;AACH,CAAC;AAED,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import "./_tz-init.js";
|
|
2
|
+
export interface ExceptionOverrides {
|
|
3
|
+
title?: string;
|
|
4
|
+
start?: string;
|
|
5
|
+
end?: string;
|
|
6
|
+
all_day?: boolean;
|
|
7
|
+
location?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
attendees?: Array<{
|
|
10
|
+
email: string;
|
|
11
|
+
}>;
|
|
12
|
+
alarms?: Array<{
|
|
13
|
+
type: "relative" | "absolute";
|
|
14
|
+
trigger: number | string;
|
|
15
|
+
}>;
|
|
16
|
+
categories?: string[];
|
|
17
|
+
organizer?: {
|
|
18
|
+
email: string;
|
|
19
|
+
name?: string | null;
|
|
20
|
+
};
|
|
21
|
+
availability?: "busy" | "free";
|
|
22
|
+
}
|
|
23
|
+
export declare function createExceptionComponent(masterIcs: string, componentType: "vevent" | "vtodo", occurrenceDate: string, overrides: ExceptionOverrides, allDay: boolean): string;
|
|
24
|
+
export declare function combineIcsComponents(masterIcs: string, exceptionComponent: string): string;
|
|
25
|
+
export declare function addExdateToIcs(icsContent: string, occurrenceDate: string, allDay: boolean): string;
|
|
26
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/ics/components.ts"],"names":[],"mappings":"AACA,OAAO,eAAe,CAAC;AAIvB,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACpD,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC;AAUD,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,QAAQ,GAAG,OAAO,EACjC,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,kBAAkB,EAC7B,MAAM,EAAE,OAAO,GACd,MAAM,CAoGR;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAyC1F;AAED,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,OAAO,GACd,MAAM,CAiCR"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import ICAL from "ical.js";
|
|
2
|
+
import "./_tz-init.js";
|
|
3
|
+
import { parseAttendees, parseCategories, parseOrganizer } from "./_shared.js";
|
|
4
|
+
import { IcsParseError } from "./errors.js";
|
|
5
|
+
function parseRoot(ics) {
|
|
6
|
+
try {
|
|
7
|
+
return ICAL.Component.fromString(ics);
|
|
8
|
+
}
|
|
9
|
+
catch (e) {
|
|
10
|
+
throw new IcsParseError("Invalid ICS content", e);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function createExceptionComponent(masterIcs, componentType, occurrenceDate, overrides, allDay) {
|
|
14
|
+
const masterRoot = parseRoot(masterIcs);
|
|
15
|
+
const masterComp = masterRoot.getFirstSubcomponent(componentType);
|
|
16
|
+
if (!masterComp)
|
|
17
|
+
throw new IcsParseError(`No ${componentType} found in master ICS`, null);
|
|
18
|
+
// Read fields directly from the already-parsed component instead of running a
|
|
19
|
+
// second full pass through parseIcsEvents.
|
|
20
|
+
const rawUid = masterComp.getFirstPropertyValue("uid");
|
|
21
|
+
const uid = typeof rawUid === "string" ? rawUid : "";
|
|
22
|
+
const masterDtstart = masterComp.getFirstPropertyValue("dtstart");
|
|
23
|
+
const masterDtend = masterComp.getFirstPropertyValue("dtend");
|
|
24
|
+
const masterStartMs = masterDtstart instanceof ICAL.Time ? masterDtstart.toJSDate().getTime() : 0;
|
|
25
|
+
const masterEndMs = masterDtend instanceof ICAL.Time ? masterDtend.toJSDate().getTime() : 0;
|
|
26
|
+
const duration = masterEndMs - masterStartMs;
|
|
27
|
+
const occMs = new Date(occurrenceDate).getTime();
|
|
28
|
+
const defaultStart = new Date(occMs).toISOString();
|
|
29
|
+
const defaultEnd = new Date(occMs + duration).toISOString();
|
|
30
|
+
const rawSummary = masterComp.getFirstPropertyValue("summary");
|
|
31
|
+
const masterTitle = typeof rawSummary === "string" ? rawSummary : "";
|
|
32
|
+
const rawLocation = masterComp.getFirstPropertyValue("location");
|
|
33
|
+
const masterLocation = typeof rawLocation === "string" && rawLocation.length > 0 ? rawLocation : null;
|
|
34
|
+
const rawDescription = masterComp.getFirstPropertyValue("description");
|
|
35
|
+
const masterDescription = typeof rawDescription === "string" && rawDescription.length > 0 ? rawDescription : null;
|
|
36
|
+
const masterOrganizer = parseOrganizer(masterComp);
|
|
37
|
+
const masterAttendees = parseAttendees(masterComp);
|
|
38
|
+
const masterCategories = parseCategories(masterComp);
|
|
39
|
+
const masterTransp = masterComp.getFirstPropertyValue("transp");
|
|
40
|
+
let masterAvailability = null;
|
|
41
|
+
if (typeof masterTransp === "string") {
|
|
42
|
+
if (masterTransp.toUpperCase() === "OPAQUE")
|
|
43
|
+
masterAvailability = "busy";
|
|
44
|
+
else if (masterTransp.toUpperCase() === "TRANSPARENT")
|
|
45
|
+
masterAvailability = "free";
|
|
46
|
+
}
|
|
47
|
+
const ex = new ICAL.Component(componentType);
|
|
48
|
+
ex.updatePropertyWithValue("uid", uid);
|
|
49
|
+
const recurId = ICAL.Time.fromJSDate(new Date(occurrenceDate), true);
|
|
50
|
+
if (allDay)
|
|
51
|
+
recurId.isDate = true;
|
|
52
|
+
const recurProp = ex.updatePropertyWithValue("recurrence-id", recurId);
|
|
53
|
+
if (allDay)
|
|
54
|
+
recurProp.setParameter("value", "DATE");
|
|
55
|
+
const startIso = overrides.start ?? defaultStart;
|
|
56
|
+
const endIso = overrides.end ?? defaultEnd;
|
|
57
|
+
const isAllDay = overrides.all_day ?? allDay;
|
|
58
|
+
const dtstart = ICAL.Time.fromJSDate(new Date(startIso), true);
|
|
59
|
+
if (isAllDay)
|
|
60
|
+
dtstart.isDate = true;
|
|
61
|
+
const dtstartProp = ex.updatePropertyWithValue("dtstart", dtstart);
|
|
62
|
+
if (isAllDay)
|
|
63
|
+
dtstartProp.setParameter("value", "DATE");
|
|
64
|
+
const dtend = ICAL.Time.fromJSDate(new Date(endIso), true);
|
|
65
|
+
if (isAllDay)
|
|
66
|
+
dtend.isDate = true;
|
|
67
|
+
const dtendProp = ex.updatePropertyWithValue("dtend", dtend);
|
|
68
|
+
if (isAllDay)
|
|
69
|
+
dtendProp.setParameter("value", "DATE");
|
|
70
|
+
// SEQUENCE: bump master's
|
|
71
|
+
const masterSeq = masterComp.getFirstPropertyValue("sequence");
|
|
72
|
+
const seq = (typeof masterSeq === "number" ? masterSeq : 0) + 1;
|
|
73
|
+
ex.updatePropertyWithValue("sequence", seq);
|
|
74
|
+
ex.updatePropertyWithValue("summary", overrides.title ?? masterTitle);
|
|
75
|
+
if (overrides.location ?? masterLocation) {
|
|
76
|
+
ex.updatePropertyWithValue("location", overrides.location ?? masterLocation ?? "");
|
|
77
|
+
}
|
|
78
|
+
if (overrides.description ?? masterDescription) {
|
|
79
|
+
ex.updatePropertyWithValue("description", overrides.description ?? masterDescription ?? "");
|
|
80
|
+
}
|
|
81
|
+
const organizer = overrides.organizer ?? masterOrganizer;
|
|
82
|
+
if (organizer) {
|
|
83
|
+
const name = organizer.name && organizer.name.trim().length > 0
|
|
84
|
+
? organizer.name
|
|
85
|
+
: organizer.email.split("@")[0];
|
|
86
|
+
const orgProp = ex.updatePropertyWithValue("organizer", `mailto:${organizer.email}`);
|
|
87
|
+
orgProp.setParameter("cn", name);
|
|
88
|
+
}
|
|
89
|
+
const attendees = overrides.attendees ?? masterAttendees;
|
|
90
|
+
if (attendees) {
|
|
91
|
+
for (const att of attendees) {
|
|
92
|
+
ex.addPropertyWithValue("attendee", `mailto:${att.email}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const categories = overrides.categories ?? masterCategories;
|
|
96
|
+
if (categories && categories.length > 0) {
|
|
97
|
+
ex.addPropertyWithValue("categories", categories.join(","));
|
|
98
|
+
}
|
|
99
|
+
const availability = overrides.availability ?? masterAvailability;
|
|
100
|
+
if (availability === "free")
|
|
101
|
+
ex.updatePropertyWithValue("transp", "TRANSPARENT");
|
|
102
|
+
else if (availability === "busy")
|
|
103
|
+
ex.updatePropertyWithValue("transp", "OPAQUE");
|
|
104
|
+
ex.updatePropertyWithValue("status", "CONFIRMED");
|
|
105
|
+
return ex.toString();
|
|
106
|
+
}
|
|
107
|
+
export function combineIcsComponents(masterIcs, exceptionComponent) {
|
|
108
|
+
const masterRoot = parseRoot(masterIcs);
|
|
109
|
+
// Guard against double-wrap: callers should pass a bare BEGIN:VEVENT…END:VEVENT
|
|
110
|
+
// block (the output of createExceptionComponent), not a full VCALENDAR.
|
|
111
|
+
if (/BEGIN:VCALENDAR/i.test(exceptionComponent)) {
|
|
112
|
+
throw new IcsParseError("exceptionComponent must be a bare VEVENT/VTODO block, not a full VCALENDAR", null);
|
|
113
|
+
}
|
|
114
|
+
// Wrap the bare exception VEVENT/VTODO in a synthetic VCALENDAR so it can be parsed.
|
|
115
|
+
const wrapped = `BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//pim-core//combine//EN\r\n${exceptionComponent}\r\nEND:VCALENDAR`;
|
|
116
|
+
const exRoot = parseRoot(wrapped);
|
|
117
|
+
const exComp = exRoot.getFirstSubcomponent("vevent") ?? exRoot.getFirstSubcomponent("vtodo");
|
|
118
|
+
if (!exComp)
|
|
119
|
+
throw new IcsParseError("Exception component is not a VEVENT or VTODO", null);
|
|
120
|
+
const exUid = exComp.getFirstPropertyValue("uid");
|
|
121
|
+
const exRecurId = exComp.getFirstPropertyValue("recurrence-id");
|
|
122
|
+
if (!(exRecurId instanceof ICAL.Time)) {
|
|
123
|
+
throw new IcsParseError("Exception component must have a RECURRENCE-ID", null);
|
|
124
|
+
}
|
|
125
|
+
const exRecurMs = exRecurId.toJSDate().getTime();
|
|
126
|
+
const componentName = exComp.name;
|
|
127
|
+
// Find and remove any existing matching subcomponent.
|
|
128
|
+
const existing = masterRoot.getAllSubcomponents(componentName);
|
|
129
|
+
for (const sub of existing) {
|
|
130
|
+
const subUid = sub.getFirstPropertyValue("uid");
|
|
131
|
+
const subRecur = sub.getFirstPropertyValue("recurrence-id");
|
|
132
|
+
if (subUid === exUid &&
|
|
133
|
+
subRecur instanceof ICAL.Time &&
|
|
134
|
+
subRecur.toJSDate().getTime() === exRecurMs) {
|
|
135
|
+
masterRoot.removeSubcomponent(sub);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
masterRoot.addSubcomponent(exComp);
|
|
139
|
+
return masterRoot.toString();
|
|
140
|
+
}
|
|
141
|
+
export function addExdateToIcs(icsContent, occurrenceDate, allDay) {
|
|
142
|
+
const root = parseRoot(icsContent);
|
|
143
|
+
// EXDATE goes on the master event (first VEVENT without a RECURRENCE-ID).
|
|
144
|
+
const masters = root
|
|
145
|
+
.getAllSubcomponents("vevent")
|
|
146
|
+
.filter((c) => !c.getFirstProperty("recurrence-id"));
|
|
147
|
+
const master = masters[0];
|
|
148
|
+
if (!master)
|
|
149
|
+
return icsContent;
|
|
150
|
+
const newDate = ICAL.Time.fromJSDate(new Date(occurrenceDate), true);
|
|
151
|
+
if (allDay)
|
|
152
|
+
newDate.isDate = true;
|
|
153
|
+
const newMs = newDate.toJSDate().getTime();
|
|
154
|
+
const newYmd = `${newDate.year}-${String(newDate.month).padStart(2, "0")}-${String(newDate.day).padStart(2, "0")}`;
|
|
155
|
+
// Idempotency check: scan existing EXDATE values. For all-day (DATE-typed)
|
|
156
|
+
// EXDATEs compare YYYY-MM-DD strings — toJSDate() on a date-only value uses
|
|
157
|
+
// local-midnight which can drift across DST boundaries vs. the new value's
|
|
158
|
+
// UTC-midnight epoch ms. For date-time EXDATEs the epoch comparison works.
|
|
159
|
+
for (const exProp of master.getAllProperties("exdate")) {
|
|
160
|
+
for (const v of exProp.getValues()) {
|
|
161
|
+
if (!(v instanceof ICAL.Time))
|
|
162
|
+
continue;
|
|
163
|
+
if (allDay && v.isDate) {
|
|
164
|
+
const vYmd = `${v.year}-${String(v.month).padStart(2, "0")}-${String(v.day).padStart(2, "0")}`;
|
|
165
|
+
if (vYmd === newYmd)
|
|
166
|
+
return icsContent;
|
|
167
|
+
}
|
|
168
|
+
else if (!allDay && !v.isDate && v.toJSDate().getTime() === newMs) {
|
|
169
|
+
return icsContent;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const exProp = master.addPropertyWithValue("exdate", newDate);
|
|
174
|
+
if (allDay)
|
|
175
|
+
exProp.setParameter("value", "DATE");
|
|
176
|
+
return root.toString();
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.js","sourceRoot":"","sources":["../../src/ics/components.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/ics/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAI5C;AAED,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAI5C"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class IcsParseError extends Error {
|
|
2
|
+
constructor(message, cause) {
|
|
3
|
+
super(message, { cause });
|
|
4
|
+
this.name = "IcsParseError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export class IcsGenerateError extends Error {
|
|
8
|
+
constructor(message, cause) {
|
|
9
|
+
super(message, { cause });
|
|
10
|
+
this.name = "IcsGenerateError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/ics/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe,EAAE,KAAc;QACzC,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YAAY,OAAe,EAAE,KAAc;QACzC,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/ics/generate.ts"],"names":[],"mappings":"AAGA,OAAO,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAoBnD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAqFhE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// packages/core/src/ics/generate.ts
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import ICAL from "ical.js";
|
|
4
|
+
import "./_tz-init.js";
|
|
5
|
+
import { IcsGenerateError } from "./errors.js";
|
|
6
|
+
import { normalizeRecurrenceRule } from "./rrule.js";
|
|
7
|
+
function toIcalTime(iso, allDay, tzid) {
|
|
8
|
+
const date = new Date(iso);
|
|
9
|
+
if (Number.isNaN(date.getTime())) {
|
|
10
|
+
throw new IcsGenerateError(`Invalid ISO date: ${iso}`, null);
|
|
11
|
+
}
|
|
12
|
+
if (allDay) {
|
|
13
|
+
return ICAL.Time.fromDateString(date.toISOString().slice(0, 10));
|
|
14
|
+
}
|
|
15
|
+
if (tzid) {
|
|
16
|
+
const zone = ICAL.TimezoneService.get(tzid);
|
|
17
|
+
if (zone) {
|
|
18
|
+
const utc = ICAL.Time.fromJSDate(date, true);
|
|
19
|
+
return utc.convertToZone(zone);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return ICAL.Time.fromJSDate(date, true);
|
|
23
|
+
}
|
|
24
|
+
export function generateEventIcs(props) {
|
|
25
|
+
if (props.attendees && props.attendees.length > 0 && !props.organizer) {
|
|
26
|
+
throw new IcsGenerateError("ORGANIZER is required when ATTENDEE is present (RFC 6638)", null);
|
|
27
|
+
}
|
|
28
|
+
const calendar = new ICAL.Component(["vcalendar", [], []]);
|
|
29
|
+
calendar.updatePropertyWithValue("prodid", "-//pim-core//cal-mcp//EN");
|
|
30
|
+
calendar.updatePropertyWithValue("version", "2.0");
|
|
31
|
+
if (props.timezone) {
|
|
32
|
+
const zone = ICAL.TimezoneService.get(props.timezone);
|
|
33
|
+
if (zone?.component) {
|
|
34
|
+
calendar.addSubcomponent(zone.component);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const vevent = new ICAL.Component("vevent");
|
|
38
|
+
const uid = props.uid ?? `${randomUUID()}@pim-core`;
|
|
39
|
+
vevent.updatePropertyWithValue("uid", uid);
|
|
40
|
+
vevent.updatePropertyWithValue("dtstamp", ICAL.Time.now());
|
|
41
|
+
vevent.updatePropertyWithValue("summary", props.title);
|
|
42
|
+
vevent.updatePropertyWithValue("status", "CONFIRMED");
|
|
43
|
+
const allDay = props.all_day === true;
|
|
44
|
+
const dtstart = toIcalTime(props.start, allDay, props.timezone);
|
|
45
|
+
const dtend = toIcalTime(props.end, allDay, props.timezone);
|
|
46
|
+
const dtstartProp = vevent.updatePropertyWithValue("dtstart", dtstart);
|
|
47
|
+
const dtendProp = vevent.updatePropertyWithValue("dtend", dtend);
|
|
48
|
+
if (props.timezone && !allDay) {
|
|
49
|
+
dtstartProp.setParameter("tzid", props.timezone);
|
|
50
|
+
dtendProp.setParameter("tzid", props.timezone);
|
|
51
|
+
}
|
|
52
|
+
if (props.location)
|
|
53
|
+
vevent.updatePropertyWithValue("location", props.location);
|
|
54
|
+
if (props.description)
|
|
55
|
+
vevent.updatePropertyWithValue("description", props.description);
|
|
56
|
+
if (props.availability === "free")
|
|
57
|
+
vevent.updatePropertyWithValue("transp", "TRANSPARENT");
|
|
58
|
+
else if (props.availability === "busy")
|
|
59
|
+
vevent.updatePropertyWithValue("transp", "OPAQUE");
|
|
60
|
+
if (props.organizer) {
|
|
61
|
+
const name = props.organizer.name && props.organizer.name.trim().length > 0
|
|
62
|
+
? props.organizer.name
|
|
63
|
+
: props.organizer.email.split("@")[0];
|
|
64
|
+
const orgProp = vevent.updatePropertyWithValue("organizer", `mailto:${props.organizer.email}`);
|
|
65
|
+
orgProp.setParameter("cn", name);
|
|
66
|
+
}
|
|
67
|
+
if (props.attendees) {
|
|
68
|
+
for (const att of props.attendees) {
|
|
69
|
+
vevent.addPropertyWithValue("attendee", `mailto:${att.email}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (props.categories && props.categories.length > 0) {
|
|
73
|
+
vevent.addPropertyWithValue("categories", props.categories.join(","));
|
|
74
|
+
}
|
|
75
|
+
if (props.recurrence_rule) {
|
|
76
|
+
const normalized = normalizeRecurrenceRule(props.recurrence_rule);
|
|
77
|
+
if (!normalized) {
|
|
78
|
+
throw new IcsGenerateError(`Invalid recurrence_rule: ${props.recurrence_rule}`, null);
|
|
79
|
+
}
|
|
80
|
+
vevent.addProperty(ICAL.Property.fromString(`RRULE:${normalized}`));
|
|
81
|
+
}
|
|
82
|
+
if (props.alarms) {
|
|
83
|
+
for (const alarm of props.alarms) {
|
|
84
|
+
const valarm = new ICAL.Component("valarm");
|
|
85
|
+
valarm.updatePropertyWithValue("action", "DISPLAY");
|
|
86
|
+
valarm.updatePropertyWithValue("description", props.title);
|
|
87
|
+
if (alarm.type === "relative" && typeof alarm.trigger === "number") {
|
|
88
|
+
const dur = ICAL.Duration.fromSeconds(alarm.trigger);
|
|
89
|
+
valarm.updatePropertyWithValue("trigger", dur);
|
|
90
|
+
}
|
|
91
|
+
else if (alarm.type === "absolute" && typeof alarm.trigger === "string") {
|
|
92
|
+
const t = ICAL.Time.fromJSDate(new Date(alarm.trigger), true);
|
|
93
|
+
valarm.updatePropertyWithValue("trigger", t);
|
|
94
|
+
}
|
|
95
|
+
vevent.addSubcomponent(valarm);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
calendar.addSubcomponent(vevent);
|
|
99
|
+
return calendar.toString();
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/ics/generate.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAGrD,SAAS,UAAU,CAAC,GAAW,EAAE,MAAe,EAAE,IAAa;IAC7D,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,gBAAgB,CAAC,qBAAqB,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC7C,OAAO,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAuB;IACtD,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACtE,MAAM,IAAI,gBAAgB,CAAC,2DAA2D,EAAE,IAAI,CAAC,CAAC;IAChG,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,uBAAuB,CAAC,QAAQ,EAAE,0BAA0B,CAAC,CAAC;IACvE,QAAQ,CAAC,uBAAuB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAEnD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtD,IAAI,IAAI,EAAE,SAAS,EAAE,CAAC;YACpB,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAE5C,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,GAAG,UAAU,EAAE,WAAW,CAAC;IACpD,MAAM,CAAC,uBAAuB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC3C,MAAM,CAAC,uBAAuB,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3D,MAAM,CAAC,uBAAuB,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACvD,MAAM,CAAC,uBAAuB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC;IACtC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,MAAM,CAAC,uBAAuB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,MAAM,CAAC,uBAAuB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACjE,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9B,WAAW,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjD,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ;QAAE,MAAM,CAAC,uBAAuB,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/E,IAAI,KAAK,CAAC,WAAW;QAAE,MAAM,CAAC,uBAAuB,CAAC,aAAa,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAExF,IAAI,KAAK,CAAC,YAAY,KAAK,MAAM;QAAE,MAAM,CAAC,uBAAuB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;SACtF,IAAI,KAAK,CAAC,YAAY,KAAK,MAAM;QAAE,MAAM,CAAC,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAE3F,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,GACR,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;YAC5D,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI;YACtB,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,uBAAuB,CAAC,WAAW,EAAE,UAAU,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/F,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAClC,MAAM,CAAC,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,MAAM,CAAC,oBAAoB,CAAC,YAAY,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,uBAAuB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAClE,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,gBAAgB,CAAC,4BAA4B,KAAK,CAAC,eAAe,EAAE,EAAE,IAAI,CAAC,CAAC;QACxF,CAAC;QACD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,CAAC,uBAAuB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;YACpD,MAAM,CAAC,uBAAuB,CAAC,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3D,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACnE,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACrD,MAAM,CAAC,uBAAuB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YACjD,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC1E,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;gBAC9D,MAAM,CAAC,uBAAuB,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YAC/C,CAAC;YACD,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,QAAQ,CAAC,QAAQ,EAAE,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import "./_tz-init.js";
|
|
2
|
+
export { IcsParseError, IcsGenerateError } from "./errors.js";
|
|
3
|
+
export type { ParsedAlarm, ParsedAttendee, ParsedOrganizer, ParsedGeo, ParsedEvent, ParsedTodo, ParsedJournal, TimeRange, EventCreateProps, } from "./types.js";
|
|
4
|
+
export { normalizeRecurrenceRule } from "./rrule.js";
|
|
5
|
+
export { parseIcsEvents } from "./parse-events.js";
|
|
6
|
+
export { parseIcsTodos } from "./parse-todos.js";
|
|
7
|
+
export { parseIcsJournals } from "./parse-journals.js";
|
|
8
|
+
export { generateEventIcs } from "./generate.js";
|
|
9
|
+
export { createExceptionComponent, combineIcsComponents, addExdateToIcs, } from "./components.js";
|
|
10
|
+
export type { ExceptionOverrides } from "./components.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ics/index.ts"],"names":[],"mappings":"AAGA,OAAO,eAAe,CAAC;AAEvB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EACV,WAAW,EACX,cAAc,EACd,eAAe,EACf,SAAS,EACT,WAAW,EACX,UAAU,EACV,aAAa,EACb,SAAS,EACT,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Side-effect import: registers the IANA timezone set with ICAL.TimezoneService
|
|
2
|
+
// at module load. Consumers of @miguelarios/pim-core/ics get tz resolution wired
|
|
3
|
+
// up by virtue of importing from this barrel.
|
|
4
|
+
import "./_tz-init.js";
|
|
5
|
+
export { IcsParseError, IcsGenerateError } from "./errors.js";
|
|
6
|
+
export { normalizeRecurrenceRule } from "./rrule.js";
|
|
7
|
+
export { parseIcsEvents } from "./parse-events.js";
|
|
8
|
+
export { parseIcsTodos } from "./parse-todos.js";
|
|
9
|
+
export { parseIcsJournals } from "./parse-journals.js";
|
|
10
|
+
export { generateEventIcs } from "./generate.js";
|
|
11
|
+
export { createExceptionComponent, combineIcsComponents, addExdateToIcs, } from "./components.js";
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ics/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,iFAAiF;AACjF,8CAA8C;AAC9C,OAAO,eAAe,CAAC;AAEvB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAY9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,cAAc,GACf,MAAM,iBAAiB,CAAC"}
|