@devrev/airsync-sdk 2.0.0-beta.0

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 (180) hide show
  1. package/README.md +31 -0
  2. package/dist/attachments-streaming/attachments-streaming-pool.d.ts +16 -0
  3. package/dist/attachments-streaming/attachments-streaming-pool.d.ts.map +1 -0
  4. package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts +9 -0
  5. package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts.map +1 -0
  6. package/dist/attachments-streaming/attachments-streaming-pool.interfaces.js +2 -0
  7. package/dist/attachments-streaming/attachments-streaming-pool.js +97 -0
  8. package/dist/attachments-streaming/attachments-streaming-pool.test.d.ts +2 -0
  9. package/dist/attachments-streaming/attachments-streaming-pool.test.d.ts.map +1 -0
  10. package/dist/attachments-streaming/attachments-streaming-pool.test.js +267 -0
  11. package/dist/common/constants.d.ts +25 -0
  12. package/dist/common/constants.d.ts.map +1 -0
  13. package/dist/common/constants.js +58 -0
  14. package/dist/common/control-protocol.d.ts +10 -0
  15. package/dist/common/control-protocol.d.ts.map +1 -0
  16. package/dist/common/control-protocol.js +31 -0
  17. package/dist/common/errors.d.ts +6 -0
  18. package/dist/common/errors.d.ts.map +1 -0
  19. package/dist/common/errors.js +4 -0
  20. package/dist/common/event-type-translation.d.ts +24 -0
  21. package/dist/common/event-type-translation.d.ts.map +1 -0
  22. package/dist/common/event-type-translation.js +117 -0
  23. package/dist/common/helpers.d.ts +41 -0
  24. package/dist/common/helpers.d.ts.map +1 -0
  25. package/dist/common/helpers.js +124 -0
  26. package/dist/common/install-initial-domain-mapping.d.ts +4 -0
  27. package/dist/common/install-initial-domain-mapping.d.ts.map +1 -0
  28. package/dist/common/install-initial-domain-mapping.js +58 -0
  29. package/dist/common/install-initial-domain-mapping.test.d.ts +2 -0
  30. package/dist/common/install-initial-domain-mapping.test.d.ts.map +1 -0
  31. package/dist/common/install-initial-domain-mapping.test.js +207 -0
  32. package/dist/deprecated/adapter/index.d.ts +62 -0
  33. package/dist/deprecated/adapter/index.d.ts.map +1 -0
  34. package/dist/deprecated/adapter/index.js +151 -0
  35. package/dist/deprecated/common/helpers.d.ts +7 -0
  36. package/dist/deprecated/common/helpers.d.ts.map +1 -0
  37. package/dist/deprecated/common/helpers.js +47 -0
  38. package/dist/deprecated/demo-extractor/external_domain_metadata.json +38 -0
  39. package/dist/deprecated/demo-extractor/index.d.ts +18 -0
  40. package/dist/deprecated/demo-extractor/index.d.ts.map +1 -0
  41. package/dist/deprecated/demo-extractor/index.js +161 -0
  42. package/dist/deprecated/http/client.d.ts +22 -0
  43. package/dist/deprecated/http/client.d.ts.map +1 -0
  44. package/dist/deprecated/http/client.js +161 -0
  45. package/dist/deprecated/uploader/index.d.ts +35 -0
  46. package/dist/deprecated/uploader/index.d.ts.map +1 -0
  47. package/dist/deprecated/uploader/index.js +161 -0
  48. package/dist/http/axios-client-internal.d.ts +3 -0
  49. package/dist/http/axios-client-internal.d.ts.map +1 -0
  50. package/dist/http/axios-client-internal.js +66 -0
  51. package/dist/http/axios-client-internal.test.d.ts +2 -0
  52. package/dist/http/axios-client-internal.test.d.ts.map +1 -0
  53. package/dist/http/axios-client-internal.test.js +154 -0
  54. package/dist/http/axios-client.d.ts +27 -0
  55. package/dist/http/axios-client.d.ts.map +1 -0
  56. package/dist/http/axios-client.js +57 -0
  57. package/dist/http/constants.d.ts +4 -0
  58. package/dist/http/constants.d.ts.map +1 -0
  59. package/dist/http/constants.js +6 -0
  60. package/dist/http/index.d.ts +3 -0
  61. package/dist/http/index.d.ts.map +1 -0
  62. package/dist/http/index.js +18 -0
  63. package/dist/http/types.d.ts +17 -0
  64. package/dist/http/types.d.ts.map +1 -0
  65. package/dist/http/types.js +2 -0
  66. package/dist/index.d.ts +14 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +34 -0
  69. package/dist/logger/logger.constants.d.ts +6 -0
  70. package/dist/logger/logger.constants.d.ts.map +1 -0
  71. package/dist/logger/logger.constants.js +13 -0
  72. package/dist/logger/logger.context.d.ts +58 -0
  73. package/dist/logger/logger.context.d.ts.map +1 -0
  74. package/dist/logger/logger.context.js +86 -0
  75. package/dist/logger/logger.d.ts +89 -0
  76. package/dist/logger/logger.d.ts.map +1 -0
  77. package/dist/logger/logger.interfaces.d.ts +43 -0
  78. package/dist/logger/logger.interfaces.d.ts.map +1 -0
  79. package/dist/logger/logger.interfaces.js +9 -0
  80. package/dist/logger/logger.js +196 -0
  81. package/dist/logger/logger.test.d.ts +2 -0
  82. package/dist/logger/logger.test.d.ts.map +1 -0
  83. package/dist/logger/logger.test.js +490 -0
  84. package/dist/mappers/mappers.d.ts +52 -0
  85. package/dist/mappers/mappers.d.ts.map +1 -0
  86. package/dist/mappers/mappers.interface.d.ts +294 -0
  87. package/dist/mappers/mappers.interface.d.ts.map +1 -0
  88. package/dist/mappers/mappers.interface.js +48 -0
  89. package/dist/mappers/mappers.js +83 -0
  90. package/dist/mappers/mappers.test.d.ts +2 -0
  91. package/dist/mappers/mappers.test.d.ts.map +1 -0
  92. package/dist/mappers/mappers.test.js +107 -0
  93. package/dist/multithreading/create-worker.d.ts +5 -0
  94. package/dist/multithreading/create-worker.d.ts.map +1 -0
  95. package/dist/multithreading/create-worker.js +28 -0
  96. package/dist/multithreading/create-worker.test.d.ts +2 -0
  97. package/dist/multithreading/create-worker.test.d.ts.map +1 -0
  98. package/dist/multithreading/create-worker.test.js +89 -0
  99. package/dist/multithreading/process-task.d.ts +3 -0
  100. package/dist/multithreading/process-task.d.ts.map +1 -0
  101. package/dist/multithreading/process-task.js +58 -0
  102. package/dist/multithreading/spawn/spawn.d.ts +30 -0
  103. package/dist/multithreading/spawn/spawn.d.ts.map +1 -0
  104. package/dist/multithreading/spawn/spawn.helpers.d.ts +21 -0
  105. package/dist/multithreading/spawn/spawn.helpers.d.ts.map +1 -0
  106. package/dist/multithreading/spawn/spawn.helpers.js +114 -0
  107. package/dist/multithreading/spawn/spawn.helpers.test.d.ts +2 -0
  108. package/dist/multithreading/spawn/spawn.helpers.test.d.ts.map +1 -0
  109. package/dist/multithreading/spawn/spawn.helpers.test.js +293 -0
  110. package/dist/multithreading/spawn/spawn.js +249 -0
  111. package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.d.ts +2 -0
  112. package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.d.ts.map +1 -0
  113. package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.js +127 -0
  114. package/dist/multithreading/worker-adapter/worker-adapter.d.ts +91 -0
  115. package/dist/multithreading/worker-adapter/worker-adapter.d.ts.map +1 -0
  116. package/dist/multithreading/worker-adapter/worker-adapter.helpers.d.ts +22 -0
  117. package/dist/multithreading/worker-adapter/worker-adapter.helpers.d.ts.map +1 -0
  118. package/dist/multithreading/worker-adapter/worker-adapter.helpers.js +64 -0
  119. package/dist/multithreading/worker-adapter/worker-adapter.helpers.test.d.ts +2 -0
  120. package/dist/multithreading/worker-adapter/worker-adapter.helpers.test.d.ts.map +1 -0
  121. package/dist/multithreading/worker-adapter/worker-adapter.helpers.test.js +514 -0
  122. package/dist/multithreading/worker-adapter/worker-adapter.js +747 -0
  123. package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts +2 -0
  124. package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts.map +1 -0
  125. package/dist/multithreading/worker-adapter/worker-adapter.test.js +483 -0
  126. package/dist/multithreading/worker.d.ts +2 -0
  127. package/dist/multithreading/worker.d.ts.map +1 -0
  128. package/dist/multithreading/worker.js +9 -0
  129. package/dist/repo/repo.d.ts +18 -0
  130. package/dist/repo/repo.d.ts.map +1 -0
  131. package/dist/repo/repo.interfaces.d.ts +46 -0
  132. package/dist/repo/repo.interfaces.d.ts.map +1 -0
  133. package/dist/repo/repo.interfaces.js +2 -0
  134. package/dist/repo/repo.js +75 -0
  135. package/dist/repo/repo.test.d.ts +2 -0
  136. package/dist/repo/repo.test.d.ts.map +1 -0
  137. package/dist/repo/repo.test.js +131 -0
  138. package/dist/state/state.d.ts +30 -0
  139. package/dist/state/state.d.ts.map +1 -0
  140. package/dist/state/state.interfaces.d.ts +51 -0
  141. package/dist/state/state.interfaces.d.ts.map +1 -0
  142. package/dist/state/state.interfaces.js +21 -0
  143. package/dist/state/state.js +166 -0
  144. package/dist/state/state.test.d.ts +2 -0
  145. package/dist/state/state.test.d.ts.map +1 -0
  146. package/dist/state/state.test.js +224 -0
  147. package/dist/types/common.d.ts +50 -0
  148. package/dist/types/common.d.ts.map +1 -0
  149. package/dist/types/common.js +25 -0
  150. package/dist/types/extraction.d.ts +417 -0
  151. package/dist/types/extraction.d.ts.map +1 -0
  152. package/dist/types/extraction.js +170 -0
  153. package/dist/types/extraction.test.d.ts +2 -0
  154. package/dist/types/extraction.test.d.ts.map +1 -0
  155. package/dist/types/extraction.test.js +70 -0
  156. package/dist/types/index.d.ts +9 -0
  157. package/dist/types/index.d.ts.map +1 -0
  158. package/dist/types/index.js +18 -0
  159. package/dist/types/loading.d.ts +147 -0
  160. package/dist/types/loading.d.ts.map +1 -0
  161. package/dist/types/loading.js +48 -0
  162. package/dist/types/workers.d.ts +161 -0
  163. package/dist/types/workers.d.ts.map +1 -0
  164. package/dist/types/workers.js +22 -0
  165. package/dist/uploader/uploader.d.ts +92 -0
  166. package/dist/uploader/uploader.d.ts.map +1 -0
  167. package/dist/uploader/uploader.helpers.d.ts +33 -0
  168. package/dist/uploader/uploader.helpers.d.ts.map +1 -0
  169. package/dist/uploader/uploader.helpers.js +139 -0
  170. package/dist/uploader/uploader.helpers.test.d.ts +2 -0
  171. package/dist/uploader/uploader.helpers.test.d.ts.map +1 -0
  172. package/dist/uploader/uploader.helpers.test.js +267 -0
  173. package/dist/uploader/uploader.interfaces.d.ts +95 -0
  174. package/dist/uploader/uploader.interfaces.d.ts.map +1 -0
  175. package/dist/uploader/uploader.interfaces.js +2 -0
  176. package/dist/uploader/uploader.js +305 -0
  177. package/dist/uploader/uploader.test.d.ts +2 -0
  178. package/dist/uploader/uploader.test.d.ts.map +1 -0
  179. package/dist/uploader/uploader.test.js +589 -0
  180. package/package.json +60 -0
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const constants_1 = require("../common/constants");
4
+ const test_helpers_1 = require("../tests/test-helpers");
5
+ const types_1 = require("../types");
6
+ const repo_1 = require("./repo");
7
+ jest.mock('../tests/test-helpers', () => (Object.assign(Object.assign({}, jest.requireActual('../tests/test-helpers')), { normalizeItem: jest.fn() })));
8
+ describe(repo_1.Repo.name, () => {
9
+ let repo;
10
+ let normalize;
11
+ beforeEach(() => {
12
+ normalize = jest.fn();
13
+ repo = new repo_1.Repo({
14
+ event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
15
+ itemType: 'test_item_type',
16
+ normalize,
17
+ onUpload: jest.fn(),
18
+ });
19
+ });
20
+ afterEach(() => {
21
+ jest.clearAllMocks();
22
+ });
23
+ it('should normalize and push items when array contains items', async () => {
24
+ const items = (0, test_helpers_1.createItems)(10);
25
+ await repo.push(items);
26
+ expect(normalize).toHaveBeenCalledTimes(10);
27
+ const normalizedItems = items.map((item) => (0, test_helpers_1.normalizeItem)(item));
28
+ expect(repo.getItems()).toEqual(normalizedItems);
29
+ });
30
+ it('should not normalize items when normalize function is not provided', async () => {
31
+ repo = new repo_1.Repo({
32
+ event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
33
+ itemType: 'test_item_type',
34
+ onUpload: jest.fn(),
35
+ options: {},
36
+ });
37
+ const items = (0, test_helpers_1.createItems)(10);
38
+ await repo.push(items);
39
+ expect(normalize).not.toHaveBeenCalled();
40
+ });
41
+ it('[edge] should not push items when items array is empty', async () => {
42
+ await repo.push([]);
43
+ expect(repo.getItems()).toEqual([]);
44
+ });
45
+ it('should not normalize items when item type is external_domain_metadata', async () => {
46
+ repo = new repo_1.Repo({
47
+ event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
48
+ itemType: constants_1.AIRDROP_DEFAULT_ITEM_TYPES.EXTERNAL_DOMAIN_METADATA,
49
+ normalize,
50
+ onUpload: jest.fn(),
51
+ options: {},
52
+ });
53
+ const items = (0, test_helpers_1.createItems)(10);
54
+ await repo.push(items);
55
+ expect(normalize).not.toHaveBeenCalled();
56
+ });
57
+ it('should not normalize items when item type is ssor_attachment', async () => {
58
+ repo = new repo_1.Repo({
59
+ event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
60
+ itemType: constants_1.AIRDROP_DEFAULT_ITEM_TYPES.SSOR_ATTACHMENT,
61
+ normalize,
62
+ onUpload: jest.fn(),
63
+ options: {},
64
+ });
65
+ const items = (0, test_helpers_1.createItems)(10);
66
+ await repo.push(items);
67
+ expect(normalize).not.toHaveBeenCalled();
68
+ });
69
+ it('should leave 5 items in the items array after pushing 2005 items with batch size of 2000', async () => {
70
+ const items = (0, test_helpers_1.createItems)(2005);
71
+ await repo.push(items);
72
+ expect(repo.getItems().length).toBe(5);
73
+ });
74
+ it('should normalize all items when pushing 4005 items with batch size of 2000', async () => {
75
+ const items = (0, test_helpers_1.createItems)(4005);
76
+ await repo.push(items);
77
+ expect(normalize).toHaveBeenCalledTimes(4005);
78
+ });
79
+ it('should upload 2 batches when pushing 4005 items with batch size of 2000', async () => {
80
+ const uploadSpy = jest.spyOn(repo, 'upload');
81
+ const items = (0, test_helpers_1.createItems)(4005);
82
+ await repo.push(items);
83
+ expect(uploadSpy).toHaveBeenCalledTimes(2);
84
+ uploadSpy.mockRestore();
85
+ });
86
+ it('should leave 5 items in array after pushing 4005 items with batch size of 2000', async () => {
87
+ const items = (0, test_helpers_1.createItems)(4005);
88
+ await repo.push(items);
89
+ expect(repo.getItems().length).toBe(5);
90
+ });
91
+ describe('should take batch size into account', () => {
92
+ beforeEach(() => {
93
+ repo = new repo_1.Repo({
94
+ event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
95
+ itemType: 'test_item_type',
96
+ normalize,
97
+ onUpload: jest.fn(),
98
+ options: {
99
+ batchSize: 50,
100
+ },
101
+ });
102
+ });
103
+ it('should empty the items array after pushing 50 items with batch size of 50', async () => {
104
+ const items = (0, test_helpers_1.createItems)(50);
105
+ await repo.push(items);
106
+ expect(repo.getItems()).toEqual([]);
107
+ });
108
+ it('should leave 5 items in the items array after pushing 205 items with batch size of 50', async () => {
109
+ const items = (0, test_helpers_1.createItems)(205);
110
+ await repo.push(items);
111
+ expect(repo.getItems().length).toBe(5);
112
+ });
113
+ it('should normalize all items when pushing 205 items with batch size of 50', async () => {
114
+ const items = (0, test_helpers_1.createItems)(205);
115
+ await repo.push(items);
116
+ expect(normalize).toHaveBeenCalledTimes(205);
117
+ });
118
+ it('should upload 4 batches when pushing 205 items with batch size of 50', async () => {
119
+ const uploadSpy = jest.spyOn(repo, 'upload');
120
+ const items = (0, test_helpers_1.createItems)(205);
121
+ await repo.push(items);
122
+ expect(uploadSpy).toHaveBeenCalledTimes(4);
123
+ uploadSpy.mockRestore();
124
+ });
125
+ it('should leave 5 items in array after pushing 205 items with batch size of 50', async () => {
126
+ const items = (0, test_helpers_1.createItems)(205);
127
+ await repo.push(items);
128
+ expect(repo.getItems().length).toBe(5);
129
+ });
130
+ });
131
+ });
@@ -0,0 +1,30 @@
1
+ import { AdapterState, StateInterface } from './state.interfaces';
2
+ export declare function createAdapterState<ConnectorState>({ event, initialState, initialDomainMapping, options, }: StateInterface<ConnectorState>): Promise<State<ConnectorState>>;
3
+ export declare class State<ConnectorState> {
4
+ private _state;
5
+ private initialSdkState;
6
+ private workerUrl;
7
+ private devrevToken;
8
+ private syncUnitId;
9
+ private requestId;
10
+ constructor({ event, initialState }: StateInterface<ConnectorState>);
11
+ get state(): AdapterState<ConnectorState>;
12
+ set state(value: AdapterState<ConnectorState>);
13
+ /**
14
+ * Initializes the state for this adapter instance by fetching from API
15
+ * or creating an initial state if none exists (404).
16
+ * @param initialState The initial connector state provided by the spawn function
17
+ */
18
+ init(initialState: ConnectorState): Promise<void>;
19
+ /**
20
+ * Updates the state of the adapter by posting to API.
21
+ * @param {object} state - The state to be updated
22
+ */
23
+ postState(state?: AdapterState<ConnectorState>): Promise<void>;
24
+ /**
25
+ * Fetches the state of the adapter from API.
26
+ * @return The raw state data from API
27
+ */
28
+ fetchState(): Promise<string>;
29
+ }
30
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/state/state.ts"],"names":[],"mappings":"AASA,OAAO,EACL,YAAY,EAIZ,cAAc,EACf,MAAM,oBAAoB,CAAC;AAE5B,wBAAsB,kBAAkB,CAAC,cAAc,EAAE,EACvD,KAAK,EACL,YAAY,EACZ,oBAAoB,EACpB,OAAO,GACR,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CA0DjE;AAED,qBAAa,KAAK,CAAC,cAAc;IAC/B,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,eAAe,CAAW;IAClC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;gBAEd,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,cAAc,CAAC,cAAc,CAAC;IAenE,IAAI,KAAK,IAAI,YAAY,CAAC,cAAc,CAAC,CAExC;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,YAAY,CAAC,cAAc,CAAC,EAE5C;IAED;;;;OAIG;IACG,IAAI,CAAC,YAAY,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCvD;;;OAGG;IACG,SAAS,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC,cAAc,CAAC;IAuCpD;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;CAkBpC"}
@@ -0,0 +1,51 @@
1
+ import { InitialDomainMapping } from '../types/common';
2
+ import { AirdropEvent } from '../types/extraction';
3
+ import { FileToLoad } from '../types/loading';
4
+ import { WorkerAdapterOptions } from '../types/workers';
5
+ export interface SdkState {
6
+ lastSyncStarted?: string;
7
+ lastSuccessfulSyncStarted?: string;
8
+ toDevRev?: ToDevRev;
9
+ fromDevRev?: FromDevRev;
10
+ snapInVersionId?: string;
11
+ }
12
+ /**
13
+ * AdapterState is an interface that defines the structure of the adapter state that is used by the external extractor.
14
+ * It extends the connector state with additional fields: lastSyncStarted, lastSuccessfulSyncStarted, snapInVersionId and attachmentsMetadata.
15
+ */
16
+ export type AdapterState<ConnectorState> = ConnectorState & SdkState;
17
+ export interface ToDevRev {
18
+ attachmentsMetadata: {
19
+ artifactIds: string[];
20
+ lastProcessed: number;
21
+ lastProcessedAttachmentsIdsList?: string[];
22
+ };
23
+ }
24
+ export interface FromDevRev {
25
+ filesToLoad: FileToLoad[];
26
+ }
27
+ export interface StateInterface<ConnectorState> {
28
+ event: AirdropEvent;
29
+ initialState: ConnectorState;
30
+ initialDomainMapping?: InitialDomainMapping;
31
+ options?: WorkerAdapterOptions;
32
+ }
33
+ export declare const extractionSdkState: {
34
+ lastSyncStarted: string;
35
+ lastSuccessfulSyncStarted: string;
36
+ snapInVersionId: string;
37
+ toDevRev: {
38
+ attachmentsMetadata: {
39
+ artifactIds: never[];
40
+ lastProcessed: number;
41
+ lastProcessedAttachmentsIdsList: never[];
42
+ };
43
+ };
44
+ };
45
+ export declare const loadingSdkState: {
46
+ snapInVersionId: string;
47
+ fromDevRev: {
48
+ filesToLoad: never[];
49
+ };
50
+ };
51
+ //# sourceMappingURL=state.interfaces.d.ts.map
@@ -0,0 +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,QAAQ;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,cAAc,IAAI,cAAc,GAAG,QAAQ,CAAC;AAErE,MAAM,WAAW,QAAQ;IACvB,mBAAmB,EAAE;QACnB,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,+BAA+B,CAAC,EAAE,MAAM,EAAE,CAAC;KAC5C,CAAC;CACH;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,kBAAkB;;;;;;;;;;;CAW9B,CAAC;AAEF,eAAO,MAAM,eAAe;;;;;CAK3B,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadingSdkState = exports.extractionSdkState = void 0;
4
+ exports.extractionSdkState = {
5
+ lastSyncStarted: '',
6
+ lastSuccessfulSyncStarted: '',
7
+ snapInVersionId: '',
8
+ toDevRev: {
9
+ attachmentsMetadata: {
10
+ artifactIds: [],
11
+ lastProcessed: 0,
12
+ lastProcessedAttachmentsIdsList: [],
13
+ },
14
+ },
15
+ };
16
+ exports.loadingSdkState = {
17
+ snapInVersionId: '',
18
+ fromDevRev: {
19
+ filesToLoad: [],
20
+ },
21
+ };
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.State = void 0;
7
+ exports.createAdapterState = createAdapterState;
8
+ const axios_1 = __importDefault(require("axios"));
9
+ const constants_1 = require("../common/constants");
10
+ const install_initial_domain_mapping_1 = require("../common/install-initial-domain-mapping");
11
+ const axios_client_internal_1 = require("../http/axios-client-internal");
12
+ const logger_1 = require("../logger/logger");
13
+ const common_1 = require("../types/common");
14
+ const extraction_1 = require("../types/extraction");
15
+ const state_interfaces_1 = require("./state.interfaces");
16
+ async function createAdapterState({ event, initialState, initialDomainMapping, options, }) {
17
+ // Deep clone the initial state to avoid mutating the original state
18
+ const deepCloneInitialState = structuredClone(initialState);
19
+ const as = new State({
20
+ event,
21
+ initialState: deepCloneInitialState,
22
+ initialDomainMapping,
23
+ options,
24
+ });
25
+ if (!constants_1.STATELESS_EVENT_TYPES.includes(event.payload.event_type)) {
26
+ await as.init(deepCloneInitialState);
27
+ // Check if IDM needs to be updated
28
+ const snapInVersionId = event.context.snap_in_version_id;
29
+ const hasSnapInVersionInState = 'snapInVersionId' in as.state;
30
+ const shouldUpdateIDM = !hasSnapInVersionInState || as.state.snapInVersionId !== snapInVersionId;
31
+ if (!shouldUpdateIDM) {
32
+ console.log(`Snap-in version in state matches the version in event context "${snapInVersionId}". Skipping initial domain mapping installation.`);
33
+ }
34
+ else {
35
+ try {
36
+ console.log(`Snap-in version in state "${as.state.snapInVersionId}" does not match the version in event context "${snapInVersionId}". Installing initial domain mapping.`);
37
+ if (initialDomainMapping) {
38
+ await (0, install_initial_domain_mapping_1.installInitialDomainMapping)(event, initialDomainMapping);
39
+ as.state.snapInVersionId = snapInVersionId;
40
+ }
41
+ else {
42
+ throw new Error('No initial domain mapping was passed to spawn function. Skipping initial domain mapping installation.');
43
+ }
44
+ }
45
+ catch (error) {
46
+ console.error('Error while installing initial domain mapping.', (0, logger_1.serializeError)(error));
47
+ process.exit(1);
48
+ }
49
+ }
50
+ // Set lastSyncStarted if the event type is StartExtractingData
51
+ if (event.payload.event_type === extraction_1.EventType.StartExtractingData &&
52
+ !as.state.lastSyncStarted) {
53
+ as.state.lastSyncStarted = new Date().toISOString();
54
+ console.log(`Setting lastSyncStarted to ${as.state.lastSyncStarted}.`);
55
+ }
56
+ }
57
+ return as;
58
+ }
59
+ class State {
60
+ constructor({ event, initialState }) {
61
+ this.initialSdkState =
62
+ event.payload.event_context.mode === common_1.SyncMode.LOADING
63
+ ? state_interfaces_1.loadingSdkState
64
+ : state_interfaces_1.extractionSdkState;
65
+ this._state = Object.assign(Object.assign({}, initialState), this.initialSdkState);
66
+ this.workerUrl = event.payload.event_context.worker_data_url;
67
+ this.devrevToken = event.context.secrets.service_account_token;
68
+ this.syncUnitId = event.payload.event_context.sync_unit_id;
69
+ this.requestId = event.payload.event_context.request_id_adaas;
70
+ }
71
+ get state() {
72
+ return this._state;
73
+ }
74
+ set state(value) {
75
+ this._state = value;
76
+ }
77
+ /**
78
+ * Initializes the state for this adapter instance by fetching from API
79
+ * or creating an initial state if none exists (404).
80
+ * @param initialState The initial connector state provided by the spawn function
81
+ */
82
+ async init(initialState) {
83
+ var _a;
84
+ try {
85
+ const stringifiedState = await this.fetchState();
86
+ if (!stringifiedState) {
87
+ throw new Error('No state found in response.');
88
+ }
89
+ let parsedState;
90
+ try {
91
+ parsedState = JSON.parse(stringifiedState);
92
+ }
93
+ catch (error) {
94
+ throw new Error(`Failed to parse state. ${error}`);
95
+ }
96
+ this.state = parsedState;
97
+ console.log('State fetched successfully. Current state', (0, logger_1.getPrintableState)(this.state));
98
+ }
99
+ catch (error) {
100
+ if (axios_1.default.isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
101
+ console.log('State not found. Initializing state with initial state.');
102
+ const initialAdapterState = Object.assign(Object.assign({}, initialState), this.initialSdkState);
103
+ this.state = initialAdapterState;
104
+ await this.postState(initialAdapterState);
105
+ }
106
+ else {
107
+ console.error('Failed to init state.', (0, logger_1.serializeError)(error));
108
+ process.exit(1);
109
+ }
110
+ }
111
+ }
112
+ /**
113
+ * Updates the state of the adapter by posting to API.
114
+ * @param {object} state - The state to be updated
115
+ */
116
+ async postState(state) {
117
+ const url = this.workerUrl + '.update';
118
+ this.state = state || this.state;
119
+ let stringifiedState;
120
+ try {
121
+ stringifiedState = JSON.stringify(this.state);
122
+ }
123
+ catch (error) {
124
+ console.error('Failed to stringify state.', (0, logger_1.serializeError)(error));
125
+ process.exit(1);
126
+ }
127
+ try {
128
+ await axios_client_internal_1.axiosClient.post(url, {
129
+ state: stringifiedState,
130
+ }, {
131
+ headers: {
132
+ Authorization: this.devrevToken,
133
+ },
134
+ params: {
135
+ sync_unit: this.syncUnitId,
136
+ request_id: this.requestId,
137
+ },
138
+ });
139
+ console.log('State updated successfully to', (0, logger_1.getPrintableState)(this.state));
140
+ }
141
+ catch (error) {
142
+ console.error('Failed to update the state.', (0, logger_1.serializeError)(error));
143
+ process.exit(1);
144
+ }
145
+ }
146
+ /**
147
+ * Fetches the state of the adapter from API.
148
+ * @return The raw state data from API
149
+ */
150
+ async fetchState() {
151
+ var _a;
152
+ console.log(`Fetching state with sync unit id ${this.syncUnitId} and request id ${this.requestId}.`);
153
+ const url = this.workerUrl + '.get';
154
+ const response = await axios_client_internal_1.axiosClient.get(url, {
155
+ headers: {
156
+ Authorization: this.devrevToken,
157
+ },
158
+ params: {
159
+ sync_unit: this.syncUnitId,
160
+ request_id: this.requestId,
161
+ },
162
+ });
163
+ return (_a = response.data) === null || _a === void 0 ? void 0 : _a.state;
164
+ }
165
+ }
166
+ exports.State = State;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=state.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.test.d.ts","sourceRoot":"","sources":["../../src/state/state.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const constants_1 = require("../common/constants");
4
+ const test_helpers_1 = require("../tests/test-helpers");
5
+ const extraction_1 = require("../types/extraction");
6
+ const state_1 = require("./state");
7
+ const state_interfaces_1 = require("./state.interfaces");
8
+ /* eslint-disable @typescript-eslint/no-require-imports */
9
+ describe(state_1.State.name, () => {
10
+ let initSpy;
11
+ let postStateSpy;
12
+ let fetchStateSpy;
13
+ let installInitialDomainMappingSpy;
14
+ let processExitSpy;
15
+ beforeEach(() => {
16
+ jest.clearAllMocks();
17
+ jest.restoreAllMocks();
18
+ initSpy = jest.spyOn(state_1.State.prototype, 'init');
19
+ postStateSpy = jest.spyOn(state_1.State.prototype, 'postState');
20
+ fetchStateSpy = jest.spyOn(state_1.State.prototype, 'fetchState');
21
+ installInitialDomainMappingSpy = jest.spyOn(require('../common/install-initial-domain-mapping'), 'installInitialDomainMapping');
22
+ processExitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {
23
+ throw new Error('process.exit called');
24
+ });
25
+ });
26
+ it.each(constants_1.STATELESS_EVENT_TYPES)('should not init, fetch, post or install IDM for stateless event type %s', async (eventType) => {
27
+ // Arrange
28
+ const event = (0, test_helpers_1.createEvent)({
29
+ eventType: eventType,
30
+ });
31
+ // Act
32
+ await (0, state_1.createAdapterState)({
33
+ event,
34
+ initialState: {},
35
+ initialDomainMapping: {},
36
+ });
37
+ // Assert
38
+ expect(initSpy).not.toHaveBeenCalled();
39
+ expect(fetchStateSpy).not.toHaveBeenCalled();
40
+ expect(postStateSpy).not.toHaveBeenCalled();
41
+ expect(installInitialDomainMappingSpy).not.toHaveBeenCalled();
42
+ });
43
+ it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if fetching the state fails', async (eventType) => {
44
+ // Arrange
45
+ const event = (0, test_helpers_1.createEvent)({
46
+ eventType: eventType,
47
+ });
48
+ fetchStateSpy.mockRejectedValue({
49
+ isAxiosError: true,
50
+ response: { status: 500 },
51
+ });
52
+ jest.spyOn(console, 'error').mockImplementation(() => { });
53
+ // Act & Assert
54
+ await expect((0, state_1.createAdapterState)({
55
+ event,
56
+ initialState: {},
57
+ initialDomainMapping: {},
58
+ })).rejects.toThrow('process.exit called');
59
+ expect(processExitSpy).toHaveBeenCalledWith(1);
60
+ });
61
+ it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if parsing the state fails', async (eventType) => {
62
+ // Arrange
63
+ const event = (0, test_helpers_1.createEvent)({
64
+ eventType: eventType,
65
+ });
66
+ fetchStateSpy.mockResolvedValue('invalid-json');
67
+ jest.spyOn(console, 'error').mockImplementation(() => { });
68
+ // Act & Assert
69
+ await expect((0, state_1.createAdapterState)({
70
+ event,
71
+ initialState: {},
72
+ initialDomainMapping: {},
73
+ })).rejects.toThrow('process.exit called');
74
+ expect(processExitSpy).toHaveBeenCalledWith(1);
75
+ });
76
+ 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) => {
77
+ // Arrange
78
+ const event = (0, test_helpers_1.createEvent)({
79
+ eventType: eventType,
80
+ });
81
+ fetchStateSpy.mockResolvedValue(null);
82
+ jest.spyOn(console, 'error').mockImplementation(() => { });
83
+ // Act & Assert
84
+ await expect((0, state_1.createAdapterState)({
85
+ event,
86
+ initialState: {},
87
+ initialDomainMapping: {},
88
+ })).rejects.toThrow('process.exit called');
89
+ expect(processExitSpy).toHaveBeenCalledWith(1);
90
+ });
91
+ it.each(constants_1.STATEFUL_EVENT_TYPES.filter((eventType) => eventType !== extraction_1.EventType.StartExtractingData))('should call post state with full adapter state if fetching returns 404 for event type %s', async (eventType) => {
92
+ // Arrange
93
+ const initialState = {
94
+ test: 'test',
95
+ };
96
+ const event = (0, test_helpers_1.createEvent)({
97
+ eventType: eventType,
98
+ contextOverrides: {
99
+ snap_in_version_id: '',
100
+ },
101
+ });
102
+ fetchStateSpy.mockRejectedValue({
103
+ isAxiosError: true,
104
+ response: { status: 404 },
105
+ });
106
+ installInitialDomainMappingSpy.mockResolvedValue({
107
+ success: true,
108
+ });
109
+ postStateSpy.mockResolvedValue({
110
+ success: true,
111
+ });
112
+ jest.spyOn(console, 'log').mockImplementation(() => { });
113
+ // Act
114
+ await (0, state_1.createAdapterState)({
115
+ event,
116
+ initialState,
117
+ initialDomainMapping: {},
118
+ });
119
+ const expectedState = Object.assign(Object.assign({}, initialState), state_interfaces_1.extractionSdkState);
120
+ expect(postStateSpy).toHaveBeenCalledWith(expectedState);
121
+ });
122
+ it(extraction_1.EventType.StartExtractingData, async () => {
123
+ // Arrange
124
+ const initialState = {
125
+ test: 'test',
126
+ };
127
+ const event = (0, test_helpers_1.createEvent)({
128
+ eventType: extraction_1.EventType.StartExtractingData,
129
+ contextOverrides: {
130
+ snap_in_version_id: '',
131
+ },
132
+ });
133
+ fetchStateSpy.mockRejectedValue({
134
+ isAxiosError: true,
135
+ response: { status: 404 },
136
+ });
137
+ installInitialDomainMappingSpy.mockResolvedValue({
138
+ success: true,
139
+ });
140
+ postStateSpy.mockResolvedValue({
141
+ success: true,
142
+ });
143
+ jest.spyOn(console, 'log').mockImplementation(() => { });
144
+ // Act
145
+ await (0, state_1.createAdapterState)({
146
+ event,
147
+ initialState,
148
+ initialDomainMapping: {},
149
+ });
150
+ // Assert
151
+ // Verify that post state is called with object that contains
152
+ // lastSyncStarted which is not empty string
153
+ expect(postStateSpy).toHaveBeenCalledWith(expect.objectContaining({
154
+ lastSyncStarted: expect.not.stringMatching(/^$/),
155
+ }));
156
+ });
157
+ it.each(constants_1.STATEFUL_EVENT_TYPES)('should exit the process if initialDomainMapping is not provided for event type %s', async (eventType) => {
158
+ // Arrange
159
+ const event = (0, test_helpers_1.createEvent)({
160
+ eventType: eventType,
161
+ });
162
+ fetchStateSpy.mockResolvedValue(JSON.stringify({
163
+ test: 'test',
164
+ }));
165
+ jest.spyOn(console, 'log').mockImplementation(() => { });
166
+ jest.spyOn(console, 'error').mockImplementation(() => { });
167
+ // Act & Assert
168
+ await expect((0, state_1.createAdapterState)({
169
+ event,
170
+ initialState: {},
171
+ initialDomainMapping: undefined,
172
+ })).rejects.toThrow('process.exit called');
173
+ expect(processExitSpy).toHaveBeenCalledWith(1);
174
+ });
175
+ it.each(constants_1.STATEFUL_EVENT_TYPES)('should not install IDM if version matches for event type %s', async (eventType) => {
176
+ // Arrange
177
+ const event = (0, test_helpers_1.createEvent)({
178
+ eventType: eventType,
179
+ contextOverrides: {
180
+ snap_in_version_id: '1.0.0',
181
+ },
182
+ });
183
+ const stringifiedState = JSON.stringify({
184
+ test: 'test',
185
+ snapInVersionId: '1.0.0',
186
+ });
187
+ fetchStateSpy.mockResolvedValue(stringifiedState);
188
+ jest.spyOn(console, 'log').mockImplementation(() => { });
189
+ // Act & Assert
190
+ await (0, state_1.createAdapterState)({
191
+ event,
192
+ initialState: {},
193
+ initialDomainMapping: {},
194
+ });
195
+ // Assert
196
+ expect(installInitialDomainMappingSpy).not.toHaveBeenCalled();
197
+ });
198
+ it.each(constants_1.STATEFUL_EVENT_TYPES)('should install IDM if version does not match for event type %s', async (eventType) => {
199
+ // Arrange
200
+ const event = (0, test_helpers_1.createEvent)({
201
+ eventType: eventType,
202
+ contextOverrides: {
203
+ snap_in_version_id: '2.0.0',
204
+ },
205
+ });
206
+ const stringifiedState = JSON.stringify({
207
+ test: 'test',
208
+ snapInVersionId: '1.0.0',
209
+ });
210
+ fetchStateSpy.mockResolvedValue(stringifiedState);
211
+ installInitialDomainMappingSpy.mockResolvedValue({
212
+ success: true,
213
+ });
214
+ jest.spyOn(console, 'log').mockImplementation(() => { });
215
+ // Act
216
+ await (0, state_1.createAdapterState)({
217
+ event,
218
+ initialState: {},
219
+ initialDomainMapping: {},
220
+ });
221
+ // Assert
222
+ expect(installInitialDomainMappingSpy).toHaveBeenCalled();
223
+ });
224
+ });