@remit/calendar-service 0.0.18 → 0.0.20
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.
- package/dist/accept.d.ts +71 -0
- package/dist/accept.js +159 -0
- package/dist/build.d.ts +79 -0
- package/dist/build.js +196 -0
- package/dist/correct.d.ts +4 -0
- package/dist/correct.js +22 -0
- package/dist/errors.d.ts +56 -0
- package/dist/errors.js +1 -0
- package/dist/etag.d.ts +9 -0
- package/{src/etag.ts → dist/etag.js} +1 -3
- package/dist/expand.d.ts +73 -0
- package/dist/expand.js +188 -0
- package/dist/feed.d.ts +81 -0
- package/dist/feed.js +157 -0
- package/dist/fixtures.d.ts +19 -0
- package/dist/fixtures.js +37 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +15 -0
- package/dist/memory-store.d.ts +105 -0
- package/dist/memory-store.js +319 -0
- package/dist/parse.d.ts +39 -0
- package/dist/parse.js +87 -0
- package/dist/project.d.ts +30 -0
- package/dist/project.js +57 -0
- package/dist/put.d.ts +52 -0
- package/dist/put.js +78 -0
- package/dist/reopen.d.ts +14 -0
- package/dist/reopen.js +92 -0
- package/dist/scope.d.ts +70 -0
- package/dist/scope.js +687 -0
- package/dist/subscribe.d.ts +96 -0
- package/dist/subscribe.js +298 -0
- package/dist/suggest.d.ts +74 -0
- package/dist/suggest.js +138 -0
- package/dist/time.d.ts +76 -0
- package/dist/time.js +164 -0
- package/dist/window.d.ts +85 -0
- package/dist/window.js +161 -0
- package/package.json +40 -35
- package/src/accept.test.ts +0 -403
- package/src/accept.ts +0 -250
- package/src/build.test.ts +0 -113
- package/src/build.ts +0 -311
- package/src/correct.test.ts +0 -173
- package/src/correct.ts +0 -40
- package/src/errors.ts +0 -62
- package/src/etag.test.ts +0 -54
- package/src/expand.test.ts +0 -361
- package/src/expand.ts +0 -303
- package/src/feed.test.ts +0 -334
- package/src/feed.ts +0 -203
- package/src/feeds/google-secret-address.ics +0 -99
- package/src/fixtures.ts +0 -52
- package/src/index.ts +0 -128
- package/src/memory-store.ts +0 -485
- package/src/parse.test.ts +0 -264
- package/src/parse.ts +0 -138
- package/src/project.test.ts +0 -247
- package/src/project.ts +0 -122
- package/src/put.test.ts +0 -318
- package/src/put.ts +0 -133
- package/src/reopen.test.ts +0 -529
- package/src/reopen.ts +0 -199
- package/src/scope.test.ts +0 -1421
- package/src/scope.ts +0 -1003
- package/src/subscribe.test.ts +0 -582
- package/src/subscribe.ts +0 -433
- package/src/suggest.test.ts +0 -376
- package/src/suggest.ts +0 -244
- package/src/time.ts +0 -260
- package/src/window.test.ts +0 -648
- package/src/window.ts +0 -281
- package/tsconfig.json +0 -8
package/src/memory-store.ts
DELETED
|
@@ -1,485 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
CalendarCollectionItem,
|
|
3
|
-
CalendarEventIndexItem,
|
|
4
|
-
CalendarFeedTokenItem,
|
|
5
|
-
CalendarObjectItem,
|
|
6
|
-
CalendarOccurrenceInput,
|
|
7
|
-
CalendarRepositories,
|
|
8
|
-
CalendarSuggestionItem,
|
|
9
|
-
CalendarWrite,
|
|
10
|
-
CreateCalendarCollectionInput,
|
|
11
|
-
ICalendarCollectionRepository,
|
|
12
|
-
ICalendarEventIndexRepository,
|
|
13
|
-
ICalendarFeedTokenRepository,
|
|
14
|
-
ICalendarObjectRepository,
|
|
15
|
-
ICalendarStore,
|
|
16
|
-
ICalendarSuggestionRepository,
|
|
17
|
-
PutCalendarFeedTokenInput,
|
|
18
|
-
PutCalendarObjectInput as PutCalendarObjectRow,
|
|
19
|
-
PutCalendarSuggestionInput,
|
|
20
|
-
SettleCalendarSuggestionInput,
|
|
21
|
-
UpdateCalendarCollectionInput,
|
|
22
|
-
} from "@remit/data-ports";
|
|
23
|
-
import { NotFoundError } from "@remit/data-ports/errors";
|
|
24
|
-
import {
|
|
25
|
-
deriveCalendarFeedTokenId,
|
|
26
|
-
deriveCalendarId,
|
|
27
|
-
deriveCalendarObjectId,
|
|
28
|
-
deriveCalendarSuggestionId,
|
|
29
|
-
normalizeCalendarUrlSegment,
|
|
30
|
-
} from "@remit/data-ports/id";
|
|
31
|
-
import { CalendarSuggestionState } from "@remit/domain-enums";
|
|
32
|
-
|
|
33
|
-
// The class the port's conformance suite requires a repository to throw for an
|
|
34
|
-
// absent row, so a caller that branches on it — the calendar feed answers 404 to
|
|
35
|
-
// a token whose collection is gone — behaves the same against this double as
|
|
36
|
-
// against a real one.
|
|
37
|
-
export class MissingRow extends NotFoundError {}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* The calendar store over plain maps. A commit applies its writes in order;
|
|
41
|
-
* that they stand or fall together on a real database is proven in
|
|
42
|
-
* drizzle-service's calendar-put.sqlite.test.ts.
|
|
43
|
-
*/
|
|
44
|
-
export class MemoryCalendarStore implements ICalendarStore {
|
|
45
|
-
readonly collections = new Map<string, CalendarCollectionItem>();
|
|
46
|
-
readonly objects = new Map<string, CalendarObjectItem>();
|
|
47
|
-
readonly occurrences = new Map<string, CalendarEventIndexItem[]>();
|
|
48
|
-
readonly suggestions = new Map<string, CalendarSuggestionItem>();
|
|
49
|
-
readonly feedTokens = new Map<string, CalendarFeedTokenItem>();
|
|
50
|
-
|
|
51
|
-
private readonly collectionRepo: ICalendarCollectionRepository = {
|
|
52
|
-
create: async (input: CreateCalendarCollectionInput) => {
|
|
53
|
-
const urlSegment = normalizeCalendarUrlSegment(input.urlSegment);
|
|
54
|
-
const calendarId = deriveCalendarId(input.accountConfigId, urlSegment);
|
|
55
|
-
const existing = this.collections.get(calendarId);
|
|
56
|
-
if (existing) return existing;
|
|
57
|
-
const now = Date.now();
|
|
58
|
-
const collection: CalendarCollectionItem = {
|
|
59
|
-
calendarId,
|
|
60
|
-
accountConfigId: input.accountConfigId,
|
|
61
|
-
urlSegment,
|
|
62
|
-
displayName: input.displayName,
|
|
63
|
-
color: input.color ?? "Cal1",
|
|
64
|
-
componentSet: input.componentSet ?? "VeventOnly",
|
|
65
|
-
source: input.source ?? "UserCreated",
|
|
66
|
-
timezone: input.timezone ?? "",
|
|
67
|
-
syncSequence: 0,
|
|
68
|
-
subscriptionUrl: input.subscriptionUrl ?? "",
|
|
69
|
-
subscriptionEnabled: input.subscriptionEnabled ?? false,
|
|
70
|
-
subscriptionCheckedAt: 0,
|
|
71
|
-
subscriptionFetchedAt: 0,
|
|
72
|
-
subscriptionError: "",
|
|
73
|
-
createdAt: now,
|
|
74
|
-
updatedAt: now,
|
|
75
|
-
};
|
|
76
|
-
this.collections.set(calendarId, collection);
|
|
77
|
-
return collection;
|
|
78
|
-
},
|
|
79
|
-
get: async (_accountConfigId: string, calendarId: string) => {
|
|
80
|
-
const collection = this.collections.get(calendarId);
|
|
81
|
-
if (!collection) throw new MissingRow(calendarId);
|
|
82
|
-
return collection;
|
|
83
|
-
},
|
|
84
|
-
update: async (
|
|
85
|
-
_accountConfigId: string,
|
|
86
|
-
calendarId: string,
|
|
87
|
-
input: UpdateCalendarCollectionInput,
|
|
88
|
-
) => {
|
|
89
|
-
const collection = this.collections.get(calendarId);
|
|
90
|
-
if (!collection) throw new MissingRow(calendarId);
|
|
91
|
-
const updated = { ...collection, ...input };
|
|
92
|
-
this.collections.set(calendarId, updated);
|
|
93
|
-
return updated;
|
|
94
|
-
},
|
|
95
|
-
delete: async (_accountConfigId: string, calendarId: string) => {
|
|
96
|
-
this.collections.delete(calendarId);
|
|
97
|
-
},
|
|
98
|
-
listByAccountConfig: async (accountConfigId: string) =>
|
|
99
|
-
[...this.collections.values()].filter(
|
|
100
|
-
(collection) => collection.accountConfigId === accountConfigId,
|
|
101
|
-
),
|
|
102
|
-
createExclusive: async (input: CreateCalendarCollectionInput) => {
|
|
103
|
-
const calendarId = deriveCalendarId(
|
|
104
|
-
input.accountConfigId,
|
|
105
|
-
input.urlSegment,
|
|
106
|
-
);
|
|
107
|
-
if (this.collections.has(calendarId)) return null;
|
|
108
|
-
return this.collectionRepo.create(input);
|
|
109
|
-
},
|
|
110
|
-
listEnabledSubscriptions: async () =>
|
|
111
|
-
[...this.collections.values()].filter(
|
|
112
|
-
(collection) =>
|
|
113
|
-
collection.source === "Subscribed" && collection.subscriptionEnabled,
|
|
114
|
-
),
|
|
115
|
-
findByUrlSegment: async (accountConfigId: string, urlSegment: string) =>
|
|
116
|
-
this.collections.get(deriveCalendarId(accountConfigId, urlSegment)) ??
|
|
117
|
-
null,
|
|
118
|
-
bumpSyncSequence: async (_accountConfigId: string, calendarId: string) => {
|
|
119
|
-
const collection = this.collections.get(calendarId);
|
|
120
|
-
if (!collection) throw new MissingRow(calendarId);
|
|
121
|
-
const bumped = {
|
|
122
|
-
...collection,
|
|
123
|
-
syncSequence: collection.syncSequence + 1,
|
|
124
|
-
updatedAt: Date.now(),
|
|
125
|
-
};
|
|
126
|
-
this.collections.set(calendarId, bumped);
|
|
127
|
-
return bumped.syncSequence;
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
private readonly objectRepo: ICalendarObjectRepository = {
|
|
132
|
-
put: async (input: PutCalendarObjectRow) => {
|
|
133
|
-
const calendarObjectId = deriveCalendarObjectId(
|
|
134
|
-
input.calendarId,
|
|
135
|
-
input.resourceName,
|
|
136
|
-
);
|
|
137
|
-
const now = Date.now();
|
|
138
|
-
const object: CalendarObjectItem = {
|
|
139
|
-
...input,
|
|
140
|
-
calendarObjectId,
|
|
141
|
-
createdAt: this.objects.get(calendarObjectId)?.createdAt ?? now,
|
|
142
|
-
updatedAt: now,
|
|
143
|
-
};
|
|
144
|
-
this.objects.set(calendarObjectId, object);
|
|
145
|
-
return object;
|
|
146
|
-
},
|
|
147
|
-
listIncompleteExpansions: async (calendarId: string, instant: string) =>
|
|
148
|
-
[...this.objects.values()].filter(
|
|
149
|
-
(object) =>
|
|
150
|
-
object.calendarId === calendarId &&
|
|
151
|
-
object.expandedThrough !== "" &&
|
|
152
|
-
object.expandedThrough < instant,
|
|
153
|
-
),
|
|
154
|
-
find: async (_calendarId: string, calendarObjectId: string) =>
|
|
155
|
-
this.objects.get(calendarObjectId) ?? null,
|
|
156
|
-
get: async (_calendarId: string, calendarObjectId: string) => {
|
|
157
|
-
const object = this.objects.get(calendarObjectId);
|
|
158
|
-
if (!object) throw new MissingRow(calendarObjectId);
|
|
159
|
-
return object;
|
|
160
|
-
},
|
|
161
|
-
delete: async (_calendarId: string, calendarObjectId: string) => {
|
|
162
|
-
this.objects.delete(calendarObjectId);
|
|
163
|
-
},
|
|
164
|
-
findByResourceName: async (calendarId: string, resourceName: string) =>
|
|
165
|
-
this.objects.get(deriveCalendarObjectId(calendarId, resourceName)) ??
|
|
166
|
-
null,
|
|
167
|
-
findByUid: async (calendarId: string, icalUid: string) =>
|
|
168
|
-
[...this.objects.values()].find(
|
|
169
|
-
(object) =>
|
|
170
|
-
object.calendarId === calendarId && object.icalUid === icalUid,
|
|
171
|
-
) ?? null,
|
|
172
|
-
listByUidPrefix: async (calendarId: string, prefix: string) =>
|
|
173
|
-
[...this.objects.values()].filter(
|
|
174
|
-
(object) =>
|
|
175
|
-
object.calendarId === calendarId && object.icalUid.startsWith(prefix),
|
|
176
|
-
),
|
|
177
|
-
listByCalendar: async (calendarId: string) =>
|
|
178
|
-
[...this.objects.values()].filter(
|
|
179
|
-
(object) => object.calendarId === calendarId,
|
|
180
|
-
),
|
|
181
|
-
listChangedSince: async (calendarId: string, syncSequence: number) =>
|
|
182
|
-
[...this.objects.values()]
|
|
183
|
-
.filter(
|
|
184
|
-
(object) =>
|
|
185
|
-
object.calendarId === calendarId &&
|
|
186
|
-
object.syncSequence > syncSequence,
|
|
187
|
-
)
|
|
188
|
-
.sort((left, right) => left.syncSequence - right.syncSequence),
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
private readonly eventIndexRepo: ICalendarEventIndexRepository = {
|
|
192
|
-
replaceForObject: async (
|
|
193
|
-
calendarId: string,
|
|
194
|
-
calendarObjectId: string,
|
|
195
|
-
occurrences: CalendarOccurrenceInput[],
|
|
196
|
-
) => {
|
|
197
|
-
const now = Date.now();
|
|
198
|
-
this.occurrences.set(
|
|
199
|
-
calendarObjectId,
|
|
200
|
-
occurrences.map((occurrence) => ({
|
|
201
|
-
...occurrence,
|
|
202
|
-
calendarId,
|
|
203
|
-
calendarObjectId,
|
|
204
|
-
createdAt: now,
|
|
205
|
-
updatedAt: now,
|
|
206
|
-
})),
|
|
207
|
-
);
|
|
208
|
-
},
|
|
209
|
-
deleteForObject: async (_calendarId: string, calendarObjectId: string) => {
|
|
210
|
-
this.occurrences.delete(calendarObjectId);
|
|
211
|
-
},
|
|
212
|
-
listForObject: async (_calendarId: string, calendarObjectId: string) =>
|
|
213
|
-
this.occurrences.get(calendarObjectId) ?? [],
|
|
214
|
-
listByStartRange: async (
|
|
215
|
-
calendarId: string,
|
|
216
|
-
startAt: string,
|
|
217
|
-
endAt: string,
|
|
218
|
-
) =>
|
|
219
|
-
[...this.occurrences.values()]
|
|
220
|
-
.flat()
|
|
221
|
-
.filter(
|
|
222
|
-
(row) =>
|
|
223
|
-
row.calendarId === calendarId &&
|
|
224
|
-
row.startAt >= startAt &&
|
|
225
|
-
row.startAt < endAt,
|
|
226
|
-
)
|
|
227
|
-
.sort((left, right) => left.startAt.localeCompare(right.startAt)),
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
private readonly suggestionRepo: ICalendarSuggestionRepository = {
|
|
231
|
-
put: async (input: PutCalendarSuggestionInput) => {
|
|
232
|
-
const suggestionId = deriveCalendarSuggestionId(
|
|
233
|
-
input.messageId,
|
|
234
|
-
input.bodyPartId,
|
|
235
|
-
input.icalUid,
|
|
236
|
-
);
|
|
237
|
-
const now = Date.now();
|
|
238
|
-
const existing = this.suggestions.get(suggestionId);
|
|
239
|
-
const suggestion: CalendarSuggestionItem = {
|
|
240
|
-
...input,
|
|
241
|
-
suggestionId,
|
|
242
|
-
state: existing?.state ?? CalendarSuggestionState.Pending,
|
|
243
|
-
acceptedCalendarObjectId: existing?.acceptedCalendarObjectId ?? "",
|
|
244
|
-
supersededByMessageId: existing?.supersededByMessageId ?? "",
|
|
245
|
-
createdAt: existing?.createdAt ?? now,
|
|
246
|
-
updatedAt: now,
|
|
247
|
-
};
|
|
248
|
-
this.suggestions.set(suggestionId, suggestion);
|
|
249
|
-
return suggestion;
|
|
250
|
-
},
|
|
251
|
-
get: async (accountConfigId: string, suggestionId: string) => {
|
|
252
|
-
const suggestion = this.suggestions.get(suggestionId);
|
|
253
|
-
if (!suggestion || suggestion.accountConfigId !== accountConfigId) {
|
|
254
|
-
throw new MissingRow(suggestionId);
|
|
255
|
-
}
|
|
256
|
-
return suggestion;
|
|
257
|
-
},
|
|
258
|
-
listByAcceptedCalendarObjects: async (
|
|
259
|
-
accountConfigId: string,
|
|
260
|
-
calendarObjectIds: string[],
|
|
261
|
-
) =>
|
|
262
|
-
[...this.suggestions.values()].filter(
|
|
263
|
-
(suggestion) =>
|
|
264
|
-
suggestion.accountConfigId === accountConfigId &&
|
|
265
|
-
calendarObjectIds.includes(suggestion.acceptedCalendarObjectId),
|
|
266
|
-
),
|
|
267
|
-
listByMessage: async (accountConfigId: string, messageId: string) =>
|
|
268
|
-
[...this.suggestions.values()].filter(
|
|
269
|
-
(suggestion) =>
|
|
270
|
-
suggestion.accountConfigId === accountConfigId &&
|
|
271
|
-
suggestion.messageId === messageId,
|
|
272
|
-
),
|
|
273
|
-
listByState: async (
|
|
274
|
-
accountConfigId: string,
|
|
275
|
-
state: CalendarSuggestionItem["state"],
|
|
276
|
-
options: {
|
|
277
|
-
endsAfter: string;
|
|
278
|
-
limit?: number;
|
|
279
|
-
continuationToken?: string;
|
|
280
|
-
},
|
|
281
|
-
) => ({
|
|
282
|
-
items: [...this.suggestions.values()].filter(
|
|
283
|
-
(suggestion) =>
|
|
284
|
-
suggestion.accountConfigId === accountConfigId &&
|
|
285
|
-
suggestion.state === state &&
|
|
286
|
-
suggestion.endsAtUtc >= options.endsAfter,
|
|
287
|
-
),
|
|
288
|
-
continuationToken: undefined,
|
|
289
|
-
}),
|
|
290
|
-
settle: async (
|
|
291
|
-
accountConfigId: string,
|
|
292
|
-
suggestionId: string,
|
|
293
|
-
input: SettleCalendarSuggestionInput,
|
|
294
|
-
) => {
|
|
295
|
-
const suggestion = this.suggestions.get(suggestionId);
|
|
296
|
-
if (!suggestion || suggestion.accountConfigId !== accountConfigId) {
|
|
297
|
-
throw new MissingRow(suggestionId);
|
|
298
|
-
}
|
|
299
|
-
const settled = { ...suggestion, ...input, updatedAt: Date.now() };
|
|
300
|
-
this.suggestions.set(suggestionId, settled);
|
|
301
|
-
return settled;
|
|
302
|
-
},
|
|
303
|
-
supersedeIfPending: async (
|
|
304
|
-
accountConfigId: string,
|
|
305
|
-
suggestionId: string,
|
|
306
|
-
supersededByMessageId: string,
|
|
307
|
-
) => {
|
|
308
|
-
const suggestion = this.suggestions.get(suggestionId);
|
|
309
|
-
if (
|
|
310
|
-
!suggestion ||
|
|
311
|
-
suggestion.accountConfigId !== accountConfigId ||
|
|
312
|
-
suggestion.state !== CalendarSuggestionState.Pending
|
|
313
|
-
) {
|
|
314
|
-
return null;
|
|
315
|
-
}
|
|
316
|
-
const retired = {
|
|
317
|
-
...suggestion,
|
|
318
|
-
state: CalendarSuggestionState.Superseded,
|
|
319
|
-
acceptedCalendarObjectId: "",
|
|
320
|
-
supersededByMessageId,
|
|
321
|
-
updatedAt: Date.now(),
|
|
322
|
-
};
|
|
323
|
-
this.suggestions.set(suggestionId, retired);
|
|
324
|
-
return retired;
|
|
325
|
-
},
|
|
326
|
-
repointSuperseded: async (
|
|
327
|
-
accountConfigId: string,
|
|
328
|
-
suggestionId: string,
|
|
329
|
-
supersededByMessageId: string,
|
|
330
|
-
) => {
|
|
331
|
-
const suggestion = this.suggestions.get(suggestionId);
|
|
332
|
-
if (
|
|
333
|
-
!suggestion ||
|
|
334
|
-
suggestion.accountConfigId !== accountConfigId ||
|
|
335
|
-
suggestion.state !== CalendarSuggestionState.Superseded
|
|
336
|
-
) {
|
|
337
|
-
return null;
|
|
338
|
-
}
|
|
339
|
-
const repointed = {
|
|
340
|
-
...suggestion,
|
|
341
|
-
supersededByMessageId,
|
|
342
|
-
updatedAt: Date.now(),
|
|
343
|
-
};
|
|
344
|
-
this.suggestions.set(suggestionId, repointed);
|
|
345
|
-
return repointed;
|
|
346
|
-
},
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
private readonly feedTokenRepo: ICalendarFeedTokenRepository = {
|
|
350
|
-
put: async (input: PutCalendarFeedTokenInput) => {
|
|
351
|
-
const feedTokenId = deriveCalendarFeedTokenId(input.calendarId);
|
|
352
|
-
const now = Date.now();
|
|
353
|
-
const existing = this.feedTokens.get(feedTokenId);
|
|
354
|
-
const token: CalendarFeedTokenItem = {
|
|
355
|
-
feedTokenId,
|
|
356
|
-
accountConfigId: input.accountConfigId,
|
|
357
|
-
calendarId: input.calendarId,
|
|
358
|
-
tokenHash: input.tokenHash,
|
|
359
|
-
createdAt: existing?.createdAt ?? now,
|
|
360
|
-
rotatedAt: existing ? now : 0,
|
|
361
|
-
updatedAt: now,
|
|
362
|
-
};
|
|
363
|
-
this.feedTokens.set(feedTokenId, token);
|
|
364
|
-
return token;
|
|
365
|
-
},
|
|
366
|
-
findByCalendar: async (accountConfigId: string, calendarId: string) => {
|
|
367
|
-
const token = this.feedTokens.get(deriveCalendarFeedTokenId(calendarId));
|
|
368
|
-
if (!token || token.accountConfigId !== accountConfigId) return null;
|
|
369
|
-
return token;
|
|
370
|
-
},
|
|
371
|
-
findByTokenHash: async (tokenHash: string) =>
|
|
372
|
-
[...this.feedTokens.values()].find(
|
|
373
|
-
(token) => token.tokenHash === tokenHash,
|
|
374
|
-
) ?? null,
|
|
375
|
-
delete: async (accountConfigId: string, calendarId: string) => {
|
|
376
|
-
const feedTokenId = deriveCalendarFeedTokenId(calendarId);
|
|
377
|
-
const token = this.feedTokens.get(feedTokenId);
|
|
378
|
-
if (!token || token.accountConfigId !== accountConfigId) return;
|
|
379
|
-
this.feedTokens.delete(feedTokenId);
|
|
380
|
-
},
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
get calendarSuggestion(): ICalendarSuggestionRepository {
|
|
384
|
-
return this.suggestionRepo;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
get repos(): CalendarRepositories {
|
|
388
|
-
return {
|
|
389
|
-
calendarCollection: this.collectionRepo,
|
|
390
|
-
calendarObject: this.objectRepo,
|
|
391
|
-
calendarEventIndex: this.eventIndexRepo,
|
|
392
|
-
calendarSuggestion: this.suggestionRepo,
|
|
393
|
-
calendarFeedToken: this.feedTokenRepo,
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
async commit(writes: readonly CalendarWrite[]): Promise<void> {
|
|
398
|
-
for (const write of writes) await this.apply(write);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
private async apply(write: CalendarWrite): Promise<void> {
|
|
402
|
-
switch (write.kind) {
|
|
403
|
-
case "PutObject": {
|
|
404
|
-
const { calendarId } = write.object;
|
|
405
|
-
const syncSequence = await this.collectionRepo.bumpSyncSequence(
|
|
406
|
-
write.accountConfigId,
|
|
407
|
-
calendarId,
|
|
408
|
-
);
|
|
409
|
-
const object = await this.objectRepo.put({
|
|
410
|
-
...write.object,
|
|
411
|
-
syncSequence,
|
|
412
|
-
});
|
|
413
|
-
await this.eventIndexRepo.replaceForObject(
|
|
414
|
-
calendarId,
|
|
415
|
-
object.calendarObjectId,
|
|
416
|
-
write.occurrences,
|
|
417
|
-
);
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
case "ReprojectObject": {
|
|
421
|
-
const { calendarId, resourceName } = write.object;
|
|
422
|
-
const stored = await this.objectRepo.findByResourceName(
|
|
423
|
-
calendarId,
|
|
424
|
-
resourceName,
|
|
425
|
-
);
|
|
426
|
-
if (stored === null || stored.etag !== write.readEtag) return;
|
|
427
|
-
await this.apply({
|
|
428
|
-
kind: "PutObject",
|
|
429
|
-
accountConfigId: write.accountConfigId,
|
|
430
|
-
object: write.object,
|
|
431
|
-
occurrences: write.occurrences,
|
|
432
|
-
});
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
case "DeleteObject":
|
|
436
|
-
await this.eventIndexRepo.deleteForObject(
|
|
437
|
-
write.calendarId,
|
|
438
|
-
write.calendarObjectId,
|
|
439
|
-
);
|
|
440
|
-
await this.objectRepo.delete(write.calendarId, write.calendarObjectId);
|
|
441
|
-
await this.collectionRepo.bumpSyncSequence(
|
|
442
|
-
write.accountConfigId,
|
|
443
|
-
write.calendarId,
|
|
444
|
-
);
|
|
445
|
-
return;
|
|
446
|
-
case "SettleSuggestion":
|
|
447
|
-
await this.suggestionRepo.settle(
|
|
448
|
-
write.accountConfigId,
|
|
449
|
-
write.suggestionId,
|
|
450
|
-
write.settle,
|
|
451
|
-
);
|
|
452
|
-
return;
|
|
453
|
-
case "UpdateCollection":
|
|
454
|
-
await this.collectionRepo.update(
|
|
455
|
-
write.accountConfigId,
|
|
456
|
-
write.calendarId,
|
|
457
|
-
write.patch,
|
|
458
|
-
);
|
|
459
|
-
return;
|
|
460
|
-
case "DeleteCollection": {
|
|
461
|
-
for (const object of await this.objectRepo.listByCalendar(
|
|
462
|
-
write.calendarId,
|
|
463
|
-
)) {
|
|
464
|
-
await this.eventIndexRepo.deleteForObject(
|
|
465
|
-
write.calendarId,
|
|
466
|
-
object.calendarObjectId,
|
|
467
|
-
);
|
|
468
|
-
await this.objectRepo.delete(
|
|
469
|
-
write.calendarId,
|
|
470
|
-
object.calendarObjectId,
|
|
471
|
-
);
|
|
472
|
-
}
|
|
473
|
-
await this.feedTokenRepo.delete(
|
|
474
|
-
write.accountConfigId,
|
|
475
|
-
write.calendarId,
|
|
476
|
-
);
|
|
477
|
-
await this.collectionRepo.delete(
|
|
478
|
-
write.accountConfigId,
|
|
479
|
-
write.calendarId,
|
|
480
|
-
);
|
|
481
|
-
return;
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
}
|