@devrev/ts-adaas 1.19.4 → 1.19.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/attachments-streaming/attachments-streaming-pool.test.js +3 -6
  2. package/dist/common/event-type-translation.test.d.ts +2 -0
  3. package/dist/common/event-type-translation.test.d.ts.map +1 -0
  4. package/dist/common/event-type-translation.test.js +175 -0
  5. package/dist/common/time-value-resolver.test.js +0 -1
  6. package/dist/multithreading/create-worker.test.js +34 -16
  7. package/dist/multithreading/process-task.test.d.ts +2 -0
  8. package/dist/multithreading/process-task.test.d.ts.map +1 -0
  9. package/dist/multithreading/process-task.test.js +166 -0
  10. package/dist/multithreading/spawn/spawn.test.d.ts +2 -0
  11. package/dist/multithreading/spawn/spawn.test.d.ts.map +1 -0
  12. package/dist/multithreading/spawn/spawn.test.js +223 -0
  13. package/dist/multithreading/worker-adapter/worker-adapter.emit.test.d.ts +2 -0
  14. package/dist/multithreading/worker-adapter/worker-adapter.emit.test.d.ts.map +1 -0
  15. package/dist/multithreading/worker-adapter/worker-adapter.emit.test.js +415 -0
  16. package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.d.ts +2 -0
  17. package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.d.ts.map +1 -0
  18. package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.js +801 -0
  19. package/dist/multithreading/worker-adapter/worker-adapter.loading.test.d.ts +2 -0
  20. package/dist/multithreading/worker-adapter/worker-adapter.loading.test.d.ts.map +1 -0
  21. package/dist/multithreading/worker-adapter/worker-adapter.loading.test.js +598 -0
  22. package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.d.ts +2 -0
  23. package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.d.ts.map +1 -0
  24. package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.js +71 -0
  25. package/dist/repo/repo.test.js +41 -0
  26. package/dist/state/state.extract-window.test.d.ts +2 -0
  27. package/dist/state/state.extract-window.test.d.ts.map +1 -0
  28. package/dist/state/state.extract-window.test.js +163 -0
  29. package/dist/state/state.pending-boundaries.test.d.ts +2 -0
  30. package/dist/state/state.pending-boundaries.test.d.ts.map +1 -0
  31. package/dist/state/state.pending-boundaries.test.js +189 -0
  32. package/dist/state/state.post-state.test.d.ts +2 -0
  33. package/dist/state/state.post-state.test.d.ts.map +1 -0
  34. package/dist/state/state.post-state.test.js +77 -0
  35. package/dist/state/state.test.js +23 -506
  36. package/dist/state/state.time-value-resolution.test.d.ts +2 -0
  37. package/dist/state/state.time-value-resolution.test.d.ts.map +1 -0
  38. package/dist/state/state.time-value-resolution.test.js +175 -0
  39. package/dist/types/extraction.test.js +57 -21
  40. package/dist/uploader/uploader.helpers.test.js +0 -11
  41. package/dist/uploader/uploader.test.js +0 -9
  42. package/package.json +7 -6
  43. package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts +0 -2
  44. package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts.map +0 -1
  45. package/dist/multithreading/worker-adapter/worker-adapter.test.js +0 -1243
@@ -41,7 +41,7 @@ describe(state_1.State.name, () => {
41
41
  expect(postStateSpy).not.toHaveBeenCalled();
42
42
  expect(installInitialDomainMappingSpy).not.toHaveBeenCalled();
43
43
  });
44
- it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if fetching the state fails', async (eventType) => {
44
+ it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if fetching the state fails for event type %s', async (eventType) => {
45
45
  // Arrange
46
46
  const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
47
47
  payload: { event_type: eventType },
@@ -50,7 +50,6 @@ describe(state_1.State.name, () => {
50
50
  isAxiosError: true,
51
51
  response: { status: 500 },
52
52
  });
53
- jest.spyOn(console, 'error').mockImplementation(() => { });
54
53
  // Act & Assert
55
54
  await expect((0, state_1.createAdapterState)({
56
55
  event,
@@ -59,13 +58,12 @@ describe(state_1.State.name, () => {
59
58
  })).rejects.toThrow('process.exit called');
60
59
  expect(processExitSpy).toHaveBeenCalledWith(1);
61
60
  });
62
- it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if parsing the state fails', async (eventType) => {
61
+ it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if parsing the state fails for event type %s', async (eventType) => {
63
62
  // Arrange
64
63
  const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
65
64
  payload: { event_type: eventType },
66
65
  });
67
66
  fetchStateSpy.mockResolvedValue({ state: 'invalid-json' });
68
- jest.spyOn(console, 'error').mockImplementation(() => { });
69
67
  // Act & Assert
70
68
  await expect((0, state_1.createAdapterState)({
71
69
  event,
@@ -74,13 +72,12 @@ describe(state_1.State.name, () => {
74
72
  })).rejects.toThrow('process.exit called');
75
73
  expect(processExitSpy).toHaveBeenCalledWith(1);
76
74
  });
77
- it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if fetching is successful but there is no state in the response', async (eventType) => {
75
+ it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if fetching is successful but there is no state in the response for event type %s', async (eventType) => {
78
76
  // Arrange
79
77
  const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
80
78
  payload: { event_type: eventType },
81
79
  });
82
80
  fetchStateSpy.mockResolvedValue({ state: null });
83
- jest.spyOn(console, 'error').mockImplementation(() => { });
84
81
  // Act & Assert
85
82
  await expect((0, state_1.createAdapterState)({
86
83
  event,
@@ -110,7 +107,6 @@ describe(state_1.State.name, () => {
110
107
  postStateSpy.mockResolvedValue({
111
108
  success: true,
112
109
  });
113
- jest.spyOn(console, 'log').mockImplementation(() => { });
114
110
  // Act
115
111
  await (0, state_1.createAdapterState)({
116
112
  event,
@@ -141,7 +137,6 @@ describe(state_1.State.name, () => {
141
137
  postStateSpy.mockResolvedValue({
142
138
  success: true,
143
139
  });
144
- jest.spyOn(console, 'log').mockImplementation(() => { });
145
140
  // Act
146
141
  await (0, state_1.createAdapterState)({
147
142
  event,
@@ -165,8 +160,6 @@ describe(state_1.State.name, () => {
165
160
  test: 'test',
166
161
  }),
167
162
  });
168
- jest.spyOn(console, 'log').mockImplementation(() => { });
169
- jest.spyOn(console, 'error').mockImplementation(() => { });
170
163
  // Act & Assert
171
164
  await expect((0, state_1.createAdapterState)({
172
165
  event,
@@ -188,7 +181,6 @@ describe(state_1.State.name, () => {
188
181
  snapInVersionId: '1.0.0',
189
182
  });
190
183
  fetchStateSpy.mockResolvedValue({ state: stringifiedState });
191
- jest.spyOn(console, 'log').mockImplementation(() => { });
192
184
  // Act & Assert
193
185
  await (0, state_1.createAdapterState)({
194
186
  event,
@@ -214,7 +206,6 @@ describe(state_1.State.name, () => {
214
206
  installInitialDomainMappingSpy.mockResolvedValue({
215
207
  success: true,
216
208
  });
217
- jest.spyOn(console, 'log').mockImplementation(() => { });
218
209
  // Act
219
210
  await (0, state_1.createAdapterState)({
220
211
  event,
@@ -224,498 +215,6 @@ describe(state_1.State.name, () => {
224
215
  // Assert
225
216
  expect(installInitialDomainMappingSpy).toHaveBeenCalled();
226
217
  });
227
- describe('Enhanced Control Protocol - TimeValue resolution failures', () => {
228
- it('should exit the process if extraction_start_time resolution fails', async () => {
229
- // Arrange: WORKERS_NEWEST type but state has no workersNewest
230
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
231
- payload: {
232
- event_type: extraction_1.EventType.StartExtractingMetadata,
233
- event_context: {
234
- extraction_start_time: {
235
- type: extraction_1.TimeValueType.WORKERS_NEWEST,
236
- },
237
- },
238
- },
239
- });
240
- const stringifiedState = JSON.stringify({
241
- snapInVersionId: 'test_snap_in_version_id',
242
- workers_oldest: '',
243
- workers_newest: '',
244
- });
245
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
246
- jest.spyOn(console, 'log').mockImplementation(() => { });
247
- jest.spyOn(console, 'error').mockImplementation(() => { });
248
- // Act & Assert
249
- await expect((0, state_1.createAdapterState)({
250
- event,
251
- initialState: {},
252
- initialDomainMapping: {},
253
- })).rejects.toThrow('process.exit called');
254
- expect(processExitSpy).toHaveBeenCalledWith(1);
255
- });
256
- it('should exit the process if extraction_end_time resolution fails', async () => {
257
- // Arrange: WORKERS_NEWEST type but state has no workersNewest
258
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
259
- payload: {
260
- event_type: extraction_1.EventType.StartExtractingMetadata,
261
- event_context: {
262
- extraction_start_time: {
263
- type: extraction_1.TimeValueType.UNBOUNDED,
264
- },
265
- extraction_end_time: {
266
- type: extraction_1.TimeValueType.WORKERS_NEWEST,
267
- },
268
- },
269
- },
270
- });
271
- const stringifiedState = JSON.stringify({
272
- snapInVersionId: 'test_snap_in_version_id',
273
- workers_oldest: '',
274
- workers_newest: '',
275
- });
276
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
277
- jest.spyOn(console, 'log').mockImplementation(() => { });
278
- jest.spyOn(console, 'error').mockImplementation(() => { });
279
- // Act & Assert
280
- await expect((0, state_1.createAdapterState)({
281
- event,
282
- initialState: {},
283
- initialDomainMapping: {},
284
- })).rejects.toThrow('process.exit called');
285
- expect(processExitSpy).toHaveBeenCalledWith(1);
286
- });
287
- });
288
- describe('Backwards compatibility - missing TimeValue type', () => {
289
- it('should skip resolution when extraction_start_time has no type', async () => {
290
- // Arrange: platform sends extraction_start_time without a type field (old platform version)
291
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
292
- context: {
293
- snap_in_version_id: 'test_snap_in_version_id',
294
- },
295
- payload: {
296
- event_type: extraction_1.EventType.StartExtractingMetadata,
297
- event_context: {
298
- extraction_start_time: {},
299
- extraction_end_time: {
300
- type: extraction_1.TimeValueType.ABSOLUTE_TIME,
301
- value: '2025-06-01T00:00:00Z',
302
- },
303
- },
304
- },
305
- });
306
- const stringifiedState = JSON.stringify({
307
- snapInVersionId: 'test_snap_in_version_id',
308
- });
309
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
310
- jest.spyOn(console, 'log').mockImplementation(() => { });
311
- // Act
312
- const state = await (0, state_1.createAdapterState)({
313
- event,
314
- initialState: {},
315
- initialDomainMapping: {},
316
- });
317
- // Assert: should not crash, extract_from is not set, extract_to is resolved
318
- expect(processExitSpy).not.toHaveBeenCalled();
319
- expect(event.payload.event_context.extract_from).toBeUndefined();
320
- expect(event.payload.event_context.extract_to).toBe('2025-06-01T00:00:00.000Z');
321
- expect(state.state.pendingWorkersNewest).toBe('2025-06-01T00:00:00.000Z');
322
- });
323
- it('should skip resolution when extraction_end_time has no type', async () => {
324
- // Arrange: platform sends extraction_end_time without a type field
325
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
326
- context: {
327
- snap_in_version_id: 'test_snap_in_version_id',
328
- },
329
- payload: {
330
- event_type: extraction_1.EventType.StartExtractingMetadata,
331
- event_context: {
332
- extraction_start_time: {
333
- type: extraction_1.TimeValueType.ABSOLUTE_TIME,
334
- value: '2024-01-01T00:00:00Z',
335
- },
336
- extraction_end_time: {},
337
- },
338
- },
339
- });
340
- const stringifiedState = JSON.stringify({
341
- snapInVersionId: 'test_snap_in_version_id',
342
- });
343
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
344
- jest.spyOn(console, 'log').mockImplementation(() => { });
345
- // Act
346
- await (0, state_1.createAdapterState)({
347
- event,
348
- initialState: {},
349
- initialDomainMapping: {},
350
- });
351
- // Assert: should not crash, extract_to is not set, extract_from is resolved
352
- expect(processExitSpy).not.toHaveBeenCalled();
353
- expect(event.payload.event_context.extract_from).toBe('2024-01-01T00:00:00.000Z');
354
- expect(event.payload.event_context.extract_to).toBeUndefined();
355
- });
356
- it('should skip resolution when both extraction times have no type', async () => {
357
- // Arrange: platform sends both time values without type fields
358
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
359
- context: {
360
- snap_in_version_id: 'test_snap_in_version_id',
361
- },
362
- payload: {
363
- event_type: extraction_1.EventType.StartExtractingMetadata,
364
- event_context: {
365
- extraction_start_time: {
366
- value: 'some-value',
367
- },
368
- extraction_end_time: {
369
- value: 'some-value',
370
- },
371
- },
372
- },
373
- });
374
- const stringifiedState = JSON.stringify({
375
- snapInVersionId: 'test_snap_in_version_id',
376
- });
377
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
378
- jest.spyOn(console, 'log').mockImplementation(() => { });
379
- // Act
380
- await (0, state_1.createAdapterState)({
381
- event,
382
- initialState: {},
383
- initialDomainMapping: {},
384
- });
385
- // Assert: should not crash, neither extraction time is resolved
386
- expect(processExitSpy).not.toHaveBeenCalled();
387
- expect(event.payload.event_context.extract_from).toBeUndefined();
388
- expect(event.payload.event_context.extract_to).toBeUndefined();
389
- });
390
- });
391
- describe('Enhanced Control Protocol - extraction window validation', () => {
392
- it('should exit the process if extract_from >= extract_to', async () => {
393
- // Arrange: start is after end (inverted window)
394
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
395
- payload: {
396
- event_type: extraction_1.EventType.StartExtractingMetadata,
397
- event_context: {
398
- extraction_start_time: {
399
- type: extraction_1.TimeValueType.ABSOLUTE_TIME,
400
- value: '2025-06-01T00:00:00Z',
401
- },
402
- extraction_end_time: {
403
- type: extraction_1.TimeValueType.ABSOLUTE_TIME,
404
- value: '2024-01-01T00:00:00Z',
405
- },
406
- },
407
- },
408
- });
409
- const stringifiedState = JSON.stringify({
410
- snapInVersionId: 'test_snap_in_version_id',
411
- });
412
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
413
- jest.spyOn(console, 'log').mockImplementation(() => { });
414
- jest.spyOn(console, 'error').mockImplementation(() => { });
415
- // Act & Assert
416
- await expect((0, state_1.createAdapterState)({
417
- event,
418
- initialState: {},
419
- initialDomainMapping: {},
420
- })).rejects.toThrow('process.exit called');
421
- expect(processExitSpy).toHaveBeenCalledWith(1);
422
- });
423
- it('should exit the process if extract_from equals extract_to', async () => {
424
- // Arrange: start equals end (zero-width window)
425
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
426
- payload: {
427
- event_type: extraction_1.EventType.StartExtractingMetadata,
428
- event_context: {
429
- extraction_start_time: {
430
- type: extraction_1.TimeValueType.ABSOLUTE_TIME,
431
- value: '2024-06-01T00:00:00Z',
432
- },
433
- extraction_end_time: {
434
- type: extraction_1.TimeValueType.ABSOLUTE_TIME,
435
- value: '2024-06-01T00:00:00Z',
436
- },
437
- },
438
- },
439
- });
440
- const stringifiedState = JSON.stringify({
441
- snapInVersionId: 'test_snap_in_version_id',
442
- });
443
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
444
- jest.spyOn(console, 'log').mockImplementation(() => { });
445
- jest.spyOn(console, 'error').mockImplementation(() => { });
446
- // Act & Assert
447
- await expect((0, state_1.createAdapterState)({
448
- event,
449
- initialState: {},
450
- initialDomainMapping: {},
451
- })).rejects.toThrow('process.exit called');
452
- expect(processExitSpy).toHaveBeenCalledWith(1);
453
- });
454
- it('should not exit when extract_from < extract_to', async () => {
455
- // Arrange: valid window
456
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
457
- payload: {
458
- event_type: extraction_1.EventType.StartExtractingMetadata,
459
- event_context: {
460
- extraction_start_time: {
461
- type: extraction_1.TimeValueType.ABSOLUTE_TIME,
462
- value: '2024-01-01T00:00:00Z',
463
- },
464
- extraction_end_time: {
465
- type: extraction_1.TimeValueType.ABSOLUTE_TIME,
466
- value: '2025-06-01T00:00:00Z',
467
- },
468
- },
469
- },
470
- });
471
- const stringifiedState = JSON.stringify({
472
- snapInVersionId: 'test_snap_in_version_id',
473
- });
474
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
475
- jest.spyOn(console, 'log').mockImplementation(() => { });
476
- // Act
477
- await (0, state_1.createAdapterState)({
478
- event,
479
- initialState: {},
480
- initialDomainMapping: {},
481
- });
482
- // Assert: process.exit should NOT have been called
483
- expect(processExitSpy).not.toHaveBeenCalled();
484
- });
485
- it('should not validate when only extract_from is set', async () => {
486
- // Arrange: only start, no end
487
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
488
- payload: {
489
- event_type: extraction_1.EventType.StartExtractingMetadata,
490
- event_context: {
491
- extraction_start_time: {
492
- type: extraction_1.TimeValueType.ABSOLUTE_TIME,
493
- value: '2024-01-01T00:00:00Z',
494
- },
495
- },
496
- },
497
- });
498
- const stringifiedState = JSON.stringify({
499
- snapInVersionId: 'test_snap_in_version_id',
500
- });
501
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
502
- jest.spyOn(console, 'log').mockImplementation(() => { });
503
- // Act
504
- await (0, state_1.createAdapterState)({
505
- event,
506
- initialState: {},
507
- initialDomainMapping: {},
508
- });
509
- // Assert: process.exit should NOT have been called
510
- expect(processExitSpy).not.toHaveBeenCalled();
511
- });
512
- it('should not exit when extract_from is UNBOUNDED and extract_to is a real timestamp', async () => {
513
- // Arrange: UNBOUNDED start (epoch) with a real ABSOLUTE end timestamp
514
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
515
- payload: {
516
- event_type: extraction_1.EventType.StartExtractingMetadata,
517
- event_context: {
518
- extraction_start_time: {
519
- type: extraction_1.TimeValueType.UNBOUNDED,
520
- },
521
- extraction_end_time: {
522
- type: extraction_1.TimeValueType.ABSOLUTE_TIME,
523
- value: '2025-06-01T00:00:00Z',
524
- },
525
- },
526
- },
527
- });
528
- const stringifiedState = JSON.stringify({
529
- snapInVersionId: 'test_snap_in_version_id',
530
- });
531
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
532
- jest.spyOn(console, 'log').mockImplementation(() => { });
533
- // Act
534
- await (0, state_1.createAdapterState)({
535
- event,
536
- initialState: {},
537
- initialDomainMapping: {},
538
- });
539
- // Assert: process.exit should NOT have been called
540
- expect(processExitSpy).not.toHaveBeenCalled();
541
- });
542
- });
543
- describe('Pending extraction boundaries (pendingWorkersOldest/pendingWorkersNewest)', () => {
544
- const FIXED_NOW = '2026-03-26T10:00:00.000Z';
545
- beforeEach(() => {
546
- jest.useFakeTimers();
547
- jest.setSystemTime(new Date(FIXED_NOW));
548
- });
549
- afterEach(() => {
550
- jest.useRealTimers();
551
- });
552
- it('should store resolved values in pendingWorkersOldest/pendingWorkersNewest on StartExtractingMetadata', async () => {
553
- // Arrange
554
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
555
- context: {
556
- snap_in_version_id: '',
557
- },
558
- payload: {
559
- event_type: extraction_1.EventType.StartExtractingMetadata,
560
- event_context: {
561
- extraction_start_time: {
562
- type: extraction_1.TimeValueType.UNBOUNDED,
563
- },
564
- extraction_end_time: {
565
- type: extraction_1.TimeValueType.CURRENT_TIME,
566
- },
567
- },
568
- },
569
- });
570
- fetchStateSpy.mockRejectedValue({
571
- isAxiosError: true,
572
- response: { status: 404 },
573
- });
574
- installInitialDomainMappingSpy.mockResolvedValue({ success: true });
575
- postStateSpy.mockResolvedValue({ success: true });
576
- jest.spyOn(console, 'log').mockImplementation(() => { });
577
- // Act
578
- const state = await (0, state_1.createAdapterState)({
579
- event,
580
- initialState: {},
581
- initialDomainMapping: {},
582
- });
583
- // Assert
584
- expect(state.state.pendingWorkersOldest).toBe('1970-01-01T00:00:00.000Z');
585
- expect(state.state.pendingWorkersNewest).toBe(FIXED_NOW);
586
- expect(event.payload.event_context.extract_from).toBe('1970-01-01T00:00:00.000Z');
587
- expect(event.payload.event_context.extract_to).toBe(FIXED_NOW);
588
- });
589
- it('should overwrite pending values on a retry (new StartExtractingMetadata after failure)', async () => {
590
- // Arrange: state has stale pending values from a previous failed attempt
591
- const staleOldest = '2026-03-25T08:00:00.000Z';
592
- const staleNewest = '2026-03-25T09:00:00.000Z';
593
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
594
- context: {
595
- snap_in_version_id: 'test_snap_in_version_id',
596
- },
597
- payload: {
598
- event_type: extraction_1.EventType.StartExtractingMetadata,
599
- event_context: {
600
- extraction_start_time: {
601
- type: extraction_1.TimeValueType.UNBOUNDED,
602
- },
603
- extraction_end_time: {
604
- type: extraction_1.TimeValueType.CURRENT_TIME,
605
- },
606
- },
607
- },
608
- });
609
- const stringifiedState = JSON.stringify({
610
- snapInVersionId: 'test_snap_in_version_id',
611
- pendingWorkersOldest: staleOldest,
612
- pendingWorkersNewest: staleNewest,
613
- });
614
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
615
- jest.spyOn(console, 'log').mockImplementation(() => { });
616
- // Act
617
- const state = await (0, state_1.createAdapterState)({
618
- event,
619
- initialState: {},
620
- initialDomainMapping: {},
621
- });
622
- // Assert: pending values are overwritten with fresh resolution, not stale values
623
- expect(state.state.pendingWorkersOldest).toBe('1970-01-01T00:00:00.000Z');
624
- expect(state.state.pendingWorkersNewest).toBe(FIXED_NOW);
625
- expect(state.state.pendingWorkersNewest).not.toBe(staleNewest);
626
- });
627
- it('should reuse pending values from state on ContinueExtractingData instead of re-resolving', async () => {
628
- // Arrange: state has pending values from a prior StartExtractingMetadata phase
629
- const pendingOldest = '1970-01-01T00:00:00.000Z';
630
- const pendingNewest = '2026-03-26T08:00:00.000Z'; // Earlier than FIXED_NOW
631
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
632
- context: {
633
- snap_in_version_id: 'test_snap_in_version_id',
634
- },
635
- payload: {
636
- event_type: extraction_1.EventType.ContinueExtractingData,
637
- event_context: {
638
- // Platform still sends TimeValue objects, but they should be ignored
639
- extraction_start_time: {
640
- type: extraction_1.TimeValueType.CURRENT_TIME,
641
- },
642
- extraction_end_time: {
643
- type: extraction_1.TimeValueType.CURRENT_TIME,
644
- },
645
- },
646
- },
647
- });
648
- const stringifiedState = JSON.stringify({
649
- snapInVersionId: 'test_snap_in_version_id',
650
- pendingWorkersOldest: pendingOldest,
651
- pendingWorkersNewest: pendingNewest,
652
- });
653
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
654
- jest.spyOn(console, 'log').mockImplementation(() => { });
655
- // Act
656
- const state = await (0, state_1.createAdapterState)({
657
- event,
658
- initialState: {},
659
- initialDomainMapping: {},
660
- });
661
- // Assert: uses cached pending values, NOT new Date() resolution
662
- expect(event.payload.event_context.extract_from).toBe(pendingOldest);
663
- expect(event.payload.event_context.extract_to).toBe(pendingNewest);
664
- // Pending values in state remain unchanged
665
- expect(state.state.pendingWorkersOldest).toBe(pendingOldest);
666
- expect(state.state.pendingWorkersNewest).toBe(pendingNewest);
667
- });
668
- it('should not set extract_from/extract_to on ContinueExtractingData if no pending values exist', async () => {
669
- // Arrange: state has no pending values (e.g. old state from before this feature)
670
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
671
- context: {
672
- snap_in_version_id: 'test_snap_in_version_id',
673
- },
674
- payload: { event_type: extraction_1.EventType.ContinueExtractingData },
675
- });
676
- const stringifiedState = JSON.stringify({
677
- snapInVersionId: 'test_snap_in_version_id',
678
- });
679
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
680
- jest.spyOn(console, 'log').mockImplementation(() => { });
681
- // Act
682
- await (0, state_1.createAdapterState)({
683
- event,
684
- initialState: {},
685
- initialDomainMapping: {},
686
- });
687
- // Assert: no extraction timestamps are set
688
- expect(event.payload.event_context.extract_from).toBeUndefined();
689
- expect(event.payload.event_context.extract_to).toBeUndefined();
690
- });
691
- it('should reuse pending values on StartExtractingAttachments', async () => {
692
- // Arrange: state has pending values from the StartExtractingMetadata phase
693
- const pendingOldest = '1970-01-01T00:00:00.000Z';
694
- const pendingNewest = '2026-03-26T08:00:00.000Z';
695
- const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
696
- context: {
697
- snap_in_version_id: 'test_snap_in_version_id',
698
- },
699
- payload: { event_type: extraction_1.EventType.StartExtractingAttachments },
700
- });
701
- const stringifiedState = JSON.stringify({
702
- snapInVersionId: 'test_snap_in_version_id',
703
- pendingWorkersOldest: pendingOldest,
704
- pendingWorkersNewest: pendingNewest,
705
- });
706
- fetchStateSpy.mockResolvedValue({ state: stringifiedState });
707
- jest.spyOn(console, 'log').mockImplementation(() => { });
708
- // Act
709
- await (0, state_1.createAdapterState)({
710
- event,
711
- initialState: {},
712
- initialDomainMapping: {},
713
- });
714
- // Assert: pending values are reused
715
- expect(event.payload.event_context.extract_from).toBe(pendingOldest);
716
- expect(event.payload.event_context.extract_to).toBe(pendingNewest);
717
- });
718
- });
719
218
  it('should populate extractionScope from API response', async () => {
720
219
  // Arrange
721
220
  const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
@@ -731,7 +230,6 @@ describe(state_1.State.name, () => {
731
230
  users: { extract: true },
732
231
  }),
733
232
  });
734
- jest.spyOn(console, 'log').mockImplementation(() => { });
735
233
  // Act
736
234
  const result = await (0, state_1.createAdapterState)({
737
235
  event,
@@ -758,7 +256,6 @@ describe(state_1.State.name, () => {
758
256
  });
759
257
  installInitialDomainMappingSpy.mockResolvedValue({ success: true });
760
258
  postStateSpy.mockResolvedValue({ success: true });
761
- jest.spyOn(console, 'log').mockImplementation(() => { });
762
259
  // Act
763
260
  const result = await (0, state_1.createAdapterState)({
764
261
  event,
@@ -782,4 +279,24 @@ describe(state_1.State.name, () => {
782
279
  // Assert
783
280
  expect(result.extractionScope).toEqual({});
784
281
  });
282
+ it('should continue with empty extractionScope when objects field contains invalid JSON', async () => {
283
+ // Arrange
284
+ const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
285
+ context: { snap_in_version_id: '1.0.0' },
286
+ payload: { event_type: extraction_1.EventType.StartExtractingData },
287
+ });
288
+ fetchStateSpy.mockResolvedValue({
289
+ state: JSON.stringify({ snapInVersionId: '1.0.0' }),
290
+ objects: 'NOT_VALID_JSON',
291
+ });
292
+ // Act
293
+ const result = await (0, state_1.createAdapterState)({
294
+ event,
295
+ initialState: {},
296
+ initialDomainMapping: {},
297
+ });
298
+ // Assert: should not crash, extractionScope is empty (default)
299
+ expect(result.extractionScope).toEqual({});
300
+ expect(processExitSpy).not.toHaveBeenCalled();
301
+ });
785
302
  });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=state.time-value-resolution.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.time-value-resolution.test.d.ts","sourceRoot":"","sources":["../../src/state/state.time-value-resolution.test.ts"],"names":[],"mappings":""}