@kadoa/node-sdk 0.2.0 → 0.4.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.
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import { EventEmitter } from 'events';
2
- import globalAxios2, { AxiosError } from 'axios';
2
+ import globalAxios2, { isAxiosError } from 'axios';
3
+ import { URL, URLSearchParams } from 'url';
3
4
  import { merge } from 'es-toolkit/object';
4
- import { URL as URL$1, URLSearchParams } from 'url';
5
5
 
6
- // src/events/index.ts
6
+ // src/core/events/event-emitter.ts
7
7
  var KadoaEventEmitter = class extends EventEmitter {
8
8
  /**
9
9
  * Emit a typed SDK event
@@ -44,8 +44,8 @@ var KadoaEventEmitter = class extends EventEmitter {
44
44
  }
45
45
  };
46
46
 
47
- // src/exceptions/kadoa-sdk.exception.ts
48
- var KadoaSdkException = class _KadoaSdkException extends Error {
47
+ // src/core/exceptions/base.exception.ts
48
+ var _KadoaSdkException = class _KadoaSdkException extends Error {
49
49
  constructor(message, options) {
50
50
  super(message);
51
51
  this.name = "KadoaSdkException";
@@ -74,9 +74,54 @@ var KadoaSdkException = class _KadoaSdkException extends Error {
74
74
  toString() {
75
75
  return [this.name, this.code, this.message].filter(Boolean).join(": ");
76
76
  }
77
+ toDetailedString() {
78
+ const parts = [`${this.name}: ${this.message}`, `Code: ${this.code}`];
79
+ if (this.details && Object.keys(this.details).length > 0) {
80
+ parts.push(`Details: ${JSON.stringify(this.details, null, 2)}`);
81
+ }
82
+ if (this.cause) {
83
+ parts.push(`Cause: ${this.cause}`);
84
+ }
85
+ return parts.join("\n");
86
+ }
87
+ static isInstance(error) {
88
+ return error instanceof _KadoaSdkException;
89
+ }
90
+ static wrap(error, extra) {
91
+ if (error instanceof _KadoaSdkException) return error;
92
+ const message = extra?.message || (error instanceof Error ? error.message : typeof error === "string" ? error : "Unexpected error");
93
+ return new _KadoaSdkException(message, {
94
+ code: "UNKNOWN",
95
+ details: extra?.details,
96
+ cause: error
97
+ });
98
+ }
77
99
  };
78
-
79
- // src/exceptions/http.exception.ts
100
+ _KadoaSdkException.ERROR_MESSAGES = {
101
+ // General errors
102
+ CONFIG_ERROR: "Invalid configuration provided",
103
+ AUTH_FAILED: "Authentication failed. Please check your API key",
104
+ RATE_LIMITED: "Rate limit exceeded. Please try again later",
105
+ NETWORK_ERROR: "Network error occurred",
106
+ SERVER_ERROR: "Server error occurred",
107
+ PARSE_ERROR: "Failed to parse response",
108
+ // Workflow specific errors
109
+ NO_WORKFLOW_ID: "Failed to start extraction process - no ID received",
110
+ WORKFLOW_CREATE_FAILED: "Failed to create workflow",
111
+ WORKFLOW_TIMEOUT: "Workflow processing timed out",
112
+ WORKFLOW_UNEXPECTED_STATUS: "Extraction completed with unexpected status",
113
+ PROGRESS_CHECK_FAILED: "Failed to check extraction progress",
114
+ DATA_FETCH_FAILED: "Failed to retrieve extracted data from workflow",
115
+ // Extraction specific errors
116
+ NO_URLS: "At least one URL is required for extraction",
117
+ NO_API_KEY: "API key is required for entity detection",
118
+ LINK_REQUIRED: "Link is required for entity field detection",
119
+ NO_PREDICTIONS: "No entity predictions returned from the API",
120
+ EXTRACTION_FAILED: "Data extraction failed for the provided URLs",
121
+ ENTITY_FETCH_FAILED: "Failed to fetch entity fields"
122
+ };
123
+ var KadoaSdkException = _KadoaSdkException;
124
+ var ERROR_MESSAGES = KadoaSdkException.ERROR_MESSAGES;
80
125
  var KadoaHttpException = class _KadoaHttpException extends KadoaSdkException {
81
126
  constructor(message, options) {
82
127
  super(message, {
@@ -117,10 +162,43 @@ var KadoaHttpException = class _KadoaHttpException extends KadoaSdkException {
117
162
  responseBody: this.responseBody
118
163
  };
119
164
  }
120
- static mapStatusToCode(error) {
121
- const status = error.response?.status;
165
+ toDetailedString() {
166
+ const parts = [`${this.name}: ${this.message}`, `Code: ${this.code}`];
167
+ if (this.httpStatus) {
168
+ parts.push(`HTTP Status: ${this.httpStatus}`);
169
+ }
170
+ if (this.method && this.endpoint) {
171
+ parts.push(`Request: ${this.method} ${this.endpoint}`);
172
+ }
173
+ if (this.requestId) {
174
+ parts.push(`Request ID: ${this.requestId}`);
175
+ }
176
+ if (this.responseBody) {
177
+ parts.push(
178
+ `Response Body: ${JSON.stringify(this.responseBody, null, 2)}`
179
+ );
180
+ }
181
+ if (this.details && Object.keys(this.details).length > 0) {
182
+ parts.push(`Details: ${JSON.stringify(this.details, null, 2)}`);
183
+ }
184
+ if (this.cause) {
185
+ parts.push(`Cause: ${this.cause}`);
186
+ }
187
+ return parts.join("\n");
188
+ }
189
+ static wrap(error, extra) {
190
+ if (error instanceof _KadoaHttpException) return error;
191
+ if (error instanceof KadoaSdkException) return error;
192
+ if (isAxiosError(error)) {
193
+ return _KadoaHttpException.fromAxiosError(error, extra);
194
+ }
195
+ return KadoaSdkException.wrap(error, extra);
196
+ }
197
+ static mapStatusToCode(errorOrStatus) {
198
+ const status = typeof errorOrStatus === "number" ? errorOrStatus : errorOrStatus.response?.status;
122
199
  if (!status) {
123
- return error.code === "ECONNABORTED" ? "TIMEOUT" : error.request ? "NETWORK_ERROR" : "UNKNOWN";
200
+ if (typeof errorOrStatus === "number") return "UNKNOWN";
201
+ return errorOrStatus.code === "ECONNABORTED" ? "TIMEOUT" : errorOrStatus.request ? "NETWORK_ERROR" : "UNKNOWN";
124
202
  }
125
203
  if (status === 401 || status === 403) return "AUTH_ERROR";
126
204
  if (status === 404) return "NOT_FOUND";
@@ -131,54 +209,6 @@ var KadoaHttpException = class _KadoaHttpException extends KadoaSdkException {
131
209
  return "UNKNOWN";
132
210
  }
133
211
  };
134
- function isKadoaSdkException(error) {
135
- return error instanceof KadoaSdkException;
136
- }
137
- function isKadoaHttpException(error) {
138
- return error instanceof KadoaHttpException;
139
- }
140
- function wrapKadoaError(error, extra) {
141
- if (error instanceof AxiosError)
142
- return KadoaHttpException.fromAxiosError(error, extra);
143
- return KadoaSdkException.from(error, extra?.details);
144
- }
145
-
146
- // src/extraction/constants.ts
147
- var DEFAULT_OPTIONS = {
148
- pollingInterval: 5e3,
149
- maxWaitTime: 3e5,
150
- navigationMode: "single-page",
151
- location: { type: "auto" },
152
- name: "Untitled Workflow",
153
- dataLimit: 100
154
- };
155
- var MAX_DATA_LIMIT = 99999;
156
- var TERMINAL_RUN_STATES = /* @__PURE__ */ new Set([
157
- "FINISHED",
158
- "SUCCESS",
159
- "FAILED",
160
- "ERROR",
161
- "STOPPED",
162
- "CANCELLED"
163
- ]);
164
- var SUCCESSFUL_RUN_STATES = /* @__PURE__ */ new Set(["FINISHED", "SUCCESS"]);
165
- var ENTITY_API_ENDPOINT = "/v4/entity";
166
- var DEFAULT_API_BASE_URL = "https://api.kadoa.com";
167
- var ERROR_MESSAGES = {
168
- NO_URLS: "At least one URL is required for extraction",
169
- NO_API_KEY: "API key is required for entity detection",
170
- LINK_REQUIRED: "Link is required for entity field detection",
171
- NO_WORKFLOW_ID: "Failed to start extraction process - no ID received",
172
- NO_PREDICTIONS: "No entity predictions returned from the API",
173
- PARSE_ERROR: "Failed to parse entity response",
174
- NETWORK_ERROR: "Network error while fetching entity fields",
175
- AUTH_FAILED: "Authentication failed. Please check your API key",
176
- RATE_LIMITED: "Rate limit exceeded. Please try again later",
177
- SERVER_ERROR: "Server error while fetching entity fields",
178
- DATA_FETCH_FAILED: "Failed to retrieve extracted data from workflow",
179
- PROGRESS_CHECK_FAILED: "Failed to check extraction progress",
180
- EXTRACTION_FAILED: "Data extraction failed for the provided URLs"
181
- };
182
212
  var BASE_PATH = "https://api.kadoa.com".replace(/\/+$/, "");
183
213
  var BaseAPI = class {
184
214
  constructor(configuration, basePath = BASE_PATH, axios2 = globalAxios2) {
@@ -267,7 +297,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
267
297
  v4ChangesChangeIdGet: async (changeId, xApiKey, authorization, options = {}) => {
268
298
  assertParamExists("v4ChangesChangeIdGet", "changeId", changeId);
269
299
  const localVarPath = `/v4/changes/{changeId}`.replace(`{${"changeId"}}`, encodeURIComponent(String(changeId)));
270
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
300
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
271
301
  let baseOptions;
272
302
  if (configuration) {
273
303
  baseOptions = configuration.baseOptions;
@@ -306,7 +336,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
306
336
  */
307
337
  v4ChangesGet: async (xApiKey, authorization, workflowIds, startDate, endDate, skip, limit, options = {}) => {
308
338
  const localVarPath = `/v4/changes`;
309
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
339
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
310
340
  let baseOptions;
311
341
  if (configuration) {
312
342
  baseOptions = configuration.baseOptions;
@@ -363,7 +393,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
363
393
  */
364
394
  v4WorkflowsGet: async (search, skip, limit, state, tags, monitoring, updateInterval, templateId, includeDeleted, format, options = {}) => {
365
395
  const localVarPath = `/v4/workflows`;
366
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
396
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
367
397
  let baseOptions;
368
398
  if (configuration) {
369
399
  baseOptions = configuration.baseOptions;
@@ -420,7 +450,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
420
450
  v4WorkflowsPost: async (v4WorkflowsPostRequest, options = {}) => {
421
451
  assertParamExists("v4WorkflowsPost", "v4WorkflowsPostRequest", v4WorkflowsPostRequest);
422
452
  const localVarPath = `/v4/workflows`;
423
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
453
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
424
454
  let baseOptions;
425
455
  if (configuration) {
426
456
  baseOptions = configuration.baseOptions;
@@ -450,7 +480,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
450
480
  v4WorkflowsSetupEditPost: async (v4WorkflowsSetupEditPostRequest, options = {}) => {
451
481
  assertParamExists("v4WorkflowsSetupEditPost", "v4WorkflowsSetupEditPostRequest", v4WorkflowsSetupEditPostRequest);
452
482
  const localVarPath = `/v4/workflows/setup/edit`;
453
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
483
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
454
484
  let baseOptions;
455
485
  if (configuration) {
456
486
  baseOptions = configuration.baseOptions;
@@ -479,7 +509,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
479
509
  v4WorkflowsSetupPost: async (v4WorkflowsSetupPostRequest, options = {}) => {
480
510
  assertParamExists("v4WorkflowsSetupPost", "v4WorkflowsSetupPostRequest", v4WorkflowsSetupPostRequest);
481
511
  const localVarPath = `/v4/workflows/setup`;
482
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
512
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
483
513
  let baseOptions;
484
514
  if (configuration) {
485
515
  baseOptions = configuration.baseOptions;
@@ -512,7 +542,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
512
542
  v4WorkflowsWorkflowIdAuditlogGet: async (workflowId, xApiKey, authorization, page, limit, options = {}) => {
513
543
  assertParamExists("v4WorkflowsWorkflowIdAuditlogGet", "workflowId", workflowId);
514
544
  const localVarPath = `/v4/workflows/{workflowId}/auditlog`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
515
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
545
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
516
546
  let baseOptions;
517
547
  if (configuration) {
518
548
  baseOptions = configuration.baseOptions;
@@ -554,7 +584,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
554
584
  v4WorkflowsWorkflowIdComplianceApprovePut: async (workflowId, xApiKey, authorization, options = {}) => {
555
585
  assertParamExists("v4WorkflowsWorkflowIdComplianceApprovePut", "workflowId", workflowId);
556
586
  const localVarPath = `/v4/workflows/{workflowId}/compliance-approve`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
557
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
587
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
558
588
  let baseOptions;
559
589
  if (configuration) {
560
590
  baseOptions = configuration.baseOptions;
@@ -591,7 +621,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
591
621
  assertParamExists("v4WorkflowsWorkflowIdComplianceRejectPut", "workflowId", workflowId);
592
622
  assertParamExists("v4WorkflowsWorkflowIdComplianceRejectPut", "v4WorkflowsWorkflowIdComplianceRejectPutRequest", v4WorkflowsWorkflowIdComplianceRejectPutRequest);
593
623
  const localVarPath = `/v4/workflows/{workflowId}/compliance-reject`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
594
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
624
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
595
625
  let baseOptions;
596
626
  if (configuration) {
597
627
  baseOptions = configuration.baseOptions;
@@ -638,7 +668,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
638
668
  v4WorkflowsWorkflowIdDataGet: async (workflowId, xApiKey, authorization, runId, format, sortBy, order, filters, page, limit, gzip, rowIds, includeAnomalies, options = {}) => {
639
669
  assertParamExists("v4WorkflowsWorkflowIdDataGet", "workflowId", workflowId);
640
670
  const localVarPath = `/v4/workflows/{workflowId}/data`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
641
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
671
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
642
672
  let baseOptions;
643
673
  if (configuration) {
644
674
  baseOptions = configuration.baseOptions;
@@ -702,7 +732,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
702
732
  v4WorkflowsWorkflowIdDelete: async (workflowId, options = {}) => {
703
733
  assertParamExists("v4WorkflowsWorkflowIdDelete", "workflowId", workflowId);
704
734
  const localVarPath = `/v4/workflows/{workflowId}`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
705
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
735
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
706
736
  let baseOptions;
707
737
  if (configuration) {
708
738
  baseOptions = configuration.baseOptions;
@@ -729,7 +759,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
729
759
  v4WorkflowsWorkflowIdGet: async (workflowId, options = {}) => {
730
760
  assertParamExists("v4WorkflowsWorkflowIdGet", "workflowId", workflowId);
731
761
  const localVarPath = `/v4/workflows/{workflowId}`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
732
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
762
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
733
763
  let baseOptions;
734
764
  if (configuration) {
735
765
  baseOptions = configuration.baseOptions;
@@ -756,7 +786,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
756
786
  v4WorkflowsWorkflowIdHistoryGet: async (workflowId, options = {}) => {
757
787
  assertParamExists("v4WorkflowsWorkflowIdHistoryGet", "workflowId", workflowId);
758
788
  const localVarPath = `/v4/workflows/{workflowId}/history`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
759
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
789
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
760
790
  let baseOptions;
761
791
  if (configuration) {
762
792
  baseOptions = configuration.baseOptions;
@@ -785,7 +815,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
785
815
  assertParamExists("v4WorkflowsWorkflowIdMetadataPut", "workflowId", workflowId);
786
816
  assertParamExists("v4WorkflowsWorkflowIdMetadataPut", "v4WorkflowsWorkflowIdMetadataPutRequest", v4WorkflowsWorkflowIdMetadataPutRequest);
787
817
  const localVarPath = `/v4/workflows/{workflowId}/metadata`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
788
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
818
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
789
819
  let baseOptions;
790
820
  if (configuration) {
791
821
  baseOptions = configuration.baseOptions;
@@ -814,7 +844,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
814
844
  v4WorkflowsWorkflowIdPausePut: async (workflowId, options = {}) => {
815
845
  assertParamExists("v4WorkflowsWorkflowIdPausePut", "workflowId", workflowId);
816
846
  const localVarPath = `/v4/workflows/{workflowId}/pause`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
817
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
847
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
818
848
  let baseOptions;
819
849
  if (configuration) {
820
850
  baseOptions = configuration.baseOptions;
@@ -841,7 +871,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
841
871
  v4WorkflowsWorkflowIdResumePut: async (workflowId, options = {}) => {
842
872
  assertParamExists("v4WorkflowsWorkflowIdResumePut", "workflowId", workflowId);
843
873
  const localVarPath = `/v4/workflows/{workflowId}/resume`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
844
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
874
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
845
875
  let baseOptions;
846
876
  if (configuration) {
847
877
  baseOptions = configuration.baseOptions;
@@ -868,7 +898,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
868
898
  v4WorkflowsWorkflowIdRunPut: async (workflowId, options = {}) => {
869
899
  assertParamExists("v4WorkflowsWorkflowIdRunPut", "workflowId", workflowId);
870
900
  const localVarPath = `/v4/workflows/{workflowId}/run`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
871
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
901
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
872
902
  let baseOptions;
873
903
  if (configuration) {
874
904
  baseOptions = configuration.baseOptions;
@@ -897,7 +927,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
897
927
  assertParamExists("v4WorkflowsWorkflowIdSchedulePut", "workflowId", workflowId);
898
928
  assertParamExists("v4WorkflowsWorkflowIdSchedulePut", "v4WorkflowsWorkflowIdSchedulePutRequest", v4WorkflowsWorkflowIdSchedulePutRequest);
899
929
  const localVarPath = `/v4/workflows/{workflowId}/schedule`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
900
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
930
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
901
931
  let baseOptions;
902
932
  if (configuration) {
903
933
  baseOptions = configuration.baseOptions;
@@ -928,7 +958,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
928
958
  v5ChangesChangeIdGet: async (changeId, xApiKey, authorization, options = {}) => {
929
959
  assertParamExists("v5ChangesChangeIdGet", "changeId", changeId);
930
960
  const localVarPath = `/v5/changes/{changeId}`.replace(`{${"changeId"}}`, encodeURIComponent(String(changeId)));
931
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
961
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
932
962
  let baseOptions;
933
963
  if (configuration) {
934
964
  baseOptions = configuration.baseOptions;
@@ -967,7 +997,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
967
997
  */
968
998
  v5ChangesGet: async (xApiKey, authorization, workflowIds, startDate, endDate, skip, limit, options = {}) => {
969
999
  const localVarPath = `/v5/changes`;
970
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
1000
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
971
1001
  let baseOptions;
972
1002
  if (configuration) {
973
1003
  baseOptions = configuration.baseOptions;
@@ -1016,7 +1046,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
1016
1046
  v5WorkflowsIdDelete: async (id, options = {}) => {
1017
1047
  assertParamExists("v5WorkflowsIdDelete", "id", id);
1018
1048
  const localVarPath = `/v5/workflows/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(id)));
1019
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
1049
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
1020
1050
  let baseOptions;
1021
1051
  if (configuration) {
1022
1052
  baseOptions = configuration.baseOptions;
@@ -1044,7 +1074,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
1044
1074
  v5WorkflowsIdGet: async (id, options = {}) => {
1045
1075
  assertParamExists("v5WorkflowsIdGet", "id", id);
1046
1076
  const localVarPath = `/v5/workflows/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(id)));
1047
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
1077
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
1048
1078
  let baseOptions;
1049
1079
  if (configuration) {
1050
1080
  baseOptions = configuration.baseOptions;
@@ -1074,7 +1104,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
1074
1104
  assertParamExists("v5WorkflowsIdPut", "id", id);
1075
1105
  assertParamExists("v5WorkflowsIdPut", "v5WorkflowsIdPutRequest", v5WorkflowsIdPutRequest);
1076
1106
  const localVarPath = `/v5/workflows/{id}`.replace(`{${"id"}}`, encodeURIComponent(String(id)));
1077
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
1107
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
1078
1108
  let baseOptions;
1079
1109
  if (configuration) {
1080
1110
  baseOptions = configuration.baseOptions;
@@ -1104,7 +1134,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
1104
1134
  v5WorkflowsPost: async (v5WorkflowsPostRequest, options = {}) => {
1105
1135
  assertParamExists("v5WorkflowsPost", "v5WorkflowsPostRequest", v5WorkflowsPostRequest);
1106
1136
  const localVarPath = `/v5/workflows`;
1107
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
1137
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
1108
1138
  let baseOptions;
1109
1139
  if (configuration) {
1110
1140
  baseOptions = configuration.baseOptions;
@@ -1138,7 +1168,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
1138
1168
  v5WorkflowsWorkflowIdAuditlogGet: async (workflowId, xApiKey, authorization, page, limit, options = {}) => {
1139
1169
  assertParamExists("v5WorkflowsWorkflowIdAuditlogGet", "workflowId", workflowId);
1140
1170
  const localVarPath = `/v5/workflows/{workflowId}/auditlog`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
1141
- const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
1171
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
1142
1172
  let baseOptions;
1143
1173
  if (configuration) {
1144
1174
  baseOptions = configuration.baseOptions;
@@ -1864,405 +1894,545 @@ var Configuration = class {
1864
1894
  }
1865
1895
  };
1866
1896
 
1867
- // src/api-client.ts
1897
+ // src/core/patterns/command.ts
1898
+ var Command = class {
1899
+ };
1900
+
1901
+ // src/core/http/client-factory.ts
1868
1902
  var workflowsApiCache = /* @__PURE__ */ new WeakMap();
1869
- function getWorkflowsApi(app) {
1870
- let api = workflowsApiCache.get(app);
1903
+ function getWorkflowsApi(client) {
1904
+ let api = workflowsApiCache.get(client);
1871
1905
  if (!api) {
1872
- api = new WorkflowsApi(app.configuration, app.baseUrl, app.axiosInstance);
1873
- workflowsApiCache.set(app, api);
1906
+ api = new WorkflowsApi(
1907
+ client.configuration,
1908
+ client.baseUrl,
1909
+ client.axiosInstance
1910
+ );
1911
+ workflowsApiCache.set(client, api);
1874
1912
  }
1875
1913
  return api;
1876
1914
  }
1877
1915
 
1878
- // src/extraction/data-fetcher.ts
1879
- async function fetchWorkflowData(sdkInstance, workflowId, limit = DEFAULT_OPTIONS.dataLimit) {
1880
- const workflowsApi = getWorkflowsApi(sdkInstance);
1881
- try {
1882
- const response = await workflowsApi.v4WorkflowsWorkflowIdDataGet({
1883
- workflowId,
1884
- limit
1885
- });
1886
- return response.data.data ?? [];
1887
- } catch (error) {
1888
- throw wrapKadoaError(error, {
1889
- message: ERROR_MESSAGES.DATA_FETCH_FAILED,
1890
- details: { workflowId, limit }
1891
- });
1916
+ // src/modules/extraction/services/data-fetcher.service.ts
1917
+ var DataFetcherService = class {
1918
+ constructor(client) {
1919
+ this.client = client;
1892
1920
  }
1893
- }
1921
+ /**
1922
+ * Fetch extracted data from a workflow
1923
+ *
1924
+ * @param workflowId The workflow ID to fetch data from
1925
+ * @param limit Maximum number of records to retrieve
1926
+ * @returns Array of extracted data objects
1927
+ */
1928
+ async fetchWorkflowData(workflowId, limit) {
1929
+ const workflowsApi = getWorkflowsApi(this.client);
1930
+ try {
1931
+ const response = await workflowsApi.v4WorkflowsWorkflowIdDataGet({
1932
+ workflowId,
1933
+ limit
1934
+ });
1935
+ return response.data.data ?? [];
1936
+ } catch (error) {
1937
+ throw KadoaHttpException.wrap(error, {
1938
+ message: ERROR_MESSAGES.DATA_FETCH_FAILED,
1939
+ details: { workflowId, limit }
1940
+ });
1941
+ }
1942
+ }
1943
+ };
1894
1944
 
1895
- // src/extraction/entity-detector.ts
1896
- function validateEntityOptions(options) {
1897
- if (!options.link) {
1898
- throw new KadoaSdkException(ERROR_MESSAGES.LINK_REQUIRED, {
1899
- code: "VALIDATION_ERROR",
1900
- details: { options }
1901
- });
1945
+ // src/core/config/constants.ts
1946
+ var DEFAULT_API_BASE_URL = "https://api.kadoa.com";
1947
+
1948
+ // src/modules/extraction/services/entity-detector.service.ts
1949
+ var ENTITY_API_ENDPOINT = "/v4/entity";
1950
+ var EntityDetectorService = class {
1951
+ constructor(client) {
1952
+ this.client = client;
1902
1953
  }
1903
- }
1904
- async function buildRequestHeaders(config) {
1905
- const headers = {
1906
- "Content-Type": "application/json",
1907
- Accept: "application/json"
1908
- };
1909
- if (config?.apiKey) {
1910
- if (typeof config.apiKey === "function") {
1911
- const apiKeyValue = await config.apiKey("X-API-Key");
1912
- if (apiKeyValue) {
1913
- headers["X-API-Key"] = apiKeyValue;
1914
- }
1915
- } else if (typeof config.apiKey === "string") {
1916
- headers["X-API-Key"] = config.apiKey;
1954
+ /**
1955
+ * Fetches entity fields dynamically from the /v4/entity endpoint.
1956
+ * This is a workaround implementation using native fetch since the endpoint
1957
+ * is not yet included in the OpenAPI specification.
1958
+ *
1959
+ * @param options Request options including the link to analyze
1960
+ * @returns EntityPrediction containing the detected entity type and fields
1961
+ */
1962
+ async fetchEntityFields(options) {
1963
+ this.validateEntityOptions(options);
1964
+ const url = `${this.client.baseUrl || DEFAULT_API_BASE_URL}${ENTITY_API_ENDPOINT}`;
1965
+ const headers = await this.buildRequestHeaders();
1966
+ const requestBody = options;
1967
+ try {
1968
+ const response = await this.client.axiosInstance.post(url, requestBody, {
1969
+ headers
1970
+ });
1971
+ const data = response.data;
1972
+ if (!data.success || !data.entityPrediction || data.entityPrediction.length === 0) {
1973
+ throw new KadoaSdkException(ERROR_MESSAGES.NO_PREDICTIONS, {
1974
+ code: "NOT_FOUND",
1975
+ details: {
1976
+ success: data.success,
1977
+ hasPredictions: !!data.entityPrediction,
1978
+ predictionCount: data.entityPrediction?.length || 0,
1979
+ link: options.link
1980
+ }
1981
+ });
1982
+ }
1983
+ return data.entityPrediction[0];
1984
+ } catch (error) {
1985
+ throw KadoaHttpException.wrap(error, {
1986
+ details: {
1987
+ url,
1988
+ link: options.link
1989
+ }
1990
+ });
1917
1991
  }
1918
- } else {
1919
- throw new KadoaSdkException(ERROR_MESSAGES.NO_API_KEY, {
1920
- code: "AUTH_ERROR",
1921
- details: { hasConfig: !!config, hasApiKey: !!config?.apiKey }
1922
- });
1923
1992
  }
1924
- return headers;
1925
- }
1926
- function getErrorCodeFromStatus(status) {
1927
- if (status === 401 || status === 403) return "AUTH_ERROR";
1928
- if (status === 404) return "NOT_FOUND";
1929
- if (status === 429) return "RATE_LIMITED";
1930
- if (status >= 400 && status < 500) return "VALIDATION_ERROR";
1931
- if (status >= 500) return "HTTP_ERROR";
1932
- return "UNKNOWN";
1933
- }
1934
- async function handleErrorResponse(response, url, link) {
1935
- let errorData;
1936
- let errorText = "";
1937
- try {
1938
- errorText = await response.text();
1939
- errorData = JSON.parse(errorText);
1940
- } catch {
1941
- errorData = { message: errorText || response.statusText };
1942
- }
1943
- const baseErrorOptions = {
1944
- httpStatus: response.status,
1945
- endpoint: url.toString(),
1946
- method: "POST",
1947
- responseBody: errorData,
1948
- details: {
1949
- url: url.toString(),
1950
- link
1993
+ /**
1994
+ * Validates entity request options
1995
+ */
1996
+ validateEntityOptions(options) {
1997
+ if (!options.link) {
1998
+ throw new KadoaSdkException(ERROR_MESSAGES.LINK_REQUIRED, {
1999
+ code: "VALIDATION_ERROR",
2000
+ details: { options }
2001
+ });
1951
2002
  }
1952
- };
1953
- if (response.status === 401) {
1954
- throw new KadoaHttpException(ERROR_MESSAGES.AUTH_FAILED, {
1955
- ...baseErrorOptions,
1956
- code: "AUTH_ERROR"
1957
- });
1958
2003
  }
1959
- if (response.status === 429) {
1960
- throw new KadoaHttpException(ERROR_MESSAGES.RATE_LIMITED, {
1961
- ...baseErrorOptions,
1962
- code: "RATE_LIMITED"
1963
- });
1964
- }
1965
- if (response.status >= 500) {
1966
- throw new KadoaHttpException(ERROR_MESSAGES.SERVER_ERROR, {
1967
- ...baseErrorOptions,
1968
- code: "HTTP_ERROR"
1969
- });
1970
- }
1971
- throw new KadoaHttpException(
1972
- `Failed to fetch entity fields: ${errorData?.message || response.statusText}`,
1973
- {
1974
- ...baseErrorOptions,
1975
- code: getErrorCodeFromStatus(response.status)
2004
+ /**
2005
+ * Builds request headers including API key authentication
2006
+ */
2007
+ async buildRequestHeaders() {
2008
+ const headers = {
2009
+ "Content-Type": "application/json",
2010
+ Accept: "application/json"
2011
+ };
2012
+ const config = this.client.configuration;
2013
+ if (config?.apiKey) {
2014
+ if (typeof config.apiKey === "function") {
2015
+ const apiKeyValue = await config.apiKey("X-API-Key");
2016
+ if (apiKeyValue) {
2017
+ headers["X-API-Key"] = apiKeyValue;
2018
+ }
2019
+ } else if (typeof config.apiKey === "string") {
2020
+ headers["X-API-Key"] = config.apiKey;
2021
+ }
2022
+ } else {
2023
+ throw new KadoaSdkException(ERROR_MESSAGES.NO_API_KEY, {
2024
+ code: "AUTH_ERROR",
2025
+ details: { hasConfig: !!config, hasApiKey: !!config?.apiKey }
2026
+ });
1976
2027
  }
1977
- );
1978
- }
1979
- async function fetchEntityFields(app, options) {
1980
- validateEntityOptions(options);
1981
- const url = new URL(ENTITY_API_ENDPOINT, app.baseUrl || DEFAULT_API_BASE_URL);
1982
- const headers = await buildRequestHeaders(app.configuration);
1983
- const requestBody = options;
1984
- let response;
1985
- try {
1986
- response = await fetch(url.toString(), {
1987
- method: "POST",
1988
- headers,
1989
- body: JSON.stringify(requestBody)
1990
- });
1991
- } catch (error) {
1992
- throw new KadoaSdkException(ERROR_MESSAGES.NETWORK_ERROR, {
1993
- code: "NETWORK_ERROR",
1994
- details: {
1995
- url: url.toString(),
1996
- link: options.link
1997
- },
1998
- cause: error
1999
- });
2000
- }
2001
- if (!response.ok) {
2002
- await handleErrorResponse(response, url, options.link);
2028
+ return headers;
2003
2029
  }
2004
- let data;
2005
- try {
2006
- data = await response.json();
2007
- } catch (error) {
2008
- throw new KadoaSdkException(ERROR_MESSAGES.PARSE_ERROR, {
2009
- code: "INTERNAL_ERROR",
2010
- details: {
2011
- url: url.toString(),
2012
- link: options.link
2013
- },
2014
- cause: error
2015
- });
2030
+ };
2031
+
2032
+ // src/modules/extraction/services/workflow-manager.service.ts
2033
+ var TERMINAL_RUN_STATES = /* @__PURE__ */ new Set([
2034
+ "FINISHED",
2035
+ "SUCCESS",
2036
+ "FAILED",
2037
+ "ERROR",
2038
+ "STOPPED",
2039
+ "CANCELLED"
2040
+ ]);
2041
+ var WorkflowManagerService = class {
2042
+ constructor(client) {
2043
+ this.client = client;
2016
2044
  }
2017
- if (!data.success || !data.entityPrediction || data.entityPrediction.length === 0) {
2018
- throw new KadoaSdkException(ERROR_MESSAGES.NO_PREDICTIONS, {
2019
- code: "NOT_FOUND",
2020
- details: {
2021
- success: data.success,
2022
- hasPredictions: !!data.entityPrediction,
2023
- predictionCount: data.entityPrediction?.length || 0,
2024
- link: options.link
2025
- }
2026
- });
2045
+ /**
2046
+ * Check if a workflow runState is terminal (finished processing)
2047
+ */
2048
+ isTerminalRunState(runState) {
2049
+ if (!runState) return false;
2050
+ return TERMINAL_RUN_STATES.has(runState.toUpperCase());
2027
2051
  }
2028
- return data.entityPrediction[0];
2029
- }
2030
-
2031
- // src/extraction/workflow-manager.ts
2032
- function isTerminalRunState(runState) {
2033
- if (!runState) return false;
2034
- return TERMINAL_RUN_STATES.has(runState.toUpperCase());
2035
- }
2036
- async function createWorkflow(sdkInstance, config) {
2037
- const workflowsApi = getWorkflowsApi(sdkInstance);
2038
- const request = {
2039
- urls: config.urls,
2040
- navigationMode: config.navigationMode,
2041
- entity: config.entity,
2042
- name: config.name,
2043
- fields: config.fields,
2044
- bypassPreview: true,
2045
- limit: MAX_DATA_LIMIT,
2046
- tags: ["sdk"]
2047
- };
2048
- try {
2049
- const response = await workflowsApi.v4WorkflowsPost({
2050
- v4WorkflowsPostRequest: request
2051
- });
2052
- const workflowId = response.data.workflowId;
2053
- if (!workflowId) {
2054
- throw new KadoaSdkException(ERROR_MESSAGES.NO_WORKFLOW_ID, {
2055
- code: "INTERNAL_ERROR",
2056
- details: { urls: config.urls }
2052
+ /**
2053
+ * Creates a new workflow with the provided configuration
2054
+ */
2055
+ async createWorkflow(config) {
2056
+ const workflowsApi = getWorkflowsApi(this.client);
2057
+ const request = {
2058
+ urls: config.urls,
2059
+ navigationMode: config.navigationMode,
2060
+ entity: config.entity,
2061
+ name: config.name,
2062
+ fields: config.fields,
2063
+ bypassPreview: true,
2064
+ limit: config.maxRecords,
2065
+ tags: ["sdk"]
2066
+ };
2067
+ try {
2068
+ const response = await workflowsApi.v4WorkflowsPost({
2069
+ v4WorkflowsPostRequest: request
2070
+ });
2071
+ const workflowId = response.data.workflowId;
2072
+ if (!workflowId) {
2073
+ throw new KadoaSdkException(ERROR_MESSAGES.NO_WORKFLOW_ID, {
2074
+ code: "INTERNAL_ERROR",
2075
+ details: { response: response.data }
2076
+ });
2077
+ }
2078
+ return workflowId;
2079
+ } catch (error) {
2080
+ throw KadoaHttpException.wrap(error, {
2081
+ message: ERROR_MESSAGES.WORKFLOW_CREATE_FAILED,
2082
+ details: config
2057
2083
  });
2058
2084
  }
2059
- return workflowId;
2060
- } catch (error) {
2061
- throw wrapKadoaError(error, {
2062
- message: "Failed to create workflow",
2063
- details: config
2064
- });
2065
2085
  }
2066
- }
2067
- async function getWorkflowStatus(sdkInstance, workflowId) {
2068
- const workflowsApi = getWorkflowsApi(sdkInstance);
2069
- try {
2070
- const response = await workflowsApi.v4WorkflowsWorkflowIdGet({
2071
- workflowId
2072
- });
2073
- return response.data;
2074
- } catch (error) {
2075
- throw wrapKadoaError(error, {
2076
- message: ERROR_MESSAGES.PROGRESS_CHECK_FAILED,
2077
- details: { workflowId }
2078
- });
2086
+ /**
2087
+ * Gets the current status of a workflow
2088
+ */
2089
+ async getWorkflowStatus(workflowId) {
2090
+ const workflowsApi = getWorkflowsApi(this.client);
2091
+ try {
2092
+ const response = await workflowsApi.v4WorkflowsWorkflowIdGet({
2093
+ workflowId
2094
+ });
2095
+ return response.data;
2096
+ } catch (error) {
2097
+ throw KadoaHttpException.wrap(error, {
2098
+ message: ERROR_MESSAGES.PROGRESS_CHECK_FAILED,
2099
+ details: { workflowId }
2100
+ });
2101
+ }
2079
2102
  }
2080
- }
2081
- async function waitForWorkflowCompletion(sdkInstance, workflowId, options) {
2082
- const pollingInterval = options.pollingInterval;
2083
- const maxWaitTime = options.maxWaitTime;
2084
- const startTime = Date.now();
2085
- let previousState;
2086
- let previousRunState;
2087
- while (Date.now() - startTime < maxWaitTime) {
2088
- const workflow = await getWorkflowStatus(sdkInstance, workflowId);
2089
- if (workflow.state !== previousState || workflow.runState !== previousRunState) {
2090
- const statusChange = {
2091
- workflowId,
2092
- previousState,
2093
- previousRunState,
2094
- currentState: workflow.state,
2095
- currentRunState: workflow.runState
2096
- };
2097
- sdkInstance.emit("extraction:status_changed", statusChange, "extraction");
2098
- if (options?.onStatusChange) {
2099
- options.onStatusChange(statusChange);
2103
+ /**
2104
+ * Waits for a workflow to complete processing
2105
+ *
2106
+ * @param workflowId The workflow ID to monitor
2107
+ * @param pollingInterval How often to check the status (in milliseconds)
2108
+ * @param maxWaitTime Maximum time to wait before timing out (in milliseconds)
2109
+ * @param onStatusChange Optional callback for status changes
2110
+ * @returns The final workflow status
2111
+ */
2112
+ async waitForWorkflowCompletion(workflowId, pollingInterval, maxWaitTime, onStatusChange) {
2113
+ const startTime = Date.now();
2114
+ let lastStatus;
2115
+ while (Date.now() - startTime < maxWaitTime) {
2116
+ const currentStatus = await this.getWorkflowStatus(workflowId);
2117
+ if (lastStatus?.state !== currentStatus.state || lastStatus?.runState !== currentStatus.runState) {
2118
+ const eventPayload = {
2119
+ workflowId,
2120
+ previousState: lastStatus?.state,
2121
+ previousRunState: lastStatus?.runState,
2122
+ currentState: currentStatus.state,
2123
+ currentRunState: currentStatus.runState
2124
+ };
2125
+ this.client.emit(
2126
+ "extraction:status_changed",
2127
+ eventPayload,
2128
+ "extraction"
2129
+ );
2130
+ if (onStatusChange) {
2131
+ onStatusChange(lastStatus, currentStatus);
2132
+ }
2100
2133
  }
2101
- previousState = workflow.state;
2102
- previousRunState = workflow.runState;
2103
- }
2104
- if (isTerminalRunState(workflow.runState)) {
2105
- return workflow;
2134
+ if (this.isTerminalRunState(currentStatus.runState)) {
2135
+ return currentStatus;
2136
+ }
2137
+ lastStatus = currentStatus;
2138
+ await new Promise((resolve) => setTimeout(resolve, pollingInterval));
2106
2139
  }
2107
- await new Promise((resolve) => setTimeout(resolve, pollingInterval));
2140
+ throw new KadoaSdkException(ERROR_MESSAGES.WORKFLOW_TIMEOUT, {
2141
+ code: "TIMEOUT",
2142
+ details: {
2143
+ workflowId,
2144
+ maxWaitTime,
2145
+ lastState: lastStatus?.state,
2146
+ lastRunState: lastStatus?.runState
2147
+ }
2148
+ });
2108
2149
  }
2109
- throw new KadoaSdkException(
2110
- `Extraction did not complete within ${maxWaitTime / 1e3} seconds`,
2111
- { code: "TIMEOUT", details: { workflowId, maxWaitTime } }
2112
- );
2113
- }
2150
+ };
2114
2151
 
2115
- // src/extraction/extraction-runner.ts
2116
- function validateExtractionOptions(options) {
2117
- if (!options.urls || options.urls.length === 0) {
2118
- throw new KadoaSdkException(ERROR_MESSAGES.NO_URLS, {
2119
- code: "VALIDATION_ERROR"
2120
- });
2152
+ // src/modules/extraction/commands/run-extraction.command.ts
2153
+ var SUCCESSFUL_RUN_STATES = /* @__PURE__ */ new Set(["FINISHED", "SUCCESS"]);
2154
+ var DEFAULT_OPTIONS = {
2155
+ pollingInterval: 5e3,
2156
+ maxWaitTime: 3e5,
2157
+ navigationMode: "single-page",
2158
+ location: { type: "auto" },
2159
+ name: "Untitled Workflow",
2160
+ maxRecords: 1e3
2161
+ };
2162
+ var RunExtractionCommand = class extends Command {
2163
+ constructor(client) {
2164
+ super();
2165
+ this.client = client;
2166
+ this.dataFetcher = new DataFetcherService(client);
2167
+ this.entityDetector = new EntityDetectorService(client);
2168
+ this.workflowManager = new WorkflowManagerService(client);
2121
2169
  }
2122
- }
2123
- function isExtractionSuccessful(runState) {
2124
- return runState ? SUCCESSFUL_RUN_STATES.has(runState.toUpperCase()) : false;
2125
- }
2126
- async function runExtraction(sdkInstance, options) {
2127
- validateExtractionOptions(options);
2128
- const config = merge(
2129
- DEFAULT_OPTIONS,
2130
- options
2131
- );
2132
- try {
2133
- const entityPrediction = await fetchEntityFields(sdkInstance, {
2134
- link: config.urls[0],
2135
- location: config.location,
2136
- navigationMode: config.navigationMode
2137
- });
2138
- sdkInstance.emit(
2139
- "entity:detected",
2140
- {
2141
- entity: entityPrediction.entity,
2142
- fields: entityPrediction.fields,
2143
- url: config.urls[0]
2144
- },
2145
- "extraction",
2146
- {
2147
- navigationMode: config.navigationMode,
2148
- location: config.location
2149
- }
2150
- );
2151
- const workflowId = await createWorkflow(sdkInstance, {
2152
- urls: config.urls,
2153
- navigationMode: config.navigationMode,
2154
- entity: entityPrediction.entity,
2155
- fields: entityPrediction.fields,
2156
- name: config.name
2157
- });
2158
- sdkInstance.emit(
2159
- "extraction:started",
2160
- {
2161
- workflowId,
2162
- name: config.name,
2163
- urls: config.urls
2164
- },
2165
- "extraction"
2170
+ /**
2171
+ * Execute the extraction workflow
2172
+ */
2173
+ async execute(options) {
2174
+ this.validateOptions(options);
2175
+ const config = merge(
2176
+ DEFAULT_OPTIONS,
2177
+ options
2166
2178
  );
2167
- const workflow = await waitForWorkflowCompletion(sdkInstance, workflowId, {
2168
- pollingInterval: config.pollingInterval,
2169
- maxWaitTime: config.maxWaitTime
2170
- });
2171
- let data;
2172
- const isSuccess = isExtractionSuccessful(workflow.runState);
2173
- if (isSuccess) {
2174
- data = await fetchWorkflowData(sdkInstance, workflowId);
2175
- if (data) {
2176
- sdkInstance.emit(
2177
- "extraction:data_available",
2178
- {
2179
- workflowId,
2180
- recordCount: data.length,
2181
- isPartial: false
2182
- },
2183
- "extraction"
2184
- );
2185
- }
2186
- sdkInstance.emit(
2187
- "extraction:completed",
2179
+ try {
2180
+ const entityPrediction = await this.entityDetector.fetchEntityFields({
2181
+ link: config.urls[0],
2182
+ location: config.location,
2183
+ navigationMode: config.navigationMode
2184
+ });
2185
+ this.client.emit(
2186
+ "entity:detected",
2188
2187
  {
2189
- workflowId,
2190
- success: true,
2191
- finalRunState: workflow.runState,
2192
- finalState: workflow.state,
2193
- recordCount: data?.length
2188
+ entity: entityPrediction.entity,
2189
+ fields: entityPrediction.fields,
2190
+ url: config.urls[0]
2194
2191
  },
2195
- "extraction"
2192
+ "extraction",
2193
+ {
2194
+ navigationMode: config.navigationMode,
2195
+ location: config.location
2196
+ }
2196
2197
  );
2197
- } else {
2198
- sdkInstance.emit(
2199
- "extraction:completed",
2198
+ const workflowId = await this.workflowManager.createWorkflow({
2199
+ entity: entityPrediction.entity,
2200
+ fields: entityPrediction.fields,
2201
+ ...config
2202
+ });
2203
+ this.client.emit(
2204
+ "extraction:started",
2200
2205
  {
2201
2206
  workflowId,
2202
- success: false,
2203
- finalRunState: workflow.runState,
2204
- finalState: workflow.state,
2205
- error: `Extraction completed with unexpected status: ${workflow.runState}`
2207
+ name: config.name,
2208
+ urls: config.urls
2206
2209
  },
2207
2210
  "extraction"
2208
2211
  );
2209
- throw new KadoaSdkException(
2210
- `Extraction completed with unexpected status: ${workflow.runState}`,
2211
- {
2212
- code: "INTERNAL_ERROR",
2213
- details: {
2212
+ const workflow = await this.workflowManager.waitForWorkflowCompletion(
2213
+ workflowId,
2214
+ config.pollingInterval,
2215
+ config.maxWaitTime
2216
+ );
2217
+ let data;
2218
+ const isSuccess = this.isExtractionSuccessful(workflow.runState);
2219
+ if (isSuccess) {
2220
+ data = await this.dataFetcher.fetchWorkflowData(
2221
+ workflowId,
2222
+ config.maxRecords
2223
+ );
2224
+ if (data) {
2225
+ this.client.emit(
2226
+ "extraction:data_available",
2227
+ {
2228
+ workflowId,
2229
+ recordCount: data.length,
2230
+ isPartial: false
2231
+ },
2232
+ "extraction"
2233
+ );
2234
+ }
2235
+ this.client.emit(
2236
+ "extraction:completed",
2237
+ {
2214
2238
  workflowId,
2215
- runState: workflow.runState,
2216
- state: workflow.state
2239
+ success: true,
2240
+ finalRunState: workflow.runState,
2241
+ finalState: workflow.state,
2242
+ recordCount: data?.length
2243
+ },
2244
+ "extraction"
2245
+ );
2246
+ } else {
2247
+ this.client.emit(
2248
+ "extraction:completed",
2249
+ {
2250
+ workflowId,
2251
+ success: false,
2252
+ finalRunState: workflow.runState,
2253
+ finalState: workflow.state,
2254
+ error: `Extraction completed with unexpected status: ${workflow.runState}`
2255
+ },
2256
+ "extraction"
2257
+ );
2258
+ throw new KadoaSdkException(
2259
+ `${ERROR_MESSAGES.WORKFLOW_UNEXPECTED_STATUS}: ${workflow.runState}`,
2260
+ {
2261
+ code: "INTERNAL_ERROR",
2262
+ details: {
2263
+ workflowId,
2264
+ runState: workflow.runState,
2265
+ state: workflow.state
2266
+ }
2217
2267
  }
2218
- }
2219
- );
2268
+ );
2269
+ }
2270
+ return {
2271
+ workflowId,
2272
+ workflow,
2273
+ data
2274
+ };
2275
+ } catch (error) {
2276
+ throw KadoaHttpException.wrap(error, {
2277
+ message: ERROR_MESSAGES.EXTRACTION_FAILED,
2278
+ details: { urls: options.urls }
2279
+ });
2220
2280
  }
2221
- return {
2222
- workflowId,
2223
- workflow,
2224
- data
2281
+ }
2282
+ /**
2283
+ * Validates extraction options
2284
+ * @private
2285
+ */
2286
+ validateOptions(options) {
2287
+ if (!options.urls || options.urls.length === 0) {
2288
+ throw new KadoaSdkException(ERROR_MESSAGES.NO_URLS, {
2289
+ code: "VALIDATION_ERROR"
2290
+ });
2291
+ }
2292
+ }
2293
+ /**
2294
+ * Checks if extraction was successful
2295
+ * @private
2296
+ */
2297
+ isExtractionSuccessful(runState) {
2298
+ return runState ? SUCCESSFUL_RUN_STATES.has(runState.toUpperCase()) : false;
2299
+ }
2300
+ };
2301
+
2302
+ // src/modules/extraction/extraction.module.ts
2303
+ var ExtractionModule = class {
2304
+ constructor(client) {
2305
+ this.runExtractionCommand = new RunExtractionCommand(client);
2306
+ }
2307
+ /**
2308
+ * Run extraction workflow using dynamic entity detection
2309
+ *
2310
+ * @param options Extraction configuration options
2311
+ * @returns ExtractionResult containing workflow ID, workflow details, and extracted data
2312
+ *
2313
+ * @example
2314
+ * ```typescript
2315
+ * const result = await client.extraction.run({
2316
+ * urls: ['https://example.com'],
2317
+ * name: 'My Extraction'
2318
+ * });
2319
+ * ```
2320
+ */
2321
+ async run(options) {
2322
+ return this.runExtractionCommand.execute(options);
2323
+ }
2324
+ };
2325
+
2326
+ // src/version.ts
2327
+ var SDK_VERSION = "0.4.0";
2328
+ var SDK_NAME = "kadoa-node-sdk";
2329
+ var SDK_LANGUAGE = "node";
2330
+
2331
+ // src/kadoa-client.ts
2332
+ var KadoaClient = class {
2333
+ constructor(config) {
2334
+ this._baseUrl = config.baseUrl || "https://api.kadoa.com";
2335
+ this._timeout = config.timeout || 3e4;
2336
+ const configParams = {
2337
+ apiKey: config.apiKey,
2338
+ basePath: this._baseUrl,
2339
+ baseOptions: {
2340
+ headers: {
2341
+ "User-Agent": `${SDK_NAME}/${SDK_VERSION}`,
2342
+ "X-SDK-Version": SDK_VERSION,
2343
+ "X-SDK-Language": SDK_LANGUAGE
2344
+ }
2345
+ }
2225
2346
  };
2226
- } catch (error) {
2227
- throw wrapKadoaError(error, {
2228
- message: ERROR_MESSAGES.EXTRACTION_FAILED,
2229
- details: { urls: options.urls }
2347
+ this._configuration = new Configuration(configParams);
2348
+ this._axiosInstance = globalAxios2.create({
2349
+ timeout: this._timeout,
2350
+ headers: {
2351
+ "User-Agent": `${SDK_NAME}/${SDK_VERSION}`,
2352
+ "X-SDK-Version": SDK_VERSION,
2353
+ "X-SDK-Language": SDK_LANGUAGE
2354
+ }
2230
2355
  });
2356
+ this._events = new KadoaEventEmitter();
2357
+ this.extraction = new ExtractionModule(this);
2231
2358
  }
2232
- }
2233
- function initializeSdk(config) {
2234
- const baseUrl = config.baseUrl || "https://api.kadoa.com";
2235
- const configParams = {
2236
- apiKey: config.apiKey,
2237
- basePath: baseUrl
2238
- };
2239
- const configuration = new Configuration(configParams);
2240
- const axiosInstance = globalAxios2.create({
2241
- timeout: config.timeout || 3e4
2242
- });
2243
- const events = new KadoaEventEmitter();
2244
- return {
2245
- configuration,
2246
- axiosInstance,
2247
- baseUrl,
2248
- events,
2249
- emit: (eventName, payload, source, metadata) => {
2250
- events.emit(eventName, payload, source, metadata);
2251
- },
2252
- onEvent: (listener) => {
2253
- events.onEvent(listener);
2254
- },
2255
- offEvent: (listener) => {
2256
- events.offEvent(listener);
2257
- }
2258
- };
2259
- }
2260
- function dispose(sdkInstance) {
2261
- if (sdkInstance?.events) {
2262
- sdkInstance.events.removeAllListeners();
2359
+ /**
2360
+ * Register an event listener
2361
+ *
2362
+ * @param listener Function to handle events
2363
+ */
2364
+ onEvent(listener) {
2365
+ this._events.onEvent(listener);
2263
2366
  }
2264
- }
2367
+ /**
2368
+ * Remove an event listener
2369
+ *
2370
+ * @param listener Function to remove from event handlers
2371
+ */
2372
+ offEvent(listener) {
2373
+ this._events.offEvent(listener);
2374
+ }
2375
+ /**
2376
+ * Emit an event
2377
+ * @internal
2378
+ *
2379
+ * @param eventName The name of the event
2380
+ * @param payload The event payload
2381
+ * @param source Optional source identifier
2382
+ * @param metadata Optional metadata
2383
+ */
2384
+ emit(eventName, payload, source, metadata) {
2385
+ this._events.emit(eventName, payload, source, metadata);
2386
+ }
2387
+ /**
2388
+ * Get the underlying configuration
2389
+ *
2390
+ * @returns The configuration object
2391
+ */
2392
+ get configuration() {
2393
+ return this._configuration;
2394
+ }
2395
+ /**
2396
+ * Get the axios instance
2397
+ *
2398
+ * @returns The axios instance
2399
+ */
2400
+ get axiosInstance() {
2401
+ return this._axiosInstance;
2402
+ }
2403
+ /**
2404
+ * Get the base URL
2405
+ *
2406
+ * @returns The base URL
2407
+ */
2408
+ get baseUrl() {
2409
+ return this._baseUrl;
2410
+ }
2411
+ /**
2412
+ * Get the timeout value
2413
+ *
2414
+ * @returns The timeout in milliseconds
2415
+ */
2416
+ get timeout() {
2417
+ return this._timeout;
2418
+ }
2419
+ /**
2420
+ * Get the event emitter
2421
+ * @internal
2422
+ *
2423
+ * @returns The event emitter
2424
+ */
2425
+ get events() {
2426
+ return this._events;
2427
+ }
2428
+ /**
2429
+ * Dispose of the client and clean up resources
2430
+ */
2431
+ dispose() {
2432
+ this._events?.removeAllListeners();
2433
+ }
2434
+ };
2265
2435
 
2266
- export { KadoaEventEmitter, KadoaHttpException, KadoaSdkException, dispose, initializeSdk, isKadoaHttpException, isKadoaSdkException, runExtraction };
2436
+ export { ERROR_MESSAGES, KadoaClient, KadoaEventEmitter, KadoaHttpException, KadoaSdkException };
2267
2437
  //# sourceMappingURL=index.mjs.map
2268
2438
  //# sourceMappingURL=index.mjs.map