@wasto/sdk 1.0.3 → 1.0.5

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 (56) hide show
  1. package/dist/index.d.mts +60 -3
  2. package/dist/index.d.ts +60 -3
  3. package/dist/index.js +79 -0
  4. package/dist/index.mjs +79 -0
  5. package/package.json +1 -1
  6. package/src/client.ts +791 -692
  7. package/src/dashboard-apps.ts +367 -350
  8. package/src/dto/cms-app-settings.ts +91 -91
  9. package/src/enums.ts +298 -298
  10. package/src/free-tier.ts +56 -56
  11. package/src/index.ts +35 -35
  12. package/src/opening-hours/constants.ts +48 -48
  13. package/src/opening-hours/convert.ts +276 -276
  14. package/src/opening-hours/format.ts +99 -99
  15. package/src/opening-hours/index.ts +9 -9
  16. package/src/opening-hours/is-open-now.ts +38 -38
  17. package/src/opening-hours/resolve.ts +71 -71
  18. package/src/opening-hours/time.ts +74 -74
  19. package/src/opening-hours/timezone.ts +34 -34
  20. package/src/opening-hours/types.ts +53 -53
  21. package/src/opening-hours/validate.ts +182 -182
  22. package/src/roi/calculations.ts +732 -732
  23. package/src/roi/index.ts +1 -1
  24. package/src/types/app-preload.types.ts +10 -0
  25. package/src/types/asset-bookings.types.ts +19 -19
  26. package/src/types/asset-interventions.types.ts +24 -24
  27. package/src/types/assets.types.ts +68 -68
  28. package/src/types/auth.types.ts +37 -37
  29. package/src/types/blog-posts.types.ts +19 -19
  30. package/src/types/calendar-pdf.types.ts +24 -24
  31. package/src/types/calendo-events.types.ts +64 -64
  32. package/src/types/challenges.types.ts +30 -30
  33. package/src/types/chatbot.types.ts +82 -82
  34. package/src/types/cities.types.ts +27 -27
  35. package/src/types/city-groups.types.ts +46 -46
  36. package/src/types/cms.types.ts +87 -87
  37. package/src/types/field-reports.types.ts +66 -66
  38. package/src/types/free-tier.types.ts +54 -54
  39. package/src/types/index.ts +33 -32
  40. package/src/types/iot.types.ts +31 -31
  41. package/src/types/maintenance.types.ts +44 -44
  42. package/src/types/mapso.types.ts +146 -146
  43. package/src/types/notifications.types.ts +68 -68
  44. package/src/types/onboarding.types.ts +117 -117
  45. package/src/types/operational-zones.types.ts +70 -70
  46. package/src/types/pagination.types.ts +33 -33
  47. package/src/types/providers.types.ts +29 -29
  48. package/src/types/quiz-questions.types.ts +59 -59
  49. package/src/types/recycling-points.types.ts +47 -47
  50. package/src/types/roi.types.ts +60 -60
  51. package/src/types/surveys.types.ts +103 -103
  52. package/src/types/tickets.types.ts +65 -65
  53. package/src/types/users.types.ts +30 -30
  54. package/src/types/waste-collection-places-query.types.ts +4 -4
  55. package/src/types/waste-collection-places.types.ts +34 -33
  56. package/src/types/waste-types.types.ts +21 -21
@@ -1,276 +1,276 @@
1
- import type {
2
- OpeningHours,
3
- OpeningHoursException,
4
- OpeningHoursRule,
5
- TimeSlot,
6
- Weekday,
7
- } from './types';
8
- import { WEEKDAYS } from './types';
9
- import {
10
- addDaysToIsoDate,
11
- nextWeekday,
12
- parseTimeMinutes,
13
- refDateForWeekday,
14
- sortSlots,
15
- utcHhmmFromDate,
16
- weekdayFromUtcDate,
17
- } from './time';
18
- import { localDateTimeToUtc, utcDateIso } from './timezone';
19
-
20
- type LocalOpeningHoursInput = {
21
- rules: OpeningHoursRule[];
22
- exceptions?: OpeningHoursException[];
23
- };
24
-
25
- function addSlotToMap(
26
- map: Map<Weekday, TimeSlot[]>,
27
- day: Weekday,
28
- slot: TimeSlot,
29
- ): void {
30
- const existing = map.get(day) ?? [];
31
- existing.push(slot);
32
- map.set(day, existing);
33
- }
34
-
35
- function mergeSlots(slots: TimeSlot[]): TimeSlot[] {
36
- const sorted = sortSlots(slots);
37
- const merged: TimeSlot[] = [];
38
- for (const slot of sorted) {
39
- const last = merged[merged.length - 1];
40
- if (last && last.close === slot.open) {
41
- merged[merged.length - 1] = { open: last.open, close: slot.close };
42
- } else {
43
- merged.push({ ...slot });
44
- }
45
- }
46
- return merged.filter((s) => {
47
- const o = parseTimeMinutes(s.open);
48
- const c = parseTimeMinutes(s.close);
49
- return o != null && c != null && c > o;
50
- });
51
- }
52
-
53
- function mapToRules(map: Map<Weekday, TimeSlot[]>): OpeningHoursRule[] {
54
- const rules: OpeningHoursRule[] = [];
55
- for (const day of WEEKDAYS) {
56
- const slots = map.get(day);
57
- if (!slots?.length) continue;
58
- rules.push({ days: [day], slots: mergeSlots(slots) });
59
- }
60
- return coalesceDayRules(rules);
61
- }
62
-
63
- function coalesceDayRules(rules: OpeningHoursRule[]): OpeningHoursRule[] {
64
- const bySignature = new Map<string, Weekday[]>();
65
- for (const rule of rules) {
66
- const sig = JSON.stringify(rule.slots);
67
- const days = bySignature.get(sig) ?? [];
68
- days.push(...rule.days);
69
- bySignature.set(sig, days);
70
- }
71
- const out: OpeningHoursRule[] = [];
72
- for (const [sig, days] of bySignature) {
73
- out.push({
74
- days: sortWeekdays([...new Set(days)]),
75
- slots: JSON.parse(sig) as TimeSlot[],
76
- });
77
- }
78
- return out;
79
- }
80
-
81
- function sortWeekdays(days: Weekday[]): Weekday[] {
82
- const order = new Map(WEEKDAYS.map((d, i) => [d, i]));
83
- return [...days].sort((a, b) => (order.get(a) ?? 0) - (order.get(b) ?? 0));
84
- }
85
-
86
- function convertLocalSlotToUtcFixed(
87
- map: Map<Weekday, TimeSlot[]>,
88
- localDay: Weekday,
89
- slot: TimeSlot,
90
- timeZone: string,
91
- ): void {
92
- const openMin = parseTimeMinutes(slot.open);
93
- const closeMin = parseTimeMinutes(slot.close);
94
- if (openMin == null || closeMin == null) return;
95
-
96
- const openDate = refDateForWeekday(localDay);
97
- let closeDate = openDate;
98
- const closeTime = slot.close;
99
-
100
- if (closeMin <= openMin) {
101
- closeDate = addDaysToIsoDate(openDate, 1);
102
- }
103
-
104
- const openUtc = localDateTimeToUtc(openDate, slot.open, timeZone);
105
- const closeUtc = localDateTimeToUtc(closeDate, closeTime, timeZone);
106
-
107
- const openDay = weekdayFromUtcDate(openUtc);
108
- const closeDay = weekdayFromUtcDate(closeUtc);
109
- const openStr = utcHhmmFromDate(openUtc);
110
- const closeStr = utcHhmmFromDate(closeUtc);
111
-
112
- if (openDay === closeDay) {
113
- if (openStr !== closeStr) {
114
- addSlotToMap(map, openDay, { open: openStr, close: closeStr });
115
- }
116
- return;
117
- }
118
-
119
- addSlotToMap(map, openDay, { open: openStr, close: '23:59' });
120
- if (closeStr !== '00:00') {
121
- addSlotToMap(map, closeDay, { open: '00:00', close: closeStr });
122
- }
123
- }
124
-
125
- function convertUtcSlotToLocal(
126
- map: Map<Weekday, TimeSlot[]>,
127
- utcDay: Weekday,
128
- slot: TimeSlot,
129
- timeZone: string,
130
- ): void {
131
- const openMin = parseTimeMinutes(slot.open);
132
- const closeMin = parseTimeMinutes(slot.close);
133
- if (openMin == null || closeMin == null) return;
134
-
135
- const openDate = refDateForWeekday(utcDay);
136
- let closeDate = openDate;
137
- const closeTime = slot.close;
138
-
139
- if (closeMin <= openMin) {
140
- closeDate = addDaysToIsoDate(openDate, 1);
141
- }
142
-
143
- const openUtc = new Date(`${openDate}T${slot.open}:00.000Z`);
144
- const closeUtc = new Date(`${closeDate}T${closeTime}:00.000Z`);
145
-
146
- const openLocal = formatZoned(openUtc, timeZone);
147
- const closeLocal = formatZoned(closeUtc, timeZone);
148
-
149
- if (openLocal.day === closeLocal.day) {
150
- if (openLocal.time !== closeLocal.time) {
151
- addSlotToMap(map, openLocal.day, { open: openLocal.time, close: closeLocal.time });
152
- }
153
- return;
154
- }
155
-
156
- addSlotToMap(map, openLocal.day, { open: openLocal.time, close: '23:59' });
157
- if (closeLocal.time !== '00:00') {
158
- addSlotToMap(map, closeLocal.day, { open: '00:00', close: closeLocal.time });
159
- }
160
- }
161
-
162
- function formatZoned(utc: Date, timeZone: string): { day: Weekday; time: string } {
163
- const parts = new Intl.DateTimeFormat('en-US', {
164
- timeZone,
165
- weekday: 'long',
166
- hour: '2-digit',
167
- minute: '2-digit',
168
- hour12: false,
169
- }).formatToParts(utc);
170
- const weekdayRaw = parts.find((p) => p.type === 'weekday')?.value?.toLowerCase();
171
- const hour = parts.find((p) => p.type === 'hour')?.value ?? '00';
172
- const minute = parts.find((p) => p.type === 'minute')?.value ?? '00';
173
- const dayMap: Record<string, Weekday> = {
174
- monday: 'monday',
175
- tuesday: 'tuesday',
176
- wednesday: 'wednesday',
177
- thursday: 'thursday',
178
- friday: 'friday',
179
- saturday: 'saturday',
180
- sunday: 'sunday',
181
- };
182
- const day = dayMap[weekdayRaw ?? 'monday'] ?? 'monday';
183
- return { day, time: `${hour.padStart(2, '0')}:${minute.padStart(2, '0')}` };
184
- }
185
-
186
- export function convertLocalToUtc(
187
- local: LocalOpeningHoursInput,
188
- timeZone: string,
189
- ): OpeningHours {
190
- const map = new Map<Weekday, TimeSlot[]>();
191
-
192
- for (const rule of local.rules) {
193
- for (const day of rule.days) {
194
- for (const slot of rule.slots) {
195
- convertLocalSlotToUtcFixed(map, day, slot, timeZone);
196
- }
197
- }
198
- }
199
-
200
- const exceptions = local.exceptions?.map((exc) => {
201
- if (exc.closed) return exc;
202
- const excMap = new Map<Weekday, TimeSlot[]>();
203
- for (const slot of exc.slots) {
204
- convertLocalSlotToUtcFixed(excMap, 'monday', slot, timeZone);
205
- }
206
- const merged = [...excMap.values()].flat();
207
- return { ...exc, slots: merged.length ? mergeSlots(merged) : exc.slots };
208
- });
209
-
210
- return {
211
- version: 1,
212
- storage: 'utc',
213
- rules: mapToRules(map),
214
- exceptions,
215
- };
216
- }
217
-
218
- export function convertUtcToLocal(
219
- utc: OpeningHours,
220
- timeZone: string,
221
- ): LocalOpeningHoursInput {
222
- const map = new Map<Weekday, TimeSlot[]>();
223
-
224
- for (const rule of utc.rules) {
225
- for (const day of rule.days) {
226
- for (const slot of rule.slots) {
227
- convertUtcSlotToLocal(map, day, slot, timeZone);
228
- }
229
- }
230
- }
231
-
232
- const exceptions = utc.exceptions?.map((exc) => {
233
- if (exc.closed) return exc;
234
- const excMap = new Map<Weekday, TimeSlot[]>();
235
- for (const slot of exc.slots) {
236
- convertUtcSlotToLocal(excMap, 'monday', slot, timeZone);
237
- }
238
- const merged = [...excMap.values()].flat();
239
- return { ...exc, slots: merged.length ? mergeSlots(merged) : exc.slots };
240
- });
241
-
242
- return {
243
- rules: mapToRules(map),
244
- exceptions,
245
- };
246
- }
247
-
248
- export function localRulesFromRange(
249
- fromDay: Weekday,
250
- toDay: Weekday,
251
- slots: TimeSlot[],
252
- exceptDays: Weekday[] = [],
253
- ): OpeningHoursRule {
254
- const fromIdx = WEEKDAYS.indexOf(fromDay);
255
- const toIdx = WEEKDAYS.indexOf(toDay);
256
- const except = new Set(exceptDays);
257
- const days: Weekday[] = [];
258
- if (fromIdx <= toIdx) {
259
- for (let i = fromIdx; i <= toIdx; i++) {
260
- const d = WEEKDAYS[i];
261
- if (!except.has(d)) days.push(d);
262
- }
263
- } else {
264
- for (let i = fromIdx; i < 7; i++) {
265
- const d = WEEKDAYS[i];
266
- if (!except.has(d)) days.push(d);
267
- }
268
- for (let i = 0; i <= toIdx; i++) {
269
- const d = WEEKDAYS[i];
270
- if (!except.has(d)) days.push(d);
271
- }
272
- }
273
- return { days, slots: [...slots] };
274
- }
275
-
276
- export { nextWeekday };
1
+ import type {
2
+ OpeningHours,
3
+ OpeningHoursException,
4
+ OpeningHoursRule,
5
+ TimeSlot,
6
+ Weekday,
7
+ } from './types';
8
+ import { WEEKDAYS } from './types';
9
+ import {
10
+ addDaysToIsoDate,
11
+ nextWeekday,
12
+ parseTimeMinutes,
13
+ refDateForWeekday,
14
+ sortSlots,
15
+ utcHhmmFromDate,
16
+ weekdayFromUtcDate,
17
+ } from './time';
18
+ import { localDateTimeToUtc, utcDateIso } from './timezone';
19
+
20
+ type LocalOpeningHoursInput = {
21
+ rules: OpeningHoursRule[];
22
+ exceptions?: OpeningHoursException[];
23
+ };
24
+
25
+ function addSlotToMap(
26
+ map: Map<Weekday, TimeSlot[]>,
27
+ day: Weekday,
28
+ slot: TimeSlot,
29
+ ): void {
30
+ const existing = map.get(day) ?? [];
31
+ existing.push(slot);
32
+ map.set(day, existing);
33
+ }
34
+
35
+ function mergeSlots(slots: TimeSlot[]): TimeSlot[] {
36
+ const sorted = sortSlots(slots);
37
+ const merged: TimeSlot[] = [];
38
+ for (const slot of sorted) {
39
+ const last = merged[merged.length - 1];
40
+ if (last && last.close === slot.open) {
41
+ merged[merged.length - 1] = { open: last.open, close: slot.close };
42
+ } else {
43
+ merged.push({ ...slot });
44
+ }
45
+ }
46
+ return merged.filter((s) => {
47
+ const o = parseTimeMinutes(s.open);
48
+ const c = parseTimeMinutes(s.close);
49
+ return o != null && c != null && c > o;
50
+ });
51
+ }
52
+
53
+ function mapToRules(map: Map<Weekday, TimeSlot[]>): OpeningHoursRule[] {
54
+ const rules: OpeningHoursRule[] = [];
55
+ for (const day of WEEKDAYS) {
56
+ const slots = map.get(day);
57
+ if (!slots?.length) continue;
58
+ rules.push({ days: [day], slots: mergeSlots(slots) });
59
+ }
60
+ return coalesceDayRules(rules);
61
+ }
62
+
63
+ function coalesceDayRules(rules: OpeningHoursRule[]): OpeningHoursRule[] {
64
+ const bySignature = new Map<string, Weekday[]>();
65
+ for (const rule of rules) {
66
+ const sig = JSON.stringify(rule.slots);
67
+ const days = bySignature.get(sig) ?? [];
68
+ days.push(...rule.days);
69
+ bySignature.set(sig, days);
70
+ }
71
+ const out: OpeningHoursRule[] = [];
72
+ for (const [sig, days] of bySignature) {
73
+ out.push({
74
+ days: sortWeekdays([...new Set(days)]),
75
+ slots: JSON.parse(sig) as TimeSlot[],
76
+ });
77
+ }
78
+ return out;
79
+ }
80
+
81
+ function sortWeekdays(days: Weekday[]): Weekday[] {
82
+ const order = new Map(WEEKDAYS.map((d, i) => [d, i]));
83
+ return [...days].sort((a, b) => (order.get(a) ?? 0) - (order.get(b) ?? 0));
84
+ }
85
+
86
+ function convertLocalSlotToUtcFixed(
87
+ map: Map<Weekday, TimeSlot[]>,
88
+ localDay: Weekday,
89
+ slot: TimeSlot,
90
+ timeZone: string,
91
+ ): void {
92
+ const openMin = parseTimeMinutes(slot.open);
93
+ const closeMin = parseTimeMinutes(slot.close);
94
+ if (openMin == null || closeMin == null) return;
95
+
96
+ const openDate = refDateForWeekday(localDay);
97
+ let closeDate = openDate;
98
+ const closeTime = slot.close;
99
+
100
+ if (closeMin <= openMin) {
101
+ closeDate = addDaysToIsoDate(openDate, 1);
102
+ }
103
+
104
+ const openUtc = localDateTimeToUtc(openDate, slot.open, timeZone);
105
+ const closeUtc = localDateTimeToUtc(closeDate, closeTime, timeZone);
106
+
107
+ const openDay = weekdayFromUtcDate(openUtc);
108
+ const closeDay = weekdayFromUtcDate(closeUtc);
109
+ const openStr = utcHhmmFromDate(openUtc);
110
+ const closeStr = utcHhmmFromDate(closeUtc);
111
+
112
+ if (openDay === closeDay) {
113
+ if (openStr !== closeStr) {
114
+ addSlotToMap(map, openDay, { open: openStr, close: closeStr });
115
+ }
116
+ return;
117
+ }
118
+
119
+ addSlotToMap(map, openDay, { open: openStr, close: '23:59' });
120
+ if (closeStr !== '00:00') {
121
+ addSlotToMap(map, closeDay, { open: '00:00', close: closeStr });
122
+ }
123
+ }
124
+
125
+ function convertUtcSlotToLocal(
126
+ map: Map<Weekday, TimeSlot[]>,
127
+ utcDay: Weekday,
128
+ slot: TimeSlot,
129
+ timeZone: string,
130
+ ): void {
131
+ const openMin = parseTimeMinutes(slot.open);
132
+ const closeMin = parseTimeMinutes(slot.close);
133
+ if (openMin == null || closeMin == null) return;
134
+
135
+ const openDate = refDateForWeekday(utcDay);
136
+ let closeDate = openDate;
137
+ const closeTime = slot.close;
138
+
139
+ if (closeMin <= openMin) {
140
+ closeDate = addDaysToIsoDate(openDate, 1);
141
+ }
142
+
143
+ const openUtc = new Date(`${openDate}T${slot.open}:00.000Z`);
144
+ const closeUtc = new Date(`${closeDate}T${closeTime}:00.000Z`);
145
+
146
+ const openLocal = formatZoned(openUtc, timeZone);
147
+ const closeLocal = formatZoned(closeUtc, timeZone);
148
+
149
+ if (openLocal.day === closeLocal.day) {
150
+ if (openLocal.time !== closeLocal.time) {
151
+ addSlotToMap(map, openLocal.day, { open: openLocal.time, close: closeLocal.time });
152
+ }
153
+ return;
154
+ }
155
+
156
+ addSlotToMap(map, openLocal.day, { open: openLocal.time, close: '23:59' });
157
+ if (closeLocal.time !== '00:00') {
158
+ addSlotToMap(map, closeLocal.day, { open: '00:00', close: closeLocal.time });
159
+ }
160
+ }
161
+
162
+ function formatZoned(utc: Date, timeZone: string): { day: Weekday; time: string } {
163
+ const parts = new Intl.DateTimeFormat('en-US', {
164
+ timeZone,
165
+ weekday: 'long',
166
+ hour: '2-digit',
167
+ minute: '2-digit',
168
+ hour12: false,
169
+ }).formatToParts(utc);
170
+ const weekdayRaw = parts.find((p) => p.type === 'weekday')?.value?.toLowerCase();
171
+ const hour = parts.find((p) => p.type === 'hour')?.value ?? '00';
172
+ const minute = parts.find((p) => p.type === 'minute')?.value ?? '00';
173
+ const dayMap: Record<string, Weekday> = {
174
+ monday: 'monday',
175
+ tuesday: 'tuesday',
176
+ wednesday: 'wednesday',
177
+ thursday: 'thursday',
178
+ friday: 'friday',
179
+ saturday: 'saturday',
180
+ sunday: 'sunday',
181
+ };
182
+ const day = dayMap[weekdayRaw ?? 'monday'] ?? 'monday';
183
+ return { day, time: `${hour.padStart(2, '0')}:${minute.padStart(2, '0')}` };
184
+ }
185
+
186
+ export function convertLocalToUtc(
187
+ local: LocalOpeningHoursInput,
188
+ timeZone: string,
189
+ ): OpeningHours {
190
+ const map = new Map<Weekday, TimeSlot[]>();
191
+
192
+ for (const rule of local.rules) {
193
+ for (const day of rule.days) {
194
+ for (const slot of rule.slots) {
195
+ convertLocalSlotToUtcFixed(map, day, slot, timeZone);
196
+ }
197
+ }
198
+ }
199
+
200
+ const exceptions = local.exceptions?.map((exc) => {
201
+ if (exc.closed) return exc;
202
+ const excMap = new Map<Weekday, TimeSlot[]>();
203
+ for (const slot of exc.slots) {
204
+ convertLocalSlotToUtcFixed(excMap, 'monday', slot, timeZone);
205
+ }
206
+ const merged = [...excMap.values()].flat();
207
+ return { ...exc, slots: merged.length ? mergeSlots(merged) : exc.slots };
208
+ });
209
+
210
+ return {
211
+ version: 1,
212
+ storage: 'utc',
213
+ rules: mapToRules(map),
214
+ exceptions,
215
+ };
216
+ }
217
+
218
+ export function convertUtcToLocal(
219
+ utc: OpeningHours,
220
+ timeZone: string,
221
+ ): LocalOpeningHoursInput {
222
+ const map = new Map<Weekday, TimeSlot[]>();
223
+
224
+ for (const rule of utc.rules) {
225
+ for (const day of rule.days) {
226
+ for (const slot of rule.slots) {
227
+ convertUtcSlotToLocal(map, day, slot, timeZone);
228
+ }
229
+ }
230
+ }
231
+
232
+ const exceptions = utc.exceptions?.map((exc) => {
233
+ if (exc.closed) return exc;
234
+ const excMap = new Map<Weekday, TimeSlot[]>();
235
+ for (const slot of exc.slots) {
236
+ convertUtcSlotToLocal(excMap, 'monday', slot, timeZone);
237
+ }
238
+ const merged = [...excMap.values()].flat();
239
+ return { ...exc, slots: merged.length ? mergeSlots(merged) : exc.slots };
240
+ });
241
+
242
+ return {
243
+ rules: mapToRules(map),
244
+ exceptions,
245
+ };
246
+ }
247
+
248
+ export function localRulesFromRange(
249
+ fromDay: Weekday,
250
+ toDay: Weekday,
251
+ slots: TimeSlot[],
252
+ exceptDays: Weekday[] = [],
253
+ ): OpeningHoursRule {
254
+ const fromIdx = WEEKDAYS.indexOf(fromDay);
255
+ const toIdx = WEEKDAYS.indexOf(toDay);
256
+ const except = new Set(exceptDays);
257
+ const days: Weekday[] = [];
258
+ if (fromIdx <= toIdx) {
259
+ for (let i = fromIdx; i <= toIdx; i++) {
260
+ const d = WEEKDAYS[i];
261
+ if (!except.has(d)) days.push(d);
262
+ }
263
+ } else {
264
+ for (let i = fromIdx; i < 7; i++) {
265
+ const d = WEEKDAYS[i];
266
+ if (!except.has(d)) days.push(d);
267
+ }
268
+ for (let i = 0; i <= toIdx; i++) {
269
+ const d = WEEKDAYS[i];
270
+ if (!except.has(d)) days.push(d);
271
+ }
272
+ }
273
+ return { days, slots: [...slots] };
274
+ }
275
+
276
+ export { nextWeekday };