@vicacha-devs/strapi-plugin-events 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +121 -2
- package/dist/admin/CalendarPage-CwCvPDRx.js +1215 -0
- package/dist/admin/CalendarPage-Dz7g19qp.mjs +1215 -0
- package/dist/admin/RRuleInput-BQl-siRj.js +11 -0
- package/dist/admin/RRuleInput-C8bR37X9.mjs +6 -0
- package/dist/admin/SettingsPage-CNG9AEO_.mjs +415 -0
- package/dist/admin/SettingsPage-DhjtKDmY.js +415 -0
- package/dist/admin/ar-mMKUXxch.js +216 -0
- package/dist/admin/ar-tWKEvJLB.mjs +216 -0
- package/dist/admin/de-CGk8UZ3W.js +216 -0
- package/dist/admin/de-OdbJEFs0.mjs +216 -0
- package/dist/admin/en-Dskn9ZPa.mjs +216 -0
- package/dist/admin/en-imdSlLhJ.js +216 -0
- package/dist/admin/es-DcMsMHrI.mjs +216 -0
- package/dist/admin/es-DkqqxUJQ.js +216 -0
- package/dist/admin/fr-BTEIPOFw.mjs +216 -0
- package/dist/admin/fr-D92B_ZTv.js +216 -0
- package/dist/admin/index-BTq_X4uT.js +1005 -0
- package/dist/admin/index-BatOiwBu.mjs +1006 -0
- package/dist/admin/index.js +6 -0
- package/dist/admin/index.mjs +6 -0
- package/dist/admin/it-CAxPpL_9.mjs +216 -0
- package/dist/admin/it-ClKaSCgv.js +216 -0
- package/dist/admin/nl-CS1aUfT7.mjs +216 -0
- package/dist/admin/nl-F6FIi7zw.js +216 -0
- package/dist/admin/pl-BfmBU9FW.mjs +216 -0
- package/dist/admin/pl-p8VLXi02.js +216 -0
- package/dist/admin/pt-BUdH0uSw.js +216 -0
- package/dist/admin/pt-DdulKcbk.mjs +216 -0
- package/dist/admin/src/components/EventSidePanel.d.ts +13 -0
- package/dist/admin/src/components/Initializer.d.ts +5 -0
- package/dist/admin/src/components/PluginIcon.d.ts +2 -0
- package/dist/admin/src/components/RRuleInput.d.ts +3 -0
- package/dist/admin/src/components/events/AttendeesManagerPanel.d.ts +15 -0
- package/dist/admin/src/components/events/EventsDirectoryPanel.d.ts +11 -0
- package/dist/admin/src/components/events/EventsKpiCards.d.ts +16 -0
- package/dist/admin/src/components/events/QuickCreateEventPanel.d.ts +21 -0
- package/dist/admin/src/components/events/calendarPageHelpers.d.ts +8 -0
- package/dist/admin/src/fields/rruleField.d.ts +41 -0
- package/dist/admin/src/index.d.ts +15 -0
- package/dist/admin/src/pages/CalendarPage.d.ts +3 -0
- package/dist/admin/src/pages/SettingsPage.d.ts +3 -0
- package/dist/admin/src/permissions.d.ts +15 -0
- package/dist/admin/src/translations/cmLabels.d.ts +1 -0
- package/dist/admin/src/translations/cmPlaceholders.d.ts +1 -0
- package/dist/admin/tr-Bp50qvL8.mjs +216 -0
- package/dist/admin/tr-C7G9mPtg.js +216 -0
- package/dist/server/index.js +3709 -0
- package/dist/server/index.mjs +3705 -0
- package/dist/server/src/bootstrap.d.ts +5 -0
- package/dist/server/src/config/index.d.ts +7 -0
- package/dist/server/src/content-types/event/schema.json.d.ts +279 -0
- package/dist/server/src/content-types/index.d.ts +366 -0
- package/dist/server/src/content-types/registration/schema.json.d.ts +86 -0
- package/dist/server/src/controllers/admin.d.ts +17 -0
- package/dist/server/src/controllers/content-api.d.ts +14 -0
- package/dist/server/src/controllers/index.d.ts +28 -0
- package/dist/server/src/destroy.d.ts +5 -0
- package/dist/server/src/index.d.ts +551 -0
- package/dist/server/src/middlewares/index.d.ts +2 -0
- package/dist/server/src/policies/index.d.ts +2 -0
- package/dist/server/src/register.d.ts +5 -0
- package/dist/server/src/routes/admin.d.ts +17 -0
- package/dist/server/src/routes/content-api.d.ts +12 -0
- package/dist/server/src/routes/index.d.ts +30 -0
- package/dist/server/src/services/ical.d.ts +18 -0
- package/dist/server/src/services/index.d.ts +110 -0
- package/dist/server/src/services/occurrence.d.ts +44 -0
- package/dist/server/src/services/occurrenceHelpers.d.ts +16 -0
- package/dist/server/src/services/occurrencePayloadHelpers.d.ts +30 -0
- package/dist/server/src/services/occurrenceRsvpBatch.d.ts +25 -0
- package/dist/server/src/services/rsvp.d.ts +51 -0
- package/dist/server/src/services/rsvpHelpers.d.ts +52 -0
- package/dist/server/src/services/rsvpMutations.d.ts +34 -0
- package/dist/server/src/services/rsvpSecurity.d.ts +22 -0
- package/dist/server/src/services/settings.d.ts +10 -0
- package/dist/server/src/types.d.ts +171 -0
- package/dist/shared/calendarSystems.d.ts +6 -0
- package/dist/shared/icalGenerator.d.ts +25 -0
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/index.js +753 -0
- package/dist/shared/index.mjs +727 -0
- package/dist/shared/pluginId.d.ts +4 -0
- package/dist/shared/rruleEngine.d.ts +20 -0
- package/dist/shared/spotlightHelpers.d.ts +17 -0
- package/dist/shared/types.d.ts +309 -0
- package/dist/shared/urlAndPosterHelpers.d.ts +18 -0
- package/package.json +109 -3
|
@@ -0,0 +1,753 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const shared = require("@vicacha-devs/strapi-plugin-calendar/shared");
|
|
4
|
+
const DANGEROUS_OBJECT_KEYS = /* @__PURE__ */ new Set([
|
|
5
|
+
"__proto__",
|
|
6
|
+
"constructor",
|
|
7
|
+
"prototype"
|
|
8
|
+
]);
|
|
9
|
+
function isSafeObjectKey(key) {
|
|
10
|
+
return typeof key === "string" && key.length > 0 && !DANGEROUS_OBJECT_KEYS.has(key);
|
|
11
|
+
}
|
|
12
|
+
function sanitizePlainRecord(raw, maxDepth = 4) {
|
|
13
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw) || maxDepth < 0) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const clean = {};
|
|
17
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
18
|
+
if (!isSafeObjectKey(k)) continue;
|
|
19
|
+
if (v && typeof v === "object" && !Array.isArray(v)) {
|
|
20
|
+
if (maxDepth === 0) continue;
|
|
21
|
+
clean[k] = sanitizePlainRecord(v, maxDepth - 1);
|
|
22
|
+
} else if (Array.isArray(v)) {
|
|
23
|
+
clean[k] = maxDepth === 0 ? [] : v.map(
|
|
24
|
+
(item) => item && typeof item === "object" && !Array.isArray(item) ? sanitizePlainRecord(item, maxDepth - 1) : item
|
|
25
|
+
);
|
|
26
|
+
} else {
|
|
27
|
+
clean[k] = v;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return clean;
|
|
31
|
+
}
|
|
32
|
+
const ALLOWED_ACTION_VARIANTS = /* @__PURE__ */ new Set([
|
|
33
|
+
"primary",
|
|
34
|
+
"secondary",
|
|
35
|
+
"outline"
|
|
36
|
+
]);
|
|
37
|
+
const HTTP_PROTOCOLS = /* @__PURE__ */ new Set(["https:", "http:"]);
|
|
38
|
+
const ACTION_PROTOCOLS = /* @__PURE__ */ new Set(["https:", "http:", "mailto:"]);
|
|
39
|
+
function isSafeRelativeUrl(trimmed) {
|
|
40
|
+
return trimmed.startsWith("/") && !trimmed.startsWith("//") && !trimmed.includes("\\");
|
|
41
|
+
}
|
|
42
|
+
function isAllowedAbsoluteUrl(trimmed, allowMailto) {
|
|
43
|
+
try {
|
|
44
|
+
const parsed = new URL(trimmed);
|
|
45
|
+
const proto = parsed.protocol.toLowerCase();
|
|
46
|
+
return allowMailto ? ACTION_PROTOCOLS.has(proto) : HTTP_PROTOCOLS.has(proto);
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function sanitizeEventUrl(rawUrl, options) {
|
|
52
|
+
if (typeof rawUrl !== "string") return null;
|
|
53
|
+
const trimmed = rawUrl.trim();
|
|
54
|
+
if (!trimmed || trimmed.length > 2048 || /[\u0000-\u001F\u007F]/.test(trimmed)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const allowMailto = options?.allowMailto ?? true;
|
|
58
|
+
if (isSafeRelativeUrl(trimmed) || isAllowedAbsoluteUrl(trimmed, allowMailto)) {
|
|
59
|
+
return trimmed;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
function parseJsonIfNeeded(raw) {
|
|
64
|
+
if (typeof raw !== "string") return raw;
|
|
65
|
+
const trimmed = raw.trim();
|
|
66
|
+
const isJsonLike = trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]");
|
|
67
|
+
if (!isJsonLike) return raw;
|
|
68
|
+
try {
|
|
69
|
+
return JSON.parse(trimmed);
|
|
70
|
+
} catch {
|
|
71
|
+
return raw;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function getTrimmedString(val, maxLen) {
|
|
75
|
+
if (typeof val !== "string") return void 0;
|
|
76
|
+
const trimmed = val.trim();
|
|
77
|
+
if (!trimmed) return void 0;
|
|
78
|
+
return maxLen ? trimmed.slice(0, maxLen) : trimmed;
|
|
79
|
+
}
|
|
80
|
+
function getPositiveInteger(val) {
|
|
81
|
+
if (typeof val !== "number" || !Number.isFinite(val) || val <= 0) {
|
|
82
|
+
return void 0;
|
|
83
|
+
}
|
|
84
|
+
return Math.round(val);
|
|
85
|
+
}
|
|
86
|
+
function unwrapPosterRecord(obj) {
|
|
87
|
+
if (obj.data && typeof obj.data === "object" && !Array.isArray(obj.data)) {
|
|
88
|
+
return unwrapPosterRecord(obj.data);
|
|
89
|
+
}
|
|
90
|
+
if (obj.attributes && typeof obj.attributes === "object" && !Array.isArray(obj.attributes)) {
|
|
91
|
+
return unwrapPosterRecord(obj.attributes);
|
|
92
|
+
}
|
|
93
|
+
return obj;
|
|
94
|
+
}
|
|
95
|
+
function resolvePosterAltText(obj, fallbackAlt) {
|
|
96
|
+
return getTrimmedString(obj.alt) || getTrimmedString(obj.alternativeText) || getTrimmedString(obj.caption) || fallbackAlt || void 0;
|
|
97
|
+
}
|
|
98
|
+
function normalizeEventPoster(rawPoster, fallbackAlt) {
|
|
99
|
+
if (!rawPoster) return void 0;
|
|
100
|
+
if (typeof rawPoster === "string") {
|
|
101
|
+
const safeUrl2 = sanitizeEventUrl(rawPoster, { allowMailto: false });
|
|
102
|
+
return safeUrl2 ? { url: safeUrl2, alt: fallbackAlt || void 0 } : void 0;
|
|
103
|
+
}
|
|
104
|
+
if (Array.isArray(rawPoster)) {
|
|
105
|
+
return rawPoster.length > 0 ? normalizeEventPoster(rawPoster[0], fallbackAlt) : void 0;
|
|
106
|
+
}
|
|
107
|
+
if (typeof rawPoster !== "object") return void 0;
|
|
108
|
+
const obj = unwrapPosterRecord(rawPoster);
|
|
109
|
+
const safeUrl = sanitizeEventUrl(obj.url, { allowMailto: false });
|
|
110
|
+
if (!safeUrl) return void 0;
|
|
111
|
+
return {
|
|
112
|
+
url: safeUrl,
|
|
113
|
+
alt: resolvePosterAltText(obj, fallbackAlt),
|
|
114
|
+
mime: getTrimmedString(obj.mime),
|
|
115
|
+
width: getPositiveInteger(obj.width),
|
|
116
|
+
height: getPositiveInteger(obj.height)
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function resolveActionVariant(rawVariant, index) {
|
|
120
|
+
const candidate = getTrimmedString(rawVariant);
|
|
121
|
+
if (candidate && ALLOWED_ACTION_VARIANTS.has(candidate)) {
|
|
122
|
+
return candidate;
|
|
123
|
+
}
|
|
124
|
+
return index === 0 ? "primary" : "outline";
|
|
125
|
+
}
|
|
126
|
+
function normalizeSingleActionLink(item, index) {
|
|
127
|
+
if (!item || typeof item !== "object") return null;
|
|
128
|
+
const rec = item;
|
|
129
|
+
const label = getTrimmedString(rec.label, 120);
|
|
130
|
+
const safeUrl = sanitizeEventUrl(rec.url);
|
|
131
|
+
if (!label || !safeUrl) return null;
|
|
132
|
+
const external = typeof rec.external === "boolean" ? rec.external : /^https?:\/\//i.test(safeUrl);
|
|
133
|
+
const icon = getTrimmedString(rec.icon, 60);
|
|
134
|
+
return {
|
|
135
|
+
label,
|
|
136
|
+
url: safeUrl,
|
|
137
|
+
variant: resolveActionVariant(rec.variant, index),
|
|
138
|
+
external,
|
|
139
|
+
...icon ? { icon } : {}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function normalizeEventActionLinks(rawLinks) {
|
|
143
|
+
const parsed = parseJsonIfNeeded(rawLinks);
|
|
144
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
145
|
+
return void 0;
|
|
146
|
+
}
|
|
147
|
+
const normalized = parsed.map((item, idx) => normalizeSingleActionLink(item, idx)).filter((link) => link !== null);
|
|
148
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
149
|
+
}
|
|
150
|
+
function isValidCalendarDateKey(dateStr) {
|
|
151
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
const parsed = /* @__PURE__ */ new Date(`${dateStr}T00:00:00.000Z`);
|
|
155
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
return parsed.toISOString().slice(0, 10) === dateStr;
|
|
159
|
+
}
|
|
160
|
+
function toDateKey(dateInput) {
|
|
161
|
+
const d = typeof dateInput === "string" ? new Date(dateInput) : dateInput;
|
|
162
|
+
if (Number.isNaN(d.getTime())) {
|
|
163
|
+
return "";
|
|
164
|
+
}
|
|
165
|
+
return d.toISOString().slice(0, 10);
|
|
166
|
+
}
|
|
167
|
+
function normalizeRRuleString(raw) {
|
|
168
|
+
if (!raw || typeof raw !== "string") {
|
|
169
|
+
return "";
|
|
170
|
+
}
|
|
171
|
+
return raw.replace(/[\u0000-\u001F\u007F]+/g, "").trim().replace(/^RRULE:/i, "").trim();
|
|
172
|
+
}
|
|
173
|
+
function sanitizeOccurrenceOverrides(rawOverrides) {
|
|
174
|
+
const clean = {};
|
|
175
|
+
if (!rawOverrides || typeof rawOverrides !== "object" || Array.isArray(rawOverrides)) {
|
|
176
|
+
return clean;
|
|
177
|
+
}
|
|
178
|
+
for (const [key, ov] of Object.entries(rawOverrides)) {
|
|
179
|
+
if (!isSafeObjectKey(key) || !isValidCalendarDateKey(key)) continue;
|
|
180
|
+
if (!ov || typeof ov !== "object" || Array.isArray(ov)) continue;
|
|
181
|
+
let validStart;
|
|
182
|
+
let startMs = null;
|
|
183
|
+
if (ov.startDate !== void 0 && ov.startDate !== "") {
|
|
184
|
+
if (typeof ov.startDate !== "string") continue;
|
|
185
|
+
const parsedStart = new Date(ov.startDate).getTime();
|
|
186
|
+
if (Number.isNaN(parsedStart)) continue;
|
|
187
|
+
validStart = ov.startDate;
|
|
188
|
+
startMs = parsedStart;
|
|
189
|
+
}
|
|
190
|
+
let validEnd;
|
|
191
|
+
if (ov.endDate !== void 0 && ov.endDate !== "") {
|
|
192
|
+
if (typeof ov.endDate !== "string") continue;
|
|
193
|
+
const parsedEnd = new Date(ov.endDate).getTime();
|
|
194
|
+
if (Number.isNaN(parsedEnd)) continue;
|
|
195
|
+
const minStartMs = startMs ?? (/* @__PURE__ */ new Date(`${key}T00:00:00.000Z`)).getTime();
|
|
196
|
+
if (parsedEnd < minStartMs) continue;
|
|
197
|
+
validEnd = ov.endDate;
|
|
198
|
+
}
|
|
199
|
+
clean[key] = {
|
|
200
|
+
...ov,
|
|
201
|
+
originalDate: typeof ov.originalDate === "string" && isValidCalendarDateKey(ov.originalDate) ? ov.originalDate : key,
|
|
202
|
+
startDate: validStart,
|
|
203
|
+
endDate: validEnd
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
return clean;
|
|
207
|
+
}
|
|
208
|
+
function sanitizeRRuleFieldValue(rec, defaultTimezone = "UTC") {
|
|
209
|
+
const rrule = normalizeRRuleString(rec?.rrule);
|
|
210
|
+
const timezone = typeof rec?.timezone === "string" && rec.timezone.trim() ? rec.timezone.trim() : defaultTimezone;
|
|
211
|
+
const exdates = Array.isArray(rec?.exdates) ? rec.exdates.filter(
|
|
212
|
+
(d) => typeof d === "string" && isValidCalendarDateKey(d)
|
|
213
|
+
) : [];
|
|
214
|
+
const overrides = sanitizeOccurrenceOverrides(rec?.overrides);
|
|
215
|
+
return {
|
|
216
|
+
...rec,
|
|
217
|
+
rrule,
|
|
218
|
+
timezone,
|
|
219
|
+
allDay: Boolean(rec?.allDay),
|
|
220
|
+
exdates,
|
|
221
|
+
overrides
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function parseRRuleFieldValue(raw, defaultTimezone = "UTC") {
|
|
225
|
+
const parsed = shared.parseRRuleFieldValue(raw, defaultTimezone);
|
|
226
|
+
return sanitizeRRuleFieldValue(parsed, defaultTimezone);
|
|
227
|
+
}
|
|
228
|
+
function buildRRule(parsed) {
|
|
229
|
+
return shared.buildRRule({
|
|
230
|
+
freq: parsed.freq ?? "NONE",
|
|
231
|
+
interval: parsed.interval ?? 1,
|
|
232
|
+
byDay: parsed.byDay ?? [],
|
|
233
|
+
byMonthDay: parsed.byMonthDay,
|
|
234
|
+
count: parsed.count,
|
|
235
|
+
until: parsed.until
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
const FREQ_UNITS = {
|
|
239
|
+
DAILY: { singular: "day", plural: "days" },
|
|
240
|
+
WEEKLY: { singular: "week", plural: "weeks" },
|
|
241
|
+
MONTHLY: { singular: "month", plural: "months" },
|
|
242
|
+
YEARLY: { singular: "year", plural: "years" }
|
|
243
|
+
};
|
|
244
|
+
function formatIntervalUnit(freq, interval) {
|
|
245
|
+
const unit = Object.hasOwn(FREQ_UNITS, freq) ? FREQ_UNITS[freq] : FREQ_UNITS.YEARLY;
|
|
246
|
+
return interval === 1 ? unit.singular : `${interval} ${unit.plural}`;
|
|
247
|
+
}
|
|
248
|
+
function describeRRule(rruleString) {
|
|
249
|
+
const parsed = shared.parseRRule(normalizeRRuleString(rruleString));
|
|
250
|
+
if (parsed.freq === "NONE") {
|
|
251
|
+
return "Does not repeat";
|
|
252
|
+
}
|
|
253
|
+
let summary = `Every ${formatIntervalUnit(parsed.freq, parsed.interval)}`;
|
|
254
|
+
if (parsed.freq === "WEEKLY" && parsed.byDay.length > 0) {
|
|
255
|
+
summary += ` on ${parsed.byDay.join(", ")}`;
|
|
256
|
+
} else if (parsed.freq === "MONTHLY" && parsed.byMonthDay) {
|
|
257
|
+
summary += ` on day ${parsed.byMonthDay}`;
|
|
258
|
+
}
|
|
259
|
+
if (parsed.until) {
|
|
260
|
+
summary += ` until ${parsed.until}`;
|
|
261
|
+
} else if (parsed.count) {
|
|
262
|
+
summary += ` (${parsed.count} occurrences)`;
|
|
263
|
+
}
|
|
264
|
+
return summary;
|
|
265
|
+
}
|
|
266
|
+
function expandRuleSlots(options) {
|
|
267
|
+
const baseStartMs = new Date(options.baseStartDate).getTime();
|
|
268
|
+
if (Number.isNaN(baseStartMs)) {
|
|
269
|
+
return [];
|
|
270
|
+
}
|
|
271
|
+
let safeBaseEnd = null;
|
|
272
|
+
if (typeof options.baseEndDate === "string" && options.baseEndDate) {
|
|
273
|
+
const baseEndMs = new Date(options.baseEndDate).getTime();
|
|
274
|
+
if (!Number.isNaN(baseEndMs) && baseEndMs >= baseStartMs) {
|
|
275
|
+
safeBaseEnd = options.baseEndDate;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const windowStartIso = typeof options.windowStart === "string" ? options.windowStart : options.windowStart.toISOString();
|
|
279
|
+
const windowEndIso = typeof options.windowEnd === "string" ? options.windowEnd : options.windowEnd.toISOString();
|
|
280
|
+
if (Number.isNaN(new Date(windowStartIso).getTime()) || Number.isNaN(new Date(windowEndIso).getTime())) {
|
|
281
|
+
return [];
|
|
282
|
+
}
|
|
283
|
+
return shared.expandRuleSlots({
|
|
284
|
+
baseStartDate: options.baseStartDate,
|
|
285
|
+
baseEndDate: safeBaseEnd,
|
|
286
|
+
recurrence: sanitizeRRuleFieldValue(
|
|
287
|
+
options.recurrence,
|
|
288
|
+
options.recurrence?.timezone || "UTC"
|
|
289
|
+
),
|
|
290
|
+
windowStart: windowStartIso,
|
|
291
|
+
windowEnd: windowEndIso,
|
|
292
|
+
maxOccurrences: options.maxInstances ?? 366
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
const utf8Encoder = new TextEncoder();
|
|
296
|
+
function toIcsTimestamp(isoString, allDay = false) {
|
|
297
|
+
const d = new Date(isoString);
|
|
298
|
+
if (Number.isNaN(d.getTime())) {
|
|
299
|
+
return "";
|
|
300
|
+
}
|
|
301
|
+
const iso = d.toISOString();
|
|
302
|
+
if (allDay) {
|
|
303
|
+
return iso.slice(0, 10).replace(/-/g, "");
|
|
304
|
+
}
|
|
305
|
+
return iso.replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z");
|
|
306
|
+
}
|
|
307
|
+
function resolveExclusiveAllDayEndStamp(startDate, endDate, dtStartStamp) {
|
|
308
|
+
const rawEndStamp = toIcsTimestamp(endDate, true);
|
|
309
|
+
if (rawEndStamp && rawEndStamp > dtStartStamp) {
|
|
310
|
+
return rawEndStamp;
|
|
311
|
+
}
|
|
312
|
+
const startObj = new Date(startDate);
|
|
313
|
+
if (Number.isNaN(startObj.getTime())) {
|
|
314
|
+
return rawEndStamp;
|
|
315
|
+
}
|
|
316
|
+
const nextDay = new Date(
|
|
317
|
+
Date.UTC(
|
|
318
|
+
startObj.getUTCFullYear(),
|
|
319
|
+
startObj.getUTCMonth(),
|
|
320
|
+
startObj.getUTCDate() + 1
|
|
321
|
+
)
|
|
322
|
+
);
|
|
323
|
+
return nextDay.toISOString().slice(0, 10).replace(/-/g, "");
|
|
324
|
+
}
|
|
325
|
+
function escapeIcsText(value) {
|
|
326
|
+
if (!value) return "";
|
|
327
|
+
return String(value).replace(/\\/g, "\\\\").replace(/\r\n|\r|\n/g, "\\n").replace(/;/g, "\\;").replace(/,/g, "\\,");
|
|
328
|
+
}
|
|
329
|
+
function foldIcsLine(line) {
|
|
330
|
+
if (utf8Encoder.encode(line).byteLength <= 75) {
|
|
331
|
+
return line;
|
|
332
|
+
}
|
|
333
|
+
const chunks = [];
|
|
334
|
+
let currentChunk = "";
|
|
335
|
+
let currentBytes = 0;
|
|
336
|
+
let maxBytes = 75;
|
|
337
|
+
for (const codePoint of line) {
|
|
338
|
+
const byteLen = utf8Encoder.encode(codePoint).byteLength;
|
|
339
|
+
if (currentBytes + byteLen > maxBytes && currentChunk.length > 0) {
|
|
340
|
+
chunks.push(chunks.length === 0 ? currentChunk : ` ${currentChunk}`);
|
|
341
|
+
currentChunk = codePoint;
|
|
342
|
+
currentBytes = byteLen;
|
|
343
|
+
maxBytes = 74;
|
|
344
|
+
} else {
|
|
345
|
+
currentChunk += codePoint;
|
|
346
|
+
currentBytes += byteLen;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (currentChunk.length > 0) {
|
|
350
|
+
chunks.push(chunks.length === 0 ? currentChunk : ` ${currentChunk}`);
|
|
351
|
+
}
|
|
352
|
+
return chunks.join("\r\n");
|
|
353
|
+
}
|
|
354
|
+
function buildCalendarLinks(params) {
|
|
355
|
+
const {
|
|
356
|
+
documentId,
|
|
357
|
+
title,
|
|
358
|
+
startDate,
|
|
359
|
+
endDate,
|
|
360
|
+
allDay = false,
|
|
361
|
+
summary = "",
|
|
362
|
+
location = "",
|
|
363
|
+
occurrenceDate
|
|
364
|
+
} = params;
|
|
365
|
+
const icsStart = toIcsTimestamp(startDate, allDay);
|
|
366
|
+
const icsEnd = allDay ? resolveExclusiveAllDayEndStamp(startDate, endDate, icsStart) : toIcsTimestamp(endDate, false);
|
|
367
|
+
const googleParams = new URLSearchParams({
|
|
368
|
+
action: "TEMPLATE",
|
|
369
|
+
text: title,
|
|
370
|
+
dates: `${icsStart}/${icsEnd}`,
|
|
371
|
+
details: summary,
|
|
372
|
+
location
|
|
373
|
+
});
|
|
374
|
+
const outlookParams = new URLSearchParams({
|
|
375
|
+
path: "/calendar/action/compose",
|
|
376
|
+
rru: "addevent",
|
|
377
|
+
subject: title,
|
|
378
|
+
startdt: startDate,
|
|
379
|
+
enddt: endDate,
|
|
380
|
+
body: summary,
|
|
381
|
+
location,
|
|
382
|
+
allday: allDay ? "true" : "false"
|
|
383
|
+
});
|
|
384
|
+
const yahooParams = new URLSearchParams({
|
|
385
|
+
v: "60",
|
|
386
|
+
title,
|
|
387
|
+
st: icsStart,
|
|
388
|
+
et: icsEnd,
|
|
389
|
+
desc: summary,
|
|
390
|
+
in_loc: location
|
|
391
|
+
});
|
|
392
|
+
const querySuffix = occurrenceDate ? `?occurrenceDate=${encodeURIComponent(occurrenceDate)}` : "";
|
|
393
|
+
return {
|
|
394
|
+
google: `https://calendar.google.com/calendar/render?${googleParams.toString()}`,
|
|
395
|
+
outlook: `https://outlook.live.com/calendar/0/deeplink/compose?${outlookParams.toString()}`,
|
|
396
|
+
yahoo: `https://calendar.yahoo.com/?${yahooParams.toString()}`,
|
|
397
|
+
icsPath: `/api/events/${encodeURIComponent(documentId)}/invite.ics${querySuffix}`
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
const ICS_STATUS_MAP = {
|
|
401
|
+
cancelled: "CANCELLED",
|
|
402
|
+
postponed: "TENTATIVE"
|
|
403
|
+
};
|
|
404
|
+
function resolveIcsStatus(status) {
|
|
405
|
+
return Object.hasOwn(ICS_STATUS_MAP, status) ? ICS_STATUS_MAP[status] : "CONFIRMED";
|
|
406
|
+
}
|
|
407
|
+
function appendVEventDateLines(lines, occ) {
|
|
408
|
+
const isAllDay = Boolean(occ.allDay);
|
|
409
|
+
const prefix = isAllDay ? ";VALUE=DATE" : "";
|
|
410
|
+
const startStamp = toIcsTimestamp(occ.startDate, isAllDay);
|
|
411
|
+
const endStamp = isAllDay ? resolveExclusiveAllDayEndStamp(occ.startDate, occ.endDate, startStamp) : toIcsTimestamp(occ.endDate, false);
|
|
412
|
+
lines.push(`DTSTART${prefix}:${startStamp}`);
|
|
413
|
+
lines.push(`DTEND${prefix}:${endStamp}`);
|
|
414
|
+
}
|
|
415
|
+
function appendVEventOptionalLines(lines, occ) {
|
|
416
|
+
if (occ.summary) {
|
|
417
|
+
lines.push(foldIcsLine(`DESCRIPTION:${escapeIcsText(occ.summary)}`));
|
|
418
|
+
}
|
|
419
|
+
if (occ.location) {
|
|
420
|
+
lines.push(foldIcsLine(`LOCATION:${escapeIcsText(occ.location)}`));
|
|
421
|
+
}
|
|
422
|
+
if (occ.virtualUrl) {
|
|
423
|
+
lines.push(foldIcsLine(`URL:${escapeIcsText(occ.virtualUrl)}`));
|
|
424
|
+
}
|
|
425
|
+
if (occ.isRecurring && occ.rrule) {
|
|
426
|
+
const normalized = normalizeRRuleString(occ.rrule).replace(/[\r\n]+/g, "");
|
|
427
|
+
if (normalized) {
|
|
428
|
+
lines.push(foldIcsLine(`RRULE:${normalized}`));
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
function generateIcsCalendar(occurrences, feedTitle = "Events Calendar") {
|
|
433
|
+
const nowStamp = toIcsTimestamp((/* @__PURE__ */ new Date()).toISOString(), false);
|
|
434
|
+
const lines = [
|
|
435
|
+
"BEGIN:VCALENDAR",
|
|
436
|
+
"VERSION:2.0",
|
|
437
|
+
"PRODID:-//Strapi v5//strapi-plugin-events//EN",
|
|
438
|
+
"CALSCALE:GREGORIAN",
|
|
439
|
+
"METHOD:PUBLISH",
|
|
440
|
+
foldIcsLine(`X-WR-CALNAME:${escapeIcsText(feedTitle)}`)
|
|
441
|
+
];
|
|
442
|
+
for (const occ of occurrences) {
|
|
443
|
+
const uid = `${occ.documentId}-${occ.occurrenceDate}@strapi-plugin-events`;
|
|
444
|
+
lines.push("BEGIN:VEVENT");
|
|
445
|
+
lines.push(foldIcsLine(`UID:${escapeIcsText(uid)}`));
|
|
446
|
+
lines.push(`DTSTAMP:${nowStamp}`);
|
|
447
|
+
appendVEventDateLines(lines, occ);
|
|
448
|
+
lines.push(foldIcsLine(`SUMMARY:${escapeIcsText(occ.title)}`));
|
|
449
|
+
appendVEventOptionalLines(lines, occ);
|
|
450
|
+
lines.push(`STATUS:${resolveIcsStatus(occ.status)}`);
|
|
451
|
+
lines.push("END:VEVENT");
|
|
452
|
+
}
|
|
453
|
+
lines.push("END:VCALENDAR");
|
|
454
|
+
return `${lines.join("\r\n")}\r
|
|
455
|
+
`;
|
|
456
|
+
}
|
|
457
|
+
function sanitizeCsvCell(raw) {
|
|
458
|
+
if (raw === null || raw === void 0) {
|
|
459
|
+
return '""';
|
|
460
|
+
}
|
|
461
|
+
let text = String(raw);
|
|
462
|
+
if (/^[\s\u0085\u2028\u2029]*[=+\-@|]|^[\t\r\n]/.test(text)) {
|
|
463
|
+
text = `'${text}`;
|
|
464
|
+
}
|
|
465
|
+
const escaped = text.replace(/"/g, '""');
|
|
466
|
+
return `"${escaped}"`;
|
|
467
|
+
}
|
|
468
|
+
function generateRegistrationsCsv(records) {
|
|
469
|
+
const headers = [
|
|
470
|
+
"Document ID",
|
|
471
|
+
"Event UID",
|
|
472
|
+
"Event Document ID",
|
|
473
|
+
"Event Title",
|
|
474
|
+
"Occurrence Date",
|
|
475
|
+
"Attendee Name",
|
|
476
|
+
"Attendee Email",
|
|
477
|
+
"Attendee Phone",
|
|
478
|
+
"Guests Count",
|
|
479
|
+
"Status",
|
|
480
|
+
"Checked In At",
|
|
481
|
+
"Locale",
|
|
482
|
+
"Notes",
|
|
483
|
+
"Created At"
|
|
484
|
+
];
|
|
485
|
+
const rows = [headers.map(sanitizeCsvCell).join(",")];
|
|
486
|
+
for (const r of records) {
|
|
487
|
+
rows.push(
|
|
488
|
+
[
|
|
489
|
+
r.documentId,
|
|
490
|
+
r.eventUid,
|
|
491
|
+
r.eventDocumentId,
|
|
492
|
+
r.eventTitle ?? "",
|
|
493
|
+
r.occurrenceDate,
|
|
494
|
+
r.attendeeName,
|
|
495
|
+
r.attendeeEmail,
|
|
496
|
+
r.attendeePhone ?? "",
|
|
497
|
+
r.guestsCount,
|
|
498
|
+
r.status,
|
|
499
|
+
r.checkedInAt ?? "",
|
|
500
|
+
r.locale,
|
|
501
|
+
r.notes ?? "",
|
|
502
|
+
r.createdAt ?? ""
|
|
503
|
+
].map(sanitizeCsvCell).join(",")
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
return `${rows.join("\r\n")}\r
|
|
507
|
+
`;
|
|
508
|
+
}
|
|
509
|
+
const PLUGIN_ID = "events";
|
|
510
|
+
const RRULE_CUSTOM_FIELD_UID = `plugin::${PLUGIN_ID}.rrule`;
|
|
511
|
+
const EVENT_CONTENT_TYPE_UID = `plugin::${PLUGIN_ID}.event`;
|
|
512
|
+
const REGISTRATION_CONTENT_TYPE_UID = `plugin::${PLUGIN_ID}.registration`;
|
|
513
|
+
const ALLOWED_SPOTLIGHT_POSITIONS = /* @__PURE__ */ new Set([
|
|
514
|
+
"bottom-end",
|
|
515
|
+
"bottom-start"
|
|
516
|
+
]);
|
|
517
|
+
function resolveSpotlightPosition(rawPos) {
|
|
518
|
+
const candidate = getTrimmedString(rawPos);
|
|
519
|
+
return candidate && ALLOWED_SPOTLIGHT_POSITIONS.has(candidate) ? candidate : void 0;
|
|
520
|
+
}
|
|
521
|
+
function resolveFiniteRoundNumber(val) {
|
|
522
|
+
return typeof val === "number" && Number.isFinite(val) ? Math.round(val) : void 0;
|
|
523
|
+
}
|
|
524
|
+
function normalizeEventSpotlightConfig(rawConfig) {
|
|
525
|
+
const parsed = parseJsonIfNeeded(rawConfig);
|
|
526
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
527
|
+
return void 0;
|
|
528
|
+
}
|
|
529
|
+
const rec = parsed;
|
|
530
|
+
const config = {
|
|
531
|
+
enabled: Boolean(rec.enabled)
|
|
532
|
+
};
|
|
533
|
+
const badgeText = getTrimmedString(rec.badgeText, 80);
|
|
534
|
+
if (badgeText) config.badgeText = badgeText;
|
|
535
|
+
const priority = resolveFiniteRoundNumber(rec.priority);
|
|
536
|
+
if (priority !== void 0) config.priority = priority;
|
|
537
|
+
const position = resolveSpotlightPosition(rec.position);
|
|
538
|
+
if (position) config.position = position;
|
|
539
|
+
if (typeof rec.showCountdown === "boolean") {
|
|
540
|
+
config.showCountdown = rec.showCountdown;
|
|
541
|
+
}
|
|
542
|
+
const startAt = getTrimmedString(rec.startAt);
|
|
543
|
+
if (startAt) config.startAt = startAt;
|
|
544
|
+
const endAt = getTrimmedString(rec.endAt);
|
|
545
|
+
if (endAt) config.endAt = endAt;
|
|
546
|
+
return config;
|
|
547
|
+
}
|
|
548
|
+
function toBoundaryTimestamp(rawIsoOrDate, isEndBoundary) {
|
|
549
|
+
const trimmed = rawIsoOrDate.trim();
|
|
550
|
+
const isoString = /^\d{4}-\d{2}-\d{2}$/.test(trimmed) ? `${trimmed}${isEndBoundary ? "T23:59:59.999Z" : "T00:00:00.000Z"}` : trimmed;
|
|
551
|
+
const ts = new Date(isoString).getTime();
|
|
552
|
+
return Number.isNaN(ts) ? null : ts;
|
|
553
|
+
}
|
|
554
|
+
function toReferenceTimestamp(referenceDate) {
|
|
555
|
+
if (referenceDate instanceof Date) {
|
|
556
|
+
const ts2 = referenceDate.getTime();
|
|
557
|
+
return Number.isNaN(ts2) ? null : ts2;
|
|
558
|
+
}
|
|
559
|
+
const str = getTrimmedString(referenceDate);
|
|
560
|
+
const dt = str ? new Date(str) : /* @__PURE__ */ new Date();
|
|
561
|
+
const ts = dt.getTime();
|
|
562
|
+
return Number.isNaN(ts) ? null : ts;
|
|
563
|
+
}
|
|
564
|
+
function isEventSpotlightActiveOnDate(params) {
|
|
565
|
+
const { spotlightConfig, eventStartDate, eventEndDate, referenceDate } = params;
|
|
566
|
+
if (!spotlightConfig?.enabled) return false;
|
|
567
|
+
const refTs = toReferenceTimestamp(referenceDate);
|
|
568
|
+
if (refTs === null) return false;
|
|
569
|
+
const startTs = toBoundaryTimestamp(
|
|
570
|
+
spotlightConfig.startAt || eventStartDate,
|
|
571
|
+
false
|
|
572
|
+
);
|
|
573
|
+
const endTs = toBoundaryTimestamp(
|
|
574
|
+
spotlightConfig.endAt || eventEndDate || eventStartDate,
|
|
575
|
+
true
|
|
576
|
+
);
|
|
577
|
+
const afterStart = startTs === null || refTs >= startTs;
|
|
578
|
+
const beforeEnd = endTs === null || refTs <= endTs;
|
|
579
|
+
return afterStart && beforeEnd;
|
|
580
|
+
}
|
|
581
|
+
function deduplicateAndSortSpotlights(occurrences) {
|
|
582
|
+
const byDocKey = /* @__PURE__ */ new Map();
|
|
583
|
+
for (const occ of occurrences) {
|
|
584
|
+
if (!occ.spotlightConfig?.enabled || occ.status === "cancelled") {
|
|
585
|
+
continue;
|
|
586
|
+
}
|
|
587
|
+
const key = `${occ.sourceId}:${occ.documentId}`;
|
|
588
|
+
if (!byDocKey.has(key)) {
|
|
589
|
+
byDocKey.set(key, occ);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
const unique = Array.from(byDocKey.values());
|
|
593
|
+
unique.sort((a, b) => {
|
|
594
|
+
const prioA = a.spotlightConfig?.priority ?? 0;
|
|
595
|
+
const prioB = b.spotlightConfig?.priority ?? 0;
|
|
596
|
+
if (prioB !== prioA) {
|
|
597
|
+
return prioB - prioA;
|
|
598
|
+
}
|
|
599
|
+
return new Date(a.startDate).getTime() - new Date(b.startDate).getTime();
|
|
600
|
+
});
|
|
601
|
+
return unique;
|
|
602
|
+
}
|
|
603
|
+
const DEFAULT_TIME_SLOTS = {
|
|
604
|
+
morning: { start: "09:00:00", end: "11:00:00" },
|
|
605
|
+
afternoon: { start: "14:00:00", end: "16:00:00" },
|
|
606
|
+
evening: { start: "18:00:00", end: "20:00:00" }
|
|
607
|
+
};
|
|
608
|
+
function buildSafeSlotMap(customSlots) {
|
|
609
|
+
const slotMap = { ...DEFAULT_TIME_SLOTS };
|
|
610
|
+
if (customSlots && typeof customSlots === "object") {
|
|
611
|
+
for (const [k, v] of Object.entries(customSlots)) {
|
|
612
|
+
if (isSafeObjectKey(k) && v && typeof v === "object") {
|
|
613
|
+
slotMap[k] = v;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
return slotMap;
|
|
618
|
+
}
|
|
619
|
+
function resolveDateOnlySlotWindow(rawStart, rawSlot, source) {
|
|
620
|
+
if (!isSafeObjectKey(rawSlot)) return null;
|
|
621
|
+
const slotMap = buildSafeSlotMap(source.timeSlotMap);
|
|
622
|
+
const mapped = Object.hasOwn(slotMap, rawSlot) ? slotMap[rawSlot] : void 0;
|
|
623
|
+
if (mapped) {
|
|
624
|
+
return {
|
|
625
|
+
startDate: `${rawStart}T${mapped.start}.000Z`,
|
|
626
|
+
endDate: `${rawStart}T${mapped.end}.000Z`,
|
|
627
|
+
allDay: false
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
if (/^\d{2}:\d{2}(:\d{2})?$/.test(rawSlot)) {
|
|
631
|
+
const normalizedTime = rawSlot.length === 5 ? `${rawSlot}:00` : rawSlot;
|
|
632
|
+
return {
|
|
633
|
+
startDate: `${rawStart}T${normalizedTime}.000Z`,
|
|
634
|
+
endDate: null,
|
|
635
|
+
allDay: false
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
return null;
|
|
639
|
+
}
|
|
640
|
+
function resolveDateOnlyEnd(rawStart, rawEnd) {
|
|
641
|
+
if (typeof rawEnd === "string" && rawEnd) {
|
|
642
|
+
return /^\d{4}-\d{2}-\d{2}$/.test(rawEnd) ? `${rawEnd}T23:59:59.000Z` : rawEnd;
|
|
643
|
+
}
|
|
644
|
+
return `${rawStart}T23:59:59.000Z`;
|
|
645
|
+
}
|
|
646
|
+
function readOptionalDocField(doc, fieldName) {
|
|
647
|
+
return fieldName && isSafeObjectKey(fieldName) ? doc[fieldName] : null;
|
|
648
|
+
}
|
|
649
|
+
function resolveNonEmptyEnd(rawEnd) {
|
|
650
|
+
return typeof rawEnd === "string" && rawEnd ? rawEnd : null;
|
|
651
|
+
}
|
|
652
|
+
function resolveStartEndFromDocument(doc, source) {
|
|
653
|
+
const startField = source.fields.startDate;
|
|
654
|
+
const rawStart = isSafeObjectKey(startField) ? doc[startField] : void 0;
|
|
655
|
+
if (typeof rawStart !== "string" || !rawStart) {
|
|
656
|
+
return null;
|
|
657
|
+
}
|
|
658
|
+
const rawEnd = readOptionalDocField(doc, source.fields.endDate);
|
|
659
|
+
const rawSlot = readOptionalDocField(doc, source.fields.timeSlot);
|
|
660
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(rawStart)) {
|
|
661
|
+
const slotWindow = resolveDateOnlySlotWindow(rawStart, rawSlot, source);
|
|
662
|
+
if (slotWindow) return slotWindow;
|
|
663
|
+
return {
|
|
664
|
+
startDate: `${rawStart}T00:00:00.000Z`,
|
|
665
|
+
endDate: resolveDateOnlyEnd(rawStart, rawEnd),
|
|
666
|
+
allDay: source.defaultAllDay ?? true
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
const allDay = typeof doc.allDay === "boolean" ? doc.allDay : Boolean(source.defaultAllDay);
|
|
670
|
+
return {
|
|
671
|
+
startDate: rawStart,
|
|
672
|
+
endDate: resolveNonEmptyEnd(rawEnd),
|
|
673
|
+
allDay
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
const EVENT_STATUS_ALIAS_MAP = {
|
|
677
|
+
cancelled: "cancelled",
|
|
678
|
+
canceled: "cancelled",
|
|
679
|
+
postponed: "postponed",
|
|
680
|
+
pending: "postponed",
|
|
681
|
+
rescheduled: "rescheduled"
|
|
682
|
+
};
|
|
683
|
+
function mapEventStatus(rawStatus) {
|
|
684
|
+
if (typeof rawStatus !== "string") return "scheduled";
|
|
685
|
+
const lower = rawStatus.toLowerCase();
|
|
686
|
+
return Object.hasOwn(EVENT_STATUS_ALIAS_MAP, lower) ? EVENT_STATUS_ALIAS_MAP[lower] : "scheduled";
|
|
687
|
+
}
|
|
688
|
+
Object.defineProperty(exports, "SUPPORTED_INTL_CALENDARS", {
|
|
689
|
+
enumerable: true,
|
|
690
|
+
get: () => shared.SUPPORTED_INTL_CALENDARS
|
|
691
|
+
});
|
|
692
|
+
Object.defineProperty(exports, "applyDayOffset", {
|
|
693
|
+
enumerable: true,
|
|
694
|
+
get: () => shared.applyDayOffset
|
|
695
|
+
});
|
|
696
|
+
Object.defineProperty(exports, "extractCalendarParts", {
|
|
697
|
+
enumerable: true,
|
|
698
|
+
get: () => shared.extractCalendarParts
|
|
699
|
+
});
|
|
700
|
+
Object.defineProperty(exports, "formatDateInCalendarSystem", {
|
|
701
|
+
enumerable: true,
|
|
702
|
+
get: () => shared.formatDateInCalendarSystem
|
|
703
|
+
});
|
|
704
|
+
Object.defineProperty(exports, "getRegisteredCalendarFormatters", {
|
|
705
|
+
enumerable: true,
|
|
706
|
+
get: () => shared.getRegisteredCalendarFormatters
|
|
707
|
+
});
|
|
708
|
+
Object.defineProperty(exports, "parseRRule", {
|
|
709
|
+
enumerable: true,
|
|
710
|
+
get: () => shared.parseRRule
|
|
711
|
+
});
|
|
712
|
+
Object.defineProperty(exports, "registerCalendarSystemFormatter", {
|
|
713
|
+
enumerable: true,
|
|
714
|
+
get: () => shared.registerCalendarSystemFormatter
|
|
715
|
+
});
|
|
716
|
+
Object.defineProperty(exports, "resolveOccurrenceAlternateDates", {
|
|
717
|
+
enumerable: true,
|
|
718
|
+
get: () => shared.resolveOccurrenceAlternateDates
|
|
719
|
+
});
|
|
720
|
+
Object.defineProperty(exports, "unregisterCalendarSystemFormatter", {
|
|
721
|
+
enumerable: true,
|
|
722
|
+
get: () => shared.unregisterCalendarSystemFormatter
|
|
723
|
+
});
|
|
724
|
+
exports.EVENT_CONTENT_TYPE_UID = EVENT_CONTENT_TYPE_UID;
|
|
725
|
+
exports.PLUGIN_ID = PLUGIN_ID;
|
|
726
|
+
exports.REGISTRATION_CONTENT_TYPE_UID = REGISTRATION_CONTENT_TYPE_UID;
|
|
727
|
+
exports.RRULE_CUSTOM_FIELD_UID = RRULE_CUSTOM_FIELD_UID;
|
|
728
|
+
exports.buildCalendarLinks = buildCalendarLinks;
|
|
729
|
+
exports.buildRRule = buildRRule;
|
|
730
|
+
exports.deduplicateAndSortSpotlights = deduplicateAndSortSpotlights;
|
|
731
|
+
exports.describeRRule = describeRRule;
|
|
732
|
+
exports.escapeIcsText = escapeIcsText;
|
|
733
|
+
exports.expandRuleSlots = expandRuleSlots;
|
|
734
|
+
exports.foldIcsLine = foldIcsLine;
|
|
735
|
+
exports.generateIcsCalendar = generateIcsCalendar;
|
|
736
|
+
exports.generateRegistrationsCsv = generateRegistrationsCsv;
|
|
737
|
+
exports.isEventSpotlightActiveOnDate = isEventSpotlightActiveOnDate;
|
|
738
|
+
exports.isSafeObjectKey = isSafeObjectKey;
|
|
739
|
+
exports.isValidCalendarDateKey = isValidCalendarDateKey;
|
|
740
|
+
exports.mapEventStatus = mapEventStatus;
|
|
741
|
+
exports.normalizeEventActionLinks = normalizeEventActionLinks;
|
|
742
|
+
exports.normalizeEventPoster = normalizeEventPoster;
|
|
743
|
+
exports.normalizeEventSpotlightConfig = normalizeEventSpotlightConfig;
|
|
744
|
+
exports.normalizeRRuleString = normalizeRRuleString;
|
|
745
|
+
exports.parseRRuleFieldValue = parseRRuleFieldValue;
|
|
746
|
+
exports.resolveStartEndFromDocument = resolveStartEndFromDocument;
|
|
747
|
+
exports.sanitizeCsvCell = sanitizeCsvCell;
|
|
748
|
+
exports.sanitizeEventUrl = sanitizeEventUrl;
|
|
749
|
+
exports.sanitizeOccurrenceOverrides = sanitizeOccurrenceOverrides;
|
|
750
|
+
exports.sanitizePlainRecord = sanitizePlainRecord;
|
|
751
|
+
exports.sanitizeRRuleFieldValue = sanitizeRRuleFieldValue;
|
|
752
|
+
exports.toDateKey = toDateKey;
|
|
753
|
+
exports.toIcsTimestamp = toIcsTimestamp;
|