@devrev/ts-adaas 0.0.1 → 0.0.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.
Files changed (41) hide show
  1. package/README.md +20 -4
  2. package/dist/src/adapter/index.d.ts +35 -30
  3. package/dist/src/adapter/index.js +93 -56
  4. package/dist/src/common/constants.d.ts +2 -0
  5. package/dist/src/common/constants.js +10 -0
  6. package/dist/src/{adapter → common}/helpers.d.ts +4 -1
  7. package/dist/src/{adapter → common}/helpers.js +16 -4
  8. package/dist/src/common/install-initial-domain-mapping.d.ts +3 -0
  9. package/dist/src/common/install-initial-domain-mapping.js +60 -0
  10. package/dist/src/demo-extractor/external_domain_metadata.json +38 -0
  11. package/dist/src/demo-extractor/index.d.ts +8 -1
  12. package/dist/src/demo-extractor/index.js +79 -73
  13. package/dist/src/http/client.d.ts +1 -1
  14. package/dist/src/http/client.js +2 -2
  15. package/dist/src/http/index.d.ts +0 -1
  16. package/dist/src/http/index.js +0 -1
  17. package/dist/src/index.d.ts +2 -0
  18. package/dist/src/index.js +2 -0
  19. package/dist/src/logging/index.d.ts +5 -18
  20. package/dist/src/logging/index.js +20 -41
  21. package/dist/src/state/index.d.ts +23 -0
  22. package/dist/src/state/index.js +111 -0
  23. package/dist/src/types/common.d.ts +4 -0
  24. package/dist/src/types/extraction.d.ts +17 -5
  25. package/dist/src/uploader/index.d.ts +4 -2
  26. package/dist/src/uploader/index.js +61 -4
  27. package/dist/tests/adapter.helpers.test.js +60 -0
  28. package/dist/tests/adapter.test.js +107 -57
  29. package/dist/tests/demo-extractor.test.js +45 -81
  30. package/dist/tests/state.test.js +101 -0
  31. package/dist/tests/uploader.test.js +29 -0
  32. package/package.json +1 -1
  33. package/dist/src/adapter/index.test.js +0 -105
  34. package/dist/src/demo-extractor/recipe.json +0 -37
  35. package/dist/tests/helpers.test.js +0 -38
  36. package/dist/tests/test-helpers.d.ts +0 -2
  37. package/dist/tests/test-helpers.js +0 -33
  38. package/dist/tests/types.test.js +0 -71
  39. /package/dist/{src/adapter/index.test.d.ts → tests/adapter.helpers.test.d.ts} +0 -0
  40. /package/dist/tests/{helpers.test.d.ts → state.test.d.ts} +0 -0
  41. /package/dist/tests/{types.test.d.ts → uploader.test.d.ts} +0 -0
package/README.md CHANGED
@@ -1,14 +1,30 @@
1
1
  # ADaaS Library
2
2
 
3
-
4
- # ADaaS Library
5
-
6
3
  Typescript ADaaS Library (@devrev/ts-adaas) provides:
7
4
 
8
5
  - type definitions for ADaaS control protocol,
9
6
  - an adapter for ADaaS control protocol,
10
7
  - helpers for uploading artifacts and manage the state for ADaaS snap-in.
11
8
 
9
+ ## Release Notes
10
+
11
+ #### v0.0.3
12
+
13
+ - Support for new recipe management
14
+
15
+ #### v0.0.2
16
+
17
+ - Support for the State API
18
+ - HTTP client for API requests
19
+ - Local development environment creates local artifact files
20
+ - Improvements in logging
21
+
22
+ #### v0.0.1
23
+
24
+ - Demo implementation of ADaaS snap-in
25
+ - Adapter for ADaaS control protocol with helper functions
26
+ - Uploader for uploading artifacts
27
+
12
28
  ## Usage
13
29
 
14
30
  Create a new ADaaS adapter on each ADaaS snap-in invocation:
@@ -160,4 +176,4 @@ By managing its own state, the ADaaS snap-in keeps track of the process of extra
160
176
 
161
177
  ```typescript
162
178
  async update({ artifacts, extractor_state}: AdapterUpdateParams)
163
- ```
179
+ ```
@@ -1,42 +1,43 @@
1
- import { Artifact, AirdropEvent, ExtractorEventType, EventData } from '../types';
2
- import { AdapterUpdateParams } from '../types/common';
1
+ import { AirdropEvent, ExtractorEventType, EventData, AdapterState, Artifact } from '../types';
2
+ import { State } from '../state';
3
3
  /**
4
4
  * Adapter class is used to interact with Airdrop platform. The class provides
5
5
  * utilities to
6
6
  * - emit control events to the platform
7
7
  * - update the state of the extractor
8
- * - add artifacts to the list of artifacts to be returned to the platform
9
- * - Return the last saved state and artifacts in case timeout
10
- * - The event sent in case of timeout for each event type is as follows:
11
- * - EXTRACTION_EXTERNAL_SYNC_UNITS_START => EXTRACTION_EXTERNAL_SYNC_UNITS_ERROR
12
- * - EXTRACTION_METADATA_START => EXTRACTION_METADATA_ERROR
13
- * - EXTRACTION_DATA_START => EXTRACTION_DATA_PROGRESS
14
- * - EXTRACTION_DATA_CONTINUE => EXTRACTION_DATA_PROGRESS
15
- * - EXTRACTION_ATTACHMENTS_START => EXTRACTION_ATTACHMENTS_PROGRESS
16
- * - EXTRACTION_ATTACHMENTS_CONTINUE => EXTRACTION_ATTACHMENTS_PROGRESS
8
+ * - set the last saved state in case of a timeout
17
9
  *
18
10
  * @class Adapter
19
11
  * @constructor
20
12
  * @param {AirdropEvent} event - The event object received from the platform
21
- * @param {object=} state - Optional state object to be passed to the extractor. If not provided, an empty object is used.
13
+ * @param {object=} initialState - The initial state of the adapter
14
+ * @param {boolean=} isLocalDevelopment - A flag to indicate if the adapter is being used in local development
22
15
  */
23
- export declare class Adapter {
24
- private artifacts;
25
- /** Adapter level state to return to the platform */
26
- private extractorState;
16
+ /**
17
+ * Creates an adapter instance.
18
+ *
19
+ * @param {AirdropEvent} event - The event object received from the platform
20
+ * @param initialState
21
+ * @param {boolean=} isLocalDevelopment - A flag to indicate if the adapter is being used in local development
22
+ * @return The adapter instance
23
+ */
24
+ export declare function createAdapter<ExtractorState>(event: AirdropEvent, initialState: ExtractorState, isLocalDevelopment?: boolean): Promise<Adapter<ExtractorState>>;
25
+ export declare class Adapter<ExtractorState> {
26
+ private adapterState;
27
+ private _artifacts;
27
28
  private event;
28
29
  private callbackUrl;
29
30
  private devrevToken;
30
- constructor(event: AirdropEvent, state?: object);
31
- /**
32
- * Adds artifact to the list of artifacts.
33
- * Overrides extractor state if provided.
34
- *
35
- * @param {AdapterUpdateParams} params - The parameters to update the adapter
36
- * @param {Artifact=} params.artifact - The artifact to be added to the list of artifacts
37
- * @param {object=} params.extractor_state - The state object to be updated
38
- */
39
- update(params: AdapterUpdateParams): Promise<void>;
31
+ private startTime;
32
+ private heartBeatFn;
33
+ private exit;
34
+ private lambdaTimeout;
35
+ private heartBeatInterval;
36
+ constructor(event: AirdropEvent, adapterState: State<ExtractorState>, isLocalDevelopment?: boolean);
37
+ get state(): AdapterState<ExtractorState>;
38
+ set state(value: AdapterState<ExtractorState>);
39
+ get artifacts(): Artifact[];
40
+ set artifacts(value: Artifact[]);
40
41
  /**
41
42
  * Emits an event to the platform.
42
43
  *
@@ -45,9 +46,13 @@ export declare class Adapter {
45
46
  */
46
47
  emit(newEventType: ExtractorEventType, data?: EventData): Promise<void>;
47
48
  /**
48
- * Returns the list of artifacts stored in the adapter.
49
- *
50
- * @return The list of artifacts
49
+ * Exit the adapter. This will stop the heartbeat and no
50
+ * further events will be emitted.
51
+ */
52
+ private exitAdapter;
53
+ /**
54
+ * Heartbeat function to check if the lambda is about to timeout.
55
+ * @returns true if 10 minutes have passed since the start of the lambda.
51
56
  */
52
- getArtifacts(): Artifact[];
57
+ private heartbeat;
53
58
  }
@@ -3,60 +3,73 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Adapter = void 0;
6
+ exports.Adapter = exports.createAdapter = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
- const helpers_1 = require("../adapter/helpers");
8
+ const constants_1 = require("../common/constants");
9
+ const helpers_1 = require("../common/helpers");
10
+ const logging_1 = require("../logging");
11
+ const state_1 = require("../state");
9
12
  /**
10
13
  * Adapter class is used to interact with Airdrop platform. The class provides
11
14
  * utilities to
12
15
  * - emit control events to the platform
13
16
  * - update the state of the extractor
14
- * - add artifacts to the list of artifacts to be returned to the platform
15
- * - Return the last saved state and artifacts in case timeout
16
- * - The event sent in case of timeout for each event type is as follows:
17
- * - EXTRACTION_EXTERNAL_SYNC_UNITS_START => EXTRACTION_EXTERNAL_SYNC_UNITS_ERROR
18
- * - EXTRACTION_METADATA_START => EXTRACTION_METADATA_ERROR
19
- * - EXTRACTION_DATA_START => EXTRACTION_DATA_PROGRESS
20
- * - EXTRACTION_DATA_CONTINUE => EXTRACTION_DATA_PROGRESS
21
- * - EXTRACTION_ATTACHMENTS_START => EXTRACTION_ATTACHMENTS_PROGRESS
22
- * - EXTRACTION_ATTACHMENTS_CONTINUE => EXTRACTION_ATTACHMENTS_PROGRESS
17
+ * - set the last saved state in case of a timeout
23
18
  *
24
19
  * @class Adapter
25
20
  * @constructor
26
21
  * @param {AirdropEvent} event - The event object received from the platform
27
- * @param {object=} state - Optional state object to be passed to the extractor. If not provided, an empty object is used.
22
+ * @param {object=} initialState - The initial state of the adapter
23
+ * @param {boolean=} isLocalDevelopment - A flag to indicate if the adapter is being used in local development
28
24
  */
25
+ /**
26
+ * Creates an adapter instance.
27
+ *
28
+ * @param {AirdropEvent} event - The event object received from the platform
29
+ * @param initialState
30
+ * @param {boolean=} isLocalDevelopment - A flag to indicate if the adapter is being used in local development
31
+ * @return The adapter instance
32
+ */
33
+ async function createAdapter(event, initialState, isLocalDevelopment = false) {
34
+ const newInitialState = structuredClone(initialState);
35
+ const adapterState = await (0, state_1.createAdapterState)(event, newInitialState);
36
+ const a = new Adapter(event, adapterState, isLocalDevelopment);
37
+ return a;
38
+ }
39
+ exports.createAdapter = createAdapter;
29
40
  class Adapter {
30
- constructor(event, state) {
41
+ constructor(event, adapterState, isLocalDevelopment = false) {
42
+ this.exit = false;
43
+ this.lambdaTimeout = 10 * 60 * 1000; // 10 minutes in milliseconds
44
+ this.heartBeatInterval = 30 * 1000; // 30 seconds in milliseconds
45
+ if (!isLocalDevelopment) {
46
+ logging_1.Logger.init(event);
47
+ }
48
+ this.adapterState = adapterState;
49
+ this._artifacts = [];
31
50
  this.event = event;
32
- this.artifacts = [];
33
- this.extractorState = state || {};
34
51
  this.callbackUrl = event.payload.event_context.callback_url;
35
- this.devrevToken = event.context.secrets["service_account_token"];
36
- // Once lambda is near to timeout, Snap-in needs to submit the information about artifacts
37
- // that have been uploaded and state, so next time it is run, can continue where it has left off
38
- setTimeout(async () => {
39
- const extractorEventType = (0, helpers_1.getTimeoutExtractorEventType)(this.event.payload.event_type);
40
- if (extractorEventType) {
41
- await this.emit(extractorEventType, { artifacts: this.artifacts });
52
+ this.devrevToken = event.context.secrets.service_account_token;
53
+ this.startTime = Date.now();
54
+ // Run heartbeat every 30 seconds
55
+ this.heartBeatFn = setInterval(async () => {
56
+ const b = await this.heartbeat();
57
+ if (b) {
58
+ this.exitAdapter();
42
59
  }
43
- }, 12 * 60 * 1000);
60
+ }, this.heartBeatInterval);
44
61
  }
45
- /**
46
- * Adds artifact to the list of artifacts.
47
- * Overrides extractor state if provided.
48
- *
49
- * @param {AdapterUpdateParams} params - The parameters to update the adapter
50
- * @param {Artifact=} params.artifact - The artifact to be added to the list of artifacts
51
- * @param {object=} params.extractor_state - The state object to be updated
52
- */
53
- async update(params) {
54
- if (params.artifact) {
55
- this.artifacts.push(params.artifact);
56
- }
57
- if (params.extractor_state) {
58
- this.extractorState = params.extractor_state;
59
- }
62
+ get state() {
63
+ return this.adapterState.state;
64
+ }
65
+ set state(value) {
66
+ this.adapterState.state = value;
67
+ }
68
+ get artifacts() {
69
+ return this._artifacts;
70
+ }
71
+ set artifacts(value) {
72
+ this._artifacts = value;
60
73
  }
61
74
  /**
62
75
  * Emits an event to the platform.
@@ -65,21 +78,22 @@ class Adapter {
65
78
  * @param {EventData=} data - The data to be sent with the event
66
79
  */
67
80
  async emit(newEventType, data) {
81
+ if (this.exit) {
82
+ console.warn('Adapter is already in exit state. No more events can be emitted.');
83
+ return;
84
+ }
85
+ // We want to save the state every time we emit an event, except for the start and delete events
86
+ if (!constants_1.STATELESS_EVENT_TYPES.includes(this.event.payload.event_type)) {
87
+ console.log(`Saving state before emitting event`);
88
+ await this.adapterState.postState(this.state);
89
+ }
68
90
  const newEvent = {
69
- extractor_state: JSON.stringify(this.extractorState),
70
91
  event_type: newEventType,
71
- event_context: {
72
- uuid: this.event.payload.event_context.uuid,
73
- sync_run: this.event.payload.event_context.sync_run_id,
74
- },
75
- event_data: Object.assign(Object.assign({}, data), { artifacts: this.artifacts }),
92
+ event_context: Object.assign({ uuid: this.event.payload.event_context.uuid, sync_run: this.event.payload.event_context.sync_run_id }, (this.event.payload.event_context.sync_unit_id && {
93
+ sync_unit: this.event.payload.event_context.sync_unit_id,
94
+ })),
95
+ event_data: Object.assign({}, data),
76
96
  };
77
- // If sync_unit_id is present in the event, add it to the new event
78
- if (this.event.payload.event_context.sync_unit_id) {
79
- newEvent.event_context.sync_unit =
80
- this.event.payload.event_context.sync_unit_id;
81
- }
82
- console.log('Event that will be emitted: ' + JSON.stringify(newEvent));
83
97
  try {
84
98
  await axios_1.default.post(this.callbackUrl, Object.assign({}, newEvent), {
85
99
  headers: {
@@ -88,23 +102,46 @@ class Adapter {
88
102
  'Content-Type': 'application/json',
89
103
  },
90
104
  });
105
+ console.log('Successfully emitted event: ' + JSON.stringify(newEvent));
91
106
  }
92
107
  catch (error) {
93
108
  // If this request fails the extraction will be stuck in loop and
94
109
  // we need to stop it through UI or think about retrying this request
95
- console.log('Emitting failed for this event: ' +
110
+ console.log('Failed to emit event: ' +
96
111
  JSON.stringify(newEvent) +
97
112
  ', error: ' +
98
113
  error);
99
114
  }
115
+ finally {
116
+ this.exitAdapter();
117
+ }
100
118
  }
101
119
  /**
102
- * Returns the list of artifacts stored in the adapter.
103
- *
104
- * @return The list of artifacts
120
+ * Exit the adapter. This will stop the heartbeat and no
121
+ * further events will be emitted.
105
122
  */
106
- getArtifacts() {
107
- return this.artifacts;
123
+ exitAdapter() {
124
+ this.exit = true;
125
+ clearInterval(this.heartBeatFn);
126
+ }
127
+ /**
128
+ * Heartbeat function to check if the lambda is about to timeout.
129
+ * @returns true if 10 minutes have passed since the start of the lambda.
130
+ */
131
+ async heartbeat() {
132
+ if (this.exit) {
133
+ return true;
134
+ }
135
+ if (Date.now() - this.startTime > this.lambdaTimeout) {
136
+ const timeoutEventType = (0, helpers_1.getTimeoutExtractorEventType)(this.event.payload.event_type);
137
+ if (timeoutEventType !== null) {
138
+ const { eventType, isError } = timeoutEventType;
139
+ const err = isError ? { message: 'Lambda Timeout' } : undefined;
140
+ await this.emit(eventType, { error: err, artifacts: this._artifacts });
141
+ return true;
142
+ }
143
+ }
144
+ return false;
108
145
  }
109
146
  }
110
147
  exports.Adapter = Adapter;
@@ -0,0 +1,2 @@
1
+ import { EventType } from '../types';
2
+ export declare const STATELESS_EVENT_TYPES: EventType[];
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.STATELESS_EVENT_TYPES = void 0;
4
+ const types_1 = require("../types");
5
+ exports.STATELESS_EVENT_TYPES = [
6
+ types_1.EventType.ExtractionExternalSyncUnitsStart,
7
+ types_1.EventType.ExtractionMetadataStart,
8
+ types_1.EventType.ExtractionDataDelete,
9
+ types_1.EventType.ExtractionAttachmentsDelete,
10
+ ];
@@ -1,4 +1,7 @@
1
1
  import { Artifact, EventType, ExtractorEventType } from '../types';
2
2
  export declare function createFormData(preparedArtifact: any, fetchedObjects: object[] | object): FormData;
3
3
  export declare function createArtifact(preparedArtifact: any, fetchedObjects: object[] | object, entity: string): Artifact;
4
- export declare function getTimeoutExtractorEventType(eventType: EventType): ExtractorEventType | null;
4
+ export declare function getTimeoutExtractorEventType(eventType: EventType): {
5
+ eventType: ExtractorEventType;
6
+ isError: boolean;
7
+ } | null;
@@ -29,15 +29,27 @@ exports.createArtifact = createArtifact;
29
29
  function getTimeoutExtractorEventType(eventType) {
30
30
  switch (eventType) {
31
31
  case types_1.EventType.ExtractionMetadataStart:
32
- return types_1.ExtractorEventType.ExtractionMetadataError;
32
+ return {
33
+ eventType: types_1.ExtractorEventType.ExtractionMetadataError,
34
+ isError: true,
35
+ };
33
36
  case types_1.EventType.ExtractionDataStart:
34
37
  case types_1.EventType.ExtractionDataContinue:
35
- return types_1.ExtractorEventType.ExtractionDataProgress;
38
+ return {
39
+ eventType: types_1.ExtractorEventType.ExtractionDataProgress,
40
+ isError: false,
41
+ };
36
42
  case types_1.EventType.ExtractionAttachmentsStart:
37
43
  case types_1.EventType.ExtractionAttachmentsContinue:
38
- return types_1.ExtractorEventType.ExtractionAttachmentsProgress;
44
+ return {
45
+ eventType: types_1.ExtractorEventType.ExtractionAttachmentsProgress,
46
+ isError: false,
47
+ };
39
48
  case types_1.EventType.ExtractionExternalSyncUnitsStart:
40
- return types_1.ExtractorEventType.ExtractionExternalSyncUnitsError;
49
+ return {
50
+ eventType: types_1.ExtractorEventType.ExtractionExternalSyncUnitsError,
51
+ isError: true,
52
+ };
41
53
  default:
42
54
  console.log('Event type not recognized in getTimeoutExtractorEventType function: ' +
43
55
  eventType);
@@ -0,0 +1,3 @@
1
+ import { AirdropEvent } from '../types/extraction';
2
+ import { InitialDomainMapping } from '../types/common';
3
+ export declare function installInitialDomainMapping(event: AirdropEvent, initialDomainMappingJson: InitialDomainMapping): Promise<void>;
@@ -0,0 +1,60 @@
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.installInitialDomainMapping = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ async function installInitialDomainMapping(event, initialDomainMappingJson) {
9
+ const devrevEndpoint = event.execution_metadata.devrev_endpoint;
10
+ const devrevToken = event.context.secrets.service_account_token;
11
+ const snapInVersionId = event.context.snap_in_version_id;
12
+ if (!initialDomainMappingJson) {
13
+ console.warn('No initial domain mapping found');
14
+ return;
15
+ }
16
+ const snapInVersionResponse = await axios_1.default.get(devrevEndpoint + '/internal/snap-in-versions.get', {
17
+ headers: {
18
+ Authorization: devrevToken,
19
+ },
20
+ params: {
21
+ id: snapInVersionId,
22
+ },
23
+ });
24
+ const importSlug = snapInVersionResponse.data.snap_in_version.imports[0].slug;
25
+ const snapInSlug = snapInVersionResponse.data.snap_in_version.slug;
26
+ const startingRecipeBlueprint = initialDomainMappingJson === null || initialDomainMappingJson === void 0 ? void 0 : initialDomainMappingJson.starting_recipe_blueprint;
27
+ let recipeBlueprintId;
28
+ if (startingRecipeBlueprint &&
29
+ Object.keys(startingRecipeBlueprint).length !== 0) {
30
+ try {
31
+ const recipeBlueprintResponse = await axios_1.default.post(`${devrevEndpoint}/internal/airdrop.recipe.blueprints.create`, Object.assign({}, startingRecipeBlueprint), {
32
+ headers: {
33
+ Authorization: devrevToken,
34
+ },
35
+ });
36
+ recipeBlueprintId = recipeBlueprintResponse.data.recipe_blueprint.id;
37
+ console.log('Successfully created recipe blueprint with id: ' + recipeBlueprintId);
38
+ }
39
+ catch (error) {
40
+ console.error('Error while creating recipe blueprint', error);
41
+ }
42
+ }
43
+ try {
44
+ // 2. Install the initial domain mappings
45
+ const additionalMappings = initialDomainMappingJson.additional_mappings || {};
46
+ const initialDomainMappingInstallResponse = await axios_1.default.post(`${devrevEndpoint}/internal/airdrop.recipe.initial-domain-mappings.install`, Object.assign(Object.assign({ external_system_type: 'ADaaS', import_slug: importSlug, snap_in_slug: snapInSlug }, (recipeBlueprintId && {
47
+ starting_recipe_blueprint: recipeBlueprintId,
48
+ })), additionalMappings), {
49
+ headers: {
50
+ Authorization: devrevToken,
51
+ },
52
+ });
53
+ console.log('Successfully installed initial domain mapping', initialDomainMappingInstallResponse.data);
54
+ }
55
+ catch (error) {
56
+ console.error('Error while installing initial domain mapping', error);
57
+ return;
58
+ }
59
+ }
60
+ exports.installInitialDomainMapping = installInitialDomainMapping;
@@ -0,0 +1,38 @@
1
+ {
2
+ "record_types": {
3
+ "users": {
4
+ "fields": {
5
+ "name": {
6
+ "is_required": true,
7
+ "type": "text",
8
+ "name": "Name",
9
+ "text": {
10
+ "min_length": 1
11
+ }
12
+ },
13
+ "email": {
14
+ "type": "text",
15
+ "name": "Email",
16
+ "is_required": true
17
+ }
18
+ }
19
+ },
20
+ "contacts": {
21
+ "fields": {
22
+ "name": {
23
+ "is_required": true,
24
+ "type": "text",
25
+ "name": "Name",
26
+ "text": {
27
+ "min_length": 1
28
+ }
29
+ },
30
+ "email": {
31
+ "type": "text",
32
+ "name": "Email",
33
+ "is_required": true
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
@@ -1,4 +1,11 @@
1
1
  import { AirdropEvent } from '../types';
2
+ import { Adapter } from '../adapter';
3
+ type ExtractorState = object;
2
4
  export declare class DemoExtractor {
3
- run(event: AirdropEvent): Promise<void>;
5
+ private event;
6
+ private adapter;
7
+ private uploader;
8
+ constructor(event: AirdropEvent, adapter: Adapter<ExtractorState>);
9
+ run(): Promise<void>;
4
10
  }
11
+ export {};