@webamoki/web-svelte 1.2.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/README.md +3 -1
  2. package/dist/components/showcase/CodeBlock.svelte +1 -1
  3. package/dist/{components → shared/components}/form/Button.svelte +2 -2
  4. package/dist/{components → shared/components}/form/Button.svelte.d.ts +2 -2
  5. package/dist/{components → shared/components}/form/Errors.svelte +1 -1
  6. package/dist/{components → shared/components}/form/FieldWrapper.svelte +1 -1
  7. package/dist/{components → shared/components}/form/fields/ChoiceMultiField.svelte +3 -1
  8. package/dist/{components → shared/components}/form/fields/DateField.svelte +2 -2
  9. package/dist/{components → shared/components}/form/fields/MessageField.svelte +2 -2
  10. package/dist/{components → shared/components}/form/fields/NumberField.svelte +2 -2
  11. package/dist/{components → shared/components}/form/fields/PasswordField.svelte +2 -2
  12. package/dist/{components → shared/components}/form/fields/SelectField.svelte +3 -3
  13. package/dist/{components → shared/components}/form/fields/SelectMultiField.svelte +3 -3
  14. package/dist/{components → shared/components}/form/fields/TextField.svelte +2 -2
  15. package/dist/{components → shared/components}/form/fields/TextFieldNullable.svelte +2 -2
  16. package/dist/{components → shared/components}/form/fields/TimeField.svelte +2 -2
  17. package/dist/{components → shared/components}/ui/choice/ChoiceInternal.svelte +1 -1
  18. package/dist/{components → shared/components}/ui/choice/WeekdayChoice.svelte +6 -3
  19. package/dist/{components → shared/components}/ui/choice/WeekdayChoice.svelte.d.ts +1 -1
  20. package/dist/{components → shared/components}/ui/choice/WeekdayChoiceMulti.svelte +6 -3
  21. package/dist/{components → shared/components}/ui/choice/WeekdayChoiceMulti.svelte.d.ts +1 -1
  22. package/dist/{components → shared/components}/ui/context-menu/ContextMenuContent.svelte +1 -1
  23. package/dist/{components → shared/components}/ui/context-menu/ContextMenuItem.svelte +1 -1
  24. package/dist/{components → shared/components}/ui/search/SearchBar.svelte +2 -2
  25. package/dist/{utils/types → shared/utils}/arktype.d.ts +4 -12
  26. package/dist/shared/utils/arktype.js +40 -0
  27. package/dist/{utils → shared/utils}/datetime/datetime.spec.js +39 -26
  28. package/dist/{utils → shared/utils}/datetime/index.d.ts +52 -34
  29. package/dist/{utils → shared/utils}/datetime/index.js +105 -78
  30. package/dist/{utils → shared/utils}/email/README.md +5 -5
  31. package/dist/{utils → shared/utils}/email/ses.js +17 -9
  32. package/dist/shared/utils/functional/index.d.ts +2 -0
  33. package/dist/shared/utils/functional/index.js +2 -0
  34. package/dist/shared/utils/functional/result.d.ts +72 -0
  35. package/dist/shared/utils/functional/result.js +86 -0
  36. package/dist/shared/utils/functional/result.spec.d.ts +1 -0
  37. package/dist/shared/utils/functional/result.spec.js +96 -0
  38. package/dist/shared/utils/remote.d.ts +28 -0
  39. package/dist/shared/utils/remote.js +74 -0
  40. package/dist/{utils/search.d.ts → shared/utils/string.d.ts} +1 -0
  41. package/dist/{utils/search.js → shared/utils/string.js} +13 -4
  42. package/package.json +27 -30
  43. package/dist/utils/email/aws-signer.d.ts +0 -17
  44. package/dist/utils/email/aws-signer.js +0 -83
  45. package/dist/utils/string.d.ts +0 -1
  46. package/dist/utils/string.js +0 -4
  47. package/dist/utils/types/arktype.js +0 -92
  48. package/dist/utils/types/consts.d.ts +0 -5
  49. package/dist/utils/types/consts.js +0 -5
  50. package/dist/utils/types/db.d.ts +0 -57
  51. package/dist/utils/types/db.js +0 -34
  52. /package/dist/{components → shared/components}/form/Errors.svelte.d.ts +0 -0
  53. /package/dist/{components → shared/components}/form/FieldWrapper.svelte.d.ts +0 -0
  54. /package/dist/{components → shared/components}/form/Form.svelte +0 -0
  55. /package/dist/{components → shared/components}/form/Form.svelte.d.ts +0 -0
  56. /package/dist/{components → shared/components}/form/IconInputWrapper.svelte +0 -0
  57. /package/dist/{components → shared/components}/form/IconInputWrapper.svelte.d.ts +0 -0
  58. /package/dist/{components → shared/components}/form/fields/ChoiceField.svelte +0 -0
  59. /package/dist/{components → shared/components}/form/fields/ChoiceField.svelte.d.ts +0 -0
  60. /package/dist/{components → shared/components}/form/fields/ChoiceMultiField.svelte.d.ts +0 -0
  61. /package/dist/{components → shared/components}/form/fields/DateField.svelte.d.ts +0 -0
  62. /package/dist/{components → shared/components}/form/fields/HexColorField.svelte +0 -0
  63. /package/dist/{components → shared/components}/form/fields/HexColorField.svelte.d.ts +0 -0
  64. /package/dist/{components → shared/components}/form/fields/MessageField.svelte.d.ts +0 -0
  65. /package/dist/{components → shared/components}/form/fields/NumberField.svelte.d.ts +0 -0
  66. /package/dist/{components → shared/components}/form/fields/PasswordField.svelte.d.ts +0 -0
  67. /package/dist/{components → shared/components}/form/fields/SelectField.svelte.d.ts +0 -0
  68. /package/dist/{components → shared/components}/form/fields/SelectMultiField.svelte.d.ts +0 -0
  69. /package/dist/{components → shared/components}/form/fields/TextField.svelte.d.ts +0 -0
  70. /package/dist/{components → shared/components}/form/fields/TextFieldNullable.svelte.d.ts +0 -0
  71. /package/dist/{components → shared/components}/form/fields/TimeField.svelte.d.ts +0 -0
  72. /package/dist/{components → shared/components}/form/fields/WeekdayChoiceField.svelte +0 -0
  73. /package/dist/{components → shared/components}/form/fields/WeekdayChoiceField.svelte.d.ts +0 -0
  74. /package/dist/{components → shared/components}/form/fields/WeekdayChoiceMultiField.svelte +0 -0
  75. /package/dist/{components → shared/components}/form/fields/WeekdayChoiceMultiField.svelte.d.ts +0 -0
  76. /package/dist/{components → shared/components}/form/index.d.ts +0 -0
  77. /package/dist/{components → shared/components}/form/index.js +0 -0
  78. /package/dist/{components → shared/components}/ui/choice/Choice.svelte +0 -0
  79. /package/dist/{components → shared/components}/ui/choice/Choice.svelte.d.ts +0 -0
  80. /package/dist/{components → shared/components}/ui/choice/ChoiceInternal.svelte.d.ts +0 -0
  81. /package/dist/{components → shared/components}/ui/choice/ChoiceMulti.svelte +0 -0
  82. /package/dist/{components → shared/components}/ui/choice/ChoiceMulti.svelte.d.ts +0 -0
  83. /package/dist/{components → shared/components}/ui/context-menu/ContextMenu.svelte +0 -0
  84. /package/dist/{components → shared/components}/ui/context-menu/ContextMenu.svelte.d.ts +0 -0
  85. /package/dist/{components → shared/components}/ui/context-menu/ContextMenuContent.svelte.d.ts +0 -0
  86. /package/dist/{components → shared/components}/ui/context-menu/ContextMenuItem.svelte.d.ts +0 -0
  87. /package/dist/{components → shared/components}/ui/context-menu/ContextMenuSeparator.svelte +0 -0
  88. /package/dist/{components → shared/components}/ui/context-menu/ContextMenuSeparator.svelte.d.ts +0 -0
  89. /package/dist/{components → shared/components}/ui/context-menu/ContextMenuTrigger.svelte +0 -0
  90. /package/dist/{components → shared/components}/ui/context-menu/ContextMenuTrigger.svelte.d.ts +0 -0
  91. /package/dist/{components → shared/components}/ui/context-menu/context-menu-state.svelte.d.ts +0 -0
  92. /package/dist/{components → shared/components}/ui/context-menu/context-menu-state.svelte.js +0 -0
  93. /package/dist/{components → shared/components}/ui/drag-drop/Draggable.svelte +0 -0
  94. /package/dist/{components → shared/components}/ui/drag-drop/Draggable.svelte.d.ts +0 -0
  95. /package/dist/{components → shared/components}/ui/drag-drop/Dropzone.svelte +0 -0
  96. /package/dist/{components → shared/components}/ui/drag-drop/Dropzone.svelte.d.ts +0 -0
  97. /package/dist/{components → shared/components}/ui/drag-drop/drag-manager.d.ts +0 -0
  98. /package/dist/{components → shared/components}/ui/drag-drop/drag-manager.js +0 -0
  99. /package/dist/{components → shared/components}/ui/index.d.ts +0 -0
  100. /package/dist/{components → shared/components}/ui/index.js +0 -0
  101. /package/dist/{components → shared/components}/ui/search/SearchBar.svelte.d.ts +0 -0
  102. /package/dist/{server → shared/server}/form-handler.d.ts +0 -0
  103. /package/dist/{server → shared/server}/form-handler.js +0 -0
  104. /package/dist/{server → shared/server}/form-processor.d.ts +0 -0
  105. /package/dist/{server → shared/server}/form-processor.js +0 -0
  106. /package/dist/{utils → shared/utils}/datetime/datetime.spec.d.ts +0 -0
  107. /package/dist/{utils → shared/utils}/email/index.d.ts +0 -0
  108. /package/dist/{utils → shared/utils}/email/index.js +0 -0
  109. /package/dist/{utils → shared/utils}/email/ses.d.ts +0 -0
  110. /package/dist/{utils → shared/utils}/email/ses.test.d.ts +0 -0
  111. /package/dist/{utils → shared/utils}/email/ses.test.js +0 -0
  112. /package/dist/{utils → shared/utils}/form/index.d.ts +0 -0
  113. /package/dist/{utils → shared/utils}/form/index.js +0 -0
  114. /package/dist/{utils → shared/utils}/form/virtual-form.d.ts +0 -0
  115. /package/dist/{utils → shared/utils}/form/virtual-form.js +0 -0
  116. /package/dist/{highlight.d.ts → utils/highlight.d.ts} +0 -0
  117. /package/dist/{highlight.js → utils/highlight.js} +0 -0
@@ -1,15 +1,48 @@
1
1
  import type { Transport } from '@sveltejs/kit';
2
2
  import { CalendarDate, type DateDuration, Time, ZonedDateTime } from '@internationalized/date';
3
- import type { Day } from '../types/arktype.js';
4
3
  export declare const Days: readonly ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
4
+ export type Day = (typeof Days)[number];
5
5
  export declare const DayIndex: Record<Day, number>;
6
+ export declare class LocalDateF {
7
+ private readonly timezone;
8
+ constructor(timezone: string);
9
+ /**
10
+ * Calculates the age from a date of birth.
11
+ * @param dob - The date of birth.
12
+ * @returns The age in years.
13
+ * @throws Error if the date of birth is in the future.
14
+ */
15
+ ageFromDob(dob: CalendarDate): number;
16
+ /**
17
+ * Checks if a given date is today.
18
+ * @param date - The date to check.
19
+ * @returns True if the date is today, false otherwise.
20
+ */
21
+ isDateToday(date: CalendarDate): boolean;
22
+ /**
23
+ * @returns The current date and time.
24
+ */
25
+ now(): ZonedDateTime;
26
+ /**
27
+ * @returns The current date.
28
+ */
29
+ today(): CalendarDate;
30
+ }
31
+ /** Gets the day index of the date */
32
+ export declare function getDayIndexOfDate(date: CalendarDate): number;
6
33
  /**
7
- * Calculates the age from a date of birth.
8
- * @param dob - The date of birth.
9
- * @returns The age in years.
10
- * @throws Error if the date of birth is in the future.
34
+ * Gets the day of the week for a given date.
35
+ * @param date - The date to get the day of the week for.
36
+ * @returns The day of the week
11
37
  */
12
- export declare function ageFromDob(dob: CalendarDate, timezone: string): number;
38
+ export declare function getDayOfDate(date: CalendarDate): Day;
39
+ /**
40
+ * Checks if a given date is a specific day of the week.
41
+ * @param date - The date to check.
42
+ * @param dayOfWeek - The day of the week to check against.
43
+ * @returns True if the date is the specified day, false otherwise.
44
+ */
45
+ export declare function isDateDay(date: CalendarDate, dayOfWeek: Day): boolean;
13
46
  /**
14
47
  * Checks if two time ranges overlap, boundaries are not considered overlapping.
15
48
  * @param start1 - The start time of the first range.
@@ -27,14 +60,6 @@ export declare function checkOverlap(start1: Time, end1: Time, start2: Time, end
27
60
  * @returns True if the dates are within duration, false otherwise.
28
61
  */
29
62
  export declare function datesWithin(date1: CalendarDate, date2: CalendarDate, duration: DateDuration): boolean;
30
- /** Gets the day index of the date */
31
- export declare function getDayIndex(date: CalendarDate): number;
32
- /**
33
- * Gets the day of the week for a given date.
34
- * @param date - The date to get the day of the week for.
35
- * @returns The day of the week
36
- */
37
- export declare function getDayOfDate(date: CalendarDate): Day;
38
63
  /**
39
64
  * Gets the most recent occurrence of a day of the week.
40
65
  * @param dayOfWeek - The day of the week
@@ -66,19 +91,6 @@ export declare function getLastMonths(count: number, startDate: CalendarDate): C
66
91
  * @returns The date of the next occurrence of the specified day.
67
92
  */
68
93
  export declare function getNextDateOfDay(dayOfWeek: Day, startDate: CalendarDate): CalendarDate;
69
- /**
70
- * Checks if a given date is a specific day of the week.
71
- * @param date - The date to check.
72
- * @param dayOfWeek - The day of the week to check against.
73
- * @returns True if the date is the specified day, false otherwise.
74
- */
75
- export declare function isDateDay(date: CalendarDate, dayOfWeek: Day): boolean;
76
- /**
77
- * Checks if a given date is today.
78
- * @param date - The date to check.
79
- * @returns True if the date is today, false otherwise.
80
- */
81
- export declare function isDateToday(date: CalendarDate, timezone: string): boolean;
82
94
  /**
83
95
  * Calculates the difference in weeks between two dates.
84
96
  * @param date1 - The first date in order.
@@ -135,9 +147,15 @@ export declare function formatDateShort(date: CalendarDate): string;
135
147
  * Formats the month only.
136
148
  * @param date - The date to format.
137
149
  * @returns The formatted month string.
138
- * @example "Oct"
150
+ * @example "Oct 23"
139
151
  */
140
152
  export declare function formatMonth(date: CalendarDate): string;
153
+ /**
154
+ * Gives time in HH:MM format
155
+ * @param time
156
+ * @returns string of time in that format
157
+ */
158
+ export declare function formatTime(time: Time): string;
141
159
  /**
142
160
  * Calculates the end time given a starting time and duration.
143
161
  * @param timeStart starting time
@@ -151,12 +169,6 @@ export declare function formatTimeEnd(timeStart: Time, durationMinutes: number):
151
169
  * @returns string of time in that format
152
170
  */
153
171
  export declare function formatTimeFull(time: Time): string;
154
- /**
155
- * Gives time in HH:MM format
156
- * @param time
157
- * @returns string of time in that format
158
- */
159
- export declare function formatTimeShort(time: Time): string;
160
172
  /**
161
173
  * Unfreezes a CalendarDate object from a snapshot.
162
174
  * @param raw - The snapshot of the CalendarDate object.
@@ -169,4 +181,10 @@ export declare function unfreezeDate(raw: ReturnType<typeof $state.snapshot<Cale
169
181
  * @returns The unfrozen Time object.
170
182
  */
171
183
  export declare function unfreezeTime(raw: ReturnType<typeof $state.snapshot<Time>>): Time;
184
+ /**
185
+ * Unfreezes a ZonedDateTime object from a snapshot.
186
+ * @param date - The snapshot of the ZonedDateTime object.
187
+ * @returns The unfrozen ZonedDateTime object.
188
+ */
189
+ export declare function unfreezeAbsoluteDate(date: ReturnType<typeof $state.snapshot<ZonedDateTime>>): ZonedDateTime;
172
190
  export declare const dateTransport: Transport;
@@ -1,6 +1,5 @@
1
- import { CalendarDate, DateFormatter, fromDate, getDayOfWeek, getLocalTimeZone, startOfMonth, Time, toCalendarDate, today, toTime, ZonedDateTime } from '@internationalized/date';
1
+ import { CalendarDate, DateFormatter, fromDate, getDayOfWeek, getLocalTimeZone, now as nowFn, startOfMonth, Time, toCalendarDate, today as todayFn, toTime, ZonedDateTime } from '@internationalized/date';
2
2
  import { map, range } from 'ramda';
3
- const DEFAULT_TIME_ZONE = 'Europe/London';
4
3
  const DEFAULT_LOCALE = 'en-GB';
5
4
  // Day of the week
6
5
  export const Days = [
@@ -13,26 +12,77 @@ export const Days = [
13
12
  'Sunday'
14
13
  ];
15
14
  export const DayIndex = Object.fromEntries(Days.map((day, index) => [day, index]));
16
- /**
17
- * Calculates the age from a date of birth.
18
- * @param dob - The date of birth.
19
- * @returns The age in years.
20
- * @throws Error if the date of birth is in the future.
21
- */
22
- export function ageFromDob(dob, timezone) {
23
- const todayDate = today(timezone);
24
- if (todayDate.compare(dob) < 0) {
25
- throw new Error('Date of birth is in the future');
15
+ // Date functions local to a timezone
16
+ export class LocalDateF {
17
+ timezone;
18
+ constructor(timezone) {
19
+ this.timezone = timezone;
20
+ }
21
+ /**
22
+ * Calculates the age from a date of birth.
23
+ * @param dob - The date of birth.
24
+ * @returns The age in years.
25
+ * @throws Error if the date of birth is in the future.
26
+ */
27
+ ageFromDob(dob) {
28
+ const todayDate = this.today();
29
+ if (todayDate.compare(dob) < 0) {
30
+ throw new Error('Date of birth is in the future');
31
+ }
32
+ let years = todayDate.year - dob.year;
33
+ const monthDiff = todayDate.month - dob.month;
34
+ const dayDiff = todayDate.day - dob.day;
35
+ // Adjust years down if birthday hasn't occurred this year
36
+ if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
37
+ years--;
38
+ }
39
+ return years;
26
40
  }
27
- let years = todayDate.year - dob.year;
28
- const monthDiff = todayDate.month - dob.month;
29
- const dayDiff = todayDate.day - dob.day;
30
- // Adjust years down if birthday hasn't occurred this year
31
- if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
32
- years--;
41
+ /**
42
+ * Checks if a given date is today.
43
+ * @param date - The date to check.
44
+ * @returns True if the date is today, false otherwise.
45
+ */
46
+ isDateToday(date) {
47
+ return this.today().compare(date) === 0;
33
48
  }
34
- return years;
49
+ /**
50
+ * @returns The current date and time.
51
+ */
52
+ now() {
53
+ return nowFn(this.timezone);
54
+ }
55
+ /**
56
+ * @returns The current date.
57
+ */
58
+ today() {
59
+ return todayFn(this.timezone);
60
+ }
61
+ }
62
+ /** Gets the day index of the date */
63
+ export function getDayIndexOfDate(date) {
64
+ // Always start 0 on Monday
65
+ return getDayOfWeek(date, DEFAULT_LOCALE, 'mon');
66
+ }
67
+ /**
68
+ * Gets the day of the week for a given date.
69
+ * @param date - The date to get the day of the week for.
70
+ * @returns The day of the week
71
+ */
72
+ export function getDayOfDate(date) {
73
+ return Days[getDayIndexOfDate(date)];
74
+ }
75
+ /**
76
+ * Checks if a given date is a specific day of the week.
77
+ * @param date - The date to check.
78
+ * @param dayOfWeek - The day of the week to check against.
79
+ * @returns True if the date is the specified day, false otherwise.
80
+ */
81
+ export function isDateDay(date, dayOfWeek) {
82
+ const dateDay = getDayOfDate(date);
83
+ return dateDay === dayOfWeek;
35
84
  }
85
+ /* Intervals */
36
86
  /**
37
87
  * Checks if two time ranges overlap, boundaries are not considered overlapping.
38
88
  * @param start1 - The start time of the first range.
@@ -57,19 +107,6 @@ export function datesWithin(date1, date2, duration) {
57
107
  return false;
58
108
  return date1.add(duration).compare(date2) >= 0;
59
109
  }
60
- /** Gets the day index of the date */
61
- export function getDayIndex(date) {
62
- // Always start 0 on Monday
63
- return getDayOfWeek(date, DEFAULT_LOCALE, 'mon');
64
- }
65
- /**
66
- * Gets the day of the week for a given date.
67
- * @param date - The date to get the day of the week for.
68
- * @returns The day of the week
69
- */
70
- export function getDayOfDate(date) {
71
- return Days[getDayIndex(date)];
72
- }
73
110
  /**
74
111
  * Gets the most recent occurrence of a day of the week.
75
112
  * @param dayOfWeek - The day of the week
@@ -79,7 +116,7 @@ export function getDayOfDate(date) {
79
116
  */
80
117
  export function getLastDateOfDay(dayOfWeek, startDate) {
81
118
  const dayIndex = DayIndex[dayOfWeek];
82
- const startIndex = getDayIndex(startDate);
119
+ const startIndex = getDayIndexOfDate(startDate);
83
120
  // Already on the day
84
121
  if (startIndex === dayIndex)
85
122
  return startDate;
@@ -126,7 +163,7 @@ export function getLastMonths(count, startDate) {
126
163
  */
127
164
  export function getNextDateOfDay(dayOfWeek, startDate) {
128
165
  const dayIndex = DayIndex[dayOfWeek];
129
- const startIndex = getDayIndex(startDate);
166
+ const startIndex = getDayIndexOfDate(startDate);
130
167
  // Already on the day
131
168
  if (startIndex === dayIndex)
132
169
  return startDate;
@@ -134,25 +171,6 @@ export function getNextDateOfDay(dayOfWeek, startDate) {
134
171
  const addition = (dayIndex - startIndex + 7) % 7;
135
172
  return startDate.add({ days: addition });
136
173
  }
137
- /* Intervals */
138
- /**
139
- * Checks if a given date is a specific day of the week.
140
- * @param date - The date to check.
141
- * @param dayOfWeek - The day of the week to check against.
142
- * @returns True if the date is the specified day, false otherwise.
143
- */
144
- export function isDateDay(date, dayOfWeek) {
145
- const dateDay = getDayOfDate(date);
146
- return dateDay === dayOfWeek;
147
- }
148
- /**
149
- * Checks if a given date is today.
150
- * @param date - The date to check.
151
- * @returns True if the date is today, false otherwise.
152
- */
153
- export function isDateToday(date, timezone) {
154
- return today(timezone).compare(date) === 0;
155
- }
156
174
  const msPerWeek = 7 * 24 * 60 * 60 * 1000;
157
175
  /**
158
176
  * Calculates the difference in weeks between two dates.
@@ -160,9 +178,10 @@ const msPerWeek = 7 * 24 * 60 * 60 * 1000;
160
178
  * @param date2 - The second date in order.
161
179
  */
162
180
  export function dateDiffWeeks(date1, date2) {
163
- const date1Abs = date1.toDate(DEFAULT_TIME_ZONE).getTime();
164
- const date2Abs = date2.toDate(DEFAULT_TIME_ZONE).getTime();
165
- return Math.floor((date2Abs - date1Abs) / msPerWeek);
181
+ const date1Ms = date1.toDate('UTC').getTime();
182
+ const date2Ms = date2.toDate('UTC').getTime();
183
+ const absDiff = Math.abs(date2Ms - date1Ms);
184
+ return Math.floor(absDiff / msPerWeek);
166
185
  }
167
186
  /* Formatting */
168
187
  /* Day of the week*/
@@ -253,12 +272,22 @@ export function formatDateShort(date) {
253
272
  * Formats the month only.
254
273
  * @param date - The date to format.
255
274
  * @returns The formatted month string.
256
- * @example "Oct"
275
+ * @example "Oct 23"
257
276
  */
258
277
  export function formatMonth(date) {
259
278
  return formatDate(date, MonthFormatter);
260
279
  }
261
280
  /* Times */
281
+ /**
282
+ * Gives time in HH:MM format
283
+ * @param time
284
+ * @returns string of time in that format
285
+ */
286
+ export function formatTime(time) {
287
+ const hours = padNum(time.hour, 2);
288
+ const minutes = padNum(time.minute, 2);
289
+ return `${hours}:${minutes}`;
290
+ }
262
291
  /**
263
292
  * Calculates the end time given a starting time and duration.
264
293
  * @param timeStart starting time
@@ -267,7 +296,7 @@ export function formatMonth(date) {
267
296
  */
268
297
  export function formatTimeEnd(timeStart, durationMinutes) {
269
298
  const timeEnd = timeStart.add({ minutes: durationMinutes });
270
- return formatTimeShort(timeEnd);
299
+ return formatTime(timeEnd);
271
300
  }
272
301
  /**
273
302
  * Gives time in HH:MM:SS format
@@ -280,16 +309,18 @@ export function formatTimeFull(time) {
280
309
  const seconds = padNum(time.second, 2);
281
310
  return `${hours}:${minutes}:${seconds}`;
282
311
  }
283
- /**
284
- * Gives time in HH:MM format
285
- * @param time
286
- * @returns string of time in that format
287
- */
288
- export function formatTimeShort(time) {
289
- const hours = padNum(time.hour, 2);
290
- const minutes = padNum(time.minute, 2);
291
- return `${hours}:${minutes}`;
312
+ /* Helpers */
313
+ function formatDate(date, formatter) {
314
+ const nativeDate = date.toDate(getLocalTimeZone());
315
+ return formatter.format(nativeDate);
292
316
  }
317
+ // Pad number with zeroes to the left
318
+ function padNum(num, len) {
319
+ if (isNaN(num))
320
+ return '0'.repeat(len);
321
+ return num.toString().padStart(len, '0');
322
+ }
323
+ /* State handling */
293
324
  /**
294
325
  * Unfreezes a CalendarDate object from a snapshot.
295
326
  * @param raw - The snapshot of the CalendarDate object.
@@ -306,17 +337,13 @@ export function unfreezeDate(raw) {
306
337
  export function unfreezeTime(raw) {
307
338
  return new Time(raw.hour, raw.minute, raw.second, raw.millisecond);
308
339
  }
309
- /* State handling */
310
- function formatDate(date, formatter) {
311
- const nativeDate = date.toDate(getLocalTimeZone());
312
- return formatter.format(nativeDate);
313
- }
314
- // Pad number with zeroes to the left
315
- function padNum(num, len) {
316
- if (isNaN(num)) {
317
- return '0'.repeat(len);
318
- }
319
- return num.toString().padStart(len, '0');
340
+ /**
341
+ * Unfreezes a ZonedDateTime object from a snapshot.
342
+ * @param date - The snapshot of the ZonedDateTime object.
343
+ * @returns The unfrozen ZonedDateTime object.
344
+ */
345
+ export function unfreezeAbsoluteDate(date) {
346
+ return new ZonedDateTime(date.year, date.month, date.day, date.timeZone, date.offset, date.hour, date.minute, date.second, date.millisecond);
320
347
  }
321
348
  // SerDe
322
349
  export const dateTransport = {
@@ -4,17 +4,17 @@ This package provides utilities for sending emails using AWS Simple Email Servic
4
4
 
5
5
  ## Key Features
6
6
 
7
- - **Cloudflare Workers Compatible**: Uses direct AWS SES API calls with fetch instead of AWS SDK
8
- - **AWS Signature V4**: Implements proper AWS authentication for secure API requests
7
+ - **Cloudflare Workers Compatible**: Uses `aws4fetch` for direct AWS SES API calls
8
+ - **AWS Signature V4**: Handled by `aws4fetch` for secure API requests
9
9
  - **Zero Heavy Dependencies**: No AWS SDK required, works in any JavaScript runtime with fetch support
10
10
 
11
11
  ## Installation
12
12
 
13
- No additional dependencies required beyond the standard JavaScript runtime. The implementation uses:
13
+ The implementation uses:
14
14
 
15
+ - `aws4fetch` for AWS Signature V4 signing and requests
15
16
  - Native `fetch` API for HTTP requests
16
- - Web Crypto API for AWS Signature V4 signing
17
- - Native `DOMParser` for XML response parsing
17
+ - Native `DOMParser` for XML response parsing (optional, used for error/response parsing)
18
18
 
19
19
  ## Configuration
20
20
 
@@ -1,4 +1,4 @@
1
- import { signRequest } from './aws-signer.js';
1
+ import { AwsClient } from 'aws4fetch';
2
2
  /**
3
3
  * Send an email using AWS SES API.
4
4
  * Uses AWS Signature V4 signing and fetch API for Cloudflare Workers compatibility.
@@ -71,21 +71,29 @@ export async function sendEmail(options) {
71
71
  const host = `email.${awsRegion}.amazonaws.com`;
72
72
  const path = '/';
73
73
  try {
74
- // Sign the request
75
- const { headers } = await signRequest('POST', host, path, body, {
74
+ const aws = new AwsClient({
76
75
  accessKeyId: awsAccessKeyId,
77
76
  region: awsRegion,
78
- secretAccessKey: awsSecretAccessKey
77
+ secretAccessKey: awsSecretAccessKey,
78
+ service: 'ses'
79
79
  });
80
- // Make the request
81
- const response = await fetch(`https://${host}${path}`, {
80
+ const url = `https://${host}${path}`;
81
+ const init = {
82
82
  body,
83
83
  headers: {
84
- ...headers,
85
- 'Content-Length': body.length.toString(),
86
- Host: host
84
+ 'Content-Type': 'application/x-form-urlencoded'
87
85
  },
88
86
  method: 'POST'
87
+ };
88
+ // Sign the request and then use the global fetch.
89
+ // We avoid using aws.fetch() directly as it can cause issues in some test environments
90
+ // or when fetch is mocked/replaced after AwsClient instantiation.
91
+ const signedRequest = await aws.sign(url, init);
92
+ // Use two-argument fetch to satisfy tests that expect the second argument to be an options object
93
+ const response = await fetch(signedRequest.url, {
94
+ body: init.body,
95
+ headers: signedRequest.headers,
96
+ method: signedRequest.method
89
97
  });
90
98
  const responseText = await response.text();
91
99
  if (!response.ok) {
@@ -0,0 +1,2 @@
1
+ import { Result } from './result.js';
2
+ export { Result };
@@ -0,0 +1,2 @@
1
+ import { Result } from './result.js';
2
+ export { Result };
@@ -0,0 +1,72 @@
1
+ export type Result<T, E> = {
2
+ error: E;
3
+ ok: false;
4
+ } | {
5
+ ok: true;
6
+ value: T;
7
+ };
8
+ export declare const Result: {
9
+ /**
10
+ * Creates a failed result with the given error.
11
+ */
12
+ err<E>(error: E): {
13
+ error: E;
14
+ ok: false;
15
+ };
16
+ /**
17
+ * Creates a successful result with the given value.
18
+ */
19
+ ok<T>(value: T): {
20
+ ok: true;
21
+ value: T;
22
+ };
23
+ /**
24
+ * Returns true if the result is Ok.
25
+ */
26
+ isOk<T, E>(result: Result<T, E>): result is {
27
+ ok: true;
28
+ value: T;
29
+ };
30
+ /**
31
+ * Returns true if the result is Err.
32
+ */
33
+ isErr<T, E>(result: Result<T, E>): result is {
34
+ error: E;
35
+ ok: false;
36
+ };
37
+ /**
38
+ * Returns the contained Ok value or a provided default.
39
+ */
40
+ unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T;
41
+ /**
42
+ * Returns the contained Ok value or computes it from the provided op.
43
+ * @param op - Computes value in error case or throws an error.
44
+ */
45
+ unwrapOrElse<T, E>(result: Result<T, E>, op: (error: E) => T): T;
46
+ /**
47
+ * Maps a Result<T, E> to Result<U, E> by applying a function to a contained Ok value,
48
+ * leaving an Err value untouched.
49
+ */
50
+ map<T, U, E>(result: Result<T, E>, fn: (val: T) => U): Result<U, E>;
51
+ /**
52
+ * Maps a Result<T, E> to Result<T, F> by applying a function to a contained Err value,
53
+ * leaving an Ok value untouched.
54
+ */
55
+ mapErr<T, E, F>(result: Result<T, E>, fn: (err: E) => F): Result<T, F>;
56
+ /**
57
+ * Calls op if the result is Ok, otherwise returns the Err value of self.
58
+ * This function can be used for control flow based on Result values.
59
+ */
60
+ andThen<T, U, E>(result: Result<T, E>, op: (val: T) => Result<U, E>): Result<U, E>;
61
+ /**
62
+ * Calls op if the result is Err, otherwise returns the Ok value of self.
63
+ */
64
+ orElse<T, E, F>(result: Result<T, E>, op: (err: E) => Result<T, F>): Result<T, F>;
65
+ /**
66
+ * Pattern matches the Result and returns the result of the corresponding arm.
67
+ */
68
+ match<T, E, R>(result: Result<T, E>, arms: {
69
+ err: (err: E) => R;
70
+ ok: (val: T) => R;
71
+ }): R;
72
+ };
@@ -0,0 +1,86 @@
1
+ export const Result = {
2
+ /**
3
+ * Creates a failed result with the given error.
4
+ */
5
+ err(error) {
6
+ return { error, ok: false };
7
+ },
8
+ /**
9
+ * Creates a successful result with the given value.
10
+ */
11
+ ok(value) {
12
+ return { ok: true, value };
13
+ },
14
+ /**
15
+ * Returns true if the result is Ok.
16
+ */
17
+ isOk(result) {
18
+ return result.ok;
19
+ },
20
+ /**
21
+ * Returns true if the result is Err.
22
+ */
23
+ isErr(result) {
24
+ return !result.ok;
25
+ },
26
+ /**
27
+ * Returns the contained Ok value or a provided default.
28
+ */
29
+ unwrapOr(result, defaultValue) {
30
+ if (result.ok)
31
+ return result.value;
32
+ return defaultValue;
33
+ },
34
+ /**
35
+ * Returns the contained Ok value or computes it from the provided op.
36
+ * @param op - Computes value in error case or throws an error.
37
+ */
38
+ unwrapOrElse(result, op) {
39
+ if (result.ok)
40
+ return result.value;
41
+ return op(result.error);
42
+ },
43
+ /**
44
+ * Maps a Result<T, E> to Result<U, E> by applying a function to a contained Ok value,
45
+ * leaving an Err value untouched.
46
+ */
47
+ map(result, fn) {
48
+ if (result.ok)
49
+ return Result.ok(fn(result.value));
50
+ return result;
51
+ },
52
+ /**
53
+ * Maps a Result<T, E> to Result<T, F> by applying a function to a contained Err value,
54
+ * leaving an Ok value untouched.
55
+ */
56
+ mapErr(result, fn) {
57
+ if (!result.ok)
58
+ return Result.err(fn(result.error));
59
+ return result;
60
+ },
61
+ /**
62
+ * Calls op if the result is Ok, otherwise returns the Err value of self.
63
+ * This function can be used for control flow based on Result values.
64
+ */
65
+ andThen(result, op) {
66
+ if (result.ok)
67
+ return op(result.value);
68
+ return result;
69
+ },
70
+ /**
71
+ * Calls op if the result is Err, otherwise returns the Ok value of self.
72
+ */
73
+ orElse(result, op) {
74
+ if (!result.ok)
75
+ return op(result.error);
76
+ return result;
77
+ },
78
+ /**
79
+ * Pattern matches the Result and returns the result of the corresponding arm.
80
+ */
81
+ match(result, arms) {
82
+ if (result.ok)
83
+ return arms.ok(result.value);
84
+ return arms.err(result.error);
85
+ }
86
+ };
@@ -0,0 +1 @@
1
+ export {};