kaafil-js 0.1.0-beta.1 → 0.1.0-beta.3

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.
@@ -16,19 +16,103 @@ var SECURITY_SCHEME_CARRIERS = {
16
16
  shareAuth: { kind: "bearer" }
17
17
  };
18
18
  var OperationId = {
19
+ AddChecklistItem: "addChecklistItem",
20
+ AddItineraryItem: "addItineraryItem",
21
+ AdjustFloat: "adjustFloat",
22
+ AssignPickupTraveller: "assignPickupTraveller",
23
+ AssignRoomingBed: "assignRoomingBed",
24
+ AssignSeating: "assignSeating",
25
+ AutoAssignRooming: "autoAssignRooming",
26
+ AutoAssignSeating: "autoAssignSeating",
27
+ BoardPickupTraveller: "boardPickupTraveller",
28
+ ClaimStatusIngest: "claimStatusIngest",
29
+ ClosePickupStop: "closePickupStop",
30
+ ConfirmFileUpload: "confirmFileUpload",
31
+ CreatePickupStop: "createPickupStop",
32
+ CreateRoomingRoom: "createRoomingRoom",
33
+ CreateRoomingStayWindow: "createRoomingStayWindow",
34
+ CreateSeatingVehicle: "createSeatingVehicle",
35
+ CreateTrekWalkIn: "createTrekWalkIn",
36
+ DeleteChecklistItem: "deleteChecklistItem",
37
+ DeleteItineraryItem: "deleteItineraryItem",
38
+ DeletePickupStop: "deletePickupStop",
39
+ DeleteRoomingRoom: "deleteRoomingRoom",
40
+ DeleteRoomingStayWindow: "deleteRoomingStayWindow",
41
+ DeleteSeatingVehicle: "deleteSeatingVehicle",
42
+ ExportCloseoutPack: "exportCloseoutPack",
43
+ GetShareManifest: "getShareManifest",
44
+ GetShareSnapshot: "getShareSnapshot",
45
+ IssueFloat: "issueFloat",
46
+ LinkExpenseReceipt: "linkExpenseReceipt",
47
+ LinkSeatingManager: "linkSeatingManager",
48
+ ListChecklistTemplates: "listChecklistTemplates",
49
+ ListCollections: "listCollections",
50
+ ListEligibleCollections: "listEligibleCollections",
51
+ ListExpenses: "listExpenses",
19
52
  ListJourneyTriggers: "listJourneyTriggers",
53
+ ListManagerNotifications: "listManagerNotifications",
54
+ ListPickupStops: "listPickupStops",
55
+ ListRoomingStayWindows: "listRoomingStayWindows",
20
56
  ListTripVendors: "listTripVendors",
57
+ LockCloseout: "lockCloseout",
58
+ LogExpense: "logExpense",
59
+ PatchChecklistItem: "patchChecklistItem",
60
+ PatchItineraryDay: "patchItineraryDay",
61
+ PatchItineraryItem: "patchItineraryItem",
21
62
  PatchJourneyTrigger: "patchJourneyTrigger",
63
+ PatchPickupStop: "patchPickupStop",
64
+ PatchRoomingRoom: "patchRoomingRoom",
65
+ PatchRoomingStayWindow: "patchRoomingStayWindow",
66
+ PatchSeatingVehicle: "patchSeatingVehicle",
67
+ PostponeTrek: "postponeTrek",
68
+ PullChecklistTemplate: "pullChecklistTemplate",
69
+ ReadChecklistAggregate: "readChecklistAggregate",
70
+ ReadCloseout: "readCloseout",
71
+ ReadExpense: "readExpense",
72
+ ReadFile: "readFile",
73
+ ReadFileUrl: "readFileUrl",
74
+ ReadFloatLedger: "readFloatLedger",
75
+ ReadFloatSummary: "readFloatSummary",
76
+ ReadItinerary: "readItinerary",
77
+ ReadItineraryChangeLog: "readItineraryChangeLog",
22
78
  ReadJourney: "readJourney",
23
79
  ReadJourneyCapabilities: "readJourneyCapabilities",
80
+ ReadManifestByPickup: "readManifestByPickup",
81
+ ReadRoomingBoard: "readRoomingBoard",
82
+ ReadSeatingBoard: "readSeatingBoard",
83
+ ReadTrekBoard: "readTrekBoard",
84
+ ReadTrekWalkInMeta: "readTrekWalkInMeta",
24
85
  RebuildJourney: "rebuildJourney",
25
- RunJourneyStep: "runJourneyStep"};
86
+ RecordCollection: "recordCollection",
87
+ ReopenPickupStop: "reopenPickupStop",
88
+ ReorderItineraryItem: "reorderItineraryItem",
89
+ ReorderPickupStops: "reorderPickupStops",
90
+ RequestFileUpload: "requestFileUpload",
91
+ ReturnFloat: "returnFloat",
92
+ RunJourneyStep: "runJourneyStep",
93
+ SaveCloseoutHandover: "saveCloseoutHandover",
94
+ ShareListForms: "shareListForms",
95
+ ShareRenderForm: "shareRenderForm",
96
+ ShareSaveForm: "shareSaveForm",
97
+ ShareSubmitForm: "shareSubmitForm",
98
+ SubmitExpenseClaim: "submitExpenseClaim",
99
+ SyncPullTrip: "syncPullTrip",
100
+ SyncPush: "syncPush",
101
+ SyncPushShare: "syncPushShare",
102
+ ToggleChecklistItem: "toggleChecklistItem",
103
+ UnlinkSeatingManager: "unlinkSeatingManager",
104
+ UnlockCloseout: "unlockCloseout",
105
+ VoidCollection: "voidCollection",
106
+ VoidExpense: "voidExpense",
107
+ WithdrawExpenseClaim: "withdrawExpenseClaim"
108
+ };
26
109
  var OPERATION_SECURITY = {
27
110
  acceptConsoleInvite: [],
28
111
  acceptPlatformAdminInvite: [],
29
112
  addChecklistItem: ["managerAuth"],
30
113
  addItineraryItem: ["managerAuth"],
31
114
  adjustFloat: ["managerAuth", "apiKeyAuth", "agencyAdminAuth"],
115
+ archiveForm: ["apiKeyAuth", "agencyAdminAuth"],
32
116
  assignManager: ["apiKeyAuth"],
33
117
  assignPickupTraveller: ["managerAuth"],
34
118
  assignRoomingBed: ["managerAuth"],
@@ -36,16 +120,23 @@ var OPERATION_SECURITY = {
36
120
  autoAssignRooming: ["managerAuth"],
37
121
  autoAssignSeating: ["managerAuth"],
38
122
  boardPickupTraveller: ["managerAuth"],
123
+ bulkUpsertBookings: ["apiKeyAuth"],
39
124
  cancelTrip: ["apiKeyAuth"],
40
125
  changeOwnPlatformPassword: ["platformAdminAuth"],
41
126
  claimStatusIngest: ["apiKeyAuth"],
127
+ cloneForm: ["apiKeyAuth", "agencyAdminAuth"],
128
+ closeForm: ["apiKeyAuth", "agencyAdminAuth"],
42
129
  closePickupStop: ["managerAuth"],
43
- confirmFileUpload: ["managerAuth"],
130
+ confirmFileUpload: ["managerAuth", "apiKeyAuth"],
44
131
  consoleLogin: [],
45
132
  consoleLogout: ["consoleAuth"],
46
133
  consoleSwitchPlane: ["consoleAuth"],
47
134
  createApiKey: ["consoleAuth"],
48
135
  createConsoleUser: ["consoleAuth"],
136
+ createForm: ["apiKeyAuth", "agencyAdminAuth"],
137
+ createFormField: ["apiKeyAuth", "agencyAdminAuth"],
138
+ createFormSection: ["apiKeyAuth", "agencyAdminAuth"],
139
+ createMessageTemplate: ["apiKeyAuth"],
49
140
  createPickupStop: ["managerAuth"],
50
141
  createPlatformAdmin: ["platformAdminAuth"],
51
142
  createPlatformPartner: ["platformAdminAuth"],
@@ -54,14 +145,29 @@ var OPERATION_SECURITY = {
54
145
  createRoomingStayWindow: ["managerAuth"],
55
146
  createSeatingVehicle: ["managerAuth"],
56
147
  createTrekWalkIn: ["managerAuth"],
148
+ deleteBooking: ["apiKeyAuth"],
57
149
  deleteChecklistItem: ["managerAuth"],
150
+ deleteForm: ["apiKeyAuth", "agencyAdminAuth"],
151
+ deleteFormField: ["apiKeyAuth", "agencyAdminAuth"],
152
+ deleteFormSection: ["apiKeyAuth", "agencyAdminAuth"],
58
153
  deleteItineraryItem: ["managerAuth"],
59
154
  deletePickupStop: ["managerAuth"],
60
155
  deletePlatformPartnerPlan: ["platformAdminAuth"],
61
156
  deleteRoomingRoom: ["managerAuth"],
62
157
  deleteRoomingStayWindow: ["managerAuth"],
63
158
  deleteSeatingVehicle: ["managerAuth"],
159
+ dispatchForm: ["managerAuth", "apiKeyAuth"],
64
160
  editWebhookEndpoint: ["consoleAuth"],
161
+ exportCloseoutPack: ["managerAuth", "apiKeyAuth"],
162
+ exportFormResponses: ["apiKeyAuth", "managerAuth"],
163
+ getForm: ["apiKeyAuth", "agencyAdminAuth", "managerAuth"],
164
+ getFormAggregate: ["apiKeyAuth"],
165
+ getFormConsentReceipt: ["apiKeyAuth", "managerAuth"],
166
+ getFormResponse: ["managerAuth", "apiKeyAuth"],
167
+ getFormsCompletionMatrix: ["managerAuth", "apiKeyAuth"],
168
+ getFormsCrossModuleAnswers: ["managerAuth", "apiKeyAuth"],
169
+ getShareManifest: ["shareAuth"],
170
+ getShareSnapshot: ["shareAuth"],
65
171
  getTrip: ["apiKeyAuth"],
66
172
  health: [],
67
173
  healthV1: [],
@@ -72,6 +178,7 @@ var OPERATION_SECURITY = {
72
178
  linkSeatingManager: ["managerAuth"],
73
179
  listAgencies: ["consoleAuth"],
74
180
  listApiKeys: ["consoleAuth"],
181
+ listBookings: ["apiKeyAuth", "managerAuth"],
75
182
  listChecklistTemplates: ["managerAuth", "apiKeyAuth"],
76
183
  listCollections: ["managerAuth", "apiKeyAuth"],
77
184
  listConsoleTrips: ["consoleAuth"],
@@ -79,45 +186,65 @@ var OPERATION_SECURITY = {
79
186
  listEligibleCollections: ["managerAuth", "apiKeyAuth"],
80
187
  listEvents: ["apiKeyAuth"],
81
188
  listExpenses: ["managerAuth", "apiKeyAuth"],
189
+ listFormBindings: ["apiKeyAuth", "agencyAdminAuth", "managerAuth"],
190
+ listForms: ["apiKeyAuth", "agencyAdminAuth"],
82
191
  listJourneyTriggers: ["apiKeyAuth", "agencyAdminAuth"],
192
+ listManagerNotifications: ["managerAuth"],
193
+ listMessages: ["apiKeyAuth"],
194
+ listMessageTemplates: ["apiKeyAuth"],
83
195
  listPickupStops: ["managerAuth", "agencyAdminAuth", "apiKeyAuth"],
84
196
  listPlatformAdmins: ["platformAdminAuth"],
85
197
  listPlatformPartnerApiKeys: ["platformAdminAuth"],
86
198
  listPlatformPartnerConsoleUsers: ["platformAdminAuth"],
87
199
  listPlatformPartners: ["platformAdminAuth"],
88
200
  listRoomingStayWindows: ["managerAuth", "agencyAdminAuth", "apiKeyAuth"],
201
+ listTripFormResponses: ["managerAuth", "apiKeyAuth"],
202
+ listTripForms: ["managerAuth", "apiKeyAuth"],
89
203
  listTripVendors: ["apiKeyAuth", "managerAuth", "agencyAdminAuth"],
90
204
  listWebhookDeliveries: ["apiKeyAuth"],
91
205
  listWebhookEndpoints: ["consoleAuth"],
206
+ lockCloseout: ["managerAuth"],
92
207
  logExpense: ["managerAuth"],
208
+ managerCreateFormResponse: ["managerAuth"],
209
+ markNotificationRead: ["managerAuth"],
93
210
  mintAgencyAdminTokens: ["apiKeyAuth"],
94
211
  mintManagerTokens: ["apiKeyAuth"],
95
212
  mintShareToken: ["apiKeyAuth"],
96
213
  patchAgencyEntitlement: ["consoleAuth"],
97
214
  patchChecklistItem: ["managerAuth"],
98
215
  patchConsoleUser: ["consoleAuth"],
216
+ patchForm: ["apiKeyAuth", "agencyAdminAuth"],
217
+ patchFormField: ["apiKeyAuth", "agencyAdminAuth"],
218
+ patchFormSection: ["apiKeyAuth", "agencyAdminAuth"],
99
219
  patchItineraryDay: ["managerAuth"],
100
220
  patchItineraryItem: ["managerAuth"],
101
221
  patchJourneyTrigger: ["apiKeyAuth", "agencyAdminAuth"],
222
+ patchMessageTemplate: ["apiKeyAuth"],
102
223
  patchPickupStop: ["managerAuth"],
103
224
  patchPlatformAdmin: ["platformAdminAuth"],
104
225
  patchPlatformPartnerConsoleUser: ["platformAdminAuth"],
105
226
  patchRoomingRoom: ["managerAuth"],
106
227
  patchRoomingStayWindow: ["managerAuth"],
107
228
  patchSeatingVehicle: ["managerAuth"],
229
+ patchShareToken: ["apiKeyAuth"],
108
230
  platformLogin: [],
109
231
  platformLogout: ["platformAdminAuth"],
110
232
  platformMe: ["platformAdminAuth"],
111
233
  platformRefreshTokens: ["platformAdminAuth"],
112
234
  postponeTrek: ["managerAuth"],
235
+ publishForm: ["apiKeyAuth", "agencyAdminAuth"],
113
236
  pullChecklistTemplate: ["managerAuth"],
114
237
  pushBulkTrips: ["apiKeyAuth"],
115
238
  pushManifest: ["apiKeyAuth"],
116
239
  pushTripBalances: ["apiKeyAuth"],
240
+ putCommsConfig: ["apiKeyAuth"],
117
241
  putPlatformPartnerPlan: ["platformAdminAuth"],
118
242
  readAgencyEntitlement: ["consoleAuth"],
243
+ readAgencyFeedbackSummary: ["agencyAdminAuth", "apiKeyAuth"],
119
244
  readApiKey: ["consoleAuth"],
120
245
  readChecklistAggregate: ["managerAuth", "apiKeyAuth"],
246
+ readCloseout: ["managerAuth", "apiKeyAuth"],
247
+ readCommsConfig: ["apiKeyAuth"],
121
248
  readConsoleAudit: ["consoleAuth"],
122
249
  readConsoleChecklist: ["consoleAuth"],
123
250
  readConsoleItinerary: ["consoleAuth"],
@@ -146,6 +273,7 @@ var OPERATION_SECURITY = {
146
273
  readShareToken: ["apiKeyAuth"],
147
274
  readTrekBoard: ["managerAuth", "apiKeyAuth"],
148
275
  readTrekWalkInMeta: ["managerAuth", "apiKeyAuth"],
276
+ readTripFeedbackSummary: ["managerAuth", "agencyAdminAuth", "apiKeyAuth"],
149
277
  readUsage: ["consoleAuth"],
150
278
  readWebhookDelivery: ["apiKeyAuth"],
151
279
  readWebhookEndpoint: ["consoleAuth"],
@@ -155,17 +283,21 @@ var OPERATION_SECURITY = {
155
283
  redeliverWebhookDelivery: ["apiKeyAuth"],
156
284
  refreshAgencyAdminTokens: ["agencyAdminAuth"],
157
285
  refreshManagerTokens: ["managerAuth"],
286
+ regenerateShareToken: ["apiKeyAuth"],
158
287
  registerWebhookEndpoint: ["consoleAuth"],
159
288
  reissueConsoleUserInvite: ["consoleAuth"],
160
289
  reissuePlatformAdminInvite: ["platformAdminAuth"],
161
290
  reissuePlatformPartnerConsoleUserInvite: ["platformAdminAuth"],
162
291
  removeFromManifest: ["apiKeyAuth"],
163
292
  renamePlatformPartner: ["platformAdminAuth"],
293
+ reopenForm: ["apiKeyAuth", "agencyAdminAuth"],
164
294
  reopenPickupStop: ["managerAuth"],
295
+ reorderForm: ["apiKeyAuth", "agencyAdminAuth"],
165
296
  reorderItineraryItem: ["managerAuth"],
166
297
  reorderPickupStops: ["managerAuth"],
298
+ replaceBookingVouchers: ["apiKeyAuth"],
167
299
  replayWebhookEndpoint: ["apiKeyAuth"],
168
- requestFileUpload: ["managerAuth"],
300
+ requestFileUpload: ["managerAuth", "apiKeyAuth"],
169
301
  resetPlatformPartnerConsoleUser: ["platformAdminAuth"],
170
302
  returnFloat: ["managerAuth"],
171
303
  revokeApiKey: ["consoleAuth"],
@@ -174,11 +306,23 @@ var OPERATION_SECURITY = {
174
306
  rotateApiKey: ["consoleAuth"],
175
307
  rotateWebhookEndpointSecret: ["consoleAuth"],
176
308
  runJourneyStep: ["apiKeyAuth"],
309
+ saveCloseoutHandover: ["managerAuth"],
310
+ sendMessage: ["apiKeyAuth"],
177
311
  setPlatformPartnerStatus: ["platformAdminAuth"],
312
+ shareListForms: ["shareAuth"],
313
+ shareRenderForm: ["shareAuth"],
314
+ shareSaveForm: ["shareAuth"],
315
+ shareSubmitForm: ["shareAuth"],
178
316
  submitExpenseClaim: ["managerAuth"],
317
+ syncDigest: ["apiKeyAuth"],
318
+ syncPullTrip: ["managerAuth", "apiKeyAuth"],
319
+ syncPush: ["managerAuth", "apiKeyAuth"],
320
+ syncPushShare: [],
179
321
  toggleChecklistItem: ["managerAuth"],
322
+ unarchiveForm: ["apiKeyAuth", "agencyAdminAuth"],
180
323
  unassignManager: ["apiKeyAuth"],
181
324
  unlinkSeatingManager: ["managerAuth"],
325
+ unlockCloseout: ["apiKeyAuth"],
182
326
  upsertAgencyAdmin: ["apiKeyAuth"],
183
327
  upsertManager: ["apiKeyAuth"],
184
328
  upsertTravellerProfile: ["apiKeyAuth"],
@@ -193,6 +337,7 @@ var OPERATION_ACCEPTS_IDEMPOTENCY_KEY = {
193
337
  addChecklistItem: true,
194
338
  addItineraryItem: true,
195
339
  adjustFloat: true,
340
+ archiveForm: false,
196
341
  assignManager: true,
197
342
  assignPickupTraveller: true,
198
343
  assignRoomingBed: true,
@@ -200,9 +345,12 @@ var OPERATION_ACCEPTS_IDEMPOTENCY_KEY = {
200
345
  autoAssignRooming: true,
201
346
  autoAssignSeating: true,
202
347
  boardPickupTraveller: true,
348
+ bulkUpsertBookings: true,
203
349
  cancelTrip: true,
204
350
  changeOwnPlatformPassword: false,
205
351
  claimStatusIngest: true,
352
+ cloneForm: true,
353
+ closeForm: false,
206
354
  closePickupStop: true,
207
355
  confirmFileUpload: true,
208
356
  consoleLogin: false,
@@ -210,6 +358,10 @@ var OPERATION_ACCEPTS_IDEMPOTENCY_KEY = {
210
358
  consoleSwitchPlane: false,
211
359
  createApiKey: true,
212
360
  createConsoleUser: true,
361
+ createForm: true,
362
+ createFormField: false,
363
+ createFormSection: false,
364
+ createMessageTemplate: true,
213
365
  createPickupStop: true,
214
366
  createPlatformAdmin: false,
215
367
  createPlatformPartner: false,
@@ -218,14 +370,29 @@ var OPERATION_ACCEPTS_IDEMPOTENCY_KEY = {
218
370
  createRoomingStayWindow: true,
219
371
  createSeatingVehicle: true,
220
372
  createTrekWalkIn: true,
373
+ deleteBooking: true,
221
374
  deleteChecklistItem: false,
375
+ deleteForm: false,
376
+ deleteFormField: false,
377
+ deleteFormSection: false,
222
378
  deleteItineraryItem: false,
223
379
  deletePickupStop: false,
224
380
  deletePlatformPartnerPlan: false,
225
381
  deleteRoomingRoom: false,
226
382
  deleteRoomingStayWindow: false,
227
383
  deleteSeatingVehicle: false,
384
+ dispatchForm: true,
228
385
  editWebhookEndpoint: true,
386
+ exportCloseoutPack: false,
387
+ exportFormResponses: false,
388
+ getForm: false,
389
+ getFormAggregate: false,
390
+ getFormConsentReceipt: false,
391
+ getFormResponse: false,
392
+ getFormsCompletionMatrix: false,
393
+ getFormsCrossModuleAnswers: false,
394
+ getShareManifest: false,
395
+ getShareSnapshot: false,
229
396
  getTrip: false,
230
397
  health: false,
231
398
  healthV1: false,
@@ -236,6 +403,7 @@ var OPERATION_ACCEPTS_IDEMPOTENCY_KEY = {
236
403
  linkSeatingManager: true,
237
404
  listAgencies: false,
238
405
  listApiKeys: false,
406
+ listBookings: false,
239
407
  listChecklistTemplates: false,
240
408
  listCollections: false,
241
409
  listConsoleTrips: false,
@@ -243,45 +411,65 @@ var OPERATION_ACCEPTS_IDEMPOTENCY_KEY = {
243
411
  listEligibleCollections: false,
244
412
  listEvents: false,
245
413
  listExpenses: false,
414
+ listFormBindings: false,
415
+ listForms: false,
246
416
  listJourneyTriggers: false,
417
+ listManagerNotifications: false,
418
+ listMessages: false,
419
+ listMessageTemplates: false,
247
420
  listPickupStops: false,
248
421
  listPlatformAdmins: false,
249
422
  listPlatformPartnerApiKeys: false,
250
423
  listPlatformPartnerConsoleUsers: false,
251
424
  listPlatformPartners: false,
252
425
  listRoomingStayWindows: false,
426
+ listTripFormResponses: false,
427
+ listTripForms: false,
253
428
  listTripVendors: false,
254
429
  listWebhookDeliveries: false,
255
430
  listWebhookEndpoints: false,
431
+ lockCloseout: true,
256
432
  logExpense: true,
433
+ managerCreateFormResponse: true,
434
+ markNotificationRead: true,
257
435
  mintAgencyAdminTokens: false,
258
436
  mintManagerTokens: false,
259
437
  mintShareToken: true,
260
438
  patchAgencyEntitlement: true,
261
439
  patchChecklistItem: false,
262
440
  patchConsoleUser: true,
441
+ patchForm: false,
442
+ patchFormField: false,
443
+ patchFormSection: false,
263
444
  patchItineraryDay: false,
264
445
  patchItineraryItem: false,
265
446
  patchJourneyTrigger: true,
447
+ patchMessageTemplate: false,
266
448
  patchPickupStop: false,
267
449
  patchPlatformAdmin: false,
268
450
  patchPlatformPartnerConsoleUser: false,
269
451
  patchRoomingRoom: false,
270
452
  patchRoomingStayWindow: false,
271
453
  patchSeatingVehicle: false,
454
+ patchShareToken: false,
272
455
  platformLogin: true,
273
456
  platformLogout: false,
274
457
  platformMe: false,
275
458
  platformRefreshTokens: true,
276
459
  postponeTrek: true,
460
+ publishForm: false,
277
461
  pullChecklistTemplate: true,
278
462
  pushBulkTrips: true,
279
463
  pushManifest: true,
280
464
  pushTripBalances: true,
465
+ putCommsConfig: false,
281
466
  putPlatformPartnerPlan: false,
282
467
  readAgencyEntitlement: false,
468
+ readAgencyFeedbackSummary: false,
283
469
  readApiKey: false,
284
470
  readChecklistAggregate: false,
471
+ readCloseout: false,
472
+ readCommsConfig: false,
285
473
  readConsoleAudit: false,
286
474
  readConsoleChecklist: false,
287
475
  readConsoleItinerary: false,
@@ -310,6 +498,7 @@ var OPERATION_ACCEPTS_IDEMPOTENCY_KEY = {
310
498
  readShareToken: false,
311
499
  readTrekBoard: false,
312
500
  readTrekWalkInMeta: false,
501
+ readTripFeedbackSummary: false,
313
502
  readUsage: false,
314
503
  readWebhookDelivery: false,
315
504
  readWebhookEndpoint: false,
@@ -319,15 +508,19 @@ var OPERATION_ACCEPTS_IDEMPOTENCY_KEY = {
319
508
  redeliverWebhookDelivery: true,
320
509
  refreshAgencyAdminTokens: false,
321
510
  refreshManagerTokens: false,
511
+ regenerateShareToken: true,
322
512
  registerWebhookEndpoint: true,
323
513
  reissueConsoleUserInvite: true,
324
514
  reissuePlatformAdminInvite: false,
325
515
  reissuePlatformPartnerConsoleUserInvite: false,
326
516
  removeFromManifest: true,
327
517
  renamePlatformPartner: false,
518
+ reopenForm: false,
328
519
  reopenPickupStop: true,
520
+ reorderForm: false,
329
521
  reorderItineraryItem: true,
330
522
  reorderPickupStops: true,
523
+ replaceBookingVouchers: false,
331
524
  replayWebhookEndpoint: true,
332
525
  requestFileUpload: true,
333
526
  resetPlatformPartnerConsoleUser: false,
@@ -338,11 +531,23 @@ var OPERATION_ACCEPTS_IDEMPOTENCY_KEY = {
338
531
  rotateApiKey: true,
339
532
  rotateWebhookEndpointSecret: true,
340
533
  runJourneyStep: true,
534
+ saveCloseoutHandover: true,
535
+ sendMessage: true,
341
536
  setPlatformPartnerStatus: false,
537
+ shareListForms: false,
538
+ shareRenderForm: false,
539
+ shareSaveForm: true,
540
+ shareSubmitForm: true,
342
541
  submitExpenseClaim: true,
542
+ syncDigest: false,
543
+ syncPullTrip: false,
544
+ syncPush: false,
545
+ syncPushShare: false,
343
546
  toggleChecklistItem: true,
547
+ unarchiveForm: false,
344
548
  unassignManager: true,
345
549
  unlinkSeatingManager: false,
550
+ unlockCloseout: true,
346
551
  upsertAgencyAdmin: true,
347
552
  upsertManager: true,
348
553
  upsertTravellerProfile: true,
@@ -358,8 +563,16 @@ var KaafilErrorCode = {
358
563
  CannotPostpone: "CANNOT_POSTPONE",
359
564
  CapabilityUnavailable: "CAPABILITY_UNAVAILABLE",
360
565
  ConflictVersion: "CONFLICT_VERSION",
566
+ ConsentRequired: "CONSENT_REQUIRED",
567
+ FieldNotVisible: "FIELD_NOT_VISIBLE",
361
568
  FileOrphaned: "FILE_ORPHANED",
362
569
  FilePurged: "FILE_PURGED",
570
+ FormClosed: "FORM_CLOSED",
571
+ FormDefinitionChanged: "FORM_DEFINITION_CHANGED",
572
+ FormLockedByResponses: "FORM_LOCKED_BY_RESPONSES",
573
+ FormNotOpen: "FORM_NOT_OPEN",
574
+ FormNotPublishable: "FORM_NOT_PUBLISHABLE",
575
+ FormWindowInvalid: "FORM_WINDOW_INVALID",
363
576
  IdempotencyKeyReused: "IDEMPOTENCY_KEY_REUSED",
364
577
  InternalError: "INTERNAL_ERROR",
365
578
  Locked: "LOCKED",
@@ -371,14 +584,17 @@ var KaafilErrorCode = {
371
584
  ReadOnlyRole: "READ_ONLY_ROLE",
372
585
  ResourceNotFound: "RESOURCE_NOT_FOUND",
373
586
  ResponseClosed: "RESPONSE_CLOSED",
587
+ ResponseLimitReached: "RESPONSE_LIMIT_REACHED",
374
588
  SeatingCapacityOrphan: "SEATING_CAPACITY_ORPHAN",
375
589
  SecretNotReplayable: "SECRET_NOT_REPLAYABLE",
376
590
  ShareTokenExpired: "SHARE_TOKEN_EXPIRED",
377
591
  ShareTokenRevoked: "SHARE_TOKEN_REVOKED",
592
+ ShareWriteGraceExpired: "SHARE_WRITE_GRACE_EXPIRED",
378
593
  StayWindowHasAssignments: "STAY_WINDOW_HAS_ASSIGNMENTS",
379
594
  StayWindowOverlap: "STAY_WINDOW_OVERLAP",
380
595
  StopHasPending: "STOP_HAS_PENDING",
381
596
  SubjectRequired: "SUBJECT_REQUIRED",
597
+ SyncTargetRefused: "SYNC_TARGET_REFUSED",
382
598
  TenantScopeMissing: "TENANT_SCOPE_MISSING",
383
599
  Unauthenticated: "UNAUTHENTICATED",
384
600
  UploadMismatch: "UPLOAD_MISMATCH",
@@ -400,8 +616,16 @@ var ERROR_CODE_TABLE = {
400
616
  CANNOT_POSTPONE: { status: 422, retryability: "no", outboxClass: "FATAL" },
401
617
  CAPABILITY_UNAVAILABLE: { status: 422, retryability: "no", outboxClass: "FATAL" },
402
618
  CONFLICT_VERSION: { status: 409, retryability: "no", outboxClass: "CONFLICT" },
619
+ CONSENT_REQUIRED: { status: 422, retryability: "no", outboxClass: "FATAL" },
620
+ FIELD_NOT_VISIBLE: { status: 422, retryability: "no", outboxClass: "FATAL" },
403
621
  FILE_ORPHANED: { status: 409, retryability: "no", outboxClass: "FATAL" },
404
622
  FILE_PURGED: { status: 410, retryability: "no", outboxClass: "FATAL" },
623
+ FORM_CLOSED: { status: 409, retryability: "no", outboxClass: "FATAL" },
624
+ FORM_DEFINITION_CHANGED: { status: 409, retryability: "no", outboxClass: "FATAL" },
625
+ FORM_LOCKED_BY_RESPONSES: { status: 422, retryability: "no", outboxClass: "FATAL" },
626
+ FORM_NOT_OPEN: { status: 422, retryability: "no", outboxClass: "FATAL" },
627
+ FORM_NOT_PUBLISHABLE: { status: 422, retryability: "no", outboxClass: "FATAL" },
628
+ FORM_WINDOW_INVALID: { status: 422, retryability: "no", outboxClass: "FATAL" },
405
629
  IDEMPOTENCY_KEY_REUSED: { status: 422, retryability: "no", outboxClass: "FATAL" },
406
630
  INTERNAL_ERROR: { status: 500, retryability: "yes", outboxClass: "TRANSIENT" },
407
631
  LOCKED: { status: 423, retryability: "no", outboxClass: "FATAL" },
@@ -413,14 +637,17 @@ var ERROR_CODE_TABLE = {
413
637
  READ_ONLY_ROLE: { status: 422, retryability: "no", outboxClass: "FATAL" },
414
638
  RESOURCE_NOT_FOUND: { status: 404, retryability: "no", outboxClass: "FATAL" },
415
639
  RESPONSE_CLOSED: { status: 409, retryability: "no", outboxClass: "FATAL" },
640
+ RESPONSE_LIMIT_REACHED: { status: 422, retryability: "no", outboxClass: "FATAL" },
416
641
  SEATING_CAPACITY_ORPHAN: { status: 422, retryability: "no", outboxClass: "FATAL" },
417
642
  SECRET_NOT_REPLAYABLE: { status: 409, retryability: "no", outboxClass: "CONFLICT" },
418
643
  SHARE_TOKEN_EXPIRED: { status: 401, retryability: "no", outboxClass: "FATAL" },
419
644
  SHARE_TOKEN_REVOKED: { status: 401, retryability: "no", outboxClass: "FATAL" },
645
+ SHARE_WRITE_GRACE_EXPIRED: { status: 422, retryability: "no", outboxClass: "FATAL" },
420
646
  STAY_WINDOW_HAS_ASSIGNMENTS: { status: 422, retryability: "no", outboxClass: "FATAL" },
421
647
  STAY_WINDOW_OVERLAP: { status: 422, retryability: "no", outboxClass: "FATAL" },
422
648
  STOP_HAS_PENDING: { status: 422, retryability: "no", outboxClass: "FATAL" },
423
649
  SUBJECT_REQUIRED: { status: 422, retryability: "no", outboxClass: "FATAL" },
650
+ SYNC_TARGET_REFUSED: { status: 422, retryability: "no", outboxClass: "FATAL" },
424
651
  TENANT_SCOPE_MISSING: { status: 500, retryability: "yes", outboxClass: "TRANSIENT" },
425
652
  UNAUTHENTICATED: { status: 401, retryability: "after-refresh", outboxClass: "FATAL" },
426
653
  UPLOAD_MISMATCH: { status: 422, retryability: "no", outboxClass: "FATAL" },
@@ -1055,7 +1282,8 @@ function createHttpClient(config) {
1055
1282
  random: config.random
1056
1283
  };
1057
1284
  return {
1058
- execute: (request) => execute(ctx, request)
1285
+ execute: (request) => execute(ctx, request),
1286
+ executeBinary: (request) => executeBinary(ctx, request)
1059
1287
  };
1060
1288
  }
1061
1289
  function renderPath(template, params) {
@@ -1112,7 +1340,7 @@ async function buildHeaders(ctx, request, idempotencyKey, hasBody) {
1112
1340
  const acceptedSchemes = OPERATION_SECURITY[request.operationId];
1113
1341
  const credential = await ctx.credentials.resolveHeaders(request.operationId, acceptedSchemes);
1114
1342
  const headers = new Headers();
1115
- headers.set("Accept", "application/json");
1343
+ headers.set("Accept", request.accept ?? "application/json");
1116
1344
  if (hasBody) {
1117
1345
  headers.set("Content-Type", "application/json");
1118
1346
  }
@@ -1188,7 +1416,17 @@ function describeCrossOriginSuspect(url) {
1188
1416
  }
1189
1417
  return `Request failed while calling a different origin (${url.origin}) than the page's own origin (${origin}). The most likely cause is that the API has not allowlisted this origin for CORS \u2014 but the browser withholds the actual reason from JavaScript when it blocks a cross-origin response, so the SDK cannot confirm this; a genuine network outage produces the same rejection. If this is unexpected, the fix is server-side: add this origin to the API's CORS allowlist.`;
1190
1418
  }
1191
- async function sendOnce(ctx, request, idempotencyKey) {
1419
+ async function throwFromErrorResponse(response, status, requestId) {
1420
+ const text = await response.text();
1421
+ const body = text.length > 0 ? tryParseJson(text) : void 0;
1422
+ const retryAfterSeconds = parseRetryAfterSeconds(response.headers.get("retry-after"));
1423
+ throw fromEnvelope(body, {
1424
+ status,
1425
+ ...requestId !== void 0 ? { requestId } : {},
1426
+ ...retryAfterSeconds !== void 0 ? { retryAfterSeconds } : {}
1427
+ });
1428
+ }
1429
+ async function sendOnceWith(ctx, request, idempotencyKey, readSuccess) {
1192
1430
  const hasBody = request.body !== void 0;
1193
1431
  const renderedPath = renderPath(request.path, request.pathParams);
1194
1432
  const url = buildUrl(ctx.baseUrl, renderedPath, request.query);
@@ -1203,23 +1441,10 @@ async function sendOnce(ctx, request, idempotencyKey) {
1203
1441
  });
1204
1442
  const requestId = response.headers.get("x-request-id") ?? void 0;
1205
1443
  const status = response.status;
1206
- const text = await response.text();
1207
- const body = text.length > 0 ? tryParseJson(text) : void 0;
1208
1444
  if (response.ok) {
1209
- if (!isSuccessEnvelope(body)) {
1210
- throw new KaafilNetworkError(`Received an unrecognizable success body for HTTP ${status}`, {
1211
- status,
1212
- ...requestId !== void 0 ? { requestId } : {}
1213
- });
1214
- }
1215
- return { data: body.data, meta: buildResponseMeta(status, requestId, body.meta) };
1445
+ return await readSuccess(response, status, requestId);
1216
1446
  }
1217
- const retryAfterSeconds = parseRetryAfterSeconds(response.headers.get("retry-after"));
1218
- throw fromEnvelope(body, {
1219
- status,
1220
- ...requestId !== void 0 ? { requestId } : {},
1221
- ...retryAfterSeconds !== void 0 ? { retryAfterSeconds } : {}
1222
- });
1447
+ return await throwFromErrorResponse(response, status, requestId);
1223
1448
  } catch (error) {
1224
1449
  if (isKaafilError(error)) {
1225
1450
  throw error;
@@ -1237,6 +1462,30 @@ async function sendOnce(ctx, request, idempotencyKey) {
1237
1462
  combined.cleanup();
1238
1463
  }
1239
1464
  }
1465
+ function sendOnce(ctx, request, idempotencyKey) {
1466
+ return sendOnceWith(ctx, request, idempotencyKey, async (response, status, requestId) => {
1467
+ const text = await response.text();
1468
+ const body = text.length > 0 ? tryParseJson(text) : void 0;
1469
+ if (!isSuccessEnvelope(body)) {
1470
+ throw new KaafilNetworkError(`Received an unrecognizable success body for HTTP ${status}`, {
1471
+ status,
1472
+ ...requestId !== void 0 ? { requestId } : {}
1473
+ });
1474
+ }
1475
+ return { data: body.data, meta: buildResponseMeta(status, requestId, body.meta) };
1476
+ });
1477
+ }
1478
+ function sendOnceBinary(ctx, request, idempotencyKey) {
1479
+ return sendOnceWith(ctx, request, idempotencyKey, async (response, status, requestId) => {
1480
+ const buffer = await response.arrayBuffer();
1481
+ const meta = {
1482
+ status,
1483
+ requestId,
1484
+ contentType: response.headers.get("content-type") ?? void 0
1485
+ };
1486
+ return { bytes: new Uint8Array(buffer), meta };
1487
+ });
1488
+ }
1240
1489
  var MANAGER_TOKENS_REFRESH_PATH = "/api/v1/auth/manager-tokens/refresh";
1241
1490
  var AGENCY_ADMIN_TOKENS_REFRESH_PATH = "/api/v1/auth/agency-admin-tokens/refresh";
1242
1491
  function createRotatingSessionRefreshExchange(baseUrl, refreshPath, networkErrorMessage) {
@@ -1304,17 +1553,19 @@ function toFailureOutcome(error) {
1304
1553
  ...error instanceof KaafilRateLimitedError && error.retryAfterSeconds !== void 0 ? { retryAfterSeconds: error.retryAfterSeconds } : {}
1305
1554
  };
1306
1555
  }
1307
- async function execute(ctx, request) {
1556
+ async function runWithLadder(ctx, request, send) {
1308
1557
  const idempotencyKey = OPERATION_ACCEPTS_IDEMPOTENCY_KEY[request.operationId] ? request.idempotencyKey ?? globalThis.crypto.randomUUID() : void 0;
1309
1558
  let lastError;
1310
1559
  let refreshAttempted = false;
1311
1560
  const sendAndClassify = async () => {
1312
1561
  try {
1313
- const { data, meta } = await sendOnce(ctx, request, idempotencyKey);
1314
- return { ok: true, value: attachMeta(data, meta) };
1562
+ return { ok: true, value: await send(idempotencyKey) };
1315
1563
  } catch (error) {
1316
1564
  const typed = toKaafilError(error);
1317
1565
  lastError = typed;
1566
+ if (typed.kind === "transport" && !isRetryable(typed)) {
1567
+ throw typed;
1568
+ }
1318
1569
  return toFailureOutcome(typed);
1319
1570
  }
1320
1571
  };
@@ -1354,159 +1605,2926 @@ async function execute(ctx, request) {
1354
1605
  throw error;
1355
1606
  }
1356
1607
  }
1608
+ function execute(ctx, request) {
1609
+ return runWithLadder(ctx, request, async (idempotencyKey) => {
1610
+ const { data, meta } = await sendOnce(ctx, request, idempotencyKey);
1611
+ return attachMeta(data, meta);
1612
+ });
1613
+ }
1614
+ function executeBinary(ctx, request) {
1615
+ return runWithLadder(
1616
+ ctx,
1617
+ request,
1618
+ (idempotencyKey) => sendOnceBinary(ctx, request, idempotencyKey)
1619
+ );
1620
+ }
1357
1621
 
1358
1622
  // src/idempotency.ts
1359
1623
  function newIdempotencyKey() {
1360
1624
  return globalThis.crypto.randomUUID();
1361
1625
  }
1362
1626
 
1363
- // src/resources/journey.ts
1364
- var DEFAULT_WAIT_UNTIL_READY_TIMEOUT_MS = 6e4;
1365
- var DEFAULT_WAIT_UNTIL_READY_POLL_INTERVAL_MS = 1e3;
1366
- function createJourneyResource(client) {
1367
- const resource = {
1368
- async get(options) {
1369
- const { tripRef, signal } = options;
1627
+ // src/resources/sync.ts
1628
+ var KaafilShareBatchUnauthenticatedError = class _KaafilShareBatchUnauthenticatedError extends KaafilInvalidRequestError {
1629
+ constructor() {
1630
+ super(
1631
+ `The vendored spec declares no security scheme for "syncPushShare", so a batched share push would be sent with no credential at all, carrying a traveller's queued writes. Refused locally. Drain share ops through their own endpoints (shareSaveForm / shareSubmitForm) until the engine declares shareAuth on POST /api/v1/sync/push/share.`
1632
+ );
1633
+ this.name = "KaafilShareBatchUnauthenticatedError";
1634
+ Object.setPrototypeOf(this, _KaafilShareBatchUnauthenticatedError.prototype);
1635
+ }
1636
+ };
1637
+ function isShareBatchPushAvailable() {
1638
+ return OPERATION_SECURITY[OperationId.SyncPushShare].includes(
1639
+ SecuritySchemeId.ShareAuth
1640
+ );
1641
+ }
1642
+ function createSyncResource(client) {
1643
+ return {
1644
+ async push(options) {
1645
+ const { ops, signal } = options;
1646
+ const body = { ops: [...ops] };
1370
1647
  return client.execute({
1371
- method: "GET",
1372
- operationId: OperationId.ReadJourney,
1373
- path: "/api/v1/trips/{ref}/journey",
1374
- pathParams: { ref: tripRef },
1648
+ method: "POST",
1649
+ operationId: OperationId.SyncPush,
1650
+ path: "/api/v1/sync/push",
1651
+ body,
1375
1652
  ...signal !== void 0 ? { signal } : {}
1376
1653
  });
1377
1654
  },
1378
- async capabilities(options) {
1379
- const { tripRef, signal } = options;
1655
+ async pullTrip(options) {
1656
+ const { tripRef, since, signal } = options;
1380
1657
  return client.execute({
1381
1658
  method: "GET",
1382
- operationId: OperationId.ReadJourneyCapabilities,
1383
- path: "/api/v1/trips/{ref}/journey/capabilities",
1659
+ operationId: OperationId.SyncPullTrip,
1660
+ path: "/api/v1/trips/{ref}/sync",
1384
1661
  pathParams: { ref: tripRef },
1662
+ // A `since` of `undefined` is omitted by `RequestDescriptor`'s own
1663
+ // rule, which is exactly the cold-start shape: no `?since=` at all.
1664
+ query: { since },
1385
1665
  ...signal !== void 0 ? { signal } : {}
1386
1666
  });
1387
1667
  },
1388
- async rebuild(options) {
1389
- const { tripRef, idempotencyKey, signal } = options;
1668
+ async pushShare(options) {
1669
+ if (!isShareBatchPushAvailable()) {
1670
+ throw new KaafilShareBatchUnauthenticatedError();
1671
+ }
1672
+ const { ops, signal } = options;
1673
+ const body = { ops: [...ops] };
1390
1674
  return client.execute({
1391
1675
  method: "POST",
1392
- operationId: OperationId.RebuildJourney,
1393
- path: "/api/v1/trips/{ref}/journey/rebuild",
1394
- pathParams: { ref: tripRef },
1395
- ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
1676
+ operationId: OperationId.SyncPushShare,
1677
+ path: "/api/v1/sync/push/share",
1678
+ body,
1396
1679
  ...signal !== void 0 ? { signal } : {}
1397
1680
  });
1681
+ }
1682
+ };
1683
+ }
1684
+
1685
+ // src/http/classify.ts
1686
+ var OUTBOX_CLASS_TO_VERDICT = {
1687
+ TRANSIENT: "transient",
1688
+ CONFLICT: "conflict",
1689
+ FATAL: "fatal"
1690
+ };
1691
+ function classifyFailure(input) {
1692
+ if (input.status === null) {
1693
+ return "transient";
1694
+ }
1695
+ const entry = input.code !== void 0 ? ERROR_CODE_TABLE[input.code] : void 0;
1696
+ if (entry !== void 0) {
1697
+ return OUTBOX_CLASS_TO_VERDICT[entry.outboxClass];
1698
+ }
1699
+ if (input.status === 429 || input.status >= 500 && input.status <= 599 && input.status !== 501) {
1700
+ return "transient";
1701
+ }
1702
+ if (input.status === 409) {
1703
+ return "conflict";
1704
+ }
1705
+ return "fatal";
1706
+ }
1707
+
1708
+ // src/offline/blob.ts
1709
+ var BlobStatus = {
1710
+ Pending: "pending",
1711
+ Confirmed: "confirmed",
1712
+ Parked: "parked"
1713
+ };
1714
+ function createBlobLane(options) {
1715
+ const key = `${options.keyPrefix}:blobs`;
1716
+ const now = options.now ?? Date.now;
1717
+ const random = options.random ?? Math.random;
1718
+ let blobs = /* @__PURE__ */ new Map();
1719
+ const bodyBuilders = /* @__PURE__ */ new Map();
1720
+ let backfills = /* @__PURE__ */ new Map();
1721
+ async function persist() {
1722
+ const shape = {
1723
+ blobs: [...blobs.values()],
1724
+ backfills: Object.fromEntries(backfills)
1725
+ };
1726
+ await options.storage.set(key, JSON.stringify(shape));
1727
+ }
1728
+ async function update(id, patch) {
1729
+ const held = blobs.get(id);
1730
+ if (held === void 0) {
1731
+ return void 0;
1732
+ }
1733
+ const next = { ...held, ...patch };
1734
+ blobs.set(id, next);
1735
+ await persist();
1736
+ return next;
1737
+ }
1738
+ async function park(id, reason) {
1739
+ const record = await update(id, {
1740
+ status: BlobStatus.Parked,
1741
+ parkReason: reason,
1742
+ nextRetryAt: null
1743
+ });
1744
+ if (record !== void 0) {
1745
+ options.onParked?.(record);
1746
+ }
1747
+ }
1748
+ async function retryLater(record) {
1749
+ await update(record.id, {
1750
+ attemptCount: record.attemptCount + 1,
1751
+ nextRetryAt: now() + computeRetryDelayMs(record.attemptCount + 1, { random })
1752
+ });
1753
+ }
1754
+ async function driveOne(record) {
1755
+ const backfill = backfills.get(record.id);
1756
+ const buildBody = bodyBuilders.get(record.id);
1757
+ if (backfill === void 0 || buildBody === void 0) {
1758
+ await park(
1759
+ record.id,
1760
+ "No back-fill builder is registered for this blob in the current process, so the file key could not be written onto the parent entity. Re-register it and re-enqueue."
1761
+ );
1762
+ return "parked";
1763
+ }
1764
+ const bytes = await options.source(record.id);
1765
+ if (bytes === void 0) {
1766
+ await park(
1767
+ record.id,
1768
+ "The bytes for this attachment were not retained across the restart, so it can never be uploaded. The entity it belongs to is unaffected."
1769
+ );
1770
+ return "parked";
1771
+ }
1772
+ let fileId = record.fileId;
1773
+ if (fileId === void 0) {
1774
+ try {
1775
+ const created = await options.uploader.request({
1776
+ contentType: record.contentType,
1777
+ sizeBytes: record.sizeBytes,
1778
+ tripRef: record.tripRef
1779
+ });
1780
+ fileId = created.fileId;
1781
+ await update(record.id, { fileId });
1782
+ const put = await options.uploader.put({
1783
+ uploadUrl: created.uploadUrl,
1784
+ bytes,
1785
+ contentType: record.contentType
1786
+ });
1787
+ if (put.status < 200 || put.status >= 300) {
1788
+ await retryLater({ ...record, fileId });
1789
+ return "pending";
1790
+ }
1791
+ } catch {
1792
+ await retryLater(record);
1793
+ return "pending";
1794
+ }
1795
+ }
1796
+ let confirmStatus;
1797
+ let confirmCode;
1798
+ try {
1799
+ const confirmed = await options.uploader.confirm({ fileId });
1800
+ confirmStatus = confirmed.status;
1801
+ confirmCode = confirmed.code;
1802
+ } catch {
1803
+ await retryLater(record);
1804
+ return "pending";
1805
+ }
1806
+ if (confirmStatus < 200 || confirmStatus >= 300) {
1807
+ const verdict = classifyFailure({
1808
+ status: confirmStatus,
1809
+ ...confirmCode !== void 0 ? { code: confirmCode } : {}
1810
+ });
1811
+ if (verdict === "transient") {
1812
+ await retryLater(record);
1813
+ return "pending";
1814
+ }
1815
+ await park(
1816
+ record.id,
1817
+ `The upload could not be confirmed (${confirmCode ?? confirmStatus}). The entity it belongs to is unaffected.`
1818
+ );
1819
+ return "parked";
1820
+ }
1821
+ await options.outbox.enqueue({
1822
+ tripRef: record.tripRef,
1823
+ method: backfill.method,
1824
+ path: backfill.path,
1825
+ operationId: backfill.operationId,
1826
+ body: buildBody(fileId),
1827
+ ...backfill.entity !== void 0 ? { entity: backfill.entity } : {},
1828
+ ...backfill.ifMatch !== void 0 ? { ifMatch: backfill.ifMatch } : {}
1829
+ });
1830
+ await update(record.id, { status: BlobStatus.Confirmed, nextRetryAt: null });
1831
+ return "confirmed";
1832
+ }
1833
+ return {
1834
+ async load() {
1835
+ blobs = /* @__PURE__ */ new Map();
1836
+ backfills = /* @__PURE__ */ new Map();
1837
+ const raw = await options.storage.get(key);
1838
+ if (raw === void 0) {
1839
+ return;
1840
+ }
1841
+ let parsed;
1842
+ try {
1843
+ parsed = JSON.parse(raw);
1844
+ } catch {
1845
+ return;
1846
+ }
1847
+ for (const record of parsed.blobs ?? []) {
1848
+ blobs.set(record.id, record);
1849
+ }
1850
+ for (const [id, shape] of Object.entries(parsed.backfills ?? {})) {
1851
+ backfills.set(id, shape);
1852
+ }
1398
1853
  },
1399
- async runStep(options) {
1400
- const { tripRef, stepId, idempotencyKey, signal } = options;
1401
- return client.execute({
1402
- method: "POST",
1403
- operationId: OperationId.RunJourneyStep,
1404
- path: "/api/v1/trips/{ref}/journey/steps/{stepId}/run",
1405
- pathParams: { ref: tripRef, stepId },
1406
- ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
1407
- ...signal !== void 0 ? { signal } : {}
1854
+ async enqueue(args) {
1855
+ const record = {
1856
+ id: args.blobId,
1857
+ tripRef: args.tripRef,
1858
+ parentOpId: args.parentOpId,
1859
+ contentType: args.contentType,
1860
+ sizeBytes: args.sizeBytes,
1861
+ status: BlobStatus.Pending,
1862
+ attemptCount: 0,
1863
+ nextRetryAt: null,
1864
+ fileId: void 0,
1865
+ parkReason: void 0
1866
+ };
1867
+ blobs.set(record.id, record);
1868
+ backfills.set(record.id, {
1869
+ method: args.backfill.method,
1870
+ path: args.backfill.path,
1871
+ operationId: args.backfill.operationId,
1872
+ entity: args.backfill.entity,
1873
+ ifMatch: args.backfill.ifMatch
1408
1874
  });
1875
+ bodyBuilders.set(record.id, args.backfill.body);
1876
+ await persist();
1877
+ return record;
1409
1878
  },
1410
- async waitUntilReady(options) {
1411
- const {
1412
- tripRef,
1413
- timeoutMs = DEFAULT_WAIT_UNTIL_READY_TIMEOUT_MS,
1414
- pollIntervalMs = DEFAULT_WAIT_UNTIL_READY_POLL_INTERVAL_MS,
1415
- signal
1416
- } = options;
1417
- const deadlineAt = Date.now() + timeoutMs;
1418
- for (; ; ) {
1419
- try {
1420
- return await resource.get({ tripRef, ...signal !== void 0 ? { signal } : {} });
1421
- } catch (error) {
1422
- if (!(error instanceof KaafilNotFoundError)) {
1423
- throw error;
1424
- }
1425
- const remainingMs = deadlineAt - Date.now();
1426
- if (remainingMs <= 0) {
1427
- throw new KaafilTimeoutError(
1428
- `journey.waitUntilReady timed out after ${String(timeoutMs)}ms waiting for trip "${tripRef}" to become ready. The most likely cause is that the background worker that consumes the build queue is not running against this engine.`,
1429
- { cause: error }
1430
- );
1431
- }
1432
- try {
1433
- await delayWithAbort(Math.min(pollIntervalMs, remainingMs), signal);
1434
- } catch (sleepError) {
1435
- throw new KaafilAbortError("Request aborted", { cause: sleepError });
1436
- }
1879
+ async drain() {
1880
+ let confirmed = 0;
1881
+ let parked = 0;
1882
+ const at = now();
1883
+ for (const record of [...blobs.values()]) {
1884
+ if (record.status !== BlobStatus.Pending) {
1885
+ continue;
1886
+ }
1887
+ if (record.nextRetryAt !== null && record.nextRetryAt > at) {
1888
+ continue;
1889
+ }
1890
+ const outcome = await driveOne(record);
1891
+ if (outcome === "confirmed") {
1892
+ confirmed += 1;
1893
+ } else if (outcome === "parked") {
1894
+ parked += 1;
1895
+ }
1896
+ }
1897
+ let pending = 0;
1898
+ for (const record of blobs.values()) {
1899
+ if (record.status === BlobStatus.Pending) {
1900
+ pending += 1;
1437
1901
  }
1438
1902
  }
1903
+ return { confirmed, parked, pending };
1439
1904
  },
1440
- triggers: {
1441
- async list(options) {
1442
- const { agencyRef, signal } = options;
1443
- return client.execute({
1444
- method: "GET",
1445
- operationId: OperationId.ListJourneyTriggers,
1446
- path: "/api/v1/agencies/{ref}/journey-triggers",
1447
- pathParams: { ref: agencyRef },
1448
- ...signal !== void 0 ? { signal } : {}
1449
- });
1450
- },
1451
- async patch(options) {
1452
- const { agencyRef, key, version, idempotencyKey, signal, ...body } = options;
1453
- return client.execute({
1454
- method: "PATCH",
1455
- operationId: OperationId.PatchJourneyTrigger,
1456
- path: "/api/v1/agencies/{ref}/journey-triggers/{key}",
1457
- pathParams: { ref: agencyRef, key },
1458
- body,
1459
- headers: { "If-Match": String(version) },
1460
- ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
1461
- ...signal !== void 0 ? { signal } : {}
1905
+ all() {
1906
+ return [...blobs.values()];
1907
+ }
1908
+ };
1909
+ }
1910
+
1911
+ // src/offline/outbox.ts
1912
+ var OutboxStatus = {
1913
+ /** Waiting to be sent, or waiting out a backoff rung. */
1914
+ Pending: "pending",
1915
+ /** Handed to the transport; not yet answered. */
1916
+ Inflight: "inflight",
1917
+ /** Terminal failure. Out of the FIFO ordering; surfaced to the user. */
1918
+ Parked: "parked",
1919
+ /** Terminal success. Pruned on the next persist. */
1920
+ Done: "done"
1921
+ };
1922
+ function createOutbox(options) {
1923
+ const key = `${options.keyPrefix}:outbox`;
1924
+ const mintId = options.newId ?? newIdempotencyKey;
1925
+ let ops = /* @__PURE__ */ new Map();
1926
+ let seq = 0;
1927
+ function ordered() {
1928
+ return [...ops.values()].sort((a, b) => a.seq - b.seq);
1929
+ }
1930
+ async function persist() {
1931
+ for (const [id, op] of [...ops]) {
1932
+ if (op.status === OutboxStatus.Done) {
1933
+ ops.delete(id);
1934
+ }
1935
+ }
1936
+ const shape = { seq, ops: ordered() };
1937
+ await options.storage.set(key, JSON.stringify(shape));
1938
+ }
1939
+ async function mutate(opId, patch) {
1940
+ const op = ops.get(opId);
1941
+ if (op === void 0) {
1942
+ return;
1943
+ }
1944
+ ops.set(opId, { ...op, ...patch });
1945
+ await persist();
1946
+ }
1947
+ return {
1948
+ async load() {
1949
+ ops = /* @__PURE__ */ new Map();
1950
+ seq = 0;
1951
+ const raw = await options.storage.get(key);
1952
+ if (raw === void 0) {
1953
+ return;
1954
+ }
1955
+ let parsed;
1956
+ try {
1957
+ parsed = JSON.parse(raw);
1958
+ } catch {
1959
+ return;
1960
+ }
1961
+ seq = typeof parsed.seq === "number" ? parsed.seq : 0;
1962
+ for (const op of parsed.ops ?? []) {
1963
+ ops.set(op.id, {
1964
+ ...op,
1965
+ status: op.status === OutboxStatus.Inflight ? OutboxStatus.Pending : op.status
1462
1966
  });
1463
1967
  }
1968
+ },
1969
+ async enqueue(input) {
1970
+ seq += 1;
1971
+ const op = {
1972
+ id: mintId(),
1973
+ seq,
1974
+ tripRef: input.tripRef,
1975
+ method: input.method,
1976
+ path: input.path,
1977
+ operationId: input.operationId,
1978
+ body: input.body,
1979
+ ifMatch: input.ifMatch,
1980
+ entity: input.entity,
1981
+ idempotencyKey: input.idempotencyKey ?? newIdempotencyKey(),
1982
+ enqueuedAt: input.enqueuedAt,
1983
+ receiptPending: input.receiptPending === true,
1984
+ blobId: input.blobId,
1985
+ status: OutboxStatus.Pending,
1986
+ attemptCount: 0,
1987
+ nextRetryAt: null,
1988
+ refreshAttempted: false,
1989
+ parkReason: void 0
1990
+ };
1991
+ ops.set(op.id, op);
1992
+ await persist();
1993
+ return op;
1994
+ },
1995
+ get(opId) {
1996
+ return ops.get(opId);
1997
+ },
1998
+ all() {
1999
+ return ordered();
2000
+ },
2001
+ lanes() {
2002
+ const seen = /* @__PURE__ */ new Set();
2003
+ for (const op of ops.values()) {
2004
+ if (op.status === OutboxStatus.Pending) {
2005
+ seen.add(op.tripRef);
2006
+ }
2007
+ }
2008
+ return [...seen];
2009
+ },
2010
+ head(tripRef) {
2011
+ return ordered().find((op) => op.tripRef === tripRef && op.status === OutboxStatus.Pending);
2012
+ },
2013
+ readyPrefix(tripRef, at, limit) {
2014
+ const out = [];
2015
+ for (const op of ordered()) {
2016
+ if (op.tripRef !== tripRef || op.status !== OutboxStatus.Pending) {
2017
+ continue;
2018
+ }
2019
+ if (op.nextRetryAt !== null && op.nextRetryAt > at) {
2020
+ break;
2021
+ }
2022
+ out.push(op);
2023
+ if (out.length >= limit) {
2024
+ break;
2025
+ }
2026
+ }
2027
+ return out;
2028
+ },
2029
+ async markInflight(opId) {
2030
+ await mutate(opId, { status: OutboxStatus.Inflight });
2031
+ },
2032
+ async markDone(opId) {
2033
+ await mutate(opId, { status: OutboxStatus.Done });
2034
+ },
2035
+ async park(opId, reason) {
2036
+ const op = ops.get(opId);
2037
+ await mutate(opId, {
2038
+ status: OutboxStatus.Parked,
2039
+ parkReason: reason,
2040
+ attemptCount: (op?.attemptCount ?? 0) + 1,
2041
+ nextRetryAt: null
2042
+ });
2043
+ },
2044
+ async scheduleRetry(opId, nextRetryAt) {
2045
+ const op = ops.get(opId);
2046
+ await mutate(opId, {
2047
+ status: OutboxStatus.Pending,
2048
+ attemptCount: (op?.attemptCount ?? 0) + 1,
2049
+ nextRetryAt
2050
+ });
2051
+ },
2052
+ async requeue(opId) {
2053
+ await mutate(opId, { status: OutboxStatus.Pending });
2054
+ },
2055
+ async markRefreshAttempted(opId) {
2056
+ await mutate(opId, { refreshAttempted: true });
2057
+ },
2058
+ async reissue(opId, patch) {
2059
+ const op = ops.get(opId);
2060
+ if (op === void 0) {
2061
+ return;
2062
+ }
2063
+ ops.set(opId, {
2064
+ ...op,
2065
+ status: OutboxStatus.Pending,
2066
+ nextRetryAt: null,
2067
+ attemptCount: op.attemptCount + 1,
2068
+ ...patch.body !== void 0 ? { body: patch.body } : {},
2069
+ ...patch.ifMatch !== void 0 ? { ifMatch: patch.ifMatch } : {}
2070
+ });
2071
+ await persist();
2072
+ },
2073
+ async drop(opId) {
2074
+ if (!ops.delete(opId)) {
2075
+ return;
2076
+ }
2077
+ await persist();
2078
+ },
2079
+ counts() {
2080
+ let pending = 0;
2081
+ let inflight = 0;
2082
+ let parked = 0;
2083
+ for (const op of ops.values()) {
2084
+ if (op.status === OutboxStatus.Pending) {
2085
+ pending += 1;
2086
+ } else if (op.status === OutboxStatus.Inflight) {
2087
+ inflight += 1;
2088
+ } else if (op.status === OutboxStatus.Parked) {
2089
+ parked += 1;
2090
+ }
2091
+ }
2092
+ return { pending, inflight, parked };
1464
2093
  }
1465
2094
  };
1466
- return resource;
1467
2095
  }
1468
2096
 
1469
- // src/resources/vendors.ts
1470
- function createVendorsResource(client) {
1471
- return {
1472
- async list(options) {
1473
- const { tripRef, signal } = options;
1474
- return client.execute({
1475
- method: "GET",
1476
- operationId: OperationId.ListTripVendors,
1477
- path: "/api/v1/trips/{ref}/vendors",
1478
- pathParams: { ref: tripRef },
1479
- ...signal !== void 0 ? { signal } : {}
2097
+ // src/offline/reconcile.ts
2098
+ function readCurrentVersion(details) {
2099
+ const value = details?.currentVersion;
2100
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
2101
+ }
2102
+ async function reconcileConflict(args) {
2103
+ const { op, transport, snapshot, resolver } = args;
2104
+ const currentVersion = readCurrentVersion(args.details);
2105
+ let current;
2106
+ if (op.entity !== void 0 && transport.readEntity !== void 0) {
2107
+ let read;
2108
+ try {
2109
+ read = await transport.readEntity({
2110
+ tripRef: op.tripRef,
2111
+ listName: op.entity.listName,
2112
+ id: op.entity.id
2113
+ });
2114
+ } catch {
2115
+ return { action: "deferred", body: void 0, currentVersion, current: void 0 };
2116
+ }
2117
+ if (read.status === 200 && read.entity !== void 0) {
2118
+ current = read.entity;
2119
+ await snapshot.upsert({
2120
+ tripRef: op.tripRef,
2121
+ listName: op.entity.listName,
2122
+ row: read.entity
1480
2123
  });
1481
2124
  }
2125
+ }
2126
+ const context = { op, currentVersion, current };
2127
+ const resolution = resolver === void 0 ? { action: "surface" } : await resolver(context);
2128
+ return {
2129
+ action: resolution.action,
2130
+ body: resolution.action === "reissue" ? resolution.body : void 0,
2131
+ currentVersion,
2132
+ current
1482
2133
  };
1483
2134
  }
1484
2135
 
1485
- // src/generated/enums.ts
1486
- var BookingStatus = {
1487
- Confirmed: "CONFIRMED",
1488
- Tentative: "TENTATIVE",
1489
- Cancelled: "CANCELLED"
1490
- };
1491
- var ClaimStatusIngest = {
1492
- Approved: "APPROVED",
1493
- Paid: "PAID",
1494
- Rejected: "REJECTED"
1495
- };
1496
- var EventType = {
1497
- Trip: "TRIP",
1498
- Trek: "TREK"
1499
- };
1500
- var Gender = {
1501
- Male: "MALE",
1502
- Female: "FEMALE",
1503
- Other: "OTHER",
1504
- Unknown: "UNKNOWN"
1505
- };
1506
- var ManagerRole = {
1507
- Manager: "MANAGER",
1508
- Coordinator: "COORDINATOR"
1509
- };
2136
+ // src/offline/transport.ts
2137
+ var BATCH_THRESHOLD_OPS = 5;
2138
+ var MAX_BATCH_OPS = 200;
2139
+ var CONSOLIDATED_PULL_THRESHOLD_LISTS = 3;
2140
+ function shouldUseBatchTransport(args) {
2141
+ return args.transport.sendBatch !== void 0 && args.readyCount >= BATCH_THRESHOLD_OPS;
2142
+ }
2143
+
2144
+ // src/offline/drainer.ts
2145
+ function userMessageFor(outcome) {
2146
+ if (outcome.code === "LOCKED" || outcome.status === 423) {
2147
+ return "This trip has been closed out, so this change was not saved.";
2148
+ }
2149
+ if (outcome.code === "FILE_PURGED" || outcome.status === 410) {
2150
+ return "That file is no longer available \u2014 its retention period has ended.";
2151
+ }
2152
+ if (outcome.code === "PLAN_FEATURE_DISABLED" || outcome.status === 402) {
2153
+ return "That feature is not included in this plan, so this change was not saved.";
2154
+ }
2155
+ if (outcome.code === "SHARE_WRITE_GRACE_EXPIRED") {
2156
+ return "This link expired \u2014 your submission was not delivered.";
2157
+ }
2158
+ if (outcome.status === 404) {
2159
+ return "That item is no longer available to you.";
2160
+ }
2161
+ if (outcome.status === 401) {
2162
+ return "Your session expired, so this change was not saved. Sign in again.";
2163
+ }
2164
+ return "This change could not be saved.";
2165
+ }
2166
+ function createDrainer(options) {
2167
+ const { outbox, snapshot, transport, events } = options;
2168
+ const now = options.now ?? Date.now;
2169
+ const random = options.random ?? Math.random;
2170
+ let inFlight = null;
2171
+ function observeServerTime(outcome) {
2172
+ if (outcome.serverTime !== void 0) {
2173
+ options.onServerTime?.(outcome.serverTime);
2174
+ }
2175
+ }
2176
+ async function applySuccess(op, outcome, state) {
2177
+ if (op.entity !== void 0 && outcome.entity !== void 0) {
2178
+ await snapshot.upsert({
2179
+ tripRef: op.tripRef,
2180
+ listName: op.entity.listName,
2181
+ row: outcome.entity,
2182
+ ...outcome.serverTime !== void 0 ? { syncedAt: outcome.serverTime } : {}
2183
+ });
2184
+ }
2185
+ await outbox.markDone(op.id);
2186
+ state.applied += 1;
2187
+ }
2188
+ async function park(op, outcome, state) {
2189
+ const message = userMessageFor(outcome);
2190
+ await outbox.park(op.id, {
2191
+ status: outcome.status,
2192
+ code: outcome.code,
2193
+ userMessage: message
2194
+ });
2195
+ state.parked += 1;
2196
+ events.emit("sync.error", {
2197
+ opId: op.id,
2198
+ tripRef: op.tripRef,
2199
+ error: outcome.error,
2200
+ status: outcome.status,
2201
+ parked: true,
2202
+ userMessage: message
2203
+ });
2204
+ }
2205
+ async function purgeIfCached(op, outcome) {
2206
+ if (op.entity === void 0) {
2207
+ return;
2208
+ }
2209
+ const held = snapshot.list(op.tripRef, op.entity.listName).some((row) => row.id === op.entity?.id);
2210
+ if (!held) {
2211
+ return;
2212
+ }
2213
+ if (outcome.status === 404 || outcome.status === 410) {
2214
+ await snapshot.purgeEntity(op.tripRef, op.entity.listName, op.entity.id);
2215
+ }
2216
+ }
2217
+ async function applyOutcome(op, outcome, state) {
2218
+ observeServerTime(outcome);
2219
+ if (outcome.status !== null && outcome.status >= 200 && outcome.status < 300) {
2220
+ await applySuccess(op, outcome, state);
2221
+ return "terminal";
2222
+ }
2223
+ if (outcome.status === 401 && !op.refreshAttempted) {
2224
+ await outbox.markRefreshAttempted(op.id);
2225
+ let refreshed = false;
2226
+ try {
2227
+ refreshed = await transport.refreshSession?.() === true;
2228
+ } catch {
2229
+ refreshed = false;
2230
+ }
2231
+ if (refreshed) {
2232
+ await outbox.requeue(op.id);
2233
+ return "pending";
2234
+ }
2235
+ events.emit("session.expired", { reason: "refresh-failed" });
2236
+ await park(op, outcome, state);
2237
+ return "terminal";
2238
+ }
2239
+ const verdict = classifyFailure({
2240
+ status: outcome.status,
2241
+ ...outcome.code !== void 0 ? { code: outcome.code } : {},
2242
+ ...outcome.transportFailureKind !== void 0 ? { transportFailureKind: outcome.transportFailureKind } : {}
2243
+ });
2244
+ if (verdict === "transient") {
2245
+ const delay = computeRetryDelayMs(op.attemptCount + 1, {
2246
+ ...outcome.retryAfterSeconds !== void 0 ? { retryAfterSeconds: outcome.retryAfterSeconds } : {},
2247
+ random
2248
+ });
2249
+ await outbox.scheduleRetry(op.id, now() + delay);
2250
+ events.emit("sync.error", {
2251
+ opId: op.id,
2252
+ tripRef: op.tripRef,
2253
+ error: outcome.error,
2254
+ status: outcome.status,
2255
+ parked: false
2256
+ });
2257
+ return "pending";
2258
+ }
2259
+ if (verdict === "conflict") {
2260
+ state.conflicted += 1;
2261
+ const result = await reconcileConflict({
2262
+ op,
2263
+ details: outcome.details,
2264
+ transport,
2265
+ snapshot,
2266
+ resolver: options.conflictResolver
2267
+ });
2268
+ switch (result.action) {
2269
+ case "drop":
2270
+ await outbox.drop(op.id);
2271
+ return "terminal";
2272
+ case "reissue":
2273
+ await outbox.reissue(op.id, {
2274
+ ...result.body !== void 0 ? { body: result.body } : {},
2275
+ ...result.currentVersion !== void 0 ? { ifMatch: result.currentVersion } : {}
2276
+ });
2277
+ return "pending";
2278
+ case "deferred":
2279
+ await outbox.requeue(op.id);
2280
+ return "pending";
2281
+ case "surface":
2282
+ await park(op, outcome, state);
2283
+ return "terminal";
2284
+ }
2285
+ }
2286
+ await purgeIfCached(op, outcome);
2287
+ await park(op, outcome, state);
2288
+ return "terminal";
2289
+ }
2290
+ async function drainLane(tripRef, state, signal) {
2291
+ for (; ; ) {
2292
+ if (signal?.aborted === true) {
2293
+ return;
2294
+ }
2295
+ const head = outbox.head(tripRef);
2296
+ if (head === void 0) {
2297
+ return;
2298
+ }
2299
+ if (head.nextRetryAt !== null && head.nextRetryAt > now()) {
2300
+ return;
2301
+ }
2302
+ const ready = outbox.readyPrefix(tripRef, now(), MAX_BATCH_OPS);
2303
+ if (ready.length === 0) {
2304
+ return;
2305
+ }
2306
+ if (shouldUseBatchTransport({ transport, readyCount: ready.length })) {
2307
+ state.usedBatch = true;
2308
+ const sent = await sendBatchedPrefix(ready, state, signal);
2309
+ if (!sent) {
2310
+ return;
2311
+ }
2312
+ continue;
2313
+ }
2314
+ await outbox.markInflight(head.id);
2315
+ let outcome;
2316
+ try {
2317
+ outcome = await transport.sendOne(head, signal);
2318
+ } catch (error) {
2319
+ outcome = {
2320
+ status: null,
2321
+ transportFailureKind: "network",
2322
+ ...isKaafilLike(error) ? { error } : {}
2323
+ };
2324
+ }
2325
+ const disposition = await applyOutcome(head, outcome, state);
2326
+ if (disposition === "pending") {
2327
+ const again = outbox.get(head.id);
2328
+ if (again !== void 0 && again.nextRetryAt !== null && again.nextRetryAt > now()) {
2329
+ return;
2330
+ }
2331
+ }
2332
+ }
2333
+ }
2334
+ async function sendBatchedPrefix(ready, state, signal) {
2335
+ const sendBatch = transport.sendBatch;
2336
+ if (sendBatch === void 0) {
2337
+ return false;
2338
+ }
2339
+ for (const op of ready) {
2340
+ await outbox.markInflight(op.id);
2341
+ }
2342
+ let outcomes;
2343
+ try {
2344
+ outcomes = await sendBatch(ready, signal);
2345
+ } catch {
2346
+ const [head, ...rest] = ready;
2347
+ if (head !== void 0) {
2348
+ await outbox.scheduleRetry(
2349
+ head.id,
2350
+ now() + computeRetryDelayMs(head.attemptCount + 1, { random })
2351
+ );
2352
+ }
2353
+ for (const op of rest) {
2354
+ await outbox.requeue(op.id);
2355
+ }
2356
+ return false;
2357
+ }
2358
+ let halted = false;
2359
+ for (let index = 0; index < ready.length; index += 1) {
2360
+ const op = ready[index];
2361
+ if (op === void 0) {
2362
+ continue;
2363
+ }
2364
+ if (halted) {
2365
+ await outbox.requeue(op.id);
2366
+ continue;
2367
+ }
2368
+ const outcome = outcomes[index];
2369
+ if (outcome === void 0) {
2370
+ await outbox.requeue(op.id);
2371
+ halted = true;
2372
+ continue;
2373
+ }
2374
+ const disposition = await applyOutcome(op, outcome, state);
2375
+ if (disposition === "pending") {
2376
+ halted = true;
2377
+ }
2378
+ }
2379
+ return !halted;
2380
+ }
2381
+ async function runPass(signal) {
2382
+ const state = { applied: 0, parked: 0, conflicted: 0, usedBatch: false };
2383
+ const lanes = outbox.lanes();
2384
+ await Promise.all(lanes.map((tripRef) => drainLane(tripRef, state, signal)));
2385
+ const report = {
2386
+ applied: state.applied,
2387
+ parked: state.parked,
2388
+ conflicted: state.conflicted,
2389
+ remaining: outbox.counts().pending,
2390
+ usedBatchTransport: state.usedBatch,
2391
+ lanes
2392
+ };
2393
+ events.emit("sync.drained", {
2394
+ applied: report.applied,
2395
+ parked: report.parked,
2396
+ conflicted: report.conflicted,
2397
+ remaining: report.remaining,
2398
+ usedBatchTransport: report.usedBatchTransport
2399
+ });
2400
+ return report;
2401
+ }
2402
+ const drainer = {
2403
+ async drain(drainOptions = {}) {
2404
+ if (inFlight !== null) {
2405
+ return inFlight;
2406
+ }
2407
+ const pass = runPass(drainOptions.signal).finally(() => {
2408
+ inFlight = null;
2409
+ });
2410
+ inFlight = pass;
2411
+ return pass;
2412
+ },
2413
+ kick() {
2414
+ void drainer.drain().catch(() => {
2415
+ });
2416
+ },
2417
+ bindOpportunisticTriggers() {
2418
+ const target = typeof globalThis.addEventListener === "function" ? globalThis : void 0;
2419
+ if (target === void 0) {
2420
+ return () => {
2421
+ };
2422
+ }
2423
+ const onOnline = () => {
2424
+ drainer.kick();
2425
+ };
2426
+ const onVisible = () => {
2427
+ const state = globalThis.document?.visibilityState;
2428
+ if (state === void 0 || state === "visible") {
2429
+ drainer.kick();
2430
+ }
2431
+ };
2432
+ target.addEventListener("online", onOnline);
2433
+ target.addEventListener("visibilitychange", onVisible);
2434
+ target.addEventListener("focus", onVisible);
2435
+ return () => {
2436
+ target.removeEventListener("online", onOnline);
2437
+ target.removeEventListener("visibilitychange", onVisible);
2438
+ target.removeEventListener("focus", onVisible);
2439
+ };
2440
+ }
2441
+ };
2442
+ return drainer;
2443
+ }
2444
+ function isKaafilLike(error) {
2445
+ return typeof error === "object" && error !== null && "kind" in error && error instanceof Error;
2446
+ }
2447
+
2448
+ // src/offline/events.ts
2449
+ function createOfflineEvents(options = {}) {
2450
+ const handlers = /* @__PURE__ */ new Map();
2451
+ return {
2452
+ on(name, handler) {
2453
+ let set = handlers.get(name);
2454
+ if (set === void 0) {
2455
+ set = /* @__PURE__ */ new Set();
2456
+ handlers.set(name, set);
2457
+ }
2458
+ set.add(handler);
2459
+ let removed = false;
2460
+ return () => {
2461
+ if (removed) {
2462
+ return;
2463
+ }
2464
+ removed = true;
2465
+ set?.delete(handler);
2466
+ };
2467
+ },
2468
+ emit(name, event) {
2469
+ const set = handlers.get(name);
2470
+ if (set === void 0) {
2471
+ return;
2472
+ }
2473
+ for (const handler of [...set]) {
2474
+ try {
2475
+ handler(event);
2476
+ } catch (error) {
2477
+ options.onHandlerError?.(error, name);
2478
+ }
2479
+ }
2480
+ },
2481
+ clear() {
2482
+ handlers.clear();
2483
+ }
2484
+ };
2485
+ }
2486
+
2487
+ // src/offline/pull.ts
2488
+ var SYNC_PULL_SECTIONS = [
2489
+ "rooming",
2490
+ "stayWindows",
2491
+ "pickups",
2492
+ "seating",
2493
+ "bookings",
2494
+ "expenses",
2495
+ "checklist",
2496
+ "float",
2497
+ "collections",
2498
+ "itinerary",
2499
+ "closeout"
2500
+ ];
2501
+ function extractSectionRows(data) {
2502
+ if (Array.isArray(data)) {
2503
+ return isRowArray(data) ? data : void 0;
2504
+ }
2505
+ if (typeof data !== "object" || data === null) {
2506
+ return void 0;
2507
+ }
2508
+ let found;
2509
+ for (const value of Object.values(data)) {
2510
+ if (!Array.isArray(value) || !isRowArray(value)) {
2511
+ continue;
2512
+ }
2513
+ if (found !== void 0) {
2514
+ return void 0;
2515
+ }
2516
+ found = value;
2517
+ }
2518
+ return found;
2519
+ }
2520
+ function isRowArray(value) {
2521
+ return value.every(
2522
+ (item) => typeof item === "object" && item !== null && typeof item.id === "string"
2523
+ );
2524
+ }
2525
+ function createPullCoordinator(options) {
2526
+ const { snapshot, transport, events } = options;
2527
+ function sinceFor(tripRef) {
2528
+ const known = snapshot.listNames(tripRef).filter(
2529
+ (name) => SYNC_PULL_SECTIONS.includes(name)
2530
+ );
2531
+ if (known.length === 0) {
2532
+ return void 0;
2533
+ }
2534
+ let min;
2535
+ for (const name of known) {
2536
+ const cursor = snapshot.cursor(tripRef, name);
2537
+ if (cursor === void 0) {
2538
+ return void 0;
2539
+ }
2540
+ if (min === void 0 || cursor < min) {
2541
+ min = cursor;
2542
+ }
2543
+ }
2544
+ return min;
2545
+ }
2546
+ async function applyOnce(tripRef, since, signal) {
2547
+ const pullTripFn = transport.pullTrip;
2548
+ if (pullTripFn === void 0) {
2549
+ throw new TypeError(
2550
+ "This offline engine was built without a consolidated-pull transport, so pullTrip() has nothing to call. Supply OfflineTransport.pullTrip."
2551
+ );
2552
+ }
2553
+ const response = await pullTripFn({
2554
+ tripRef,
2555
+ since,
2556
+ ...signal !== void 0 ? { signal } : {}
2557
+ });
2558
+ const serverTime = response.serverTime;
2559
+ options.onServerTime?.(serverTime);
2560
+ const present = [];
2561
+ const absent = [];
2562
+ const unmapped = [];
2563
+ const changed = [];
2564
+ let coldRepullNeeded = false;
2565
+ for (const name of SYNC_PULL_SECTIONS) {
2566
+ const section = response.sections[name];
2567
+ if (section === void 0) {
2568
+ absent.push(name);
2569
+ continue;
2570
+ }
2571
+ const rows = extractSectionRows(section.data);
2572
+ if (rows === void 0) {
2573
+ unmapped.push(name);
2574
+ continue;
2575
+ }
2576
+ present.push(name);
2577
+ const hadCursor = snapshot.cursor(tripRef, name) !== void 0;
2578
+ if (!hadCursor && since !== void 0) {
2579
+ coldRepullNeeded = true;
2580
+ }
2581
+ const applied = await snapshot.applyPull({ tripRef, listName: name, rows, serverTime });
2582
+ if (applied.changed) {
2583
+ changed.push(name);
2584
+ }
2585
+ }
2586
+ if (changed.length > 0) {
2587
+ events.emit("snapshot.updated", { tripRef, lists: changed, serverTime });
2588
+ }
2589
+ return {
2590
+ result: { tripRef, serverTime, present, absent, unmapped, changed, coldRepulled: false },
2591
+ coldRepullNeeded
2592
+ };
2593
+ }
2594
+ return {
2595
+ sinceFor,
2596
+ async pullTrip({ tripRef, signal, cold }) {
2597
+ const since = cold === true ? void 0 : sinceFor(tripRef);
2598
+ const first = await applyOnce(tripRef, since, signal);
2599
+ if (!first.coldRepullNeeded) {
2600
+ return first.result;
2601
+ }
2602
+ const second = await applyOnce(tripRef, void 0, signal);
2603
+ return { ...second.result, coldRepulled: true };
2604
+ }
2605
+ };
2606
+ }
2607
+
2608
+ // src/offline/share.ts
2609
+ var SHARE_WRITE_GRACE_MS = 7 * 24 * 60 * 60 * 1e3;
2610
+ var KaafilShareLinkExpiredError = class _KaafilShareLinkExpiredError extends Error {
2611
+ constructor() {
2612
+ super("This link has expired, so it can no longer be used to view or submit anything.");
2613
+ this.name = "KaafilShareLinkExpiredError";
2614
+ Object.setPrototypeOf(this, _KaafilShareLinkExpiredError.prototype);
2615
+ }
2616
+ };
2617
+ function defaultMonotonicClock() {
2618
+ const performanceNow = globalThis.performance?.now;
2619
+ if (typeof performanceNow === "function") {
2620
+ return () => performanceNow.call(globalThis.performance);
2621
+ }
2622
+ let ticks = 0;
2623
+ return () => {
2624
+ ticks += 1;
2625
+ return ticks;
2626
+ };
2627
+ }
2628
+ function createShareGuard(options) {
2629
+ const monotonic = options.monotonic ?? defaultMonotonicClock();
2630
+ const expiresAtMs = Date.parse(options.expiresAt);
2631
+ let anchor;
2632
+ function estimateNow() {
2633
+ if (anchor === void 0) {
2634
+ return void 0;
2635
+ }
2636
+ return anchor.serverMs + Math.max(0, monotonic() - anchor.monotonicMs);
2637
+ }
2638
+ const guard = {
2639
+ observeServerTime(serverTime) {
2640
+ const parsed = Date.parse(serverTime);
2641
+ if (Number.isNaN(parsed)) {
2642
+ return;
2643
+ }
2644
+ if (anchor !== void 0 && parsed <= anchor.serverMs) {
2645
+ return;
2646
+ }
2647
+ anchor = { serverMs: parsed, monotonicMs: monotonic() };
2648
+ },
2649
+ now() {
2650
+ return estimateNow();
2651
+ },
2652
+ isExpired() {
2653
+ const at = estimateNow();
2654
+ if (at === void 0 || Number.isNaN(expiresAtMs)) {
2655
+ return false;
2656
+ }
2657
+ return at >= expiresAtMs;
2658
+ },
2659
+ isGraceClosed() {
2660
+ const at = estimateNow();
2661
+ if (at === void 0 || Number.isNaN(expiresAtMs)) {
2662
+ return false;
2663
+ }
2664
+ return at >= expiresAtMs + SHARE_WRITE_GRACE_MS;
2665
+ },
2666
+ assertWritable() {
2667
+ if (guard.isExpired()) {
2668
+ throw new KaafilShareLinkExpiredError();
2669
+ }
2670
+ },
2671
+ async invalidate(reason, code) {
2672
+ await options.snapshot.purgeTrip(options.tripRef);
2673
+ const preserved = options.outbox.counts().pending;
2674
+ const payload = {
2675
+ code: code === KaafilErrorCode.ShareTokenExpired || code === KaafilErrorCode.ShareTokenRevoked ? code : void 0,
2676
+ snapshotPurged: true,
2677
+ pendingOpsPreserved: preserved
2678
+ };
2679
+ options.events.emit(reason === "expired" ? "share.expired" : "share.revoked", payload);
2680
+ },
2681
+ async applyPreflight(result) {
2682
+ if (result.code === KaafilErrorCode.ShareTokenRevoked) {
2683
+ await guard.invalidate("revoked", result.code);
2684
+ return "revoked";
2685
+ }
2686
+ if (result.code === KaafilErrorCode.ShareTokenExpired) {
2687
+ await guard.invalidate("expired", result.code);
2688
+ return "expired";
2689
+ }
2690
+ return "valid";
2691
+ },
2692
+ async parkOpsPastGrace() {
2693
+ if (!guard.isGraceClosed()) {
2694
+ return 0;
2695
+ }
2696
+ let parked = 0;
2697
+ for (const op of options.outbox.all()) {
2698
+ if (op.status !== "pending") {
2699
+ continue;
2700
+ }
2701
+ await options.outbox.park(op.id, {
2702
+ status: null,
2703
+ code: KaafilErrorCode.ShareWriteGraceExpired,
2704
+ userMessage: "This link expired \u2014 your submission was not delivered."
2705
+ });
2706
+ parked += 1;
2707
+ options.events.emit("sync.error", {
2708
+ opId: op.id,
2709
+ tripRef: op.tripRef,
2710
+ error: void 0,
2711
+ status: null,
2712
+ parked: true,
2713
+ userMessage: "This link expired \u2014 your submission was not delivered."
2714
+ });
2715
+ }
2716
+ return parked;
2717
+ }
2718
+ };
2719
+ return guard;
2720
+ }
2721
+
2722
+ // src/datetime.ts
2723
+ var FULL_DATETIME_WITH_OFFSET = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;
2724
+ var DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
2725
+ function invalidRequest(fieldPath, message) {
2726
+ return new KaafilInvalidRequestError(`${fieldPath}: ${message}`);
2727
+ }
2728
+ function normalizeDateTimeInput(value, fieldPath) {
2729
+ if (value instanceof Date) {
2730
+ if (Number.isNaN(value.getTime())) {
2731
+ throw invalidRequest(fieldPath, "received an invalid Date (getTime() is NaN).");
2732
+ }
2733
+ return value.toISOString();
2734
+ }
2735
+ if (typeof value === "number") {
2736
+ if (!Number.isFinite(value)) {
2737
+ throw invalidRequest(
2738
+ fieldPath,
2739
+ `received a non-finite number (${String(value)}); expected epoch milliseconds.`
2740
+ );
2741
+ }
2742
+ return new Date(value).toISOString();
2743
+ }
2744
+ if (FULL_DATETIME_WITH_OFFSET.test(value)) {
2745
+ return value;
2746
+ }
2747
+ if (DATE_ONLY.test(value)) {
2748
+ throw invalidRequest(
2749
+ fieldPath,
2750
+ `received a date-only string ("${value}"). This API requires a full ISO-8601 datetime WITH an offset, and the SDK will not guess which timezone you meant (midnight UTC is rarely midnight where the trip actually starts). Pass a \`Date\` instead \u2014 e.g. \`new Date("2026-08-20T09:00:00+05:30")\` \u2014 or add an explicit offset yourself, e.g. "2026-08-20T00:00:00+05:30".`
2751
+ );
2752
+ }
2753
+ throw invalidRequest(
2754
+ fieldPath,
2755
+ `received "${value}", which is not a full ISO-8601 datetime with an offset. Pass a \`Date\`, an epoch-milliseconds number, or a string like "2026-08-20T09:00:00+05:30".`
2756
+ );
2757
+ }
2758
+ function normalizeNullableDateTimeInput(value, fieldPath) {
2759
+ return value === null ? null : normalizeDateTimeInput(value, fieldPath);
2760
+ }
2761
+
2762
+ // src/delta/cursor.ts
2763
+ function isTombstone(row) {
2764
+ return row._tombstone === true;
2765
+ }
2766
+ function mergeDeltaRows(store, rows) {
2767
+ let added = 0;
2768
+ let updated = 0;
2769
+ let removed = 0;
2770
+ let unchanged = 0;
2771
+ for (const row of rows) {
2772
+ const held = store.get(row.id);
2773
+ if (isTombstone(row)) {
2774
+ if (held === void 0 || held.version > row.version) {
2775
+ unchanged += 1;
2776
+ continue;
2777
+ }
2778
+ store.delete(row.id);
2779
+ removed += 1;
2780
+ continue;
2781
+ }
2782
+ if (held === void 0) {
2783
+ store.set(row.id, row);
2784
+ added += 1;
2785
+ continue;
2786
+ }
2787
+ if (held.version >= row.version) {
2788
+ unchanged += 1;
2789
+ continue;
2790
+ }
2791
+ store.set(row.id, row);
2792
+ updated += 1;
2793
+ }
2794
+ return { added, updated, removed, unchanged };
2795
+ }
2796
+ var KaafilDeltaCursorInFlightError = class _KaafilDeltaCursorInFlightError extends Error {
2797
+ constructor() {
2798
+ super(
2799
+ "pull() was called while a previous pull on this delta cursor was still in flight. Two concurrent pulls would settle in an unknown order and leave the cursor at whichever response landed last, not the newest \u2014 await the first one's result."
2800
+ );
2801
+ this.name = "KaafilDeltaCursorInFlightError";
2802
+ Object.setPrototypeOf(this, _KaafilDeltaCursorInFlightError.prototype);
2803
+ }
2804
+ };
2805
+ function createDeltaCursor(config) {
2806
+ const { fetchDelta } = config;
2807
+ const state = {
2808
+ cursor: void 0,
2809
+ isLoading: false
2810
+ };
2811
+ function restore(cursor) {
2812
+ state.cursor = normalizeDateTimeInput(cursor, "cursor");
2813
+ }
2814
+ if (config.cursor !== void 0) {
2815
+ restore(config.cursor);
2816
+ }
2817
+ async function pull(options = {}) {
2818
+ if (state.isLoading) {
2819
+ throw new KaafilDeltaCursorInFlightError();
2820
+ }
2821
+ const previousCursor = state.cursor;
2822
+ state.isLoading = true;
2823
+ try {
2824
+ const response = await fetchDelta({ since: previousCursor, signal: options.signal });
2825
+ state.cursor = response.meta.serverTime;
2826
+ return {
2827
+ data: response,
2828
+ meta: response.meta,
2829
+ cursor: response.meta.serverTime,
2830
+ previousCursor
2831
+ };
2832
+ } finally {
2833
+ state.isLoading = false;
2834
+ }
2835
+ }
2836
+ return {
2837
+ get cursor() {
2838
+ return state.cursor;
2839
+ },
2840
+ get isLoading() {
2841
+ return state.isLoading;
2842
+ },
2843
+ get hasSynced() {
2844
+ return state.cursor !== void 0;
2845
+ },
2846
+ pull,
2847
+ restore,
2848
+ reset() {
2849
+ state.cursor = void 0;
2850
+ }
2851
+ };
2852
+ }
2853
+
2854
+ // src/offline/snapshot.ts
2855
+ var EMPTY_LIST = { cursor: void 0, rows: {}, syncedAt: {} };
2856
+ function createSnapshotStore(options) {
2857
+ const key = `${options.keyPrefix}:snapshot`;
2858
+ let trips = /* @__PURE__ */ new Map();
2859
+ async function persist() {
2860
+ const shape = { trips: {} };
2861
+ for (const [tripRef, lists] of trips) {
2862
+ const out = {};
2863
+ for (const [listName, value] of lists) {
2864
+ out[listName] = value;
2865
+ }
2866
+ shape.trips[tripRef] = out;
2867
+ }
2868
+ await options.storage.set(key, JSON.stringify(shape));
2869
+ }
2870
+ function getList(tripRef, listName) {
2871
+ return trips.get(tripRef)?.get(listName) ?? EMPTY_LIST;
2872
+ }
2873
+ function setList(tripRef, listName, value) {
2874
+ let lists = trips.get(tripRef);
2875
+ if (lists === void 0) {
2876
+ lists = /* @__PURE__ */ new Map();
2877
+ trips.set(tripRef, lists);
2878
+ }
2879
+ lists.set(listName, value);
2880
+ }
2881
+ return {
2882
+ async load() {
2883
+ const raw = await options.storage.get(key);
2884
+ trips = /* @__PURE__ */ new Map();
2885
+ if (raw === void 0) {
2886
+ return;
2887
+ }
2888
+ let parsed;
2889
+ try {
2890
+ parsed = JSON.parse(raw);
2891
+ } catch {
2892
+ return;
2893
+ }
2894
+ for (const [tripRef, lists] of Object.entries(parsed.trips ?? {})) {
2895
+ for (const [listName, value] of Object.entries(lists)) {
2896
+ setList(tripRef, listName, {
2897
+ cursor: value.cursor,
2898
+ rows: value.rows ?? {},
2899
+ syncedAt: value.syncedAt ?? {}
2900
+ });
2901
+ }
2902
+ }
2903
+ },
2904
+ list(tripRef, listName) {
2905
+ return Object.values(getList(tripRef, listName).rows);
2906
+ },
2907
+ cursor(tripRef, listName) {
2908
+ return getList(tripRef, listName).cursor;
2909
+ },
2910
+ syncedAt(tripRef, listName, id) {
2911
+ return getList(tripRef, listName).syncedAt[id];
2912
+ },
2913
+ listNames(tripRef) {
2914
+ return [...trips.get(tripRef)?.keys() ?? []];
2915
+ },
2916
+ async applyPull({ tripRef, listName, rows, serverTime }) {
2917
+ const current = getList(tripRef, listName);
2918
+ const merged = new Map(Object.entries(current.rows));
2919
+ const stats = mergeDeltaRows(merged, rows);
2920
+ const syncedAt = {};
2921
+ for (const id of merged.keys()) {
2922
+ syncedAt[id] = current.rows[id] === merged.get(id) ? current.syncedAt[id] ?? serverTime : serverTime;
2923
+ }
2924
+ setList(tripRef, listName, {
2925
+ cursor: serverTime,
2926
+ rows: Object.fromEntries(merged),
2927
+ syncedAt
2928
+ });
2929
+ await persist();
2930
+ return {
2931
+ stats,
2932
+ // Derived from what the merge DID, not from `rows.length` — an
2933
+ // at-least-once window routinely re-delivers rows that change
2934
+ // nothing, and counting them would report a change that never
2935
+ // happened (`06 §5`).
2936
+ changed: stats.added + stats.updated + stats.removed > 0,
2937
+ cursor: serverTime
2938
+ };
2939
+ },
2940
+ async upsert({ tripRef, listName, row, syncedAt }) {
2941
+ const current = getList(tripRef, listName);
2942
+ const held = current.rows[row.id];
2943
+ if (held !== void 0 && held.version > row.version) {
2944
+ return false;
2945
+ }
2946
+ setList(tripRef, listName, {
2947
+ cursor: current.cursor,
2948
+ rows: { ...current.rows, [row.id]: row },
2949
+ syncedAt: syncedAt !== void 0 ? { ...current.syncedAt, [row.id]: syncedAt } : current.syncedAt
2950
+ });
2951
+ await persist();
2952
+ return true;
2953
+ },
2954
+ async purgeEntity(tripRef, listName, id) {
2955
+ const current = getList(tripRef, listName);
2956
+ if (current.rows[id] === void 0) {
2957
+ return;
2958
+ }
2959
+ const rows = { ...current.rows };
2960
+ const stamps = { ...current.syncedAt };
2961
+ delete rows[id];
2962
+ delete stamps[id];
2963
+ setList(tripRef, listName, { cursor: current.cursor, rows, syncedAt: stamps });
2964
+ await persist();
2965
+ },
2966
+ async purgeTrip(tripRef) {
2967
+ if (!trips.delete(tripRef)) {
2968
+ return;
2969
+ }
2970
+ await persist();
2971
+ }
2972
+ };
2973
+ }
2974
+
2975
+ // src/offline/engine.ts
2976
+ function createOfflineEngine(options) {
2977
+ const keyPrefix = `kaafil:v1:${options.scope}`;
2978
+ const events = createOfflineEvents({
2979
+ ...options.onEventHandlerError !== void 0 ? { onHandlerError: (error) => options.onEventHandlerError?.(error) } : {}
2980
+ });
2981
+ const snapshot = createSnapshotStore({ storage: options.storage, keyPrefix });
2982
+ const outbox = createOutbox({
2983
+ storage: options.storage,
2984
+ keyPrefix,
2985
+ ...options.now !== void 0 ? { now: options.now } : {},
2986
+ ...options.newId !== void 0 ? { newId: options.newId } : {}
2987
+ });
2988
+ let share;
2989
+ const onServerTime = (serverTime) => {
2990
+ share?.observeServerTime(serverTime);
2991
+ };
2992
+ if (options.share !== void 0) {
2993
+ share = createShareGuard({
2994
+ tripRef: options.share.tripRef,
2995
+ expiresAt: options.share.expiresAt,
2996
+ snapshot,
2997
+ outbox,
2998
+ events,
2999
+ ...options.share.monotonic !== void 0 ? { monotonic: options.share.monotonic } : {}
3000
+ });
3001
+ }
3002
+ const drainer = createDrainer({
3003
+ outbox,
3004
+ snapshot,
3005
+ transport: options.transport,
3006
+ events,
3007
+ onServerTime,
3008
+ ...options.conflictResolver !== void 0 ? { conflictResolver: options.conflictResolver } : {},
3009
+ ...options.now !== void 0 ? { now: options.now } : {},
3010
+ ...options.random !== void 0 ? { random: options.random } : {}
3011
+ });
3012
+ const pull = createPullCoordinator({
3013
+ snapshot,
3014
+ transport: options.transport,
3015
+ events,
3016
+ onServerTime
3017
+ });
3018
+ const blobs = options.blob === void 0 ? void 0 : createBlobLane({
3019
+ storage: options.storage,
3020
+ keyPrefix,
3021
+ outbox,
3022
+ uploader: options.blob.uploader,
3023
+ source: options.blob.source,
3024
+ ...options.now !== void 0 ? { now: options.now } : {},
3025
+ ...options.random !== void 0 ? { random: options.random } : {}
3026
+ });
3027
+ let unbind;
3028
+ async function enqueue(input) {
3029
+ share?.assertWritable();
3030
+ const op = await outbox.enqueue({
3031
+ tripRef: input.tripRef,
3032
+ method: input.method,
3033
+ path: input.path,
3034
+ operationId: input.operationId,
3035
+ ...input.body !== void 0 ? { body: input.body } : {},
3036
+ ...input.ifMatch !== void 0 ? { ifMatch: input.ifMatch } : {},
3037
+ ...input.entity !== void 0 ? { entity: input.entity } : {},
3038
+ ...input.idempotencyKey !== void 0 ? { idempotencyKey: input.idempotencyKey } : {},
3039
+ ...input.enqueuedAt !== void 0 ? { enqueuedAt: input.enqueuedAt } : {}
3040
+ });
3041
+ if (input.optimistic !== void 0 && input.entity !== void 0) {
3042
+ await snapshot.upsert({
3043
+ tripRef: input.tripRef,
3044
+ listName: input.entity.listName,
3045
+ row: input.optimistic
3046
+ });
3047
+ }
3048
+ drainer.kick();
3049
+ return op;
3050
+ }
3051
+ return {
3052
+ events,
3053
+ snapshot,
3054
+ outbox,
3055
+ drainer,
3056
+ pull,
3057
+ blobs,
3058
+ share,
3059
+ async open() {
3060
+ await Promise.all([snapshot.load(), outbox.load(), blobs?.load() ?? Promise.resolve()]);
3061
+ unbind = drainer.bindOpportunisticTriggers();
3062
+ },
3063
+ enqueue,
3064
+ async enqueueWithBlob(input) {
3065
+ const { blob, ...rest } = input;
3066
+ share?.assertWritable();
3067
+ const op = await outbox.enqueue({
3068
+ tripRef: rest.tripRef,
3069
+ method: rest.method,
3070
+ path: rest.path,
3071
+ operationId: rest.operationId,
3072
+ receiptPending: true,
3073
+ blobId: blob.id,
3074
+ ...rest.body !== void 0 ? { body: rest.body } : {},
3075
+ ...rest.ifMatch !== void 0 ? { ifMatch: rest.ifMatch } : {},
3076
+ ...rest.entity !== void 0 ? { entity: rest.entity } : {},
3077
+ ...rest.idempotencyKey !== void 0 ? { idempotencyKey: rest.idempotencyKey } : {},
3078
+ ...rest.enqueuedAt !== void 0 ? { enqueuedAt: rest.enqueuedAt } : {}
3079
+ });
3080
+ if (rest.optimistic !== void 0 && rest.entity !== void 0) {
3081
+ await snapshot.upsert({
3082
+ tripRef: rest.tripRef,
3083
+ listName: rest.entity.listName,
3084
+ row: rest.optimistic
3085
+ });
3086
+ }
3087
+ if (blobs !== void 0) {
3088
+ await blobs.enqueue({
3089
+ blobId: blob.id,
3090
+ tripRef: rest.tripRef,
3091
+ parentOpId: op.id,
3092
+ contentType: blob.contentType,
3093
+ sizeBytes: blob.sizeBytes,
3094
+ backfill: blob.backfill
3095
+ });
3096
+ }
3097
+ drainer.kick();
3098
+ return op;
3099
+ },
3100
+ async drain() {
3101
+ await share?.parkOpsPastGrace();
3102
+ const report = await drainer.drain();
3103
+ await blobs?.drain();
3104
+ return report;
3105
+ },
3106
+ close() {
3107
+ unbind?.();
3108
+ unbind = void 0;
3109
+ events.clear();
3110
+ }
3111
+ };
3112
+ }
3113
+ function outcomeFromError(error) {
3114
+ if (isKaafilError(error)) {
3115
+ const kaafil = error;
3116
+ return {
3117
+ status: kaafil.status ?? null,
3118
+ ...kaafil.code !== void 0 ? { code: kaafil.code } : {},
3119
+ ...kaafil.details !== void 0 ? { details: kaafil.details } : {},
3120
+ ...kaafil.meta?.serverTime !== void 0 ? { serverTime: kaafil.meta.serverTime } : {},
3121
+ error: kaafil
3122
+ };
3123
+ }
3124
+ return { status: null, transportFailureKind: "network" };
3125
+ }
3126
+ function entityFromBody(body) {
3127
+ if (typeof body !== "object" || body === null) {
3128
+ return void 0;
3129
+ }
3130
+ const candidate = body;
3131
+ if (typeof candidate.id === "string" && typeof candidate.version === "number") {
3132
+ return body;
3133
+ }
3134
+ return void 0;
3135
+ }
3136
+ function createHttpOfflineTransport(options) {
3137
+ const { http, sync } = options;
3138
+ const batchable = options.credential !== "share" || isShareBatchPushAvailable();
3139
+ const transport = {
3140
+ async sendOne(op, signal) {
3141
+ try {
3142
+ const response = await http.execute({
3143
+ method: op.method,
3144
+ operationId: op.operationId,
3145
+ path: op.path,
3146
+ // The op's OWN key, fixed at enqueue and reused on every attempt.
3147
+ idempotencyKey: op.idempotencyKey,
3148
+ ...op.body !== void 0 ? { body: op.body } : {},
3149
+ ...op.ifMatch !== void 0 ? { headers: { "If-Match": String(op.ifMatch) } } : {},
3150
+ ...signal !== void 0 ? { signal } : {}
3151
+ });
3152
+ const { meta, ...data } = response;
3153
+ const entity = entityFromBody(data);
3154
+ return {
3155
+ status: meta.status,
3156
+ serverTime: meta.serverTime,
3157
+ ...entity !== void 0 ? { entity } : {}
3158
+ };
3159
+ } catch (error) {
3160
+ return outcomeFromError(error);
3161
+ }
3162
+ },
3163
+ ...options.readEntity !== void 0 ? { readEntity: options.readEntity } : {},
3164
+ async pullTrip({ tripRef, since, signal }) {
3165
+ const response = await sync.pullTrip({
3166
+ tripRef,
3167
+ ...since !== void 0 ? { since } : {},
3168
+ ...signal !== void 0 ? { signal } : {}
3169
+ });
3170
+ return {
3171
+ tripRef: response.tripRef,
3172
+ // `sections` is a PARTIAL record and stays one all the way through —
3173
+ // nothing here fills a missing key with an empty list (`./pull.ts`).
3174
+ sections: response.sections,
3175
+ serverTime: response.meta.serverTime
3176
+ };
3177
+ }
3178
+ };
3179
+ if (!batchable) {
3180
+ return transport;
3181
+ }
3182
+ return {
3183
+ ...transport,
3184
+ async sendBatch(ops, signal) {
3185
+ const push = options.credential === "share" ? sync.pushShare : sync.push;
3186
+ const response = await push({
3187
+ ops: ops.map((op) => ({
3188
+ method: op.method,
3189
+ path: op.path,
3190
+ idempotencyKey: op.idempotencyKey,
3191
+ ...op.ifMatch !== void 0 ? { ifMatch: op.ifMatch } : {},
3192
+ ...op.enqueuedAt !== void 0 ? { enqueuedAt: op.enqueuedAt } : {},
3193
+ ...op.body !== void 0 ? { body: op.body } : {}
3194
+ })),
3195
+ ...signal !== void 0 ? { signal } : {}
3196
+ });
3197
+ const serverTime = response.meta.serverTime;
3198
+ const byIndex = new Map(response.verdicts.map((verdict) => [verdict.index, verdict]));
3199
+ return ops.map((_op, index) => {
3200
+ const verdict = byIndex.get(index);
3201
+ if (verdict === void 0) {
3202
+ return { status: null, transportFailureKind: "network" };
3203
+ }
3204
+ const envelope = verdict.body;
3205
+ if (verdict.status >= 200 && verdict.status < 300) {
3206
+ const entity = entityFromBody(envelope?.data);
3207
+ return {
3208
+ status: verdict.status,
3209
+ serverTime,
3210
+ ...entity !== void 0 ? { entity } : {}
3211
+ };
3212
+ }
3213
+ const code = envelope?.error?.code;
3214
+ const details = envelope?.error?.details;
3215
+ return {
3216
+ status: verdict.status,
3217
+ serverTime,
3218
+ ...typeof code === "string" && code in KaafilErrorCodeValues ? { code } : {},
3219
+ ...typeof details === "object" && details !== null ? { details } : {}
3220
+ };
3221
+ });
3222
+ }
3223
+ };
3224
+ }
3225
+ var KaafilErrorCodeValues = Object.fromEntries(
3226
+ Object.values(KaafilErrorCode).map((code) => [code, true])
3227
+ );
3228
+
3229
+ // src/resources/checklists.ts
3230
+ function createChecklistsResource(client) {
3231
+ return {
3232
+ async read(options) {
3233
+ const { tripRef, since, signal } = options;
3234
+ return client.execute({
3235
+ method: "GET",
3236
+ operationId: OperationId.ReadChecklistAggregate,
3237
+ path: "/api/v1/trips/{ref}/checklist",
3238
+ pathParams: { ref: tripRef },
3239
+ query: { since },
3240
+ ...signal !== void 0 ? { signal } : {}
3241
+ });
3242
+ },
3243
+ items: {
3244
+ async add(options) {
3245
+ const { tripRef, idempotencyKey, signal, ...body } = options;
3246
+ return client.execute({
3247
+ method: "POST",
3248
+ operationId: OperationId.AddChecklistItem,
3249
+ path: "/api/v1/trips/{ref}/checklist/items",
3250
+ pathParams: { ref: tripRef },
3251
+ body,
3252
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3253
+ ...signal !== void 0 ? { signal } : {}
3254
+ });
3255
+ },
3256
+ async patch(options) {
3257
+ const { tripRef, itemId, version, signal, ...body } = options;
3258
+ return client.execute({
3259
+ method: "PATCH",
3260
+ operationId: OperationId.PatchChecklistItem,
3261
+ path: "/api/v1/trips/{ref}/checklist/items/{itemId}",
3262
+ pathParams: { ref: tripRef, itemId },
3263
+ body,
3264
+ headers: { "If-Match": String(version) },
3265
+ ...signal !== void 0 ? { signal } : {}
3266
+ });
3267
+ },
3268
+ async remove(options) {
3269
+ const { tripRef, itemId, version, signal } = options;
3270
+ return client.execute({
3271
+ method: "DELETE",
3272
+ operationId: OperationId.DeleteChecklistItem,
3273
+ path: "/api/v1/trips/{ref}/checklist/items/{itemId}",
3274
+ pathParams: { ref: tripRef, itemId },
3275
+ headers: { "If-Match": String(version) },
3276
+ ...signal !== void 0 ? { signal } : {}
3277
+ });
3278
+ },
3279
+ async toggle(options) {
3280
+ const { tripRef, itemId, idempotencyKey, signal, ...body } = options;
3281
+ return client.execute({
3282
+ method: "POST",
3283
+ operationId: OperationId.ToggleChecklistItem,
3284
+ path: "/api/v1/trips/{ref}/checklist/items/{itemId}/toggle",
3285
+ pathParams: { ref: tripRef, itemId },
3286
+ body,
3287
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3288
+ ...signal !== void 0 ? { signal } : {}
3289
+ });
3290
+ }
3291
+ },
3292
+ templates: {
3293
+ async list(options) {
3294
+ const { tripRef, locale, signal } = options;
3295
+ return client.execute({
3296
+ method: "GET",
3297
+ operationId: OperationId.ListChecklistTemplates,
3298
+ path: "/api/v1/trips/{ref}/checklist/templates",
3299
+ pathParams: { ref: tripRef },
3300
+ query: { locale },
3301
+ ...signal !== void 0 ? { signal } : {}
3302
+ });
3303
+ },
3304
+ async pull(options) {
3305
+ const { tripRef, idempotencyKey, signal, ...body } = options;
3306
+ return client.execute({
3307
+ method: "POST",
3308
+ operationId: OperationId.PullChecklistTemplate,
3309
+ path: "/api/v1/trips/{ref}/checklist/pull-template",
3310
+ pathParams: { ref: tripRef },
3311
+ body,
3312
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3313
+ ...signal !== void 0 ? { signal } : {}
3314
+ });
3315
+ }
3316
+ }
3317
+ };
3318
+ }
3319
+
3320
+ // src/resources/closeout.ts
3321
+ function createCloseoutResource(client) {
3322
+ return {
3323
+ async get(options) {
3324
+ const { tripRef, since, signal } = options;
3325
+ return client.execute({
3326
+ method: "GET",
3327
+ operationId: OperationId.ReadCloseout,
3328
+ path: "/api/v1/trips/{ref}/closeout",
3329
+ pathParams: { ref: tripRef },
3330
+ query: { since },
3331
+ ...signal !== void 0 ? { signal } : {}
3332
+ });
3333
+ },
3334
+ async saveHandover(options) {
3335
+ const { tripRef, idempotencyKey, signal, ...body } = options;
3336
+ return client.execute({
3337
+ method: "POST",
3338
+ operationId: OperationId.SaveCloseoutHandover,
3339
+ path: "/api/v1/trips/{ref}/closeout/handover",
3340
+ pathParams: { ref: tripRef },
3341
+ body,
3342
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3343
+ ...signal !== void 0 ? { signal } : {}
3344
+ });
3345
+ },
3346
+ async lock(options) {
3347
+ const { tripRef, idempotencyKey, signal, ...body } = options;
3348
+ return client.execute({
3349
+ method: "POST",
3350
+ operationId: OperationId.LockCloseout,
3351
+ path: "/api/v1/trips/{ref}/closeout/lock",
3352
+ pathParams: { ref: tripRef },
3353
+ body,
3354
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3355
+ ...signal !== void 0 ? { signal } : {}
3356
+ });
3357
+ },
3358
+ async unlock(options) {
3359
+ const { tripRef, idempotencyKey, signal, ...body } = options;
3360
+ return client.execute({
3361
+ method: "POST",
3362
+ operationId: OperationId.UnlockCloseout,
3363
+ path: "/api/v1/trips/{ref}/closeout/unlock",
3364
+ pathParams: { ref: tripRef },
3365
+ body,
3366
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3367
+ ...signal !== void 0 ? { signal } : {}
3368
+ });
3369
+ },
3370
+ async exportPdf(options) {
3371
+ const { tripRef, signal, ...body } = options;
3372
+ return client.executeBinary({
3373
+ method: "POST",
3374
+ operationId: OperationId.ExportCloseoutPack,
3375
+ path: "/api/v1/trips/{ref}/closeout/export-pdf",
3376
+ pathParams: { ref: tripRef },
3377
+ body,
3378
+ // The one place a non-JSON `Accept` is sent. `exportCloseoutPack`
3379
+ // declares no `Idempotency-Key` parameter
3380
+ // (`OPERATION_ACCEPTS_IDEMPOTENCY_KEY.exportCloseoutPack` is `false`),
3381
+ // and rightly — printing the same pack twice creates nothing — so no
3382
+ // key is offered here and the transport mints none.
3383
+ accept: "application/pdf",
3384
+ ...signal !== void 0 ? { signal } : {}
3385
+ });
3386
+ }
3387
+ };
3388
+ }
3389
+
3390
+ // src/resources/collections.ts
3391
+ function createCollectionsResource(client) {
3392
+ return {
3393
+ async list(options) {
3394
+ const { tripRef, travellerId, since, signal } = options;
3395
+ return client.execute({
3396
+ method: "GET",
3397
+ operationId: OperationId.ListCollections,
3398
+ path: "/api/v1/trips/{ref}/collections",
3399
+ pathParams: { ref: tripRef },
3400
+ query: { travellerId, since },
3401
+ ...signal !== void 0 ? { signal } : {}
3402
+ });
3403
+ },
3404
+ async eligible(options) {
3405
+ const { tripRef, signal } = options;
3406
+ return client.execute({
3407
+ method: "GET",
3408
+ operationId: OperationId.ListEligibleCollections,
3409
+ path: "/api/v1/trips/{ref}/collections/eligible",
3410
+ pathParams: { ref: tripRef },
3411
+ ...signal !== void 0 ? { signal } : {}
3412
+ });
3413
+ },
3414
+ async record(options) {
3415
+ const { tripRef, idempotencyKey, signal, collectedAt, ...rest } = options;
3416
+ const body = {
3417
+ ...rest,
3418
+ ...collectedAt !== void 0 ? { collectedAt: normalizeDateTimeInput(collectedAt, "collectedAt") } : {}
3419
+ };
3420
+ return client.execute({
3421
+ method: "POST",
3422
+ operationId: OperationId.RecordCollection,
3423
+ path: "/api/v1/trips/{ref}/collections",
3424
+ pathParams: { ref: tripRef },
3425
+ body,
3426
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3427
+ ...signal !== void 0 ? { signal } : {}
3428
+ });
3429
+ },
3430
+ async void(options) {
3431
+ const { tripRef, collectionId, version, signal, ...body } = options;
3432
+ return client.execute({
3433
+ method: "DELETE",
3434
+ operationId: OperationId.VoidCollection,
3435
+ path: "/api/v1/trips/{ref}/collections/{id}/void",
3436
+ pathParams: { ref: tripRef, id: collectionId },
3437
+ body,
3438
+ headers: { "If-Match": String(version) },
3439
+ ...signal !== void 0 ? { signal } : {}
3440
+ });
3441
+ }
3442
+ };
3443
+ }
3444
+
3445
+ // src/resources/expenses.ts
3446
+ function createExpensesResource(client) {
3447
+ return {
3448
+ async list(options) {
3449
+ const { tripRef, since, signal, ...filters } = options;
3450
+ return client.execute({
3451
+ method: "GET",
3452
+ operationId: OperationId.ListExpenses,
3453
+ path: "/api/v1/trips/{ref}/expenses",
3454
+ pathParams: { ref: tripRef },
3455
+ query: { ...filters, since },
3456
+ ...signal !== void 0 ? { signal } : {}
3457
+ });
3458
+ },
3459
+ async read(options) {
3460
+ const { tripRef, expenseId, signal } = options;
3461
+ return client.execute({
3462
+ method: "GET",
3463
+ operationId: OperationId.ReadExpense,
3464
+ path: "/api/v1/trips/{ref}/expenses/{id}",
3465
+ pathParams: { ref: tripRef, id: expenseId },
3466
+ ...signal !== void 0 ? { signal } : {}
3467
+ });
3468
+ },
3469
+ async log(options) {
3470
+ const { tripRef, idempotencyKey, signal, spentAt, ...rest } = options;
3471
+ const body = {
3472
+ ...rest,
3473
+ ...spentAt !== void 0 ? { spentAt: normalizeDateTimeInput(spentAt, "spentAt") } : {}
3474
+ };
3475
+ return client.execute({
3476
+ method: "POST",
3477
+ operationId: OperationId.LogExpense,
3478
+ path: "/api/v1/trips/{ref}/expenses",
3479
+ pathParams: { ref: tripRef },
3480
+ body,
3481
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3482
+ ...signal !== void 0 ? { signal } : {}
3483
+ });
3484
+ },
3485
+ async linkReceipt(options) {
3486
+ const { tripRef, expenseId, idempotencyKey, signal, ...body } = options;
3487
+ return client.execute({
3488
+ method: "PATCH",
3489
+ operationId: OperationId.LinkExpenseReceipt,
3490
+ path: "/api/v1/trips/{ref}/expenses/{id}/receipt",
3491
+ pathParams: { ref: tripRef, id: expenseId },
3492
+ body,
3493
+ idempotencyKey,
3494
+ ...signal !== void 0 ? { signal } : {}
3495
+ });
3496
+ },
3497
+ async void(options) {
3498
+ const { tripRef, expenseId, version, signal, ...body } = options;
3499
+ return client.execute({
3500
+ method: "DELETE",
3501
+ operationId: OperationId.VoidExpense,
3502
+ path: "/api/v1/trips/{ref}/expenses/{id}/void",
3503
+ pathParams: { ref: tripRef, id: expenseId },
3504
+ body,
3505
+ headers: { "If-Match": String(version) },
3506
+ ...signal !== void 0 ? { signal } : {}
3507
+ });
3508
+ },
3509
+ claims: {
3510
+ async submit(options) {
3511
+ const { tripRef, expenseId, idempotencyKey, signal } = options;
3512
+ return client.execute({
3513
+ method: "POST",
3514
+ operationId: OperationId.SubmitExpenseClaim,
3515
+ path: "/api/v1/trips/{ref}/expenses/{id}/claim",
3516
+ pathParams: { ref: tripRef, id: expenseId },
3517
+ body: {},
3518
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3519
+ ...signal !== void 0 ? { signal } : {}
3520
+ });
3521
+ },
3522
+ async withdraw(options) {
3523
+ const { tripRef, expenseId, version, signal } = options;
3524
+ return client.execute({
3525
+ method: "DELETE",
3526
+ operationId: OperationId.WithdrawExpenseClaim,
3527
+ path: "/api/v1/trips/{ref}/expenses/{id}/claim/withdraw",
3528
+ pathParams: { ref: tripRef, id: expenseId },
3529
+ body: {},
3530
+ headers: { "If-Match": String(version) },
3531
+ ...signal !== void 0 ? { signal } : {}
3532
+ });
3533
+ },
3534
+ async ingest(options) {
3535
+ const { tripRef, expenseId, idempotencyKey, signal, decisionAt, ...rest } = options;
3536
+ const body = {
3537
+ ...rest,
3538
+ decisionAt: normalizeDateTimeInput(decisionAt, "decisionAt")
3539
+ };
3540
+ return client.execute({
3541
+ method: "POST",
3542
+ operationId: OperationId.ClaimStatusIngest,
3543
+ path: "/api/v1/trips/{ref}/expenses/{id}/claim-status",
3544
+ pathParams: { ref: tripRef, id: expenseId },
3545
+ body,
3546
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3547
+ ...signal !== void 0 ? { signal } : {}
3548
+ });
3549
+ }
3550
+ }
3551
+ };
3552
+ }
3553
+
3554
+ // src/resources/files.ts
3555
+ function createFilesResource(client) {
3556
+ return {
3557
+ async request(options) {
3558
+ const { idempotencyKey, signal, ...body } = options;
3559
+ return client.execute({
3560
+ method: "POST",
3561
+ operationId: OperationId.RequestFileUpload,
3562
+ path: "/api/v1/files",
3563
+ body,
3564
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3565
+ ...signal !== void 0 ? { signal } : {}
3566
+ });
3567
+ },
3568
+ async meta(options) {
3569
+ const { fileId, signal } = options;
3570
+ return client.execute({
3571
+ method: "GET",
3572
+ operationId: OperationId.ReadFile,
3573
+ path: "/api/v1/files/{id}",
3574
+ pathParams: { id: fileId },
3575
+ ...signal !== void 0 ? { signal } : {}
3576
+ });
3577
+ },
3578
+ async confirm(options) {
3579
+ const { fileId, idempotencyKey, signal } = options;
3580
+ return client.execute({
3581
+ method: "POST",
3582
+ operationId: OperationId.ConfirmFileUpload,
3583
+ path: "/api/v1/files/{id}/confirm",
3584
+ pathParams: { id: fileId },
3585
+ body: {},
3586
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3587
+ ...signal !== void 0 ? { signal } : {}
3588
+ });
3589
+ },
3590
+ async url(options) {
3591
+ const { fileId, signal } = options;
3592
+ return client.execute({
3593
+ method: "GET",
3594
+ operationId: OperationId.ReadFileUrl,
3595
+ path: "/api/v1/files/{id}/url",
3596
+ pathParams: { id: fileId },
3597
+ ...signal !== void 0 ? { signal } : {}
3598
+ });
3599
+ }
3600
+ };
3601
+ }
3602
+
3603
+ // src/resources/float.ts
3604
+ function createFloatResource(client) {
3605
+ return {
3606
+ async readSummary(options) {
3607
+ const { tripRef, since, signal } = options;
3608
+ return client.execute({
3609
+ method: "GET",
3610
+ operationId: OperationId.ReadFloatSummary,
3611
+ path: "/api/v1/trips/{ref}/float",
3612
+ pathParams: { ref: tripRef },
3613
+ query: { since },
3614
+ ...signal !== void 0 ? { signal } : {}
3615
+ });
3616
+ },
3617
+ async readLedger(options) {
3618
+ const { tripRef, managerId, signal } = options;
3619
+ return client.execute({
3620
+ method: "GET",
3621
+ operationId: OperationId.ReadFloatLedger,
3622
+ path: "/api/v1/trips/{ref}/float/{managerId}/ledger",
3623
+ pathParams: { ref: tripRef, managerId },
3624
+ ...signal !== void 0 ? { signal } : {}
3625
+ });
3626
+ },
3627
+ async issue(options) {
3628
+ const { tripRef, idempotencyKey, signal, ...body } = options;
3629
+ return client.execute({
3630
+ method: "POST",
3631
+ operationId: OperationId.IssueFloat,
3632
+ path: "/api/v1/trips/{ref}/float/issue",
3633
+ pathParams: { ref: tripRef },
3634
+ body,
3635
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3636
+ ...signal !== void 0 ? { signal } : {}
3637
+ });
3638
+ },
3639
+ async return(options) {
3640
+ const { tripRef, idempotencyKey, signal, ...body } = options;
3641
+ return client.execute({
3642
+ method: "POST",
3643
+ operationId: OperationId.ReturnFloat,
3644
+ path: "/api/v1/trips/{ref}/float/return",
3645
+ pathParams: { ref: tripRef },
3646
+ body,
3647
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3648
+ ...signal !== void 0 ? { signal } : {}
3649
+ });
3650
+ },
3651
+ async adjust(options) {
3652
+ const { tripRef, idempotencyKey, signal, ...body } = options;
3653
+ return client.execute({
3654
+ method: "POST",
3655
+ operationId: OperationId.AdjustFloat,
3656
+ path: "/api/v1/trips/{ref}/float/adjust",
3657
+ pathParams: { ref: tripRef },
3658
+ body,
3659
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3660
+ ...signal !== void 0 ? { signal } : {}
3661
+ });
3662
+ }
3663
+ };
3664
+ }
3665
+
3666
+ // src/resources/itinerary.ts
3667
+ function createItineraryResource(client) {
3668
+ return {
3669
+ async read(options) {
3670
+ const { tripRef, dayIndex, since, signal } = options;
3671
+ return client.execute({
3672
+ method: "GET",
3673
+ operationId: OperationId.ReadItinerary,
3674
+ path: "/api/v1/trips/{ref}/itinerary",
3675
+ pathParams: { ref: tripRef },
3676
+ query: { dayIndex, since },
3677
+ ...signal !== void 0 ? { signal } : {}
3678
+ });
3679
+ },
3680
+ items: {
3681
+ async add(options) {
3682
+ const { tripRef, idempotencyKey, signal, isoDate, startTime, endTime, ...rest } = options;
3683
+ const body = {
3684
+ ...rest,
3685
+ isoDate: normalizeDateTimeInput(isoDate, "isoDate"),
3686
+ ...startTime !== void 0 ? { startTime: normalizeNullableDateTimeInput(startTime, "startTime") } : {},
3687
+ ...endTime !== void 0 ? { endTime: normalizeNullableDateTimeInput(endTime, "endTime") } : {}
3688
+ };
3689
+ return client.execute({
3690
+ method: "POST",
3691
+ operationId: OperationId.AddItineraryItem,
3692
+ path: "/api/v1/trips/{ref}/itinerary/items",
3693
+ pathParams: { ref: tripRef },
3694
+ body,
3695
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3696
+ ...signal !== void 0 ? { signal } : {}
3697
+ });
3698
+ },
3699
+ async patch(options) {
3700
+ const { tripRef, itemId, version, signal, startTime, endTime, ...rest } = options;
3701
+ const body = {
3702
+ ...rest,
3703
+ ...startTime !== void 0 ? { startTime: normalizeNullableDateTimeInput(startTime, "startTime") } : {},
3704
+ ...endTime !== void 0 ? { endTime: normalizeNullableDateTimeInput(endTime, "endTime") } : {}
3705
+ };
3706
+ return client.execute({
3707
+ method: "PATCH",
3708
+ operationId: OperationId.PatchItineraryItem,
3709
+ path: "/api/v1/trips/{ref}/itinerary/items/{itemId}",
3710
+ pathParams: { ref: tripRef, itemId },
3711
+ body,
3712
+ headers: { "If-Match": String(version) },
3713
+ ...signal !== void 0 ? { signal } : {}
3714
+ });
3715
+ },
3716
+ async remove(options) {
3717
+ const { tripRef, itemId, version, signal } = options;
3718
+ return client.execute({
3719
+ method: "DELETE",
3720
+ operationId: OperationId.DeleteItineraryItem,
3721
+ path: "/api/v1/trips/{ref}/itinerary/items/{itemId}",
3722
+ pathParams: { ref: tripRef, itemId },
3723
+ headers: { "If-Match": String(version) },
3724
+ ...signal !== void 0 ? { signal } : {}
3725
+ });
3726
+ },
3727
+ async reorder(options) {
3728
+ const { tripRef, itemId, idempotencyKey, signal, ...body } = options;
3729
+ return client.execute({
3730
+ method: "POST",
3731
+ operationId: OperationId.ReorderItineraryItem,
3732
+ path: "/api/v1/trips/{ref}/itinerary/items/{itemId}/reorder",
3733
+ pathParams: { ref: tripRef, itemId },
3734
+ body,
3735
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3736
+ ...signal !== void 0 ? { signal } : {}
3737
+ });
3738
+ }
3739
+ },
3740
+ days: {
3741
+ async patch(options) {
3742
+ const { tripRef, dayIndex, version, signal, ...body } = options;
3743
+ return client.execute({
3744
+ method: "PATCH",
3745
+ operationId: OperationId.PatchItineraryDay,
3746
+ path: "/api/v1/trips/{ref}/itinerary/days/{dayIndex}",
3747
+ pathParams: { ref: tripRef, dayIndex },
3748
+ body,
3749
+ headers: { "If-Match": String(version) },
3750
+ ...signal !== void 0 ? { signal } : {}
3751
+ });
3752
+ }
3753
+ },
3754
+ changeLog: {
3755
+ async list(options) {
3756
+ const { tripRef, since, signal } = options;
3757
+ return client.execute({
3758
+ method: "GET",
3759
+ operationId: OperationId.ReadItineraryChangeLog,
3760
+ path: "/api/v1/trips/{ref}/itinerary/change-log",
3761
+ pathParams: { ref: tripRef },
3762
+ query: { since },
3763
+ ...signal !== void 0 ? { signal } : {}
3764
+ });
3765
+ }
3766
+ }
3767
+ };
3768
+ }
3769
+
3770
+ // src/resources/journey.ts
3771
+ var DEFAULT_WAIT_UNTIL_READY_TIMEOUT_MS = 6e4;
3772
+ var DEFAULT_WAIT_UNTIL_READY_POLL_INTERVAL_MS = 1e3;
3773
+ function createJourneyResource(client) {
3774
+ const resource = {
3775
+ async get(options) {
3776
+ const { tripRef, signal } = options;
3777
+ return client.execute({
3778
+ method: "GET",
3779
+ operationId: OperationId.ReadJourney,
3780
+ path: "/api/v1/trips/{ref}/journey",
3781
+ pathParams: { ref: tripRef },
3782
+ ...signal !== void 0 ? { signal } : {}
3783
+ });
3784
+ },
3785
+ async capabilities(options) {
3786
+ const { tripRef, signal } = options;
3787
+ return client.execute({
3788
+ method: "GET",
3789
+ operationId: OperationId.ReadJourneyCapabilities,
3790
+ path: "/api/v1/trips/{ref}/journey/capabilities",
3791
+ pathParams: { ref: tripRef },
3792
+ ...signal !== void 0 ? { signal } : {}
3793
+ });
3794
+ },
3795
+ async rebuild(options) {
3796
+ const { tripRef, idempotencyKey, signal } = options;
3797
+ return client.execute({
3798
+ method: "POST",
3799
+ operationId: OperationId.RebuildJourney,
3800
+ path: "/api/v1/trips/{ref}/journey/rebuild",
3801
+ pathParams: { ref: tripRef },
3802
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3803
+ ...signal !== void 0 ? { signal } : {}
3804
+ });
3805
+ },
3806
+ async runStep(options) {
3807
+ const { tripRef, stepId, idempotencyKey, signal } = options;
3808
+ return client.execute({
3809
+ method: "POST",
3810
+ operationId: OperationId.RunJourneyStep,
3811
+ path: "/api/v1/trips/{ref}/journey/steps/{stepId}/run",
3812
+ pathParams: { ref: tripRef, stepId },
3813
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3814
+ ...signal !== void 0 ? { signal } : {}
3815
+ });
3816
+ },
3817
+ async waitUntilReady(options) {
3818
+ const {
3819
+ tripRef,
3820
+ timeoutMs = DEFAULT_WAIT_UNTIL_READY_TIMEOUT_MS,
3821
+ pollIntervalMs = DEFAULT_WAIT_UNTIL_READY_POLL_INTERVAL_MS,
3822
+ signal
3823
+ } = options;
3824
+ const deadlineAt = Date.now() + timeoutMs;
3825
+ for (; ; ) {
3826
+ try {
3827
+ return await resource.get({ tripRef, ...signal !== void 0 ? { signal } : {} });
3828
+ } catch (error) {
3829
+ if (!(error instanceof KaafilNotFoundError)) {
3830
+ throw error;
3831
+ }
3832
+ const remainingMs = deadlineAt - Date.now();
3833
+ if (remainingMs <= 0) {
3834
+ throw new KaafilTimeoutError(
3835
+ `journey.waitUntilReady timed out after ${String(timeoutMs)}ms waiting for trip "${tripRef}" to become ready. The most likely cause is that the background worker that consumes the build queue is not running against this engine.`,
3836
+ { cause: error }
3837
+ );
3838
+ }
3839
+ try {
3840
+ await delayWithAbort(Math.min(pollIntervalMs, remainingMs), signal);
3841
+ } catch (sleepError) {
3842
+ throw new KaafilAbortError("Request aborted", { cause: sleepError });
3843
+ }
3844
+ }
3845
+ }
3846
+ },
3847
+ triggers: {
3848
+ async list(options) {
3849
+ const { agencyRef, signal } = options;
3850
+ return client.execute({
3851
+ method: "GET",
3852
+ operationId: OperationId.ListJourneyTriggers,
3853
+ path: "/api/v1/agencies/{ref}/journey-triggers",
3854
+ pathParams: { ref: agencyRef },
3855
+ ...signal !== void 0 ? { signal } : {}
3856
+ });
3857
+ },
3858
+ async patch(options) {
3859
+ const { agencyRef, key, version, idempotencyKey, signal, ...body } = options;
3860
+ return client.execute({
3861
+ method: "PATCH",
3862
+ operationId: OperationId.PatchJourneyTrigger,
3863
+ path: "/api/v1/agencies/{ref}/journey-triggers/{key}",
3864
+ pathParams: { ref: agencyRef, key },
3865
+ body,
3866
+ headers: { "If-Match": String(version) },
3867
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3868
+ ...signal !== void 0 ? { signal } : {}
3869
+ });
3870
+ }
3871
+ }
3872
+ };
3873
+ return resource;
3874
+ }
3875
+
3876
+ // src/resources/notifications.ts
3877
+ function createNotificationsResource(client) {
3878
+ return {
3879
+ async list(options = {}) {
3880
+ const { since, signal } = options;
3881
+ return client.execute({
3882
+ method: "GET",
3883
+ operationId: OperationId.ListManagerNotifications,
3884
+ path: "/api/v1/managers/me/notifications",
3885
+ ...since !== void 0 ? { query: { since } } : {},
3886
+ ...signal !== void 0 ? { signal } : {}
3887
+ });
3888
+ }
3889
+ };
3890
+ }
3891
+
3892
+ // src/resources/pickups.ts
3893
+ function createPickupsResource(client) {
3894
+ return {
3895
+ async list(options) {
3896
+ const { tripRef, kind, since, signal } = options;
3897
+ return client.execute({
3898
+ method: "GET",
3899
+ operationId: OperationId.ListPickupStops,
3900
+ path: "/api/v1/trips/{ref}/pickups",
3901
+ pathParams: { ref: tripRef },
3902
+ query: { kind, since },
3903
+ ...signal !== void 0 ? { signal } : {}
3904
+ });
3905
+ },
3906
+ async create(options) {
3907
+ const { tripRef, idempotencyKey, signal, scheduledTime, ...rest } = options;
3908
+ const body = {
3909
+ ...rest,
3910
+ scheduledTime: normalizeDateTimeInput(scheduledTime, "scheduledTime")
3911
+ };
3912
+ return client.execute({
3913
+ method: "POST",
3914
+ operationId: OperationId.CreatePickupStop,
3915
+ path: "/api/v1/trips/{ref}/pickups",
3916
+ pathParams: { ref: tripRef },
3917
+ body,
3918
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3919
+ ...signal !== void 0 ? { signal } : {}
3920
+ });
3921
+ },
3922
+ async patch(options) {
3923
+ const { tripRef, pointId, version, signal, scheduledTime, ...rest } = options;
3924
+ const body = {
3925
+ ...rest,
3926
+ ...scheduledTime !== void 0 ? { scheduledTime: normalizeDateTimeInput(scheduledTime, "scheduledTime") } : {}
3927
+ };
3928
+ return client.execute({
3929
+ method: "PATCH",
3930
+ operationId: OperationId.PatchPickupStop,
3931
+ path: "/api/v1/trips/{ref}/pickups/{pointId}",
3932
+ pathParams: { ref: tripRef, pointId },
3933
+ body,
3934
+ headers: { "If-Match": String(version) },
3935
+ ...signal !== void 0 ? { signal } : {}
3936
+ });
3937
+ },
3938
+ async remove(options) {
3939
+ const { tripRef, pointId, version, force, signal } = options;
3940
+ return client.execute({
3941
+ method: "DELETE",
3942
+ operationId: OperationId.DeletePickupStop,
3943
+ path: "/api/v1/trips/{ref}/pickups/{pointId}",
3944
+ pathParams: { ref: tripRef, pointId },
3945
+ query: { force },
3946
+ headers: { "If-Match": String(version) },
3947
+ ...signal !== void 0 ? { signal } : {}
3948
+ });
3949
+ },
3950
+ async reorder(options) {
3951
+ const { tripRef, idempotencyKey, signal, ...body } = options;
3952
+ return client.execute({
3953
+ method: "POST",
3954
+ operationId: OperationId.ReorderPickupStops,
3955
+ path: "/api/v1/trips/{ref}/pickups/reorder",
3956
+ pathParams: { ref: tripRef },
3957
+ body,
3958
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3959
+ ...signal !== void 0 ? { signal } : {}
3960
+ });
3961
+ },
3962
+ async assign(options) {
3963
+ const { tripRef, pointId, idempotencyKey, signal, ...body } = options;
3964
+ return client.execute({
3965
+ method: "POST",
3966
+ operationId: OperationId.AssignPickupTraveller,
3967
+ path: "/api/v1/trips/{ref}/pickups/{pointId}/assign",
3968
+ pathParams: { ref: tripRef, pointId },
3969
+ body,
3970
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3971
+ ...signal !== void 0 ? { signal } : {}
3972
+ });
3973
+ },
3974
+ async board(options) {
3975
+ const { tripRef, pointId, idempotencyKey, signal, ...body } = options;
3976
+ return client.execute({
3977
+ method: "POST",
3978
+ operationId: OperationId.BoardPickupTraveller,
3979
+ path: "/api/v1/trips/{ref}/pickups/{pointId}/board",
3980
+ pathParams: { ref: tripRef, pointId },
3981
+ body,
3982
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3983
+ ...signal !== void 0 ? { signal } : {}
3984
+ });
3985
+ },
3986
+ async close(options) {
3987
+ const { tripRef, pointId, idempotencyKey, signal, ...body } = options;
3988
+ return client.execute({
3989
+ method: "POST",
3990
+ operationId: OperationId.ClosePickupStop,
3991
+ path: "/api/v1/trips/{ref}/pickups/{pointId}/close",
3992
+ pathParams: { ref: tripRef, pointId },
3993
+ body,
3994
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
3995
+ ...signal !== void 0 ? { signal } : {}
3996
+ });
3997
+ },
3998
+ async reopen(options) {
3999
+ const { tripRef, pointId, idempotencyKey, signal } = options;
4000
+ return client.execute({
4001
+ method: "POST",
4002
+ operationId: OperationId.ReopenPickupStop,
4003
+ path: "/api/v1/trips/{ref}/pickups/{pointId}/reopen",
4004
+ pathParams: { ref: tripRef, pointId },
4005
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4006
+ ...signal !== void 0 ? { signal } : {}
4007
+ });
4008
+ },
4009
+ async manifestByPickup(options) {
4010
+ const { tripRef, kind, signal } = options;
4011
+ return client.execute({
4012
+ method: "GET",
4013
+ operationId: OperationId.ReadManifestByPickup,
4014
+ path: "/api/v1/trips/{ref}/manifest-by-pickup",
4015
+ pathParams: { ref: tripRef },
4016
+ query: { kind },
4017
+ ...signal !== void 0 ? { signal } : {}
4018
+ });
4019
+ }
4020
+ };
4021
+ }
4022
+
4023
+ // src/resources/rooming.ts
4024
+ function createRoomingResource(client) {
4025
+ return {
4026
+ async read(options) {
4027
+ const { tripRef, stayWindowId, since, signal } = options;
4028
+ return client.execute({
4029
+ method: "GET",
4030
+ operationId: OperationId.ReadRoomingBoard,
4031
+ path: "/api/v1/trips/{ref}/rooming",
4032
+ pathParams: { ref: tripRef },
4033
+ query: { stayWindowId, since },
4034
+ ...signal !== void 0 ? { signal } : {}
4035
+ });
4036
+ },
4037
+ async assign(options) {
4038
+ const { tripRef, idempotencyKey, signal, ...body } = options;
4039
+ return client.execute({
4040
+ method: "POST",
4041
+ operationId: OperationId.AssignRoomingBed,
4042
+ path: "/api/v1/trips/{ref}/rooming/assign",
4043
+ pathParams: { ref: tripRef },
4044
+ body,
4045
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4046
+ ...signal !== void 0 ? { signal } : {}
4047
+ });
4048
+ },
4049
+ async autoAssign(options) {
4050
+ const { tripRef, idempotencyKey, signal, ...body } = options;
4051
+ return client.execute({
4052
+ method: "POST",
4053
+ operationId: OperationId.AutoAssignRooming,
4054
+ path: "/api/v1/trips/{ref}/rooming/auto-assign",
4055
+ pathParams: { ref: tripRef },
4056
+ body,
4057
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4058
+ ...signal !== void 0 ? { signal } : {}
4059
+ });
4060
+ },
4061
+ stayWindows: {
4062
+ async list(options) {
4063
+ const { tripRef, since, signal } = options;
4064
+ return client.execute({
4065
+ method: "GET",
4066
+ operationId: OperationId.ListRoomingStayWindows,
4067
+ path: "/api/v1/trips/{ref}/rooming/stay-windows",
4068
+ pathParams: { ref: tripRef },
4069
+ query: { since },
4070
+ ...signal !== void 0 ? { signal } : {}
4071
+ });
4072
+ },
4073
+ async create(options) {
4074
+ const { tripRef, idempotencyKey, signal, startDate, endDate, ...rest } = options;
4075
+ const body = {
4076
+ ...rest,
4077
+ startDate: normalizeDateTimeInput(startDate, "startDate"),
4078
+ endDate: normalizeDateTimeInput(endDate, "endDate")
4079
+ };
4080
+ return client.execute({
4081
+ method: "POST",
4082
+ operationId: OperationId.CreateRoomingStayWindow,
4083
+ path: "/api/v1/trips/{ref}/rooming/stay-windows",
4084
+ pathParams: { ref: tripRef },
4085
+ body,
4086
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4087
+ ...signal !== void 0 ? { signal } : {}
4088
+ });
4089
+ },
4090
+ async patch(options) {
4091
+ const { tripRef, windowId, version, signal, startDate, endDate, ...rest } = options;
4092
+ const body = {
4093
+ ...rest,
4094
+ ...startDate !== void 0 ? { startDate: normalizeDateTimeInput(startDate, "startDate") } : {},
4095
+ ...endDate !== void 0 ? { endDate: normalizeDateTimeInput(endDate, "endDate") } : {}
4096
+ };
4097
+ return client.execute({
4098
+ method: "PATCH",
4099
+ operationId: OperationId.PatchRoomingStayWindow,
4100
+ path: "/api/v1/trips/{ref}/rooming/stay-windows/{windowId}",
4101
+ pathParams: { ref: tripRef, windowId },
4102
+ body,
4103
+ headers: { "If-Match": String(version) },
4104
+ ...signal !== void 0 ? { signal } : {}
4105
+ });
4106
+ },
4107
+ async remove(options) {
4108
+ const { tripRef, windowId, version, force, signal } = options;
4109
+ return client.execute({
4110
+ method: "DELETE",
4111
+ operationId: OperationId.DeleteRoomingStayWindow,
4112
+ path: "/api/v1/trips/{ref}/rooming/stay-windows/{windowId}",
4113
+ pathParams: { ref: tripRef, windowId },
4114
+ query: { force },
4115
+ headers: { "If-Match": String(version) },
4116
+ ...signal !== void 0 ? { signal } : {}
4117
+ });
4118
+ }
4119
+ },
4120
+ rooms: {
4121
+ async create(options) {
4122
+ const { tripRef, idempotencyKey, signal, ...body } = options;
4123
+ return client.execute({
4124
+ method: "POST",
4125
+ operationId: OperationId.CreateRoomingRoom,
4126
+ path: "/api/v1/trips/{ref}/rooming/rooms",
4127
+ pathParams: { ref: tripRef },
4128
+ body,
4129
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4130
+ ...signal !== void 0 ? { signal } : {}
4131
+ });
4132
+ },
4133
+ async patch(options) {
4134
+ const { tripRef, roomId, version, signal, ...body } = options;
4135
+ return client.execute({
4136
+ method: "PATCH",
4137
+ operationId: OperationId.PatchRoomingRoom,
4138
+ path: "/api/v1/trips/{ref}/rooming/rooms/{roomId}",
4139
+ pathParams: { ref: tripRef, roomId },
4140
+ body,
4141
+ headers: { "If-Match": String(version) },
4142
+ ...signal !== void 0 ? { signal } : {}
4143
+ });
4144
+ },
4145
+ async remove(options) {
4146
+ const { tripRef, roomId, version, force, signal } = options;
4147
+ return client.execute({
4148
+ method: "DELETE",
4149
+ operationId: OperationId.DeleteRoomingRoom,
4150
+ path: "/api/v1/trips/{ref}/rooming/rooms/{roomId}",
4151
+ pathParams: { ref: tripRef, roomId },
4152
+ query: { force },
4153
+ headers: { "If-Match": String(version) },
4154
+ ...signal !== void 0 ? { signal } : {}
4155
+ });
4156
+ }
4157
+ }
4158
+ };
4159
+ }
4160
+
4161
+ // src/resources/seating.ts
4162
+ function createSeatingResource(client) {
4163
+ return {
4164
+ async read(options) {
4165
+ const { tripRef, since, signal } = options;
4166
+ return client.execute({
4167
+ method: "GET",
4168
+ operationId: OperationId.ReadSeatingBoard,
4169
+ path: "/api/v1/trips/{ref}/seating",
4170
+ pathParams: { ref: tripRef },
4171
+ query: { since },
4172
+ ...signal !== void 0 ? { signal } : {}
4173
+ });
4174
+ },
4175
+ async assign(options) {
4176
+ const { tripRef, idempotencyKey, signal, ...body } = options;
4177
+ return client.execute({
4178
+ method: "POST",
4179
+ operationId: OperationId.AssignSeating,
4180
+ path: "/api/v1/trips/{ref}/seating/assign",
4181
+ pathParams: { ref: tripRef },
4182
+ body,
4183
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4184
+ ...signal !== void 0 ? { signal } : {}
4185
+ });
4186
+ },
4187
+ async autoAssign(options) {
4188
+ const { tripRef, idempotencyKey, signal, ...body } = options;
4189
+ return client.execute({
4190
+ method: "POST",
4191
+ operationId: OperationId.AutoAssignSeating,
4192
+ path: "/api/v1/trips/{ref}/seating/auto-assign",
4193
+ pathParams: { ref: tripRef },
4194
+ body,
4195
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4196
+ ...signal !== void 0 ? { signal } : {}
4197
+ });
4198
+ },
4199
+ vehicles: {
4200
+ async create(options) {
4201
+ const { tripRef, idempotencyKey, signal, ...body } = options;
4202
+ return client.execute({
4203
+ method: "POST",
4204
+ operationId: OperationId.CreateSeatingVehicle,
4205
+ path: "/api/v1/trips/{ref}/seating/vehicles",
4206
+ pathParams: { ref: tripRef },
4207
+ body,
4208
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4209
+ ...signal !== void 0 ? { signal } : {}
4210
+ });
4211
+ },
4212
+ async patch(options) {
4213
+ const { tripRef, vehicleId, version, signal, ...body } = options;
4214
+ return client.execute({
4215
+ method: "PATCH",
4216
+ operationId: OperationId.PatchSeatingVehicle,
4217
+ path: "/api/v1/trips/{ref}/seating/vehicles/{vehicleId}",
4218
+ pathParams: { ref: tripRef, vehicleId },
4219
+ body,
4220
+ headers: { "If-Match": String(version) },
4221
+ ...signal !== void 0 ? { signal } : {}
4222
+ });
4223
+ },
4224
+ async remove(options) {
4225
+ const { tripRef, vehicleId, version, signal } = options;
4226
+ return client.execute({
4227
+ method: "DELETE",
4228
+ operationId: OperationId.DeleteSeatingVehicle,
4229
+ path: "/api/v1/trips/{ref}/seating/vehicles/{vehicleId}",
4230
+ pathParams: { ref: tripRef, vehicleId },
4231
+ headers: { "If-Match": String(version) },
4232
+ ...signal !== void 0 ? { signal } : {}
4233
+ });
4234
+ },
4235
+ manager: {
4236
+ async link(options) {
4237
+ const { tripRef, vehicleId, idempotencyKey, signal, ...body } = options;
4238
+ return client.execute({
4239
+ method: "POST",
4240
+ operationId: OperationId.LinkSeatingManager,
4241
+ path: "/api/v1/trips/{ref}/seating/vehicles/{vehicleId}/manager",
4242
+ pathParams: { ref: tripRef, vehicleId },
4243
+ body,
4244
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4245
+ ...signal !== void 0 ? { signal } : {}
4246
+ });
4247
+ },
4248
+ async unlink(options) {
4249
+ const { tripRef, vehicleId, version, signal } = options;
4250
+ return client.execute({
4251
+ method: "DELETE",
4252
+ operationId: OperationId.UnlinkSeatingManager,
4253
+ path: "/api/v1/trips/{ref}/seating/vehicles/{vehicleId}/manager",
4254
+ pathParams: { ref: tripRef, vehicleId },
4255
+ headers: { "If-Match": String(version) },
4256
+ ...signal !== void 0 ? { signal } : {}
4257
+ });
4258
+ }
4259
+ }
4260
+ }
4261
+ };
4262
+ }
4263
+
4264
+ // src/resources/share.ts
4265
+ function createShareResource(client) {
4266
+ return {
4267
+ async snapshot(options) {
4268
+ const { token, signal } = options;
4269
+ return client.execute({
4270
+ method: "GET",
4271
+ operationId: OperationId.GetShareSnapshot,
4272
+ path: "/api/v1/share/{token}",
4273
+ pathParams: { token },
4274
+ ...signal !== void 0 ? { signal } : {}
4275
+ });
4276
+ },
4277
+ async manifest(options) {
4278
+ const { token, signal } = options;
4279
+ return client.execute({
4280
+ method: "GET",
4281
+ operationId: OperationId.GetShareManifest,
4282
+ path: "/api/v1/share/{token}/manifest",
4283
+ pathParams: { token },
4284
+ ...signal !== void 0 ? { signal } : {}
4285
+ });
4286
+ },
4287
+ forms: {
4288
+ async list(options) {
4289
+ const { token, signal } = options;
4290
+ return client.execute({
4291
+ method: "GET",
4292
+ operationId: OperationId.ShareListForms,
4293
+ path: "/api/v1/share/{token}/forms",
4294
+ pathParams: { token },
4295
+ ...signal !== void 0 ? { signal } : {}
4296
+ });
4297
+ },
4298
+ async render(options) {
4299
+ const { token, formId, travellerRef, signal } = options;
4300
+ return client.execute({
4301
+ method: "GET",
4302
+ operationId: OperationId.ShareRenderForm,
4303
+ path: "/api/v1/share/{token}/forms/{formId}",
4304
+ pathParams: { token, formId },
4305
+ query: { travellerRef },
4306
+ ...signal !== void 0 ? { signal } : {}
4307
+ });
4308
+ },
4309
+ async save(options) {
4310
+ const { token, formId, travellerRef, idempotencyKey, signal, ...body } = options;
4311
+ return client.execute({
4312
+ method: "POST",
4313
+ operationId: OperationId.ShareSaveForm,
4314
+ path: "/api/v1/share/{token}/forms/{formId}/save",
4315
+ pathParams: { token, formId },
4316
+ query: { travellerRef },
4317
+ body,
4318
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4319
+ ...signal !== void 0 ? { signal } : {}
4320
+ });
4321
+ },
4322
+ async submit(options) {
4323
+ const { token, formId, travellerRef, idempotencyKey, signal, ...body } = options;
4324
+ return client.execute({
4325
+ method: "POST",
4326
+ operationId: OperationId.ShareSubmitForm,
4327
+ path: "/api/v1/share/{token}/forms/{formId}/submit",
4328
+ pathParams: { token, formId },
4329
+ query: { travellerRef },
4330
+ body,
4331
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4332
+ ...signal !== void 0 ? { signal } : {}
4333
+ });
4334
+ }
4335
+ }
4336
+ };
4337
+ }
4338
+
4339
+ // src/resources/treks.ts
4340
+ var ACTIVE_TREK_REF = "active";
4341
+ function createTreksResource(client) {
4342
+ return {
4343
+ async board(options) {
4344
+ const { trekRef, signal } = options;
4345
+ return client.execute({
4346
+ method: "GET",
4347
+ operationId: OperationId.ReadTrekBoard,
4348
+ path: "/api/v1/treks/{trekRef}/board",
4349
+ pathParams: { trekRef },
4350
+ ...signal !== void 0 ? { signal } : {}
4351
+ });
4352
+ },
4353
+ async postpone(options) {
4354
+ const { trekRef, idempotencyKey, signal, newStartDate, newEndDate, ...rest } = options;
4355
+ const body = {
4356
+ ...rest,
4357
+ newStartDate: normalizeDateTimeInput(newStartDate, "newStartDate"),
4358
+ newEndDate: normalizeDateTimeInput(newEndDate, "newEndDate")
4359
+ };
4360
+ return client.execute({
4361
+ method: "POST",
4362
+ operationId: OperationId.PostponeTrek,
4363
+ path: "/api/v1/treks/{trekRef}/postpone",
4364
+ pathParams: { trekRef },
4365
+ body,
4366
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4367
+ ...signal !== void 0 ? { signal } : {}
4368
+ });
4369
+ },
4370
+ walkIns: {
4371
+ async meta(options) {
4372
+ const { trekRef, signal } = options;
4373
+ return client.execute({
4374
+ method: "GET",
4375
+ operationId: OperationId.ReadTrekWalkInMeta,
4376
+ path: "/api/v1/treks/{trekRef}/walk-ins/meta",
4377
+ pathParams: { trekRef },
4378
+ ...signal !== void 0 ? { signal } : {}
4379
+ });
4380
+ },
4381
+ async create(options) {
4382
+ const { trekRef, idempotencyKey, signal, ...body } = options;
4383
+ return client.execute({
4384
+ method: "POST",
4385
+ operationId: OperationId.CreateTrekWalkIn,
4386
+ path: "/api/v1/treks/{trekRef}/walk-ins",
4387
+ pathParams: { trekRef },
4388
+ body,
4389
+ ...idempotencyKey !== void 0 ? { idempotencyKey } : {},
4390
+ ...signal !== void 0 ? { signal } : {}
4391
+ });
4392
+ }
4393
+ }
4394
+ };
4395
+ }
4396
+
4397
+ // src/resources/vendors.ts
4398
+ function createVendorsResource(client) {
4399
+ return {
4400
+ async list(options) {
4401
+ const { tripRef, signal } = options;
4402
+ return client.execute({
4403
+ method: "GET",
4404
+ operationId: OperationId.ListTripVendors,
4405
+ path: "/api/v1/trips/{ref}/vendors",
4406
+ pathParams: { ref: tripRef },
4407
+ ...signal !== void 0 ? { signal } : {}
4408
+ });
4409
+ }
4410
+ };
4411
+ }
4412
+
4413
+ // src/generated/enums.ts
4414
+ var BoardStatus = {
4415
+ Boarded: "BOARDED",
4416
+ NoShow: "NO_SHOW"
4417
+ };
4418
+ var BookingStatus = {
4419
+ Confirmed: "CONFIRMED",
4420
+ Tentative: "TENTATIVE",
4421
+ Cancelled: "CANCELLED"
4422
+ };
4423
+ var ChecklistAudience = {
4424
+ Internal: "INTERNAL",
4425
+ External: "EXTERNAL"
4426
+ };
4427
+ var ChecklistGate = {
4428
+ None: "NONE",
4429
+ PreToActive: "PRE_TO_ACTIVE",
4430
+ ActiveToClosedOut: "ACTIVE_TO_CLOSED_OUT"
4431
+ };
4432
+ var ChecklistItemStatus = {
4433
+ Open: "OPEN",
4434
+ Complete: "COMPLETE"
4435
+ };
4436
+ var ChecklistPhase = {
4437
+ PreDeparture: "PRE_DEPARTURE",
4438
+ InTrip: "IN_TRIP",
4439
+ PostTrip: "POST_TRIP"
4440
+ };
4441
+ var ChecklistPullTemplateMode = {
4442
+ Append: "append",
4443
+ Replace: "replace"
4444
+ };
4445
+ var ClaimStatusIngest = {
4446
+ Approved: "APPROVED",
4447
+ Paid: "PAID",
4448
+ Rejected: "REJECTED"
4449
+ };
4450
+ var CloseoutPackSection = {
4451
+ Summary: "summary",
4452
+ Blockers: "blockers",
4453
+ Handover: "handover",
4454
+ Collections: "collections",
4455
+ Expenses: "expenses",
4456
+ Float: "float",
4457
+ Checklists: "checklists",
4458
+ Forms: "forms",
4459
+ Rooming: "rooming",
4460
+ Seating: "seating",
4461
+ Pickups: "pickups",
4462
+ Vendors: "vendors",
4463
+ Itinerary: "itinerary"
4464
+ };
4465
+ var CollectionMode = {
4466
+ Cash: "CASH",
4467
+ Upi: "UPI",
4468
+ Card: "CARD",
4469
+ Bank: "BANK"
4470
+ };
4471
+ var Currency = {
4472
+ Inr: "INR"
4473
+ };
4474
+ var EventType = {
4475
+ Trip: "TRIP",
4476
+ Trek: "TREK"
4477
+ };
4478
+ var ExpenseCategory = {
4479
+ Accom: "ACCOM",
4480
+ Food: "FOOD",
4481
+ Transport: "TRANSPORT",
4482
+ Activity: "ACTIVITY",
4483
+ Misc: "MISC"
4484
+ };
4485
+ var ExpensePaymentMode = {
4486
+ FloatCash: "FLOAT_CASH",
4487
+ Personal: "PERSONAL",
4488
+ Other: "OTHER"
4489
+ };
4490
+ var FileContentType = {
4491
+ ImageJpeg: "image/jpeg",
4492
+ ImagePng: "image/png",
4493
+ ImageWebp: "image/webp",
4494
+ ImageHeic: "image/heic",
4495
+ ApplicationPdf: "application/pdf"
4496
+ };
4497
+ var FilePurpose = {
4498
+ ExpenseReceipt: "expense_receipt",
4499
+ FormAttachment: "form_attachment",
4500
+ BookingVoucher: "booking_voucher"
4501
+ };
4502
+ var FloatDirection = {
4503
+ In: "IN",
4504
+ Out: "OUT"
4505
+ };
4506
+ var Gender = {
4507
+ Male: "MALE",
4508
+ Female: "FEMALE",
4509
+ Other: "OTHER",
4510
+ Unknown: "UNKNOWN"
4511
+ };
4512
+ var ItineraryItemStatusUpdate = {
4513
+ Planned: "PLANNED",
4514
+ Completed: "COMPLETED",
4515
+ Skipped: "SKIPPED"
4516
+ };
4517
+ var ItineraryItemType = {
4518
+ Accommodation: "ACCOMMODATION",
4519
+ Transport: "TRANSPORT",
4520
+ Activity: "ACTIVITY",
4521
+ Meal: "MEAL",
4522
+ Other: "OTHER"
4523
+ };
4524
+ var ManagerRole = {
4525
+ Manager: "MANAGER",
4526
+ Coordinator: "COORDINATOR"
4527
+ };
1510
4528
  var ManifestMode = {
1511
4529
  Merge: "merge",
1512
4530
  Replace: "replace"
@@ -1518,6 +4536,59 @@ var PartyKind = {
1518
4536
  Corporate: "CORPORATE",
1519
4537
  Other: "OTHER"
1520
4538
  };
4539
+ var PickupKind = {
4540
+ Pickup: "PICKUP",
4541
+ Drop: "DROP"
4542
+ };
4543
+ var RoomingFillOrder = {
4544
+ LargestRoomFirst: "LARGEST_ROOM_FIRST",
4545
+ Sequential: "SEQUENTIAL",
4546
+ Balanced: "BALANCED"
4547
+ };
4548
+ var RoomingGenderPolicy = {
4549
+ StrictSeparate: "STRICT_SEPARATE",
4550
+ GroupMixedOk: "GROUP_MIXED_OK",
4551
+ Off: "OFF"
4552
+ };
4553
+ var RoomingHeuristicKey = {
4554
+ MedicalFirst: "medicalFirst",
4555
+ Couples: "couples",
4556
+ Parties: "parties",
4557
+ Gender: "gender",
4558
+ Diet: "diet",
4559
+ SpreadSolos: "spreadSolos",
4560
+ PartyGenderPolicy: "partyGenderPolicy",
4561
+ SameBus: "sameBus"
4562
+ };
4563
+ var RoomType = {
4564
+ Single: "SINGLE",
4565
+ Twin: "TWIN",
4566
+ Shared: "SHARED",
4567
+ Dorm: "DORM"
4568
+ };
4569
+ var SeatingFillOrder = {
4570
+ Balanced: "BALANCED",
4571
+ FillFirst: "FILL_FIRST",
4572
+ ByStop: "BY_STOP"
4573
+ };
4574
+ var SeatingGenderAdjacency = {
4575
+ Off: "OFF",
4576
+ AvoidUnrelated: "AVOID_UNRELATED",
4577
+ StrictRows: "STRICT_ROWS"
4578
+ };
4579
+ var SeatingHeuristicKey = {
4580
+ MedicalFirst: "medicalFirst",
4581
+ Parties: "parties",
4582
+ SameStop: "sameStop",
4583
+ Gender: "gender",
4584
+ BalanceVehicles: "balanceVehicles"
4585
+ };
4586
+ var SyncOpMethod = {
4587
+ Post: "POST",
4588
+ Patch: "PATCH",
4589
+ Put: "PUT",
4590
+ Delete: "DELETE"
4591
+ };
1521
4592
  var TriggerAnchor = {
1522
4593
  Start: "START",
1523
4594
  End: "END"
@@ -1533,6 +4604,19 @@ var TripStatus = {
1533
4604
  Postponed: "POSTPONED",
1534
4605
  Cancelled: "CANCELLED"
1535
4606
  };
4607
+ var VehicleLayout = {
4608
+ TwoTwo: "TWO_TWO",
4609
+ TwoOne: "TWO_ONE",
4610
+ Flat: "FLAT"
4611
+ };
4612
+ var VehicleType = {
4613
+ Bus: "BUS",
4614
+ TempoTraveller: "TEMPO_TRAVELLER",
4615
+ Car: "CAR",
4616
+ Flight: "FLIGHT",
4617
+ Train: "TRAIN",
4618
+ Other: "OTHER"
4619
+ };
1536
4620
 
1537
4621
  // src/pagination/paginator.ts
1538
4622
  var KaafilPaginationError = class extends Error {
@@ -1556,6 +4640,200 @@ var KaafilPaginationExhaustedError = class _KaafilPaginationExhaustedError exten
1556
4640
  }
1557
4641
  };
1558
4642
 
4643
+ // src/rooming/vocabulary.ts
4644
+ var HEURISTIC_SEVERITY = Object.freeze({
4645
+ medicalFirst: "warn",
4646
+ couples: "warn",
4647
+ parties: "split",
4648
+ gender: "never",
4649
+ diet: "info",
4650
+ spreadSolos: "info",
4651
+ partyGenderPolicy: "info",
4652
+ sameBus: "info"
4653
+ });
4654
+ function isRoomingHeuristicKey(rule) {
4655
+ return Object.hasOwn(HEURISTIC_SEVERITY, rule);
4656
+ }
4657
+ function roomingHeuristicSeverity(rule) {
4658
+ return isRoomingHeuristicKey(rule) ? HEURISTIC_SEVERITY[rule] : void 0;
4659
+ }
4660
+ var TONE_FAMILIES = Object.freeze({
4661
+ [Gender.Male]: "male",
4662
+ [Gender.Female]: "female",
4663
+ [Gender.Other]: "other",
4664
+ [Gender.Unknown]: "unknown"
4665
+ });
4666
+ var UNKNOWN_TONE_FAMILY = TONE_FAMILIES[Gender.Unknown];
4667
+ var SHADES_PER_FAMILY = 8;
4668
+ var FALLBACK_GLYPH = "?";
4669
+ function parseRoomingTone(tone) {
4670
+ const separator = tone.lastIndexOf(".");
4671
+ if (separator <= 0 || separator === tone.length - 1) {
4672
+ return void 0;
4673
+ }
4674
+ const family = tone.slice(0, separator);
4675
+ const rawShade = tone.slice(separator + 1);
4676
+ const shade = Number(rawShade);
4677
+ if (!Number.isInteger(shade) || shade < 0) {
4678
+ return void 0;
4679
+ }
4680
+ return { family, shade };
4681
+ }
4682
+
4683
+ // src/storage/adapter.ts
4684
+ function createInMemoryStorageAdapter() {
4685
+ const store = /* @__PURE__ */ new Map();
4686
+ return {
4687
+ async get(key) {
4688
+ return store.get(key);
4689
+ },
4690
+ async set(key, value) {
4691
+ store.set(key, value);
4692
+ },
4693
+ async remove(key) {
4694
+ store.delete(key);
4695
+ },
4696
+ async clear() {
4697
+ store.clear();
4698
+ }
4699
+ };
4700
+ }
4701
+
4702
+ // src/storage/indexeddb.ts
4703
+ var STORE_NAME = "kv";
4704
+ var DEFAULT_DATABASE_PREFIX = "kaafil-js";
4705
+ var SCHEMA_VERSION = 1;
4706
+ var KaafilIndexedDbUnavailableError = class _KaafilIndexedDbUnavailableError extends Error {
4707
+ reason;
4708
+ constructor(reason, detail) {
4709
+ super(
4710
+ `IndexedDB is not usable in this runtime (${reason})${detail !== void 0 ? `: ${detail}` : ""}. No durable offline store was created. Supply your own KaafilStorageAdapter, or use createInMemoryStorageAdapter() and treat queued writes as process-lifetime only.`
4711
+ );
4712
+ this.name = "KaafilIndexedDbUnavailableError";
4713
+ Object.setPrototypeOf(this, _KaafilIndexedDbUnavailableError.prototype);
4714
+ this.reason = reason;
4715
+ }
4716
+ };
4717
+ function promisifyRequest(request) {
4718
+ return new Promise((resolve, reject) => {
4719
+ request.onsuccess = () => {
4720
+ resolve(request.result);
4721
+ };
4722
+ request.onerror = () => {
4723
+ reject(request.error ?? new Error("IndexedDB request failed with no error attached"));
4724
+ };
4725
+ });
4726
+ }
4727
+ async function openDatabase(factory, databaseName) {
4728
+ return new Promise((resolve, reject) => {
4729
+ let request;
4730
+ try {
4731
+ request = factory.open(databaseName, SCHEMA_VERSION);
4732
+ } catch (error) {
4733
+ reject(
4734
+ new KaafilIndexedDbUnavailableError(
4735
+ "open-failed",
4736
+ error instanceof Error ? error.message : String(error)
4737
+ )
4738
+ );
4739
+ return;
4740
+ }
4741
+ request.onupgradeneeded = () => {
4742
+ const db = request.result;
4743
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
4744
+ db.createObjectStore(STORE_NAME);
4745
+ }
4746
+ };
4747
+ request.onsuccess = () => {
4748
+ const db = request.result;
4749
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
4750
+ db.close();
4751
+ reject(new KaafilIndexedDbUnavailableError("open-failed", "object store missing"));
4752
+ return;
4753
+ }
4754
+ resolve(db);
4755
+ };
4756
+ request.onerror = () => {
4757
+ reject(
4758
+ new KaafilIndexedDbUnavailableError(
4759
+ "open-failed",
4760
+ request.error?.message ?? "open request failed"
4761
+ )
4762
+ );
4763
+ };
4764
+ request.onblocked = () => {
4765
+ reject(new KaafilIndexedDbUnavailableError("blocked"));
4766
+ };
4767
+ });
4768
+ }
4769
+ async function createIndexedDbStorageAdapter(options) {
4770
+ if (typeof options.scope !== "string" || options.scope.length === 0) {
4771
+ throw new TypeError(
4772
+ `"scope" is required and must be a non-empty string \u2014 an unscoped offline store lets one credential's queued writes drain under another's session.`
4773
+ );
4774
+ }
4775
+ const factory = options.indexedDB ?? globalThis.indexedDB;
4776
+ if (factory === void 0 || factory === null) {
4777
+ throw new KaafilIndexedDbUnavailableError("no-indexeddb");
4778
+ }
4779
+ const databaseName = `${options.databasePrefix ?? DEFAULT_DATABASE_PREFIX}:${options.scope}`;
4780
+ const db = await openDatabase(factory, databaseName);
4781
+ const onQuotaExceeded = options.onQuotaExceeded;
4782
+ async function write(run) {
4783
+ return new Promise((resolve, reject) => {
4784
+ let tx;
4785
+ try {
4786
+ tx = db.transaction(STORE_NAME, "readwrite");
4787
+ } catch (error) {
4788
+ reject(error);
4789
+ return;
4790
+ }
4791
+ tx.oncomplete = () => {
4792
+ resolve();
4793
+ };
4794
+ const fail = (error) => {
4795
+ if (error instanceof DOMException && error.name === "QuotaExceededError") {
4796
+ onQuotaExceeded?.(error);
4797
+ }
4798
+ reject(error ?? new Error("IndexedDB transaction failed with no error attached"));
4799
+ };
4800
+ tx.onerror = () => {
4801
+ fail(tx.error);
4802
+ };
4803
+ tx.onabort = () => {
4804
+ fail(tx.error);
4805
+ };
4806
+ try {
4807
+ run(tx.objectStore(STORE_NAME));
4808
+ } catch (error) {
4809
+ fail(error);
4810
+ }
4811
+ });
4812
+ }
4813
+ return {
4814
+ async get(key) {
4815
+ const tx = db.transaction(STORE_NAME, "readonly");
4816
+ const value = await promisifyRequest(tx.objectStore(STORE_NAME).get(key));
4817
+ return typeof value === "string" ? value : void 0;
4818
+ },
4819
+ async set(key, value) {
4820
+ await write((store) => {
4821
+ store.put(value, key);
4822
+ });
4823
+ },
4824
+ async remove(key) {
4825
+ await write((store) => {
4826
+ store.delete(key);
4827
+ });
4828
+ },
4829
+ async clear() {
4830
+ await write((store) => {
4831
+ store.clear();
4832
+ });
4833
+ }
4834
+ };
4835
+ }
4836
+
1559
4837
  // src/client-entry.ts
1560
4838
  function openTokenField(input) {
1561
4839
  switch (input.kind) {
@@ -1646,11 +4924,31 @@ var KaafilClient = class {
1646
4924
  this.#open({ kind: "agencyAdmin", ...options });
1647
4925
  }
1648
4926
  };
4927
+ /**
4928
+ * `open` mints the session; every other member proxies straight through
4929
+ * to the opened session's `ShareResource` (`./resources/share.ts`) — kept
4930
+ * on this ONE `share` object, rather than `open` here and the six read/
4931
+ * write methods on a sibling getter, because `client.share.open({ token
4932
+ * })` then `client.share.snapshot(...)` reads as one surface a caller
4933
+ * opens and then calls, not two same-named things that happen to collide.
4934
+ * Every member past `open` throws `KaafilClientNotOpenError` before a
4935
+ * session is open, and `UnsatisfiableSchemeError` if the open session is
4936
+ * a `managerSession`/`agencyAdmin` one — see `KaafilClientState.share`'s
4937
+ * own doc.
4938
+ */
1649
4939
  share = {
1650
4940
  /** Opens a read-only session with a share token minted server-side by
1651
4941
  * `kaafil.shareTokens.create(...)`. */
1652
4942
  open: (options) => {
1653
4943
  this.#open({ kind: "shareToken", ...options });
4944
+ },
4945
+ snapshot: (options) => this.#requireState().share.snapshot(options),
4946
+ manifest: (options) => this.#requireState().share.manifest(options),
4947
+ forms: {
4948
+ list: (options) => this.#requireState().share.forms.list(options),
4949
+ render: (options) => this.#requireState().share.forms.render(options),
4950
+ save: (options) => this.#requireState().share.forms.save(options),
4951
+ submit: (options) => this.#requireState().share.forms.submit(options)
1654
4952
  }
1655
4953
  };
1656
4954
  get vendors() {
@@ -1659,6 +4957,80 @@ var KaafilClient = class {
1659
4957
  get journey() {
1660
4958
  return this.#requireState().journey;
1661
4959
  }
4960
+ get notifications() {
4961
+ return this.#requireState().notifications;
4962
+ }
4963
+ get itinerary() {
4964
+ return this.#requireState().itinerary;
4965
+ }
4966
+ get rooming() {
4967
+ return this.#requireState().rooming;
4968
+ }
4969
+ get seating() {
4970
+ return this.#requireState().seating;
4971
+ }
4972
+ get pickups() {
4973
+ return this.#requireState().pickups;
4974
+ }
4975
+ get treks() {
4976
+ return this.#requireState().treks;
4977
+ }
4978
+ get checklists() {
4979
+ return this.#requireState().checklists;
4980
+ }
4981
+ get float() {
4982
+ return this.#requireState().float;
4983
+ }
4984
+ get expenses() {
4985
+ return this.#requireState().expenses;
4986
+ }
4987
+ get collections() {
4988
+ return this.#requireState().collections;
4989
+ }
4990
+ get files() {
4991
+ return this.#requireState().files;
4992
+ }
4993
+ get closeout() {
4994
+ return this.#requireState().closeout;
4995
+ }
4996
+ get sync() {
4997
+ return this.#requireState().sync;
4998
+ }
4999
+ /**
5000
+ * Builds the offline layer on top of THIS open session — the durable
5001
+ * snapshot + outbox, the FIFO drainer, the reconciler, the blob lane and
5002
+ * the batched transport (`06-offline-first.md`).
5003
+ *
5004
+ * The transport is assembled here rather than by the caller, so the
5005
+ * automatic parts stay automatic: the op's fixed idempotency key, the
5006
+ * `If-Match` header, the single-vs-batched wire switch and the consolidated
5007
+ * pull are all wired from the session's own `KaafilHttpClient` and `sync`
5008
+ * resource. What the caller supplies is what only the caller can know — a
5009
+ * durable `storage` adapter for its platform, a `scope` for this
5010
+ * credential, optionally an entity re-reader for conflict reconciliation,
5011
+ * and optionally a conflict resolver (with none, every `409` surfaces,
5012
+ * which is the correct default: `06 §6` forbids auto-merging).
5013
+ *
5014
+ * Throws `KaafilClientNotOpenError` before a session is open — there is no
5015
+ * offline layer without a credential to scope it to.
5016
+ */
5017
+ openOffline(options) {
5018
+ const state = this.#requireState();
5019
+ const transport = createHttpOfflineTransport({
5020
+ http: state.http,
5021
+ sync: state.sync,
5022
+ ...options.readEntity !== void 0 ? { readEntity: options.readEntity } : {},
5023
+ ...options.share !== void 0 ? { credential: "share" } : {}
5024
+ });
5025
+ return createOfflineEngine({
5026
+ storage: options.storage,
5027
+ scope: options.scope,
5028
+ transport,
5029
+ ...options.conflictResolver !== void 0 ? { conflictResolver: options.conflictResolver } : {},
5030
+ ...options.blob !== void 0 ? { blob: options.blob } : {},
5031
+ ...options.share !== void 0 ? { share: options.share } : {}
5032
+ });
5033
+ }
1662
5034
  /**
1663
5035
  * Total teardown. One assignment, no field to forget — see
1664
5036
  * `KaafilClientState` above. Safe to call whether or not a session is
@@ -1725,7 +5097,21 @@ var KaafilClient = class {
1725
5097
  this.#state = {
1726
5098
  http,
1727
5099
  vendors: createVendorsResource(http),
1728
- journey: createJourneyResource(http)
5100
+ journey: createJourneyResource(http),
5101
+ share: createShareResource(http),
5102
+ notifications: createNotificationsResource(http),
5103
+ itinerary: createItineraryResource(http),
5104
+ rooming: createRoomingResource(http),
5105
+ seating: createSeatingResource(http),
5106
+ pickups: createPickupsResource(http),
5107
+ treks: createTreksResource(http),
5108
+ checklists: createChecklistsResource(http),
5109
+ float: createFloatResource(http),
5110
+ expenses: createExpensesResource(http),
5111
+ collections: createCollectionsResource(http),
5112
+ files: createFilesResource(http),
5113
+ closeout: createCloseoutResource(http),
5114
+ sync: createSyncResource(http)
1729
5115
  };
1730
5116
  }
1731
5117
  #requireState() {
@@ -1736,20 +5122,44 @@ var KaafilClient = class {
1736
5122
  }
1737
5123
  };
1738
5124
 
5125
+ exports.ACTIVE_TREK_REF = ACTIVE_TREK_REF;
5126
+ exports.BATCH_THRESHOLD_OPS = BATCH_THRESHOLD_OPS;
5127
+ exports.BlobStatus = BlobStatus;
5128
+ exports.BoardStatus = BoardStatus;
1739
5129
  exports.BookingStatus = BookingStatus;
5130
+ exports.CONSOLIDATED_PULL_THRESHOLD_LISTS = CONSOLIDATED_PULL_THRESHOLD_LISTS;
5131
+ exports.ChecklistAudience = ChecklistAudience;
5132
+ exports.ChecklistGate = ChecklistGate;
5133
+ exports.ChecklistItemStatus = ChecklistItemStatus;
5134
+ exports.ChecklistPhase = ChecklistPhase;
5135
+ exports.ChecklistPullTemplateMode = ChecklistPullTemplateMode;
1740
5136
  exports.ClaimStatusIngest = ClaimStatusIngest;
5137
+ exports.CloseoutPackSection = CloseoutPackSection;
5138
+ exports.CollectionMode = CollectionMode;
5139
+ exports.Currency = Currency;
1741
5140
  exports.ERROR_CODE_TABLE = ERROR_CODE_TABLE;
1742
5141
  exports.EventType = EventType;
5142
+ exports.ExpenseCategory = ExpenseCategory;
5143
+ exports.ExpensePaymentMode = ExpensePaymentMode;
5144
+ exports.FALLBACK_GLYPH = FALLBACK_GLYPH;
5145
+ exports.FileContentType = FileContentType;
5146
+ exports.FilePurpose = FilePurpose;
5147
+ exports.FloatDirection = FloatDirection;
1743
5148
  exports.Gender = Gender;
5149
+ exports.HEURISTIC_SEVERITY = HEURISTIC_SEVERITY;
5150
+ exports.ItineraryItemStatusUpdate = ItineraryItemStatusUpdate;
5151
+ exports.ItineraryItemType = ItineraryItemType;
1744
5152
  exports.KaafilAbortError = KaafilAbortError;
1745
5153
  exports.KaafilApiError = KaafilApiError;
1746
5154
  exports.KaafilCapabilityUnavailableError = KaafilCapabilityUnavailableError;
1747
5155
  exports.KaafilClient = KaafilClient;
1748
5156
  exports.KaafilClientAlreadyOpenError = KaafilClientAlreadyOpenError;
1749
5157
  exports.KaafilClientNotOpenError = KaafilClientNotOpenError;
5158
+ exports.KaafilDeltaCursorInFlightError = KaafilDeltaCursorInFlightError;
1750
5159
  exports.KaafilEntitlementError = KaafilEntitlementError;
1751
5160
  exports.KaafilError = KaafilError;
1752
5161
  exports.KaafilErrorCode = KaafilErrorCode;
5162
+ exports.KaafilIndexedDbUnavailableError = KaafilIndexedDbUnavailableError;
1753
5163
  exports.KaafilInvalidRequestError = KaafilInvalidRequestError;
1754
5164
  exports.KaafilLockedError = KaafilLockedError;
1755
5165
  exports.KaafilNetworkError = KaafilNetworkError;
@@ -1760,6 +5170,8 @@ exports.KaafilPaginationExhaustedError = KaafilPaginationExhaustedError;
1760
5170
  exports.KaafilPaginationInFlightError = KaafilPaginationInFlightError;
1761
5171
  exports.KaafilRateLimitedError = KaafilRateLimitedError;
1762
5172
  exports.KaafilReadOnlyRoleError = KaafilReadOnlyRoleError;
5173
+ exports.KaafilShareBatchUnauthenticatedError = KaafilShareBatchUnauthenticatedError;
5174
+ exports.KaafilShareLinkExpiredError = KaafilShareLinkExpiredError;
1763
5175
  exports.KaafilShareTokenExpiredError = KaafilShareTokenExpiredError;
1764
5176
  exports.KaafilShareTokenRevokedError = KaafilShareTokenRevokedError;
1765
5177
  exports.KaafilTimeoutError = KaafilTimeoutError;
@@ -1767,16 +5179,57 @@ exports.KaafilTransportError = KaafilTransportError;
1767
5179
  exports.KaafilUnauthenticatedError = KaafilUnauthenticatedError;
1768
5180
  exports.KaafilValidationError = KaafilValidationError;
1769
5181
  exports.KaafilVersionConflictError = KaafilVersionConflictError;
5182
+ exports.MAX_BATCH_OPS = MAX_BATCH_OPS;
1770
5183
  exports.ManagerRole = ManagerRole;
1771
5184
  exports.ManifestMode = ManifestMode;
1772
5185
  exports.OutboxClass = OutboxClass;
5186
+ exports.OutboxStatus = OutboxStatus;
1773
5187
  exports.PartyKind = PartyKind;
5188
+ exports.PickupKind = PickupKind;
1774
5189
  exports.Retryability = Retryability;
5190
+ exports.RoomType = RoomType;
5191
+ exports.RoomingFillOrder = RoomingFillOrder;
5192
+ exports.RoomingGenderPolicy = RoomingGenderPolicy;
5193
+ exports.RoomingHeuristicKey = RoomingHeuristicKey;
5194
+ exports.SHADES_PER_FAMILY = SHADES_PER_FAMILY;
5195
+ exports.SHARE_WRITE_GRACE_MS = SHARE_WRITE_GRACE_MS;
5196
+ exports.SYNC_PULL_SECTIONS = SYNC_PULL_SECTIONS;
5197
+ exports.SeatingFillOrder = SeatingFillOrder;
5198
+ exports.SeatingGenderAdjacency = SeatingGenderAdjacency;
5199
+ exports.SeatingHeuristicKey = SeatingHeuristicKey;
5200
+ exports.SyncOpMethod = SyncOpMethod;
5201
+ exports.TONE_FAMILIES = TONE_FAMILIES;
1775
5202
  exports.TriggerAnchor = TriggerAnchor;
1776
5203
  exports.TripMode = TripMode;
1777
5204
  exports.TripStatus = TripStatus;
5205
+ exports.UNKNOWN_TONE_FAMILY = UNKNOWN_TONE_FAMILY;
1778
5206
  exports.UnsatisfiableSchemeError = UnsatisfiableSchemeError;
5207
+ exports.VehicleLayout = VehicleLayout;
5208
+ exports.VehicleType = VehicleType;
5209
+ exports.createBlobLane = createBlobLane;
5210
+ exports.createDeltaCursor = createDeltaCursor;
5211
+ exports.createDrainer = createDrainer;
5212
+ exports.createHttpOfflineTransport = createHttpOfflineTransport;
5213
+ exports.createInMemoryStorageAdapter = createInMemoryStorageAdapter;
5214
+ exports.createIndexedDbStorageAdapter = createIndexedDbStorageAdapter;
5215
+ exports.createOfflineEngine = createOfflineEngine;
5216
+ exports.createOfflineEvents = createOfflineEvents;
5217
+ exports.createOutbox = createOutbox;
5218
+ exports.createPullCoordinator = createPullCoordinator;
5219
+ exports.createShareGuard = createShareGuard;
5220
+ exports.createSnapshotStore = createSnapshotStore;
5221
+ exports.createSyncResource = createSyncResource;
5222
+ exports.extractSectionRows = extractSectionRows;
1779
5223
  exports.isKaafilError = isKaafilError;
1780
5224
  exports.isRetryable = isRetryable;
5225
+ exports.isRoomingHeuristicKey = isRoomingHeuristicKey;
5226
+ exports.isShareBatchPushAvailable = isShareBatchPushAvailable;
5227
+ exports.isTombstone = isTombstone;
5228
+ exports.mergeDeltaRows = mergeDeltaRows;
5229
+ exports.parseRoomingTone = parseRoomingTone;
5230
+ exports.readCurrentVersion = readCurrentVersion;
5231
+ exports.reconcileConflict = reconcileConflict;
5232
+ exports.roomingHeuristicSeverity = roomingHeuristicSeverity;
5233
+ exports.shouldUseBatchTransport = shouldUseBatchTransport;
1781
5234
  //# sourceMappingURL=client-entry.cjs.map
1782
5235
  //# sourceMappingURL=client-entry.cjs.map