@appkit/apple-calendar
v0.1.3
Published
Native macOS Calendar integration using EventKit with participation status support
Downloads
319
Maintainers
Readme
apple-calendar
Native macOS Calendar integration using EventKit with participation status support.
Features
- ✅ Native EventKit Integration - Direct access to macOS Calendar via Swift
- ✅ Participation Status - Filter events by accepted/declined/tentative/pending
- ✅ TypeScript API - Clean, type-safe interface for Node.js
- ✅ Pre-compiled Binary - No Swift toolchain required for end users
- ✅ Zero Dependencies - Minimal runtime footprint
- ✅ Fast - Native performance, no parsing overhead
Installation
npm install @appkit/apple-calendarRequirements:
- macOS 10.14 or later
- Node.js 18 or later
Quick Start
import { getEventsToday, ParticipationStatus } from "@appkit/apple-calendar";
// Get today's accepted events
const events = await getEventsToday({
participationStatus: [ParticipationStatus.Accepted],
});
console.log(events);API Reference
Event Queries
getEventsToday(options?)
Get events for today (00:00 - 23:59).
const events = await getEventsToday({
calendars: ["Work", "Personal"],
includeAllDay: false,
participationStatus: [ParticipationStatus.Accepted],
});Options:
calendars?: string[]- Filter by calendar namesincludeAllDay?: boolean- Include all-day events (default:false)participationStatus?: ParticipationStatus[]- Filter by status
getEventsFromToday(days, options?)
Get events from today through N days ahead.
// Get next 7 days of accepted events
const events = await getEventsFromToday(7, {
participationStatus: [ParticipationStatus.Accepted],
});getUpcomingEvents(hours?, options?)
Get upcoming events starting from now.
// Get events in the next 24 hours
const events = await getUpcomingEvents(24);getEventsBetween(startDate, endDate, options?)
Get events in a specific date range.
const start = new Date("2024-01-01");
const end = new Date("2024-01-31");
const events = await getEventsBetween(start, end);queryEvents(options)
Low-level query with full control.
const result = await queryEvents({
startDate: new Date(),
endDate: new Date(Date.now() + 86400000),
calendars: ["Work"],
includeAllDay: true,
participationStatus: [
ParticipationStatus.Accepted,
ParticipationStatus.Tentative,
],
});
console.log(result.events);
console.log(result.errors); // Any errors that occurredCalendar Queries
listCalendars()
Get all available calendars.
const calendars = await listCalendars();
calendars.forEach((cal) => {
console.log(`${cal.title} (${cal.type}) - ${cal.color}`);
});Types
ParticipationStatus
Enum for event participation status:
enum ParticipationStatus {
Unknown = 0, // Status not set
Pending = 1, // Invitation pending
Accepted = 2, // User accepted
Declined = 3, // User declined
Tentative = 4, // User marked as maybe
}CalendarEvent
Event object returned by queries:
interface CalendarEvent {
id: string;
title: string;
startDate: Date;
endDate: Date;
calendar: string;
location?: string;
isAllDay: boolean;
participationStatus: ParticipationStatus;
notes?: string;
url?: string;
isRecurring: boolean;
}Calendar
Calendar object returned by listCalendars():
interface Calendar {
title: string;
type: string;
isWritable: boolean;
color?: string;
}Examples
Filter Out Declined/Tentative Events
import {
getEventsFromToday,
ParticipationStatus,
} from "@appkit/apple-calendar";
// Only get events I've accepted
const acceptedEvents = await getEventsFromToday(7, {
participationStatus: [ParticipationStatus.Accepted],
});Query Specific Calendars
import { getEventsToday } from "@appkit/apple-calendar";
// Only work events
const workEvents = await getEventsToday({
calendars: ["Work Calendar"],
});
// Multiple calendars
const events = await getEventsToday({
calendars: ["Work", "Personal", "Family"],
});Get All Events Including All-Day
import { getEventsToday } from "@appkit/apple-calendar";
const allEvents = await getEventsToday({
includeAllDay: true,
});List Available Calendars
import { listCalendars } from "@appkit/apple-calendar";
const calendars = await listCalendars();
console.log("Available calendars:");
calendars.forEach((cal) => {
console.log(`- ${cal.title} (${cal.type})`);
});Custom Date Range with Filtering
import { queryEvents, ParticipationStatus } from "@appkit/apple-calendar";
const result = await queryEvents({
startDate: new Date("2024-01-01"),
endDate: new Date("2024-12-31"),
calendars: ["Work"],
includeAllDay: false,
participationStatus: [ParticipationStatus.Accepted],
});
console.log(`Found ${result.events.length} events`);
if (result.errors && result.errors.length > 0) {
console.error("Errors:", result.errors);
}Command-Line Usage
The native binary can also be used directly:
# List calendars
./dist/bin/calendar-helper calendars
# Get today's events
./dist/bin/calendar-helper events today
# Get next 7 days
./dist/bin/calendar-helper events today+7
# Get events with filters
./dist/bin/calendar-helper events \
--days 7 \
--calendars "Work,Personal" \
--participation 2 \
--include-all-day
# Custom date range
./dist/bin/calendar-helper events \
--start 2024-01-01T00:00:00Z \
--end 2024-01-31T23:59:59ZBuilding from Source
# Install dependencies
npm install
# Build native binary and TypeScript
npm run build
# Or build separately
npm run build:native # Build Swift binary
npm run build:ts # Build TypeScriptBuild Requirements:
- Xcode Command Line Tools
- Swift 5.0 or later
How It Works
This package includes a pre-compiled Swift binary that uses Apple's EventKit framework to query calendar data. The TypeScript wrapper provides a clean API that executes the binary and parses its JSON output.
Architecture:
- TypeScript API receives query
- Constructs command-line arguments
- Executes Swift binary (EventKit)
- Parses JSON response
- Returns typed results
Why Native?
icalBuddydoesn't support participation status- AppleScript Calendar integration is limited
- EventKit is the official, most capable API
Privacy & Permissions
This package requires Calendar access. On first use:
- macOS will prompt for Calendar access
- Grant access to your terminal or app
- Future calls will work without prompts
Privacy: All queries are local-only. No data leaves your machine.
License
MIT
Contributing
Contributions welcome! Please open an issue or PR.
Troubleshooting
Binary not found:
npm run build:nativePermission denied:
- System Settings → Privacy & Security → Calendars
- Enable access for Terminal or your app
No events returned:
- Check calendar names with
listCalendars() - Verify date ranges are correct
- Check participation status filters
Build errors:
- Ensure Xcode Command Line Tools are installed:
xcode-select --install - Verify Swift version:
swift --version(needs 5.0+)
