@devrev/airsync-sdk 2.0.0-beta.1 → 2.0.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.
- package/README.md +0 -4
- package/dist/airsync-sdk.d.ts +2059 -0
- package/dist/attachments-streaming/attachments-streaming-pool.d.ts +2 -1
- package/dist/attachments-streaming/attachments-streaming-pool.d.ts.map +1 -1
- package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts +8 -2
- package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts.map +1 -1
- package/dist/attachments-streaming/attachments-streaming-pool.js +27 -16
- package/dist/attachments-streaming/attachments-streaming-pool.test.js +246 -27
- package/dist/common/constants.d.ts +16 -5
- package/dist/common/constants.d.ts.map +1 -1
- package/dist/common/constants.js +20 -6
- package/dist/common/control-protocol.d.ts +2 -2
- package/dist/common/control-protocol.d.ts.map +1 -1
- package/dist/common/control-protocol.js +1 -5
- package/dist/common/helpers.d.ts +8 -0
- package/dist/common/helpers.d.ts.map +1 -1
- package/dist/common/helpers.js +15 -0
- package/dist/common/install-initial-domain-mapping.d.ts +2 -2
- package/dist/common/install-initial-domain-mapping.test.js +5 -2
- package/dist/common/test-utils.d.ts +19 -0
- package/dist/common/test-utils.d.ts.map +1 -0
- package/dist/common/test-utils.js +101 -0
- package/dist/common/time-value-resolver.d.ts +47 -0
- package/dist/common/time-value-resolver.d.ts.map +1 -0
- package/dist/common/time-value-resolver.js +141 -0
- package/dist/common/time-value-resolver.test.d.ts +2 -0
- package/dist/common/time-value-resolver.test.d.ts.map +1 -0
- package/dist/common/time-value-resolver.test.js +268 -0
- package/dist/http/axios-client-internal.d.ts.map +1 -1
- package/dist/http/axios-client-internal.js +7 -0
- package/dist/http/axios-client-internal.test.js +21 -0
- package/dist/http/axios-client.d.ts.map +1 -1
- package/dist/http/axios-client.js +6 -3
- package/dist/http/index.d.ts +0 -1
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +0 -1
- package/dist/index.d.ts +12 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -13
- package/dist/logger/logger.d.ts +1 -17
- package/dist/logger/logger.d.ts.map +1 -1
- package/dist/logger/logger.interfaces.d.ts +2 -2
- package/dist/logger/logger.js +35 -27
- package/dist/logger/logger.test.js +66 -19
- package/dist/mappers/mappers.interface.d.ts +5 -5
- package/dist/mappers/mappers.interface.js +3 -3
- package/dist/mappers/mappers.test.js +8 -10
- package/dist/mock-server/mock-server.d.ts +47 -0
- package/dist/mock-server/mock-server.d.ts.map +1 -0
- package/dist/mock-server/mock-server.interfaces.d.ts +73 -0
- package/dist/mock-server/mock-server.interfaces.d.ts.map +1 -0
- package/dist/mock-server/mock-server.interfaces.js +4 -0
- package/dist/mock-server/mock-server.js +278 -0
- package/dist/multithreading/adapters/base-adapter.d.ts +56 -0
- package/dist/multithreading/adapters/base-adapter.d.ts.map +1 -0
- package/dist/multithreading/adapters/base-adapter.emit.test.d.ts +2 -0
- package/dist/multithreading/adapters/base-adapter.emit.test.d.ts.map +1 -0
- package/dist/multithreading/adapters/base-adapter.emit.test.js +403 -0
- package/dist/multithreading/adapters/base-adapter.js +105 -0
- package/dist/multithreading/adapters/extraction-adapter.artifacts.test.d.ts +2 -0
- package/dist/multithreading/adapters/extraction-adapter.artifacts.test.d.ts.map +1 -0
- package/dist/multithreading/{worker-adapter/worker-adapter.artifacts.test.js → adapters/extraction-adapter.artifacts.test.js} +53 -5
- package/dist/multithreading/adapters/extraction-adapter.d.ts +58 -0
- package/dist/multithreading/adapters/extraction-adapter.d.ts.map +1 -0
- package/dist/multithreading/adapters/extraction-adapter.js +325 -0
- package/dist/multithreading/adapters/extraction-adapter.test.d.ts +2 -0
- package/dist/multithreading/adapters/extraction-adapter.test.d.ts.map +1 -0
- package/dist/multithreading/adapters/extraction-adapter.test.js +789 -0
- package/dist/multithreading/adapters/loading-adapter.d.ts +44 -0
- package/dist/multithreading/adapters/loading-adapter.d.ts.map +1 -0
- package/dist/multithreading/{worker-adapter/worker-adapter.helpers.d.ts → adapters/loading-adapter.helpers.d.ts} +1 -1
- package/dist/multithreading/adapters/loading-adapter.helpers.d.ts.map +1 -0
- package/dist/multithreading/adapters/loading-adapter.helpers.test.d.ts +2 -0
- package/dist/multithreading/adapters/loading-adapter.helpers.test.d.ts.map +1 -0
- package/dist/multithreading/{worker-adapter/worker-adapter.helpers.test.js → adapters/loading-adapter.helpers.test.js} +26 -26
- package/dist/multithreading/adapters/loading-adapter.js +461 -0
- package/dist/multithreading/adapters/loading-adapter.test.d.ts +2 -0
- package/dist/multithreading/adapters/loading-adapter.test.d.ts.map +1 -0
- package/dist/multithreading/adapters/loading-adapter.test.js +589 -0
- package/dist/multithreading/adapters/serialization.test.d.ts +2 -0
- package/dist/multithreading/adapters/serialization.test.d.ts.map +1 -0
- package/dist/multithreading/adapters/serialization.test.js +71 -0
- package/dist/multithreading/create-worker.test.js +36 -17
- package/dist/multithreading/process-task.d.ts +16 -1
- package/dist/multithreading/process-task.d.ts.map +1 -1
- package/dist/multithreading/process-task.js +97 -82
- package/dist/multithreading/process-task.test.d.ts +2 -0
- package/dist/multithreading/process-task.test.d.ts.map +1 -0
- package/dist/multithreading/process-task.test.js +146 -0
- package/dist/multithreading/spawn/spawn.d.ts +3 -3
- package/dist/multithreading/spawn/spawn.d.ts.map +1 -1
- package/dist/multithreading/spawn/spawn.helpers.d.ts.map +1 -1
- package/dist/multithreading/spawn/spawn.helpers.js +6 -14
- package/dist/multithreading/spawn/spawn.helpers.test.js +8 -8
- package/dist/multithreading/spawn/spawn.js +20 -25
- package/dist/multithreading/spawn/spawn.test.d.ts +2 -0
- package/dist/multithreading/spawn/spawn.test.d.ts.map +1 -0
- package/dist/multithreading/spawn/spawn.test.js +232 -0
- package/dist/repo/repo.d.ts.map +1 -1
- package/dist/repo/repo.interfaces.d.ts +4 -2
- package/dist/repo/repo.interfaces.d.ts.map +1 -1
- package/dist/repo/repo.js +4 -3
- package/dist/repo/repo.test.js +60 -7
- package/dist/state/base-state.d.ts +75 -0
- package/dist/state/base-state.d.ts.map +1 -0
- package/dist/state/base-state.js +261 -0
- package/dist/state/extraction-state.d.ts +29 -0
- package/dist/state/extraction-state.d.ts.map +1 -0
- package/dist/state/extraction-state.js +122 -0
- package/dist/state/loading-state.d.ts +19 -0
- package/dist/state/loading-state.d.ts.map +1 -0
- package/dist/state/loading-state.js +40 -0
- package/dist/state/state.extract-window.test.d.ts +2 -0
- package/dist/state/state.extract-window.test.d.ts.map +1 -0
- package/dist/state/state.extract-window.test.js +163 -0
- package/dist/state/state.interfaces.d.ts +44 -27
- package/dist/state/state.interfaces.d.ts.map +1 -1
- package/dist/state/state.interfaces.js +18 -5
- package/dist/state/state.pending-boundaries.test.d.ts +2 -0
- package/dist/state/state.pending-boundaries.test.d.ts.map +1 -0
- package/dist/state/state.pending-boundaries.test.js +189 -0
- package/dist/state/state.post-state.test.d.ts +2 -0
- package/dist/state/state.post-state.test.d.ts.map +1 -0
- package/dist/state/state.post-state.test.js +78 -0
- package/dist/state/state.test.js +135 -88
- package/dist/state/state.time-value-resolution.test.d.ts +2 -0
- package/dist/state/state.time-value-resolution.test.d.ts.map +1 -0
- package/dist/state/state.time-value-resolution.test.js +175 -0
- package/dist/tsdoc-metadata.json +11 -0
- package/dist/types/common.d.ts +0 -25
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/common.js +1 -11
- package/dist/types/external-domain-metadata.d.ts +20 -1
- package/dist/types/external-domain-metadata.d.ts.map +1 -1
- package/dist/types/extraction.d.ts +92 -221
- package/dist/types/extraction.d.ts.map +1 -1
- package/dist/types/extraction.js +56 -124
- package/dist/types/extraction.test.js +69 -43
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +6 -3
- package/dist/types/loading.d.ts +4 -24
- package/dist/types/loading.d.ts.map +1 -1
- package/dist/types/loading.js +1 -22
- package/dist/types/workers.d.ts +47 -29
- package/dist/types/workers.d.ts.map +1 -1
- package/dist/types/workers.js +1 -0
- package/dist/uploader/uploader.d.ts +1 -0
- package/dist/uploader/uploader.d.ts.map +1 -1
- package/dist/uploader/uploader.helpers.test.js +0 -11
- package/dist/uploader/uploader.interfaces.d.ts +3 -3
- package/dist/uploader/uploader.js +53 -20
- package/dist/uploader/uploader.test.js +22 -10
- package/package.json +10 -13
- package/dist/common/event-type-translation.d.ts +0 -24
- package/dist/common/event-type-translation.d.ts.map +0 -1
- package/dist/common/event-type-translation.js +0 -117
- package/dist/deprecated/adapter/index.d.ts +0 -62
- package/dist/deprecated/adapter/index.d.ts.map +0 -1
- package/dist/deprecated/adapter/index.js +0 -151
- package/dist/deprecated/common/helpers.d.ts +0 -7
- package/dist/deprecated/common/helpers.d.ts.map +0 -1
- package/dist/deprecated/common/helpers.js +0 -47
- package/dist/deprecated/demo-extractor/external_domain_metadata.json +0 -38
- package/dist/deprecated/demo-extractor/index.d.ts +0 -18
- package/dist/deprecated/demo-extractor/index.d.ts.map +0 -1
- package/dist/deprecated/demo-extractor/index.js +0 -161
- package/dist/deprecated/http/client.d.ts +0 -22
- package/dist/deprecated/http/client.d.ts.map +0 -1
- package/dist/deprecated/http/client.js +0 -161
- package/dist/deprecated/uploader/index.d.ts +0 -35
- package/dist/deprecated/uploader/index.d.ts.map +0 -1
- package/dist/deprecated/uploader/index.js +0 -161
- package/dist/http/types.d.ts +0 -17
- package/dist/http/types.d.ts.map +0 -1
- package/dist/http/types.js +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.d.ts +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.d.ts +0 -91
- package/dist/multithreading/worker-adapter/worker-adapter.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.helpers.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.helpers.test.d.ts +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.helpers.test.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.js +0 -745
- package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.test.js +0 -483
- package/dist/state/state.d.ts +0 -30
- package/dist/state/state.d.ts.map +0 -1
- package/dist/state/state.js +0 -166
- /package/dist/multithreading/{worker-adapter/worker-adapter.helpers.js → adapters/loading-adapter.helpers.js} +0 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const jest_setup_1 = require("../tests/jest.setup");
|
|
4
|
+
const test_utils_1 = require("../common/test-utils");
|
|
5
|
+
const extraction_1 = require("../types/extraction");
|
|
6
|
+
const extraction_state_1 = require("./extraction-state");
|
|
7
|
+
describe('State — extraction window validation', () => {
|
|
8
|
+
let fetchStateSpy;
|
|
9
|
+
let processExitSpy;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
jest.clearAllMocks();
|
|
12
|
+
jest.restoreAllMocks();
|
|
13
|
+
fetchStateSpy = jest.spyOn(extraction_state_1.ExtractionState.prototype, 'fetchState');
|
|
14
|
+
processExitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {
|
|
15
|
+
throw new Error('process.exit called');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe('Enhanced Control Protocol - extraction window validation', () => {
|
|
19
|
+
it('should exit the process if extract_from >= extract_to', async () => {
|
|
20
|
+
// Arrange: start is after end (inverted window)
|
|
21
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
22
|
+
payload: {
|
|
23
|
+
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
24
|
+
event_context: {
|
|
25
|
+
extraction_start_time: {
|
|
26
|
+
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
27
|
+
value: '2025-06-01T00:00:00Z',
|
|
28
|
+
},
|
|
29
|
+
extraction_end_time: {
|
|
30
|
+
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
31
|
+
value: '2024-01-01T00:00:00Z',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
const stringifiedState = JSON.stringify({
|
|
37
|
+
snapInVersionId: 'test_snap_in_version_id',
|
|
38
|
+
});
|
|
39
|
+
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
40
|
+
// Act & Assert
|
|
41
|
+
await expect((0, extraction_state_1.createExtractionState)({
|
|
42
|
+
event,
|
|
43
|
+
initialState: {},
|
|
44
|
+
initialDomainMapping: {},
|
|
45
|
+
})).rejects.toThrow('process.exit called');
|
|
46
|
+
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
47
|
+
});
|
|
48
|
+
it('should exit the process if extract_from equals extract_to', async () => {
|
|
49
|
+
// Arrange: start equals end (zero-width window)
|
|
50
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
51
|
+
payload: {
|
|
52
|
+
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
53
|
+
event_context: {
|
|
54
|
+
extraction_start_time: {
|
|
55
|
+
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
56
|
+
value: '2024-06-01T00:00:00Z',
|
|
57
|
+
},
|
|
58
|
+
extraction_end_time: {
|
|
59
|
+
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
60
|
+
value: '2024-06-01T00:00:00Z',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
const stringifiedState = JSON.stringify({
|
|
66
|
+
snapInVersionId: 'test_snap_in_version_id',
|
|
67
|
+
});
|
|
68
|
+
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
69
|
+
// Act & Assert
|
|
70
|
+
await expect((0, extraction_state_1.createExtractionState)({
|
|
71
|
+
event,
|
|
72
|
+
initialState: {},
|
|
73
|
+
initialDomainMapping: {},
|
|
74
|
+
})).rejects.toThrow('process.exit called');
|
|
75
|
+
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
76
|
+
});
|
|
77
|
+
it('should not exit when extract_from < extract_to', async () => {
|
|
78
|
+
// Arrange: valid window
|
|
79
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
80
|
+
payload: {
|
|
81
|
+
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
82
|
+
event_context: {
|
|
83
|
+
extraction_start_time: {
|
|
84
|
+
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
85
|
+
value: '2024-01-01T00:00:00Z',
|
|
86
|
+
},
|
|
87
|
+
extraction_end_time: {
|
|
88
|
+
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
89
|
+
value: '2025-06-01T00:00:00Z',
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
const stringifiedState = JSON.stringify({
|
|
95
|
+
snapInVersionId: 'test_snap_in_version_id',
|
|
96
|
+
});
|
|
97
|
+
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
98
|
+
// Act
|
|
99
|
+
await (0, extraction_state_1.createExtractionState)({
|
|
100
|
+
event,
|
|
101
|
+
initialState: {},
|
|
102
|
+
initialDomainMapping: {},
|
|
103
|
+
});
|
|
104
|
+
// Assert: process.exit should NOT have been called
|
|
105
|
+
expect(processExitSpy).not.toHaveBeenCalled();
|
|
106
|
+
});
|
|
107
|
+
it('should not validate when only extract_from is set', async () => {
|
|
108
|
+
// Arrange: only start, no end
|
|
109
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
110
|
+
payload: {
|
|
111
|
+
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
112
|
+
event_context: {
|
|
113
|
+
extraction_start_time: {
|
|
114
|
+
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
115
|
+
value: '2024-01-01T00:00:00Z',
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
const stringifiedState = JSON.stringify({
|
|
121
|
+
snapInVersionId: 'test_snap_in_version_id',
|
|
122
|
+
});
|
|
123
|
+
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
124
|
+
// Act
|
|
125
|
+
await (0, extraction_state_1.createExtractionState)({
|
|
126
|
+
event,
|
|
127
|
+
initialState: {},
|
|
128
|
+
initialDomainMapping: {},
|
|
129
|
+
});
|
|
130
|
+
// Assert: process.exit should NOT have been called
|
|
131
|
+
expect(processExitSpy).not.toHaveBeenCalled();
|
|
132
|
+
});
|
|
133
|
+
it('should not exit when extract_from is UNBOUNDED and extract_to is a real timestamp', async () => {
|
|
134
|
+
// Arrange: UNBOUNDED start (epoch) with a real ABSOLUTE end timestamp
|
|
135
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
136
|
+
payload: {
|
|
137
|
+
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
138
|
+
event_context: {
|
|
139
|
+
extraction_start_time: {
|
|
140
|
+
type: extraction_1.TimeValueType.UNBOUNDED,
|
|
141
|
+
},
|
|
142
|
+
extraction_end_time: {
|
|
143
|
+
type: extraction_1.TimeValueType.ABSOLUTE_TIME,
|
|
144
|
+
value: '2025-06-01T00:00:00Z',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
const stringifiedState = JSON.stringify({
|
|
150
|
+
snapInVersionId: 'test_snap_in_version_id',
|
|
151
|
+
});
|
|
152
|
+
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
153
|
+
// Act
|
|
154
|
+
await (0, extraction_state_1.createExtractionState)({
|
|
155
|
+
event,
|
|
156
|
+
initialState: {},
|
|
157
|
+
initialDomainMapping: {},
|
|
158
|
+
});
|
|
159
|
+
// Assert: process.exit should NOT have been called
|
|
160
|
+
expect(processExitSpy).not.toHaveBeenCalled();
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
});
|
|
@@ -1,19 +1,44 @@
|
|
|
1
1
|
import { InitialDomainMapping } from '../types/common';
|
|
2
|
-
import {
|
|
2
|
+
import { AirSyncEvent } from '../types/extraction';
|
|
3
3
|
import { FileToLoad } from '../types/loading';
|
|
4
4
|
import { WorkerAdapterOptions } from '../types/workers';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
/**
|
|
6
|
+
* BaseSdkState holds SDK bookkeeping common to every sync mode.
|
|
7
|
+
*/
|
|
8
|
+
export interface BaseSdkState {
|
|
9
|
+
snapInVersionId?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* ExtractionSdkState holds SDK bookkeeping owned by the extraction modes.
|
|
13
|
+
*/
|
|
14
|
+
export interface ExtractionSdkState extends BaseSdkState {
|
|
15
|
+
/** The pending (not yet committed) oldest extraction boundary (ISO 8601 timestamp).
|
|
16
|
+
* Set on StartExtractingMetadata, reused across subsequent phases, cleared on AttachmentExtractionDone. */
|
|
17
|
+
pendingWorkersOldest?: string;
|
|
18
|
+
/** The pending (not yet committed) newest extraction boundary (ISO 8601 timestamp).
|
|
19
|
+
* Set on StartExtractingMetadata, reused across subsequent phases, cleared on AttachmentExtractionDone. */
|
|
20
|
+
pendingWorkersNewest?: string;
|
|
21
|
+
/** The oldest point of extraction (ISO 8601 timestamp). */
|
|
22
|
+
workersOldest?: string;
|
|
23
|
+
/** The newest point of extraction (ISO 8601 timestamp). */
|
|
24
|
+
workersNewest?: string;
|
|
8
25
|
toDevRev?: ToDevRev;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* LoadingSdkState holds SDK bookkeeping owned by the loading modes.
|
|
29
|
+
*/
|
|
30
|
+
export interface LoadingSdkState extends BaseSdkState {
|
|
9
31
|
fromDevRev?: FromDevRev;
|
|
10
|
-
snapInVersionId?: string;
|
|
11
32
|
}
|
|
12
33
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
34
|
+
* AdapterStateEnvelope is the v2 on-disk state shape: connector state and SDK
|
|
35
|
+
* bookkeeping are stored as disjoint sub-objects so SDK internals stay
|
|
36
|
+
* encapsulated and never collide with connector keys.
|
|
15
37
|
*/
|
|
16
|
-
export
|
|
38
|
+
export interface AdapterStateEnvelope<ConnectorState, SdkState extends BaseSdkState> {
|
|
39
|
+
connectorState: ConnectorState;
|
|
40
|
+
sdkState: SdkState;
|
|
41
|
+
}
|
|
17
42
|
export interface ToDevRev {
|
|
18
43
|
attachmentsMetadata: {
|
|
19
44
|
artifactIds: string[];
|
|
@@ -32,27 +57,19 @@ export interface FromDevRev {
|
|
|
32
57
|
filesToLoad: FileToLoad[];
|
|
33
58
|
}
|
|
34
59
|
export interface StateInterface<ConnectorState> {
|
|
35
|
-
event:
|
|
60
|
+
event: AirSyncEvent;
|
|
36
61
|
initialState: ConnectorState;
|
|
37
62
|
initialDomainMapping?: InitialDomainMapping;
|
|
38
63
|
options?: WorkerAdapterOptions;
|
|
39
64
|
}
|
|
40
|
-
export declare const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
};
|
|
51
|
-
};
|
|
52
|
-
export declare const loadingSdkState: {
|
|
53
|
-
snapInVersionId: string;
|
|
54
|
-
fromDevRev: {
|
|
55
|
-
filesToLoad: never[];
|
|
56
|
-
};
|
|
57
|
-
};
|
|
65
|
+
export declare const initialExtractionSdkState: ExtractionSdkState;
|
|
66
|
+
export declare const initialLoadingSdkState: LoadingSdkState;
|
|
67
|
+
/**
|
|
68
|
+
* The set of top-level state keys owned by the SDK. Derived from the initial
|
|
69
|
+
* SDK state constants so it auto-updates whenever a new SDK field is added.
|
|
70
|
+
* Used by the migration shim to split a flat v1 state blob into the
|
|
71
|
+
* `{ connectorState, sdkState }` envelope: keys in this set go to `sdkState`,
|
|
72
|
+
* everything else is connector state.
|
|
73
|
+
*/
|
|
74
|
+
export declare const V1_SDK_STATE_KEYS: ReadonlySet<string>;
|
|
58
75
|
//# sourceMappingURL=state.interfaces.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.interfaces.d.ts","sourceRoot":"","sources":["../../src/state/state.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"state.interfaces.d.ts","sourceRoot":"","sources":["../../src/state/state.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD;gHAC4G;IAC5G,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;gHAC4G;IAC5G,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB,CACnC,cAAc,EACd,QAAQ,SAAS,YAAY;IAE7B,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,mBAAmB,EAAE;QACnB,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,+BAA+B,CAAC,EAAE,mBAAmB,EAAE,CAAC;KACzD,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc,CAAC,cAAc;IAC5C,KAAK,EAAE,YAAY,CAAC;IACpB,YAAY,EAAE,cAAc,CAAC;IAC7B,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAED,eAAO,MAAM,yBAAyB,EAAE,kBAavC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAKpC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAGhD,CAAC"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
5
|
-
lastSyncStarted: '',
|
|
6
|
-
lastSuccessfulSyncStarted: '',
|
|
3
|
+
exports.V1_SDK_STATE_KEYS = exports.initialLoadingSdkState = exports.initialExtractionSdkState = void 0;
|
|
4
|
+
exports.initialExtractionSdkState = {
|
|
7
5
|
snapInVersionId: '',
|
|
6
|
+
pendingWorkersOldest: '',
|
|
7
|
+
pendingWorkersNewest: '',
|
|
8
|
+
workersOldest: '',
|
|
9
|
+
workersNewest: '',
|
|
8
10
|
toDevRev: {
|
|
9
11
|
attachmentsMetadata: {
|
|
10
12
|
artifactIds: [],
|
|
@@ -13,9 +15,20 @@ exports.extractionSdkState = {
|
|
|
13
15
|
},
|
|
14
16
|
},
|
|
15
17
|
};
|
|
16
|
-
exports.
|
|
18
|
+
exports.initialLoadingSdkState = {
|
|
17
19
|
snapInVersionId: '',
|
|
18
20
|
fromDevRev: {
|
|
19
21
|
filesToLoad: [],
|
|
20
22
|
},
|
|
21
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* The set of top-level state keys owned by the SDK. Derived from the initial
|
|
26
|
+
* SDK state constants so it auto-updates whenever a new SDK field is added.
|
|
27
|
+
* Used by the migration shim to split a flat v1 state blob into the
|
|
28
|
+
* `{ connectorState, sdkState }` envelope: keys in this set go to `sdkState`,
|
|
29
|
+
* everything else is connector state.
|
|
30
|
+
*/
|
|
31
|
+
exports.V1_SDK_STATE_KEYS = new Set([
|
|
32
|
+
...Object.keys(exports.initialExtractionSdkState),
|
|
33
|
+
...Object.keys(exports.initialLoadingSdkState),
|
|
34
|
+
]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.pending-boundaries.test.d.ts","sourceRoot":"","sources":["../../src/state/state.pending-boundaries.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const jest_setup_1 = require("../tests/jest.setup");
|
|
4
|
+
const test_utils_1 = require("../common/test-utils");
|
|
5
|
+
const extraction_1 = require("../types/extraction");
|
|
6
|
+
const extraction_state_1 = require("./extraction-state");
|
|
7
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
8
|
+
const FIXED_NOW = '2026-03-26T10:00:00.000Z';
|
|
9
|
+
describe('State — pending extraction boundaries', () => {
|
|
10
|
+
let postStateSpy;
|
|
11
|
+
let fetchStateSpy;
|
|
12
|
+
let installInitialDomainMappingSpy;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
jest.clearAllMocks();
|
|
15
|
+
jest.restoreAllMocks();
|
|
16
|
+
postStateSpy = jest.spyOn(extraction_state_1.ExtractionState.prototype, 'postState');
|
|
17
|
+
fetchStateSpy = jest.spyOn(extraction_state_1.ExtractionState.prototype, 'fetchState');
|
|
18
|
+
installInitialDomainMappingSpy = jest.spyOn(require('../common/install-initial-domain-mapping'), 'installInitialDomainMapping');
|
|
19
|
+
jest.spyOn(process, 'exit').mockImplementation(() => {
|
|
20
|
+
throw new Error('process.exit called');
|
|
21
|
+
});
|
|
22
|
+
jest.useFakeTimers();
|
|
23
|
+
jest.setSystemTime(new Date(FIXED_NOW));
|
|
24
|
+
});
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
jest.useRealTimers();
|
|
27
|
+
});
|
|
28
|
+
it('should store resolved values in pendingWorkersOldest/pendingWorkersNewest on StartExtractingMetadata', async () => {
|
|
29
|
+
// Arrange
|
|
30
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
31
|
+
context: {
|
|
32
|
+
snap_in_version_id: '',
|
|
33
|
+
},
|
|
34
|
+
payload: {
|
|
35
|
+
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
36
|
+
event_context: {
|
|
37
|
+
extraction_start_time: {
|
|
38
|
+
type: extraction_1.TimeValueType.UNBOUNDED,
|
|
39
|
+
},
|
|
40
|
+
extraction_end_time: {
|
|
41
|
+
type: extraction_1.TimeValueType.CURRENT_TIME,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
fetchStateSpy.mockRejectedValue({
|
|
47
|
+
isAxiosError: true,
|
|
48
|
+
response: { status: 404 },
|
|
49
|
+
});
|
|
50
|
+
installInitialDomainMappingSpy.mockResolvedValue({ success: true });
|
|
51
|
+
postStateSpy.mockResolvedValue({ success: true });
|
|
52
|
+
// Act
|
|
53
|
+
const state = await (0, extraction_state_1.createExtractionState)({
|
|
54
|
+
event,
|
|
55
|
+
initialState: {},
|
|
56
|
+
initialDomainMapping: {},
|
|
57
|
+
});
|
|
58
|
+
// Assert
|
|
59
|
+
expect(state.sdkState.pendingWorkersOldest).toBe('1970-01-01T00:00:00.000Z');
|
|
60
|
+
expect(state.sdkState.pendingWorkersNewest).toBe(FIXED_NOW);
|
|
61
|
+
expect(event.payload.event_context.extract_from).toBe('1970-01-01T00:00:00.000Z');
|
|
62
|
+
expect(event.payload.event_context.extract_to).toBe(FIXED_NOW);
|
|
63
|
+
});
|
|
64
|
+
it('should overwrite pending values on a retry (new StartExtractingMetadata after failure)', async () => {
|
|
65
|
+
// Arrange: state has stale pending values from a previous failed attempt
|
|
66
|
+
const staleOldest = '2026-03-25T08:00:00.000Z';
|
|
67
|
+
const staleNewest = '2026-03-25T09:00:00.000Z';
|
|
68
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
69
|
+
context: {
|
|
70
|
+
snap_in_version_id: 'test_snap_in_version_id',
|
|
71
|
+
},
|
|
72
|
+
payload: {
|
|
73
|
+
event_type: extraction_1.EventType.StartExtractingMetadata,
|
|
74
|
+
event_context: {
|
|
75
|
+
extraction_start_time: {
|
|
76
|
+
type: extraction_1.TimeValueType.UNBOUNDED,
|
|
77
|
+
},
|
|
78
|
+
extraction_end_time: {
|
|
79
|
+
type: extraction_1.TimeValueType.CURRENT_TIME,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
const stringifiedState = JSON.stringify({
|
|
85
|
+
snapInVersionId: 'test_snap_in_version_id',
|
|
86
|
+
pendingWorkersOldest: staleOldest,
|
|
87
|
+
pendingWorkersNewest: staleNewest,
|
|
88
|
+
});
|
|
89
|
+
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
90
|
+
// Act
|
|
91
|
+
const state = await (0, extraction_state_1.createExtractionState)({
|
|
92
|
+
event,
|
|
93
|
+
initialState: {},
|
|
94
|
+
initialDomainMapping: {},
|
|
95
|
+
});
|
|
96
|
+
// Assert: pending values are overwritten with fresh resolution, not stale values
|
|
97
|
+
expect(state.sdkState.pendingWorkersOldest).toBe('1970-01-01T00:00:00.000Z');
|
|
98
|
+
expect(state.sdkState.pendingWorkersNewest).toBe(FIXED_NOW);
|
|
99
|
+
expect(state.sdkState.pendingWorkersNewest).not.toBe(staleNewest);
|
|
100
|
+
});
|
|
101
|
+
it('should reuse pending values from state on ContinueExtractingData instead of re-resolving', async () => {
|
|
102
|
+
// Arrange: state has pending values from a prior StartExtractingMetadata phase
|
|
103
|
+
const pendingOldest = '1970-01-01T00:00:00.000Z';
|
|
104
|
+
const pendingNewest = '2026-03-26T08:00:00.000Z'; // Earlier than FIXED_NOW
|
|
105
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
106
|
+
context: {
|
|
107
|
+
snap_in_version_id: 'test_snap_in_version_id',
|
|
108
|
+
},
|
|
109
|
+
payload: {
|
|
110
|
+
event_type: extraction_1.EventType.ContinueExtractingData,
|
|
111
|
+
event_context: {
|
|
112
|
+
// Platform still sends TimeValue objects, but they should be ignored
|
|
113
|
+
extraction_start_time: {
|
|
114
|
+
type: extraction_1.TimeValueType.CURRENT_TIME,
|
|
115
|
+
},
|
|
116
|
+
extraction_end_time: {
|
|
117
|
+
type: extraction_1.TimeValueType.CURRENT_TIME,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
const stringifiedState = JSON.stringify({
|
|
123
|
+
snapInVersionId: 'test_snap_in_version_id',
|
|
124
|
+
pendingWorkersOldest: pendingOldest,
|
|
125
|
+
pendingWorkersNewest: pendingNewest,
|
|
126
|
+
});
|
|
127
|
+
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
128
|
+
// Act
|
|
129
|
+
const state = await (0, extraction_state_1.createExtractionState)({
|
|
130
|
+
event,
|
|
131
|
+
initialState: {},
|
|
132
|
+
initialDomainMapping: {},
|
|
133
|
+
});
|
|
134
|
+
// Assert: uses cached pending values, NOT new Date() resolution
|
|
135
|
+
expect(event.payload.event_context.extract_from).toBe(pendingOldest);
|
|
136
|
+
expect(event.payload.event_context.extract_to).toBe(pendingNewest);
|
|
137
|
+
// Pending values in state remain unchanged
|
|
138
|
+
expect(state.sdkState.pendingWorkersOldest).toBe(pendingOldest);
|
|
139
|
+
expect(state.sdkState.pendingWorkersNewest).toBe(pendingNewest);
|
|
140
|
+
});
|
|
141
|
+
it('should not set extract_from/extract_to on ContinueExtractingData if no pending values exist', async () => {
|
|
142
|
+
// Arrange: state has no pending values (e.g. old state from before this feature)
|
|
143
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
144
|
+
context: {
|
|
145
|
+
snap_in_version_id: 'test_snap_in_version_id',
|
|
146
|
+
},
|
|
147
|
+
payload: { event_type: extraction_1.EventType.ContinueExtractingData },
|
|
148
|
+
});
|
|
149
|
+
const stringifiedState = JSON.stringify({
|
|
150
|
+
snapInVersionId: 'test_snap_in_version_id',
|
|
151
|
+
});
|
|
152
|
+
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
153
|
+
// Act
|
|
154
|
+
await (0, extraction_state_1.createExtractionState)({
|
|
155
|
+
event,
|
|
156
|
+
initialState: {},
|
|
157
|
+
initialDomainMapping: {},
|
|
158
|
+
});
|
|
159
|
+
// Assert: no extraction timestamps are set
|
|
160
|
+
expect(event.payload.event_context.extract_from).toBeUndefined();
|
|
161
|
+
expect(event.payload.event_context.extract_to).toBeUndefined();
|
|
162
|
+
});
|
|
163
|
+
it('should reuse pending values on StartExtractingAttachments', async () => {
|
|
164
|
+
// Arrange: state has pending values from the StartExtractingMetadata phase
|
|
165
|
+
const pendingOldest = '1970-01-01T00:00:00.000Z';
|
|
166
|
+
const pendingNewest = '2026-03-26T08:00:00.000Z';
|
|
167
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
168
|
+
context: {
|
|
169
|
+
snap_in_version_id: 'test_snap_in_version_id',
|
|
170
|
+
},
|
|
171
|
+
payload: { event_type: extraction_1.EventType.StartExtractingAttachments },
|
|
172
|
+
});
|
|
173
|
+
const stringifiedState = JSON.stringify({
|
|
174
|
+
snapInVersionId: 'test_snap_in_version_id',
|
|
175
|
+
pendingWorkersOldest: pendingOldest,
|
|
176
|
+
pendingWorkersNewest: pendingNewest,
|
|
177
|
+
});
|
|
178
|
+
fetchStateSpy.mockResolvedValue({ state: stringifiedState });
|
|
179
|
+
// Act
|
|
180
|
+
await (0, extraction_state_1.createExtractionState)({
|
|
181
|
+
event,
|
|
182
|
+
initialState: {},
|
|
183
|
+
initialDomainMapping: {},
|
|
184
|
+
});
|
|
185
|
+
// Assert: pending values are reused
|
|
186
|
+
expect(event.payload.event_context.extract_from).toBe(pendingOldest);
|
|
187
|
+
expect(event.payload.event_context.extract_to).toBe(pendingNewest);
|
|
188
|
+
});
|
|
189
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.post-state.test.d.ts","sourceRoot":"","sources":["../../src/state/state.post-state.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const jest_setup_1 = require("../tests/jest.setup");
|
|
4
|
+
const test_utils_1 = require("../common/test-utils");
|
|
5
|
+
const extraction_1 = require("../types/extraction");
|
|
6
|
+
const extraction_state_1 = require("./extraction-state");
|
|
7
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
8
|
+
describe('State.postState', () => {
|
|
9
|
+
let postStateSpy;
|
|
10
|
+
let fetchStateSpy;
|
|
11
|
+
let processExitSpy;
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
jest.clearAllMocks();
|
|
14
|
+
jest.restoreAllMocks();
|
|
15
|
+
postStateSpy = jest.spyOn(extraction_state_1.ExtractionState.prototype, 'postState');
|
|
16
|
+
fetchStateSpy = jest.spyOn(extraction_state_1.ExtractionState.prototype, 'fetchState');
|
|
17
|
+
processExitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {
|
|
18
|
+
throw new Error('process.exit called');
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
it('should POST the stringified state to the update endpoint', async () => {
|
|
22
|
+
// Arrange
|
|
23
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
24
|
+
context: {
|
|
25
|
+
snap_in_version_id: '1.0.0',
|
|
26
|
+
secrets: { service_account_token: 'test_token' },
|
|
27
|
+
},
|
|
28
|
+
payload: { event_type: extraction_1.EventType.StartExtractingData },
|
|
29
|
+
});
|
|
30
|
+
const stateToPost = { snapInVersionId: '1.0.0', foo: 'bar' };
|
|
31
|
+
fetchStateSpy.mockResolvedValue({
|
|
32
|
+
state: JSON.stringify({ snapInVersionId: '1.0.0' }),
|
|
33
|
+
});
|
|
34
|
+
postStateSpy.mockRestore();
|
|
35
|
+
const adapterState = await (0, extraction_state_1.createExtractionState)({
|
|
36
|
+
event,
|
|
37
|
+
initialState: {},
|
|
38
|
+
initialDomainMapping: {},
|
|
39
|
+
});
|
|
40
|
+
// Act
|
|
41
|
+
await adapterState.postState(stateToPost);
|
|
42
|
+
// Assert: the mock server records all incoming requests — inspect what was sent
|
|
43
|
+
const requests = jest_setup_1.mockServer.getRequests('POST', '/worker_data_url.update');
|
|
44
|
+
expect(requests).toHaveLength(1);
|
|
45
|
+
const body = requests[0].body;
|
|
46
|
+
// Body must contain the stringified v2 envelope: connector state and SDK
|
|
47
|
+
// bookkeeping stored as disjoint sub-objects.
|
|
48
|
+
expect(typeof body.state).toBe('string');
|
|
49
|
+
const parsed = JSON.parse(body.state);
|
|
50
|
+
expect(parsed.connectorState.foo).toBe('bar');
|
|
51
|
+
expect(parsed.sdkState.snapInVersionId).toBe('1.0.0');
|
|
52
|
+
});
|
|
53
|
+
it('should exit(1) when postState HTTP request fails', async () => {
|
|
54
|
+
// Arrange
|
|
55
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
56
|
+
context: { snap_in_version_id: '1.0.0' },
|
|
57
|
+
payload: { event_type: extraction_1.EventType.StartExtractingData },
|
|
58
|
+
});
|
|
59
|
+
fetchStateSpy.mockResolvedValue({
|
|
60
|
+
state: JSON.stringify({ snapInVersionId: '1.0.0' }),
|
|
61
|
+
});
|
|
62
|
+
postStateSpy.mockRestore();
|
|
63
|
+
const adapterState = await (0, extraction_state_1.createExtractionState)({
|
|
64
|
+
event,
|
|
65
|
+
initialState: {},
|
|
66
|
+
initialDomainMapping: {},
|
|
67
|
+
});
|
|
68
|
+
// Mock axiosClient.post directly to bypass the retry backoff
|
|
69
|
+
const axiosClientModule = require('../http/axios-client-internal');
|
|
70
|
+
const axiosPostSpy = jest
|
|
71
|
+
.spyOn(axiosClientModule.axiosClient, 'post')
|
|
72
|
+
.mockRejectedValue(new Error('network error'));
|
|
73
|
+
// Act & Assert
|
|
74
|
+
await expect(adapterState.postState()).rejects.toThrow('process.exit called');
|
|
75
|
+
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
76
|
+
axiosPostSpy.mockRestore();
|
|
77
|
+
});
|
|
78
|
+
});
|