A TypeScript SDK for the Permas Calendar Service, designed to simplify integration with the Calendar API.
npm install @permas/calendar-sdk
const { CalendarSDK } = require('@permas/calendar-sdk');
// Initialize the SDK with your API endpoint
const calendarSDK = new CalendarSDK({
baseUrl: 'https://calendar-service.wittyisland-1f2e1c07.eastus2.azurecontainerapps.io',
timeout: 30000 // Optional: default is 10000 (10 seconds)
});
// Use the SDK methods
async function fetchEvents() {
try {
const events = await calendarSDK.getEvents();
console.log(events.data);
} catch (error) {
console.error('Error fetching events:', error);
}
}
- Update Operations: The API does not return the updated object in response to update operations. To verify changes, fetch the object again after updating.
- PATCH Operations: The current API implementation does not support PATCH operations for partial updates. Use the full update methods instead.
- Complex Nested Objects: The API may not handle all nested objects correctly. In particular, arrays of nested objects (like sessions) may require special handling.
-
getHealth()
- Get the health status of the API -
getEvents(filter?)
- Get all events with optional filtering -
getEvent(id)
- Get a single event by ID -
createEvent(event)
- Create a new event -
updateEvent(id, data)
- Update an existing event -
updateEventField(id, field, value)
- Update a specific field in an event (not supported in current API) -
updateArrayItem(id, field, index, item)
- Update or add an item in an array field -
deleteEvent(id)
- Delete an event
const { CalendarSDK } = require('@permas/calendar-sdk');
async function manageTechConference() {
try {
// Initialize SDK
const sdk = new CalendarSDK({
baseUrl: 'https://calendar-service.wittyisland-1f2e1c07.eastus2.azurecontainerapps.io'
});
// 1. Create a new event
const newConference = {
title: "Annual Tech Conference 2025",
date: new Date("2025-09-15T09:00:00Z"),
type: "conference",
description: "Our annual technology conference featuring the latest innovations",
location: {
name: "Tech Convention Center",
address: {
street: "123 Innovation Blvd",
city: "San Francisco",
state: "CA",
zipCode: "94105",
country: "USA"
},
room: "Main Hall",
amenities: ["WiFi", "AV Equipment", "Catering"]
},
organizer: {
name: "Tech Events Inc.",
email: "events@techevents.example.com",
phone: "555-123-4567"
},
sessions: [
{
title: "Keynote Address",
speaker: "Jane Smith, CEO",
time: "2025-09-15T09:30:00Z",
duration: 60,
description: "Opening keynote on industry trends"
}
],
attendees: [
{
name: "John Doe",
email: "john@example.com",
role: "attendee",
confirmed: true
}
],
tags: ["technology", "innovation", "conference", "annual"],
maxCapacity: 500,
isVirtual: false
};
// Create the event
const createdConference = await sdk.createEvent(newConference);
console.log(`Conference created with ID: ${createdConference._id}`);
// 2. Add a session to the conference
const updatedConference = await sdk.updateArrayItem(
createdConference._id,
'sessions',
-1,
{
title: "Networking Lunch",
time: "2025-09-15T12:30:00Z",
duration: 90,
description: "Lunch and networking opportunity"
}
);
console.log(`Conference now has ${updatedConference?.sessions?.length || 0} sessions`);
// 3. Update the conference details
await sdk.updateEvent(createdConference._id, {
title: "Annual Tech Conference 2025 - SOLD OUT",
status: "full"
});
// 4. Fetch the updated conference
const updatedConferenceData = await sdk.getEvent(createdConference._id);
console.log(`Updated conference title: ${updatedConferenceData.title}`);
// 5. Find all conferences
const allConferences = await sdk.getEvents({ type: "conference" });
console.log(`Found ${allConferences.data.length} conferences`);
// 6. Delete the conference (for cleanup)
await sdk.deleteEvent(createdConference._id);
console.log('Conference deleted successfully');
} catch (error) {
console.error('Error managing conference:', error.message);
if (error.status) {
console.error(`Status: ${error.status}, Response: ${JSON.stringify(error.data)}`);
}
}
}
The SDK wraps all API errors with detailed information:
try {
await sdk.getEvent('invalid-id');
} catch (error) {
console.log(error.message); // Human-readable message
console.log(error.status); // HTTP status code (e.g., 404)
console.log(error.data); // Response data from the API
}
The SDK includes several test scripts to verify functionality:
# Basic API connectivity test
node test-api.js
# CRUD operations test
node test-crud.js
# Advanced comprehensive test
node test-advanced.js
This SDK works with the Permas Calendar Service backend, which:
- Uses Node.js and Express
- Provides a RESTful API for calendar event management
- Supports MongoDB/CosmosDB via the permas-database-adapter
- Uses TypeScript for type safety
MIT
The SDK supports automatic configuration through environment variables:
# Google Calendar Integration
GOOGLE_CALENDAR_CLIENT_ID=your-client-id
GOOGLE_CALENDAR_CLIENT_SECRET=your-client-secret
GOOGLE_CALENDAR_REDIRECT_URI=http://localhost:3000/auth/google/callback
# iCal Feed Integration - comma-separated list of URLs
ICAL_FEEDS=https://calendar.google.com/calendar/ical/sample@example.com/public/basic.ics,https://example.com/events.ics
Use the useCalendarSyncWithConfig
hook to automatically sync with configured calendar sources:
import { useCalendarSyncWithConfig } from 'calendar-service-sdk';
function CalendarApp() {
const {
events, // All events from all sources
loading, // Loading state
error, // Error state
config, // Current environment configuration
icalFeeds, // iCal feed operations and status
googleAuth, // Google auth status and operations
deleteEvent, // Function to delete events
} = useCalendarSyncWithConfig({
autoSyncIcal: true, // Auto-sync iCal feeds on load
onIcalSyncComplete: (results) => {
console.log('iCal sync complete', results);
},
onGoogleSyncComplete: (result, error) => {
console.log('Google sync complete', result, error);
}
});
// Example: Manually trigger iCal sync
const handleSyncIcal = () => {
icalFeeds.syncAll();
};
// Example: Initiate Google auth flow
const handleGoogleLogin = () => {
googleAuth.initiateAuth();
};
return (
<div>
<h1>Calendar Events ({events.length})</h1>
{/* Your UI components */}
</div>
);
}
See the examples/ConfiguredSyncExample.tsx
for a complete implementation.