@transai/connector-runner-api 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/index.cjs +2 -0
- package/index.cjs.map +7 -0
- package/index.js +2 -0
- package/index.js.map +7 -0
- package/libs/connector-runner-api/src/lib/connector-runner-api.d.ts +8 -0
- package/libs/connector-runner-api/src/lib/extractor.service.d.ts +9 -0
- package/libs/connector-runner-api/src/lib/http-client-authentication.d.ts +8 -0
- package/libs/connector-runner-api/src/lib/result.handler.d.ts +7 -0
- package/libs/connector-runner-api/src/lib/types.d.ts +30 -0
- package/libs/connector-runtime-sdk/src/index.d.ts +3 -0
- package/libs/connector-runtime-sdk/src/lib/connector-runtime.d.ts +16 -0
- package/libs/connector-runtime-sdk/src/lib/connector-runtime.interface.d.ts +5 -0
- package/libs/connector-runtime-sdk/src/lib/sdk/files.sdk.interface.d.ts +18 -0
- package/libs/connector-runtime-sdk/src/lib/sdk/http-client.interface.d.ts +38 -0
- package/libs/connector-runtime-sdk/src/lib/sdk/index.d.ts +10 -0
- package/libs/connector-runtime-sdk/src/lib/sdk/logger.sdk.interface.d.ts +7 -0
- package/libs/connector-runtime-sdk/src/lib/sdk/offset-store.sdk.interface.d.ts +12 -0
- package/libs/connector-runtime-sdk/src/lib/sdk/processing.sdk.interface.d.ts +13 -0
- package/libs/connector-runtime-sdk/src/lib/sdk/receiver.sdk.interface.d.ts +14 -0
- package/libs/connector-runtime-sdk/src/lib/sdk/sdk.interface.d.ts +31 -0
- package/libs/connector-runtime-sdk/src/lib/sdk/sender.sdk.interface.d.ts +22 -0
- package/libs/connector-runtime-sdk/src/lib/sdk/telemetry.sdk.interface.d.ts +15 -0
- package/libs/connector-runtime-sdk/src/lib/sdk/templating.sdk.interface.d.ts +12 -0
- package/libs/types/src/index.d.ts +7 -0
- package/libs/types/src/lib/cube-query-config.types.d.ts +20 -0
- package/libs/types/src/lib/file-action.types.d.ts +5 -0
- package/libs/types/src/lib/http-status-codes.enum.d.ts +64 -0
- package/libs/types/src/lib/management-api/action-definition.interface.d.ts +12 -0
- package/libs/types/src/lib/management-api/chart.interface.d.ts +9 -0
- package/libs/types/src/lib/management-api/connector/connector.interface.d.ts +140 -0
- package/libs/types/src/lib/management-api/connector/connectors.interface.d.ts +126 -0
- package/libs/types/src/lib/management-api/connector-orchestrator-config.interface.d.ts +14 -0
- package/libs/types/src/lib/management-api/cube-dataset.interface.d.ts +93 -0
- package/libs/types/src/lib/management-api/dashboard.interface.d.ts +35 -0
- package/libs/types/src/lib/management-api/dataset/collection.interface.d.ts +16 -0
- package/libs/types/src/lib/management-api/dataset/dataset-record.interface.d.ts +5 -0
- package/libs/types/src/lib/management-api/dataset/dataset.interface.d.ts +730 -0
- package/libs/types/src/lib/management-api/dataset/datasets.interface.d.ts +710 -0
- package/libs/types/src/lib/management-api/dataset/dimension.interface.d.ts +205 -0
- package/libs/types/src/lib/management-api/dataset/dimensions.interface.d.ts +186 -0
- package/libs/types/src/lib/management-api/dataset/filter-group.interface.d.ts +8 -0
- package/libs/types/src/lib/management-api/dataset/filter.interface.d.ts +34 -0
- package/libs/types/src/lib/management-api/dataset/filters.interface.d.ts +7 -0
- package/libs/types/src/lib/management-api/dataset/measure.interface.d.ts +65 -0
- package/libs/types/src/lib/management-api/dataset/measures.interface.d.ts +56 -0
- package/libs/types/src/lib/management-api/dataset/meta.interface.d.ts +9 -0
- package/libs/types/src/lib/management-api/dataset/pre-aggregate.interface.d.ts +69 -0
- package/libs/types/src/lib/management-api/dataset/pre-aggregations.interface.d.ts +54 -0
- package/libs/types/src/lib/management-api/dataset/relation.interface.d.ts +40 -0
- package/libs/types/src/lib/management-api/dataset/relations.interface.d.ts +36 -0
- package/libs/types/src/lib/management-api/dataset/segment.interface.d.ts +45 -0
- package/libs/types/src/lib/management-api/dataset/segments.interface.d.ts +43 -0
- package/libs/types/src/lib/management-api/dataset/switch.interface.d.ts +70 -0
- package/libs/types/src/lib/management-api/dataset/when-item.interface.d.ts +41 -0
- package/libs/types/src/lib/management-api/dataset/when-items.interface.d.ts +40 -0
- package/libs/types/src/lib/management-api/event-origin.interface.d.ts +24 -0
- package/libs/types/src/lib/management-api/index.d.ts +39 -0
- package/libs/types/src/lib/management-api/semantic-trigger/custom-cron-trigger-record.interface.d.ts +6 -0
- package/libs/types/src/lib/management-api/semantic-trigger/index.d.ts +6 -0
- package/libs/types/src/lib/management-api/semantic-trigger/semantic-trigger-filter.interface.d.ts +20 -0
- package/libs/types/src/lib/management-api/semantic-trigger/semantic-trigger-filters.interface.d.ts +18 -0
- package/libs/types/src/lib/management-api/semantic-trigger/semantic-trigger-record.interface.d.ts +6 -0
- package/libs/types/src/lib/management-api/semantic-trigger/semantic-trigger.interface.d.ts +75 -0
- package/libs/types/src/lib/management-api/semantic-trigger/semantic-triggers.interface.d.ts +62 -0
- package/libs/types/src/lib/management-api/template-implementation-overrides.interface.d.ts +1152 -0
- package/libs/types/src/lib/management-api/template-implementation.interface.d.ts +2860 -0
- package/libs/types/src/lib/management-api/template.interface.d.ts +1191 -0
- package/libs/types/src/lib/management-api/tenant.interface.d.ts +8 -0
- package/libs/types/src/lib/management-api/type-enums.d.ts +85 -0
- package/libs/types/src/lib/management-api/web/generic-filter.dto.d.ts +37 -0
- package/libs/types/src/lib/management-api/web/index.d.ts +2 -0
- package/libs/types/src/lib/management-api/web/paginated-response.interface.d.ts +17 -0
- package/libs/types/src/lib/management-api/workflow/action.interface.d.ts +85 -0
- package/libs/types/src/lib/management-api/workflow/index.d.ts +6 -0
- package/libs/types/src/lib/management-api/workflow/offset.interface.d.ts +14 -0
- package/libs/types/src/lib/management-api/workflow/trigger-types.interface.d.ts +14 -0
- package/libs/types/src/lib/management-api/workflow/workflow-definition.interface.d.ts +57 -0
- package/libs/types/src/lib/management-api/workflow/workflow-run.d.ts +70 -0
- package/libs/types/src/lib/management-api/workflow/workflow.drawing.d.ts +102 -0
- package/libs/types/src/lib/message.types.d.ts +59 -0
- package/libs/types/src/lib/response.types.d.ts +27 -0
- package/libs/types/src/lib/types.d.ts +116 -0
- package/package.json +1 -1
- package/.eslintrc.json +0 -18
- package/jest.config.ts +0 -10
- package/project.json +0 -29
- package/src/lib/connector-runner-api.ts +0 -53
- package/src/lib/extractor.service.spec.ts +0 -90
- package/src/lib/extractor.service.ts +0 -97
- package/src/lib/http-client-authentication.ts +0 -108
- package/src/lib/result.handler.spec.ts +0 -135
- package/src/lib/result.handler.ts +0 -100
- package/src/lib/types.ts +0 -38
- package/tsconfig.json +0 -22
- package/tsconfig.lib.json +0 -10
- package/tsconfig.spec.json +0 -14
- /package/{src/index.ts → libs/connector-runner-api/src/index.d.ts} +0 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export interface MessageMonitorConfig {
|
|
2
|
+
type: 'in-memory' | 'redis' | 'disabled';
|
|
3
|
+
}
|
|
4
|
+
export declare enum ConfiguredConnectorTypes {
|
|
5
|
+
API = "api",
|
|
6
|
+
API_SINK = "api-sink",
|
|
7
|
+
API_SOURCE = "api-source",
|
|
8
|
+
DUMMY_NODE = "dummy-node",
|
|
9
|
+
FILE_COPY = "file-copy",
|
|
10
|
+
FILE = "file",
|
|
11
|
+
FILE_SINK = "file-sink",
|
|
12
|
+
FILE_SOURCE = "file-source",
|
|
13
|
+
SAMBA_SINK = "samba-sink",
|
|
14
|
+
SAMBA_SOURCE = "samba-source",
|
|
15
|
+
SQL_SINK = "sql-sink",
|
|
16
|
+
SQL_SOURCE = "sql-source",
|
|
17
|
+
MQTT = "mqtt",
|
|
18
|
+
CUBE_QUERY_RUNNER = "cube-query-runner",
|
|
19
|
+
FACTORY_NEBULA_SOURCE = "factory-nebula-source",
|
|
20
|
+
BYSTRONIC = "bystronic",
|
|
21
|
+
IMAP_SOURCE = "imap-source",
|
|
22
|
+
IMAP_SINK = "imap-sink",
|
|
23
|
+
OPCUA_SOURCE = "opcua-source",
|
|
24
|
+
OPCUA_SINK = "opcua-sink",
|
|
25
|
+
AI_AGENT = "ai-agent",
|
|
26
|
+
MICROSOFT_OFFICE365_EMAIL = "microsoft-office365-email",
|
|
27
|
+
MKG = "mkg"
|
|
28
|
+
}
|
|
29
|
+
export interface ConnectorConfig {
|
|
30
|
+
type: ConfiguredConnectorTypes;
|
|
31
|
+
identifier: string;
|
|
32
|
+
}
|
|
33
|
+
export interface RedisMessageMonitorConfig extends MessageMonitorConfig {
|
|
34
|
+
type: 'redis';
|
|
35
|
+
url: string;
|
|
36
|
+
ttl?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface InMemoryMessageMonitorConfig extends MessageMonitorConfig {
|
|
39
|
+
type: 'in-memory';
|
|
40
|
+
messagesToKeep: number;
|
|
41
|
+
}
|
|
42
|
+
export interface DisabledMessageMonitorConfig extends MessageMonitorConfig {
|
|
43
|
+
type: 'disabled';
|
|
44
|
+
}
|
|
45
|
+
export interface TopicRegex {
|
|
46
|
+
pattern: string;
|
|
47
|
+
flags: string;
|
|
48
|
+
}
|
|
49
|
+
export interface FileRegex {
|
|
50
|
+
pattern: string;
|
|
51
|
+
flags: string;
|
|
52
|
+
}
|
|
53
|
+
export declare function isTopicRegex(obj: TopicRegex | string): obj is TopicRegex;
|
|
54
|
+
export interface CubeConfigHeaders {
|
|
55
|
+
Authorization: string;
|
|
56
|
+
}
|
|
57
|
+
export interface CubeConfig {
|
|
58
|
+
auth0_client_secret?: string;
|
|
59
|
+
auth0_client_id?: string;
|
|
60
|
+
auth0_audience?: string;
|
|
61
|
+
auth0_token_url?: string;
|
|
62
|
+
authorization?: string;
|
|
63
|
+
apiUrl: string;
|
|
64
|
+
headers?: CubeConfigHeaders;
|
|
65
|
+
redis_url?: string;
|
|
66
|
+
}
|
|
67
|
+
export declare function isCubeConfigType(obj: CubeConfig): obj is CubeConfig;
|
|
68
|
+
export interface AwsKafkaSaslConfig {
|
|
69
|
+
region?: string;
|
|
70
|
+
accessKeyId?: string;
|
|
71
|
+
secretAccessKey?: string;
|
|
72
|
+
mechanism: 'aws';
|
|
73
|
+
}
|
|
74
|
+
export declare function isAwsKafkaSalsConfig(obj: AwsKafkaSaslConfig): obj is AwsKafkaSaslConfig;
|
|
75
|
+
export interface DatabaseConfig {
|
|
76
|
+
uri: string;
|
|
77
|
+
ssl?: boolean;
|
|
78
|
+
tenantPassword?: string;
|
|
79
|
+
}
|
|
80
|
+
export interface ActionConfig {
|
|
81
|
+
timeSensitive: boolean;
|
|
82
|
+
}
|
|
83
|
+
export interface KafkaBrokerConfig {
|
|
84
|
+
groupId: string;
|
|
85
|
+
clientId: string;
|
|
86
|
+
brokers: Array<string>;
|
|
87
|
+
consumerTopics?: Array<string | TopicRegex>;
|
|
88
|
+
sasl?: AwsKafkaSaslConfig;
|
|
89
|
+
intervalCheckForNewTopics?: number;
|
|
90
|
+
disableLogs?: boolean;
|
|
91
|
+
autoCommitThreshold?: number;
|
|
92
|
+
autoCommitInterval?: number;
|
|
93
|
+
partitionsConsumedConcurrently?: number;
|
|
94
|
+
messageMonitor?: RedisMessageMonitorConfig | InMemoryMessageMonitorConfig | DisabledMessageMonitorConfig;
|
|
95
|
+
useConfluentLibrary?: boolean;
|
|
96
|
+
newConsumerProtocol?: boolean;
|
|
97
|
+
}
|
|
98
|
+
export declare function isKafkaBrokerConfigType(obj: KafkaBrokerConfig): obj is KafkaBrokerConfig;
|
|
99
|
+
export declare function isActionConfigType(obj: any): obj is ActionConfig;
|
|
100
|
+
export declare function isDatabaseConfigType(obj: DatabaseConfig): obj is DatabaseConfig;
|
|
101
|
+
export interface BaseConnectorConfig {
|
|
102
|
+
processIdentifier: string;
|
|
103
|
+
tenantIdentifier: string;
|
|
104
|
+
datasourceIdentifier: string;
|
|
105
|
+
kafka: KafkaBrokerConfig;
|
|
106
|
+
action?: ActionConfig;
|
|
107
|
+
}
|
|
108
|
+
export declare function isBaseConnectorConfigType(obj: BaseConnectorConfig): obj is BaseConnectorConfig;
|
|
109
|
+
export interface AiAgentConfig {
|
|
110
|
+
openai: {
|
|
111
|
+
apiKey: string;
|
|
112
|
+
model: 'gpt-3.5-turbo' | 'gpt-4' | 'gpt-4-turbo' | 'gpt-4o' | 'gpt-4o-mini' | 'o1-preview' | 'o1-mini';
|
|
113
|
+
temperature?: number;
|
|
114
|
+
timeout?: number;
|
|
115
|
+
};
|
|
116
|
+
}
|
package/package.json
CHANGED
package/.eslintrc.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": ["../../.eslintrc.json"],
|
|
3
|
-
"ignorePatterns": ["!**/*"],
|
|
4
|
-
"overrides": [
|
|
5
|
-
{
|
|
6
|
-
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
|
7
|
-
"rules": {}
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
"files": ["*.ts", "*.tsx"],
|
|
11
|
-
"rules": {}
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"files": ["*.js", "*.jsx"],
|
|
15
|
-
"rules": {}
|
|
16
|
-
}
|
|
17
|
-
]
|
|
18
|
-
}
|
package/jest.config.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
displayName: 'connector-runner-api',
|
|
3
|
-
preset: '../../jest.preset.js',
|
|
4
|
-
testEnvironment: 'node',
|
|
5
|
-
transform: {
|
|
6
|
-
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
|
7
|
-
},
|
|
8
|
-
moduleFileExtensions: ['ts', 'js', 'html'],
|
|
9
|
-
coverageDirectory: '../../coverage/libs/connector-runner-api',
|
|
10
|
-
};
|
package/project.json
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "connector-runner-api",
|
|
3
|
-
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"sourceRoot": "libs/connector-runner-api/src",
|
|
5
|
-
"projectType": "library",
|
|
6
|
-
"tags": [
|
|
7
|
-
"connector:runner",
|
|
8
|
-
"connector:runner-sdk",
|
|
9
|
-
"connector:api",
|
|
10
|
-
"connector:source",
|
|
11
|
-
"provider:@transai"
|
|
12
|
-
],
|
|
13
|
-
"targets": {
|
|
14
|
-
"build": {
|
|
15
|
-
"executor": "@transai/tools:connector",
|
|
16
|
-
"outputs": ["{options.outputPath}"]
|
|
17
|
-
},
|
|
18
|
-
"lint": {
|
|
19
|
-
"executor": "@nx/eslint:lint"
|
|
20
|
-
},
|
|
21
|
-
"test": {
|
|
22
|
-
"executor": "@nx/jest:jest",
|
|
23
|
-
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
|
24
|
-
"options": {
|
|
25
|
-
"jestConfig": "libs/connector-runner-api/jest.config.ts"
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ConnectorRuntimeSDK,
|
|
3
|
-
ConnectorSDKInterface,
|
|
4
|
-
HttpClientSDKInterface,
|
|
5
|
-
} from '@transai/connector-runtime-sdk';
|
|
6
|
-
import { ConnectorInterface } from '@xip-online-data/types';
|
|
7
|
-
|
|
8
|
-
import { ExtractorService } from './extractor.service';
|
|
9
|
-
import { HttpClientAuthentication } from './http-client-authentication';
|
|
10
|
-
import { ResultHandler } from './result.handler';
|
|
11
|
-
import { ConnectorConfig } from './types';
|
|
12
|
-
|
|
13
|
-
export class ConnectorRunnerApi extends ConnectorRuntimeSDK<ConnectorConfig> {
|
|
14
|
-
readonly #httpClient?: HttpClientSDKInterface = undefined;
|
|
15
|
-
|
|
16
|
-
constructor(
|
|
17
|
-
connector: ConnectorInterface,
|
|
18
|
-
connectorSDK: ConnectorSDKInterface,
|
|
19
|
-
) {
|
|
20
|
-
super(connector, connectorSDK);
|
|
21
|
-
|
|
22
|
-
const { config } = this.connectorSDK;
|
|
23
|
-
if (config.url) {
|
|
24
|
-
this.#httpClient = this.connectorSDK
|
|
25
|
-
.httpClient({
|
|
26
|
-
baseUrl: config.url,
|
|
27
|
-
})
|
|
28
|
-
.setRequestOptionsFormatter(
|
|
29
|
-
HttpClientAuthentication.createForAuthConfig(
|
|
30
|
-
config,
|
|
31
|
-
this.connectorSDK.httpClient(),
|
|
32
|
-
),
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
override init = async (): Promise<void> => {
|
|
38
|
-
const { config } = this.connectorSDK;
|
|
39
|
-
const resultHandler = new ResultHandler(this.connectorSDK);
|
|
40
|
-
|
|
41
|
-
(config.apiCalls ?? []).forEach((apiConfig) => {
|
|
42
|
-
this.connectorSDK.processing.registerInterval(
|
|
43
|
-
apiConfig.interval,
|
|
44
|
-
new ExtractorService(
|
|
45
|
-
this.connectorSDK,
|
|
46
|
-
apiConfig,
|
|
47
|
-
resultHandler,
|
|
48
|
-
this.#httpClient,
|
|
49
|
-
),
|
|
50
|
-
);
|
|
51
|
-
});
|
|
52
|
-
};
|
|
53
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CompileDelegate,
|
|
3
|
-
ConnectorSDKInterface,
|
|
4
|
-
HttpClientSDKInterface,
|
|
5
|
-
} from '@transai/connector-runtime-sdk';
|
|
6
|
-
|
|
7
|
-
import { ExtractorService } from './extractor.service';
|
|
8
|
-
import { ResultHandler } from './result.handler';
|
|
9
|
-
import { ConnectorConfig } from './types';
|
|
10
|
-
|
|
11
|
-
describe('ExtractorService', () => {
|
|
12
|
-
let service: ExtractorService;
|
|
13
|
-
|
|
14
|
-
const callConfig = {
|
|
15
|
-
name: 'TestCall',
|
|
16
|
-
interval: 60,
|
|
17
|
-
offsetFilePrefix: 'test_offset',
|
|
18
|
-
url: 'https://localhost:443',
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const httpClientMock = {
|
|
22
|
-
request: jest.fn().mockResolvedValue({
|
|
23
|
-
status: 200,
|
|
24
|
-
data: 'some-result-data',
|
|
25
|
-
}),
|
|
26
|
-
setRequestOptionsFormatter: jest.fn().mockReturnThis(),
|
|
27
|
-
} as unknown as HttpClientSDKInterface;
|
|
28
|
-
let sdkMock: ConnectorSDKInterface<ConnectorConfig>;
|
|
29
|
-
let resultHandlerMock: ResultHandler;
|
|
30
|
-
|
|
31
|
-
beforeEach(() => {
|
|
32
|
-
sdkMock = {
|
|
33
|
-
logger: {
|
|
34
|
-
info: jest.fn(),
|
|
35
|
-
debug: jest.fn(),
|
|
36
|
-
error: jest.fn(),
|
|
37
|
-
verbose: jest.fn(),
|
|
38
|
-
warn: jest.fn(),
|
|
39
|
-
},
|
|
40
|
-
offsetStore: {
|
|
41
|
-
getOffset: jest.fn().mockResolvedValue({
|
|
42
|
-
id: 0,
|
|
43
|
-
timestamp: new Date().getTime(),
|
|
44
|
-
rawTimestamp: new Date().toISOString(),
|
|
45
|
-
isoDate: new Date().toISOString(),
|
|
46
|
-
}),
|
|
47
|
-
},
|
|
48
|
-
templating: {
|
|
49
|
-
compile: jest
|
|
50
|
-
.fn()
|
|
51
|
-
.mockImplementation(
|
|
52
|
-
(input) =>
|
|
53
|
-
jest.fn().mockReturnValue(`compiled-${input}`) as CompileDelegate,
|
|
54
|
-
),
|
|
55
|
-
},
|
|
56
|
-
config: {},
|
|
57
|
-
httpClient: jest.fn().mockReturnValue(httpClientMock),
|
|
58
|
-
} as unknown as ConnectorSDKInterface<ConnectorConfig>;
|
|
59
|
-
|
|
60
|
-
resultHandlerMock = {
|
|
61
|
-
handleResult: jest.fn().mockResolvedValue(undefined),
|
|
62
|
-
} as unknown as ResultHandler;
|
|
63
|
-
|
|
64
|
-
service = new ExtractorService(sdkMock, callConfig, resultHandlerMock);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('should initialize and register interval', () => {
|
|
68
|
-
expect(service).toBeDefined();
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
describe('extraction method', () => {
|
|
72
|
-
const runExtract = async (): Promise<void> => {
|
|
73
|
-
await expect(service.onRun()).resolves.not.toThrow();
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
it('should perform extraction without errors', async () => {
|
|
77
|
-
await runExtract();
|
|
78
|
-
|
|
79
|
-
expect(httpClientMock.request).toHaveBeenCalledWith(
|
|
80
|
-
'GET',
|
|
81
|
-
'compiled-https://localhost:443',
|
|
82
|
-
{ data: undefined, headers: { 'Content-Type': 'text' } },
|
|
83
|
-
);
|
|
84
|
-
expect(resultHandlerMock.handleResult).toHaveBeenCalledWith(
|
|
85
|
-
'some-result-data',
|
|
86
|
-
callConfig,
|
|
87
|
-
);
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
});
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CompileDelegate,
|
|
3
|
-
ConnectorSDKInterface,
|
|
4
|
-
HttpClientSDKInterface,
|
|
5
|
-
HttpMethod,
|
|
6
|
-
IntervalHandler,
|
|
7
|
-
} from '@transai/connector-runtime-sdk';
|
|
8
|
-
|
|
9
|
-
import { HttpClientAuthentication } from './http-client-authentication';
|
|
10
|
-
import { ResultHandler } from './result.handler';
|
|
11
|
-
import { ApiConfig, ConnectorConfig } from './types';
|
|
12
|
-
|
|
13
|
-
export class ExtractorService implements IntervalHandler {
|
|
14
|
-
readonly #sdk: ConnectorSDKInterface<ConnectorConfig>;
|
|
15
|
-
|
|
16
|
-
readonly #apiConfig: ApiConfig;
|
|
17
|
-
|
|
18
|
-
readonly #resultHandler: ResultHandler;
|
|
19
|
-
|
|
20
|
-
readonly #httpClient: HttpClientSDKInterface;
|
|
21
|
-
|
|
22
|
-
readonly #requestMethod: HttpMethod;
|
|
23
|
-
|
|
24
|
-
readonly #urlDelegate?: CompileDelegate;
|
|
25
|
-
|
|
26
|
-
readonly #bodyDelegate?: CompileDelegate;
|
|
27
|
-
|
|
28
|
-
constructor(
|
|
29
|
-
sdk: ConnectorSDKInterface<ConnectorConfig>,
|
|
30
|
-
apiConfig: ApiConfig,
|
|
31
|
-
resultHandler: ResultHandler,
|
|
32
|
-
httpClient?: HttpClientSDKInterface,
|
|
33
|
-
) {
|
|
34
|
-
this.#sdk = sdk;
|
|
35
|
-
this.#apiConfig = apiConfig;
|
|
36
|
-
this.#resultHandler = resultHandler;
|
|
37
|
-
|
|
38
|
-
const { config } = this.#sdk;
|
|
39
|
-
|
|
40
|
-
this.#requestMethod = this.#apiConfig.method ?? config.method ?? 'GET';
|
|
41
|
-
this.#urlDelegate = this.#apiConfig.url
|
|
42
|
-
? this.#sdk.templating.compile(this.#apiConfig.url)
|
|
43
|
-
: undefined;
|
|
44
|
-
this.#bodyDelegate = this.#apiConfig.body
|
|
45
|
-
? this.#sdk.templating.compile(this.#apiConfig.body)
|
|
46
|
-
: undefined;
|
|
47
|
-
|
|
48
|
-
if (this.#apiConfig.url) {
|
|
49
|
-
this.#httpClient = this.#sdk
|
|
50
|
-
.httpClient()
|
|
51
|
-
.setRequestOptionsFormatter(
|
|
52
|
-
HttpClientAuthentication.createForAuthConfig(
|
|
53
|
-
this.#apiConfig,
|
|
54
|
-
this.#sdk.httpClient(),
|
|
55
|
-
),
|
|
56
|
-
);
|
|
57
|
-
} else if (httpClient) {
|
|
58
|
-
this.#httpClient = httpClient;
|
|
59
|
-
} else {
|
|
60
|
-
throw new Error(
|
|
61
|
-
`No HTTP client or URL provided for API extractor: ${apiConfig.name}`,
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
get name(): string {
|
|
67
|
-
return `api-extractor-${this.#apiConfig.name}`;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async onRun(): Promise<void> {
|
|
71
|
-
const latestOffset = await this.#sdk.offsetStore.getOffset(
|
|
72
|
-
`${this.#apiConfig.offsetFilePrefix ?? 'offset'}_${this.#apiConfig.name}`,
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
this.#sdk.logger.verbose(`[API] [${this.#apiConfig.name}] Executing query`);
|
|
76
|
-
|
|
77
|
-
const compileOptions = {
|
|
78
|
-
...latestOffset,
|
|
79
|
-
limit: this.#apiConfig.batchSize ?? 10,
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
const result = await this.#httpClient.request<string>(
|
|
83
|
-
this.#requestMethod,
|
|
84
|
-
this.#urlDelegate?.(compileOptions) ?? '',
|
|
85
|
-
{
|
|
86
|
-
data: this.#bodyDelegate?.(compileOptions),
|
|
87
|
-
headers: {
|
|
88
|
-
'Content-Type': this.#apiConfig.format ?? 'text',
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
await this.#resultHandler.handleResult(result.data, this.#apiConfig);
|
|
94
|
-
|
|
95
|
-
this.#sdk.logger.debug(`[API] [${this.#apiConfig.name}] Ran query`);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HttpClientSDKInterface,
|
|
3
|
-
HttpRequestOptions,
|
|
4
|
-
HttpRequestOptionsFormatter,
|
|
5
|
-
} from '@transai/connector-runtime-sdk';
|
|
6
|
-
|
|
7
|
-
import { HttpClientAuthConfig } from './types';
|
|
8
|
-
|
|
9
|
-
export class HttpClientAuthentication {
|
|
10
|
-
readonly #config: HttpClientAuthConfig;
|
|
11
|
-
|
|
12
|
-
readonly #tokenHttpClient: HttpClientSDKInterface;
|
|
13
|
-
|
|
14
|
-
#sessionToken?: {
|
|
15
|
-
token: string;
|
|
16
|
-
expiresAt: number;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
private constructor(
|
|
20
|
-
config: HttpClientAuthConfig,
|
|
21
|
-
tokenHttpClient: HttpClientSDKInterface,
|
|
22
|
-
) {
|
|
23
|
-
this.#config = config;
|
|
24
|
-
this.#tokenHttpClient = tokenHttpClient;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
static createForAuthConfig(
|
|
28
|
-
config: HttpClientAuthConfig,
|
|
29
|
-
tokenHttpClient: HttpClientSDKInterface,
|
|
30
|
-
): HttpRequestOptionsFormatter {
|
|
31
|
-
const instance = new HttpClientAuthentication(config, tokenHttpClient);
|
|
32
|
-
|
|
33
|
-
return instance.format.bind(instance);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async format<D = string | object>(
|
|
37
|
-
requestOptions: HttpRequestOptions<D>,
|
|
38
|
-
): Promise<HttpRequestOptions<D>> {
|
|
39
|
-
if (this.#config.authorization) {
|
|
40
|
-
return {
|
|
41
|
-
...requestOptions,
|
|
42
|
-
headers: {
|
|
43
|
-
...requestOptions.headers,
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
45
|
-
Authorization: this.#config.authorization!,
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
this.#config.tokenUrl &&
|
|
52
|
-
this.#config.clientId &&
|
|
53
|
-
this.#config.clientSecret
|
|
54
|
-
) {
|
|
55
|
-
return {
|
|
56
|
-
...requestOptions,
|
|
57
|
-
headers: {
|
|
58
|
-
...requestOptions.headers,
|
|
59
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
60
|
-
Authorization: await this.#formatTokenAuth(),
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return requestOptions;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async #formatTokenAuth(): Promise<string> {
|
|
69
|
-
const token = this.#sessionToken;
|
|
70
|
-
if (token && token.expiresAt > Date.now()) {
|
|
71
|
-
return token.token;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const response = await this.#tokenHttpClient.post<{
|
|
75
|
-
access_token: string;
|
|
76
|
-
expires_in: number;
|
|
77
|
-
}>(
|
|
78
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
79
|
-
this.#config.tokenUrl!,
|
|
80
|
-
{
|
|
81
|
-
grant_type: 'client_credentials',
|
|
82
|
-
client_id: this.#config.clientId,
|
|
83
|
-
client_secret: this.#config.clientSecret,
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
headers: {
|
|
87
|
-
Accept: 'application/json',
|
|
88
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
if (!response) {
|
|
94
|
-
throw new Error(
|
|
95
|
-
'Failed to authenticate and retrieve authentication token',
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const { access_token: accessToken, expires_in: expiresIn } = response.data;
|
|
100
|
-
|
|
101
|
-
this.#sessionToken = {
|
|
102
|
-
token: accessToken,
|
|
103
|
-
expiresAt: Date.now() + expiresIn * 1000 - 1000,
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
return accessToken;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { ConnectorSDKInterface } from '@transai/connector-runtime-sdk';
|
|
2
|
-
|
|
3
|
-
import { ResultHandler } from './result.handler';
|
|
4
|
-
import { ApiConfig, ConnectorConfig } from './types';
|
|
5
|
-
|
|
6
|
-
describe('ResultHandler', () => {
|
|
7
|
-
let resultHandler: ResultHandler;
|
|
8
|
-
|
|
9
|
-
let sdkMock: ConnectorSDKInterface<ConnectorConfig>;
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
sdkMock = {
|
|
13
|
-
logger: {
|
|
14
|
-
info: jest.fn(),
|
|
15
|
-
debug: jest.fn(),
|
|
16
|
-
error: jest.fn(),
|
|
17
|
-
verbose: jest.fn(),
|
|
18
|
-
warn: jest.fn(),
|
|
19
|
-
},
|
|
20
|
-
offsetStore: {
|
|
21
|
-
setOffset: jest.fn(),
|
|
22
|
-
},
|
|
23
|
-
config: {},
|
|
24
|
-
sender: {
|
|
25
|
-
documents: jest.fn().mockResolvedValue(true),
|
|
26
|
-
metricsLegacy: jest.fn().mockResolvedValue(true),
|
|
27
|
-
},
|
|
28
|
-
} as unknown as ConnectorSDKInterface<ConnectorConfig>;
|
|
29
|
-
|
|
30
|
-
resultHandler = new ResultHandler(sdkMock);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('should be defined', () => {
|
|
34
|
-
expect(resultHandler).toBeDefined();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
describe('handle batch data', () => {
|
|
38
|
-
const apiConfig = {
|
|
39
|
-
name: 'test-api',
|
|
40
|
-
listField: 'items',
|
|
41
|
-
incrementalField: 'updatedAt',
|
|
42
|
-
offsetFilePrefix: 'offset_test',
|
|
43
|
-
keyField: 'id',
|
|
44
|
-
} as ApiConfig;
|
|
45
|
-
|
|
46
|
-
const result = JSON.stringify({
|
|
47
|
-
items: [
|
|
48
|
-
{ id: 1, updatedAt: '2024-01-01T00:00:00Z' },
|
|
49
|
-
{ id: 2, updatedAt: '2024-01-02T00:00:00Z' },
|
|
50
|
-
],
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should send batch data and set offset', async () => {
|
|
54
|
-
await resultHandler.handleResult(result, apiConfig);
|
|
55
|
-
|
|
56
|
-
expect(sdkMock.sender.documents).toHaveBeenCalledWith(
|
|
57
|
-
[
|
|
58
|
-
{ id: 1, updatedAt: '2024-01-01T00:00:00Z' },
|
|
59
|
-
{ id: 2, updatedAt: '2024-01-02T00:00:00Z' },
|
|
60
|
-
],
|
|
61
|
-
{
|
|
62
|
-
collection: 'api_test-api',
|
|
63
|
-
incrementalField: 'updatedAt',
|
|
64
|
-
keyField: 'id',
|
|
65
|
-
},
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
expect(sdkMock.offsetStore.setOffset).toHaveBeenCalledWith(
|
|
69
|
-
expect.objectContaining({
|
|
70
|
-
timestamp: new Date('2024-01-02T00:00:00Z').getTime(),
|
|
71
|
-
}),
|
|
72
|
-
'offset_test_test-api',
|
|
73
|
-
);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should send batch data as metrics', async () => {
|
|
77
|
-
await resultHandler.handleResult(result, {
|
|
78
|
-
...apiConfig,
|
|
79
|
-
type: 'metric',
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
expect(sdkMock.sender.metricsLegacy).toHaveBeenCalledWith(
|
|
83
|
-
[
|
|
84
|
-
{ id: 1, updatedAt: '2024-01-01T00:00:00Z' },
|
|
85
|
-
{ id: 2, updatedAt: '2024-01-02T00:00:00Z' },
|
|
86
|
-
],
|
|
87
|
-
{
|
|
88
|
-
collection: 'api_test-api',
|
|
89
|
-
incrementalField: 'updatedAt',
|
|
90
|
-
keyField: 'id',
|
|
91
|
-
},
|
|
92
|
-
);
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
describe('handle single record', () => {
|
|
97
|
-
const apiConfig = {
|
|
98
|
-
name: 'test-api',
|
|
99
|
-
} as ApiConfig;
|
|
100
|
-
|
|
101
|
-
const result = JSON.stringify({ id: 1, updatedAt: '2024-01-01T00:00:00Z' });
|
|
102
|
-
|
|
103
|
-
it('should send single record and set offset', async () => {
|
|
104
|
-
await resultHandler.handleResult(result, apiConfig);
|
|
105
|
-
|
|
106
|
-
expect(sdkMock.sender.documents).toHaveBeenCalledWith(
|
|
107
|
-
[{ id: 1, updatedAt: '2024-01-01T00:00:00Z' }],
|
|
108
|
-
{
|
|
109
|
-
collection: 'api_test-api',
|
|
110
|
-
},
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
expect(sdkMock.offsetStore.setOffset).toHaveBeenCalledWith(
|
|
114
|
-
expect.objectContaining({
|
|
115
|
-
timestamp: expect.any(Number),
|
|
116
|
-
}),
|
|
117
|
-
'offset_test-api',
|
|
118
|
-
);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('should send single record as metric', async () => {
|
|
122
|
-
await resultHandler.handleResult(result, {
|
|
123
|
-
...apiConfig,
|
|
124
|
-
type: 'metric',
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
expect(sdkMock.sender.metricsLegacy).toHaveBeenCalledWith(
|
|
128
|
-
[{ id: 1, updatedAt: '2024-01-01T00:00:00Z' }],
|
|
129
|
-
{
|
|
130
|
-
collection: 'api_test-api',
|
|
131
|
-
},
|
|
132
|
-
);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
});
|