@crescender/calendar
Version:
A comprehensive TypeScript calendar library with musician-specific capabilities, architected for client/server separation.
1 lines • 12.7 kB
Source Map (JSON)
{"version":3,"sources":["../src/shared/utils.ts","../src/shared/constants.ts","../src/shared/enums.ts"],"sourcesContent":["/**\n * @file Shared utility functions for the calendar library.\n * These utilities are safe to use in both client and server environments.\n */\n\n/**\n * Formats a date in Australian format (dd/mmm/yyyy).\n * Uses UTC date to avoid timezone issues in tests.\n */\nexport function formatDateAustralian(date: Date): string {\n const months = [\n 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'\n ];\n \n const day = date.getUTCDate().toString().padStart(2, '0');\n const month = months[date.getUTCMonth()];\n const year = date.getUTCFullYear();\n \n return `${day}/${month}/${year}`;\n}\n\n/**\n * Calculates the duration between two dates in minutes.\n */\nexport function getDurationMinutes(start: Date, end: Date): number {\n return Math.round((end.getTime() - start.getTime()) / (1000 * 60));\n}\n\n/**\n * Checks if two dates are on the same day.\n */\nexport function isSameDay(date1: Date, date2: Date): boolean {\n return date1.toDateString() === date2.toDateString();\n}\n\n/**\n * Gets the start of week (Monday) for a given date.\n */\nexport function getStartOfWeek(date: Date): Date {\n const result = new Date(date);\n const day = result.getDay();\n const diff = result.getDate() - day + (day === 0 ? -6 : 1); // Adjust when day is Sunday\n result.setDate(diff);\n result.setHours(0, 0, 0, 0);\n return result;\n}\n\n/**\n * Gets the end of week (Sunday) for a given date.\n */\nexport function getEndOfWeek(date: Date): Date {\n const result = new Date(date);\n const day = result.getDay();\n const diff = result.getDate() - day + (day === 0 ? 0 : 7); // Adjust when day is Sunday\n result.setDate(diff);\n result.setHours(23, 59, 59, 999);\n return result;\n}\n\n/**\n * Validates an email address.\n */\nexport function isValidEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n\n/**\n * Validates a phone number (basic validation).\n */\nexport function isValidPhone(phone: string): boolean {\n // Basic validation for Australian phone numbers\n const phoneRegex = /^(\\+61|0)[2-9]\\d{8}$/;\n return phoneRegex.test(phone.replace(/\\s/g, ''));\n}\n\n/**\n * Generates a unique ID (simple implementation for client-side).\n * Note: For production, use a proper UUID library on the server.\n */\nexport function generateTempId(): string {\n return `temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n} ","/**\n * @file Shared constants for the calendar library.\n * These constants are safe to use in both client and server environments.\n */\n\n/**\n * Default currency for financial calculations.\n */\nexport const DEFAULT_CURRENCY = 'AUD';\n\n/**\n * Maximum event duration in hours.\n */\nexport const MAX_EVENT_DURATION_HOURS = 24;\n\n/**\n * Maximum number of recurrence occurrences.\n */\nexport const MAX_RECURRENCE_OCCURRENCES = 365;\n\n/**\n * Default event duration in minutes.\n */\nexport const DEFAULT_EVENT_DURATION_MINUTES = 60;\n\n/**\n * Maximum field lengths for validation.\n */\nexport const MAX_LENGTHS = {\n EVENT_TITLE: 200,\n EVENT_DESCRIPTION: 1000,\n CALENDAR_NAME: 100,\n CALENDAR_DESCRIPTION: 500,\n VENUE_NAME: 200,\n VENUE_ADDRESS: 300,\n VENUE_CITY: 100,\n CONTACT_NAME: 200,\n CONTACT_ROLE: 100,\n NOTES: 1000,\n INCOME_DESCRIPTION: 200,\n EXPENSE_DESCRIPTION: 200,\n RECEIPT_PATH: 500\n} as const;\n\n/**\n * Date format patterns for different locales.\n */\nexport const DATE_FORMATS = {\n AUSTRALIAN: 'DD/MM/YYYY',\n AMERICAN: 'MM/DD/YYYY',\n ISO: 'YYYY-MM-DD'\n} as const;\n\n/**\n * Time format patterns.\n */\nexport const TIME_FORMATS = {\n TWELVE_HOUR: '12h',\n TWENTY_FOUR_HOUR: '24h'\n} as const;\n\n/**\n * Default calendar view options.\n */\nexport const CALENDAR_VIEWS = {\n DAY: 'day',\n WEEK: 'week',\n MONTH: 'month',\n LIST: 'list'\n} as const;\n\n/**\n * Default start of week (0 = Sunday, 1 = Monday, etc.)\n */\nexport const DEFAULT_START_OF_WEEK = 1; // Monday\n\n/**\n * Australian states and territories.\n */\nexport const AUSTRALIAN_STATES = {\n NSW: 'New South Wales',\n VIC: 'Victoria',\n QLD: 'Queensland',\n WA: 'Western Australia',\n SA: 'South Australia',\n TAS: 'Tasmania',\n ACT: 'Australian Capital Territory',\n NT: 'Northern Territory'\n} as const;\n\n/**\n * Common currency codes.\n */\nexport const CURRENCIES = {\n AUD: 'Australian Dollar',\n USD: 'US Dollar',\n EUR: 'Euro',\n GBP: 'British Pound',\n CAD: 'Canadian Dollar',\n NZD: 'New Zealand Dollar'\n} as const;\n\n/**\n * Validation patterns.\n */\nexport const VALIDATION_PATTERNS = {\n EMAIL: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/,\n PHONE_AU: /^(\\+61|0)[2-478](?:[ -]?[0-9]){8}$/,\n CURRENCY_CODE: /^[A-Z]{3}$/,\n HEX_COLOR: /^#[0-9A-F]{6}$/i,\n URL: /^https?:\\/\\/.+/\n} as const;\n\n/**\n * API configuration constants.\n */\nexport const API_CONFIG = {\n DEFAULT_PAGE_SIZE: 20,\n MAX_PAGE_SIZE: 100,\n REQUEST_TIMEOUT: 30000, // 30 seconds\n RETRY_ATTEMPTS: 3\n} as const;\n\n/**\n * File upload constraints.\n */\nexport const FILE_UPLOAD = {\n MAX_SIZE_MB: 10,\n ALLOWED_TYPES: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'],\n ALLOWED_EXTENSIONS: ['.jpg', '.jpeg', '.png', '.gif', '.pdf']\n} as const; ","/**\n * @file Shared enums for the calendar library.\n * These enums are safe to use in both client and server environments.\n */\n\n/**\n * Event types for musician-specific functionality.\n */\nexport const EVENT_TYPES = {\n GIG: 'gig',\n LESSON: 'lesson',\n AUDITION: 'audition',\n PRACTICE: 'practice',\n REHEARSAL: 'rehearsal',\n RECORDING: 'recording',\n MEETING: 'meeting'\n} as const;\n\nexport type EventType = typeof EVENT_TYPES[keyof typeof EVENT_TYPES];\n\n/**\n * Payment status options.\n */\nexport const PAYMENT_STATUS = {\n PENDING: 'Pending',\n PAID: 'Paid',\n OVERDUE: 'Overdue',\n CANCELLED: 'Cancelled'\n} as const;\n\nexport type PaymentStatus = typeof PAYMENT_STATUS[keyof typeof PAYMENT_STATUS];\n\n/**\n * Event status options.\n */\nexport const EVENT_STATUS = {\n CONFIRMED: 'Confirmed',\n TENTATIVE: 'Tentative',\n CANCELLED: 'Cancelled',\n COMPLETED: 'Completed'\n} as const;\n\nexport type EventStatus = typeof EVENT_STATUS[keyof typeof EVENT_STATUS];\n\n/**\n * Calendar types.\n */\nexport const CALENDAR_TYPES = {\n INDIVIDUAL: 'individual',\n GROUP: 'group',\n SHARED: 'shared'\n} as const;\n\nexport type CalendarType = typeof CALENDAR_TYPES[keyof typeof CALENDAR_TYPES];\n\n/**\n * Student levels for lessons.\n */\nexport const STUDENT_LEVELS = {\n BEGINNER: 'Beginner',\n INTERMEDIATE: 'Intermediate',\n ADVANCED: 'Advanced',\n PROFESSIONAL: 'Professional'\n} as const;\n\nexport type StudentLevel = typeof STUDENT_LEVELS[keyof typeof STUDENT_LEVELS];\n\n/**\n * Difficulty levels for pieces/repertoire.\n */\nexport const DIFFICULTY_LEVELS = {\n EASY: 'Easy',\n MEDIUM: 'Medium',\n HARD: 'Hard',\n EXPERT: 'Expert'\n} as const;\n\nexport type DifficultyLevel = typeof DIFFICULTY_LEVELS[keyof typeof DIFFICULTY_LEVELS];\n\n/**\n * Common musical genres.\n */\nexport const GENRES = {\n CLASSICAL: 'Classical',\n JAZZ: 'Jazz',\n ROCK: 'Rock',\n POP: 'Pop',\n BLUES: 'Blues',\n COUNTRY: 'Country',\n FOLK: 'Folk',\n ELECTRONIC: 'Electronic',\n WORLD: 'World Music',\n OTHER: 'Other'\n} as const;\n\nexport type Genre = typeof GENRES[keyof typeof GENRES];\n\n/**\n * Common instruments.\n */\nexport const INSTRUMENTS = {\n PIANO: 'Piano',\n GUITAR: 'Guitar',\n VIOLIN: 'Violin',\n DRUMS: 'Drums',\n BASS: 'Bass',\n SAXOPHONE: 'Saxophone',\n TRUMPET: 'Trumpet',\n FLUTE: 'Flute',\n CELLO: 'Cello',\n VOICE: 'Voice',\n OTHER: 'Other'\n} as const;\n\nexport type Instrument = typeof INSTRUMENTS[keyof typeof INSTRUMENTS]; "],"mappings":"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","names":["formatDateAustralian","date","months","day","getUTCDate","toString","padStart","month","getUTCMonth","year","getUTCFullYear","getDurationMinutes","start","end","Math","round","getTime","isSameDay","date1","date2","toDateString","getStartOfWeek","result","Date","getDay","diff","getDate","setDate","setHours","getEndOfWeek","isValidEmail","email","emailRegex","test","isValidPhone","phone","phoneRegex","replace","generateTempId","now","random","substr","DEFAULT_CURRENCY","MAX_EVENT_DURATION_HOURS","MAX_RECURRENCE_OCCURRENCES","DEFAULT_EVENT_DURATION_MINUTES","MAX_LENGTHS","EVENT_TITLE","EVENT_DESCRIPTION","CALENDAR_NAME","CALENDAR_DESCRIPTION","VENUE_NAME","VENUE_ADDRESS","VENUE_CITY","CONTACT_NAME","CONTACT_ROLE","NOTES","INCOME_DESCRIPTION","EXPENSE_DESCRIPTION","RECEIPT_PATH","DATE_FORMATS","AUSTRALIAN","AMERICAN","ISO","TIME_FORMATS","TWELVE_HOUR","TWENTY_FOUR_HOUR","CALENDAR_VIEWS","DAY","WEEK","MONTH","LIST","DEFAULT_START_OF_WEEK","AUSTRALIAN_STATES","NSW","VIC","QLD","WA","SA","TAS","ACT","NT","CURRENCIES","AUD","USD","EUR","GBP","CAD","NZD","VALIDATION_PATTERNS","EMAIL","PHONE_AU","CURRENCY_CODE","HEX_COLOR","URL","API_CONFIG","DEFAULT_PAGE_SIZE","MAX_PAGE_SIZE","REQUEST_TIMEOUT","RETRY_ATTEMPTS","FILE_UPLOAD","MAX_SIZE_MB","ALLOWED_TYPES","ALLOWED_EXTENSIONS","EVENT_TYPES","GIG","LESSON","AUDITION","PRACTICE","REHEARSAL","RECORDING","MEETING","PAYMENT_STATUS","PENDING","PAID","OVERDUE","CANCELLED","EVENT_STATUS","CONFIRMED","TENTATIVE","COMPLETED","CALENDAR_TYPES","INDIVIDUAL","GROUP","SHARED","STUDENT_LEVELS","BEGINNER","INTERMEDIATE","ADVANCED","PROFESSIONAL","DIFFICULTY_LEVELS","EASY","MEDIUM","HARD","EXPERT","GENRES","CLASSICAL","JAZZ","ROCK","POP","BLUES","COUNTRY","FOLK","ELECTRONIC","WORLD","OTHER","INSTRUMENTS","PIANO","GUITAR","VIOLIN","DRUMS","BASS","SAXOPHONE","TRUMPET","FLUTE","CELLO","VOICE"]}