@things-factory/integration-base 7.0.1-beta.14 → 7.0.1-beta.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist-server/controllers/scenario-controller.d.ts +2 -2
  2. package/dist-server/controllers/scenario-controller.js +8 -2
  3. package/dist-server/controllers/scenario-controller.js.map +1 -1
  4. package/dist-server/engine/types.d.ts +2 -2
  5. package/dist-server/engine/types.js.map +1 -1
  6. package/dist-server/restful/unstable/run-scenario.js +0 -1
  7. package/dist-server/restful/unstable/run-scenario.js.map +1 -1
  8. package/dist-server/service/connection/connection-query.js +8 -4
  9. package/dist-server/service/connection/connection-query.js.map +1 -1
  10. package/dist-server/service/payload-log/payload-log-query.js +1 -1
  11. package/dist-server/service/payload-log/payload-log-query.js.map +1 -1
  12. package/dist-server/service/payload-log/payload-log.js +2 -2
  13. package/dist-server/service/payload-log/payload-log.js.map +1 -1
  14. package/dist-server/service/scenario/scenario-query.js +1 -1
  15. package/dist-server/service/scenario/scenario-query.js.map +1 -1
  16. package/dist-server/service/scenario/scenario-type.d.ts +2 -0
  17. package/dist-server/service/scenario/scenario-type.js +8 -0
  18. package/dist-server/service/scenario/scenario-type.js.map +1 -1
  19. package/dist-server/service/scenario/scenario.d.ts +1 -0
  20. package/dist-server/service/scenario/scenario.js +7 -2
  21. package/dist-server/service/scenario/scenario.js.map +1 -1
  22. package/dist-server/service/scenario-instance/scenario-instance-mutation.d.ts +2 -2
  23. package/dist-server/service/scenario-instance/scenario-instance-mutation.js +1 -1
  24. package/dist-server/service/scenario-instance/scenario-instance-mutation.js.map +1 -1
  25. package/dist-server/service/scenario-instance/scenario-instance-query.d.ts +1 -7
  26. package/dist-server/service/scenario-instance/scenario-instance-query.js +1 -65
  27. package/dist-server/service/scenario-instance/scenario-instance-query.js.map +1 -1
  28. package/dist-server/service/scenario-instance/scenario-instance-type.d.ts +35 -11
  29. package/dist-server/service/scenario-instance/scenario-instance-type.js +100 -14
  30. package/dist-server/service/scenario-instance/scenario-instance-type.js.map +1 -1
  31. package/dist-server/service/state-register/state-register-query.js +1 -1
  32. package/dist-server/service/state-register/state-register-query.js.map +1 -1
  33. package/dist-server/service/step/step-query.js +1 -1
  34. package/dist-server/service/step/step-query.js.map +1 -1
  35. package/dist-server/service/step/step-type.js +2 -2
  36. package/dist-server/service/step/step-type.js.map +1 -1
  37. package/dist-server/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +9 -8
  39. package/server/controllers/scenario-controller.ts +55 -19
  40. package/server/engine/types.ts +2 -2
  41. package/server/restful/unstable/run-scenario.ts +0 -1
  42. package/server/service/connection/connection-query.ts +13 -4
  43. package/server/service/payload-log/payload-log-query.ts +4 -1
  44. package/server/service/payload-log/payload-log.ts +2 -2
  45. package/server/service/scenario/scenario-query.ts +1 -1
  46. package/server/service/scenario/scenario-type.ts +6 -0
  47. package/server/service/scenario/scenario.ts +6 -2
  48. package/server/service/scenario-instance/scenario-instance-mutation.ts +7 -4
  49. package/server/service/scenario-instance/scenario-instance-query.ts +4 -30
  50. package/server/service/scenario-instance/scenario-instance-type.ts +87 -9
  51. package/server/service/state-register/state-register-query.ts +4 -1
  52. package/server/service/step/step-query.ts +1 -1
  53. package/server/service/step/step-type.ts +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/integration-base",
3
- "version": "7.0.1-beta.14",
3
+ "version": "7.0.1-beta.19",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -27,12 +27,13 @@
27
27
  "dependencies": {
28
28
  "@apollo/client": "^3.6.9",
29
29
  "@operato/moment-timezone-es": "^2.0.0-beta.0",
30
- "@things-factory/api": "^7.0.1-beta.14",
31
- "@things-factory/auth-base": "^7.0.1-beta.14",
32
- "@things-factory/env": "^7.0.1-beta.6",
33
- "@things-factory/oauth2-client": "^7.0.1-beta.14",
34
- "@things-factory/scheduler-client": "^7.0.1-beta.14",
35
- "@things-factory/shell": "^7.0.1-beta.14",
30
+ "@things-factory/api": "^7.0.1-beta.18",
31
+ "@things-factory/auth-base": "^7.0.1-beta.18",
32
+ "@things-factory/cache-service": "^7.0.1-beta.19",
33
+ "@things-factory/env": "^7.0.1-beta.18",
34
+ "@things-factory/oauth2-client": "^7.0.1-beta.18",
35
+ "@things-factory/scheduler-client": "^7.0.1-beta.18",
36
+ "@things-factory/shell": "^7.0.1-beta.18",
36
37
  "@things-factory/utils": "^7.0.1-beta.10",
37
38
  "async-mqtt": "^2.5.0",
38
39
  "chance": "^1.1.11",
@@ -43,5 +44,5 @@
43
44
  "readline": "^1.3.0",
44
45
  "vm2": "^3.9.11"
45
46
  },
46
- "gitHead": "f98cf5cb94295657c43465d39cf55162f5566c59"
47
+ "gitHead": "bc939e291a4489432fb0fa0707e9c7594517ce94"
47
48
  }
@@ -1,14 +1,22 @@
1
1
  import { getRepository, Domain, GraphqlLocalClient } from '@things-factory/shell'
2
- import { PrivilegeObject, checkPermission } from '@things-factory/auth-base'
2
+ import { PrivilegeObject, User, checkPermission } from '@things-factory/auth-base'
3
+ import { cacheService } from '@things-factory/cache-service'
3
4
 
4
5
  import { ScenarioEngine } from '../engine/scenario-engine'
5
6
  import { Scenario } from '../service/scenario/scenario'
6
- import { ScenarioInstance } from '../service/scenario-instance/scenario-instance-type'
7
+ import {
8
+ ScenarioInstance,
9
+ ScenarioInstanceRunResult,
10
+ ScenarioInstanceStatus
11
+ } from '../service/scenario-instance/scenario-instance-type'
7
12
  import { Step } from '../service/step/step-type'
8
13
 
9
14
  const debug = require('debug')('things-factory:integration-base:controller:run-scenario')
10
15
 
11
- async function findScenario(scenarioName: string, domain: Domain): Promise<{ name: string; steps: Step[]; domain: Domain; privilege?: PrivilegeObject }> {
16
+ async function findScenario(
17
+ scenarioName: string,
18
+ domain: Domain
19
+ ): Promise<{ id: string; name: string; steps: Step[]; domain: Domain; privilege?: PrivilegeObject; ttl?: number }> {
12
20
  var repository = getRepository(Scenario)
13
21
 
14
22
  var scenario = await repository.findOne({
@@ -26,7 +34,12 @@ async function findScenario(scenarioName: string, domain: Domain): Promise<{ nam
26
34
  return scenario as any
27
35
  }
28
36
 
29
- export async function runScenario(instanceName: string, scenarioName: string, variables: any, context: ResolverContext): Promise<ScenarioInstance> {
37
+ export async function runScenario(
38
+ instanceName: string,
39
+ scenarioName: string,
40
+ variables: any,
41
+ context: ResolverContext
42
+ ): Promise<ScenarioInstanceRunResult> {
30
43
  const { domain, user, lng, unsafeIP, prohibitedPrivileges } = context.state
31
44
 
32
45
  debug('runScenario', scenarioName, instanceName, variables)
@@ -44,11 +57,22 @@ export async function runScenario(instanceName: string, scenarioName: string, va
44
57
  if (!(await checkPermission(scenario.privilege, user, domain, unsafeIP, prohibitedPrivileges))) {
45
58
  const { category, privilege } = scenario.privilege || {}
46
59
 
47
- console.error(`Unauthorized! ${category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'} required`)
60
+ console.error(
61
+ `Unauthorized! ${category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'} required`
62
+ )
63
+
64
+ throw new Error(
65
+ context.t('error.scenario run unauthorized', {
66
+ scenario: scenarioName
67
+ })
68
+ )
69
+ }
48
70
 
49
- throw new Error(context.t('error.scenario run unauthorized', {
50
- scenario: scenarioName
51
- }))
71
+ if (scenario.ttl > 0) {
72
+ const cachedValue = await cacheService.getFromCache(scenario.id, variables || {})
73
+ if (cachedValue) {
74
+ return cachedValue.value
75
+ }
52
76
  }
53
77
 
54
78
  /* 시나리오 인스턴스를 생성한다. */
@@ -62,19 +86,24 @@ export async function runScenario(instanceName: string, scenarioName: string, va
62
86
  })
63
87
 
64
88
  try {
65
- await instance.run()
66
- } catch(err) {
89
+ return await instance.run()
90
+ } catch (err) {
67
91
  console.error(err)
68
92
 
69
- throw new Error(context.t('error.scenario run error', {
70
- scenario: scenarioName
71
- }))
93
+ throw new Error(
94
+ context.t('error.scenario run error', {
95
+ scenario: scenarioName
96
+ })
97
+ )
72
98
  }
73
-
74
- return instance
75
99
  }
76
100
 
77
- export async function startScenario(instanceName: string, scenarioName: string, variables: any, context: ResolverContext): Promise<ScenarioInstance> {
101
+ export async function startScenario(
102
+ instanceName: string,
103
+ scenarioName: string,
104
+ variables: any,
105
+ context: ResolverContext
106
+ ): Promise<ScenarioInstance> {
78
107
  const { domain, user, lng, unsafeIP, prohibitedPrivileges } = context.state
79
108
 
80
109
  debug('startScenario', instanceName, scenarioName, variables)
@@ -91,14 +120,19 @@ export async function startScenario(instanceName: string, scenarioName: string,
91
120
 
92
121
  if (!(await checkPermission(scenario.privilege, user, domain, unsafeIP, prohibitedPrivileges))) {
93
122
  const { category, privilege } = scenario.privilege || {}
94
- throw new Error(`Unauthorized! ${category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'} required`)
123
+ throw new Error(
124
+ `Unauthorized! ${category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'} required`
125
+ )
95
126
  }
96
127
 
97
128
  instanceName = instanceName || scenarioName
98
129
  return await ScenarioEngine.load(instanceName, scenario, { domain, user, lng, variables })
99
130
  }
100
131
 
101
- export async function stopScenario(instanceName: string, context: ResolverContext): Promise<ScenarioInstance | undefined> {
132
+ export async function stopScenario(
133
+ instanceName: string,
134
+ context: ResolverContext
135
+ ): Promise<ScenarioInstance | undefined> {
102
136
  const { domain, user, unsafeIP, prohibitedPrivileges } = context.state
103
137
 
104
138
  debug('stopScenario', instanceName)
@@ -120,7 +154,9 @@ export async function stopScenario(instanceName: string, context: ResolverContex
120
154
 
121
155
  if (!(await checkPermission(scenario.privilege, user, domain, unsafeIP, prohibitedPrivileges))) {
122
156
  const { category, privilege } = scenario.privilege || {}
123
- throw new Error(`Unauthorized! ${category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'} required`)
157
+ throw new Error(
158
+ `Unauthorized! ${category && privilege ? category + ':' + privilege + ' privilege' : 'ownership granted'} required`
159
+ )
124
160
  }
125
161
 
126
162
  await ScenarioEngine.unload(domain, instanceName)
@@ -1,4 +1,4 @@
1
- import { Connection, PropertySpec, ScenarioInstanceStatus, Step } from '../service'
1
+ import { Connection, PropertySpec, ScenarioInstance, ScenarioInstanceStatus, Step } from '../service'
2
2
  import { Domain } from '@things-factory/shell'
3
3
  import { User } from '@things-factory/auth-base'
4
4
 
@@ -76,7 +76,7 @@ export type Context = {
76
76
  /**
77
77
  * Root object, can be used for various purposes.
78
78
  */
79
- root: Object
79
+ root?: ScenarioInstance
80
80
 
81
81
  /**
82
82
  * Array of function closures.
@@ -21,7 +21,6 @@ router.post('/unstable/run-scenario/:scenarioName', async (context, next) => {
21
21
  runScenario(instanceName: $instanceName, scenarioName: $scenarioName, variables: $variables) {
22
22
  instanceName
23
23
  scenarioName
24
- state
25
24
  data
26
25
  result
27
26
  message
@@ -19,12 +19,17 @@ export class ConnectionQuery {
19
19
 
20
20
  return {
21
21
  ...connection,
22
- state: ConnectionManager.getConnectionInstance(connection) ? ConnectionStatus.CONNECTED : ConnectionStatus.DISCONNECTED
22
+ state: ConnectionManager.getConnectionInstance(connection)
23
+ ? ConnectionStatus.CONNECTED
24
+ : ConnectionStatus.DISCONNECTED
23
25
  } as Connection
24
26
  }
25
27
 
26
28
  @Query(returns => ConnectionList, { description: 'To fetch multiple connections' })
27
- async connections(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<ConnectionList> {
29
+ async connections(
30
+ @Args(type => ListParam) params: ListParam,
31
+ @Ctx() context: ResolverContext
32
+ ): Promise<ConnectionList> {
28
33
  const { domain } = context.state
29
34
 
30
35
  const queryBuilder = getQueryBuilderFromListParams({
@@ -38,7 +43,9 @@ export class ConnectionQuery {
38
43
  const [items, total] = await queryBuilder.leftJoinAndSelect('connection.domain', 'domain').getManyAndCount()
39
44
 
40
45
  items.forEach(connection => {
41
- connection['state'] = ConnectionManager.getConnectionInstance(connection) ? ConnectionStatus.CONNECTED : ConnectionStatus.DISCONNECTED
46
+ connection['state'] = ConnectionManager.getConnectionInstance(connection)
47
+ ? ConnectionStatus.CONNECTED
48
+ : ConnectionStatus.DISCONNECTED
42
49
  })
43
50
 
44
51
  return { items, total }
@@ -63,7 +70,9 @@ export class ConnectionQuery {
63
70
 
64
71
  @FieldResolver(type => Domain)
65
72
  async domain(@Root() connection: Connection) {
66
- return connection.domain || (connection.domainId && (await getRepository(Domain).findOneBy({ id: connection.domainId })))
73
+ return (
74
+ connection.domain || (connection.domainId && (await getRepository(Domain).findOneBy({ id: connection.domainId })))
75
+ )
67
76
  }
68
77
 
69
78
  @FieldResolver(type => User)
@@ -18,7 +18,10 @@ export class PayloadLogQuery {
18
18
  }
19
19
 
20
20
  @Query(returns => PayloadLogList, { description: 'To fetch multiple PayloadLogs' })
21
- async payloadLogs(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<PayloadLogList> {
21
+ async payloadLogs(
22
+ @Args(type => ListParam) params: ListParam,
23
+ @Ctx() context: ResolverContext
24
+ ): Promise<PayloadLogList> {
22
25
  const { domain } = context.state
23
26
 
24
27
  const convertedParams = convertListParams(params, {
@@ -81,14 +81,14 @@ export class PayloadLog {
81
81
  updatedAt?: Date
82
82
 
83
83
  @ManyToOne(type => User, { nullable: true })
84
- @Field({ nullable: true })
84
+ @Field(type => User, { nullable: true })
85
85
  creator?: User
86
86
 
87
87
  @RelationId((payloadLog: PayloadLog) => payloadLog.creator)
88
88
  creatorId?: string
89
89
 
90
90
  @ManyToOne(type => User, { nullable: true })
91
- @Field({ nullable: true })
91
+ @Field(type => User, { nullable: true })
92
92
  updater?: User
93
93
 
94
94
  @RelationId((payloadLog: PayloadLog) => payloadLog.updater)
@@ -26,7 +26,7 @@ export class ScenarioQuery {
26
26
 
27
27
  @Directive('@privilege(category: "scenario", privilege: "query", domainOwnerGranted: true)')
28
28
  @Query(returns => ScenarioList, { description: 'To fetch multiple scenarios' })
29
- async scenarios(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<ScenarioList> {
29
+ async scenarios(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<ScenarioList> {
30
30
  const { domain } = context.state
31
31
 
32
32
  const queryBuilder = getQueryBuilderFromListParams({
@@ -22,6 +22,9 @@ export class NewScenario {
22
22
  @Field({ nullable: true })
23
23
  timezone?: string
24
24
 
25
+ @Field({ nullable: true })
26
+ ttl?: number
27
+
25
28
  @Field({ nullable: true })
26
29
  active?: boolean
27
30
 
@@ -49,6 +52,9 @@ export class ScenarioPatch {
49
52
  @Field({ nullable: true })
50
53
  timezone?: string
51
54
 
55
+ @Field({ nullable: true })
56
+ ttl?: number
57
+
52
58
  @Field({ nullable: true })
53
59
  active?: boolean
54
60
 
@@ -64,6 +64,10 @@ export class Scenario {
64
64
  @Field({ nullable: true })
65
65
  timezone?: string
66
66
 
67
+ @Column({ nullable: true })
68
+ @Field({ nullable: true })
69
+ ttl?: number
70
+
67
71
  @OneToMany(type => Step, step => step.scenario)
68
72
  @Field(type => [Step], { nullable: true })
69
73
  steps?: Step[]
@@ -81,14 +85,14 @@ export class Scenario {
81
85
  updatedAt?: Date
82
86
 
83
87
  @ManyToOne(type => User, { nullable: true })
84
- @Field({ nullable: true })
88
+ @Field(type => User, { nullable: true })
85
89
  creator?: User
86
90
 
87
91
  @RelationId((scenario: Scenario) => scenario.creator)
88
92
  creatorId?: string
89
93
 
90
94
  @ManyToOne(type => User, { nullable: true })
91
- @Field({ nullable: true })
95
+ @Field(type => User, { nullable: true })
92
96
  updater?: User
93
97
 
94
98
  @RelationId((scenario: Scenario) => scenario.updater)
@@ -2,7 +2,7 @@ import { Arg, Ctx, Mutation, Resolver } from 'type-graphql'
2
2
 
3
3
  import { ScalarObject } from '@things-factory/shell'
4
4
 
5
- import { ScenarioInstance } from './scenario-instance-type'
5
+ import { ScenarioInstance, ScenarioInstanceRunResult } from './scenario-instance-type'
6
6
 
7
7
  import {
8
8
  runScenario as controllerRunScenario,
@@ -12,7 +12,7 @@ import {
12
12
 
13
13
  @Resolver(ScenarioInstance)
14
14
  export class ScenarioInstanceMutation {
15
- @Mutation(returns => ScenarioInstance, {
15
+ @Mutation(returns => ScenarioInstanceRunResult, {
16
16
  description: 'To run new scenario instance and will return the result after the scenario stop.'
17
17
  })
18
18
  async runScenario(
@@ -20,7 +20,7 @@ export class ScenarioInstanceMutation {
20
20
  @Arg('scenarioName') scenarioName: string,
21
21
  @Arg('variables', type => ScalarObject, { nullable: true }) variables: any,
22
22
  @Ctx() context: ResolverContext
23
- ): Promise<ScenarioInstance> {
23
+ ): Promise<ScenarioInstanceRunResult> {
24
24
  return await controllerRunScenario(instanceName, scenarioName, variables, context)
25
25
  }
26
26
 
@@ -35,7 +35,10 @@ export class ScenarioInstanceMutation {
35
35
  }
36
36
 
37
37
  @Mutation(returns => ScenarioInstance, { nullable: true, description: 'To start new scenario instance' })
38
- async stopScenario(@Arg('instanceName', { nullable: true }) instanceName: string, @Ctx() context: ResolverContext): Promise<ScenarioInstance | undefined> {
38
+ async stopScenario(
39
+ @Arg('instanceName', { nullable: true }) instanceName: string,
40
+ @Ctx() context: ResolverContext
41
+ ): Promise<ScenarioInstance | undefined> {
39
42
  return await controllerStopScenario(instanceName, context)
40
43
  }
41
44
  }
@@ -23,7 +23,10 @@ export class ScenarioInstanceQuery {
23
23
  }
24
24
 
25
25
  @Query(returns => ScenarioInstanceList, { description: 'To fetch multiple scenario instances' })
26
- async scenarioInstances(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<ScenarioInstanceList> {
26
+ async scenarioInstances(
27
+ @Args(type => ListParam) params: ListParam,
28
+ @Ctx() context: ResolverContext
29
+ ): Promise<ScenarioInstanceList> {
27
30
  const { domain } = context.state
28
31
 
29
32
  var scenarioInstances = ScenarioEngine.getScenarioInstances(domain)
@@ -36,33 +39,4 @@ export class ScenarioInstanceQuery {
36
39
  total: items.length
37
40
  }
38
41
  }
39
-
40
- @FieldResolver(type => ScenarioInstance)
41
- async root(@Root() scenarioInstance: ScenarioInstance): Promise<ScenarioInstance> {
42
- return scenarioInstance.context?.root as ScenarioInstance
43
- }
44
-
45
- @FieldResolver(type => ScenarioInstanceStatus)
46
- async state(@Root() scenarioInstance: ScenarioInstance): Promise<ScenarioInstanceStatus> {
47
- return scenarioInstance.context?.state
48
- }
49
-
50
- @FieldResolver(type => ScenarioInstanceProgress)
51
- progress(@Root() scenarioInstance: ScenarioInstance): ScenarioInstanceProgress {
52
- return scenarioInstance.calcProgress()
53
- }
54
- @FieldResolver(type => ScalarObject)
55
- async variables(@Root() scenarioInstance: ScenarioInstance): Promise<Object> {
56
- return scenarioInstance.context?.variables
57
- }
58
-
59
- @FieldResolver(type => ScalarObject)
60
- async data(@Root() scenarioInstance: ScenarioInstance): Promise<Object> {
61
- return scenarioInstance.context?.data
62
- }
63
-
64
- @FieldResolver()
65
- async timestamp(@Root() scenarioInstance: ScenarioInstance): Promise<Date> {
66
- return new Date()
67
- }
68
42
  }
@@ -7,6 +7,7 @@ import util from 'util'
7
7
  import { createLogger, format, transports } from 'winston'
8
8
 
9
9
  import { Domain, pubsub, PubSubLogTransport, ScalarObject } from '@things-factory/shell'
10
+ import { cacheService } from '@things-factory/cache-service'
10
11
  import { User } from '@things-factory/auth-base'
11
12
  import { sleep } from '@things-factory/utils'
12
13
 
@@ -87,6 +88,33 @@ export class ScenarioInstanceState {
87
88
  public timestamp: Date
88
89
  }
89
90
 
91
+ @ObjectType()
92
+ export class ScenarioInstanceRunResult {
93
+ @Field({ nullable: true })
94
+ public scenarioName: string
95
+
96
+ @Field({ nullable: true })
97
+ public instanceName: string
98
+
99
+ @Field(type => ScalarObject, { nullable: true })
100
+ public variables: any
101
+
102
+ @Field(type => ScalarObject, { nullable: true })
103
+ public data: any
104
+
105
+ @Field(type => ScalarObject, { nullable: true })
106
+ public result: any
107
+
108
+ @Field({ nullable: true })
109
+ public timestamp: Date
110
+
111
+ @Field({ nullable: true })
112
+ public message: string
113
+
114
+ @Field({ nullable: true })
115
+ public state: ScenarioInstanceStatus
116
+ }
117
+
90
118
  @ObjectType()
91
119
  export class ScenarioInstance {
92
120
  private subScenarioInstances: ScenarioInstance[] = [] // TODO Imple by WeakSet
@@ -106,29 +134,43 @@ export class ScenarioInstance {
106
134
  public instanceName: string
107
135
 
108
136
  @Field({ nullable: true })
109
- root: ScenarioInstance
137
+ get root(): ScenarioInstance {
138
+ return this.context?.root
139
+ }
110
140
 
111
141
  @Field({ nullable: true })
112
- state: ScenarioInstanceStatus
142
+ get state(): ScenarioInstanceStatus {
143
+ return this.context?.state
144
+ }
113
145
 
114
146
  @Field(type => ScenarioInstanceProgress, { nullable: true })
115
- progress: ScenarioInstanceProgress
147
+ get progress(): ScenarioInstanceProgress {
148
+ return this.calcProgress()
149
+ }
116
150
 
117
151
  @Field(type => ScalarObject, { nullable: true })
118
- variables: any
152
+ get variables(): any {
153
+ return this.context?.variables
154
+ }
119
155
 
120
156
  @Field(type => ScalarObject, { nullable: true })
121
- data: any
157
+ get data(): any {
158
+ return this.context?.data
159
+ }
122
160
 
123
161
  @Field(type => ScalarObject, { nullable: true })
124
162
  result: any
125
163
 
126
164
  @Field({ nullable: true })
127
- timestamp: Date
165
+ get timestamp(): Date {
166
+ return new Date()
167
+ }
128
168
 
129
169
  @Field({ nullable: true })
130
170
  public message: string
131
171
 
172
+ private scenarioId: string
173
+ private scenarioTtl: number
132
174
  private steps: Step[]
133
175
  private rounds: number = 0
134
176
 
@@ -154,10 +196,22 @@ export class ScenarioInstance {
154
196
  }
155
197
  }
156
198
 
157
- constructor(instanceName, { name: scenarioName, steps, domain: scenarioDomain }, context?) {
199
+ constructor(
200
+ instanceName,
201
+ {
202
+ id: scenarioId,
203
+ ttl: scenarioTtl,
204
+ name: scenarioName,
205
+ steps,
206
+ domain: scenarioDomain
207
+ }: { id: string; ttl?: number; name: string; steps: Step[]; domain: Domain },
208
+ context?
209
+ ) {
158
210
  var { domain, user, lng, unsafeIP, prohibitedPrivileges } = context || {}
159
211
  domain ||= scenarioDomain
160
212
 
213
+ this.scenarioId = scenarioId
214
+ this.scenarioTtl = scenarioTtl
161
215
  this.instanceName = instanceName
162
216
  this.scenarioName = scenarioName
163
217
  this.steps = orderBy(steps || [], step => step.sequence)
@@ -269,7 +323,10 @@ export class ScenarioInstance {
269
323
  this.context.logger.error(ex.message ? ex.message : ex)
270
324
 
271
325
  debug('failed to run ', `[ Domain: ${domain.name}, Scenario: ${scenarioName} ]\n`, ex)
272
- this.setState(ScenarioInstanceStatus.HALTED, typeof message == 'object' ? JSON.stringify(message, null, 2) : message)
326
+ this.setState(
327
+ ScenarioInstanceStatus.HALTED,
328
+ typeof message == 'object' ? JSON.stringify(message, null, 2) : message
329
+ )
273
330
 
274
331
  throw ex
275
332
  }
@@ -280,6 +337,26 @@ export class ScenarioInstance {
280
337
  sum[step.name] = this.context.data[step.name]
281
338
  return sum
282
339
  }, {})
340
+
341
+ const { scenarioId, scenarioTtl, variables, message, scenarioName, instanceName, result } = this
342
+ const obj = {
343
+ scenarioName,
344
+ instanceName,
345
+ variables,
346
+ data: this.data,
347
+ result,
348
+ timestamp: new Date(),
349
+ message,
350
+ state: ScenarioInstanceStatus.STOPPED /* redundent, no meaning */
351
+ }
352
+
353
+ if (this.scenarioTtl && this.scenarioId) {
354
+ setTimeout(() => {
355
+ cacheService.setInCache(scenarioId, variables || {}, obj, scenarioTtl)
356
+ })
357
+ }
358
+
359
+ return obj
283
360
  }
284
361
 
285
362
  async loadSubscenario(step, scenarioConfig, context) {
@@ -442,7 +519,8 @@ export class ScenarioInstance {
442
519
  }
443
520
  step.params = step.params || {}
444
521
 
445
- const connection = step.connection && ConnectionManager.getConnectionInstanceEntityByName(this.domain, step.connection)
522
+ const connection =
523
+ step.connection && ConnectionManager.getConnectionInstanceEntityByName(this.domain, step.connection)
446
524
 
447
525
  if (!connection || !connection.edgeId) {
448
526
  var handler = TaskRegistry.getTaskHandler(step.task)
@@ -28,7 +28,10 @@ export class StateRegisterQuery {
28
28
 
29
29
  @Directive('@privilege(category: "state-register", privilege: "query", domainOwnerGranted: true)')
30
30
  @Query(returns => StateRegisterList, { description: 'To fetch multiple StateRegisters' })
31
- async stateRegisters(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<StateRegisterList> {
31
+ async stateRegisters(
32
+ @Args(type => ListParam) params: ListParam,
33
+ @Ctx() context: ResolverContext
34
+ ): Promise<StateRegisterList> {
32
35
  const { domain } = context.state
33
36
 
34
37
  const queryBuilder = getQueryBuilderFromListParams({
@@ -18,7 +18,7 @@ export class StepQuery {
18
18
  }
19
19
 
20
20
  @Query(returns => StepList, { description: 'To fetch multiple steps' })
21
- async steps(@Args() params: ListParam, @Ctx() context: ResolverContext): Promise<StepList> {
21
+ async steps(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<StepList> {
22
22
  const { domain } = context.state
23
23
 
24
24
  const queryBuilder = getQueryBuilderFromListParams({
@@ -137,7 +137,7 @@ export class Step {
137
137
  * The user who created this step.
138
138
  */
139
139
  @ManyToOne(type => User, { nullable: true })
140
- @Field({ nullable: true })
140
+ @Field(type => User, { nullable: true })
141
141
  creator?: User
142
142
 
143
143
  /**
@@ -150,7 +150,7 @@ export class Step {
150
150
  * The user who last updated this step.
151
151
  */
152
152
  @ManyToOne(type => User, { nullable: true })
153
- @Field({ nullable: true })
153
+ @Field(type => User, { nullable: true })
154
154
  updater?: User
155
155
 
156
156
  /**