@things-factory/integration-base 8.0.0-beta.9 → 8.0.2
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-server/engine/connector/http-connector.js +1 -1
- package/dist-server/engine/connector/http-connector.js.map +1 -1
- package/dist-server/engine/connector/index.d.ts +0 -1
- package/dist-server/engine/connector/index.js +0 -1
- package/dist-server/engine/connector/index.js.map +1 -1
- package/dist-server/engine/index.d.ts +0 -1
- package/dist-server/engine/index.js +0 -1
- package/dist-server/engine/index.js.map +1 -1
- package/dist-server/engine/task/headless-post.js +33 -19
- package/dist-server/engine/task/headless-post.js.map +1 -1
- package/dist-server/engine/task/headless-scrap.js +13 -20
- package/dist-server/engine/task/headless-scrap.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -12
- package/server/controllers/index.ts +2 -0
- package/server/controllers/publish-data.ts +29 -0
- package/server/controllers/scenario-controller.ts +156 -0
- package/server/engine/analyzer/analyze-integration.ts +115 -0
- package/server/engine/connection-manager.ts +239 -0
- package/server/engine/connector/echo-back-connector.ts +51 -0
- package/server/engine/connector/echo-back-server.ts +72 -0
- package/server/engine/connector/graphql-connector.ts +126 -0
- package/server/engine/connector/http-connector.ts +65 -0
- package/server/engine/connector/index.ts +12 -0
- package/server/engine/connector/mqtt-connector.ts +78 -0
- package/server/engine/connector/mssql-connector.ts +152 -0
- package/server/engine/connector/mysql-connector.ts +94 -0
- package/server/engine/connector/operato-connector.ts +264 -0
- package/server/engine/connector/oracle-connector.ts +218 -0
- package/server/engine/connector/postgresql-connector.ts +152 -0
- package/server/engine/connector/proxy-connector.ts +53 -0
- package/server/engine/connector/socket-server.ts +86 -0
- package/server/engine/connector/sqlite-connector.ts +69 -0
- package/server/engine/edge-client.ts +45 -0
- package/server/engine/index.ts +10 -0
- package/server/engine/pending-queue.ts +97 -0
- package/server/engine/scenario-engine.ts +106 -0
- package/server/engine/task/book-up-scenario.ts +73 -0
- package/server/engine/task/csv-readline.ts +127 -0
- package/server/engine/task/data-accessor.ts +36 -0
- package/server/engine/task/data-mapper.ts +47 -0
- package/server/engine/task/database-query.ts +56 -0
- package/server/engine/task/echo-receive.ts +21 -0
- package/server/engine/task/echo-send.ts +32 -0
- package/server/engine/task/empty-check.ts +38 -0
- package/server/engine/task/end.ts +18 -0
- package/server/engine/task/floating-point.ts +71 -0
- package/server/engine/task/goto.ts +27 -0
- package/server/engine/task/graphql-mutate.ts +79 -0
- package/server/engine/task/graphql-query.ts +78 -0
- package/server/engine/task/headless-post.ts +147 -0
- package/server/engine/task/headless-scrap.ts +80 -0
- package/server/engine/task/http-get.ts +117 -0
- package/server/engine/task/http-post.ts +148 -0
- package/server/engine/task/index.ts +45 -0
- package/server/engine/task/jsonata.ts +45 -0
- package/server/engine/task/local-graphql-mutate.ts +100 -0
- package/server/engine/task/local-graphql-query.ts +100 -0
- package/server/engine/task/log.ts +78 -0
- package/server/engine/task/mqtt-publish.ts +45 -0
- package/server/engine/task/mqtt-subscribe.ts +139 -0
- package/server/engine/task/mssql-procedure.ts +128 -0
- package/server/engine/task/oracle-procedure.ts +124 -0
- package/server/engine/task/pick-pending-scenario.ts +80 -0
- package/server/engine/task/publish.ts +40 -0
- package/server/engine/task/random.ts +53 -0
- package/server/engine/task/reset-pending-queue.ts +17 -0
- package/server/engine/task/script.ts +63 -0
- package/server/engine/task/set-domain.ts +37 -0
- package/server/engine/task/sleep.ts +34 -0
- package/server/engine/task/socket-listener.ts +96 -0
- package/server/engine/task/state-group-read.ts +69 -0
- package/server/engine/task/state-read.ts +56 -0
- package/server/engine/task/state-write.ts +65 -0
- package/server/engine/task/stop-scenario.ts +44 -0
- package/server/engine/task/sub-scenario.ts +57 -0
- package/server/engine/task/switch-goto.ts +43 -0
- package/server/engine/task/switch-range-goto.ts +53 -0
- package/server/engine/task/switch-range-scenario.ts +79 -0
- package/server/engine/task/switch-range-set.ts +48 -0
- package/server/engine/task/switch-scenario.ts +67 -0
- package/server/engine/task/switch-set.ts +37 -0
- package/server/engine/task/throw.ts +27 -0
- package/server/engine/task/utils/headless-pool-for-scenario.ts +71 -0
- package/server/engine/task/utils/substitute.ts +44 -0
- package/server/engine/task/variables.ts +17 -0
- package/server/engine/task-registry.ts +23 -0
- package/server/engine/types.ts +114 -0
- package/server/index.ts +20 -0
- package/server/migrations/index.ts +9 -0
- package/server/restful/index.ts +1 -0
- package/server/restful/unstable/index.ts +7 -0
- package/server/restful/unstable/run-scenario.ts +51 -0
- package/server/restful/unstable/scenario-instance.ts +52 -0
- package/server/restful/unstable/scenario-instances.ts +80 -0
- package/server/restful/unstable/scenario.ts +41 -0
- package/server/restful/unstable/scenarios.ts +69 -0
- package/server/restful/unstable/start-scenario.ts +33 -0
- package/server/restful/unstable/stop-scenario.ts +30 -0
- package/server/routers/scenario-schedule-callback-router.ts +69 -0
- package/server/routers/scenario-view-router.ts +46 -0
- package/server/routes.ts +30 -0
- package/server/service/analysis/analysis-query.ts +13 -0
- package/server/service/analysis/index.ts +3 -0
- package/server/service/connection/connection-mutation.ts +190 -0
- package/server/service/connection/connection-query.ts +87 -0
- package/server/service/connection/connection-subscription.ts +104 -0
- package/server/service/connection/connection-type.ts +288 -0
- package/server/service/connection/index.ts +7 -0
- package/server/service/connector/connector-query.ts +62 -0
- package/server/service/connector/connector-type.ts +29 -0
- package/server/service/connector/index.ts +4 -0
- package/server/service/index.ts +52 -0
- package/server/service/payload-log/index.ts +7 -0
- package/server/service/payload-log/payload-log-mutation.ts +151 -0
- package/server/service/payload-log/payload-log-query.ts +49 -0
- package/server/service/payload-log/payload-log-type.ts +36 -0
- package/server/service/payload-log/payload-log.ts +100 -0
- package/server/service/property-spec.ts +24 -0
- package/server/service/scenario/index.ts +6 -0
- package/server/service/scenario/scenario-mutation.ts +396 -0
- package/server/service/scenario/scenario-query.ts +109 -0
- package/server/service/scenario/scenario-type.ts +78 -0
- package/server/service/scenario/scenario.ts +124 -0
- package/server/service/scenario-flow/scenario-flow.ts +17 -0
- package/server/service/scenario-instance/index.ts +6 -0
- package/server/service/scenario-instance/scenario-instance-mutation.ts +44 -0
- package/server/service/scenario-instance/scenario-instance-query.ts +42 -0
- package/server/service/scenario-instance/scenario-instance-subscription.ts +118 -0
- package/server/service/scenario-instance/scenario-instance-type.ts +563 -0
- package/server/service/scenario-queue/index.ts +4 -0
- package/server/service/scenario-queue/scenario-queue-subscription.ts +55 -0
- package/server/service/scenario-queue/scenario-queue-type.ts +27 -0
- package/server/service/state-register/data-resolver.ts +56 -0
- package/server/service/state-register/index.ts +8 -0
- package/server/service/state-register/state-register-mutation.ts +166 -0
- package/server/service/state-register/state-register-query.ts +80 -0
- package/server/service/state-register/state-register-type.ts +80 -0
- package/server/service/state-register/state-register.ts +113 -0
- package/server/service/step/index.ts +6 -0
- package/server/service/step/step-mutation.ts +52 -0
- package/server/service/step/step-query.ts +55 -0
- package/server/service/step/step-type.ts +215 -0
- package/server/service/task-type/index.ts +4 -0
- package/server/service/task-type/task-type-query.ts +95 -0
- package/server/service/task-type/task-type-type.ts +29 -0
- package/translations/en.json +4 -12
- package/translations/ja.json +4 -12
- package/translations/ko.json +4 -12
- package/translations/ms.json +4 -12
- package/translations/zh.json +4 -12
- package/dist-server/engine/connector/headless-connector.d.ts +0 -23
- package/dist-server/engine/connector/headless-connector.js +0 -357
- package/dist-server/engine/connector/headless-connector.js.map +0 -1
- package/dist-server/engine/resource-pool/headless-pool.d.ts +0 -1
- package/dist-server/engine/resource-pool/headless-pool.js +0 -62
- package/dist-server/engine/resource-pool/headless-pool.js.map +0 -1
- package/dist-server/engine/resource-pool/index.d.ts +0 -1
- package/dist-server/engine/resource-pool/index.js +0 -5
- package/dist-server/engine/resource-pool/index.js.map +0 -1
@@ -0,0 +1,56 @@
|
|
1
|
+
import { ConnectionManager } from '../connection-manager'
|
2
|
+
import { TaskRegistry } from '../task-registry'
|
3
|
+
import { InputStep } from '../../service/step/step-type'
|
4
|
+
import { Context } from '../types'
|
5
|
+
import 'ses'
|
6
|
+
|
7
|
+
async function DatabaseQuery(step: InputStep, context: Context) {
|
8
|
+
var { domain, user, data, variables, lng } = context
|
9
|
+
var {
|
10
|
+
connection: connectionName,
|
11
|
+
params: { query }
|
12
|
+
} = step
|
13
|
+
|
14
|
+
var dbconnection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)
|
15
|
+
|
16
|
+
const compartment = new Compartment({
|
17
|
+
domain,
|
18
|
+
user,
|
19
|
+
lng,
|
20
|
+
data,
|
21
|
+
variables,
|
22
|
+
console
|
23
|
+
})
|
24
|
+
|
25
|
+
let evalQuery
|
26
|
+
try {
|
27
|
+
evalQuery = compartment.evaluate('`' + query + '`')
|
28
|
+
} catch (err) {
|
29
|
+
throw new Error(`Failed to evaluate query: ${err.message}`)
|
30
|
+
}
|
31
|
+
|
32
|
+
var queryResult = await dbconnection.query(evalQuery, [])
|
33
|
+
|
34
|
+
return {
|
35
|
+
data: queryResult
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
DatabaseQuery.parameterSpec = [
|
40
|
+
{
|
41
|
+
type: 'textarea',
|
42
|
+
name: 'query',
|
43
|
+
label: 'query',
|
44
|
+
property: {
|
45
|
+
language: 'sql',
|
46
|
+
showLineNumbers: true
|
47
|
+
},
|
48
|
+
styles: {
|
49
|
+
flex: '1'
|
50
|
+
}
|
51
|
+
}
|
52
|
+
]
|
53
|
+
|
54
|
+
DatabaseQuery.help = 'integration/task/database-query'
|
55
|
+
|
56
|
+
TaskRegistry.registerTaskHandler('database-query', DatabaseQuery)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { TaskRegistry } from '../task-registry'
|
2
|
+
import { ConnectionManager } from '../connection-manager'
|
3
|
+
|
4
|
+
import { InputStep } from '../../service/step/step-type'
|
5
|
+
import { Context } from '../types'
|
6
|
+
|
7
|
+
async function EchoReceive(step: InputStep, { logger, domain }: Context) {
|
8
|
+
var { connection: connectionName } = step
|
9
|
+
|
10
|
+
var connection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)
|
11
|
+
|
12
|
+
var message = await connection.read()
|
13
|
+
|
14
|
+
return {
|
15
|
+
data: message.toString()
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
EchoReceive.parameterSpec = []
|
20
|
+
|
21
|
+
TaskRegistry.registerTaskHandler('echo-receive', EchoReceive)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import { TaskRegistry } from '../task-registry'
|
2
|
+
import { ConnectionManager } from '../connection-manager'
|
3
|
+
import { InputStep } from '../../service/step/step-type'
|
4
|
+
import { Context } from '../types'
|
5
|
+
|
6
|
+
async function EchoSend(step: InputStep, { logger, domain }: Context) {
|
7
|
+
var {
|
8
|
+
connection: connectionName,
|
9
|
+
params: { message }
|
10
|
+
} = step
|
11
|
+
|
12
|
+
var connection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)
|
13
|
+
if (!connection) {
|
14
|
+
throw Error(`connection is not found : ${connectionName}`)
|
15
|
+
}
|
16
|
+
|
17
|
+
var data = await connection.write(message)
|
18
|
+
|
19
|
+
return {
|
20
|
+
data
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
EchoSend.parameterSpec = [
|
25
|
+
{
|
26
|
+
type: 'string',
|
27
|
+
name: 'message',
|
28
|
+
label: 'message'
|
29
|
+
}
|
30
|
+
]
|
31
|
+
|
32
|
+
TaskRegistry.registerTaskHandler('echo-send', EchoSend)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import { TaskRegistry } from '../task-registry'
|
2
|
+
import { access } from '@things-factory/utils'
|
3
|
+
|
4
|
+
import { InputStep } from '../../service/step/step-type'
|
5
|
+
import { Context } from '../types'
|
6
|
+
|
7
|
+
async function EmptyCheck(step: InputStep, { logger, data }: Context) {
|
8
|
+
var {
|
9
|
+
params: { accessor, goto }
|
10
|
+
} = step
|
11
|
+
|
12
|
+
const value = access(accessor, data)
|
13
|
+
if ([null, undefined, NaN, ''].indexOf(value) !== -1) {
|
14
|
+
return {
|
15
|
+
next: goto
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
return {}
|
20
|
+
}
|
21
|
+
|
22
|
+
EmptyCheck.parameterSpec = [
|
23
|
+
{
|
24
|
+
type: 'scenario-step-input',
|
25
|
+
name: 'accessor',
|
26
|
+
label: 'accessor'
|
27
|
+
},
|
28
|
+
{
|
29
|
+
type: 'scenario-step-input',
|
30
|
+
name: 'goto',
|
31
|
+
label: 'goto'
|
32
|
+
}
|
33
|
+
]
|
34
|
+
|
35
|
+
EmptyCheck.connectorFree = true
|
36
|
+
EmptyCheck.help = 'integration/task/empty-check'
|
37
|
+
|
38
|
+
TaskRegistry.registerTaskHandler('empty-check', EmptyCheck)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { TaskRegistry } from '../task-registry'
|
2
|
+
import { ScenarioInstanceStatus } from '../../service'
|
3
|
+
|
4
|
+
import { InputStep } from '../../service/step/step-type'
|
5
|
+
import { Context } from '../types'
|
6
|
+
|
7
|
+
async function End(step: InputStep, { logger }: Context) {
|
8
|
+
return {
|
9
|
+
state: ScenarioInstanceStatus.STOPPED
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
End.parameterSpec = []
|
14
|
+
|
15
|
+
End.connectorFree = true
|
16
|
+
End.help = 'integration/task/end'
|
17
|
+
|
18
|
+
TaskRegistry.registerTaskHandler('end', End)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import ieee754 from 'ieee754'
|
2
|
+
import { access } from '@things-factory/utils'
|
3
|
+
import { TaskRegistry } from '../task-registry'
|
4
|
+
|
5
|
+
import { InputStep } from '../../service/step/step-type'
|
6
|
+
import { Context } from '../types'
|
7
|
+
|
8
|
+
async function FloatingPoint(step: InputStep, { logger, data }: Context) {
|
9
|
+
var {
|
10
|
+
params: { accessor, operation, endian, floatType }
|
11
|
+
} = step
|
12
|
+
|
13
|
+
const value = access(accessor, data)
|
14
|
+
if (typeof value === 'undefined') {
|
15
|
+
throw new Error('accessor value not a found')
|
16
|
+
}
|
17
|
+
|
18
|
+
const isLE = endian === 'little'
|
19
|
+
const nBytes = floatType === 'float' ? 4 : 8
|
20
|
+
const mantissa = floatType === 'float' ? 23 : 52
|
21
|
+
|
22
|
+
var result
|
23
|
+
|
24
|
+
if (operation == 'write') {
|
25
|
+
result = Buffer.alloc(nBytes)
|
26
|
+
ieee754.write(result, value, 0, isLE, mantissa, nBytes)
|
27
|
+
} else {
|
28
|
+
result = ieee754.read(value, 0, isLE, mantissa, nBytes)
|
29
|
+
}
|
30
|
+
|
31
|
+
return {
|
32
|
+
data: result
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
FloatingPoint.parameterSpec = [
|
37
|
+
{
|
38
|
+
type: 'scenario-step-input',
|
39
|
+
name: 'accessor',
|
40
|
+
label: 'accessor'
|
41
|
+
},
|
42
|
+
{
|
43
|
+
type: 'select',
|
44
|
+
name: 'operation',
|
45
|
+
label: 'operation',
|
46
|
+
property: {
|
47
|
+
options: ['read', 'write']
|
48
|
+
}
|
49
|
+
},
|
50
|
+
{
|
51
|
+
type: 'select',
|
52
|
+
name: 'endian',
|
53
|
+
label: 'endian',
|
54
|
+
property: {
|
55
|
+
options: ['little', 'big']
|
56
|
+
}
|
57
|
+
},
|
58
|
+
{
|
59
|
+
type: 'select',
|
60
|
+
name: 'floatType',
|
61
|
+
label: 'float type',
|
62
|
+
property: {
|
63
|
+
options: ['float', 'double']
|
64
|
+
}
|
65
|
+
}
|
66
|
+
]
|
67
|
+
|
68
|
+
FloatingPoint.connectorFree = true
|
69
|
+
FloatingPoint.help = 'integration/task/floating-point'
|
70
|
+
|
71
|
+
TaskRegistry.registerTaskHandler('floating-point', FloatingPoint)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { TaskRegistry } from '../task-registry'
|
2
|
+
|
3
|
+
import { InputStep } from '../../service/step/step-type'
|
4
|
+
import { Context } from '../types'
|
5
|
+
|
6
|
+
async function Goto(step: InputStep, { logger }: Context) {
|
7
|
+
var {
|
8
|
+
params: { goto }
|
9
|
+
} = step
|
10
|
+
|
11
|
+
return {
|
12
|
+
next: goto
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
Goto.parameterSpec = [
|
17
|
+
{
|
18
|
+
type: 'scenario-step-input',
|
19
|
+
name: 'goto',
|
20
|
+
label: 'goto'
|
21
|
+
}
|
22
|
+
]
|
23
|
+
|
24
|
+
Goto.connectorFree = true
|
25
|
+
Goto.help = 'integration/task/goto'
|
26
|
+
|
27
|
+
TaskRegistry.registerTaskHandler('goto', Goto)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
import gql from 'graphql-tag'
|
2
|
+
import 'ses'
|
3
|
+
|
4
|
+
import { access } from '@things-factory/utils'
|
5
|
+
import { ConnectionManager } from '../connection-manager'
|
6
|
+
import { TaskRegistry } from '../task-registry'
|
7
|
+
import { InputStep } from '../../service/step/step-type'
|
8
|
+
import { Context } from '../types'
|
9
|
+
|
10
|
+
async function GraphqlMutate(step: InputStep, context: Context) {
|
11
|
+
var { connection: connectionName, params: stepOptions } = step
|
12
|
+
var { mutation, variables: variablesAccessorMap, headers } = stepOptions || {}
|
13
|
+
|
14
|
+
var { domain, user, data, variables, lng } = context
|
15
|
+
|
16
|
+
const compartment = new Compartment({
|
17
|
+
domain,
|
18
|
+
user,
|
19
|
+
lng,
|
20
|
+
data,
|
21
|
+
variables,
|
22
|
+
console
|
23
|
+
})
|
24
|
+
|
25
|
+
let evalMutation
|
26
|
+
try {
|
27
|
+
evalMutation = compartment.evaluate('`' + mutation + '`')
|
28
|
+
} catch (err) {
|
29
|
+
throw new Error(`Failed to evaluate mutation: ${err.message}`)
|
30
|
+
}
|
31
|
+
|
32
|
+
var client = ConnectionManager.getConnectionInstanceByName(context.domain, connectionName)
|
33
|
+
|
34
|
+
const queryVariables = Object.keys(variablesAccessorMap || {}).reduce((variables, key) => {
|
35
|
+
const accessor = variablesAccessorMap[key]
|
36
|
+
variables[key] = access(accessor, data)
|
37
|
+
return variables
|
38
|
+
}, {})
|
39
|
+
|
40
|
+
var { data: mutateResult } = await client.mutate({
|
41
|
+
mutation: gql`
|
42
|
+
${evalMutation}
|
43
|
+
`,
|
44
|
+
variables: queryVariables,
|
45
|
+
headers
|
46
|
+
})
|
47
|
+
|
48
|
+
return {
|
49
|
+
data: mutateResult
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
GraphqlMutate.parameterSpec = [
|
54
|
+
{
|
55
|
+
type: 'graphql',
|
56
|
+
name: 'mutation',
|
57
|
+
label: 'mutation',
|
58
|
+
property: {
|
59
|
+
showLineNumbers: true
|
60
|
+
},
|
61
|
+
styles: {
|
62
|
+
flex: 1
|
63
|
+
}
|
64
|
+
},
|
65
|
+
{
|
66
|
+
type: 'key-values',
|
67
|
+
name: 'variables',
|
68
|
+
label: 'variables'
|
69
|
+
},
|
70
|
+
{
|
71
|
+
type: 'key-values',
|
72
|
+
name: 'headers',
|
73
|
+
label: 'headers'
|
74
|
+
}
|
75
|
+
]
|
76
|
+
|
77
|
+
GraphqlMutate.help = 'integration/task/graphql-mutate'
|
78
|
+
|
79
|
+
TaskRegistry.registerTaskHandler('graphql-mutate', GraphqlMutate)
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import gql from 'graphql-tag'
|
2
|
+
import 'ses'
|
3
|
+
|
4
|
+
import { access } from '@things-factory/utils'
|
5
|
+
import { ConnectionManager } from '../connection-manager'
|
6
|
+
import { TaskRegistry } from '../task-registry'
|
7
|
+
import { InputStep } from '../../service/step/step-type'
|
8
|
+
import { Context } from '../types'
|
9
|
+
|
10
|
+
async function GraphqlQuery(step: InputStep, context: Context) {
|
11
|
+
var { connection: connectionName, params: stepOptions } = step
|
12
|
+
var { query, variables: variablesAccessorMap, headers } = stepOptions || {}
|
13
|
+
var { domain, user, data, variables, lng } = context
|
14
|
+
|
15
|
+
const compartment = new Compartment({
|
16
|
+
domain,
|
17
|
+
user,
|
18
|
+
lng,
|
19
|
+
data,
|
20
|
+
variables,
|
21
|
+
console
|
22
|
+
})
|
23
|
+
|
24
|
+
let evalQuery
|
25
|
+
try {
|
26
|
+
evalQuery = compartment.evaluate('`' + query + '`')
|
27
|
+
} catch (err) {
|
28
|
+
throw new Error(`Failed to evaluate query: ${err.message}`)
|
29
|
+
}
|
30
|
+
|
31
|
+
var client = ConnectionManager.getConnectionInstanceByName(domain, connectionName)
|
32
|
+
|
33
|
+
const queryVariables = Object.keys(variablesAccessorMap || {}).reduce((variables, key) => {
|
34
|
+
const accessor = variablesAccessorMap[key]
|
35
|
+
variables[key] = access(accessor, data)
|
36
|
+
return variables
|
37
|
+
}, {})
|
38
|
+
|
39
|
+
var { data: queryResult } = await client.query({
|
40
|
+
query: gql`
|
41
|
+
${evalQuery}
|
42
|
+
`,
|
43
|
+
variables: queryVariables,
|
44
|
+
headers
|
45
|
+
})
|
46
|
+
|
47
|
+
return {
|
48
|
+
data: queryResult
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
GraphqlQuery.parameterSpec = [
|
53
|
+
{
|
54
|
+
type: 'graphql',
|
55
|
+
name: 'query',
|
56
|
+
label: 'query',
|
57
|
+
property: {
|
58
|
+
showLineNumbers: true
|
59
|
+
},
|
60
|
+
styles: {
|
61
|
+
flex: 1
|
62
|
+
}
|
63
|
+
},
|
64
|
+
{
|
65
|
+
type: 'key-values',
|
66
|
+
name: 'variables',
|
67
|
+
label: 'variables'
|
68
|
+
},
|
69
|
+
{
|
70
|
+
type: 'key-values',
|
71
|
+
name: 'headers',
|
72
|
+
label: 'headers'
|
73
|
+
}
|
74
|
+
]
|
75
|
+
|
76
|
+
GraphqlQuery.help = 'integration/task/graphql-query'
|
77
|
+
|
78
|
+
TaskRegistry.registerTaskHandler('graphql-query', GraphqlQuery)
|
@@ -0,0 +1,147 @@
|
|
1
|
+
import https from 'https'
|
2
|
+
import { URL } from 'url'
|
3
|
+
|
4
|
+
import { access } from '@things-factory/utils'
|
5
|
+
import { TaskRegistry } from '../task-registry'
|
6
|
+
import { ConnectionManager } from '../connection-manager'
|
7
|
+
|
8
|
+
import { getHeadlessPool } from './utils/headless-pool-for-scenario'
|
9
|
+
|
10
|
+
import { InputStep } from '../../service/step/step-type'
|
11
|
+
import { Context } from '../types'
|
12
|
+
|
13
|
+
async function HeadlessPost(step: InputStep, { logger, data, domain }: Context) {
|
14
|
+
var { connection: connectionName, params: stepOptions } = step
|
15
|
+
var { headers: requestHeaders, contentType, path, accessor } = stepOptions || {}
|
16
|
+
|
17
|
+
var connection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)
|
18
|
+
|
19
|
+
if (!connection) {
|
20
|
+
throw new Error(`connection '${connectionName}' is not established.`)
|
21
|
+
}
|
22
|
+
|
23
|
+
var { endpoint, params: connectionParams, authHeaders = {} } = connection
|
24
|
+
|
25
|
+
var headers = {
|
26
|
+
...authHeaders,
|
27
|
+
...requestHeaders
|
28
|
+
}
|
29
|
+
|
30
|
+
var body = access(accessor, data)
|
31
|
+
if (contentType && body) {
|
32
|
+
headers['content-type'] = contentType
|
33
|
+
switch (contentType) {
|
34
|
+
case 'text/plain':
|
35
|
+
body = JSON.stringify(body)
|
36
|
+
break
|
37
|
+
case 'application/json':
|
38
|
+
body = JSON.stringify(body)
|
39
|
+
break
|
40
|
+
case 'application/x-www-form-urlencoded':
|
41
|
+
const searchParams = new URLSearchParams()
|
42
|
+
for (const prop in body) {
|
43
|
+
searchParams.set(prop, body[prop])
|
44
|
+
}
|
45
|
+
body = searchParams
|
46
|
+
break
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
var options: any = {
|
51
|
+
method: 'POST',
|
52
|
+
headers,
|
53
|
+
body
|
54
|
+
}
|
55
|
+
|
56
|
+
var { rejectUnauthorized } = connectionParams
|
57
|
+
|
58
|
+
if (!rejectUnauthorized) {
|
59
|
+
const httpsAgent = new https.Agent({
|
60
|
+
rejectUnauthorized
|
61
|
+
})
|
62
|
+
options.agent = httpsAgent
|
63
|
+
}
|
64
|
+
|
65
|
+
const browser = (await getHeadlessPool().acquire()) as any
|
66
|
+
const page = await browser.newPage()
|
67
|
+
|
68
|
+
try {
|
69
|
+
page.on('console', async msg => {
|
70
|
+
console.log(`[browser ${msg.type()}] ${msg.text()}`)
|
71
|
+
})
|
72
|
+
|
73
|
+
page.on('requestfailed', request => {
|
74
|
+
console.log('Request failed:', request.url())
|
75
|
+
})
|
76
|
+
|
77
|
+
await page.goto(endpoint, { waitUntil: 'networkidle2' })
|
78
|
+
|
79
|
+
const response = await page.evaluate(
|
80
|
+
async (urlString, options) => {
|
81
|
+
const response = await fetch(urlString, options)
|
82
|
+
|
83
|
+
if (response.ok && response.headers.get('content-type').includes('application/json')) {
|
84
|
+
return await response.json()
|
85
|
+
} else {
|
86
|
+
return await response.text()
|
87
|
+
}
|
88
|
+
},
|
89
|
+
new URL(path, endpoint),
|
90
|
+
options
|
91
|
+
)
|
92
|
+
|
93
|
+
return {
|
94
|
+
data: response
|
95
|
+
}
|
96
|
+
} catch (e) {
|
97
|
+
console.error(e)
|
98
|
+
} finally {
|
99
|
+
page.close()
|
100
|
+
getHeadlessPool().release(browser)
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
HeadlessPost.parameterSpec = [
|
105
|
+
{
|
106
|
+
type: 'string',
|
107
|
+
name: 'path',
|
108
|
+
label: 'path'
|
109
|
+
},
|
110
|
+
{
|
111
|
+
type: 'http-headers',
|
112
|
+
name: 'headers',
|
113
|
+
label: 'headers'
|
114
|
+
},
|
115
|
+
{
|
116
|
+
type: 'select',
|
117
|
+
name: 'contentType',
|
118
|
+
label: 'content-type',
|
119
|
+
property: {
|
120
|
+
options: [
|
121
|
+
{
|
122
|
+
display: '',
|
123
|
+
value: ''
|
124
|
+
},
|
125
|
+
{
|
126
|
+
display: 'application/json',
|
127
|
+
value: 'application/json'
|
128
|
+
},
|
129
|
+
{
|
130
|
+
display: 'text/plain',
|
131
|
+
value: 'text/plain'
|
132
|
+
},
|
133
|
+
{
|
134
|
+
display: 'application/x-www-form-urlencoded',
|
135
|
+
value: 'application/x-www-form-urlencoded'
|
136
|
+
}
|
137
|
+
]
|
138
|
+
}
|
139
|
+
},
|
140
|
+
{
|
141
|
+
type: 'scenario-step-input',
|
142
|
+
name: 'accessor',
|
143
|
+
label: 'accessor'
|
144
|
+
}
|
145
|
+
]
|
146
|
+
|
147
|
+
TaskRegistry.registerTaskHandler('headless-post', HeadlessPost)
|
@@ -0,0 +1,80 @@
|
|
1
|
+
import { URL } from 'url'
|
2
|
+
|
3
|
+
import { TaskRegistry } from '../task-registry'
|
4
|
+
import { ConnectionManager } from '../connection-manager'
|
5
|
+
|
6
|
+
import { getHeadlessPool } from './utils/headless-pool-for-scenario'
|
7
|
+
import { InputStep } from '../../service/step/step-type'
|
8
|
+
import { Context } from '../types'
|
9
|
+
|
10
|
+
async function HeadlessScrap(step: InputStep, { logger, data, domain }: Context) {
|
11
|
+
var { connection: connectionName, params: stepOptions } = step
|
12
|
+
var { headers: requestHeaders, path, selectors = [] } = stepOptions || {}
|
13
|
+
|
14
|
+
var connection = ConnectionManager.getConnectionInstanceByName(domain, connectionName)
|
15
|
+
|
16
|
+
if (!connection) {
|
17
|
+
throw new Error(`connection '${connectionName}' is not established.`)
|
18
|
+
}
|
19
|
+
|
20
|
+
var { endpoint, params: connectionParams, authHeaders = {} } = connection
|
21
|
+
|
22
|
+
var headers = {
|
23
|
+
...authHeaders,
|
24
|
+
...requestHeaders
|
25
|
+
}
|
26
|
+
|
27
|
+
const browser = (await getHeadlessPool().acquire()) as any
|
28
|
+
const page = await browser.newPage()
|
29
|
+
|
30
|
+
try {
|
31
|
+
page.on('console', async msg => {
|
32
|
+
console.log(`[browser ${msg.type()}] ${msg.text()}`)
|
33
|
+
})
|
34
|
+
|
35
|
+
page.on('requestfailed', request => {
|
36
|
+
console.log('Request failed:', request.url())
|
37
|
+
})
|
38
|
+
|
39
|
+
await page.setExtraHTTPHeaders(headers)
|
40
|
+
await page.goto(new URL(path, endpoint), { waitUntil: 'networkidle2' })
|
41
|
+
|
42
|
+
const result = {}
|
43
|
+
|
44
|
+
for (const selector of selectors) {
|
45
|
+
const { text, value } = selector
|
46
|
+
result[text] = await page.$$eval(value, elements => {
|
47
|
+
return elements.map(element => element.textContent.trim())
|
48
|
+
})
|
49
|
+
}
|
50
|
+
|
51
|
+
return {
|
52
|
+
data: result
|
53
|
+
}
|
54
|
+
} catch (e) {
|
55
|
+
console.error(e)
|
56
|
+
} finally {
|
57
|
+
page.close()
|
58
|
+
getHeadlessPool().release(browser)
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
HeadlessScrap.parameterSpec = [
|
63
|
+
{
|
64
|
+
type: 'string',
|
65
|
+
name: 'path',
|
66
|
+
label: 'path'
|
67
|
+
},
|
68
|
+
{
|
69
|
+
type: 'http-headers',
|
70
|
+
name: 'headers',
|
71
|
+
label: 'headers'
|
72
|
+
},
|
73
|
+
{
|
74
|
+
type: 'options',
|
75
|
+
name: 'selectors',
|
76
|
+
label: 'selectors'
|
77
|
+
}
|
78
|
+
]
|
79
|
+
|
80
|
+
TaskRegistry.registerTaskHandler('headless-scrap', HeadlessScrap)
|