@kadoa/node-sdk 0.12.1 → 0.14.1
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/browser/index.global.js +13 -13
- package/dist/browser/index.global.js.map +1 -1
- package/dist/index.d.mts +1028 -748
- package/dist/index.d.ts +1028 -748
- package/dist/index.js +1391 -1605
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1375 -1605
- package/dist/index.mjs.map +1 -1
- package/package.json +68 -65
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var globalAxios5 = require('axios');
|
|
4
|
-
var uuid = require('uuid');
|
|
5
|
-
var url = require('url');
|
|
6
4
|
var createDebug = require('debug');
|
|
7
5
|
var esToolkit = require('es-toolkit');
|
|
8
|
-
var
|
|
6
|
+
var url = require('url');
|
|
9
7
|
var assert = require('assert');
|
|
8
|
+
var zod = require('zod');
|
|
9
|
+
var uuid = require('uuid');
|
|
10
10
|
|
|
11
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
12
|
|
|
@@ -21,12 +21,127 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
21
21
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
// src/
|
|
24
|
+
// src/domains/extraction/extraction.acl.ts
|
|
25
|
+
var FetchDataOptions = class {
|
|
26
|
+
};
|
|
27
|
+
var SchemaFieldDataType = {
|
|
28
|
+
Text: "TEXT",
|
|
29
|
+
Number: "NUMBER",
|
|
30
|
+
Date: "DATE",
|
|
31
|
+
Url: "URL",
|
|
32
|
+
Email: "EMAIL",
|
|
33
|
+
Image: "IMAGE",
|
|
34
|
+
Video: "VIDEO",
|
|
35
|
+
Phone: "PHONE",
|
|
36
|
+
Boolean: "BOOLEAN",
|
|
37
|
+
Location: "LOCATION",
|
|
38
|
+
Array: "ARRAY",
|
|
39
|
+
Object: "OBJECT"
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// src/runtime/pagination/paginator.ts
|
|
43
|
+
var PagedIterator = class {
|
|
44
|
+
constructor(fetchPage) {
|
|
45
|
+
this.fetchPage = fetchPage;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Fetch all items across all pages
|
|
49
|
+
* @param options Base options (page will be overridden)
|
|
50
|
+
* @returns Array of all items
|
|
51
|
+
*/
|
|
52
|
+
async fetchAll(options = {}) {
|
|
53
|
+
const allItems = [];
|
|
54
|
+
let currentPage = 1;
|
|
55
|
+
let hasMore = true;
|
|
56
|
+
while (hasMore) {
|
|
57
|
+
const result = await this.fetchPage({ ...options, page: currentPage });
|
|
58
|
+
allItems.push(...result.data);
|
|
59
|
+
const pagination = result.pagination;
|
|
60
|
+
hasMore = pagination.page !== void 0 && pagination.totalPages !== void 0 && pagination.page < pagination.totalPages;
|
|
61
|
+
currentPage++;
|
|
62
|
+
}
|
|
63
|
+
return allItems;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create an async iterator for pages
|
|
67
|
+
* @param options Base options (page will be overridden)
|
|
68
|
+
* @returns Async generator that yields pages
|
|
69
|
+
*/
|
|
70
|
+
async *pages(options = {}) {
|
|
71
|
+
let currentPage = 1;
|
|
72
|
+
let hasMore = true;
|
|
73
|
+
while (hasMore) {
|
|
74
|
+
const result = await this.fetchPage({ ...options, page: currentPage });
|
|
75
|
+
yield result;
|
|
76
|
+
const pagination = result.pagination;
|
|
77
|
+
hasMore = pagination.page !== void 0 && pagination.totalPages !== void 0 && pagination.page < pagination.totalPages;
|
|
78
|
+
currentPage++;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Create an async iterator for individual items
|
|
83
|
+
* @param options Base options (page will be overridden)
|
|
84
|
+
* @returns Async generator that yields items
|
|
85
|
+
*/
|
|
86
|
+
async *items(options = {}) {
|
|
87
|
+
for await (const page of this.pages(options)) {
|
|
88
|
+
for (const item of page.data) {
|
|
89
|
+
yield item;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// src/domains/extraction/services/data-fetcher.service.ts
|
|
96
|
+
var DataFetcherService = class {
|
|
97
|
+
constructor(workflowsApi) {
|
|
98
|
+
this.workflowsApi = workflowsApi;
|
|
99
|
+
this.defaultLimit = 100;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Fetch a page of workflow data
|
|
103
|
+
*/
|
|
104
|
+
async fetchData(options) {
|
|
105
|
+
const response = await this.workflowsApi.v4WorkflowsWorkflowIdDataGet({
|
|
106
|
+
...options,
|
|
107
|
+
page: options.page ?? 1,
|
|
108
|
+
limit: options.limit ?? this.defaultLimit
|
|
109
|
+
});
|
|
110
|
+
const result = response.data;
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Fetch all pages of workflow data
|
|
115
|
+
*/
|
|
116
|
+
async fetchAllData(options) {
|
|
117
|
+
const iterator = new PagedIterator(
|
|
118
|
+
(pageOptions) => this.fetchData({ ...options, ...pageOptions })
|
|
119
|
+
);
|
|
120
|
+
return iterator.fetchAll({ limit: options.limit ?? this.defaultLimit });
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Create an async iterator for paginated data fetching
|
|
124
|
+
*/
|
|
125
|
+
async *fetchDataPages(options) {
|
|
126
|
+
const iterator = new PagedIterator(
|
|
127
|
+
(pageOptions) => this.fetchData({ ...options, ...pageOptions })
|
|
128
|
+
);
|
|
129
|
+
for await (const page of iterator.pages({
|
|
130
|
+
limit: options.limit ?? this.defaultLimit
|
|
131
|
+
})) {
|
|
132
|
+
yield page;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// src/runtime/exceptions/base.exception.ts
|
|
25
138
|
var KadoaErrorCode = {
|
|
26
139
|
AUTH_ERROR: "AUTH_ERROR",
|
|
27
140
|
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
28
141
|
BAD_REQUEST: "BAD_REQUEST",
|
|
29
|
-
NOT_FOUND: "NOT_FOUND"
|
|
142
|
+
NOT_FOUND: "NOT_FOUND",
|
|
143
|
+
INTERNAL_ERROR: "INTERNAL_ERROR"
|
|
144
|
+
};
|
|
30
145
|
var _KadoaSdkException = class _KadoaSdkException extends Error {
|
|
31
146
|
constructor(message, options) {
|
|
32
147
|
super(message);
|
|
@@ -108,7 +223,10 @@ _KadoaSdkException.ERROR_MESSAGES = {
|
|
|
108
223
|
// Schema specific errors
|
|
109
224
|
SCHEMA_NOT_FOUND: "Schema not found",
|
|
110
225
|
SCHEMA_FETCH_ERROR: "Failed to fetch schema",
|
|
111
|
-
SCHEMAS_FETCH_ERROR: "Failed to fetch schemas"
|
|
226
|
+
SCHEMAS_FETCH_ERROR: "Failed to fetch schemas",
|
|
227
|
+
SCHEMA_CREATE_FAILED: "Failed to create schema",
|
|
228
|
+
SCHEMA_UPDATE_FAILED: "Failed to update schema",
|
|
229
|
+
SCHEMA_DELETE_FAILED: "Failed to delete schema"
|
|
112
230
|
};
|
|
113
231
|
var KadoaSdkException = _KadoaSdkException;
|
|
114
232
|
var ERROR_MESSAGES = KadoaSdkException.ERROR_MESSAGES;
|
|
@@ -199,6 +317,128 @@ var KadoaHttpException = class _KadoaHttpException extends KadoaSdkException {
|
|
|
199
317
|
return "UNKNOWN";
|
|
200
318
|
}
|
|
201
319
|
};
|
|
320
|
+
var createLogger = (namespace) => createDebug__default.default(`kadoa:${namespace}`);
|
|
321
|
+
var logger = {
|
|
322
|
+
client: createLogger("client"),
|
|
323
|
+
wss: createLogger("wss"),
|
|
324
|
+
extraction: createLogger("extraction"),
|
|
325
|
+
http: createLogger("http"),
|
|
326
|
+
workflow: createLogger("workflow"),
|
|
327
|
+
crawl: createLogger("crawl"),
|
|
328
|
+
notifications: createLogger("notifications"),
|
|
329
|
+
schemas: createLogger("schemas"),
|
|
330
|
+
validation: createLogger("validation")
|
|
331
|
+
};
|
|
332
|
+
var _SchemaBuilder = class _SchemaBuilder {
|
|
333
|
+
constructor() {
|
|
334
|
+
this.fields = [];
|
|
335
|
+
}
|
|
336
|
+
entity(entityName) {
|
|
337
|
+
this.entityName = entityName;
|
|
338
|
+
return this;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Add a structured field to the schema
|
|
342
|
+
* @param name - Field name (alphanumeric only)
|
|
343
|
+
* @param description - Field description
|
|
344
|
+
* @param dataType - Data type (STRING, NUMBER, BOOLEAN, etc.)
|
|
345
|
+
* @param options - Optional field configuration
|
|
346
|
+
*/
|
|
347
|
+
field(name, description, dataType, options) {
|
|
348
|
+
this.validateFieldName(name);
|
|
349
|
+
const requiresExample = _SchemaBuilder.TYPES_REQUIRING_EXAMPLE.includes(dataType);
|
|
350
|
+
if (requiresExample && !options?.example) {
|
|
351
|
+
throw new KadoaSdkException(
|
|
352
|
+
`Field "${name}" with type ${dataType} requires an example`,
|
|
353
|
+
{ code: "VALIDATION_ERROR", details: { name, dataType } }
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
this.fields.push({
|
|
357
|
+
name,
|
|
358
|
+
description,
|
|
359
|
+
dataType,
|
|
360
|
+
fieldType: "SCHEMA",
|
|
361
|
+
example: options?.example,
|
|
362
|
+
isKey: options?.isKey
|
|
363
|
+
});
|
|
364
|
+
return this;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Add a classification field to categorize content
|
|
368
|
+
* @param name - Field name (alphanumeric only)
|
|
369
|
+
* @param description - Field description
|
|
370
|
+
* @param categories - Array of category definitions
|
|
371
|
+
*/
|
|
372
|
+
classify(name, description, categories) {
|
|
373
|
+
this.validateFieldName(name);
|
|
374
|
+
this.fields.push({
|
|
375
|
+
name,
|
|
376
|
+
description,
|
|
377
|
+
fieldType: "CLASSIFICATION",
|
|
378
|
+
categories
|
|
379
|
+
});
|
|
380
|
+
return this;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Add raw page content to extract
|
|
384
|
+
* @param name - Raw content format(s): "html", "markdown", or "url"
|
|
385
|
+
*/
|
|
386
|
+
raw(name) {
|
|
387
|
+
const names = Array.isArray(name) ? name : [name];
|
|
388
|
+
for (const name2 of names) {
|
|
389
|
+
const fieldName = `raw${esToolkit.upperFirst(esToolkit.camelCase(name2))}`;
|
|
390
|
+
if (this.fields.some((field) => field.name === fieldName)) {
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
this.fields.push({
|
|
394
|
+
name: fieldName,
|
|
395
|
+
description: `Raw page content in ${name2.toUpperCase()} format`,
|
|
396
|
+
fieldType: "METADATA",
|
|
397
|
+
metadataKey: name2
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
return this;
|
|
401
|
+
}
|
|
402
|
+
build() {
|
|
403
|
+
if (!this.entityName) {
|
|
404
|
+
throw new KadoaSdkException("Entity name is required", {
|
|
405
|
+
code: "VALIDATION_ERROR",
|
|
406
|
+
details: { entityName: this.entityName }
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
return {
|
|
410
|
+
entityName: this.entityName,
|
|
411
|
+
fields: this.fields
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
validateFieldName(name) {
|
|
415
|
+
if (!_SchemaBuilder.FIELD_NAME_PATTERN.test(name)) {
|
|
416
|
+
throw new KadoaSdkException(
|
|
417
|
+
`Field name "${name}" must be alphanumeric only (no underscores or special characters)`,
|
|
418
|
+
{
|
|
419
|
+
code: "VALIDATION_ERROR",
|
|
420
|
+
details: { name, pattern: "^[A-Za-z0-9]+$" }
|
|
421
|
+
}
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
const lowerName = name.toLowerCase();
|
|
425
|
+
if (this.fields.some((f) => f.name.toLowerCase() === lowerName)) {
|
|
426
|
+
throw new KadoaSdkException(`Duplicate field name: "${name}"`, {
|
|
427
|
+
code: "VALIDATION_ERROR",
|
|
428
|
+
details: { name }
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
_SchemaBuilder.FIELD_NAME_PATTERN = /^[A-Za-z0-9]+$/;
|
|
434
|
+
_SchemaBuilder.TYPES_REQUIRING_EXAMPLE = [
|
|
435
|
+
"STRING",
|
|
436
|
+
"IMAGE",
|
|
437
|
+
"LINK",
|
|
438
|
+
"OBJECT",
|
|
439
|
+
"ARRAY"
|
|
440
|
+
];
|
|
441
|
+
var SchemaBuilder = _SchemaBuilder;
|
|
202
442
|
var BASE_PATH = "https://api.kadoa.com".replace(/\/+$/, "");
|
|
203
443
|
var BaseAPI = class {
|
|
204
444
|
constructor(configuration, basePath = BASE_PATH, axios2 = globalAxios5__default.default) {
|
|
@@ -2611,7 +2851,7 @@ var WorkflowsApiAxiosParamCreator = function(configuration) {
|
|
|
2611
2851
|
/**
|
|
2612
2852
|
* Retrieves a list of workflows with pagination and search capabilities
|
|
2613
2853
|
* @summary Get a list of workflows
|
|
2614
|
-
* @param {string} [search] Search term to filter workflows by name or
|
|
2854
|
+
* @param {string} [search] Search term to filter workflows by name, URL, or workflow ID
|
|
2615
2855
|
* @param {number} [skip] Number of items to skip
|
|
2616
2856
|
* @param {number} [limit] Maximum number of items to return
|
|
2617
2857
|
* @param {V4WorkflowsGetStateEnum} [state] Filter workflows by state
|
|
@@ -3445,7 +3685,7 @@ var WorkflowsApiFp = function(configuration) {
|
|
|
3445
3685
|
/**
|
|
3446
3686
|
* Retrieves a list of workflows with pagination and search capabilities
|
|
3447
3687
|
* @summary Get a list of workflows
|
|
3448
|
-
* @param {string} [search] Search term to filter workflows by name or
|
|
3688
|
+
* @param {string} [search] Search term to filter workflows by name, URL, or workflow ID
|
|
3449
3689
|
* @param {number} [skip] Number of items to skip
|
|
3450
3690
|
* @param {number} [limit] Maximum number of items to return
|
|
3451
3691
|
* @param {V4WorkflowsGetStateEnum} [state] Filter workflows by state
|
|
@@ -4053,624 +4293,277 @@ var Configuration = class {
|
|
|
4053
4293
|
}
|
|
4054
4294
|
};
|
|
4055
4295
|
|
|
4056
|
-
// src/
|
|
4057
|
-
var
|
|
4058
|
-
var
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4296
|
+
// src/domains/schemas/schemas.service.ts
|
|
4297
|
+
var debug = logger.schemas;
|
|
4298
|
+
var SchemasService = class {
|
|
4299
|
+
constructor(client) {
|
|
4300
|
+
this.schemasApi = new SchemasApi(client.configuration);
|
|
4301
|
+
}
|
|
4302
|
+
/**
|
|
4303
|
+
* Create a schema builder with fluent API and inline create support.
|
|
4304
|
+
*/
|
|
4305
|
+
builder(entityName) {
|
|
4306
|
+
const service = this;
|
|
4307
|
+
return new class extends SchemaBuilder {
|
|
4308
|
+
constructor() {
|
|
4309
|
+
super();
|
|
4310
|
+
this.entity(entityName);
|
|
4311
|
+
}
|
|
4312
|
+
async create(name) {
|
|
4313
|
+
const built = this.build();
|
|
4314
|
+
return service.createSchema({
|
|
4315
|
+
name: name || built.entityName,
|
|
4316
|
+
entity: built.entityName,
|
|
4317
|
+
fields: built.fields
|
|
4318
|
+
});
|
|
4319
|
+
}
|
|
4320
|
+
}();
|
|
4321
|
+
}
|
|
4322
|
+
/**
|
|
4323
|
+
* Get a schema by ID
|
|
4324
|
+
*/
|
|
4325
|
+
async getSchema(schemaId) {
|
|
4326
|
+
debug("Fetching schema with ID: %s", schemaId);
|
|
4327
|
+
const response = await this.schemasApi.v4SchemasSchemaIdGet({
|
|
4328
|
+
schemaId
|
|
4329
|
+
});
|
|
4330
|
+
const schemaData = response.data.data;
|
|
4331
|
+
if (!schemaData) {
|
|
4091
4332
|
throw new KadoaSdkException(
|
|
4092
|
-
|
|
4333
|
+
`${ERROR_MESSAGES.SCHEMA_NOT_FOUND}: ${schemaId}`,
|
|
4093
4334
|
{
|
|
4094
|
-
code:
|
|
4095
|
-
details: {
|
|
4096
|
-
}
|
|
4097
|
-
);
|
|
4098
|
-
}
|
|
4099
|
-
this.teamApiKey = config.teamApiKey;
|
|
4100
|
-
this.heartbeatInterval = config.heartbeatInterval || 1e4;
|
|
4101
|
-
this.reconnectDelay = config.reconnectDelay || 5e3;
|
|
4102
|
-
this.missedHeartbeatsLimit = config.missedHeartbeatsLimit || 3e4;
|
|
4103
|
-
}
|
|
4104
|
-
async connect() {
|
|
4105
|
-
if (this.isConnecting) return;
|
|
4106
|
-
this.isConnecting = true;
|
|
4107
|
-
try {
|
|
4108
|
-
const response = await fetch(`${PUBLIC_API_URI}/v4/oauth2/token`, {
|
|
4109
|
-
method: "POST",
|
|
4110
|
-
headers: {
|
|
4111
|
-
"Content-Type": "application/json",
|
|
4112
|
-
"x-api-key": `${this.teamApiKey}`,
|
|
4113
|
-
"x-sdk-version": SDK_VERSION
|
|
4335
|
+
code: KadoaErrorCode.NOT_FOUND,
|
|
4336
|
+
details: { schemaId }
|
|
4114
4337
|
}
|
|
4115
|
-
});
|
|
4116
|
-
const { access_token, team_id } = await response.json();
|
|
4117
|
-
this.socket = new WebSocket(
|
|
4118
|
-
`${WSS_API_URI}?access_token=${access_token}`
|
|
4119
4338
|
);
|
|
4120
|
-
this.socket.onopen = () => {
|
|
4121
|
-
this.isConnecting = false;
|
|
4122
|
-
this.lastHeartbeat = Date.now();
|
|
4123
|
-
if (this.socket?.readyState === WebSocket.OPEN) {
|
|
4124
|
-
this.socket.send(
|
|
4125
|
-
JSON.stringify({
|
|
4126
|
-
action: "subscribe",
|
|
4127
|
-
channel: team_id
|
|
4128
|
-
})
|
|
4129
|
-
);
|
|
4130
|
-
debug("Connected to WebSocket");
|
|
4131
|
-
this.notifyConnectionListeners(true);
|
|
4132
|
-
}
|
|
4133
|
-
this.startHeartbeatCheck();
|
|
4134
|
-
};
|
|
4135
|
-
this.socket.onmessage = (event) => {
|
|
4136
|
-
try {
|
|
4137
|
-
const data = JSON.parse(event.data);
|
|
4138
|
-
if (data.type === "heartbeat") {
|
|
4139
|
-
this.handleHeartbeat();
|
|
4140
|
-
} else {
|
|
4141
|
-
if (data?.id) {
|
|
4142
|
-
fetch(`${REALTIME_API_URI}/api/v1/events/ack`, {
|
|
4143
|
-
method: "POST",
|
|
4144
|
-
headers: { "Content-Type": "application/json" },
|
|
4145
|
-
body: JSON.stringify({ id: data.id })
|
|
4146
|
-
});
|
|
4147
|
-
}
|
|
4148
|
-
this.notifyEventListeners(data);
|
|
4149
|
-
}
|
|
4150
|
-
} catch (err) {
|
|
4151
|
-
debug("Failed to parse incoming message: %O", err);
|
|
4152
|
-
}
|
|
4153
|
-
};
|
|
4154
|
-
this.socket.onclose = () => {
|
|
4155
|
-
debug("WebSocket disconnected. Attempting to reconnect...");
|
|
4156
|
-
this.isConnecting = false;
|
|
4157
|
-
this.stopHeartbeatCheck();
|
|
4158
|
-
this.notifyConnectionListeners(false, "Connection closed");
|
|
4159
|
-
setTimeout(() => this.connect(), this.reconnectDelay);
|
|
4160
|
-
};
|
|
4161
|
-
this.socket.onerror = (error) => {
|
|
4162
|
-
debug("WebSocket error: %O", error);
|
|
4163
|
-
this.isConnecting = false;
|
|
4164
|
-
this.notifyErrorListeners(error);
|
|
4165
|
-
};
|
|
4166
|
-
} catch (err) {
|
|
4167
|
-
debug("Failed to connect: %O", err);
|
|
4168
|
-
this.isConnecting = false;
|
|
4169
|
-
setTimeout(() => this.connect(), this.reconnectDelay);
|
|
4170
|
-
}
|
|
4171
|
-
}
|
|
4172
|
-
handleHeartbeat() {
|
|
4173
|
-
debug("Heartbeat received");
|
|
4174
|
-
this.lastHeartbeat = Date.now();
|
|
4175
|
-
}
|
|
4176
|
-
notifyEventListeners(event) {
|
|
4177
|
-
this.eventListeners.forEach((listener) => {
|
|
4178
|
-
try {
|
|
4179
|
-
listener(event);
|
|
4180
|
-
} catch (error) {
|
|
4181
|
-
debug("Error in event listener: %O", error);
|
|
4182
|
-
}
|
|
4183
|
-
});
|
|
4184
|
-
}
|
|
4185
|
-
notifyConnectionListeners(connected, reason) {
|
|
4186
|
-
this.connectionListeners.forEach((listener) => {
|
|
4187
|
-
try {
|
|
4188
|
-
listener(connected, reason);
|
|
4189
|
-
} catch (error) {
|
|
4190
|
-
debug("Error in connection listener: %O", error);
|
|
4191
|
-
}
|
|
4192
|
-
});
|
|
4193
|
-
}
|
|
4194
|
-
notifyErrorListeners(error) {
|
|
4195
|
-
this.errorListeners.forEach((listener) => {
|
|
4196
|
-
try {
|
|
4197
|
-
listener(error);
|
|
4198
|
-
} catch (error2) {
|
|
4199
|
-
debug("Error in error listener: %O", error2);
|
|
4200
|
-
}
|
|
4201
|
-
});
|
|
4202
|
-
}
|
|
4203
|
-
startHeartbeatCheck() {
|
|
4204
|
-
this.missedHeartbeatCheckTimer = setInterval(() => {
|
|
4205
|
-
if (Date.now() - this.lastHeartbeat > this.missedHeartbeatsLimit) {
|
|
4206
|
-
debug("No heartbeat received in 30 seconds! Closing connection.");
|
|
4207
|
-
this.socket?.close();
|
|
4208
|
-
}
|
|
4209
|
-
}, this.heartbeatInterval);
|
|
4210
|
-
}
|
|
4211
|
-
stopHeartbeatCheck() {
|
|
4212
|
-
if (this.missedHeartbeatCheckTimer) {
|
|
4213
|
-
clearInterval(this.missedHeartbeatCheckTimer);
|
|
4214
4339
|
}
|
|
4340
|
+
return schemaData;
|
|
4215
4341
|
}
|
|
4216
4342
|
/**
|
|
4217
|
-
*
|
|
4218
|
-
* @param listener Function to handle incoming events
|
|
4219
|
-
* @returns Function to unsubscribe
|
|
4343
|
+
* List all schemas
|
|
4220
4344
|
*/
|
|
4221
|
-
|
|
4222
|
-
this.
|
|
4223
|
-
return
|
|
4224
|
-
this.eventListeners.delete(listener);
|
|
4225
|
-
};
|
|
4345
|
+
async listSchemas() {
|
|
4346
|
+
const response = await this.schemasApi.v4SchemasGet();
|
|
4347
|
+
return response.data.data;
|
|
4226
4348
|
}
|
|
4227
4349
|
/**
|
|
4228
|
-
*
|
|
4229
|
-
* @param listener Function to handle connection state changes
|
|
4230
|
-
* @returns Function to unsubscribe
|
|
4350
|
+
* Create a new schema
|
|
4231
4351
|
*/
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
};
|
|
4352
|
+
async createSchema(body) {
|
|
4353
|
+
debug("Creating schema with name: %s", body.name);
|
|
4354
|
+
const response = await this.schemasApi.v4SchemasPost({
|
|
4355
|
+
createSchemaBody: body
|
|
4356
|
+
});
|
|
4357
|
+
const schemaId = response.data.schemaId;
|
|
4358
|
+
if (!schemaId) {
|
|
4359
|
+
throw new KadoaSdkException(ERROR_MESSAGES.SCHEMA_CREATE_FAILED, {
|
|
4360
|
+
code: KadoaErrorCode.INTERNAL_ERROR
|
|
4361
|
+
});
|
|
4362
|
+
}
|
|
4363
|
+
return this.getSchema(schemaId);
|
|
4237
4364
|
}
|
|
4238
4365
|
/**
|
|
4239
|
-
*
|
|
4240
|
-
* @param listener Function to handle errors
|
|
4241
|
-
* @returns Function to unsubscribe
|
|
4366
|
+
* Update an existing schema
|
|
4242
4367
|
*/
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
if (this.socket) {
|
|
4251
|
-
this.stopHeartbeatCheck();
|
|
4252
|
-
this.socket.close();
|
|
4253
|
-
this.socket = void 0;
|
|
4254
|
-
}
|
|
4255
|
-
this.eventListeners.clear();
|
|
4256
|
-
this.connectionListeners.clear();
|
|
4257
|
-
this.errorListeners.clear();
|
|
4368
|
+
async updateSchema(schemaId, body) {
|
|
4369
|
+
debug("Updating schema with ID: %s", schemaId);
|
|
4370
|
+
await this.schemasApi.v4SchemasSchemaIdPut({
|
|
4371
|
+
schemaId,
|
|
4372
|
+
updateSchemaBody: body
|
|
4373
|
+
});
|
|
4374
|
+
return this.getSchema(schemaId);
|
|
4258
4375
|
}
|
|
4259
|
-
|
|
4260
|
-
|
|
4376
|
+
/**
|
|
4377
|
+
* Delete a schema
|
|
4378
|
+
*/
|
|
4379
|
+
async deleteSchema(schemaId) {
|
|
4380
|
+
debug("Deleting schema with ID: %s", schemaId);
|
|
4381
|
+
await this.schemasApi.v4SchemasSchemaIdDelete({
|
|
4382
|
+
schemaId
|
|
4383
|
+
});
|
|
4261
4384
|
}
|
|
4262
4385
|
};
|
|
4263
4386
|
|
|
4264
|
-
// src/
|
|
4265
|
-
var
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
this.
|
|
4269
|
-
this.
|
|
4270
|
-
this.settingsService = settingsService;
|
|
4271
|
-
this.workflowsCoreService = workflowsCoreService;
|
|
4387
|
+
// src/domains/extraction/services/entity-resolver.service.ts
|
|
4388
|
+
var ENTITY_API_ENDPOINT = "/v4/entity";
|
|
4389
|
+
var EntityResolverService = class {
|
|
4390
|
+
constructor(client) {
|
|
4391
|
+
this.client = client;
|
|
4392
|
+
this.schemasService = new SchemasService(client);
|
|
4272
4393
|
}
|
|
4273
4394
|
/**
|
|
4274
|
-
*
|
|
4275
|
-
*
|
|
4276
|
-
* @param options Extraction configuration options including optional notification settings
|
|
4277
|
-
* @returns ExtractionResult containing workflow ID, workflow details, and first page of extracted data
|
|
4278
|
-
*
|
|
4279
|
-
* @example Simple extraction with AI detection
|
|
4280
|
-
* ```typescript
|
|
4281
|
-
* const result = await client.extraction.run({
|
|
4282
|
-
* urls: ['https://example.com'],
|
|
4283
|
-
* name: 'My Extraction'
|
|
4284
|
-
* });
|
|
4285
|
-
* ```
|
|
4286
|
-
*
|
|
4287
|
-
* @example With notifications
|
|
4288
|
-
* ```typescript
|
|
4289
|
-
* const result = await client.extraction.run({
|
|
4290
|
-
* urls: ['https://example.com'],
|
|
4291
|
-
* name: 'My Extraction',
|
|
4292
|
-
* notifications: {
|
|
4293
|
-
* events: ['workflow_completed', 'workflow_failed'],
|
|
4294
|
-
* channels: {
|
|
4295
|
-
* email: true,
|
|
4296
|
-
* slack: { channelId: 'slack-channel-id' }
|
|
4297
|
-
* }
|
|
4298
|
-
* }
|
|
4299
|
-
* });
|
|
4300
|
-
* ```
|
|
4395
|
+
* Resolves entity and fields from the provided entity configuration
|
|
4301
4396
|
*
|
|
4302
|
-
* @
|
|
4397
|
+
* @param entityConfig The entity configuration to resolve
|
|
4398
|
+
* @param options Additional options for AI detection
|
|
4399
|
+
* @returns Resolved entity with fields
|
|
4303
4400
|
*/
|
|
4304
|
-
async
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4401
|
+
async resolveEntity(entityConfig, options) {
|
|
4402
|
+
if (entityConfig === "ai-detection") {
|
|
4403
|
+
if (!options?.link) {
|
|
4404
|
+
throw new KadoaSdkException(ERROR_MESSAGES.LINK_REQUIRED, {
|
|
4405
|
+
code: "VALIDATION_ERROR",
|
|
4406
|
+
details: { entityConfig, options }
|
|
4407
|
+
});
|
|
4408
|
+
}
|
|
4409
|
+
const entityPrediction = await this.fetchEntityFields({
|
|
4410
|
+
link: options.link,
|
|
4411
|
+
location: options.location,
|
|
4412
|
+
navigationMode: options.navigationMode
|
|
4413
|
+
});
|
|
4414
|
+
return {
|
|
4415
|
+
entity: entityPrediction.entity,
|
|
4416
|
+
fields: entityPrediction.fields
|
|
4417
|
+
};
|
|
4418
|
+
} else if (entityConfig) {
|
|
4419
|
+
if ("schemaId" in entityConfig) {
|
|
4420
|
+
const schema = await this.schemasService.getSchema(
|
|
4421
|
+
entityConfig.schemaId
|
|
4422
|
+
);
|
|
4423
|
+
return {
|
|
4424
|
+
entity: schema.entity ?? "",
|
|
4425
|
+
fields: schema.schema
|
|
4426
|
+
};
|
|
4427
|
+
} else if ("name" in entityConfig && "fields" in entityConfig) {
|
|
4428
|
+
return {
|
|
4429
|
+
entity: entityConfig.name,
|
|
4430
|
+
fields: entityConfig.fields
|
|
4431
|
+
};
|
|
4432
|
+
}
|
|
4433
|
+
}
|
|
4434
|
+
throw new KadoaSdkException(ERROR_MESSAGES.ENTITY_INVARIANT_VIOLATION, {
|
|
4435
|
+
details: {
|
|
4436
|
+
entity: entityConfig
|
|
4437
|
+
}
|
|
4308
4438
|
});
|
|
4309
4439
|
}
|
|
4310
4440
|
/**
|
|
4311
|
-
*
|
|
4312
|
-
*
|
|
4313
|
-
*
|
|
4314
|
-
* @returns SubmitExtractionResult containing workflow ID
|
|
4315
|
-
*
|
|
4316
|
-
* @example
|
|
4317
|
-
* ```typescript
|
|
4318
|
-
* const result = await client.extraction.submit({
|
|
4319
|
-
* urls: ['https://example.com'],
|
|
4320
|
-
* name: 'My Extraction',
|
|
4321
|
-
* notifications: {
|
|
4322
|
-
* events: 'all',
|
|
4323
|
-
* channels: {
|
|
4324
|
-
* email: true
|
|
4325
|
-
* }
|
|
4326
|
-
* }
|
|
4327
|
-
* });
|
|
4328
|
-
* ```
|
|
4441
|
+
* Fetches entity fields dynamically from the /v4/entity endpoint.
|
|
4442
|
+
* This is a workaround implementation using native fetch since the endpoint
|
|
4443
|
+
* is not yet included in the OpenAPI specification.
|
|
4329
4444
|
*
|
|
4330
|
-
* @
|
|
4445
|
+
* @param options Request options including the link to analyze
|
|
4446
|
+
* @returns EntityPrediction containing the detected entity type and fields
|
|
4331
4447
|
*/
|
|
4332
|
-
async
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4448
|
+
async fetchEntityFields(options) {
|
|
4449
|
+
this.validateEntityOptions(options);
|
|
4450
|
+
const url = `${this.client.baseUrl}${ENTITY_API_ENDPOINT}`;
|
|
4451
|
+
const requestBody = options;
|
|
4452
|
+
const response = await this.client.axiosInstance.post(url, requestBody, {
|
|
4453
|
+
headers: {
|
|
4454
|
+
"Content-Type": "application/json",
|
|
4455
|
+
Accept: "application/json",
|
|
4456
|
+
"x-api-key": this.client.apiKey
|
|
4457
|
+
}
|
|
4336
4458
|
});
|
|
4459
|
+
const data = response.data;
|
|
4460
|
+
if (!data.success || !data.entityPrediction || data.entityPrediction.length === 0) {
|
|
4461
|
+
throw new KadoaSdkException(ERROR_MESSAGES.NO_PREDICTIONS, {
|
|
4462
|
+
code: "NOT_FOUND",
|
|
4463
|
+
details: {
|
|
4464
|
+
success: data.success,
|
|
4465
|
+
hasPredictions: !!data.entityPrediction,
|
|
4466
|
+
predictionCount: data.entityPrediction?.length || 0,
|
|
4467
|
+
link: options.link
|
|
4468
|
+
}
|
|
4469
|
+
});
|
|
4470
|
+
}
|
|
4471
|
+
return data.entityPrediction[0];
|
|
4337
4472
|
}
|
|
4338
4473
|
/**
|
|
4339
|
-
*
|
|
4474
|
+
* Validates entity request options
|
|
4340
4475
|
*/
|
|
4341
|
-
|
|
4342
|
-
|
|
4476
|
+
validateEntityOptions(options) {
|
|
4477
|
+
if (!options.link) {
|
|
4478
|
+
throw new KadoaSdkException(ERROR_MESSAGES.LINK_REQUIRED, {
|
|
4479
|
+
code: "VALIDATION_ERROR",
|
|
4480
|
+
details: { options }
|
|
4481
|
+
});
|
|
4482
|
+
}
|
|
4483
|
+
}
|
|
4484
|
+
};
|
|
4485
|
+
var debug2 = logger.extraction;
|
|
4486
|
+
var SUCCESSFUL_RUN_STATES = /* @__PURE__ */ new Set(["FINISHED", "SUCCESS"]);
|
|
4487
|
+
var DEFAULT_OPTIONS = {
|
|
4488
|
+
mode: "run",
|
|
4489
|
+
pollingInterval: 5e3,
|
|
4490
|
+
maxWaitTime: 3e5,
|
|
4491
|
+
navigationMode: "single-page",
|
|
4492
|
+
location: { type: "auto" },
|
|
4493
|
+
name: "Untitled Workflow",
|
|
4494
|
+
bypassPreview: true,
|
|
4495
|
+
autoStart: true
|
|
4496
|
+
};
|
|
4497
|
+
var ExtractionService = class {
|
|
4498
|
+
constructor(workflowsCoreService, dataFetcherService, entityResolverService, notificationSetupService, notificationChannelsService, notificationSettingsService) {
|
|
4499
|
+
this.workflowsCoreService = workflowsCoreService;
|
|
4500
|
+
this.dataFetcherService = dataFetcherService;
|
|
4501
|
+
this.entityResolverService = entityResolverService;
|
|
4502
|
+
this.notificationSetupService = notificationSetupService;
|
|
4503
|
+
this.notificationChannelsService = notificationChannelsService;
|
|
4504
|
+
this.notificationSettingsService = notificationSettingsService;
|
|
4505
|
+
}
|
|
4506
|
+
/**
|
|
4507
|
+
* Run an extraction workflow and wait for completion.
|
|
4508
|
+
*/
|
|
4509
|
+
async run(options) {
|
|
4510
|
+
return await this.executeExtraction({ ...options, mode: "run" });
|
|
4511
|
+
}
|
|
4512
|
+
/**
|
|
4513
|
+
* Submit an extraction workflow for asynchronous processing.
|
|
4514
|
+
*/
|
|
4515
|
+
async submit(options) {
|
|
4516
|
+
return await this.executeExtraction({ ...options, mode: "submit" });
|
|
4517
|
+
}
|
|
4518
|
+
/**
|
|
4519
|
+
* Trigger a workflow run without waiting for completion.
|
|
4520
|
+
*/
|
|
4521
|
+
async runJob(workflowId, input) {
|
|
4522
|
+
return await this.workflowsCoreService.runWorkflow(workflowId, input);
|
|
4343
4523
|
}
|
|
4344
4524
|
/**
|
|
4345
|
-
*
|
|
4525
|
+
* Trigger a workflow run and wait for the job to complete.
|
|
4346
4526
|
*/
|
|
4347
4527
|
async runJobAndWait(workflowId, input) {
|
|
4348
4528
|
const result = await this.workflowsCoreService.runWorkflow(
|
|
4349
4529
|
workflowId,
|
|
4350
4530
|
input
|
|
4351
4531
|
);
|
|
4352
|
-
return this.workflowsCoreService.waitForJobCompletion(
|
|
4532
|
+
return await this.workflowsCoreService.waitForJobCompletion(
|
|
4353
4533
|
workflowId,
|
|
4354
|
-
result.jobId
|
|
4534
|
+
result.jobId || ""
|
|
4355
4535
|
);
|
|
4356
4536
|
}
|
|
4357
4537
|
/**
|
|
4358
|
-
* Fetch
|
|
4359
|
-
*
|
|
4360
|
-
* @param options Options for fetching data including workflowId and pagination parameters
|
|
4361
|
-
* @returns Paginated workflow data with metadata
|
|
4362
|
-
*
|
|
4363
|
-
* @example
|
|
4364
|
-
* ```typescript
|
|
4365
|
-
* // Fetch first page
|
|
4366
|
-
* const firstPage = await client.extraction.fetchData({
|
|
4367
|
-
* workflowId: 'workflow-id',
|
|
4368
|
-
* page: 1,
|
|
4369
|
-
* limit: 100
|
|
4370
|
-
* });
|
|
4371
|
-
*
|
|
4372
|
-
* // Iterate through all pages
|
|
4373
|
-
* for await (const page of client.extraction.fetchDataPages({ workflowId: 'workflow-id' })) {
|
|
4374
|
-
* console.log(`Processing ${page.data.length} records`);
|
|
4375
|
-
* }
|
|
4376
|
-
* ```
|
|
4538
|
+
* Fetch a single page of extraction data.
|
|
4377
4539
|
*/
|
|
4378
4540
|
async fetchData(options) {
|
|
4379
|
-
return this.dataFetcherService.fetchData(options);
|
|
4541
|
+
return await this.dataFetcherService.fetchData(options);
|
|
4380
4542
|
}
|
|
4381
4543
|
/**
|
|
4382
|
-
* Fetch all data
|
|
4383
|
-
*
|
|
4384
|
-
* @param options Options for fetching data
|
|
4385
|
-
* @returns All workflow data combined from all pages
|
|
4386
|
-
*
|
|
4387
|
-
* @example
|
|
4388
|
-
* ```typescript
|
|
4389
|
-
* const allData = await client.extraction.fetchAllData({
|
|
4390
|
-
* workflowId: 'workflow-id'
|
|
4391
|
-
* });
|
|
4392
|
-
* ```
|
|
4544
|
+
* Fetch all extraction data across all pages.
|
|
4393
4545
|
*/
|
|
4394
4546
|
async fetchAllData(options) {
|
|
4395
|
-
return this.dataFetcherService.fetchAllData(options);
|
|
4547
|
+
return await this.dataFetcherService.fetchAllData(options);
|
|
4396
4548
|
}
|
|
4397
4549
|
/**
|
|
4398
|
-
*
|
|
4399
|
-
*
|
|
4400
|
-
* @param options Options for fetching data
|
|
4401
|
-
* @returns Async iterator that yields pages of data
|
|
4402
|
-
*
|
|
4403
|
-
* @example
|
|
4404
|
-
* ```typescript
|
|
4405
|
-
* for await (const page of client.extraction.fetchDataPages({ workflowId: 'workflow-id' })) {
|
|
4406
|
-
* console.log(`Page ${page.pagination.page}: ${page.data.length} records`);
|
|
4407
|
-
* }
|
|
4408
|
-
* ```
|
|
4550
|
+
* Iterate through extraction data pages.
|
|
4409
4551
|
*/
|
|
4410
4552
|
fetchDataPages(options) {
|
|
4411
4553
|
return this.dataFetcherService.fetchDataPages(options);
|
|
4412
4554
|
}
|
|
4413
4555
|
/**
|
|
4414
|
-
*
|
|
4415
|
-
*
|
|
4416
|
-
* @param workflowId The workflow ID
|
|
4417
|
-
* @returns Array of notification channels
|
|
4418
|
-
*
|
|
4419
|
-
* @example
|
|
4420
|
-
* ```typescript
|
|
4421
|
-
* const channels = await client.extraction.getNotificationChannels('workflow-id');
|
|
4422
|
-
* ```
|
|
4556
|
+
* List notification channels for a workflow.
|
|
4423
4557
|
*/
|
|
4424
4558
|
async getNotificationChannels(workflowId) {
|
|
4425
|
-
return this.
|
|
4559
|
+
return await this.notificationChannelsService.listChannels({ workflowId });
|
|
4426
4560
|
}
|
|
4427
4561
|
/**
|
|
4428
|
-
*
|
|
4429
|
-
*
|
|
4430
|
-
* @param workflowId The workflow ID
|
|
4431
|
-
* @returns Array of notification settings
|
|
4432
|
-
*
|
|
4433
|
-
* @example
|
|
4434
|
-
* ```typescript
|
|
4435
|
-
* const settings = await client.extraction.getNotificationSettings('workflow-id');
|
|
4436
|
-
* ```
|
|
4562
|
+
* List notification settings for a workflow.
|
|
4437
4563
|
*/
|
|
4438
4564
|
async getNotificationSettings(workflowId) {
|
|
4439
|
-
return this.
|
|
4440
|
-
}
|
|
4441
|
-
};
|
|
4442
|
-
|
|
4443
|
-
// src/modules/notifications.module.ts
|
|
4444
|
-
var NotificationsModule = class {
|
|
4445
|
-
constructor(channelsService, settingsService, channelSetupService) {
|
|
4446
|
-
this.channelsService = channelsService;
|
|
4447
|
-
this.settingsService = settingsService;
|
|
4448
|
-
this.channelSetupService = channelSetupService;
|
|
4449
|
-
}
|
|
4450
|
-
async setupForWorkflow(requestData) {
|
|
4451
|
-
const existingSettings = await this.settingsService.listSettings({
|
|
4452
|
-
workflowId: requestData.workflowId
|
|
4453
|
-
});
|
|
4454
|
-
if (existingSettings.length > 0) {
|
|
4455
|
-
throw new KadoaSdkException("Settings already exist", {
|
|
4456
|
-
code: KadoaErrorCode.BAD_REQUEST,
|
|
4457
|
-
details: {
|
|
4458
|
-
workflowId: requestData.workflowId
|
|
4459
|
-
}
|
|
4460
|
-
});
|
|
4461
|
-
}
|
|
4462
|
-
return this.channelSetupService.setup({
|
|
4463
|
-
workflowId: requestData.workflowId,
|
|
4464
|
-
events: requestData.events,
|
|
4465
|
-
channels: requestData.channels
|
|
4466
|
-
});
|
|
4467
|
-
}
|
|
4468
|
-
async setupForWorkspace(requestData) {
|
|
4469
|
-
const existingSettings = await this.settingsService.listSettings({});
|
|
4470
|
-
if (existingSettings.length > 0) {
|
|
4471
|
-
throw new KadoaSdkException("Workspace settings already exist", {
|
|
4472
|
-
code: KadoaErrorCode.BAD_REQUEST
|
|
4473
|
-
});
|
|
4474
|
-
}
|
|
4475
|
-
return this.channelSetupService.setup({
|
|
4476
|
-
events: requestData.events,
|
|
4477
|
-
channels: requestData.channels
|
|
4478
|
-
});
|
|
4479
|
-
}
|
|
4480
|
-
/**
|
|
4481
|
-
* Get the channels service
|
|
4482
|
-
*/
|
|
4483
|
-
get channels() {
|
|
4484
|
-
return this.channelsService;
|
|
4485
|
-
}
|
|
4486
|
-
/**
|
|
4487
|
-
* Get the settings service
|
|
4488
|
-
*/
|
|
4489
|
-
get settings() {
|
|
4490
|
-
return this.settingsService;
|
|
4491
|
-
}
|
|
4492
|
-
};
|
|
4493
|
-
|
|
4494
|
-
// src/modules/schemas.module.ts
|
|
4495
|
-
var SchemasModule = class {
|
|
4496
|
-
constructor(service) {
|
|
4497
|
-
this.service = service;
|
|
4498
|
-
}
|
|
4499
|
-
};
|
|
4500
|
-
|
|
4501
|
-
// src/modules/user.module.ts
|
|
4502
|
-
var UserModule = class {
|
|
4503
|
-
constructor(userService) {
|
|
4504
|
-
this.userService = userService;
|
|
4505
|
-
}
|
|
4506
|
-
/**
|
|
4507
|
-
* Get the underlying UserService instance
|
|
4508
|
-
* @returns UserService instance
|
|
4509
|
-
*/
|
|
4510
|
-
get service() {
|
|
4511
|
-
return this.userService;
|
|
4512
|
-
}
|
|
4513
|
-
/**
|
|
4514
|
-
* Get current user details
|
|
4515
|
-
* @returns KadoaUser details
|
|
4516
|
-
*/
|
|
4517
|
-
async getCurrentUser() {
|
|
4518
|
-
return this.userService.getCurrentUser();
|
|
4519
|
-
}
|
|
4520
|
-
};
|
|
4521
|
-
|
|
4522
|
-
// src/modules/validation.module.ts
|
|
4523
|
-
var ValidationModule = class {
|
|
4524
|
-
constructor(coreService, rulesService) {
|
|
4525
|
-
this.coreService = coreService;
|
|
4526
|
-
this.rulesService = rulesService;
|
|
4527
|
-
}
|
|
4528
|
-
listRules(options) {
|
|
4529
|
-
return this.rulesService.listRules(options);
|
|
4530
|
-
}
|
|
4531
|
-
getRuleByName(name) {
|
|
4532
|
-
return this.rulesService.getRuleByName(name);
|
|
4533
|
-
}
|
|
4534
|
-
createRule(data) {
|
|
4535
|
-
return this.rulesService.createRule(data);
|
|
4536
|
-
}
|
|
4537
|
-
generateRule(data) {
|
|
4538
|
-
return this.rulesService.generateRule(data);
|
|
4539
|
-
}
|
|
4540
|
-
generateRules(data) {
|
|
4541
|
-
return this.rulesService.generateRules(data);
|
|
4542
|
-
}
|
|
4543
|
-
bulkApproveRules(data) {
|
|
4544
|
-
return this.rulesService.bulkApproveRules(data);
|
|
4545
|
-
}
|
|
4546
|
-
bulkDeleteRules(data) {
|
|
4547
|
-
return this.rulesService.bulkDeleteRules(data);
|
|
4548
|
-
}
|
|
4549
|
-
deleteAllRules(data) {
|
|
4550
|
-
return this.rulesService.deleteAllRules(data);
|
|
4551
|
-
}
|
|
4552
|
-
listWorkflowValidations(workflowId, jobId) {
|
|
4553
|
-
return this.coreService.listWorkflowValidations({ workflowId, jobId });
|
|
4554
|
-
}
|
|
4555
|
-
scheduleValidation(workflowId, jobId) {
|
|
4556
|
-
return this.coreService.scheduleValidation(workflowId, jobId);
|
|
4557
|
-
}
|
|
4558
|
-
waitUntilCompleted(validationId, options) {
|
|
4559
|
-
return this.coreService.waitUntilCompleted(validationId, options);
|
|
4560
|
-
}
|
|
4561
|
-
getValidationDetails(validationId) {
|
|
4562
|
-
return this.coreService.getValidationDetails(validationId);
|
|
4563
|
-
}
|
|
4564
|
-
getLatestValidation(workflowId, jobId) {
|
|
4565
|
-
return this.coreService.getLatestValidation(workflowId, jobId);
|
|
4566
|
-
}
|
|
4567
|
-
getValidationAnomalies(validationId) {
|
|
4568
|
-
return this.coreService.getValidationAnomalies(validationId);
|
|
4569
|
-
}
|
|
4570
|
-
getValidationAnomaliesByRule(validationId, ruleName) {
|
|
4571
|
-
return this.coreService.getValidationAnomaliesByRule(
|
|
4572
|
-
validationId,
|
|
4573
|
-
ruleName
|
|
4574
|
-
);
|
|
4575
|
-
}
|
|
4576
|
-
toggleValidationEnabled(workflowId) {
|
|
4577
|
-
return this.coreService.toggleValidationEnabled(workflowId);
|
|
4578
|
-
}
|
|
4579
|
-
};
|
|
4580
|
-
|
|
4581
|
-
// src/modules/workflows.module.ts
|
|
4582
|
-
var WorkflowsModule = class {
|
|
4583
|
-
constructor(core) {
|
|
4584
|
-
this.core = core;
|
|
4585
|
-
}
|
|
4586
|
-
async get(workflowId) {
|
|
4587
|
-
return this.core.get(workflowId);
|
|
4588
|
-
}
|
|
4589
|
-
async list(filters) {
|
|
4590
|
-
return this.core.list(filters);
|
|
4591
|
-
}
|
|
4592
|
-
async getByName(name) {
|
|
4593
|
-
return this.core.getByName(name);
|
|
4594
|
-
}
|
|
4595
|
-
async create(input) {
|
|
4596
|
-
return this.core.create(input);
|
|
4597
|
-
}
|
|
4598
|
-
async cancel(workflowId) {
|
|
4599
|
-
return this.core.cancel(workflowId);
|
|
4600
|
-
}
|
|
4601
|
-
async approve(workflowId) {
|
|
4602
|
-
return this.core.resume(workflowId);
|
|
4603
|
-
}
|
|
4604
|
-
async resume(workflowId) {
|
|
4605
|
-
return this.core.resume(workflowId);
|
|
4606
|
-
}
|
|
4607
|
-
async wait(workflowId, options) {
|
|
4608
|
-
return this.core.wait(workflowId, options);
|
|
4609
|
-
}
|
|
4610
|
-
/**
|
|
4611
|
-
* Get job status directly without polling workflow details
|
|
4612
|
-
*/
|
|
4613
|
-
async getJobStatus(workflowId, jobId) {
|
|
4614
|
-
return this.core.getJobStatus(workflowId, jobId);
|
|
4615
|
-
}
|
|
4616
|
-
/**
|
|
4617
|
-
* Wait for a job to complete using the job status endpoint
|
|
4618
|
-
*/
|
|
4619
|
-
async waitForJobCompletion(workflowId, jobId, options) {
|
|
4620
|
-
return this.core.waitForJobCompletion(workflowId, jobId, options);
|
|
4621
|
-
}
|
|
4622
|
-
};
|
|
4623
|
-
|
|
4624
|
-
// src/internal/domains/user/user.service.ts
|
|
4625
|
-
var UserService = class {
|
|
4626
|
-
constructor(client) {
|
|
4627
|
-
this.client = client;
|
|
4628
|
-
}
|
|
4629
|
-
/**
|
|
4630
|
-
* Get current user details
|
|
4631
|
-
* @returns User details
|
|
4632
|
-
*/
|
|
4633
|
-
async getCurrentUser() {
|
|
4634
|
-
const response = await this.client.axiosInstance.get("/v5/user", {
|
|
4635
|
-
baseURL: this.client.baseUrl,
|
|
4636
|
-
headers: {
|
|
4637
|
-
"x-api-key": this.client.apiKey,
|
|
4638
|
-
"Content-Type": "application/json"
|
|
4639
|
-
}
|
|
4640
|
-
});
|
|
4641
|
-
const userData = response.data;
|
|
4642
|
-
if (!userData || !userData.userId) {
|
|
4643
|
-
throw new KadoaSdkException("Invalid user data received");
|
|
4644
|
-
}
|
|
4645
|
-
return {
|
|
4646
|
-
userId: userData.userId,
|
|
4647
|
-
email: userData.email,
|
|
4648
|
-
featureFlags: userData.featureFlags || []
|
|
4649
|
-
};
|
|
4650
|
-
}
|
|
4651
|
-
};
|
|
4652
|
-
var debug2 = logger.extraction;
|
|
4653
|
-
var SUCCESSFUL_RUN_STATES = /* @__PURE__ */ new Set(["FINISHED", "SUCCESS"]);
|
|
4654
|
-
var DEFAULT_OPTIONS = {
|
|
4655
|
-
mode: "run",
|
|
4656
|
-
pollingInterval: 5e3,
|
|
4657
|
-
maxWaitTime: 3e5,
|
|
4658
|
-
navigationMode: "single-page",
|
|
4659
|
-
location: { type: "auto" },
|
|
4660
|
-
name: "Untitled Workflow",
|
|
4661
|
-
bypassPreview: true,
|
|
4662
|
-
autoStart: true
|
|
4663
|
-
};
|
|
4664
|
-
var ExtractionService = class {
|
|
4665
|
-
constructor(workflowsCoreService, dataFetcherService, entityResolverService, notificationSetupService) {
|
|
4666
|
-
this.workflowsCoreService = workflowsCoreService;
|
|
4667
|
-
this.dataFetcherService = dataFetcherService;
|
|
4668
|
-
this.entityResolverService = entityResolverService;
|
|
4669
|
-
this.notificationSetupService = notificationSetupService;
|
|
4565
|
+
return await this.notificationSettingsService.listSettings({ workflowId });
|
|
4670
4566
|
}
|
|
4671
|
-
/**
|
|
4672
|
-
* execute extraction workflow
|
|
4673
|
-
*/
|
|
4674
4567
|
async executeExtraction(options) {
|
|
4675
4568
|
this.validateOptions(options);
|
|
4676
4569
|
const config = esToolkit.merge(
|
|
@@ -4793,54 +4686,228 @@ var ExtractionService = class {
|
|
|
4793
4686
|
return runState ? SUCCESSFUL_RUN_STATES.has(runState.toUpperCase()) : false;
|
|
4794
4687
|
}
|
|
4795
4688
|
};
|
|
4796
|
-
var
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
recipients: zod.z.array(zod.z.email()).min(1, "Recipients are required for email channel"),
|
|
4804
|
-
from: zod.z.email().refine(
|
|
4805
|
-
(email) => email.endsWith("@kadoa.com"),
|
|
4806
|
-
"From email address must end with @kadoa.com"
|
|
4807
|
-
).optional()
|
|
4808
|
-
});
|
|
4809
|
-
var _NotificationChannelsService = class _NotificationChannelsService {
|
|
4810
|
-
constructor(notificationsApi, userService) {
|
|
4811
|
-
this.api = notificationsApi;
|
|
4812
|
-
this.userService = userService;
|
|
4689
|
+
var debug3 = logger.extraction;
|
|
4690
|
+
var ExtractionBuilderService = class {
|
|
4691
|
+
constructor(workflowsCoreService, entityResolverService, dataFetcherService, notificationSetupService) {
|
|
4692
|
+
this.workflowsCoreService = workflowsCoreService;
|
|
4693
|
+
this.entityResolverService = entityResolverService;
|
|
4694
|
+
this.dataFetcherService = dataFetcherService;
|
|
4695
|
+
this.notificationSetupService = notificationSetupService;
|
|
4813
4696
|
}
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
if (!data) {
|
|
4818
|
-
throw KadoaHttpException.wrap(response, {
|
|
4819
|
-
message: "Failed to list channels"
|
|
4820
|
-
});
|
|
4821
|
-
}
|
|
4822
|
-
return data;
|
|
4697
|
+
get options() {
|
|
4698
|
+
assert__default.default(this._options, "Options are not set");
|
|
4699
|
+
return this._options;
|
|
4823
4700
|
}
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4701
|
+
get notificationOptions() {
|
|
4702
|
+
return this._notificationOptions;
|
|
4703
|
+
}
|
|
4704
|
+
get monitoringOptions() {
|
|
4705
|
+
return this._monitoringOptions;
|
|
4706
|
+
}
|
|
4707
|
+
get workflowId() {
|
|
4708
|
+
assert__default.default(this._workflowId, "Workflow ID is not set");
|
|
4709
|
+
return this._workflowId;
|
|
4710
|
+
}
|
|
4711
|
+
get jobId() {
|
|
4712
|
+
assert__default.default(this._jobId, "Job ID is not set");
|
|
4713
|
+
return this._jobId;
|
|
4714
|
+
}
|
|
4715
|
+
extract({
|
|
4716
|
+
urls,
|
|
4717
|
+
name,
|
|
4718
|
+
description,
|
|
4719
|
+
navigationMode,
|
|
4720
|
+
extraction
|
|
4721
|
+
}) {
|
|
4722
|
+
let entity = "ai-detection";
|
|
4723
|
+
if (extraction) {
|
|
4724
|
+
const result = extraction(new SchemaBuilder());
|
|
4725
|
+
if ("schemaId" in result) {
|
|
4726
|
+
entity = { schemaId: result.schemaId };
|
|
4727
|
+
} else {
|
|
4728
|
+
const builtSchema = result.build();
|
|
4729
|
+
entity = { name: builtSchema.entityName, fields: builtSchema.fields };
|
|
4730
|
+
}
|
|
4731
|
+
}
|
|
4732
|
+
this._options = {
|
|
4733
|
+
urls,
|
|
4734
|
+
name,
|
|
4735
|
+
description,
|
|
4736
|
+
navigationMode: navigationMode || "single-page",
|
|
4737
|
+
entity,
|
|
4738
|
+
bypassPreview: false
|
|
4739
|
+
};
|
|
4740
|
+
return this;
|
|
4741
|
+
}
|
|
4742
|
+
withNotifications(options) {
|
|
4743
|
+
this._notificationOptions = options;
|
|
4744
|
+
return this;
|
|
4745
|
+
}
|
|
4746
|
+
withMonitoring(options) {
|
|
4747
|
+
this._monitoringOptions = options;
|
|
4748
|
+
return this;
|
|
4749
|
+
}
|
|
4750
|
+
bypassPreview() {
|
|
4751
|
+
assert__default.default(this._options, "Options are not set");
|
|
4752
|
+
this._options.bypassPreview = true;
|
|
4753
|
+
return this;
|
|
4754
|
+
}
|
|
4755
|
+
setInterval(options) {
|
|
4756
|
+
assert__default.default(this._options, "Options are not set");
|
|
4757
|
+
if ("interval" in options) {
|
|
4758
|
+
this._options.interval = options.interval;
|
|
4759
|
+
} else {
|
|
4760
|
+
this._options.interval = "CUSTOM";
|
|
4761
|
+
this._options.schedules = options.schedules;
|
|
4762
|
+
}
|
|
4763
|
+
return this;
|
|
4764
|
+
}
|
|
4765
|
+
setLocation(options) {
|
|
4766
|
+
assert__default.default(this._options, "Options are not set");
|
|
4767
|
+
this._options.location = options;
|
|
4768
|
+
return this;
|
|
4769
|
+
}
|
|
4770
|
+
async create() {
|
|
4771
|
+
assert__default.default(this._options, "Options are not set");
|
|
4772
|
+
const { urls, name, description, navigationMode, entity } = this.options;
|
|
4773
|
+
const resolvedEntity = typeof entity === "object" && "schemaId" in entity ? void 0 : await this.entityResolverService.resolveEntity(entity, {
|
|
4774
|
+
link: urls[0],
|
|
4775
|
+
location: this._options.location,
|
|
4776
|
+
navigationMode
|
|
4777
|
+
});
|
|
4778
|
+
if (!resolvedEntity) {
|
|
4779
|
+
throw new KadoaSdkException(ERROR_MESSAGES.ENTITY_FETCH_FAILED, {
|
|
4780
|
+
code: "VALIDATION_ERROR",
|
|
4781
|
+
details: { entity }
|
|
4782
|
+
});
|
|
4783
|
+
}
|
|
4784
|
+
const workflow = await this.workflowsCoreService.create({
|
|
4785
|
+
urls,
|
|
4786
|
+
name,
|
|
4787
|
+
description,
|
|
4788
|
+
navigationMode,
|
|
4789
|
+
monitoring: this._monitoringOptions,
|
|
4790
|
+
schemaId: typeof entity === "object" && "schemaId" in entity ? entity.schemaId : void 0,
|
|
4791
|
+
entity: resolvedEntity.entity,
|
|
4792
|
+
fields: resolvedEntity.fields,
|
|
4793
|
+
autoStart: false,
|
|
4794
|
+
interval: this._options.interval,
|
|
4795
|
+
schedules: this._options.schedules
|
|
4796
|
+
});
|
|
4797
|
+
if (this._notificationOptions) {
|
|
4798
|
+
await this.notificationSetupService.setup({
|
|
4799
|
+
...this._notificationOptions,
|
|
4800
|
+
workflowId: workflow.id
|
|
4801
|
+
});
|
|
4802
|
+
}
|
|
4803
|
+
this._workflowId = workflow.id;
|
|
4804
|
+
return this;
|
|
4805
|
+
}
|
|
4806
|
+
async run(options) {
|
|
4807
|
+
assert__default.default(this._options, "Options are not set");
|
|
4808
|
+
assert__default.default(this._workflowId, "Workflow ID is not set");
|
|
4809
|
+
const startedJob = await this.workflowsCoreService.runWorkflow(
|
|
4810
|
+
this._workflowId,
|
|
4811
|
+
{ variables: options?.variables, limit: options?.limit }
|
|
4812
|
+
);
|
|
4813
|
+
assert__default.default(startedJob.jobId, "Job ID is not set");
|
|
4814
|
+
debug3("Job started: %O", startedJob);
|
|
4815
|
+
this._jobId = startedJob.jobId;
|
|
4816
|
+
const finishedJob = await this.workflowsCoreService.waitForJobCompletion(
|
|
4817
|
+
this._workflowId,
|
|
4818
|
+
startedJob.jobId
|
|
4819
|
+
);
|
|
4820
|
+
debug3("Job finished: %O", finishedJob);
|
|
4821
|
+
return this;
|
|
4822
|
+
}
|
|
4823
|
+
async submit(options) {
|
|
4824
|
+
assert__default.default(this._options, "Options are not set");
|
|
4825
|
+
assert__default.default(this._workflowId, "Workflow ID is not set");
|
|
4826
|
+
const submittedJob = await this.workflowsCoreService.runWorkflow(
|
|
4827
|
+
this._workflowId,
|
|
4828
|
+
{ variables: options?.variables, limit: options?.limit }
|
|
4829
|
+
);
|
|
4830
|
+
assert__default.default(submittedJob.jobId, "Job ID is not set");
|
|
4831
|
+
debug3("Job submitted: %O", submittedJob);
|
|
4832
|
+
this._jobId = submittedJob.jobId;
|
|
4833
|
+
return {
|
|
4834
|
+
workflowId: this._workflowId,
|
|
4835
|
+
jobId: this._jobId
|
|
4836
|
+
};
|
|
4837
|
+
}
|
|
4838
|
+
async fetchData(options) {
|
|
4839
|
+
assert__default.default(this._workflowId, "Workflow ID is not set");
|
|
4840
|
+
assert__default.default(this._jobId, "Job ID is not set");
|
|
4841
|
+
return this.dataFetcherService.fetchData({
|
|
4842
|
+
workflowId: this._workflowId,
|
|
4843
|
+
runId: this._jobId,
|
|
4844
|
+
page: options.page ?? 1,
|
|
4845
|
+
limit: options.limit ?? 100,
|
|
4846
|
+
...options
|
|
4847
|
+
});
|
|
4848
|
+
}
|
|
4849
|
+
async fetchAllData(options) {
|
|
4850
|
+
assert__default.default(this._jobId, "Job ID is not set");
|
|
4851
|
+
assert__default.default(this._workflowId, "Workflow ID is not set");
|
|
4852
|
+
return this.dataFetcherService.fetchAllData({
|
|
4853
|
+
workflowId: this._workflowId,
|
|
4854
|
+
runId: this._jobId,
|
|
4855
|
+
...options
|
|
4856
|
+
});
|
|
4857
|
+
}
|
|
4858
|
+
};
|
|
4859
|
+
|
|
4860
|
+
// src/domains/notifications/notifications.acl.ts
|
|
4861
|
+
var NotificationChannelType = {
|
|
4862
|
+
EMAIL: "EMAIL",
|
|
4863
|
+
SLACK: "SLACK",
|
|
4864
|
+
WEBHOOK: "WEBHOOK",
|
|
4865
|
+
WEBSOCKET: "WEBSOCKET"
|
|
4866
|
+
};
|
|
4867
|
+
|
|
4868
|
+
// src/domains/notifications/notification-channels.service.ts
|
|
4869
|
+
var emailChannelConfigSchema = zod.z.object({
|
|
4870
|
+
recipients: zod.z.array(zod.z.email()).min(1, "Recipients are required for email channel"),
|
|
4871
|
+
from: zod.z.email().refine(
|
|
4872
|
+
(email) => email.endsWith("@kadoa.com"),
|
|
4873
|
+
"From email address must end with @kadoa.com"
|
|
4874
|
+
).optional()
|
|
4875
|
+
});
|
|
4876
|
+
var _NotificationChannelsService = class _NotificationChannelsService {
|
|
4877
|
+
constructor(notificationsApi, userService) {
|
|
4878
|
+
this.api = notificationsApi;
|
|
4879
|
+
this.userService = userService;
|
|
4880
|
+
}
|
|
4881
|
+
async listChannels(filters) {
|
|
4882
|
+
const response = await this.api.v5NotificationsChannelsGet(filters);
|
|
4883
|
+
const data = response.data.data?.channels;
|
|
4884
|
+
if (!data) {
|
|
4885
|
+
throw KadoaHttpException.wrap(response, {
|
|
4886
|
+
message: "Failed to list channels"
|
|
4887
|
+
});
|
|
4888
|
+
}
|
|
4889
|
+
return data;
|
|
4890
|
+
}
|
|
4891
|
+
/**
|
|
4892
|
+
* List all channels (both workflow-specific and workspace-level)
|
|
4893
|
+
* This is useful for finding workspace-level channels like WebSocket channels
|
|
4894
|
+
* that might not be associated with a specific workflow
|
|
4895
|
+
*/
|
|
4896
|
+
async listAllChannels(workflowId) {
|
|
4897
|
+
if (!workflowId) {
|
|
4898
|
+
return this.listChannels({});
|
|
4899
|
+
}
|
|
4900
|
+
const [workflowChannels, workspaceChannels] = await Promise.all([
|
|
4901
|
+
this.listChannels({ workflowId }),
|
|
4902
|
+
this.listChannels({})
|
|
4903
|
+
]);
|
|
4904
|
+
const allChannels = [...workflowChannels];
|
|
4905
|
+
workspaceChannels.forEach((channel) => {
|
|
4906
|
+
if (!allChannels.find((c) => c.id === channel.id)) {
|
|
4907
|
+
allChannels.push(channel);
|
|
4908
|
+
}
|
|
4909
|
+
});
|
|
4910
|
+
return allChannels;
|
|
4844
4911
|
}
|
|
4845
4912
|
async deleteChannel(channelId) {
|
|
4846
4913
|
const response = await this.api.v5NotificationsChannelsChannelIdDelete({
|
|
@@ -4943,7 +5010,7 @@ var _NotificationChannelsService = class _NotificationChannelsService {
|
|
|
4943
5010
|
_NotificationChannelsService.DEFAULT_CHANNEL_NAME = "default";
|
|
4944
5011
|
var NotificationChannelsService = _NotificationChannelsService;
|
|
4945
5012
|
|
|
4946
|
-
// src/
|
|
5013
|
+
// src/domains/notifications/notification-settings.service.ts
|
|
4947
5014
|
var NotificationSettingsService = class {
|
|
4948
5015
|
constructor(notificationsApi) {
|
|
4949
5016
|
this.api = notificationsApi;
|
|
@@ -4985,360 +5052,48 @@ var NotificationSettingsService = class {
|
|
|
4985
5052
|
}
|
|
4986
5053
|
};
|
|
4987
5054
|
|
|
4988
|
-
// src/
|
|
4989
|
-
var
|
|
4990
|
-
|
|
4991
|
-
|
|
5055
|
+
// src/domains/notifications/notification-setup.service.ts
|
|
5056
|
+
var debug4 = logger.notifications;
|
|
5057
|
+
var NotificationSetupService = class {
|
|
5058
|
+
constructor(channelsService, settingsService) {
|
|
5059
|
+
this.channelsService = channelsService;
|
|
5060
|
+
this.settingsService = settingsService;
|
|
4992
5061
|
}
|
|
4993
5062
|
/**
|
|
4994
|
-
*
|
|
4995
|
-
* @param options Base options (page will be overridden)
|
|
4996
|
-
* @returns Array of all items
|
|
5063
|
+
* Setup notification settings for a specific workflow ensuring no duplicates exist.
|
|
4997
5064
|
*/
|
|
4998
|
-
async
|
|
4999
|
-
const
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5065
|
+
async setupForWorkflow(requestData) {
|
|
5066
|
+
const existingSettings = await this.settingsService.listSettings({
|
|
5067
|
+
workflowId: requestData.workflowId
|
|
5068
|
+
});
|
|
5069
|
+
if (existingSettings.length > 0) {
|
|
5070
|
+
throw new KadoaSdkException("Settings already exist", {
|
|
5071
|
+
code: KadoaErrorCode.BAD_REQUEST,
|
|
5072
|
+
details: {
|
|
5073
|
+
workflowId: requestData.workflowId
|
|
5074
|
+
}
|
|
5075
|
+
});
|
|
5008
5076
|
}
|
|
5009
|
-
return
|
|
5077
|
+
return this.setup({
|
|
5078
|
+
workflowId: requestData.workflowId,
|
|
5079
|
+
events: requestData.events,
|
|
5080
|
+
channels: requestData.channels
|
|
5081
|
+
});
|
|
5010
5082
|
}
|
|
5011
5083
|
/**
|
|
5012
|
-
*
|
|
5013
|
-
* @param options Base options (page will be overridden)
|
|
5014
|
-
* @returns Async generator that yields pages
|
|
5084
|
+
* Setup notification settings at the workspace level ensuring no duplicates exist.
|
|
5015
5085
|
*/
|
|
5016
|
-
async
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
const pagination = result.pagination;
|
|
5023
|
-
hasMore = pagination.page !== void 0 && pagination.totalPages !== void 0 && pagination.page < pagination.totalPages;
|
|
5024
|
-
currentPage++;
|
|
5086
|
+
async setupForWorkspace(requestData) {
|
|
5087
|
+
const existingSettings = await this.settingsService.listSettings({});
|
|
5088
|
+
if (existingSettings.length > 0) {
|
|
5089
|
+
throw new KadoaSdkException("Workspace settings already exist", {
|
|
5090
|
+
code: KadoaErrorCode.BAD_REQUEST
|
|
5091
|
+
});
|
|
5025
5092
|
}
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
* @returns Async generator that yields items
|
|
5031
|
-
*/
|
|
5032
|
-
async *items(options = {}) {
|
|
5033
|
-
for await (const page of this.pages(options)) {
|
|
5034
|
-
for (const item of page.data) {
|
|
5035
|
-
yield item;
|
|
5036
|
-
}
|
|
5037
|
-
}
|
|
5038
|
-
}
|
|
5039
|
-
};
|
|
5040
|
-
|
|
5041
|
-
// src/internal/domains/extraction/services/data-fetcher.service.ts
|
|
5042
|
-
var DataFetcherService = class {
|
|
5043
|
-
constructor(workflowsApi) {
|
|
5044
|
-
this.workflowsApi = workflowsApi;
|
|
5045
|
-
this.defaultLimit = 100;
|
|
5046
|
-
}
|
|
5047
|
-
/**
|
|
5048
|
-
* Fetch a page of workflow data
|
|
5049
|
-
*/
|
|
5050
|
-
async fetchData(options) {
|
|
5051
|
-
const response = await this.workflowsApi.v4WorkflowsWorkflowIdDataGet({
|
|
5052
|
-
...options,
|
|
5053
|
-
page: options.page ?? 1,
|
|
5054
|
-
limit: options.limit ?? this.defaultLimit
|
|
5055
|
-
});
|
|
5056
|
-
const result = response.data;
|
|
5057
|
-
return result;
|
|
5058
|
-
}
|
|
5059
|
-
/**
|
|
5060
|
-
* Fetch all pages of workflow data
|
|
5061
|
-
*/
|
|
5062
|
-
async fetchAllData(options) {
|
|
5063
|
-
const iterator = new PagedIterator(
|
|
5064
|
-
(pageOptions) => this.fetchData({ ...options, ...pageOptions })
|
|
5065
|
-
);
|
|
5066
|
-
return iterator.fetchAll({ limit: options.limit ?? this.defaultLimit });
|
|
5067
|
-
}
|
|
5068
|
-
/**
|
|
5069
|
-
* Create an async iterator for paginated data fetching
|
|
5070
|
-
*/
|
|
5071
|
-
async *fetchDataPages(options) {
|
|
5072
|
-
const iterator = new PagedIterator(
|
|
5073
|
-
(pageOptions) => this.fetchData({ ...options, ...pageOptions })
|
|
5074
|
-
);
|
|
5075
|
-
for await (const page of iterator.pages({
|
|
5076
|
-
limit: options.limit ?? this.defaultLimit
|
|
5077
|
-
})) {
|
|
5078
|
-
yield page;
|
|
5079
|
-
}
|
|
5080
|
-
}
|
|
5081
|
-
};
|
|
5082
|
-
|
|
5083
|
-
// src/internal/runtime/utils/polling.ts
|
|
5084
|
-
var DEFAULT_POLLING_OPTIONS = {
|
|
5085
|
-
pollIntervalMs: 1e3,
|
|
5086
|
-
timeoutMs: 5 * 60 * 1e3
|
|
5087
|
-
};
|
|
5088
|
-
var POLLING_ERROR_CODES = {
|
|
5089
|
-
ABORTED: "ABORTED",
|
|
5090
|
-
TIMEOUT: "TIMEOUT"
|
|
5091
|
-
};
|
|
5092
|
-
async function pollUntil(pollFn, isComplete, options = {}) {
|
|
5093
|
-
const internalOptions = {
|
|
5094
|
-
...DEFAULT_POLLING_OPTIONS,
|
|
5095
|
-
...options
|
|
5096
|
-
};
|
|
5097
|
-
const pollInterval = Math.max(250, internalOptions.pollIntervalMs);
|
|
5098
|
-
const timeoutMs = internalOptions.timeoutMs;
|
|
5099
|
-
const start = Date.now();
|
|
5100
|
-
let attempts = 0;
|
|
5101
|
-
while (Date.now() - start < timeoutMs) {
|
|
5102
|
-
if (internalOptions.abortSignal?.aborted) {
|
|
5103
|
-
throw new KadoaSdkException("Polling operation was aborted", {
|
|
5104
|
-
code: POLLING_ERROR_CODES.ABORTED
|
|
5105
|
-
});
|
|
5106
|
-
}
|
|
5107
|
-
attempts++;
|
|
5108
|
-
const current = await pollFn();
|
|
5109
|
-
if (isComplete(current)) {
|
|
5110
|
-
return {
|
|
5111
|
-
result: current,
|
|
5112
|
-
attempts,
|
|
5113
|
-
duration: Date.now() - start
|
|
5114
|
-
};
|
|
5115
|
-
}
|
|
5116
|
-
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
5117
|
-
}
|
|
5118
|
-
throw new KadoaSdkException(
|
|
5119
|
-
`Polling operation timed out after ${timeoutMs}ms`,
|
|
5120
|
-
{
|
|
5121
|
-
code: POLLING_ERROR_CODES.TIMEOUT,
|
|
5122
|
-
details: {
|
|
5123
|
-
timeoutMs,
|
|
5124
|
-
attempts,
|
|
5125
|
-
duration: Date.now() - start
|
|
5126
|
-
}
|
|
5127
|
-
}
|
|
5128
|
-
);
|
|
5129
|
-
}
|
|
5130
|
-
|
|
5131
|
-
// src/internal/domains/workflows/types.ts
|
|
5132
|
-
var TERMINAL_JOB_STATES = /* @__PURE__ */ new Set([
|
|
5133
|
-
"FINISHED",
|
|
5134
|
-
"FAILED",
|
|
5135
|
-
"NOT_SUPPORTED",
|
|
5136
|
-
"FAILED_INSUFFICIENT_FUNDS"
|
|
5137
|
-
]);
|
|
5138
|
-
|
|
5139
|
-
// src/internal/domains/workflows/workflows-core.service.ts
|
|
5140
|
-
var TERMINAL_RUN_STATES = /* @__PURE__ */ new Set([
|
|
5141
|
-
"FINISHED",
|
|
5142
|
-
"SUCCESS",
|
|
5143
|
-
"FAILED",
|
|
5144
|
-
"ERROR",
|
|
5145
|
-
"STOPPED",
|
|
5146
|
-
"CANCELLED"
|
|
5147
|
-
]);
|
|
5148
|
-
var debug3 = logger.workflow;
|
|
5149
|
-
var WorkflowsCoreService = class {
|
|
5150
|
-
constructor(workflowsApi) {
|
|
5151
|
-
this.workflowsApi = workflowsApi;
|
|
5152
|
-
}
|
|
5153
|
-
async create(input) {
|
|
5154
|
-
const request = {
|
|
5155
|
-
urls: input.urls,
|
|
5156
|
-
name: input.name,
|
|
5157
|
-
schemaId: input.schemaId,
|
|
5158
|
-
description: input.description,
|
|
5159
|
-
navigationMode: input.navigationMode,
|
|
5160
|
-
entity: input.entity,
|
|
5161
|
-
fields: input.fields,
|
|
5162
|
-
bypassPreview: input.bypassPreview ?? true,
|
|
5163
|
-
tags: input.tags,
|
|
5164
|
-
interval: input.interval,
|
|
5165
|
-
monitoring: input.monitoring,
|
|
5166
|
-
location: input.location,
|
|
5167
|
-
autoStart: input.autoStart,
|
|
5168
|
-
schedules: input.schedules
|
|
5169
|
-
};
|
|
5170
|
-
const response = await this.workflowsApi.v4WorkflowsPost({
|
|
5171
|
-
createWorkflowBody: request
|
|
5172
|
-
});
|
|
5173
|
-
const workflowId = response.data?.workflowId;
|
|
5174
|
-
if (!workflowId) {
|
|
5175
|
-
throw new KadoaSdkException(ERROR_MESSAGES.NO_WORKFLOW_ID, {
|
|
5176
|
-
code: "INTERNAL_ERROR",
|
|
5177
|
-
details: {
|
|
5178
|
-
response: response.data
|
|
5179
|
-
}
|
|
5180
|
-
});
|
|
5181
|
-
}
|
|
5182
|
-
return { id: workflowId };
|
|
5183
|
-
}
|
|
5184
|
-
async get(id) {
|
|
5185
|
-
const response = await this.workflowsApi.v4WorkflowsWorkflowIdGet({
|
|
5186
|
-
workflowId: id
|
|
5187
|
-
});
|
|
5188
|
-
return response.data;
|
|
5189
|
-
}
|
|
5190
|
-
async list(filters) {
|
|
5191
|
-
const response = await this.workflowsApi.v4WorkflowsGet(filters);
|
|
5192
|
-
return response.data?.workflows ?? [];
|
|
5193
|
-
}
|
|
5194
|
-
async getByName(name) {
|
|
5195
|
-
const response = await this.workflowsApi.v4WorkflowsGet({
|
|
5196
|
-
search: name
|
|
5197
|
-
});
|
|
5198
|
-
return response.data?.workflows?.[0];
|
|
5199
|
-
}
|
|
5200
|
-
async cancel(id) {
|
|
5201
|
-
await this.workflowsApi.v4WorkflowsWorkflowIdDelete({
|
|
5202
|
-
workflowId: id
|
|
5203
|
-
});
|
|
5204
|
-
}
|
|
5205
|
-
async resume(id) {
|
|
5206
|
-
await this.workflowsApi.v4WorkflowsWorkflowIdResumePut({
|
|
5207
|
-
workflowId: id
|
|
5208
|
-
});
|
|
5209
|
-
}
|
|
5210
|
-
/**
|
|
5211
|
-
* Wait for a workflow to reach the target state or a terminal state if no target state is provided
|
|
5212
|
-
*/
|
|
5213
|
-
async wait(id, options) {
|
|
5214
|
-
let last;
|
|
5215
|
-
const result = await pollUntil(
|
|
5216
|
-
async () => {
|
|
5217
|
-
const current = await this.get(id);
|
|
5218
|
-
if (last?.state !== current.state || last?.runState !== current.runState) {
|
|
5219
|
-
debug3(
|
|
5220
|
-
"workflow %s state: [workflowState: %s, jobState: %s]",
|
|
5221
|
-
id,
|
|
5222
|
-
current.state,
|
|
5223
|
-
current.runState
|
|
5224
|
-
);
|
|
5225
|
-
}
|
|
5226
|
-
last = current;
|
|
5227
|
-
return current;
|
|
5228
|
-
},
|
|
5229
|
-
(current) => {
|
|
5230
|
-
if (options?.targetState && current.state === options.targetState) {
|
|
5231
|
-
return true;
|
|
5232
|
-
}
|
|
5233
|
-
if (current.runState && TERMINAL_RUN_STATES.has(current.runState.toUpperCase()) && current.state !== "QUEUED") {
|
|
5234
|
-
return true;
|
|
5235
|
-
}
|
|
5236
|
-
return false;
|
|
5237
|
-
},
|
|
5238
|
-
options
|
|
5239
|
-
);
|
|
5240
|
-
return result.result;
|
|
5241
|
-
}
|
|
5242
|
-
/**
|
|
5243
|
-
* Run a workflow with variables and optional limit
|
|
5244
|
-
*/
|
|
5245
|
-
async runWorkflow(workflowId, input) {
|
|
5246
|
-
const response = await this.workflowsApi.v4WorkflowsWorkflowIdRunPut({
|
|
5247
|
-
workflowId,
|
|
5248
|
-
v4WorkflowsWorkflowIdRunPutRequest: {
|
|
5249
|
-
variables: input.variables,
|
|
5250
|
-
limit: input.limit
|
|
5251
|
-
}
|
|
5252
|
-
});
|
|
5253
|
-
const jobId = response.data?.jobId;
|
|
5254
|
-
if (!jobId) {
|
|
5255
|
-
throw new KadoaSdkException(ERROR_MESSAGES.NO_WORKFLOW_ID, {
|
|
5256
|
-
code: "INTERNAL_ERROR",
|
|
5257
|
-
details: {
|
|
5258
|
-
response: response.data
|
|
5259
|
-
}
|
|
5260
|
-
});
|
|
5261
|
-
}
|
|
5262
|
-
return {
|
|
5263
|
-
jobId,
|
|
5264
|
-
message: response.data?.message,
|
|
5265
|
-
status: response.data?.status
|
|
5266
|
-
};
|
|
5267
|
-
}
|
|
5268
|
-
/**
|
|
5269
|
-
* Get job status directly without polling workflow details
|
|
5270
|
-
*/
|
|
5271
|
-
async getJobStatus(workflowId, jobId) {
|
|
5272
|
-
const response = await this.workflowsApi.v4WorkflowsWorkflowIdJobsJobIdGet({
|
|
5273
|
-
workflowId,
|
|
5274
|
-
jobId
|
|
5275
|
-
});
|
|
5276
|
-
return response.data;
|
|
5277
|
-
}
|
|
5278
|
-
/**
|
|
5279
|
-
* Wait for a job to reach the target state or a terminal state
|
|
5280
|
-
*/
|
|
5281
|
-
async waitForJobCompletion(workflowId, jobId, options) {
|
|
5282
|
-
let last;
|
|
5283
|
-
const result = await pollUntil(
|
|
5284
|
-
async () => {
|
|
5285
|
-
const current = await this.getJobStatus(workflowId, jobId);
|
|
5286
|
-
if (last?.state !== current.state) {
|
|
5287
|
-
debug3("job %s state: %s", jobId, current.state);
|
|
5288
|
-
}
|
|
5289
|
-
last = current;
|
|
5290
|
-
return current;
|
|
5291
|
-
},
|
|
5292
|
-
(current) => {
|
|
5293
|
-
if (options?.targetStatus && current.state === options.targetStatus) {
|
|
5294
|
-
return true;
|
|
5295
|
-
}
|
|
5296
|
-
if (current.state && TERMINAL_JOB_STATES.has(current.state)) {
|
|
5297
|
-
return true;
|
|
5298
|
-
}
|
|
5299
|
-
return false;
|
|
5300
|
-
},
|
|
5301
|
-
options
|
|
5302
|
-
);
|
|
5303
|
-
return result.result;
|
|
5304
|
-
}
|
|
5305
|
-
};
|
|
5306
|
-
|
|
5307
|
-
// src/internal/domains/schemas/schemas.service.ts
|
|
5308
|
-
var debug4 = logger.schemas;
|
|
5309
|
-
var SchemasService = class {
|
|
5310
|
-
constructor(client) {
|
|
5311
|
-
this.schemasApi = new SchemasApi(client.configuration);
|
|
5312
|
-
}
|
|
5313
|
-
/**
|
|
5314
|
-
* Get a schema by ID
|
|
5315
|
-
* //todo: use proper schema type for response from generated client (when avaialble)
|
|
5316
|
-
*/
|
|
5317
|
-
async getSchema(schemaId) {
|
|
5318
|
-
debug4("Fetching schema with ID: %s", schemaId);
|
|
5319
|
-
const response = await this.schemasApi.v4SchemasSchemaIdGet({
|
|
5320
|
-
schemaId
|
|
5321
|
-
});
|
|
5322
|
-
const schemaData = response.data.data;
|
|
5323
|
-
if (!schemaData) {
|
|
5324
|
-
throw new KadoaSdkException(
|
|
5325
|
-
`${ERROR_MESSAGES.SCHEMA_NOT_FOUND}: ${schemaId}`,
|
|
5326
|
-
{
|
|
5327
|
-
code: KadoaErrorCode.NOT_FOUND,
|
|
5328
|
-
details: { schemaId }
|
|
5329
|
-
}
|
|
5330
|
-
);
|
|
5331
|
-
}
|
|
5332
|
-
return schemaData;
|
|
5333
|
-
}
|
|
5334
|
-
};
|
|
5335
|
-
|
|
5336
|
-
// src/internal/domains/notifications/notification-setup.service.ts
|
|
5337
|
-
var debug5 = logger.notifications;
|
|
5338
|
-
var NotificationSetupService = class {
|
|
5339
|
-
constructor(channelsService, settingsService) {
|
|
5340
|
-
this.channelsService = channelsService;
|
|
5341
|
-
this.settingsService = settingsService;
|
|
5093
|
+
return this.setup({
|
|
5094
|
+
events: requestData.events,
|
|
5095
|
+
channels: requestData.channels
|
|
5096
|
+
});
|
|
5342
5097
|
}
|
|
5343
5098
|
/**
|
|
5344
5099
|
* Complete workflow notification setup including channels and settings
|
|
@@ -5347,10 +5102,10 @@ var NotificationSetupService = class {
|
|
|
5347
5102
|
* @returns Array of created notification settings
|
|
5348
5103
|
*/
|
|
5349
5104
|
async setup(requestData) {
|
|
5350
|
-
requestData.workflowId ?
|
|
5105
|
+
requestData.workflowId ? debug4(
|
|
5351
5106
|
"Setting up notifications for workflow %s",
|
|
5352
5107
|
requestData.workflowId
|
|
5353
|
-
) :
|
|
5108
|
+
) : debug4("Setting up notifications for workspace");
|
|
5354
5109
|
const channels = await this.setupChannels({
|
|
5355
5110
|
workflowId: requestData.workflowId,
|
|
5356
5111
|
channels: requestData.channels || {}
|
|
@@ -5358,7 +5113,7 @@ var NotificationSetupService = class {
|
|
|
5358
5113
|
const events = requestData.events || "all";
|
|
5359
5114
|
const eventTypes = events === "all" ? await this.settingsService.listAllEvents() : events;
|
|
5360
5115
|
const channelIds = channels.map((channel) => channel.id).filter(Boolean);
|
|
5361
|
-
|
|
5116
|
+
debug4(
|
|
5362
5117
|
"Creating notification settings for workflow %s: %O",
|
|
5363
5118
|
requestData.workflowId,
|
|
5364
5119
|
{
|
|
@@ -5377,7 +5132,7 @@ var NotificationSetupService = class {
|
|
|
5377
5132
|
});
|
|
5378
5133
|
})
|
|
5379
5134
|
);
|
|
5380
|
-
|
|
5135
|
+
debug4(
|
|
5381
5136
|
requestData.workflowId ? "Successfully setup notifications for workflow %s" : "Successfully setup notifications for workspace",
|
|
5382
5137
|
requestData.workflowId
|
|
5383
5138
|
);
|
|
@@ -5459,7 +5214,7 @@ var NotificationSetupService = class {
|
|
|
5459
5214
|
(channel2) => channel2.channelType === channelType && channel2.name === NotificationChannelsService.DEFAULT_CHANNEL_NAME
|
|
5460
5215
|
);
|
|
5461
5216
|
if (existingChannel) {
|
|
5462
|
-
|
|
5217
|
+
debug4("Using existing default channel: %O", {
|
|
5463
5218
|
workflowId,
|
|
5464
5219
|
channelType,
|
|
5465
5220
|
channelId: existingChannel.id
|
|
@@ -5467,7 +5222,7 @@ var NotificationSetupService = class {
|
|
|
5467
5222
|
return existingChannel;
|
|
5468
5223
|
}
|
|
5469
5224
|
const channel = await this.channelsService.createChannel(channelType);
|
|
5470
|
-
|
|
5225
|
+
debug4("Created default channel %O", {
|
|
5471
5226
|
workflowId,
|
|
5472
5227
|
channelType,
|
|
5473
5228
|
channel
|
|
@@ -5492,7 +5247,7 @@ var NotificationSetupService = class {
|
|
|
5492
5247
|
(channel2) => channel2.channelType === channelType && (channel2.name || NotificationChannelsService.DEFAULT_CHANNEL_NAME) === channelName
|
|
5493
5248
|
);
|
|
5494
5249
|
if (existingChannel) {
|
|
5495
|
-
|
|
5250
|
+
debug4("Using existing channel: %O", {
|
|
5496
5251
|
workflowId,
|
|
5497
5252
|
channelType,
|
|
5498
5253
|
channelName,
|
|
@@ -5504,725 +5259,741 @@ var NotificationSetupService = class {
|
|
|
5504
5259
|
name: channelName,
|
|
5505
5260
|
config
|
|
5506
5261
|
});
|
|
5507
|
-
|
|
5262
|
+
debug4("Created channel with custom config %O", {
|
|
5508
5263
|
workflowId,
|
|
5509
5264
|
channelType,
|
|
5510
5265
|
channelName,
|
|
5511
5266
|
channel
|
|
5512
5267
|
});
|
|
5513
|
-
return channel;
|
|
5514
|
-
})
|
|
5515
|
-
);
|
|
5516
|
-
return channels;
|
|
5517
|
-
}
|
|
5518
|
-
};
|
|
5519
|
-
|
|
5520
|
-
// src/internal/domains/validation/validation-core.service.ts
|
|
5521
|
-
var ValidationCoreService = class {
|
|
5522
|
-
constructor(client) {
|
|
5523
|
-
this.validationApi = new DataValidationApi(
|
|
5524
|
-
client.configuration,
|
|
5525
|
-
client.baseUrl,
|
|
5526
|
-
client.axiosInstance
|
|
5527
|
-
);
|
|
5528
|
-
}
|
|
5529
|
-
async listWorkflowValidations(filters) {
|
|
5530
|
-
const response = await this.validationApi.v4DataValidationWorkflowsWorkflowIdJobsJobIdValidationsGet(
|
|
5531
|
-
filters
|
|
5532
|
-
);
|
|
5533
|
-
if (response.status !== 200) {
|
|
5534
|
-
throw KadoaHttpException.wrap(response.data, {
|
|
5535
|
-
message: "Failed to list workflow validations"
|
|
5536
|
-
});
|
|
5537
|
-
}
|
|
5538
|
-
return response.data;
|
|
5539
|
-
}
|
|
5540
|
-
async getValidationDetails(validationId) {
|
|
5541
|
-
const response = await this.validationApi.v4DataValidationValidationsValidationIdGet({
|
|
5542
|
-
validationId
|
|
5543
|
-
});
|
|
5544
|
-
if (response.status !== 200 || response.data.error) {
|
|
5545
|
-
throw KadoaHttpException.wrap(response.data, {
|
|
5546
|
-
message: "Failed to get validation details"
|
|
5547
|
-
});
|
|
5548
|
-
}
|
|
5549
|
-
return response.data;
|
|
5550
|
-
}
|
|
5551
|
-
async scheduleValidation(workflowId, jobId) {
|
|
5552
|
-
const response = await this.validationApi.v4DataValidationWorkflowsWorkflowIdJobsJobIdValidatePost(
|
|
5553
|
-
{
|
|
5554
|
-
workflowId,
|
|
5555
|
-
jobId
|
|
5556
|
-
}
|
|
5557
|
-
);
|
|
5558
|
-
if (response.status !== 200 || response.data.error) {
|
|
5559
|
-
throw KadoaHttpException.wrap(response.data, {
|
|
5560
|
-
message: response.data.message || "Failed to schedule validation"
|
|
5561
|
-
});
|
|
5562
|
-
}
|
|
5563
|
-
return response.data;
|
|
5564
|
-
}
|
|
5565
|
-
async toggleValidationEnabled(workflowId) {
|
|
5566
|
-
const response = await this.validationApi.v4DataValidationWorkflowsWorkflowIdValidationTogglePut(
|
|
5567
|
-
{
|
|
5568
|
-
workflowId
|
|
5569
|
-
}
|
|
5570
|
-
);
|
|
5571
|
-
if (response.status !== 200 || response.data.error) {
|
|
5572
|
-
throw KadoaHttpException.wrap(response.data, {
|
|
5573
|
-
message: response.data.message || "Failed to toggle validation"
|
|
5574
|
-
});
|
|
5575
|
-
}
|
|
5576
|
-
return response.data;
|
|
5577
|
-
}
|
|
5578
|
-
async getLatestValidation(workflowId, jobId) {
|
|
5579
|
-
let response;
|
|
5580
|
-
if (jobId) {
|
|
5581
|
-
response = await this.validationApi.v4DataValidationWorkflowsWorkflowIdJobsJobIdValidationsLatestGet(
|
|
5582
|
-
{
|
|
5583
|
-
workflowId,
|
|
5584
|
-
jobId
|
|
5585
|
-
}
|
|
5586
|
-
);
|
|
5587
|
-
} else {
|
|
5588
|
-
response = await this.validationApi.v4DataValidationWorkflowsWorkflowIdValidationsLatestGet(
|
|
5589
|
-
{
|
|
5590
|
-
workflowId
|
|
5591
|
-
}
|
|
5592
|
-
);
|
|
5593
|
-
}
|
|
5594
|
-
if (response.status !== 200 || response.data.error) {
|
|
5595
|
-
throw KadoaHttpException.wrap(response.data, {
|
|
5596
|
-
message: "Failed to get latest validation"
|
|
5597
|
-
});
|
|
5598
|
-
}
|
|
5599
|
-
return response.data;
|
|
5600
|
-
}
|
|
5601
|
-
async getValidationAnomalies(validationId) {
|
|
5602
|
-
const response = await this.validationApi.v4DataValidationValidationsValidationIdAnomaliesGet(
|
|
5603
|
-
{
|
|
5604
|
-
validationId
|
|
5605
|
-
}
|
|
5606
|
-
);
|
|
5607
|
-
if (response.status !== 200) {
|
|
5608
|
-
throw KadoaHttpException.wrap(response.data, {
|
|
5609
|
-
message: "Failed to get validation anomalies"
|
|
5610
|
-
});
|
|
5611
|
-
}
|
|
5612
|
-
return response.data;
|
|
5613
|
-
}
|
|
5614
|
-
async getValidationAnomaliesByRule(validationId, ruleName) {
|
|
5615
|
-
const response = await this.validationApi.v4DataValidationValidationsValidationIdAnomaliesRulesRuleNameGet(
|
|
5616
|
-
{
|
|
5617
|
-
validationId,
|
|
5618
|
-
ruleName
|
|
5619
|
-
}
|
|
5620
|
-
);
|
|
5621
|
-
if (response.status !== 200) {
|
|
5622
|
-
throw KadoaHttpException.wrap(response.data, {
|
|
5623
|
-
message: "Failed to get validation anomalies by rule"
|
|
5624
|
-
});
|
|
5625
|
-
}
|
|
5626
|
-
return response.data;
|
|
5627
|
-
}
|
|
5628
|
-
async waitUntilCompleted(validationId, options) {
|
|
5629
|
-
const result = await pollUntil(
|
|
5630
|
-
async () => {
|
|
5631
|
-
const current = await this.getValidationDetails(validationId);
|
|
5632
|
-
if (current.error) {
|
|
5633
|
-
throw new KadoaSdkException(`Validation failed: ${current.error}`, {
|
|
5634
|
-
code: "VALIDATION_ERROR",
|
|
5635
|
-
details: { validationId, error: current.error }
|
|
5636
|
-
});
|
|
5637
|
-
}
|
|
5638
|
-
return current;
|
|
5639
|
-
},
|
|
5640
|
-
(result2) => result2.completedAt != null,
|
|
5641
|
-
options
|
|
5268
|
+
return channel;
|
|
5269
|
+
})
|
|
5642
5270
|
);
|
|
5643
|
-
return
|
|
5271
|
+
return channels;
|
|
5644
5272
|
}
|
|
5645
5273
|
};
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5274
|
+
|
|
5275
|
+
// src/runtime/config/constants.ts
|
|
5276
|
+
var PUBLIC_API_URI = process.env.KADOA_PUBLIC_API_URI ?? "https://api.kadoa.com";
|
|
5277
|
+
var WSS_API_URI = process.env.KADOA_WSS_API_URI ?? "wss://realtime.kadoa.com";
|
|
5278
|
+
var REALTIME_API_URI = process.env.KADOA_REALTIME_API_URI ?? "https://realtime.kadoa.com";
|
|
5279
|
+
|
|
5280
|
+
// src/version.ts
|
|
5281
|
+
var SDK_VERSION = "0.14.1";
|
|
5282
|
+
var SDK_NAME = "kadoa-node-sdk";
|
|
5283
|
+
var SDK_LANGUAGE = "node";
|
|
5284
|
+
|
|
5285
|
+
// src/domains/realtime/realtime.ts
|
|
5286
|
+
var debug5 = logger.wss;
|
|
5287
|
+
if (typeof WebSocket === "undefined") {
|
|
5288
|
+
global.WebSocket = __require("ws");
|
|
5289
|
+
}
|
|
5290
|
+
var Realtime = class {
|
|
5291
|
+
constructor(config) {
|
|
5292
|
+
this.lastHeartbeat = Date.now();
|
|
5293
|
+
this.isConnecting = false;
|
|
5294
|
+
this.eventListeners = /* @__PURE__ */ new Set();
|
|
5295
|
+
this.connectionListeners = /* @__PURE__ */ new Set();
|
|
5296
|
+
this.errorListeners = /* @__PURE__ */ new Set();
|
|
5297
|
+
if (!config.teamApiKey.startsWith("tk-")) {
|
|
5298
|
+
throw new KadoaSdkException(
|
|
5299
|
+
"Realtime connection requires a team API key (starting with 'tk-'). Provided key does not appear to be a team API key.",
|
|
5300
|
+
{
|
|
5301
|
+
code: "AUTH_ERROR",
|
|
5302
|
+
details: { providedKeyPrefix: config.teamApiKey.substring(0, 3) }
|
|
5303
|
+
}
|
|
5304
|
+
);
|
|
5660
5305
|
}
|
|
5661
|
-
|
|
5306
|
+
this.teamApiKey = config.teamApiKey;
|
|
5307
|
+
this.heartbeatInterval = config.heartbeatInterval || 1e4;
|
|
5308
|
+
this.reconnectDelay = config.reconnectDelay || 5e3;
|
|
5309
|
+
this.missedHeartbeatsLimit = config.missedHeartbeatsLimit || 3e4;
|
|
5662
5310
|
}
|
|
5663
|
-
async
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5311
|
+
async connect() {
|
|
5312
|
+
if (this.isConnecting) return;
|
|
5313
|
+
this.isConnecting = true;
|
|
5314
|
+
try {
|
|
5315
|
+
const response = await fetch(`${PUBLIC_API_URI}/v4/oauth2/token`, {
|
|
5316
|
+
method: "POST",
|
|
5317
|
+
headers: {
|
|
5318
|
+
"Content-Type": "application/json",
|
|
5319
|
+
"x-api-key": `${this.teamApiKey}`,
|
|
5320
|
+
"x-sdk-version": SDK_VERSION
|
|
5321
|
+
}
|
|
5670
5322
|
});
|
|
5323
|
+
const { access_token, team_id } = await response.json();
|
|
5324
|
+
this.socket = new WebSocket(
|
|
5325
|
+
`${WSS_API_URI}?access_token=${access_token}`
|
|
5326
|
+
);
|
|
5327
|
+
this.socket.onopen = () => {
|
|
5328
|
+
this.isConnecting = false;
|
|
5329
|
+
this.lastHeartbeat = Date.now();
|
|
5330
|
+
if (this.socket?.readyState === WebSocket.OPEN) {
|
|
5331
|
+
this.socket.send(
|
|
5332
|
+
JSON.stringify({
|
|
5333
|
+
action: "subscribe",
|
|
5334
|
+
channel: team_id
|
|
5335
|
+
})
|
|
5336
|
+
);
|
|
5337
|
+
debug5("Connected to WebSocket");
|
|
5338
|
+
this.notifyConnectionListeners(true);
|
|
5339
|
+
}
|
|
5340
|
+
this.startHeartbeatCheck();
|
|
5341
|
+
};
|
|
5342
|
+
this.socket.onmessage = (event) => {
|
|
5343
|
+
try {
|
|
5344
|
+
const data = JSON.parse(event.data);
|
|
5345
|
+
if (data.type === "heartbeat") {
|
|
5346
|
+
this.handleHeartbeat();
|
|
5347
|
+
} else {
|
|
5348
|
+
if (data?.id) {
|
|
5349
|
+
fetch(`${REALTIME_API_URI}/api/v1/events/ack`, {
|
|
5350
|
+
method: "POST",
|
|
5351
|
+
headers: { "Content-Type": "application/json" },
|
|
5352
|
+
body: JSON.stringify({ id: data.id })
|
|
5353
|
+
});
|
|
5354
|
+
}
|
|
5355
|
+
this.notifyEventListeners(data);
|
|
5356
|
+
}
|
|
5357
|
+
} catch (err) {
|
|
5358
|
+
debug5("Failed to parse incoming message: %O", err);
|
|
5359
|
+
}
|
|
5360
|
+
};
|
|
5361
|
+
this.socket.onclose = () => {
|
|
5362
|
+
debug5("WebSocket disconnected. Attempting to reconnect...");
|
|
5363
|
+
this.isConnecting = false;
|
|
5364
|
+
this.stopHeartbeatCheck();
|
|
5365
|
+
this.notifyConnectionListeners(false, "Connection closed");
|
|
5366
|
+
setTimeout(() => this.connect(), this.reconnectDelay);
|
|
5367
|
+
};
|
|
5368
|
+
this.socket.onerror = (error) => {
|
|
5369
|
+
debug5("WebSocket error: %O", error);
|
|
5370
|
+
this.isConnecting = false;
|
|
5371
|
+
this.notifyErrorListeners(error);
|
|
5372
|
+
};
|
|
5373
|
+
} catch (err) {
|
|
5374
|
+
debug5("Failed to connect: %O", err);
|
|
5375
|
+
this.isConnecting = false;
|
|
5376
|
+
setTimeout(() => this.connect(), this.reconnectDelay);
|
|
5671
5377
|
}
|
|
5672
|
-
return response.data.data;
|
|
5673
5378
|
}
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
throw KadoaHttpException.wrap(response.data.data, {
|
|
5678
|
-
message: "Failed to get validation rule by name"
|
|
5679
|
-
});
|
|
5680
|
-
}
|
|
5681
|
-
return response.data.data?.find((rule) => rule.name === name);
|
|
5379
|
+
handleHeartbeat() {
|
|
5380
|
+
debug5("Heartbeat received");
|
|
5381
|
+
this.lastHeartbeat = Date.now();
|
|
5682
5382
|
}
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5383
|
+
notifyEventListeners(event) {
|
|
5384
|
+
this.eventListeners.forEach((listener) => {
|
|
5385
|
+
try {
|
|
5386
|
+
listener(event);
|
|
5387
|
+
} catch (error) {
|
|
5388
|
+
debug5("Error in event listener: %O", error);
|
|
5389
|
+
}
|
|
5686
5390
|
});
|
|
5687
|
-
if (response.status !== 200 || response.data.error) {
|
|
5688
|
-
throw KadoaHttpException.wrap(response.data.data, {
|
|
5689
|
-
message: response.data.message || "Failed to create validation rule"
|
|
5690
|
-
});
|
|
5691
|
-
}
|
|
5692
|
-
return response.data.data;
|
|
5693
5391
|
}
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5392
|
+
notifyConnectionListeners(connected, reason) {
|
|
5393
|
+
this.connectionListeners.forEach((listener) => {
|
|
5394
|
+
try {
|
|
5395
|
+
listener(connected, reason);
|
|
5396
|
+
} catch (error) {
|
|
5397
|
+
debug5("Error in connection listener: %O", error);
|
|
5398
|
+
}
|
|
5698
5399
|
});
|
|
5699
|
-
if (response.status !== 200 || response.data.error) {
|
|
5700
|
-
throw KadoaHttpException.wrap(response.data.data, {
|
|
5701
|
-
message: response.data.message || "Failed to update validation rule"
|
|
5702
|
-
});
|
|
5703
|
-
}
|
|
5704
|
-
return response.data.data;
|
|
5705
|
-
}
|
|
5706
|
-
async disableRule(data) {
|
|
5707
|
-
const response = await this.validationApi.v4DataValidationRulesRuleIdDisablePost(data);
|
|
5708
|
-
if (response.status !== 200 || response.data.error) {
|
|
5709
|
-
throw KadoaHttpException.wrap(response.data.data, {
|
|
5710
|
-
message: response.data.message || "Failed to disable validation rule"
|
|
5711
|
-
});
|
|
5712
|
-
}
|
|
5713
|
-
return response.data.data;
|
|
5714
5400
|
}
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5401
|
+
notifyErrorListeners(error) {
|
|
5402
|
+
this.errorListeners.forEach((listener) => {
|
|
5403
|
+
try {
|
|
5404
|
+
listener(error);
|
|
5405
|
+
} catch (error2) {
|
|
5406
|
+
debug5("Error in error listener: %O", error2);
|
|
5407
|
+
}
|
|
5718
5408
|
});
|
|
5719
|
-
if (response.status !== 200 || response.data.error) {
|
|
5720
|
-
throw KadoaHttpException.wrap(response.data.data, {
|
|
5721
|
-
message: response.data.message || "Failed to generate validation rule"
|
|
5722
|
-
});
|
|
5723
|
-
}
|
|
5724
|
-
return response.data.data;
|
|
5725
5409
|
}
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
});
|
|
5734
|
-
}
|
|
5735
|
-
return response.data.data;
|
|
5410
|
+
startHeartbeatCheck() {
|
|
5411
|
+
this.missedHeartbeatCheckTimer = setInterval(() => {
|
|
5412
|
+
if (Date.now() - this.lastHeartbeat > this.missedHeartbeatsLimit) {
|
|
5413
|
+
debug5("No heartbeat received in 30 seconds! Closing connection.");
|
|
5414
|
+
this.socket?.close();
|
|
5415
|
+
}
|
|
5416
|
+
}, this.heartbeatInterval);
|
|
5736
5417
|
}
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
});
|
|
5741
|
-
if (response.status !== 200 || response.data.error) {
|
|
5742
|
-
throw KadoaHttpException.wrap(response.data.data, {
|
|
5743
|
-
message: response.data.message || "Failed to bulk approve validation rules"
|
|
5744
|
-
});
|
|
5418
|
+
stopHeartbeatCheck() {
|
|
5419
|
+
if (this.missedHeartbeatCheckTimer) {
|
|
5420
|
+
clearInterval(this.missedHeartbeatCheckTimer);
|
|
5745
5421
|
}
|
|
5746
|
-
return response.data.data;
|
|
5747
5422
|
}
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5423
|
+
/**
|
|
5424
|
+
* Subscribe to realtime events
|
|
5425
|
+
* @param listener Function to handle incoming events
|
|
5426
|
+
* @returns Function to unsubscribe
|
|
5427
|
+
*/
|
|
5428
|
+
onEvent(listener) {
|
|
5429
|
+
this.eventListeners.add(listener);
|
|
5430
|
+
return () => {
|
|
5431
|
+
this.eventListeners.delete(listener);
|
|
5432
|
+
};
|
|
5433
|
+
}
|
|
5434
|
+
/**
|
|
5435
|
+
* Subscribe to connection state changes
|
|
5436
|
+
* @param listener Function to handle connection state changes
|
|
5437
|
+
* @returns Function to unsubscribe
|
|
5438
|
+
*/
|
|
5439
|
+
onConnection(listener) {
|
|
5440
|
+
this.connectionListeners.add(listener);
|
|
5441
|
+
return () => {
|
|
5442
|
+
this.connectionListeners.delete(listener);
|
|
5443
|
+
};
|
|
5444
|
+
}
|
|
5445
|
+
/**
|
|
5446
|
+
* Subscribe to errors
|
|
5447
|
+
* @param listener Function to handle errors
|
|
5448
|
+
* @returns Function to unsubscribe
|
|
5449
|
+
*/
|
|
5450
|
+
onError(listener) {
|
|
5451
|
+
this.errorListeners.add(listener);
|
|
5452
|
+
return () => {
|
|
5453
|
+
this.errorListeners.delete(listener);
|
|
5454
|
+
};
|
|
5455
|
+
}
|
|
5456
|
+
close() {
|
|
5457
|
+
if (this.socket) {
|
|
5458
|
+
this.stopHeartbeatCheck();
|
|
5459
|
+
this.socket.close();
|
|
5460
|
+
this.socket = void 0;
|
|
5756
5461
|
}
|
|
5757
|
-
|
|
5462
|
+
this.eventListeners.clear();
|
|
5463
|
+
this.connectionListeners.clear();
|
|
5464
|
+
this.errorListeners.clear();
|
|
5758
5465
|
}
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
deleteRuleWithReason: data
|
|
5762
|
-
});
|
|
5763
|
-
if (response.status !== 200 || response.data.error) {
|
|
5764
|
-
throw KadoaHttpException.wrap(response.data.data, {
|
|
5765
|
-
message: response.data.message || "Failed to delete all validation rules"
|
|
5766
|
-
});
|
|
5767
|
-
}
|
|
5768
|
-
return response.data.data;
|
|
5466
|
+
isConnected() {
|
|
5467
|
+
return this.socket?.readyState === WebSocket.OPEN;
|
|
5769
5468
|
}
|
|
5770
5469
|
};
|
|
5771
5470
|
|
|
5772
|
-
// src/
|
|
5773
|
-
var
|
|
5774
|
-
var EntityResolverService = class {
|
|
5471
|
+
// src/domains/user/user.service.ts
|
|
5472
|
+
var UserService = class {
|
|
5775
5473
|
constructor(client) {
|
|
5776
5474
|
this.client = client;
|
|
5777
|
-
this.schemasService = new SchemasService(client);
|
|
5778
5475
|
}
|
|
5779
5476
|
/**
|
|
5780
|
-
*
|
|
5781
|
-
*
|
|
5782
|
-
* @param entityConfig The entity configuration to resolve
|
|
5783
|
-
* @param options Additional options for AI detection
|
|
5784
|
-
* @returns Resolved entity with fields
|
|
5477
|
+
* Get current user details
|
|
5478
|
+
* @returns User details
|
|
5785
5479
|
*/
|
|
5786
|
-
async
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
});
|
|
5480
|
+
async getCurrentUser() {
|
|
5481
|
+
const response = await this.client.axiosInstance.get("/v5/user", {
|
|
5482
|
+
baseURL: this.client.baseUrl,
|
|
5483
|
+
headers: {
|
|
5484
|
+
"x-api-key": this.client.apiKey,
|
|
5485
|
+
"Content-Type": "application/json"
|
|
5793
5486
|
}
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5487
|
+
});
|
|
5488
|
+
const userData = response.data;
|
|
5489
|
+
if (!userData || !userData.userId) {
|
|
5490
|
+
throw new KadoaSdkException("Invalid user data received");
|
|
5491
|
+
}
|
|
5492
|
+
return {
|
|
5493
|
+
userId: userData.userId,
|
|
5494
|
+
email: userData.email,
|
|
5495
|
+
featureFlags: userData.featureFlags || []
|
|
5496
|
+
};
|
|
5497
|
+
}
|
|
5498
|
+
};
|
|
5499
|
+
|
|
5500
|
+
// src/runtime/utils/polling.ts
|
|
5501
|
+
var DEFAULT_POLLING_OPTIONS = {
|
|
5502
|
+
pollIntervalMs: 1e3,
|
|
5503
|
+
timeoutMs: 5 * 60 * 1e3
|
|
5504
|
+
};
|
|
5505
|
+
var POLLING_ERROR_CODES = {
|
|
5506
|
+
ABORTED: "ABORTED",
|
|
5507
|
+
TIMEOUT: "TIMEOUT"
|
|
5508
|
+
};
|
|
5509
|
+
async function pollUntil(pollFn, isComplete, options = {}) {
|
|
5510
|
+
const internalOptions = {
|
|
5511
|
+
...DEFAULT_POLLING_OPTIONS,
|
|
5512
|
+
...options
|
|
5513
|
+
};
|
|
5514
|
+
const pollInterval = Math.max(250, internalOptions.pollIntervalMs);
|
|
5515
|
+
const timeoutMs = internalOptions.timeoutMs;
|
|
5516
|
+
const start = Date.now();
|
|
5517
|
+
let attempts = 0;
|
|
5518
|
+
while (Date.now() - start < timeoutMs) {
|
|
5519
|
+
if (internalOptions.abortSignal?.aborted) {
|
|
5520
|
+
throw new KadoaSdkException("Polling operation was aborted", {
|
|
5521
|
+
code: POLLING_ERROR_CODES.ABORTED
|
|
5798
5522
|
});
|
|
5523
|
+
}
|
|
5524
|
+
attempts++;
|
|
5525
|
+
const current = await pollFn();
|
|
5526
|
+
if (isComplete(current)) {
|
|
5799
5527
|
return {
|
|
5800
|
-
|
|
5801
|
-
|
|
5528
|
+
result: current,
|
|
5529
|
+
attempts,
|
|
5530
|
+
duration: Date.now() - start
|
|
5802
5531
|
};
|
|
5803
|
-
} else if (entityConfig) {
|
|
5804
|
-
if ("schemId" in entityConfig) {
|
|
5805
|
-
const schema = await this.schemasService.getSchema(
|
|
5806
|
-
entityConfig.schemId
|
|
5807
|
-
);
|
|
5808
|
-
return {
|
|
5809
|
-
entity: schema.entity,
|
|
5810
|
-
fields: schema.schema
|
|
5811
|
-
};
|
|
5812
|
-
} else if ("name" in entityConfig && "fields" in entityConfig) {
|
|
5813
|
-
return {
|
|
5814
|
-
entity: entityConfig.name,
|
|
5815
|
-
fields: entityConfig.fields
|
|
5816
|
-
};
|
|
5817
|
-
}
|
|
5818
5532
|
}
|
|
5819
|
-
|
|
5820
|
-
details: {
|
|
5821
|
-
entity: entityConfig
|
|
5822
|
-
}
|
|
5823
|
-
});
|
|
5533
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
5824
5534
|
}
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
async fetchEntityFields(options) {
|
|
5834
|
-
this.validateEntityOptions(options);
|
|
5835
|
-
const url = `${this.client.baseUrl}${ENTITY_API_ENDPOINT}`;
|
|
5836
|
-
const requestBody = options;
|
|
5837
|
-
const response = await this.client.axiosInstance.post(url, requestBody, {
|
|
5838
|
-
headers: {
|
|
5839
|
-
"Content-Type": "application/json",
|
|
5840
|
-
Accept: "application/json",
|
|
5841
|
-
"x-api-key": this.client.apiKey
|
|
5535
|
+
throw new KadoaSdkException(
|
|
5536
|
+
`Polling operation timed out after ${timeoutMs}ms`,
|
|
5537
|
+
{
|
|
5538
|
+
code: POLLING_ERROR_CODES.TIMEOUT,
|
|
5539
|
+
details: {
|
|
5540
|
+
timeoutMs,
|
|
5541
|
+
attempts,
|
|
5542
|
+
duration: Date.now() - start
|
|
5842
5543
|
}
|
|
5843
|
-
});
|
|
5844
|
-
const data = response.data;
|
|
5845
|
-
if (!data.success || !data.entityPrediction || data.entityPrediction.length === 0) {
|
|
5846
|
-
throw new KadoaSdkException(ERROR_MESSAGES.NO_PREDICTIONS, {
|
|
5847
|
-
code: "NOT_FOUND",
|
|
5848
|
-
details: {
|
|
5849
|
-
success: data.success,
|
|
5850
|
-
hasPredictions: !!data.entityPrediction,
|
|
5851
|
-
predictionCount: data.entityPrediction?.length || 0,
|
|
5852
|
-
link: options.link
|
|
5853
|
-
}
|
|
5854
|
-
});
|
|
5855
5544
|
}
|
|
5856
|
-
|
|
5545
|
+
);
|
|
5546
|
+
}
|
|
5547
|
+
|
|
5548
|
+
// src/domains/validation/validation-core.service.ts
|
|
5549
|
+
var ValidationCoreService = class {
|
|
5550
|
+
constructor(client) {
|
|
5551
|
+
this.validationApi = new DataValidationApi(
|
|
5552
|
+
client.configuration,
|
|
5553
|
+
client.baseUrl,
|
|
5554
|
+
client.axiosInstance
|
|
5555
|
+
);
|
|
5857
5556
|
}
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
if (
|
|
5863
|
-
throw
|
|
5864
|
-
|
|
5865
|
-
details: { options }
|
|
5557
|
+
async listWorkflowValidations(filters) {
|
|
5558
|
+
const response = await this.validationApi.v4DataValidationWorkflowsWorkflowIdJobsJobIdValidationsGet(
|
|
5559
|
+
filters
|
|
5560
|
+
);
|
|
5561
|
+
if (response.status !== 200) {
|
|
5562
|
+
throw KadoaHttpException.wrap(response.data, {
|
|
5563
|
+
message: "Failed to list workflow validations"
|
|
5866
5564
|
});
|
|
5867
5565
|
}
|
|
5566
|
+
return response.data;
|
|
5868
5567
|
}
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
* Start defining a custom schema with fields
|
|
5878
|
-
* @param name - The entity name (e.g., "Product", "Article")
|
|
5879
|
-
*/
|
|
5880
|
-
schema(name) {
|
|
5881
|
-
if (this.schemaId) {
|
|
5882
|
-
throw new KadoaSdkException(
|
|
5883
|
-
"Cannot use schema() after useSchema() - they are mutually exclusive",
|
|
5884
|
-
{ code: "VALIDATION_ERROR" }
|
|
5885
|
-
);
|
|
5568
|
+
async getValidationDetails(validationId) {
|
|
5569
|
+
const response = await this.validationApi.v4DataValidationValidationsValidationIdGet({
|
|
5570
|
+
validationId
|
|
5571
|
+
});
|
|
5572
|
+
if (response.status !== 200 || response.data.error) {
|
|
5573
|
+
throw KadoaHttpException.wrap(response.data, {
|
|
5574
|
+
message: "Failed to get validation details"
|
|
5575
|
+
});
|
|
5886
5576
|
}
|
|
5887
|
-
|
|
5888
|
-
return new SchemaBuilder(this);
|
|
5577
|
+
return response.data;
|
|
5889
5578
|
}
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5579
|
+
async scheduleValidation(workflowId, jobId) {
|
|
5580
|
+
const response = await this.validationApi.v4DataValidationWorkflowsWorkflowIdJobsJobIdValidatePost(
|
|
5581
|
+
{
|
|
5582
|
+
workflowId,
|
|
5583
|
+
jobId
|
|
5584
|
+
}
|
|
5585
|
+
);
|
|
5586
|
+
if (response.status !== 200 || response.data.error) {
|
|
5587
|
+
throw KadoaHttpException.wrap(response.data, {
|
|
5588
|
+
message: response.data.message || "Failed to schedule validation"
|
|
5589
|
+
});
|
|
5900
5590
|
}
|
|
5901
|
-
|
|
5902
|
-
return this;
|
|
5591
|
+
return response.data;
|
|
5903
5592
|
}
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
raw(format) {
|
|
5909
|
-
const formats = Array.isArray(format) ? format : [format];
|
|
5910
|
-
const nameMap = {
|
|
5911
|
-
html: "rawHtml",
|
|
5912
|
-
markdown: "rawMarkdown",
|
|
5913
|
-
url: "rawUrl"
|
|
5914
|
-
};
|
|
5915
|
-
const metadataKeyMap = {
|
|
5916
|
-
html: "HTML",
|
|
5917
|
-
markdown: "MARKDOWN",
|
|
5918
|
-
url: "PAGE_URL"
|
|
5919
|
-
};
|
|
5920
|
-
for (const f of formats) {
|
|
5921
|
-
const fieldName = nameMap[f];
|
|
5922
|
-
if (this.fields.some((field) => field.name === fieldName)) {
|
|
5923
|
-
continue;
|
|
5593
|
+
async toggleValidationEnabled(workflowId) {
|
|
5594
|
+
const response = await this.validationApi.v4DataValidationWorkflowsWorkflowIdValidationTogglePut(
|
|
5595
|
+
{
|
|
5596
|
+
workflowId
|
|
5924
5597
|
}
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
metadataKey: metadataKeyMap[f]
|
|
5598
|
+
);
|
|
5599
|
+
if (response.status !== 200 || response.data.error) {
|
|
5600
|
+
throw KadoaHttpException.wrap(response.data, {
|
|
5601
|
+
message: response.data.message || "Failed to toggle validation"
|
|
5930
5602
|
});
|
|
5931
5603
|
}
|
|
5932
|
-
return
|
|
5933
|
-
}
|
|
5934
|
-
/**
|
|
5935
|
-
* Get the fields array (internal use)
|
|
5936
|
-
*/
|
|
5937
|
-
getFields() {
|
|
5938
|
-
return this.fields;
|
|
5939
|
-
}
|
|
5940
|
-
/**
|
|
5941
|
-
* Get the schema name (internal use)
|
|
5942
|
-
*/
|
|
5943
|
-
getSchemaName() {
|
|
5944
|
-
return this.schemaName;
|
|
5945
|
-
}
|
|
5946
|
-
/**
|
|
5947
|
-
* Get the schema ID (internal use)
|
|
5948
|
-
*/
|
|
5949
|
-
getSchemaId() {
|
|
5950
|
-
return this.schemaId;
|
|
5951
|
-
}
|
|
5952
|
-
};
|
|
5953
|
-
var _SchemaBuilder = class _SchemaBuilder extends ExtractionBuilder {
|
|
5954
|
-
constructor(parentBuilder) {
|
|
5955
|
-
super();
|
|
5956
|
-
this.fields = parentBuilder.getFields();
|
|
5957
|
-
this.schemaName = parentBuilder.getSchemaName();
|
|
5958
|
-
this.schemaId = parentBuilder.getSchemaId();
|
|
5604
|
+
return response.data;
|
|
5959
5605
|
}
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5606
|
+
async getLatestValidation(workflowId, jobId) {
|
|
5607
|
+
let response;
|
|
5608
|
+
if (jobId) {
|
|
5609
|
+
response = await this.validationApi.v4DataValidationWorkflowsWorkflowIdJobsJobIdValidationsLatestGet(
|
|
5610
|
+
{
|
|
5611
|
+
workflowId,
|
|
5612
|
+
jobId
|
|
5613
|
+
}
|
|
5614
|
+
);
|
|
5615
|
+
} else {
|
|
5616
|
+
response = await this.validationApi.v4DataValidationWorkflowsWorkflowIdValidationsLatestGet(
|
|
5971
5617
|
{
|
|
5972
|
-
|
|
5973
|
-
details: { name, pattern: "^[A-Za-z0-9]+$" }
|
|
5618
|
+
workflowId
|
|
5974
5619
|
}
|
|
5975
5620
|
);
|
|
5976
5621
|
}
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
code: "VALIDATION_ERROR",
|
|
5981
|
-
details: { name }
|
|
5622
|
+
if (response.status !== 200 || response.data?.error) {
|
|
5623
|
+
throw KadoaHttpException.wrap(response.data, {
|
|
5624
|
+
message: "Failed to get latest validation"
|
|
5982
5625
|
});
|
|
5983
5626
|
}
|
|
5984
|
-
|
|
5985
|
-
if (requiresExample && !options?.example) {
|
|
5986
|
-
throw new KadoaSdkException(
|
|
5987
|
-
`Field "${name}" with type ${dataType} requires an example`,
|
|
5988
|
-
{ code: "VALIDATION_ERROR", details: { name, dataType } }
|
|
5989
|
-
);
|
|
5990
|
-
}
|
|
5991
|
-
this.fields.push({
|
|
5992
|
-
name,
|
|
5993
|
-
description,
|
|
5994
|
-
dataType,
|
|
5995
|
-
fieldType: "SCHEMA",
|
|
5996
|
-
example: options?.example,
|
|
5997
|
-
isKey: options?.isKey
|
|
5998
|
-
});
|
|
5999
|
-
return this;
|
|
5627
|
+
return response.data;
|
|
6000
5628
|
}
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
{
|
|
6012
|
-
code: "VALIDATION_ERROR",
|
|
6013
|
-
details: { name, pattern: "^[A-Za-z0-9]+$" }
|
|
6014
|
-
}
|
|
6015
|
-
);
|
|
5629
|
+
async getValidationAnomalies(validationId) {
|
|
5630
|
+
const response = await this.validationApi.v4DataValidationValidationsValidationIdAnomaliesGet(
|
|
5631
|
+
{
|
|
5632
|
+
validationId
|
|
5633
|
+
}
|
|
5634
|
+
);
|
|
5635
|
+
if (response.status !== 200) {
|
|
5636
|
+
throw KadoaHttpException.wrap(response.data, {
|
|
5637
|
+
message: "Failed to get validation anomalies"
|
|
5638
|
+
});
|
|
6016
5639
|
}
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
5640
|
+
return response.data;
|
|
5641
|
+
}
|
|
5642
|
+
async getValidationAnomaliesByRule(validationId, ruleName) {
|
|
5643
|
+
const response = await this.validationApi.v4DataValidationValidationsValidationIdAnomaliesRulesRuleNameGet(
|
|
5644
|
+
{
|
|
5645
|
+
validationId,
|
|
5646
|
+
ruleName
|
|
5647
|
+
}
|
|
5648
|
+
);
|
|
5649
|
+
if (response.status !== 200) {
|
|
5650
|
+
throw KadoaHttpException.wrap(response.data, {
|
|
5651
|
+
message: "Failed to get validation anomalies by rule"
|
|
6022
5652
|
});
|
|
6023
5653
|
}
|
|
6024
|
-
|
|
6025
|
-
name,
|
|
6026
|
-
description,
|
|
6027
|
-
fieldType: "CLASSIFICATION",
|
|
6028
|
-
categories
|
|
6029
|
-
});
|
|
6030
|
-
return this;
|
|
5654
|
+
return response.data;
|
|
6031
5655
|
}
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
5656
|
+
async waitUntilCompleted(validationId, options) {
|
|
5657
|
+
const result = await pollUntil(
|
|
5658
|
+
async () => {
|
|
5659
|
+
const current = await this.getValidationDetails(validationId);
|
|
5660
|
+
if (current.error) {
|
|
5661
|
+
throw new KadoaSdkException(`Validation failed: ${current.error}`, {
|
|
5662
|
+
code: "VALIDATION_ERROR",
|
|
5663
|
+
details: { validationId, error: current.error }
|
|
5664
|
+
});
|
|
5665
|
+
}
|
|
5666
|
+
return current;
|
|
5667
|
+
},
|
|
5668
|
+
(result2) => result2.completedAt != null,
|
|
5669
|
+
options
|
|
5670
|
+
);
|
|
5671
|
+
return result.result;
|
|
6038
5672
|
}
|
|
6039
5673
|
};
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
];
|
|
6048
|
-
var SchemaBuilder = _SchemaBuilder;
|
|
6049
|
-
|
|
6050
|
-
// src/internal/domains/extraction/services/extraction-builder.service.ts
|
|
6051
|
-
var debug7 = logger.extraction;
|
|
6052
|
-
var ExtractionBuilderService = class {
|
|
6053
|
-
constructor(workflowsCoreService, entityResolverService, dataFetcherService, notificationSetupService) {
|
|
6054
|
-
this.workflowsCoreService = workflowsCoreService;
|
|
6055
|
-
this.entityResolverService = entityResolverService;
|
|
6056
|
-
this.dataFetcherService = dataFetcherService;
|
|
6057
|
-
this.notificationSetupService = notificationSetupService;
|
|
5674
|
+
var ValidationRulesService = class {
|
|
5675
|
+
constructor(client) {
|
|
5676
|
+
this.validationApi = new DataValidationApi(
|
|
5677
|
+
client.configuration,
|
|
5678
|
+
client.baseUrl,
|
|
5679
|
+
client.axiosInstance
|
|
5680
|
+
);
|
|
6058
5681
|
}
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
5682
|
+
async listRules(options) {
|
|
5683
|
+
const response = await this.validationApi.v4DataValidationRulesGet(options);
|
|
5684
|
+
if (response.status !== 200 || response.data.error) {
|
|
5685
|
+
throw KadoaHttpException.wrap(response.data.data, {
|
|
5686
|
+
message: "Failed to list validation rules"
|
|
5687
|
+
});
|
|
5688
|
+
}
|
|
5689
|
+
return response.data;
|
|
6062
5690
|
}
|
|
6063
|
-
|
|
6064
|
-
|
|
5691
|
+
async getRuleById(ruleId) {
|
|
5692
|
+
const response = await this.validationApi.v4DataValidationRulesRuleIdGet({
|
|
5693
|
+
ruleId
|
|
5694
|
+
});
|
|
5695
|
+
if (response.status !== 200 || response.data.error) {
|
|
5696
|
+
throw KadoaHttpException.wrap(response.data.data, {
|
|
5697
|
+
message: "Failed to get validation rule by id"
|
|
5698
|
+
});
|
|
5699
|
+
}
|
|
5700
|
+
return response.data.data;
|
|
6065
5701
|
}
|
|
6066
|
-
|
|
6067
|
-
|
|
5702
|
+
async getRuleByName(name) {
|
|
5703
|
+
const response = await this.validationApi.v4DataValidationRulesGet();
|
|
5704
|
+
if (response.status !== 200 || response.data.error) {
|
|
5705
|
+
throw KadoaHttpException.wrap(response.data.data, {
|
|
5706
|
+
message: "Failed to get validation rule by name"
|
|
5707
|
+
});
|
|
5708
|
+
}
|
|
5709
|
+
return response.data.data?.find((rule) => rule.name === name);
|
|
6068
5710
|
}
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
5711
|
+
async createRule(data) {
|
|
5712
|
+
const response = await this.validationApi.v4DataValidationRulesPost({
|
|
5713
|
+
createRule: data
|
|
5714
|
+
});
|
|
5715
|
+
if (response.status !== 200 || response.data.error) {
|
|
5716
|
+
throw KadoaHttpException.wrap(response.data.data, {
|
|
5717
|
+
message: response.data.message || "Failed to create validation rule"
|
|
5718
|
+
});
|
|
5719
|
+
}
|
|
5720
|
+
return response.data.data;
|
|
6072
5721
|
}
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
5722
|
+
async updateRule(ruleId, updateData) {
|
|
5723
|
+
const response = await this.validationApi.v4DataValidationRulesRuleIdPut({
|
|
5724
|
+
ruleId,
|
|
5725
|
+
updateRule: updateData
|
|
5726
|
+
});
|
|
5727
|
+
if (response.status !== 200 || response.data.error) {
|
|
5728
|
+
throw KadoaHttpException.wrap(response.data.data, {
|
|
5729
|
+
message: response.data.message || "Failed to update validation rule"
|
|
5730
|
+
});
|
|
5731
|
+
}
|
|
5732
|
+
return response.data.data;
|
|
6076
5733
|
}
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
}) {
|
|
6084
|
-
let entity = "ai-detection";
|
|
6085
|
-
if (extraction) {
|
|
6086
|
-
const builder = extraction(new ExtractionBuilder());
|
|
6087
|
-
const schemaId = builder.getSchemaId();
|
|
6088
|
-
const schemaName = builder.getSchemaName();
|
|
6089
|
-
const fields = builder.getFields();
|
|
6090
|
-
if (schemaId) {
|
|
6091
|
-
entity = { schemId: schemaId };
|
|
6092
|
-
} else if (schemaName && fields.length > 0) {
|
|
6093
|
-
entity = { name: schemaName, fields };
|
|
6094
|
-
} else if (fields.length > 0 && !schemaName) {
|
|
6095
|
-
entity = { name: "RawExtraction", fields };
|
|
6096
|
-
} else {
|
|
6097
|
-
entity = "ai-detection";
|
|
6098
|
-
}
|
|
5734
|
+
async disableRule(data) {
|
|
5735
|
+
const response = await this.validationApi.v4DataValidationRulesRuleIdDisablePost(data);
|
|
5736
|
+
if (response.status !== 200 || response.data.error) {
|
|
5737
|
+
throw KadoaHttpException.wrap(response.data.data, {
|
|
5738
|
+
message: response.data.message || "Failed to disable validation rule"
|
|
5739
|
+
});
|
|
6099
5740
|
}
|
|
6100
|
-
|
|
6101
|
-
urls,
|
|
6102
|
-
name,
|
|
6103
|
-
description,
|
|
6104
|
-
navigationMode: navigationMode || "single-page",
|
|
6105
|
-
entity,
|
|
6106
|
-
bypassPreview: false
|
|
6107
|
-
};
|
|
6108
|
-
return this;
|
|
5741
|
+
return response.data.data;
|
|
6109
5742
|
}
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
5743
|
+
async generateRule(data) {
|
|
5744
|
+
const response = await this.validationApi.v4DataValidationRulesActionsGeneratePost({
|
|
5745
|
+
generateRule: data
|
|
5746
|
+
});
|
|
5747
|
+
if (response.status !== 200 || response.data.error) {
|
|
5748
|
+
throw KadoaHttpException.wrap(response.data.data, {
|
|
5749
|
+
message: response.data.message || "Failed to generate validation rule"
|
|
5750
|
+
});
|
|
5751
|
+
}
|
|
5752
|
+
return response.data.data;
|
|
6113
5753
|
}
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
5754
|
+
async generateRules(data) {
|
|
5755
|
+
const response = await this.validationApi.v4DataValidationRulesActionsGenerateRulesPost({
|
|
5756
|
+
generateRules: data
|
|
5757
|
+
});
|
|
5758
|
+
if (response.status !== 200 || response.data.error) {
|
|
5759
|
+
throw KadoaHttpException.wrap(response.data.data, {
|
|
5760
|
+
message: response.data.message || "Failed to generate validation rules"
|
|
5761
|
+
});
|
|
5762
|
+
}
|
|
5763
|
+
return response.data.data;
|
|
6117
5764
|
}
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
5765
|
+
async bulkApproveRules(data) {
|
|
5766
|
+
const response = await this.validationApi.v4DataValidationRulesActionsBulkApprovePost({
|
|
5767
|
+
bulkApproveRules: data
|
|
5768
|
+
});
|
|
5769
|
+
if (response.status !== 200 || response.data.error) {
|
|
5770
|
+
throw KadoaHttpException.wrap(response.data.data, {
|
|
5771
|
+
message: response.data.message || "Failed to bulk approve validation rules"
|
|
5772
|
+
});
|
|
5773
|
+
}
|
|
5774
|
+
return response.data.data;
|
|
6122
5775
|
}
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
5776
|
+
async bulkDeleteRules(data) {
|
|
5777
|
+
const response = await this.validationApi.v4DataValidationRulesActionsBulkDeletePost({
|
|
5778
|
+
bulkDeleteRules: data
|
|
5779
|
+
});
|
|
5780
|
+
if (response.status !== 200 || response.data.error) {
|
|
5781
|
+
throw KadoaHttpException.wrap(response.data.data, {
|
|
5782
|
+
message: response.data.message || "Failed to bulk delete validation rules"
|
|
5783
|
+
});
|
|
6130
5784
|
}
|
|
6131
|
-
return
|
|
6132
|
-
}
|
|
6133
|
-
setLocation(options) {
|
|
6134
|
-
assert__default.default(this._options, "Options are not set");
|
|
6135
|
-
this._options.location = options;
|
|
6136
|
-
return this;
|
|
5785
|
+
return response.data.data;
|
|
6137
5786
|
}
|
|
6138
|
-
async
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
const resolvedEntity = typeof entity === "object" && "schemId" in entity ? void 0 : await this.entityResolverService.resolveEntity(entity, {
|
|
6142
|
-
link: urls[0],
|
|
6143
|
-
location: this._options.location,
|
|
6144
|
-
navigationMode
|
|
5787
|
+
async deleteAllRules(data) {
|
|
5788
|
+
const response = await this.validationApi.v4DataValidationRulesActionsDeleteAllDelete({
|
|
5789
|
+
deleteRuleWithReason: data
|
|
6145
5790
|
});
|
|
6146
|
-
if (
|
|
6147
|
-
throw
|
|
6148
|
-
|
|
6149
|
-
details: { entity }
|
|
5791
|
+
if (response.status !== 200 || response.data.error) {
|
|
5792
|
+
throw KadoaHttpException.wrap(response.data.data, {
|
|
5793
|
+
message: response.data.message || "Failed to delete all validation rules"
|
|
6150
5794
|
});
|
|
6151
5795
|
}
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
5796
|
+
return response.data.data;
|
|
5797
|
+
}
|
|
5798
|
+
};
|
|
5799
|
+
|
|
5800
|
+
// src/domains/workflows/workflows.acl.ts
|
|
5801
|
+
var JobStateEnum = {
|
|
5802
|
+
Finished: "FINISHED",
|
|
5803
|
+
Failed: "FAILED",
|
|
5804
|
+
NotSupported: "NOT_SUPPORTED",
|
|
5805
|
+
FailedInsufficientFunds: "FAILED_INSUFFICIENT_FUNDS"
|
|
5806
|
+
};
|
|
5807
|
+
|
|
5808
|
+
// src/domains/workflows/workflows-core.service.ts
|
|
5809
|
+
var TERMINAL_JOB_STATES = /* @__PURE__ */ new Set([
|
|
5810
|
+
JobStateEnum.Finished,
|
|
5811
|
+
JobStateEnum.Failed,
|
|
5812
|
+
JobStateEnum.NotSupported,
|
|
5813
|
+
JobStateEnum.FailedInsufficientFunds
|
|
5814
|
+
]);
|
|
5815
|
+
var TERMINAL_RUN_STATES = /* @__PURE__ */ new Set([
|
|
5816
|
+
"FINISHED",
|
|
5817
|
+
"SUCCESS",
|
|
5818
|
+
"FAILED",
|
|
5819
|
+
"ERROR",
|
|
5820
|
+
"STOPPED",
|
|
5821
|
+
"CANCELLED"
|
|
5822
|
+
]);
|
|
5823
|
+
var debug6 = logger.workflow;
|
|
5824
|
+
var WorkflowsCoreService = class {
|
|
5825
|
+
constructor(workflowsApi) {
|
|
5826
|
+
this.workflowsApi = workflowsApi;
|
|
5827
|
+
}
|
|
5828
|
+
async create(input) {
|
|
5829
|
+
const request = {
|
|
5830
|
+
urls: input.urls,
|
|
5831
|
+
name: input.name,
|
|
5832
|
+
schemaId: input.schemaId,
|
|
5833
|
+
description: input.description,
|
|
5834
|
+
navigationMode: input.navigationMode,
|
|
5835
|
+
entity: input.entity,
|
|
5836
|
+
fields: input.fields,
|
|
5837
|
+
bypassPreview: input.bypassPreview ?? true,
|
|
5838
|
+
tags: input.tags,
|
|
5839
|
+
interval: input.interval,
|
|
5840
|
+
monitoring: input.monitoring,
|
|
5841
|
+
location: input.location,
|
|
5842
|
+
autoStart: input.autoStart,
|
|
5843
|
+
schedules: input.schedules
|
|
5844
|
+
};
|
|
5845
|
+
const response = await this.workflowsApi.v4WorkflowsPost({
|
|
5846
|
+
createWorkflowBody: request
|
|
6164
5847
|
});
|
|
6165
|
-
|
|
6166
|
-
|
|
6167
|
-
|
|
6168
|
-
|
|
5848
|
+
const workflowId = response.data?.workflowId;
|
|
5849
|
+
if (!workflowId) {
|
|
5850
|
+
throw new KadoaSdkException(ERROR_MESSAGES.NO_WORKFLOW_ID, {
|
|
5851
|
+
code: "INTERNAL_ERROR",
|
|
5852
|
+
details: {
|
|
5853
|
+
response: response.data
|
|
5854
|
+
}
|
|
6169
5855
|
});
|
|
6170
5856
|
}
|
|
6171
|
-
|
|
6172
|
-
return this;
|
|
5857
|
+
return { id: workflowId };
|
|
6173
5858
|
}
|
|
6174
|
-
async
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
{ variables: options?.variables, limit: options?.limit }
|
|
6180
|
-
);
|
|
6181
|
-
debug7("Job started: %O", startedJob);
|
|
6182
|
-
this._jobId = startedJob.jobId;
|
|
6183
|
-
const finishedJob = await this.workflowsCoreService.waitForJobCompletion(
|
|
6184
|
-
this._workflowId,
|
|
6185
|
-
startedJob.jobId
|
|
6186
|
-
);
|
|
6187
|
-
debug7("Job finished: %O", finishedJob);
|
|
6188
|
-
return this;
|
|
5859
|
+
async get(id) {
|
|
5860
|
+
const response = await this.workflowsApi.v4WorkflowsWorkflowIdGet({
|
|
5861
|
+
workflowId: id
|
|
5862
|
+
});
|
|
5863
|
+
return response.data;
|
|
6189
5864
|
}
|
|
6190
|
-
async
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
5865
|
+
async list(filters) {
|
|
5866
|
+
const response = await this.workflowsApi.v4WorkflowsGet(filters);
|
|
5867
|
+
return response.data?.workflows ?? [];
|
|
5868
|
+
}
|
|
5869
|
+
async getByName(name) {
|
|
5870
|
+
const response = await this.workflowsApi.v4WorkflowsGet({
|
|
5871
|
+
search: name
|
|
5872
|
+
});
|
|
5873
|
+
return response.data?.workflows?.[0];
|
|
5874
|
+
}
|
|
5875
|
+
async cancel(id) {
|
|
5876
|
+
await this.workflowsApi.v4WorkflowsWorkflowIdDelete({
|
|
5877
|
+
workflowId: id
|
|
5878
|
+
});
|
|
5879
|
+
}
|
|
5880
|
+
async resume(id) {
|
|
5881
|
+
await this.workflowsApi.v4WorkflowsWorkflowIdResumePut({
|
|
5882
|
+
workflowId: id
|
|
5883
|
+
});
|
|
5884
|
+
}
|
|
5885
|
+
/**
|
|
5886
|
+
* Wait for a workflow to reach the target state or a terminal state if no target state is provided
|
|
5887
|
+
*/
|
|
5888
|
+
async wait(id, options) {
|
|
5889
|
+
let last;
|
|
5890
|
+
const result = await pollUntil(
|
|
5891
|
+
async () => {
|
|
5892
|
+
const current = await this.get(id);
|
|
5893
|
+
if (last?.state !== current.state || last?.runState !== current.runState) {
|
|
5894
|
+
debug6(
|
|
5895
|
+
"workflow %s state: [workflowState: %s, jobState: %s]",
|
|
5896
|
+
id,
|
|
5897
|
+
current.state,
|
|
5898
|
+
current.runState
|
|
5899
|
+
);
|
|
5900
|
+
}
|
|
5901
|
+
last = current;
|
|
5902
|
+
return current;
|
|
5903
|
+
},
|
|
5904
|
+
(current) => {
|
|
5905
|
+
if (options?.targetState && current.state === options.targetState) {
|
|
5906
|
+
return true;
|
|
5907
|
+
}
|
|
5908
|
+
if (current.runState && TERMINAL_RUN_STATES.has(current.runState.toUpperCase()) && current.state !== "QUEUED") {
|
|
5909
|
+
return true;
|
|
5910
|
+
}
|
|
5911
|
+
return false;
|
|
5912
|
+
},
|
|
5913
|
+
options
|
|
6196
5914
|
);
|
|
6197
|
-
|
|
6198
|
-
|
|
5915
|
+
return result.result;
|
|
5916
|
+
}
|
|
5917
|
+
/**
|
|
5918
|
+
* Run a workflow with variables and optional limit
|
|
5919
|
+
*/
|
|
5920
|
+
async runWorkflow(workflowId, input) {
|
|
5921
|
+
const response = await this.workflowsApi.v4WorkflowsWorkflowIdRunPut({
|
|
5922
|
+
workflowId,
|
|
5923
|
+
v4WorkflowsWorkflowIdRunPutRequest: {
|
|
5924
|
+
variables: input.variables,
|
|
5925
|
+
limit: input.limit
|
|
5926
|
+
}
|
|
5927
|
+
});
|
|
5928
|
+
const jobId = response.data?.jobId;
|
|
5929
|
+
if (!jobId) {
|
|
5930
|
+
throw new KadoaSdkException(ERROR_MESSAGES.NO_WORKFLOW_ID, {
|
|
5931
|
+
code: "INTERNAL_ERROR",
|
|
5932
|
+
details: {
|
|
5933
|
+
response: response.data
|
|
5934
|
+
}
|
|
5935
|
+
});
|
|
5936
|
+
}
|
|
6199
5937
|
return {
|
|
6200
|
-
|
|
6201
|
-
|
|
5938
|
+
jobId,
|
|
5939
|
+
message: response.data?.message,
|
|
5940
|
+
status: response.data?.status
|
|
6202
5941
|
};
|
|
6203
5942
|
}
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
limit: options.limit ?? 100,
|
|
6212
|
-
...options
|
|
5943
|
+
/**
|
|
5944
|
+
* Get job status directly without polling workflow details
|
|
5945
|
+
*/
|
|
5946
|
+
async getJobStatus(workflowId, jobId) {
|
|
5947
|
+
const response = await this.workflowsApi.v4WorkflowsWorkflowIdJobsJobIdGet({
|
|
5948
|
+
workflowId,
|
|
5949
|
+
jobId
|
|
6213
5950
|
});
|
|
5951
|
+
return response.data;
|
|
6214
5952
|
}
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
5953
|
+
/**
|
|
5954
|
+
* Wait for a job to reach the target state or a terminal state
|
|
5955
|
+
*/
|
|
5956
|
+
async waitForJobCompletion(workflowId, jobId, options) {
|
|
5957
|
+
let last;
|
|
5958
|
+
const result = await pollUntil(
|
|
5959
|
+
async () => {
|
|
5960
|
+
const current = await this.getJobStatus(workflowId, jobId);
|
|
5961
|
+
if (last?.state !== current.state) {
|
|
5962
|
+
debug6("job %s state: %s", jobId, current.state);
|
|
5963
|
+
}
|
|
5964
|
+
last = current;
|
|
5965
|
+
return current;
|
|
5966
|
+
},
|
|
5967
|
+
(current) => {
|
|
5968
|
+
if (options?.targetStatus && current.state === options.targetStatus) {
|
|
5969
|
+
return true;
|
|
5970
|
+
}
|
|
5971
|
+
if (current.state && TERMINAL_JOB_STATES.has(current.state)) {
|
|
5972
|
+
return true;
|
|
5973
|
+
}
|
|
5974
|
+
return false;
|
|
5975
|
+
},
|
|
5976
|
+
options
|
|
5977
|
+
);
|
|
5978
|
+
return result.result;
|
|
6223
5979
|
}
|
|
6224
5980
|
};
|
|
6225
5981
|
|
|
5982
|
+
// src/domains/validation/validation.facade.ts
|
|
5983
|
+
function createValidationDomain(core, rules) {
|
|
5984
|
+
return {
|
|
5985
|
+
rules,
|
|
5986
|
+
schedule: (workflowId, jobId) => core.scheduleValidation(workflowId, jobId),
|
|
5987
|
+
listWorkflowValidations: (filters) => core.listWorkflowValidations(filters),
|
|
5988
|
+
getValidationDetails: (validationId) => core.getValidationDetails(validationId),
|
|
5989
|
+
toggleEnabled: (workflowId) => core.toggleValidationEnabled(workflowId),
|
|
5990
|
+
getLatest: (workflowId, jobId) => core.getLatestValidation(workflowId, jobId),
|
|
5991
|
+
getAnomalies: (validationId) => core.getValidationAnomalies(validationId),
|
|
5992
|
+
getAnomaliesByRule: (validationId, ruleName) => core.getValidationAnomaliesByRule(validationId, ruleName),
|
|
5993
|
+
waitUntilCompleted: (validationId, options) => core.waitUntilCompleted(validationId, options)
|
|
5994
|
+
};
|
|
5995
|
+
}
|
|
5996
|
+
|
|
6226
5997
|
// src/kadoa-client.ts
|
|
6227
5998
|
var KadoaClient = class {
|
|
6228
5999
|
constructor(config) {
|
|
@@ -6299,7 +6070,9 @@ var KadoaClient = class {
|
|
|
6299
6070
|
workflowsCoreService,
|
|
6300
6071
|
dataFetcherService,
|
|
6301
6072
|
entityResolverService,
|
|
6302
|
-
channelSetupService
|
|
6073
|
+
channelSetupService,
|
|
6074
|
+
channelsService,
|
|
6075
|
+
settingsService
|
|
6303
6076
|
);
|
|
6304
6077
|
this._extractionBuilderService = new ExtractionBuilderService(
|
|
6305
6078
|
workflowsCoreService,
|
|
@@ -6307,22 +6080,19 @@ var KadoaClient = class {
|
|
|
6307
6080
|
dataFetcherService,
|
|
6308
6081
|
channelSetupService
|
|
6309
6082
|
);
|
|
6310
|
-
this.user =
|
|
6311
|
-
this.extraction =
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
channelSetupService
|
|
6324
|
-
);
|
|
6325
|
-
this.validation = new ValidationModule(coreService, rulesService);
|
|
6083
|
+
this.user = userService;
|
|
6084
|
+
this.extraction = extractionService;
|
|
6085
|
+
this.workflow = workflowsCoreService;
|
|
6086
|
+
this.schema = schemasService;
|
|
6087
|
+
this.notification = {
|
|
6088
|
+
channels: channelsService,
|
|
6089
|
+
settings: settingsService,
|
|
6090
|
+
setup: channelSetupService,
|
|
6091
|
+
configure: (options) => channelSetupService.setup(options),
|
|
6092
|
+
setupForWorkflow: (request) => channelSetupService.setupForWorkflow(request),
|
|
6093
|
+
setupForWorkspace: (request) => channelSetupService.setupForWorkspace(request)
|
|
6094
|
+
};
|
|
6095
|
+
this.validation = createValidationDomain(coreService, rulesService);
|
|
6326
6096
|
if (config.enableRealtime && config.realtimeConfig?.autoConnect !== false) {
|
|
6327
6097
|
this.connectRealtime();
|
|
6328
6098
|
}
|
|
@@ -6461,12 +6231,28 @@ var KadoaClient = class {
|
|
|
6461
6231
|
}
|
|
6462
6232
|
};
|
|
6463
6233
|
|
|
6234
|
+
exports.DataFetcherService = DataFetcherService;
|
|
6464
6235
|
exports.ERROR_MESSAGES = ERROR_MESSAGES;
|
|
6236
|
+
exports.EntityResolverService = EntityResolverService;
|
|
6237
|
+
exports.ExtractionBuilderService = ExtractionBuilderService;
|
|
6238
|
+
exports.ExtractionService = ExtractionService;
|
|
6239
|
+
exports.FetchDataOptions = FetchDataOptions;
|
|
6465
6240
|
exports.KadoaClient = KadoaClient;
|
|
6466
6241
|
exports.KadoaHttpException = KadoaHttpException;
|
|
6467
6242
|
exports.KadoaSdkException = KadoaSdkException;
|
|
6468
|
-
exports.
|
|
6469
|
-
exports.
|
|
6243
|
+
exports.NotificationChannelType = NotificationChannelType;
|
|
6244
|
+
exports.NotificationChannelsService = NotificationChannelsService;
|
|
6245
|
+
exports.NotificationSettingsEventTypeEnum = V5NotificationsSettingsGetEventTypeEnum;
|
|
6246
|
+
exports.NotificationSettingsService = NotificationSettingsService;
|
|
6247
|
+
exports.NotificationSetupService = NotificationSetupService;
|
|
6248
|
+
exports.Realtime = Realtime;
|
|
6249
|
+
exports.SchemaBuilder = SchemaBuilder;
|
|
6250
|
+
exports.SchemaFieldDataType = SchemaFieldDataType;
|
|
6251
|
+
exports.SchemasService = SchemasService;
|
|
6252
|
+
exports.UserService = UserService;
|
|
6253
|
+
exports.ValidationCoreService = ValidationCoreService;
|
|
6254
|
+
exports.ValidationRulesService = ValidationRulesService;
|
|
6255
|
+
exports.WorkflowsCoreService = WorkflowsCoreService;
|
|
6470
6256
|
exports.pollUntil = pollUntil;
|
|
6471
6257
|
//# sourceMappingURL=index.js.map
|
|
6472
6258
|
//# sourceMappingURL=index.js.map
|