diff --git a/node-addon/EventKitBridge.swift b/node-addon/EventKitBridge.swift index 4231cbb..bf69025 100644 --- a/node-addon/EventKitBridge.swift +++ b/node-addon/EventKitBridge.swift @@ -383,7 +383,9 @@ import Foundation @objc public let hasAlarms: Bool @objc public let availability: String @objc public let externalIdentifier: String? - + @objc public let isRecurring: Bool + @objc public let recurrenceRules: [[String: Any]] + init(from ekEvent: EKEvent) { self.id = ekEvent.eventIdentifier self.title = ekEvent.title ?? "Untitled Event" @@ -397,7 +399,37 @@ import Foundation self.url = ekEvent.url?.absoluteString self.hasAlarms = ekEvent.hasAlarms self.externalIdentifier = ekEvent.calendarItemExternalIdentifier + self.isRecurring = ekEvent.hasRecurrenceRules + var rules: [[String: Any]] = [] + if let ekRules = ekEvent.recurrenceRules { + for rule in ekRules { + var r: [String: Any] = [:] + switch rule.frequency { + case .daily: r["frequency"] = "daily" + case .weekly: r["frequency"] = "weekly" + case .monthly: r["frequency"] = "monthly" + case .yearly: r["frequency"] = "yearly" + @unknown default: r["frequency"] = "unknown" + } + r["interval"] = rule.interval + if let days = rule.daysOfTheWeek { + r["daysOfTheWeek"] = days.map { d -> [String: Any] in + let names = ["SU","MO","TU","WE","TH","FR","SA"] + return ["day": names[d.dayOfTheWeek.rawValue - 1], "weekNumber": d.weekNumber] + } + } + if let months = rule.monthsOfTheYear { r["monthsOfTheYear"] = months.map { $0.intValue } } + if let dom = rule.daysOfTheMonth { r["daysOfTheMonth"] = dom.map { $0.intValue } } + if let end = rule.recurrenceEnd { + if let endDate = end.endDate { r["endDate"] = endDate.timeIntervalSince1970 } + if end.occurrenceCount > 0 { r["count"] = end.occurrenceCount } + } + rules.append(r) + } + } + self.recurrenceRules = rules + // Convert availability to string switch ekEvent.availability { case .free: diff --git a/node-addon/eventkit_binding.mm b/node-addon/eventkit_binding.mm index 11500f3..4ff164d 100644 --- a/node-addon/eventkit_binding.mm +++ b/node-addon/eventkit_binding.mm @@ -753,7 +753,35 @@ void SetResult(bool success, const std::string& calendarIdOrError) { } else { jsObject.Set("externalIdentifier", env.Null()); } - + + jsObject.Set("isRecurring", Napi::Boolean::New(env, event.isRecurring)); + + // Map recurrenceRules array + NSArray *rules = (NSArray *)event.recurrenceRules; + Napi::Array jsRules = Napi::Array::New(env, [rules count]); + for (NSUInteger i = 0; i < [rules count]; i++) { + NSDictionary *rule = rules[i]; + Napi::Object jsRule = Napi::Object::New(env); + if (rule[@"frequency"]) jsRule.Set("frequency", Napi::String::New(env, [rule[@"frequency"] UTF8String])); + if (rule[@"interval"]) jsRule.Set("interval", Napi::Number::New(env, [rule[@"interval"] intValue])); + if (rule[@"endDate"]) jsRule.Set("endDate", Napi::Number::New(env, [rule[@"endDate"] doubleValue])); + if (rule[@"count"]) jsRule.Set("count", Napi::Number::New(env, [rule[@"count"] intValue])); + if (rule[@"daysOfTheWeek"]) { + NSArray *days = rule[@"daysOfTheWeek"]; + Napi::Array jsDays = Napi::Array::New(env, [days count]); + for (NSUInteger j = 0; j < [days count]; j++) { + NSDictionary *d = days[j]; + Napi::Object jsDay = Napi::Object::New(env); + jsDay.Set("day", Napi::String::New(env, [d[@"day"] UTF8String])); + jsDay.Set("weekNumber", Napi::Number::New(env, [d[@"weekNumber"] intValue])); + jsDays.Set(j, jsDay); + } + jsRule.Set("daysOfTheWeek", jsDays); + } + jsRules.Set(i, jsRule); + } + jsObject.Set("recurrenceRules", jsRules); + return jsObject; }