@@ -6,8 +6,18 @@ import { VALUE_OUT_OF_RANGE_ERROR_MESSAGE, UNRECOGNIZABLE_VALUE_ERROR_MESSAGE, R
66import { DayOfWeek , RecurrenceSpec , RecurrencePattern , RecurrenceRange , RecurrencePatternType , RecurrenceRangeType , DAYS_PER_WEEK , ONE_DAY_IN_MILLISECONDS } from "./model.js" ;
77import { calculateWeeklyDayOffset , sortDaysOfWeek , getDayOfWeek } from "./utils.js" ;
88
9- const START_NOT_MATCHED_ERROR_MESSAGE = "Start date is not a valid first occurrence." ;
10- const TIME_WINDOW_DURATION_OUT_OF_RANGE_ERROR_MESSAGE = "Time window duration cannot be longer than how frequently it occurs or be longer than 10 years." ;
9+ export const START_NOT_MATCHED_ERROR_MESSAGE = "Start date is not a valid first occurrence." ;
10+ export const TIME_WINDOW_DURATION_OUT_OF_RANGE_ERROR_MESSAGE = "Time window duration cannot be longer than how frequently it occurs or be longer than 10 years." ;
11+ export const PATTERN = "Recurrence.Pattern" ;
12+ export const PATTERN_TYPE = "Recurrence.Pattern.Type" ;
13+ export const INTERVAL = "Recurrence.Pattern.Interval" ;
14+ export const DAYS_OF_WEEK = "Recurrence.Pattern.DaysOfWeek" ;
15+ export const FIRST_DAY_OF_WEEK = "Recurrence.Pattern.FirstDayOfWeek" ;
16+ export const RANGE = "Recurrence.Range" ;
17+ export const RANGE_TYPE = "Recurrence.Range.Type" ;
18+ export const END_DATE = "Recurrence.Range.EndDate" ;
19+ export const NUMBER_OF_OCCURRENCES = "Recurrence.Range.NumberOfOccurrences" ;
20+
1121
1222/**
1323 * Parses @see RecurrenceParameter into a @see RecurrenceSpec object. If the parameter is invalid, an error will be thrown.
@@ -44,21 +54,21 @@ export function parseRecurrenceParameter(startTime: Date | undefined, endTime: D
4454function parseRecurrencePattern ( startTime : Date , endTime : Date , recurrenceParameter : RecurrenceParameter , timeZoneOffset : number ) : RecurrencePattern {
4555 const rawPattern = recurrenceParameter . Pattern ;
4656 if ( rawPattern === undefined ) {
47- throw new Error ( buildInvalidParameterErrorMessage ( "Pattern" , REQUIRED_PARAMETER_MISSING_ERROR_MESSAGE ) ) ;
57+ throw new Error ( buildInvalidParameterErrorMessage ( PATTERN , REQUIRED_PARAMETER_MISSING_ERROR_MESSAGE ) ) ;
4858 }
4959 if ( rawPattern . Type === undefined ) {
50- throw new Error ( buildInvalidParameterErrorMessage ( "Pattern.Type" , REQUIRED_PARAMETER_MISSING_ERROR_MESSAGE ) ) ;
60+ throw new Error ( buildInvalidParameterErrorMessage ( PATTERN_TYPE , REQUIRED_PARAMETER_MISSING_ERROR_MESSAGE ) ) ;
5161 }
5262 const patternType = RecurrencePatternType [ rawPattern . Type ] ;
5363 if ( patternType === undefined ) {
54- throw new Error ( buildInvalidParameterErrorMessage ( "Pattern.Type" , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
64+ throw new Error ( buildInvalidParameterErrorMessage ( PATTERN_TYPE , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
5565 }
5666 let interval = rawPattern . Interval ;
5767 if ( interval !== undefined ) {
5868 if ( typeof interval !== "number" ) {
59- throw new Error ( buildInvalidParameterErrorMessage ( "Pattern.Interval" , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
69+ throw new Error ( buildInvalidParameterErrorMessage ( INTERVAL , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
6070 } else if ( interval <= 0 || ! Number . isInteger ( interval ) ) {
61- throw new Error ( buildInvalidParameterErrorMessage ( "Pattern.Interval" , VALUE_OUT_OF_RANGE_ERROR_MESSAGE ) ) ;
71+ throw new Error ( buildInvalidParameterErrorMessage ( INTERVAL , VALUE_OUT_OF_RANGE_ERROR_MESSAGE ) ) ;
6272 }
6373 } else {
6474 interval = 1 ;
@@ -77,7 +87,7 @@ function parseRecurrencePattern(startTime: Date, endTime: Date, recurrenceParame
7787 if ( rawPattern . FirstDayOfWeek !== undefined ) {
7888 firstDayOfWeek = DayOfWeek [ rawPattern . FirstDayOfWeek ] ;
7989 if ( firstDayOfWeek === undefined ) {
80- throw new Error ( buildInvalidParameterErrorMessage ( "Pattern.FirstDayOfWeek" , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
90+ throw new Error ( buildInvalidParameterErrorMessage ( FIRST_DAY_OF_WEEK , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
8191 }
8292 }
8393 else {
@@ -86,11 +96,14 @@ function parseRecurrencePattern(startTime: Date, endTime: Date, recurrenceParame
8696 parsedPattern . firstDayOfWeek = firstDayOfWeek ;
8797
8898 if ( rawPattern . DaysOfWeek === undefined || rawPattern . DaysOfWeek . length === 0 ) {
89- throw new Error ( buildInvalidParameterErrorMessage ( "Pattern.DaysOfWeek" , REQUIRED_PARAMETER_MISSING_ERROR_MESSAGE ) ) ;
99+ throw new Error ( buildInvalidParameterErrorMessage ( DAYS_OF_WEEK , REQUIRED_PARAMETER_MISSING_ERROR_MESSAGE ) ) ;
100+ }
101+ if ( ! Array . isArray ( rawPattern . DaysOfWeek ) ) {
102+ throw new Error ( buildInvalidParameterErrorMessage ( DAYS_OF_WEEK , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
90103 }
91104 const daysOfWeek = [ ...new Set ( rawPattern . DaysOfWeek . map ( day => DayOfWeek [ day ] ) ) ] ; // dedup array
92105 if ( daysOfWeek . some ( day => day === undefined ) ) {
93- throw new Error ( buildInvalidParameterErrorMessage ( "Pattern.DaysOfWeek" , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
106+ throw new Error ( buildInvalidParameterErrorMessage ( DAYS_OF_WEEK , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
94107 }
95108 if ( timeWindowDuration > interval * DAYS_PER_WEEK * ONE_DAY_IN_MILLISECONDS ||
96109 ! IsDurationCompliantWithDaysOfWeek ( timeWindowDuration , interval , daysOfWeek , firstDayOfWeek ) ) {
@@ -110,25 +123,25 @@ function parseRecurrencePattern(startTime: Date, endTime: Date, recurrenceParame
110123function parseRecurrenceRange ( startTime : Date , recurrenceParameter : RecurrenceParameter ) : RecurrenceRange {
111124 const rawRange = recurrenceParameter . Range ;
112125 if ( rawRange === undefined ) {
113- throw new Error ( buildInvalidParameterErrorMessage ( "Range" , REQUIRED_PARAMETER_MISSING_ERROR_MESSAGE ) ) ;
126+ throw new Error ( buildInvalidParameterErrorMessage ( RANGE , REQUIRED_PARAMETER_MISSING_ERROR_MESSAGE ) ) ;
114127 }
115128 if ( rawRange . Type === undefined ) {
116- throw new Error ( buildInvalidParameterErrorMessage ( "Range.Type" , REQUIRED_PARAMETER_MISSING_ERROR_MESSAGE ) ) ;
129+ throw new Error ( buildInvalidParameterErrorMessage ( RANGE_TYPE , REQUIRED_PARAMETER_MISSING_ERROR_MESSAGE ) ) ;
117130 }
118131 const rangeType = RecurrenceRangeType [ rawRange . Type ] ;
119132 if ( rangeType === undefined ) {
120- throw new Error ( buildInvalidParameterErrorMessage ( "Range.Type" , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
133+ throw new Error ( buildInvalidParameterErrorMessage ( RANGE_TYPE , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
121134 }
122135 const parsedRange : RecurrenceRange = { type : rangeType } ;
123136 if ( rangeType === RecurrenceRangeType . EndDate ) {
124137 let endDate : Date ;
125138 if ( rawRange . EndDate !== undefined ) {
126139 endDate = new Date ( rawRange . EndDate ) ;
127140 if ( isNaN ( endDate . getTime ( ) ) ) {
128- throw new Error ( buildInvalidParameterErrorMessage ( "Range.EndDate" , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
141+ throw new Error ( buildInvalidParameterErrorMessage ( END_DATE , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
129142 }
130143 if ( endDate < startTime ) {
131- throw new Error ( buildInvalidParameterErrorMessage ( "Range.EndDate" , VALUE_OUT_OF_RANGE_ERROR_MESSAGE ) ) ;
144+ throw new Error ( buildInvalidParameterErrorMessage ( END_DATE , VALUE_OUT_OF_RANGE_ERROR_MESSAGE ) ) ;
132145 }
133146 } else {
134147 endDate = new Date ( 8.64e15 ) ; // the maximum date in ECMAScript: https://262.ecma-international.org/5.1/#sec-15.9.1.1
@@ -138,9 +151,9 @@ function parseRecurrenceRange(startTime: Date, recurrenceParameter: RecurrencePa
138151 let numberOfOccurrences = rawRange . NumberOfOccurrences ;
139152 if ( numberOfOccurrences !== undefined ) {
140153 if ( typeof numberOfOccurrences !== "number" ) {
141- throw new Error ( buildInvalidParameterErrorMessage ( "Range.NumberOfOccurrences" , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
154+ throw new Error ( buildInvalidParameterErrorMessage ( NUMBER_OF_OCCURRENCES , UNRECOGNIZABLE_VALUE_ERROR_MESSAGE ) ) ;
142155 } else if ( numberOfOccurrences <= 0 || ! Number . isInteger ( numberOfOccurrences ) ) {
143- throw new Error ( buildInvalidParameterErrorMessage ( "Range.NumberOfOccurrences" , VALUE_OUT_OF_RANGE_ERROR_MESSAGE ) ) ;
156+ throw new Error ( buildInvalidParameterErrorMessage ( NUMBER_OF_OCCURRENCES , VALUE_OUT_OF_RANGE_ERROR_MESSAGE ) ) ;
144157 }
145158 } else {
146159 numberOfOccurrences = Number . MAX_SAFE_INTEGER ;
0 commit comments