@contember/engine-actions 1.3.0-alpha.4
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/src/ActionsExecutionContainerHookFactory.d.ts +8 -0
- package/dist/src/ActionsExecutionContainerHookFactory.d.ts.map +1 -0
- package/dist/src/ActionsExecutionContainerHookFactory.js +28 -0
- package/dist/src/ActionsExecutionContainerHookFactory.js.map +1 -0
- package/dist/src/ImplementationException.d.ts +3 -0
- package/dist/src/ImplementationException.d.ts.map +1 -0
- package/dist/src/ImplementationException.js +7 -0
- package/dist/src/ImplementationException.js.map +1 -0
- package/dist/src/ListenerStoreProvider.d.ts +7 -0
- package/dist/src/ListenerStoreProvider.d.ts.map +1 -0
- package/dist/src/ListenerStoreProvider.js +21 -0
- package/dist/src/ListenerStoreProvider.js.map +1 -0
- package/dist/src/dispatch/DispatchWorkerSupervisor.d.ts +17 -0
- package/dist/src/dispatch/DispatchWorkerSupervisor.d.ts.map +1 -0
- package/dist/src/dispatch/DispatchWorkerSupervisor.js +123 -0
- package/dist/src/dispatch/DispatchWorkerSupervisor.js.map +1 -0
- package/dist/src/dispatch/EventDispatcher.d.ts +25 -0
- package/dist/src/dispatch/EventDispatcher.d.ts.map +1 -0
- package/dist/src/dispatch/EventDispatcher.js +46 -0
- package/dist/src/dispatch/EventDispatcher.js.map +1 -0
- package/dist/src/dispatch/EventsRepository.d.ts +22 -0
- package/dist/src/dispatch/EventsRepository.d.ts.map +1 -0
- package/dist/src/dispatch/EventsRepository.js +138 -0
- package/dist/src/dispatch/EventsRepository.js.map +1 -0
- package/dist/src/dispatch/ProjectDispatcher.d.ts +22 -0
- package/dist/src/dispatch/ProjectDispatcher.d.ts.map +1 -0
- package/dist/src/dispatch/ProjectDispatcher.js +103 -0
- package/dist/src/dispatch/ProjectDispatcher.js.map +1 -0
- package/dist/src/dispatch/TargetHandlerResolver.d.ts +9 -0
- package/dist/src/dispatch/TargetHandlerResolver.d.ts.map +1 -0
- package/dist/src/dispatch/TargetHandlerResolver.js +17 -0
- package/dist/src/dispatch/TargetHandlerResolver.js.map +1 -0
- package/dist/src/dispatch/WebhookTargetHandler.d.ts +7 -0
- package/dist/src/dispatch/WebhookTargetHandler.d.ts.map +1 -0
- package/dist/src/dispatch/WebhookTargetHandler.js +85 -0
- package/dist/src/dispatch/WebhookTargetHandler.js.map +1 -0
- package/dist/src/dispatch/types.d.ts +27 -0
- package/dist/src/dispatch/types.d.ts.map +1 -0
- package/dist/src/dispatch/types.js +3 -0
- package/dist/src/dispatch/types.js.map +1 -0
- package/dist/src/graphql/http/ActionsApiMiddlewareFactory.d.ts +10 -0
- package/dist/src/graphql/http/ActionsApiMiddlewareFactory.d.ts.map +1 -0
- package/dist/src/graphql/http/ActionsApiMiddlewareFactory.js +31 -0
- package/dist/src/graphql/http/ActionsApiMiddlewareFactory.js.map +1 -0
- package/dist/src/graphql/http/ActionsContextResolver.d.ts +11 -0
- package/dist/src/graphql/http/ActionsContextResolver.d.ts.map +1 -0
- package/dist/src/graphql/http/ActionsContextResolver.js +33 -0
- package/dist/src/graphql/http/ActionsContextResolver.js.map +1 -0
- package/dist/src/graphql/http/ActionsGraphQLHandlerFactory.d.ts +8 -0
- package/dist/src/graphql/http/ActionsGraphQLHandlerFactory.d.ts.map +1 -0
- package/dist/src/graphql/http/ActionsGraphQLHandlerFactory.js +21 -0
- package/dist/src/graphql/http/ActionsGraphQLHandlerFactory.js.map +1 -0
- package/dist/src/graphql/http/ActionsWebsocketControllerFactory.d.ts +11 -0
- package/dist/src/graphql/http/ActionsWebsocketControllerFactory.d.ts.map +1 -0
- package/dist/src/graphql/http/ActionsWebsocketControllerFactory.js +150 -0
- package/dist/src/graphql/http/ActionsWebsocketControllerFactory.js.map +1 -0
- package/dist/src/graphql/resolvers/ActionsContext.d.ts +9 -0
- package/dist/src/graphql/resolvers/ActionsContext.d.ts.map +1 -0
- package/dist/src/graphql/resolvers/ActionsContext.js +3 -0
- package/dist/src/graphql/resolvers/ActionsContext.js.map +1 -0
- package/dist/src/graphql/resolvers/ResolversFactory.d.ts +13 -0
- package/dist/src/graphql/resolvers/ResolversFactory.d.ts.map +1 -0
- package/dist/src/graphql/resolvers/ResolversFactory.js +32 -0
- package/dist/src/graphql/resolvers/ResolversFactory.js.map +1 -0
- package/dist/src/graphql/resolvers/index.d.ts +3 -0
- package/dist/src/graphql/resolvers/index.d.ts.map +1 -0
- package/dist/src/graphql/resolvers/index.js +19 -0
- package/dist/src/graphql/resolvers/index.js.map +1 -0
- package/dist/src/graphql/resolvers/mutation/ProcessBatchMutationResolver.d.ts +11 -0
- package/dist/src/graphql/resolvers/mutation/ProcessBatchMutationResolver.d.ts.map +1 -0
- package/dist/src/graphql/resolvers/mutation/ProcessBatchMutationResolver.js +16 -0
- package/dist/src/graphql/resolvers/mutation/ProcessBatchMutationResolver.js.map +1 -0
- package/dist/src/graphql/resolvers/mutation/SetVariablesMutationResolver.d.ts +11 -0
- package/dist/src/graphql/resolvers/mutation/SetVariablesMutationResolver.d.ts.map +1 -0
- package/dist/src/graphql/resolvers/mutation/SetVariablesMutationResolver.js +16 -0
- package/dist/src/graphql/resolvers/mutation/SetVariablesMutationResolver.js.map +1 -0
- package/dist/src/graphql/resolvers/mutation/index.d.ts +3 -0
- package/dist/src/graphql/resolvers/mutation/index.d.ts.map +1 -0
- package/dist/src/graphql/resolvers/mutation/index.js +19 -0
- package/dist/src/graphql/resolvers/mutation/index.js.map +1 -0
- package/dist/src/graphql/resolvers/query/EventsQueryResolver.d.ts +11 -0
- package/dist/src/graphql/resolvers/query/EventsQueryResolver.d.ts.map +1 -0
- package/dist/src/graphql/resolvers/query/EventsQueryResolver.js +43 -0
- package/dist/src/graphql/resolvers/query/EventsQueryResolver.js.map +1 -0
- package/dist/src/graphql/resolvers/query/VariablesQueryResolver.d.ts +12 -0
- package/dist/src/graphql/resolvers/query/VariablesQueryResolver.d.ts.map +1 -0
- package/dist/src/graphql/resolvers/query/VariablesQueryResolver.js +16 -0
- package/dist/src/graphql/resolvers/query/VariablesQueryResolver.js.map +1 -0
- package/dist/src/graphql/resolvers/query/index.d.ts +2 -0
- package/dist/src/graphql/resolvers/query/index.d.ts.map +1 -0
- package/dist/src/graphql/resolvers/query/index.js +18 -0
- package/dist/src/graphql/resolvers/query/index.js.map +1 -0
- package/dist/src/graphql/schema/actions.graphql.d.ts +3 -0
- package/dist/src/graphql/schema/actions.graphql.d.ts.map +1 -0
- package/dist/src/graphql/schema/actions.graphql.js +93 -0
- package/dist/src/graphql/schema/actions.graphql.js.map +1 -0
- package/dist/src/graphql/schema/index.d.ts +224 -0
- package/dist/src/graphql/schema/index.d.ts.map +1 -0
- package/dist/src/graphql/schema/index.js +3 -0
- package/dist/src/graphql/schema/index.js.map +1 -0
- package/dist/src/index.d.ts +13 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +81 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/migrations/2023-03-10-145000-actions-variables.d.ts +3 -0
- package/dist/src/migrations/2023-03-10-145000-actions-variables.d.ts.map +1 -0
- package/dist/src/migrations/2023-03-10-145000-actions-variables.js +17 -0
- package/dist/src/migrations/2023-03-10-145000-actions-variables.js.map +1 -0
- package/dist/src/migrations/index.d.ts +3 -0
- package/dist/src/migrations/index.d.ts.map +1 -0
- package/dist/src/migrations/index.js +13 -0
- package/dist/src/migrations/index.js.map +1 -0
- package/dist/src/migrations/snapshot.d.ts +3 -0
- package/dist/src/migrations/snapshot.d.ts.map +1 -0
- package/dist/src/migrations/snapshot.js +49 -0
- package/dist/src/migrations/snapshot.js.map +1 -0
- package/dist/src/model/EventsInProcessingQuery.d.ts +9 -0
- package/dist/src/model/EventsInProcessingQuery.d.ts.map +1 -0
- package/dist/src/model/EventsInProcessingQuery.js +22 -0
- package/dist/src/model/EventsInProcessingQuery.js.map +1 -0
- package/dist/src/model/EventsToProcessQuery.d.ts +9 -0
- package/dist/src/model/EventsToProcessQuery.d.ts.map +1 -0
- package/dist/src/model/EventsToProcessQuery.js +22 -0
- package/dist/src/model/EventsToProcessQuery.js.map +1 -0
- package/dist/src/model/EventsToProcessSpecification.d.ts +4 -0
- package/dist/src/model/EventsToProcessSpecification.d.ts.map +1 -0
- package/dist/src/model/EventsToProcessSpecification.js +14 -0
- package/dist/src/model/EventsToProcessSpecification.js.map +1 -0
- package/dist/src/model/FailedEventsQuery.d.ts +9 -0
- package/dist/src/model/FailedEventsQuery.d.ts.map +1 -0
- package/dist/src/model/FailedEventsQuery.js +22 -0
- package/dist/src/model/FailedEventsQuery.js.map +1 -0
- package/dist/src/model/SetVariableCommand.d.ts +8 -0
- package/dist/src/model/SetVariableCommand.d.ts.map +1 -0
- package/dist/src/model/SetVariableCommand.js +26 -0
- package/dist/src/model/SetVariableCommand.js.map +1 -0
- package/dist/src/model/VariablesManager.d.ts +8 -0
- package/dist/src/model/VariablesManager.d.ts.map +1 -0
- package/dist/src/model/VariablesManager.js +46 -0
- package/dist/src/model/VariablesManager.js.map +1 -0
- package/dist/src/model/VariablesQuery.d.ts +12 -0
- package/dist/src/model/VariablesQuery.d.ts.map +1 -0
- package/dist/src/model/VariablesQuery.js +13 -0
- package/dist/src/model/VariablesQuery.js.map +1 -0
- package/dist/src/model/types.d.ts +16 -0
- package/dist/src/model/types.d.ts.map +1 -0
- package/dist/src/model/types.js +3 -0
- package/dist/src/model/types.js.map +1 -0
- package/dist/src/triggers/Payload.d.ts +62 -0
- package/dist/src/triggers/Payload.d.ts.map +1 -0
- package/dist/src/triggers/Payload.js +3 -0
- package/dist/src/triggers/Payload.js.map +1 -0
- package/dist/src/triggers/TriggerHandler.d.ts +26 -0
- package/dist/src/triggers/TriggerHandler.d.ts.map +1 -0
- package/dist/src/triggers/TriggerHandler.js +130 -0
- package/dist/src/triggers/TriggerHandler.js.map +1 -0
- package/dist/src/triggers/TriggerIndirectChangesFetcher.d.ts +11 -0
- package/dist/src/triggers/TriggerIndirectChangesFetcher.d.ts.map +1 -0
- package/dist/src/triggers/TriggerIndirectChangesFetcher.js +24 -0
- package/dist/src/triggers/TriggerIndirectChangesFetcher.js.map +1 -0
- package/dist/src/triggers/TriggerListeners.d.ts +9 -0
- package/dist/src/triggers/TriggerListeners.d.ts.map +1 -0
- package/dist/src/triggers/TriggerListeners.js +3 -0
- package/dist/src/triggers/TriggerListeners.js.map +1 -0
- package/dist/src/triggers/TriggerListenersBuilder.d.ts +15 -0
- package/dist/src/triggers/TriggerListenersBuilder.d.ts.map +1 -0
- package/dist/src/triggers/TriggerListenersBuilder.js +169 -0
- package/dist/src/triggers/TriggerListenersBuilder.js.map +1 -0
- package/dist/src/triggers/TriggerListenersFactory.d.ts +8 -0
- package/dist/src/triggers/TriggerListenersFactory.d.ts.map +1 -0
- package/dist/src/triggers/TriggerListenersFactory.js +18 -0
- package/dist/src/triggers/TriggerListenersFactory.js.map +1 -0
- package/dist/src/triggers/TriggerListenersStore.d.ts +48 -0
- package/dist/src/triggers/TriggerListenersStore.d.ts.map +1 -0
- package/dist/src/triggers/TriggerListenersStore.js +30 -0
- package/dist/src/triggers/TriggerListenersStore.js.map +1 -0
- package/dist/src/triggers/TriggerPayloadBuilder.d.ts +14 -0
- package/dist/src/triggers/TriggerPayloadBuilder.d.ts.map +1 -0
- package/dist/src/triggers/TriggerPayloadBuilder.js +140 -0
- package/dist/src/triggers/TriggerPayloadBuilder.js.map +1 -0
- package/dist/src/triggers/TriggerPayloadManager.d.ts +27 -0
- package/dist/src/triggers/TriggerPayloadManager.d.ts.map +1 -0
- package/dist/src/triggers/TriggerPayloadManager.js +26 -0
- package/dist/src/triggers/TriggerPayloadManager.js.map +1 -0
- package/dist/src/triggers/TriggerPayloadPersister.d.ts +18 -0
- package/dist/src/triggers/TriggerPayloadPersister.d.ts.map +1 -0
- package/dist/src/triggers/TriggerPayloadPersister.js +44 -0
- package/dist/src/triggers/TriggerPayloadPersister.js.map +1 -0
- package/dist/src/triggers/index.d.ts +8 -0
- package/dist/src/triggers/index.d.ts.map +1 -0
- package/dist/src/triggers/index.js +24 -0
- package/dist/src/triggers/index.js.map +1 -0
- package/dist/src/tsconfig.tsbuildinfo +1 -0
- package/dist/src/utils/assertNever.d.ts +2 -0
- package/dist/src/utils/assertNever.d.ts.map +1 -0
- package/dist/src/utils/assertNever.js +8 -0
- package/dist/src/utils/assertNever.js.map +1 -0
- package/dist/src/utils/map.d.ts +2 -0
- package/dist/src/utils/map.d.ts.map +1 -0
- package/dist/src/utils/map.js +14 -0
- package/dist/src/utils/map.js.map +1 -0
- package/dist/tests/cases/integration/triggers.manyHasManyWatch.test.d.ts +2 -0
- package/dist/tests/cases/integration/triggers.manyHasManyWatch.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/triggers.manyHasManyWatch.test.js +442 -0
- package/dist/tests/cases/integration/triggers.manyHasManyWatch.test.js.map +1 -0
- package/dist/tests/cases/integration/triggers.manyHasOneWatch.test.d.ts +2 -0
- package/dist/tests/cases/integration/triggers.manyHasOneWatch.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/triggers.manyHasOneWatch.test.js +449 -0
- package/dist/tests/cases/integration/triggers.manyHasOneWatch.test.js.map +1 -0
- package/dist/tests/cases/integration/triggers.rootWatch.test.d.ts +2 -0
- package/dist/tests/cases/integration/triggers.rootWatch.test.d.ts.map +1 -0
- package/dist/tests/cases/integration/triggers.rootWatch.test.js +159 -0
- package/dist/tests/cases/integration/triggers.rootWatch.test.js.map +1 -0
- package/dist/tests/cases/integration/utils.d.ts +4 -0
- package/dist/tests/cases/integration/utils.d.ts.map +1 -0
- package/dist/tests/cases/integration/utils.js +12 -0
- package/dist/tests/cases/integration/utils.js.map +1 -0
- package/dist/tests/cases/unit/generator.test.d.ts +2 -0
- package/dist/tests/cases/unit/generator.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/generator.test.js +627 -0
- package/dist/tests/cases/unit/generator.test.js.map +1 -0
- package/dist/tests/src/gql.d.ts +2 -0
- package/dist/tests/src/gql.d.ts.map +1 -0
- package/dist/tests/src/gql.js +14 -0
- package/dist/tests/src/gql.js.map +1 -0
- package/dist/tests/tsconfig.tsbuildinfo +1 -0
- package/graphql-actions.codegen.yml +21 -0
- package/package.json +41 -0
- package/src/ActionsExecutionContainerHookFactory.ts +28 -0
- package/src/ImplementationException.ts +2 -0
- package/src/ListenerStoreProvider.ts +17 -0
- package/src/dispatch/DispatchWorkerSupervisor.ts +137 -0
- package/src/dispatch/EventDispatcher.ts +64 -0
- package/src/dispatch/EventsRepository.ts +165 -0
- package/src/dispatch/ProjectDispatcher.ts +119 -0
- package/src/dispatch/TargetHandlerResolver.ts +18 -0
- package/src/dispatch/WebhookTargetHandler.ts +88 -0
- package/src/dispatch/types.ts +31 -0
- package/src/graphql/http/ActionsApiMiddlewareFactory.ts +36 -0
- package/src/graphql/http/ActionsContextResolver.ts +38 -0
- package/src/graphql/http/ActionsGraphQLHandlerFactory.ts +23 -0
- package/src/graphql/http/ActionsWebsocketControllerFactory.ts +143 -0
- package/src/graphql/resolvers/ActionsContext.ts +9 -0
- package/src/graphql/resolvers/ResolversFactory.ts +35 -0
- package/src/graphql/resolvers/index.ts +2 -0
- package/src/graphql/resolvers/mutation/ProcessBatchMutationResolver.ts +16 -0
- package/src/graphql/resolvers/mutation/SetVariablesMutationResolver.ts +19 -0
- package/src/graphql/resolvers/mutation/index.ts +2 -0
- package/src/graphql/resolvers/query/EventsQueryResolver.ts +55 -0
- package/src/graphql/resolvers/query/VariablesQueryResolver.ts +18 -0
- package/src/graphql/resolvers/query/index.ts +1 -0
- package/src/graphql/schema/actions.graphql.ts +91 -0
- package/src/graphql/schema/index.ts +295 -0
- package/src/index.ts +88 -0
- package/src/migrations/2023-03-10-145000-actions-variables.ts +16 -0
- package/src/migrations/index.ts +7 -0
- package/src/migrations/snapshot.ts +47 -0
- package/src/model/EventsInProcessingQuery.ts +21 -0
- package/src/model/EventsToProcessQuery.ts +21 -0
- package/src/model/EventsToProcessSpecification.ts +11 -0
- package/src/model/FailedEventsQuery.ts +21 -0
- package/src/model/SetVariableCommand.ts +26 -0
- package/src/model/VariablesManager.ts +49 -0
- package/src/model/VariablesQuery.ts +17 -0
- package/src/model/types.ts +15 -0
- package/src/triggers/Payload.ts +82 -0
- package/src/triggers/TriggerHandler.ts +161 -0
- package/src/triggers/TriggerIndirectChangesFetcher.ts +30 -0
- package/src/triggers/TriggerListeners.ts +16 -0
- package/src/triggers/TriggerListenersBuilder.ts +190 -0
- package/src/triggers/TriggerListenersFactory.ts +19 -0
- package/src/triggers/TriggerListenersStore.ts +76 -0
- package/src/triggers/TriggerPayloadBuilder.ts +148 -0
- package/src/triggers/TriggerPayloadManager.ts +47 -0
- package/src/triggers/TriggerPayloadPersister.ts +43 -0
- package/src/triggers/index.ts +7 -0
- package/src/tsconfig.json +21 -0
- package/src/utils/assertNever.ts +3 -0
- package/src/utils/map.ts +13 -0
- package/tests/cases/integration/triggers.manyHasManyWatch.test.ts +437 -0
- package/tests/cases/integration/triggers.manyHasOneWatch.test.ts +446 -0
- package/tests/cases/integration/triggers.rootWatch.test.ts +152 -0
- package/tests/cases/integration/utils.ts +9 -0
- package/tests/cases/unit/generator.test.ts +689 -0
- package/tests/src/gql.ts +7 -0
- package/tests/tsconfig.json +16 -0
- package/tsconfig.json +5 -0
- package/tsconfig.settings.json +8 -0
- package/vite.config.js +3 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Actions } from '@contember/schema'
|
|
2
|
+
import { HandledEvent, InvokeHandler, InvokeHandlerArgs } from './types'
|
|
3
|
+
import { VariablesMap } from '../model/VariablesManager'
|
|
4
|
+
|
|
5
|
+
const DEFAULT_TIMEOUT_MS = 30_000 // 30 seconds
|
|
6
|
+
|
|
7
|
+
export class WebhookTargetHandler implements InvokeHandler<Actions.WebhookTarget> {
|
|
8
|
+
public async handle({ target, events, logger, variables }: InvokeHandlerArgs<Actions.WebhookTarget>): Promise<HandledEvent[]> {
|
|
9
|
+
const abortController = new AbortController()
|
|
10
|
+
const timeoutMs = target.timeoutMs
|
|
11
|
+
|
|
12
|
+
const start = process.hrtime.bigint()
|
|
13
|
+
const getDuration = () => Math.floor(Number((process.hrtime.bigint() - start) / BigInt(1_000_000)))
|
|
14
|
+
try {
|
|
15
|
+
const resolvedUrl = this.resolveVariables(target.url, variables)
|
|
16
|
+
const resolvedHeaders = Object.fromEntries(Object.entries(target.headers ?? {})
|
|
17
|
+
.map(([key, value]) => [key, this.resolveVariables(value, variables)]))
|
|
18
|
+
|
|
19
|
+
const response = await withTimeout({ abortController, timeoutMs }, async () => {
|
|
20
|
+
|
|
21
|
+
return await fetch(resolvedUrl, {
|
|
22
|
+
method: 'POST',
|
|
23
|
+
headers: {
|
|
24
|
+
['User-Agent']: 'Contember Actions',
|
|
25
|
+
...resolvedHeaders,
|
|
26
|
+
['Content-type']: 'application/json',
|
|
27
|
+
},
|
|
28
|
+
signal: abortController.signal,
|
|
29
|
+
body: JSON.stringify({
|
|
30
|
+
events: events.map(it => it.payload),
|
|
31
|
+
}),
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
let responseText
|
|
35
|
+
try {
|
|
36
|
+
responseText = await withTimeout({ abortController, timeoutMs }, async () => {
|
|
37
|
+
return await response.text()
|
|
38
|
+
})
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
const result = {
|
|
42
|
+
ok: response.ok,
|
|
43
|
+
code: response.status,
|
|
44
|
+
durationMs: getDuration(),
|
|
45
|
+
response: responseText,
|
|
46
|
+
errorMessage: !response.ok ? response.statusText : undefined,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// todo: per-event response format
|
|
50
|
+
|
|
51
|
+
return events.map(it => ({ target, row: it, result }))
|
|
52
|
+
} catch (e) {
|
|
53
|
+
logger.warn(e)
|
|
54
|
+
const errorMessages = []
|
|
55
|
+
let err = e
|
|
56
|
+
while (typeof err === 'object' && err !== null && 'message' in err && typeof (err as any).message === 'string') {
|
|
57
|
+
errorMessages.push((err as any).message)
|
|
58
|
+
err = (err as any).cause
|
|
59
|
+
}
|
|
60
|
+
const result = {
|
|
61
|
+
ok: false,
|
|
62
|
+
errorMessage: errorMessages.length ? errorMessages.join('; ') : undefined,
|
|
63
|
+
durationMs: getDuration(),
|
|
64
|
+
}
|
|
65
|
+
return events.map(it => ({ target, row: it, result }))
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private resolveVariables(subject: string, variables: VariablesMap) {
|
|
70
|
+
return subject.replace(/\{\{([\w_]+)}}/gm, (_, name) => {
|
|
71
|
+
if (!variables[name]) {
|
|
72
|
+
throw new Error(`Undefined variable ${name}`)
|
|
73
|
+
}
|
|
74
|
+
return variables[name]
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const withTimeout = async <T>({ abortController, timeoutMs }: { abortController: AbortController; timeoutMs?: number }, cb: () => Promise<T>): Promise<T> => {
|
|
80
|
+
const timeoutId = setTimeout(() => {
|
|
81
|
+
abortController.abort()
|
|
82
|
+
}, timeoutMs ?? DEFAULT_TIMEOUT_MS)
|
|
83
|
+
try {
|
|
84
|
+
return await cb()
|
|
85
|
+
} finally {
|
|
86
|
+
clearTimeout(timeoutId)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Logger } from '@contember/logger'
|
|
2
|
+
import { Actions } from '@contember/schema'
|
|
3
|
+
import { EventRow } from '../model/types'
|
|
4
|
+
import { VariablesMap } from '../model/VariablesManager'
|
|
5
|
+
|
|
6
|
+
export { EventRow }
|
|
7
|
+
|
|
8
|
+
export interface InvokeHandler<Target extends Actions.AnyTarget> {
|
|
9
|
+
handle(args: InvokeHandlerArgs<Target>): Promise<HandledEvent[]>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface InvokeHandlerArgs<Target extends Actions.AnyTarget> {
|
|
13
|
+
target: Target
|
|
14
|
+
events: EventRow[]
|
|
15
|
+
logger: Logger
|
|
16
|
+
variables: VariablesMap
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type HandledEvent = {
|
|
20
|
+
row: EventRow
|
|
21
|
+
result: InvocationResult
|
|
22
|
+
target?: Actions.AnyTarget
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type InvocationResult = {
|
|
26
|
+
ok: boolean
|
|
27
|
+
durationMs?: number
|
|
28
|
+
errorMessage?: string
|
|
29
|
+
code?: number
|
|
30
|
+
response?: string
|
|
31
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { HttpController } from '@contember/engine-http'
|
|
2
|
+
import { ActionsGraphQLHandler } from './ActionsGraphQLHandlerFactory'
|
|
3
|
+
import { ActionsContext } from '../resolvers/ActionsContext'
|
|
4
|
+
import { ActionsContextResolver } from './ActionsContextResolver'
|
|
5
|
+
|
|
6
|
+
export class ActionsApiMiddlewareFactory {
|
|
7
|
+
constructor(
|
|
8
|
+
private readonly actionsContextResolver: ActionsContextResolver,
|
|
9
|
+
private readonly actionsGraphQLHandler: ActionsGraphQLHandler,
|
|
10
|
+
) {
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
create(): HttpController {
|
|
14
|
+
return async ctx => {
|
|
15
|
+
const { timer, logger, koa } = ctx
|
|
16
|
+
const { projectContainer } = await this.actionsContextResolver.resolve(ctx)
|
|
17
|
+
|
|
18
|
+
const systemDatabase = projectContainer.systemDatabaseContextFactory.create()
|
|
19
|
+
|
|
20
|
+
logger.debug('Actions query processing started')
|
|
21
|
+
const graphqlContext: ActionsContext = {
|
|
22
|
+
db: systemDatabase,
|
|
23
|
+
logger,
|
|
24
|
+
contentSchemaResolver: projectContainer.contentSchemaResolver,
|
|
25
|
+
}
|
|
26
|
+
const handler = this.actionsGraphQLHandler
|
|
27
|
+
|
|
28
|
+
await timer('GraphQL', () => handler({
|
|
29
|
+
request: koa.request,
|
|
30
|
+
response: koa.response,
|
|
31
|
+
createContext: () => graphqlContext,
|
|
32
|
+
}))
|
|
33
|
+
logger.debug('Actions query finished')
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ApplicationContext, HttpErrorResponse, ProjectContextResolver } from '@contember/engine-http'
|
|
2
|
+
import { ProjectRole } from '@contember/schema'
|
|
3
|
+
|
|
4
|
+
export class ActionsContextResolver {
|
|
5
|
+
constructor(
|
|
6
|
+
private readonly debug: boolean,
|
|
7
|
+
private readonly projectContextResolver: ProjectContextResolver,
|
|
8
|
+
) {
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async resolve(ctx: ApplicationContext) {
|
|
12
|
+
const { timer, projectGroup: { tenantContainer }, logger, authResult } = ctx
|
|
13
|
+
const projectContext = await this.projectContextResolver.resolve(ctx)
|
|
14
|
+
const { project } = projectContext
|
|
15
|
+
if (!authResult) {
|
|
16
|
+
throw new HttpErrorResponse(401, 'Authentication required')
|
|
17
|
+
}
|
|
18
|
+
const memberships = await timer('MembershipFetch', () =>
|
|
19
|
+
tenantContainer.projectMemberManager.getEffectiveProjectMemberships(
|
|
20
|
+
tenantContainer.databaseContext,
|
|
21
|
+
{ slug: project.slug },
|
|
22
|
+
{
|
|
23
|
+
id: authResult.identityId,
|
|
24
|
+
roles: authResult.roles,
|
|
25
|
+
},
|
|
26
|
+
),
|
|
27
|
+
)
|
|
28
|
+
logger.debug('Memberships fetched', { memberships })
|
|
29
|
+
|
|
30
|
+
const isProjectAdmin = memberships.some(it => it.role === ProjectRole.ADMIN)
|
|
31
|
+
if (!isProjectAdmin) {
|
|
32
|
+
throw this.debug
|
|
33
|
+
? new HttpErrorResponse(404, `You are not allowed to access project ${project.slug}`)
|
|
34
|
+
: new HttpErrorResponse(404, `Project ${project.slug} NOT found`)
|
|
35
|
+
}
|
|
36
|
+
return projectContext
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { makeExecutableSchema } from '@graphql-tools/schema'
|
|
2
|
+
import { createGraphQLQueryHandler, GraphQLQueryHandler } from '@contember/engine-http'
|
|
3
|
+
import { ResolversFactory } from '../resolvers/ResolversFactory'
|
|
4
|
+
import { schema as graphqlDocument } from '../schema/actions.graphql'
|
|
5
|
+
import { ActionsContext } from '../resolvers/ActionsContext'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export type ActionsGraphQLHandler = GraphQLQueryHandler<ActionsContext>
|
|
9
|
+
|
|
10
|
+
export class ActionsGraphQLHandlerFactory {
|
|
11
|
+
create(resolversFactory: ResolversFactory): ActionsGraphQLHandler {
|
|
12
|
+
const resolvers = resolversFactory.create()
|
|
13
|
+
const schema = makeExecutableSchema({
|
|
14
|
+
typeDefs: graphqlDocument,
|
|
15
|
+
resolvers,
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
return createGraphQLQueryHandler<ActionsContext>({
|
|
19
|
+
schema,
|
|
20
|
+
listeners: [],
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { HttpErrorResponse, WebSocketController } from '@contember/engine-http'
|
|
2
|
+
import { ActionsContextResolver } from './ActionsContextResolver'
|
|
3
|
+
import { DispatchWorkerSupervisorFactory } from '../../dispatch/DispatchWorkerSupervisor'
|
|
4
|
+
import * as Typesafe from '@contember/typesafe'
|
|
5
|
+
import { TenantRole } from '@contember/engine-tenant-api'
|
|
6
|
+
import { Running } from '@contember/engine-common'
|
|
7
|
+
|
|
8
|
+
const IncomingMessage = Typesafe.discriminatedUnion(
|
|
9
|
+
'type',
|
|
10
|
+
{
|
|
11
|
+
startWorker: Typesafe.object({}),
|
|
12
|
+
stopAllWorkers: Typesafe.object({}),
|
|
13
|
+
},
|
|
14
|
+
)
|
|
15
|
+
type IncomingMessage = ReturnType<typeof IncomingMessage>
|
|
16
|
+
const OutgoingMessage = Typesafe.discriminatedUnion(
|
|
17
|
+
'type',
|
|
18
|
+
{
|
|
19
|
+
error: Typesafe.object({
|
|
20
|
+
message: Typesafe.string,
|
|
21
|
+
}),
|
|
22
|
+
message: Typesafe.object({
|
|
23
|
+
message: Typesafe.string,
|
|
24
|
+
}),
|
|
25
|
+
ready: Typesafe.object({}),
|
|
26
|
+
|
|
27
|
+
workerStarted: Typesafe.object({
|
|
28
|
+
workerId: Typesafe.string,
|
|
29
|
+
}),
|
|
30
|
+
workedStopped: Typesafe.object({
|
|
31
|
+
workerId: Typesafe.string,
|
|
32
|
+
}),
|
|
33
|
+
workerFailedToStart: Typesafe.object({
|
|
34
|
+
workerId: Typesafe.string,
|
|
35
|
+
}),
|
|
36
|
+
workerCrashed: Typesafe.object({
|
|
37
|
+
workerId: Typesafe.string,
|
|
38
|
+
}),
|
|
39
|
+
},
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
type OutgoingMessage = ReturnType<typeof OutgoingMessage>
|
|
43
|
+
|
|
44
|
+
export class ActionsWebsocketControllerFactory {
|
|
45
|
+
constructor(
|
|
46
|
+
private readonly debug: boolean,
|
|
47
|
+
private readonly actionsContextResolver: ActionsContextResolver,
|
|
48
|
+
private readonly dispatchWorkerSupervisorFactory: DispatchWorkerSupervisorFactory,
|
|
49
|
+
) {
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
create(): WebSocketController {
|
|
53
|
+
return async ctx => {
|
|
54
|
+
const { ws, logger, authResult, projectGroup } = ctx
|
|
55
|
+
if (!authResult) {
|
|
56
|
+
throw new HttpErrorResponse(401, 'Authentication required')
|
|
57
|
+
}
|
|
58
|
+
if (!authResult.roles.some(it => it === TenantRole.SUPER_ADMIN || it === TenantRole.PROJECT_ADMIN)) {
|
|
59
|
+
throw new HttpErrorResponse(403, 'Not allowed to run actions worker')
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const send = (message: OutgoingMessage) => {
|
|
63
|
+
if (this.debug) {
|
|
64
|
+
OutgoingMessage(message)
|
|
65
|
+
}
|
|
66
|
+
ws.send(JSON.stringify(message))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let workers: { id: string; running: Running }[] = []
|
|
70
|
+
const abortListener = async () => {
|
|
71
|
+
send({ type: 'message', message: 'shutting down' })
|
|
72
|
+
await stopAll()
|
|
73
|
+
send({ type: 'message', message: 'closing connection' })
|
|
74
|
+
ws.close(1012) // Service Restart
|
|
75
|
+
}
|
|
76
|
+
ctx.abortSignal.addEventListener('abort', abortListener)
|
|
77
|
+
|
|
78
|
+
const stopAll = async () => {
|
|
79
|
+
const currentWorkers = workers.map(it => it.running.end().then(() => send({
|
|
80
|
+
type: 'workedStopped',
|
|
81
|
+
workerId: it.id,
|
|
82
|
+
})))
|
|
83
|
+
workers = []
|
|
84
|
+
await Promise.all(currentWorkers)
|
|
85
|
+
}
|
|
86
|
+
send({ type: 'ready' })
|
|
87
|
+
|
|
88
|
+
ws.addEventListener('message', async message => {
|
|
89
|
+
let json
|
|
90
|
+
try {
|
|
91
|
+
json = JSON.parse(message.data.toString())
|
|
92
|
+
} catch {
|
|
93
|
+
send({ type: 'error', message: 'Invalid JSON' })
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
let data: IncomingMessage
|
|
97
|
+
try {
|
|
98
|
+
data = IncomingMessage(json)
|
|
99
|
+
} catch (e) {
|
|
100
|
+
if (e instanceof Typesafe.ParseError) {
|
|
101
|
+
send({ type: 'error', message: e.message })
|
|
102
|
+
return
|
|
103
|
+
} else {
|
|
104
|
+
throw e
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
switch (data.type) {
|
|
109
|
+
case 'startWorker':
|
|
110
|
+
const workerId = Math.random().toString().substring(2)
|
|
111
|
+
const dispatchSupervisor = this.dispatchWorkerSupervisorFactory.create(projectGroup)
|
|
112
|
+
try {
|
|
113
|
+
const running = await dispatchSupervisor.run({ logger, onError: () => {
|
|
114
|
+
send({ type: 'workerCrashed', workerId })
|
|
115
|
+
} })
|
|
116
|
+
workers.push({ id: workerId, running })
|
|
117
|
+
send({ type: 'workerStarted', workerId })
|
|
118
|
+
} catch (e) {
|
|
119
|
+
logger.error(e, { message: 'Worker failed to start' })
|
|
120
|
+
send({ type: 'workerFailedToStart', workerId })
|
|
121
|
+
}
|
|
122
|
+
break
|
|
123
|
+
case 'stopAllWorkers':
|
|
124
|
+
send({ type: 'message', message: 'stopping' })
|
|
125
|
+
await stopAll()
|
|
126
|
+
send({ type: 'message', message: 'all stopped' })
|
|
127
|
+
break
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
const pingHandle = setInterval(() => {
|
|
132
|
+
ws.ping()
|
|
133
|
+
}, 5000)
|
|
134
|
+
|
|
135
|
+
ws.addEventListener('close', async () => {
|
|
136
|
+
ctx.abortSignal.removeEventListener('abort', abortListener)
|
|
137
|
+
clearInterval(pingHandle)
|
|
138
|
+
await stopAll()
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DatabaseContext } from '@contember/engine-system-api'
|
|
2
|
+
import { ContentSchemaResolver } from '@contember/engine-http'
|
|
3
|
+
import { Logger } from '@contember/logger'
|
|
4
|
+
|
|
5
|
+
export interface ActionsContext {
|
|
6
|
+
logger: Logger
|
|
7
|
+
db: DatabaseContext
|
|
8
|
+
contentSchemaResolver: ContentSchemaResolver
|
|
9
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { DateTimeType, JSONType, UuidType } from '@contember/graphql-utils'
|
|
2
|
+
import { Resolvers } from '../schema'
|
|
3
|
+
import { EventsQueryResolver } from './query'
|
|
4
|
+
import { ProcessBatchMutationResolver, SetVariablesMutationResolver } from './mutation'
|
|
5
|
+
import { ActionsContext } from './ActionsContext'
|
|
6
|
+
import { VariablesQueryResolver } from './query/VariablesQueryResolver'
|
|
7
|
+
|
|
8
|
+
export class ResolversFactory {
|
|
9
|
+
constructor(
|
|
10
|
+
private readonly eventsQueryResolver: EventsQueryResolver,
|
|
11
|
+
private readonly processBatchMutationResolver: ProcessBatchMutationResolver,
|
|
12
|
+
private readonly variablesQueryResolver: VariablesQueryResolver,
|
|
13
|
+
private readonly setVariablesMutationResolver: SetVariablesMutationResolver,
|
|
14
|
+
) {
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
create(): Resolvers {
|
|
18
|
+
const resolvers: Resolvers<ActionsContext> & { Mutation: Required<Resolvers<ActionsContext>['Mutation']> } & { Query: Required<Resolvers<ActionsContext>['Query']> } = {
|
|
19
|
+
Json: JSONType,
|
|
20
|
+
DateTime: DateTimeType,
|
|
21
|
+
Uuid: UuidType,
|
|
22
|
+
Mutation: {
|
|
23
|
+
processBatch: this.processBatchMutationResolver.processBatch.bind(this.processBatchMutationResolver),
|
|
24
|
+
setVariables: this.setVariablesMutationResolver.setVariables.bind(this.setVariablesMutationResolver),
|
|
25
|
+
},
|
|
26
|
+
Query: {
|
|
27
|
+
eventsInProcessing: this.eventsQueryResolver.eventsInProcessing.bind(this.eventsQueryResolver),
|
|
28
|
+
eventsToProcess: this.eventsQueryResolver.eventsToProcess.bind(this.eventsQueryResolver),
|
|
29
|
+
failedEvents: this.eventsQueryResolver.failedEvents.bind(this.eventsQueryResolver),
|
|
30
|
+
variables: this.variablesQueryResolver.variables.bind(this.variablesQueryResolver),
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
return resolvers
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { MutationResolvers } from '../../schema'
|
|
2
|
+
import { ActionsContext } from '../ActionsContext'
|
|
3
|
+
import { EventDispatcher } from '../../../dispatch/EventDispatcher'
|
|
4
|
+
|
|
5
|
+
export class ProcessBatchMutationResolver implements MutationResolvers<ActionsContext> {
|
|
6
|
+
constructor(
|
|
7
|
+
private eventDispatcher: EventDispatcher,
|
|
8
|
+
) {
|
|
9
|
+
}
|
|
10
|
+
async processBatch(parent: unknown, args: unknown, ctx: ActionsContext) {
|
|
11
|
+
await this.eventDispatcher.processBatch(ctx)
|
|
12
|
+
return {
|
|
13
|
+
ok: true,
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { MutationResolvers, MutationSetVariablesArgs } from '../../schema'
|
|
2
|
+
import { ActionsContext } from '../ActionsContext'
|
|
3
|
+
import { VariablesManager } from '../../../model/VariablesManager'
|
|
4
|
+
|
|
5
|
+
export class SetVariablesMutationResolver implements MutationResolvers<ActionsContext> {
|
|
6
|
+
constructor(
|
|
7
|
+
private readonly variablesManager: VariablesManager,
|
|
8
|
+
) {
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async setVariables(parent: unknown, { args }: MutationSetVariablesArgs, ctx: ActionsContext) {
|
|
13
|
+
await this.variablesManager.setVariables(ctx.db, args)
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
ok: true,
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Event,
|
|
3
|
+
QueryEventsInProcessingArgs,
|
|
4
|
+
QueryEventsToProcessArgs,
|
|
5
|
+
QueryFailedEventsArgs,
|
|
6
|
+
QueryResolvers,
|
|
7
|
+
} from '../../schema'
|
|
8
|
+
import { ActionsContext } from '../ActionsContext'
|
|
9
|
+
import { EventsToProcessQuery } from '../../../model/EventsToProcessQuery'
|
|
10
|
+
import { EventRow } from '../../../model/types'
|
|
11
|
+
import { DatabaseContext, StagesQuery } from '@contember/engine-system-api'
|
|
12
|
+
import { Client, DatabaseQuery } from '@contember/database'
|
|
13
|
+
import { EventsInProcessingQuery } from '../../../model/EventsInProcessingQuery'
|
|
14
|
+
import { FailedEventsQuery } from '../../../model/FailedEventsQuery'
|
|
15
|
+
|
|
16
|
+
export class EventsQueryResolver implements QueryResolvers<ActionsContext> {
|
|
17
|
+
async eventsInProcessing(parent: unknown, { args }: QueryEventsInProcessingArgs, ctx: ActionsContext) {
|
|
18
|
+
return await this.fetchEvents(ctx.db, new EventsInProcessingQuery(args ?? {}))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async eventsToProcess(parent: unknown, { args }: QueryEventsToProcessArgs, ctx: ActionsContext) {
|
|
22
|
+
return await this.fetchEvents(ctx.db, new EventsToProcessQuery(args ?? {}))
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async failedEvents(parent: unknown, { args }: QueryFailedEventsArgs, ctx: ActionsContext) {
|
|
26
|
+
return await this.fetchEvents(ctx.db, new FailedEventsQuery(args ?? {}))
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private async fetchEvents(db: DatabaseContext, query: DatabaseQuery<EventRow[]>) {
|
|
30
|
+
const stages = await this.fetchStagesMap(db)
|
|
31
|
+
return this.mapEventRows(await db.queryHandler.fetch(query), stages)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private async fetchStagesMap(db: DatabaseContext): Promise<Record<string, string>> {
|
|
35
|
+
return Object.fromEntries((await db.queryHandler.fetch(new StagesQuery())).map(it => [it.id, it.slug]))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private mapEventRows(rows: EventRow[], stagesMap: Record<string, string>): Event[] {
|
|
39
|
+
|
|
40
|
+
return rows.map(row => ({
|
|
41
|
+
id: row.id,
|
|
42
|
+
createdAt: row.created_at,
|
|
43
|
+
resolvedAt: row.created_at,
|
|
44
|
+
lastStateChange: row.last_state_change,
|
|
45
|
+
visibleAt: row.visible_at,
|
|
46
|
+
log: row.log,
|
|
47
|
+
numRetries: row.num_retries,
|
|
48
|
+
payload: row.payload,
|
|
49
|
+
stage: stagesMap[row.stage_id],
|
|
50
|
+
state: row.state,
|
|
51
|
+
target: row.target,
|
|
52
|
+
transactionId: row.transaction_id,
|
|
53
|
+
}))
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { QueryResolvers } from '../../schema'
|
|
2
|
+
import { ActionsContext } from '../ActionsContext'
|
|
3
|
+
import { VariablesManager } from '../../../model/VariablesManager'
|
|
4
|
+
|
|
5
|
+
export class VariablesQueryResolver implements QueryResolvers<ActionsContext> {
|
|
6
|
+
|
|
7
|
+
constructor(
|
|
8
|
+
private readonly variablesManager: VariablesManager,
|
|
9
|
+
) {
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async variables(parent: unknown, args: unknown, ctx: ActionsContext) {
|
|
13
|
+
return Object.entries(await this.variablesManager.fetchVariables(ctx.db)).map(([name, value]) => ({
|
|
14
|
+
name,
|
|
15
|
+
value,
|
|
16
|
+
}))
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './EventsQueryResolver'
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { gql } from 'graphql-tag'
|
|
2
|
+
import { DocumentNode } from 'graphql'
|
|
3
|
+
|
|
4
|
+
export const schema: DocumentNode = gql`
|
|
5
|
+
scalar DateTime
|
|
6
|
+
scalar Json
|
|
7
|
+
scalar Uuid
|
|
8
|
+
|
|
9
|
+
schema {
|
|
10
|
+
query: Query
|
|
11
|
+
mutation: Mutation
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type Query {
|
|
15
|
+
failedEvents(args: EventArgs): [Event!]!
|
|
16
|
+
eventsToProcess(args: EventArgs): [Event!]!
|
|
17
|
+
eventsInProcessing(args: EventArgs): [Event!]!
|
|
18
|
+
variables: [Variable!]!
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type Mutation {
|
|
22
|
+
processBatch: ProcessBatchResponse!
|
|
23
|
+
setVariables(args: SetVariablesArgs!): SetVariablesResponse!
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
input EventArgs {
|
|
27
|
+
offset: Int
|
|
28
|
+
"Max 10000"
|
|
29
|
+
limit: Int
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type Event {
|
|
33
|
+
id: Uuid!
|
|
34
|
+
transactionId: Uuid!
|
|
35
|
+
createdAt: DateTime!
|
|
36
|
+
lastStateChange: DateTime!
|
|
37
|
+
resolvedAt: DateTime
|
|
38
|
+
visibleAt: DateTime
|
|
39
|
+
numRetries: Int!
|
|
40
|
+
state: EventState!
|
|
41
|
+
stage: String!
|
|
42
|
+
target: String!
|
|
43
|
+
payload: Json!
|
|
44
|
+
log: Json!
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
enum EventState {
|
|
48
|
+
created
|
|
49
|
+
retrying
|
|
50
|
+
processing
|
|
51
|
+
succeed
|
|
52
|
+
failed
|
|
53
|
+
stopped
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
type ProcessBatchResponse {
|
|
57
|
+
ok: Boolean!
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
input SetVariablesArgs {
|
|
61
|
+
variables: [VariableInput!]!
|
|
62
|
+
mode: SetVariablesMode
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
"""
|
|
66
|
+
Defines how it handles original variables.
|
|
67
|
+
- MERGE merges with new values (default behaviour)
|
|
68
|
+
- SET replaces all variables
|
|
69
|
+
- APPEND_ONLY_MISSING appends values if not already exist
|
|
70
|
+
"""
|
|
71
|
+
enum SetVariablesMode {
|
|
72
|
+
MERGE
|
|
73
|
+
SET
|
|
74
|
+
APPEND_ONLY_MISSING
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
input VariableInput {
|
|
78
|
+
name: String!
|
|
79
|
+
value: String!
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
type SetVariablesResponse {
|
|
83
|
+
ok: Boolean!
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
type Variable {
|
|
87
|
+
name: String!
|
|
88
|
+
value: String!
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
`
|