@contember/engine-actions 2.2.0-alpha.3 → 2.2.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.
Files changed (200) hide show
  1. package/CLAUDE.md +58 -0
  2. package/dist/development/index.cjs +19 -7
  3. package/dist/development/index.cjs.map +1 -1
  4. package/dist/development/index.js +19 -7
  5. package/dist/development/index.js.map +1 -1
  6. package/dist/development/src/ActionsExecutionContainerHookFactory.cjs +5 -2
  7. package/dist/development/src/ActionsExecutionContainerHookFactory.cjs.map +1 -1
  8. package/dist/development/src/ActionsExecutionContainerHookFactory.js +5 -2
  9. package/dist/development/src/ActionsExecutionContainerHookFactory.js.map +1 -1
  10. package/dist/development/src/ActionsMetrics.cjs +98 -0
  11. package/dist/development/src/ActionsMetrics.cjs.map +1 -0
  12. package/dist/development/src/ActionsMetrics.js +98 -0
  13. package/dist/development/src/ActionsMetrics.js.map +1 -0
  14. package/dist/development/src/dispatch/EventDispatcher.cjs +27 -9
  15. package/dist/development/src/dispatch/EventDispatcher.cjs.map +1 -1
  16. package/dist/development/src/dispatch/EventDispatcher.js +27 -9
  17. package/dist/development/src/dispatch/EventDispatcher.js.map +1 -1
  18. package/dist/development/src/dispatch/EventsRepository.cjs +49 -20
  19. package/dist/development/src/dispatch/EventsRepository.cjs.map +1 -1
  20. package/dist/development/src/dispatch/EventsRepository.js +49 -20
  21. package/dist/development/src/dispatch/EventsRepository.js.map +1 -1
  22. package/dist/development/src/dispatch/ProjectDispatcher.cjs +21 -13
  23. package/dist/development/src/dispatch/ProjectDispatcher.cjs.map +1 -1
  24. package/dist/development/src/dispatch/ProjectDispatcher.js +21 -13
  25. package/dist/development/src/dispatch/ProjectDispatcher.js.map +1 -1
  26. package/dist/development/src/dispatch/WebhookTargetHandler.cjs +29 -2
  27. package/dist/development/src/dispatch/WebhookTargetHandler.cjs.map +1 -1
  28. package/dist/development/src/dispatch/WebhookTargetHandler.js +29 -2
  29. package/dist/development/src/dispatch/WebhookTargetHandler.js.map +1 -1
  30. package/dist/development/src/graphql/resolvers/ResolversFactory.cjs +1 -1
  31. package/dist/development/src/graphql/resolvers/ResolversFactory.cjs.map +1 -1
  32. package/dist/development/src/graphql/resolvers/ResolversFactory.js +1 -1
  33. package/dist/development/src/graphql/resolvers/ResolversFactory.js.map +1 -1
  34. package/dist/development/src/graphql/resolvers/mutation/SetVariablesMutationResolver.cjs +1 -1
  35. package/dist/development/src/graphql/resolvers/mutation/SetVariablesMutationResolver.cjs.map +1 -1
  36. package/dist/development/src/graphql/resolvers/mutation/SetVariablesMutationResolver.js +1 -1
  37. package/dist/development/src/graphql/resolvers/mutation/SetVariablesMutationResolver.js.map +1 -1
  38. package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.cjs +1 -1
  39. package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.cjs.map +1 -1
  40. package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.js +1 -1
  41. package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.js.map +1 -1
  42. package/dist/development/src/graphql/resolvers/query/VariablesQueryResolver.cjs +1 -4
  43. package/dist/development/src/graphql/resolvers/query/VariablesQueryResolver.cjs.map +1 -1
  44. package/dist/development/src/graphql/resolvers/query/VariablesQueryResolver.js +1 -4
  45. package/dist/development/src/graphql/resolvers/query/VariablesQueryResolver.js.map +1 -1
  46. package/dist/development/src/graphql/schema/actions.graphql.cjs +20 -8
  47. package/dist/development/src/graphql/schema/actions.graphql.cjs.map +1 -1
  48. package/dist/development/src/graphql/schema/actions.graphql.js +20 -8
  49. package/dist/development/src/graphql/schema/actions.graphql.js.map +1 -1
  50. package/dist/development/src/model/VariablesManager.cjs +54 -5
  51. package/dist/development/src/model/VariablesManager.cjs.map +1 -1
  52. package/dist/development/src/model/VariablesManager.js +54 -5
  53. package/dist/development/src/model/VariablesManager.js.map +1 -1
  54. package/dist/development/src/triggers/TriggerPayloadPersister.cjs +3 -1
  55. package/dist/development/src/triggers/TriggerPayloadPersister.cjs.map +1 -1
  56. package/dist/development/src/triggers/TriggerPayloadPersister.js +3 -1
  57. package/dist/development/src/triggers/TriggerPayloadPersister.js.map +1 -1
  58. package/dist/production/index.cjs +19 -7
  59. package/dist/production/index.cjs.map +1 -1
  60. package/dist/production/index.js +19 -7
  61. package/dist/production/index.js.map +1 -1
  62. package/dist/production/src/ActionsExecutionContainerHookFactory.cjs +5 -2
  63. package/dist/production/src/ActionsExecutionContainerHookFactory.cjs.map +1 -1
  64. package/dist/production/src/ActionsExecutionContainerHookFactory.js +5 -2
  65. package/dist/production/src/ActionsExecutionContainerHookFactory.js.map +1 -1
  66. package/dist/production/src/ActionsMetrics.cjs +98 -0
  67. package/dist/production/src/ActionsMetrics.cjs.map +1 -0
  68. package/dist/production/src/ActionsMetrics.js +98 -0
  69. package/dist/production/src/ActionsMetrics.js.map +1 -0
  70. package/dist/production/src/dispatch/EventDispatcher.cjs +27 -9
  71. package/dist/production/src/dispatch/EventDispatcher.cjs.map +1 -1
  72. package/dist/production/src/dispatch/EventDispatcher.js +27 -9
  73. package/dist/production/src/dispatch/EventDispatcher.js.map +1 -1
  74. package/dist/production/src/dispatch/EventsRepository.cjs +49 -20
  75. package/dist/production/src/dispatch/EventsRepository.cjs.map +1 -1
  76. package/dist/production/src/dispatch/EventsRepository.js +49 -20
  77. package/dist/production/src/dispatch/EventsRepository.js.map +1 -1
  78. package/dist/production/src/dispatch/ProjectDispatcher.cjs +21 -13
  79. package/dist/production/src/dispatch/ProjectDispatcher.cjs.map +1 -1
  80. package/dist/production/src/dispatch/ProjectDispatcher.js +21 -13
  81. package/dist/production/src/dispatch/ProjectDispatcher.js.map +1 -1
  82. package/dist/production/src/dispatch/WebhookTargetHandler.cjs +29 -2
  83. package/dist/production/src/dispatch/WebhookTargetHandler.cjs.map +1 -1
  84. package/dist/production/src/dispatch/WebhookTargetHandler.js +29 -2
  85. package/dist/production/src/dispatch/WebhookTargetHandler.js.map +1 -1
  86. package/dist/production/src/graphql/resolvers/ResolversFactory.cjs +1 -1
  87. package/dist/production/src/graphql/resolvers/ResolversFactory.cjs.map +1 -1
  88. package/dist/production/src/graphql/resolvers/ResolversFactory.js +1 -1
  89. package/dist/production/src/graphql/resolvers/ResolversFactory.js.map +1 -1
  90. package/dist/production/src/graphql/resolvers/mutation/SetVariablesMutationResolver.cjs +1 -1
  91. package/dist/production/src/graphql/resolvers/mutation/SetVariablesMutationResolver.cjs.map +1 -1
  92. package/dist/production/src/graphql/resolvers/mutation/SetVariablesMutationResolver.js +1 -1
  93. package/dist/production/src/graphql/resolvers/mutation/SetVariablesMutationResolver.js.map +1 -1
  94. package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.cjs +1 -1
  95. package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.cjs.map +1 -1
  96. package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.js +1 -1
  97. package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.js.map +1 -1
  98. package/dist/production/src/graphql/resolvers/query/VariablesQueryResolver.cjs +1 -4
  99. package/dist/production/src/graphql/resolvers/query/VariablesQueryResolver.cjs.map +1 -1
  100. package/dist/production/src/graphql/resolvers/query/VariablesQueryResolver.js +1 -4
  101. package/dist/production/src/graphql/resolvers/query/VariablesQueryResolver.js.map +1 -1
  102. package/dist/production/src/graphql/schema/actions.graphql.cjs +20 -8
  103. package/dist/production/src/graphql/schema/actions.graphql.cjs.map +1 -1
  104. package/dist/production/src/graphql/schema/actions.graphql.js +20 -8
  105. package/dist/production/src/graphql/schema/actions.graphql.js.map +1 -1
  106. package/dist/production/src/model/VariablesManager.cjs +54 -5
  107. package/dist/production/src/model/VariablesManager.cjs.map +1 -1
  108. package/dist/production/src/model/VariablesManager.js +54 -5
  109. package/dist/production/src/model/VariablesManager.js.map +1 -1
  110. package/dist/production/src/triggers/TriggerPayloadPersister.cjs +3 -1
  111. package/dist/production/src/triggers/TriggerPayloadPersister.cjs.map +1 -1
  112. package/dist/production/src/triggers/TriggerPayloadPersister.js +3 -1
  113. package/dist/production/src/triggers/TriggerPayloadPersister.js.map +1 -1
  114. package/dist/tests/cases/unit/actionsMetrics.test.d.ts +2 -0
  115. package/dist/tests/cases/unit/actionsMetrics.test.d.ts.map +1 -0
  116. package/dist/tests/cases/unit/eventsRepository.test.d.ts +2 -0
  117. package/dist/tests/cases/unit/eventsRepository.test.d.ts.map +1 -0
  118. package/dist/tests/cases/unit/variablesManager.test.d.ts +2 -0
  119. package/dist/tests/cases/unit/variablesManager.test.d.ts.map +1 -0
  120. package/dist/tests/src/event.d.ts +4 -0
  121. package/dist/tests/src/event.d.ts.map +1 -0
  122. package/dist/tests/src/gql.d.ts.map +1 -1
  123. package/dist/tests/src/uuid.d.ts.map +1 -1
  124. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  125. package/dist/types/ActionsExecutionContainerHookFactory.d.ts +3 -1
  126. package/dist/types/ActionsExecutionContainerHookFactory.d.ts.map +1 -1
  127. package/dist/types/ActionsMetrics.d.ts +59 -0
  128. package/dist/types/ActionsMetrics.d.ts.map +1 -0
  129. package/dist/types/ListenerStoreProvider.d.ts.map +1 -1
  130. package/dist/types/authorization/ActionsPermissionsFactory.d.ts.map +1 -1
  131. package/dist/types/dispatch/DispatchWorkerSupervisor.d.ts.map +1 -1
  132. package/dist/types/dispatch/EventDispatcher.d.ts +12 -3
  133. package/dist/types/dispatch/EventDispatcher.d.ts.map +1 -1
  134. package/dist/types/dispatch/EventsRepository.d.ts +14 -2
  135. package/dist/types/dispatch/EventsRepository.d.ts.map +1 -1
  136. package/dist/types/dispatch/LazyDispatchWorker.d.ts.map +1 -1
  137. package/dist/types/dispatch/ProjectDispatcher.d.ts +5 -2
  138. package/dist/types/dispatch/ProjectDispatcher.d.ts.map +1 -1
  139. package/dist/types/dispatch/TargetHandlerResolver.d.ts.map +1 -1
  140. package/dist/types/dispatch/WebhookFetcher.d.ts.map +1 -1
  141. package/dist/types/dispatch/WebhookTargetHandler.d.ts.map +1 -1
  142. package/dist/types/graphql/http/ActionsApiMiddlewareFactory.d.ts.map +1 -1
  143. package/dist/types/graphql/http/ActionsContextResolver.d.ts.map +1 -1
  144. package/dist/types/graphql/http/ActionsGraphQLHandlerFactory.d.ts.map +1 -1
  145. package/dist/types/graphql/http/ActionsWebsocketControllerFactory.d.ts.map +1 -1
  146. package/dist/types/graphql/resolvers/ResolversFactory.d.ts.map +1 -1
  147. package/dist/types/graphql/resolvers/mutation/ProcessBatchMutationResolver.d.ts.map +1 -1
  148. package/dist/types/graphql/resolvers/mutation/RetryEventMutationResolver.d.ts.map +1 -1
  149. package/dist/types/graphql/resolvers/mutation/SetVariablesMutationResolver.d.ts.map +1 -1
  150. package/dist/types/graphql/resolvers/mutation/StopEventMutationResolver.d.ts.map +1 -1
  151. package/dist/types/graphql/resolvers/query/EventsQueryResolver.d.ts.map +1 -1
  152. package/dist/types/graphql/resolvers/query/VariablesQueryResolver.d.ts +1 -4
  153. package/dist/types/graphql/resolvers/query/VariablesQueryResolver.d.ts.map +1 -1
  154. package/dist/types/graphql/schema/actions.graphql.d.ts.map +1 -1
  155. package/dist/types/graphql/schema/index.d.ts +27 -17
  156. package/dist/types/graphql/schema/index.d.ts.map +1 -1
  157. package/dist/types/index.d.ts +6 -0
  158. package/dist/types/index.d.ts.map +1 -1
  159. package/dist/types/model/EventByIdQuery.d.ts.map +1 -1
  160. package/dist/types/model/EventsInProcessingQuery.d.ts.map +1 -1
  161. package/dist/types/model/EventsToProcessQuery.d.ts.map +1 -1
  162. package/dist/types/model/FailedEventsQuery.d.ts.map +1 -1
  163. package/dist/types/model/SetVariableCommand.d.ts.map +1 -1
  164. package/dist/types/model/VariablesManager.d.ts +16 -3
  165. package/dist/types/model/VariablesManager.d.ts.map +1 -1
  166. package/dist/types/model/VariablesQuery.d.ts.map +1 -1
  167. package/dist/types/triggers/TriggerHandler.d.ts.map +1 -1
  168. package/dist/types/triggers/TriggerIndirectChangesFetcher.d.ts.map +1 -1
  169. package/dist/types/triggers/TriggerListenersBuilder.d.ts.map +1 -1
  170. package/dist/types/triggers/TriggerListenersFactory.d.ts.map +1 -1
  171. package/dist/types/triggers/TriggerListenersStore.d.ts.map +1 -1
  172. package/dist/types/triggers/TriggerPayloadBuilder.d.ts.map +1 -1
  173. package/dist/types/triggers/TriggerPayloadManager.d.ts.map +1 -1
  174. package/dist/types/triggers/TriggerPayloadPersister.d.ts +3 -1
  175. package/dist/types/triggers/TriggerPayloadPersister.d.ts.map +1 -1
  176. package/dist/types/tsconfig.tsbuildinfo +1 -1
  177. package/dist/types/utils/map.d.ts.map +1 -1
  178. package/dist/types/utils/notifyChannel.d.ts.map +1 -1
  179. package/graphql.codegen.yml +1 -1
  180. package/package.json +18 -16
  181. package/src/ActionsExecutionContainerHookFactory.ts +6 -0
  182. package/src/ActionsMetrics.ts +135 -0
  183. package/src/dispatch/EventDispatcher.ts +36 -11
  184. package/src/dispatch/EventsRepository.ts +68 -26
  185. package/src/dispatch/ProjectDispatcher.ts +27 -11
  186. package/src/dispatch/WebhookTargetHandler.ts +36 -1
  187. package/src/graphql/resolvers/ResolversFactory.ts +1 -1
  188. package/src/graphql/resolvers/mutation/SetVariablesMutationResolver.ts +1 -1
  189. package/src/graphql/resolvers/query/EventsQueryResolver.ts +1 -1
  190. package/src/graphql/resolvers/query/VariablesQueryResolver.ts +1 -4
  191. package/src/graphql/schema/actions.graphql.ts +20 -8
  192. package/src/graphql/schema/index.ts +30 -17
  193. package/src/index.ts +27 -5
  194. package/src/model/VariablesManager.ts +66 -6
  195. package/src/triggers/TriggerPayloadPersister.ts +6 -0
  196. package/tests/cases/unit/actionsMetrics.test.ts +76 -0
  197. package/tests/cases/unit/eventsRepository.test.ts +136 -0
  198. package/tests/cases/unit/variablesManager.test.ts +154 -0
  199. package/tests/cases/unit/webhookHandler.test.ts +80 -24
  200. package/tests/src/event.ts +27 -0
@@ -1 +1 @@
1
- {"version":3,"file":"EventsQueryResolver.cjs","sources":["../../../../../../../packages/engine-actions/src/graphql/resolvers/query/EventsQueryResolver.ts"],"sourcesContent":["import { Event, QueryEventsInProcessingArgs, QueryEventsToProcessArgs, QueryFailedEventsArgs, QueryResolvers } from '../../schema/index.js'\nimport { ActionsContext } from '../ActionsContext.js'\nimport { EventsToProcessQuery } from '../../../model/EventsToProcessQuery.js'\nimport { EventRow } from '../../../model/types.js'\nimport { DatabaseContext, StagesQuery } from '@contember/engine-system-api'\nimport { Client, DatabaseQuery } from '@contember/database'\nimport { EventsInProcessingQuery } from '../../../model/EventsInProcessingQuery.js'\nimport { FailedEventsQuery } from '../../../model/FailedEventsQuery.js'\nimport { ActionsAuthorizationActions } from '../../../authorization/index.js'\nimport { EventByIdQuery } from '../../../model/EventByIdQuery.js'\n\nexport class EventsQueryResolver implements QueryResolvers<ActionsContext> {\n\tasync eventsInProcessing(parent: unknown, { args }: QueryEventsInProcessingArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new EventsInProcessingQuery(args ?? {}))\n\t}\n\n\tasync eventsToProcess(parent: unknown, { args }: QueryEventsToProcessArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new EventsToProcessQuery(args ?? {}))\n\t}\n\n\tasync failedEvents(parent: unknown, { args }: QueryFailedEventsArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new FailedEventsQuery(args ?? {}))\n\t}\n\n\tasync event(parent: unknown, { id }: { id: string }, ctx: ActionsContext): Promise<Event | null> {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\t\tconst stages = await this.fetchStagesMap(ctx.db)\n\t\tconst result = await ctx.db.queryHandler.fetch(new EventByIdQuery(id))\n\t\tif (!result) {\n\t\t\treturn null\n\t\t}\n\t\treturn this.mapEventRows([result], stages)[0]\n\t}\n\n\tprivate async fetchEvents(db: DatabaseContext, query: DatabaseQuery<EventRow[]>) {\n\t\tconst stages = await this.fetchStagesMap(db)\n\t\treturn this.mapEventRows(await db.queryHandler.fetch(query), stages)\n\t}\n\n\tprivate async fetchStagesMap(db: DatabaseContext): Promise<Record<string, string>> {\n\t\treturn Object.fromEntries((await db.queryHandler.fetch(new StagesQuery())).map(it => [it.id, it.slug]))\n\t}\n\n\tprivate mapEventRows(rows: EventRow[], stagesMap: Record<string, string>): Event[] {\n\t\treturn rows.map(row => ({\n\t\t\tid: row.id,\n\t\t\tcreatedAt: row.created_at,\n\t\t\tresolvedAt: row.created_at,\n\t\t\tlastStateChange: row.last_state_change,\n\t\t\tvisibleAt: row.visible_at,\n\t\t\tlog: row.log,\n\t\t\tnumRetries: row.num_retries,\n\t\t\tpayload: row.payload,\n\t\t\tstage: stagesMap[row.stage_id],\n\t\t\tstate: row.state,\n\t\t\ttarget: row.target,\n\t\t\ttransactionId: row.transaction_id,\n\t\t\tidentityId: row.identity_id ?? undefined,\n\t\t\tipAddress: row.ip_address ?? undefined,\n\t\t\tuserAgent: row.user_agent ?? undefined,\n\t\t}))\n\t}\n}\n"],"names":["ActionsAuthorizationActions","EventsInProcessingQuery","EventsToProcessQuery","FailedEventsQuery","EventByIdQuery","StagesQuery"],"mappings":";;;;;;;;;;AAWO,MAAM,oBAA8D;AAAA,EAC1E,MAAM,mBAAmB,QAAiB,EAAE,KAAA,GAAqC,KAAqB;AACrG,UAAM,IAAI,cAAcA,4BAAAA,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAIC,wBAAAA,wBAAwB,QAAQ,CAAA,CAAE,CAAC;AAAA,EAC9E;AAAA,EAEA,MAAM,gBAAgB,QAAiB,EAAE,KAAA,GAAkC,KAAqB;AAC/F,UAAM,IAAI,cAAcD,4BAAAA,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAIE,qBAAAA,qBAAqB,QAAQ,CAAA,CAAE,CAAC;AAAA,EAC3E;AAAA,EAEA,MAAM,aAAa,QAAiB,EAAE,KAAA,GAA+B,KAAqB;AACzF,UAAM,IAAI,cAAcF,4BAAAA,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAIG,kBAAAA,kBAAkB,QAAQ,CAAA,CAAE,CAAC;AAAA,EACxE;AAAA,EAEA,MAAM,MAAM,QAAiB,EAAE,GAAA,GAAsB,KAA4C;AAChG,UAAM,IAAI,cAAcH,4BAAAA,4BAA4B,WAAW;AAC/D,UAAM,SAAS,MAAM,KAAK,eAAe,IAAI,EAAE;AAC/C,UAAM,SAAS,MAAM,IAAI,GAAG,aAAa,MAAM,IAAII,8BAAe,EAAE,CAAC;AACrE,QAAI,CAAC,QAAQ;AACZ,aAAO;AAAA,IACR;AACA,WAAO,KAAK,aAAa,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;AAAA,EAC7C;AAAA,EAEA,MAAc,YAAY,IAAqB,OAAkC;AAChF,UAAM,SAAS,MAAM,KAAK,eAAe,EAAE;AAC3C,WAAO,KAAK,aAAa,MAAM,GAAG,aAAa,MAAM,KAAK,GAAG,MAAM;AAAA,EACpE;AAAA,EAEA,MAAc,eAAe,IAAsD;AAClF,WAAO,OAAO,aAAa,MAAM,GAAG,aAAa,MAAM,IAAIC,gBAAAA,YAAA,CAAa,GAAG,IAAI,QAAM,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;AAAA,EACvG;AAAA,EAEQ,aAAa,MAAkB,WAA4C;AAClF,WAAO,KAAK,IAAI,CAAA,SAAQ;AAAA,MACvB,IAAI,IAAI;AAAA,MACR,WAAW,IAAI;AAAA,MACf,YAAY,IAAI;AAAA,MAChB,iBAAiB,IAAI;AAAA,MACrB,WAAW,IAAI;AAAA,MACf,KAAK,IAAI;AAAA,MACT,YAAY,IAAI;AAAA,MAChB,SAAS,IAAI;AAAA,MACb,OAAO,UAAU,IAAI,QAAQ;AAAA,MAC7B,OAAO,IAAI;AAAA,MACX,QAAQ,IAAI;AAAA,MACZ,eAAe,IAAI;AAAA,MACnB,YAAY,IAAI,eAAe;AAAA,MAC/B,WAAW,IAAI,cAAc;AAAA,MAC7B,WAAW,IAAI,cAAc;AAAA,IAAA,EAC5B;AAAA,EACH;AACD;;"}
1
+ {"version":3,"file":"EventsQueryResolver.cjs","sources":["../../../../../../../packages/engine-actions/src/graphql/resolvers/query/EventsQueryResolver.ts"],"sourcesContent":["import { Event, QueryEventsInProcessingArgs, QueryEventsToProcessArgs, QueryFailedEventsArgs, QueryResolvers } from '../../schema/index.js'\nimport { ActionsContext } from '../ActionsContext.js'\nimport { EventsToProcessQuery } from '../../../model/EventsToProcessQuery.js'\nimport { EventRow } from '../../../model/types.js'\nimport { DatabaseContext, StagesQuery } from '@contember/engine-system-api'\nimport { Client, DatabaseQuery } from '@contember/database'\nimport { EventsInProcessingQuery } from '../../../model/EventsInProcessingQuery.js'\nimport { FailedEventsQuery } from '../../../model/FailedEventsQuery.js'\nimport { ActionsAuthorizationActions } from '../../../authorization/index.js'\nimport { EventByIdQuery } from '../../../model/EventByIdQuery.js'\n\nexport class EventsQueryResolver implements QueryResolvers<ActionsContext> {\n\tasync eventsInProcessing(parent: unknown, { args }: QueryEventsInProcessingArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new EventsInProcessingQuery(args ?? {}))\n\t}\n\n\tasync eventsToProcess(parent: unknown, { args }: QueryEventsToProcessArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new EventsToProcessQuery(args ?? {}))\n\t}\n\n\tasync failedEvents(parent: unknown, { args }: QueryFailedEventsArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new FailedEventsQuery(args ?? {}))\n\t}\n\n\tasync event(parent: unknown, { id }: { id: string }, ctx: ActionsContext): Promise<Event | null> {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\t\tconst stages = await this.fetchStagesMap(ctx.db)\n\t\tconst result = await ctx.db.queryHandler.fetch(new EventByIdQuery(id))\n\t\tif (!result) {\n\t\t\treturn null\n\t\t}\n\t\treturn this.mapEventRows([result], stages)[0]\n\t}\n\n\tprivate async fetchEvents(db: DatabaseContext, query: DatabaseQuery<EventRow[]>) {\n\t\tconst stages = await this.fetchStagesMap(db)\n\t\treturn this.mapEventRows(await db.queryHandler.fetch(query), stages)\n\t}\n\n\tprivate async fetchStagesMap(db: DatabaseContext): Promise<Record<string, string>> {\n\t\treturn Object.fromEntries((await db.queryHandler.fetch(new StagesQuery())).map(it => [it.id, it.slug]))\n\t}\n\n\tprivate mapEventRows(rows: EventRow[], stagesMap: Record<string, string>): Event[] {\n\t\treturn rows.map(row => ({\n\t\t\tid: row.id,\n\t\t\tcreatedAt: row.created_at,\n\t\t\tresolvedAt: row.resolved_at ?? undefined,\n\t\t\tlastStateChange: row.last_state_change,\n\t\t\tvisibleAt: row.visible_at,\n\t\t\tlog: row.log,\n\t\t\tnumRetries: row.num_retries,\n\t\t\tpayload: row.payload,\n\t\t\tstage: stagesMap[row.stage_id],\n\t\t\tstate: row.state,\n\t\t\ttarget: row.target,\n\t\t\ttransactionId: row.transaction_id,\n\t\t\tidentityId: row.identity_id ?? undefined,\n\t\t\tipAddress: row.ip_address ?? undefined,\n\t\t\tuserAgent: row.user_agent ?? undefined,\n\t\t}))\n\t}\n}\n"],"names":["ActionsAuthorizationActions","EventsInProcessingQuery","EventsToProcessQuery","FailedEventsQuery","EventByIdQuery","StagesQuery"],"mappings":";;;;;;;;;;AAWO,MAAM,oBAA8D;AAAA,EAC1E,MAAM,mBAAmB,QAAiB,EAAE,KAAA,GAAqC,KAAqB;AACrG,UAAM,IAAI,cAAcA,4BAAAA,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAIC,wBAAAA,wBAAwB,QAAQ,CAAA,CAAE,CAAC;AAAA,EAC9E;AAAA,EAEA,MAAM,gBAAgB,QAAiB,EAAE,KAAA,GAAkC,KAAqB;AAC/F,UAAM,IAAI,cAAcD,4BAAAA,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAIE,qBAAAA,qBAAqB,QAAQ,CAAA,CAAE,CAAC;AAAA,EAC3E;AAAA,EAEA,MAAM,aAAa,QAAiB,EAAE,KAAA,GAA+B,KAAqB;AACzF,UAAM,IAAI,cAAcF,4BAAAA,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAIG,kBAAAA,kBAAkB,QAAQ,CAAA,CAAE,CAAC;AAAA,EACxE;AAAA,EAEA,MAAM,MAAM,QAAiB,EAAE,GAAA,GAAsB,KAA4C;AAChG,UAAM,IAAI,cAAcH,4BAAAA,4BAA4B,WAAW;AAC/D,UAAM,SAAS,MAAM,KAAK,eAAe,IAAI,EAAE;AAC/C,UAAM,SAAS,MAAM,IAAI,GAAG,aAAa,MAAM,IAAII,8BAAe,EAAE,CAAC;AACrE,QAAI,CAAC,QAAQ;AACZ,aAAO;AAAA,IACR;AACA,WAAO,KAAK,aAAa,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;AAAA,EAC7C;AAAA,EAEA,MAAc,YAAY,IAAqB,OAAkC;AAChF,UAAM,SAAS,MAAM,KAAK,eAAe,EAAE;AAC3C,WAAO,KAAK,aAAa,MAAM,GAAG,aAAa,MAAM,KAAK,GAAG,MAAM;AAAA,EACpE;AAAA,EAEA,MAAc,eAAe,IAAsD;AAClF,WAAO,OAAO,aAAa,MAAM,GAAG,aAAa,MAAM,IAAIC,gBAAAA,YAAA,CAAa,GAAG,IAAI,QAAM,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;AAAA,EACvG;AAAA,EAEQ,aAAa,MAAkB,WAA4C;AAClF,WAAO,KAAK,IAAI,CAAA,SAAQ;AAAA,MACvB,IAAI,IAAI;AAAA,MACR,WAAW,IAAI;AAAA,MACf,YAAY,IAAI,eAAe;AAAA,MAC/B,iBAAiB,IAAI;AAAA,MACrB,WAAW,IAAI;AAAA,MACf,KAAK,IAAI;AAAA,MACT,YAAY,IAAI;AAAA,MAChB,SAAS,IAAI;AAAA,MACb,OAAO,UAAU,IAAI,QAAQ;AAAA,MAC7B,OAAO,IAAI;AAAA,MACX,QAAQ,IAAI;AAAA,MACZ,eAAe,IAAI;AAAA,MACnB,YAAY,IAAI,eAAe;AAAA,MAC/B,WAAW,IAAI,cAAc;AAAA,MAC7B,WAAW,IAAI,cAAc;AAAA,IAAA,EAC5B;AAAA,EACH;AACD;;"}
@@ -39,7 +39,7 @@ class EventsQueryResolver {
39
39
  return rows.map((row) => ({
40
40
  id: row.id,
41
41
  createdAt: row.created_at,
42
- resolvedAt: row.created_at,
42
+ resolvedAt: row.resolved_at ?? void 0,
43
43
  lastStateChange: row.last_state_change,
44
44
  visibleAt: row.visible_at,
45
45
  log: row.log,
@@ -1 +1 @@
1
- {"version":3,"file":"EventsQueryResolver.js","sources":["../../../../../../../packages/engine-actions/src/graphql/resolvers/query/EventsQueryResolver.ts"],"sourcesContent":["import { Event, QueryEventsInProcessingArgs, QueryEventsToProcessArgs, QueryFailedEventsArgs, QueryResolvers } from '../../schema/index.js'\nimport { ActionsContext } from '../ActionsContext.js'\nimport { EventsToProcessQuery } from '../../../model/EventsToProcessQuery.js'\nimport { EventRow } from '../../../model/types.js'\nimport { DatabaseContext, StagesQuery } from '@contember/engine-system-api'\nimport { Client, DatabaseQuery } from '@contember/database'\nimport { EventsInProcessingQuery } from '../../../model/EventsInProcessingQuery.js'\nimport { FailedEventsQuery } from '../../../model/FailedEventsQuery.js'\nimport { ActionsAuthorizationActions } from '../../../authorization/index.js'\nimport { EventByIdQuery } from '../../../model/EventByIdQuery.js'\n\nexport class EventsQueryResolver implements QueryResolvers<ActionsContext> {\n\tasync eventsInProcessing(parent: unknown, { args }: QueryEventsInProcessingArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new EventsInProcessingQuery(args ?? {}))\n\t}\n\n\tasync eventsToProcess(parent: unknown, { args }: QueryEventsToProcessArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new EventsToProcessQuery(args ?? {}))\n\t}\n\n\tasync failedEvents(parent: unknown, { args }: QueryFailedEventsArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new FailedEventsQuery(args ?? {}))\n\t}\n\n\tasync event(parent: unknown, { id }: { id: string }, ctx: ActionsContext): Promise<Event | null> {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\t\tconst stages = await this.fetchStagesMap(ctx.db)\n\t\tconst result = await ctx.db.queryHandler.fetch(new EventByIdQuery(id))\n\t\tif (!result) {\n\t\t\treturn null\n\t\t}\n\t\treturn this.mapEventRows([result], stages)[0]\n\t}\n\n\tprivate async fetchEvents(db: DatabaseContext, query: DatabaseQuery<EventRow[]>) {\n\t\tconst stages = await this.fetchStagesMap(db)\n\t\treturn this.mapEventRows(await db.queryHandler.fetch(query), stages)\n\t}\n\n\tprivate async fetchStagesMap(db: DatabaseContext): Promise<Record<string, string>> {\n\t\treturn Object.fromEntries((await db.queryHandler.fetch(new StagesQuery())).map(it => [it.id, it.slug]))\n\t}\n\n\tprivate mapEventRows(rows: EventRow[], stagesMap: Record<string, string>): Event[] {\n\t\treturn rows.map(row => ({\n\t\t\tid: row.id,\n\t\t\tcreatedAt: row.created_at,\n\t\t\tresolvedAt: row.created_at,\n\t\t\tlastStateChange: row.last_state_change,\n\t\t\tvisibleAt: row.visible_at,\n\t\t\tlog: row.log,\n\t\t\tnumRetries: row.num_retries,\n\t\t\tpayload: row.payload,\n\t\t\tstage: stagesMap[row.stage_id],\n\t\t\tstate: row.state,\n\t\t\ttarget: row.target,\n\t\t\ttransactionId: row.transaction_id,\n\t\t\tidentityId: row.identity_id ?? undefined,\n\t\t\tipAddress: row.ip_address ?? undefined,\n\t\t\tuserAgent: row.user_agent ?? undefined,\n\t\t}))\n\t}\n}\n"],"names":[],"mappings":";;;;;;;;AAWO,MAAM,oBAA8D;AAAA,EAC1E,MAAM,mBAAmB,QAAiB,EAAE,KAAA,GAAqC,KAAqB;AACrG,UAAM,IAAI,cAAc,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAI,wBAAwB,QAAQ,CAAA,CAAE,CAAC;AAAA,EAC9E;AAAA,EAEA,MAAM,gBAAgB,QAAiB,EAAE,KAAA,GAAkC,KAAqB;AAC/F,UAAM,IAAI,cAAc,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAI,qBAAqB,QAAQ,CAAA,CAAE,CAAC;AAAA,EAC3E;AAAA,EAEA,MAAM,aAAa,QAAiB,EAAE,KAAA,GAA+B,KAAqB;AACzF,UAAM,IAAI,cAAc,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAI,kBAAkB,QAAQ,CAAA,CAAE,CAAC;AAAA,EACxE;AAAA,EAEA,MAAM,MAAM,QAAiB,EAAE,GAAA,GAAsB,KAA4C;AAChG,UAAM,IAAI,cAAc,4BAA4B,WAAW;AAC/D,UAAM,SAAS,MAAM,KAAK,eAAe,IAAI,EAAE;AAC/C,UAAM,SAAS,MAAM,IAAI,GAAG,aAAa,MAAM,IAAI,eAAe,EAAE,CAAC;AACrE,QAAI,CAAC,QAAQ;AACZ,aAAO;AAAA,IACR;AACA,WAAO,KAAK,aAAa,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;AAAA,EAC7C;AAAA,EAEA,MAAc,YAAY,IAAqB,OAAkC;AAChF,UAAM,SAAS,MAAM,KAAK,eAAe,EAAE;AAC3C,WAAO,KAAK,aAAa,MAAM,GAAG,aAAa,MAAM,KAAK,GAAG,MAAM;AAAA,EACpE;AAAA,EAEA,MAAc,eAAe,IAAsD;AAClF,WAAO,OAAO,aAAa,MAAM,GAAG,aAAa,MAAM,IAAI,YAAA,CAAa,GAAG,IAAI,QAAM,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;AAAA,EACvG;AAAA,EAEQ,aAAa,MAAkB,WAA4C;AAClF,WAAO,KAAK,IAAI,CAAA,SAAQ;AAAA,MACvB,IAAI,IAAI;AAAA,MACR,WAAW,IAAI;AAAA,MACf,YAAY,IAAI;AAAA,MAChB,iBAAiB,IAAI;AAAA,MACrB,WAAW,IAAI;AAAA,MACf,KAAK,IAAI;AAAA,MACT,YAAY,IAAI;AAAA,MAChB,SAAS,IAAI;AAAA,MACb,OAAO,UAAU,IAAI,QAAQ;AAAA,MAC7B,OAAO,IAAI;AAAA,MACX,QAAQ,IAAI;AAAA,MACZ,eAAe,IAAI;AAAA,MACnB,YAAY,IAAI,eAAe;AAAA,MAC/B,WAAW,IAAI,cAAc;AAAA,MAC7B,WAAW,IAAI,cAAc;AAAA,IAAA,EAC5B;AAAA,EACH;AACD;"}
1
+ {"version":3,"file":"EventsQueryResolver.js","sources":["../../../../../../../packages/engine-actions/src/graphql/resolvers/query/EventsQueryResolver.ts"],"sourcesContent":["import { Event, QueryEventsInProcessingArgs, QueryEventsToProcessArgs, QueryFailedEventsArgs, QueryResolvers } from '../../schema/index.js'\nimport { ActionsContext } from '../ActionsContext.js'\nimport { EventsToProcessQuery } from '../../../model/EventsToProcessQuery.js'\nimport { EventRow } from '../../../model/types.js'\nimport { DatabaseContext, StagesQuery } from '@contember/engine-system-api'\nimport { Client, DatabaseQuery } from '@contember/database'\nimport { EventsInProcessingQuery } from '../../../model/EventsInProcessingQuery.js'\nimport { FailedEventsQuery } from '../../../model/FailedEventsQuery.js'\nimport { ActionsAuthorizationActions } from '../../../authorization/index.js'\nimport { EventByIdQuery } from '../../../model/EventByIdQuery.js'\n\nexport class EventsQueryResolver implements QueryResolvers<ActionsContext> {\n\tasync eventsInProcessing(parent: unknown, { args }: QueryEventsInProcessingArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new EventsInProcessingQuery(args ?? {}))\n\t}\n\n\tasync eventsToProcess(parent: unknown, { args }: QueryEventsToProcessArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new EventsToProcessQuery(args ?? {}))\n\t}\n\n\tasync failedEvents(parent: unknown, { args }: QueryFailedEventsArgs, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\n\t\treturn await this.fetchEvents(ctx.db, new FailedEventsQuery(args ?? {}))\n\t}\n\n\tasync event(parent: unknown, { id }: { id: string }, ctx: ActionsContext): Promise<Event | null> {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.EVENTS_VIEW)\n\t\tconst stages = await this.fetchStagesMap(ctx.db)\n\t\tconst result = await ctx.db.queryHandler.fetch(new EventByIdQuery(id))\n\t\tif (!result) {\n\t\t\treturn null\n\t\t}\n\t\treturn this.mapEventRows([result], stages)[0]\n\t}\n\n\tprivate async fetchEvents(db: DatabaseContext, query: DatabaseQuery<EventRow[]>) {\n\t\tconst stages = await this.fetchStagesMap(db)\n\t\treturn this.mapEventRows(await db.queryHandler.fetch(query), stages)\n\t}\n\n\tprivate async fetchStagesMap(db: DatabaseContext): Promise<Record<string, string>> {\n\t\treturn Object.fromEntries((await db.queryHandler.fetch(new StagesQuery())).map(it => [it.id, it.slug]))\n\t}\n\n\tprivate mapEventRows(rows: EventRow[], stagesMap: Record<string, string>): Event[] {\n\t\treturn rows.map(row => ({\n\t\t\tid: row.id,\n\t\t\tcreatedAt: row.created_at,\n\t\t\tresolvedAt: row.resolved_at ?? undefined,\n\t\t\tlastStateChange: row.last_state_change,\n\t\t\tvisibleAt: row.visible_at,\n\t\t\tlog: row.log,\n\t\t\tnumRetries: row.num_retries,\n\t\t\tpayload: row.payload,\n\t\t\tstage: stagesMap[row.stage_id],\n\t\t\tstate: row.state,\n\t\t\ttarget: row.target,\n\t\t\ttransactionId: row.transaction_id,\n\t\t\tidentityId: row.identity_id ?? undefined,\n\t\t\tipAddress: row.ip_address ?? undefined,\n\t\t\tuserAgent: row.user_agent ?? undefined,\n\t\t}))\n\t}\n}\n"],"names":[],"mappings":";;;;;;;;AAWO,MAAM,oBAA8D;AAAA,EAC1E,MAAM,mBAAmB,QAAiB,EAAE,KAAA,GAAqC,KAAqB;AACrG,UAAM,IAAI,cAAc,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAI,wBAAwB,QAAQ,CAAA,CAAE,CAAC;AAAA,EAC9E;AAAA,EAEA,MAAM,gBAAgB,QAAiB,EAAE,KAAA,GAAkC,KAAqB;AAC/F,UAAM,IAAI,cAAc,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAI,qBAAqB,QAAQ,CAAA,CAAE,CAAC;AAAA,EAC3E;AAAA,EAEA,MAAM,aAAa,QAAiB,EAAE,KAAA,GAA+B,KAAqB;AACzF,UAAM,IAAI,cAAc,4BAA4B,WAAW;AAE/D,WAAO,MAAM,KAAK,YAAY,IAAI,IAAI,IAAI,kBAAkB,QAAQ,CAAA,CAAE,CAAC;AAAA,EACxE;AAAA,EAEA,MAAM,MAAM,QAAiB,EAAE,GAAA,GAAsB,KAA4C;AAChG,UAAM,IAAI,cAAc,4BAA4B,WAAW;AAC/D,UAAM,SAAS,MAAM,KAAK,eAAe,IAAI,EAAE;AAC/C,UAAM,SAAS,MAAM,IAAI,GAAG,aAAa,MAAM,IAAI,eAAe,EAAE,CAAC;AACrE,QAAI,CAAC,QAAQ;AACZ,aAAO;AAAA,IACR;AACA,WAAO,KAAK,aAAa,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;AAAA,EAC7C;AAAA,EAEA,MAAc,YAAY,IAAqB,OAAkC;AAChF,UAAM,SAAS,MAAM,KAAK,eAAe,EAAE;AAC3C,WAAO,KAAK,aAAa,MAAM,GAAG,aAAa,MAAM,KAAK,GAAG,MAAM;AAAA,EACpE;AAAA,EAEA,MAAc,eAAe,IAAsD;AAClF,WAAO,OAAO,aAAa,MAAM,GAAG,aAAa,MAAM,IAAI,YAAA,CAAa,GAAG,IAAI,QAAM,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;AAAA,EACvG;AAAA,EAEQ,aAAa,MAAkB,WAA4C;AAClF,WAAO,KAAK,IAAI,CAAA,SAAQ;AAAA,MACvB,IAAI,IAAI;AAAA,MACR,WAAW,IAAI;AAAA,MACf,YAAY,IAAI,eAAe;AAAA,MAC/B,iBAAiB,IAAI;AAAA,MACrB,WAAW,IAAI;AAAA,MACf,KAAK,IAAI;AAAA,MACT,YAAY,IAAI;AAAA,MAChB,SAAS,IAAI;AAAA,MACb,OAAO,UAAU,IAAI,QAAQ;AAAA,MAC7B,OAAO,IAAI;AAAA,MACX,QAAQ,IAAI;AAAA,MACZ,eAAe,IAAI;AAAA,MACnB,YAAY,IAAI,eAAe;AAAA,MAC/B,WAAW,IAAI,cAAc;AAAA,MAC7B,WAAW,IAAI,cAAc;AAAA,IAAA,EAC5B;AAAA,EACH;AACD;"}
@@ -9,10 +9,7 @@ class VariablesQueryResolver {
9
9
  }
10
10
  async variables(parent, args, ctx) {
11
11
  await ctx.requireAccess(ActionsAuthorizationActions.ActionsAuthorizationActions.VARIABLES_VIEW);
12
- return Object.entries(await this.variablesManager.fetchVariables(ctx.db)).map(([name, value]) => ({
13
- name,
14
- value
15
- }));
12
+ return await this.variablesManager.listVariables(ctx.db, ctx.project.slug);
16
13
  }
17
14
  }
18
15
  exports.VariablesQueryResolver = VariablesQueryResolver;
@@ -1 +1 @@
1
- {"version":3,"file":"VariablesQueryResolver.cjs","sources":["../../../../../../../packages/engine-actions/src/graphql/resolvers/query/VariablesQueryResolver.ts"],"sourcesContent":["import { QueryResolvers } from '../../schema/index.js'\nimport { ActionsContext } from '../ActionsContext.js'\nimport { VariablesManager } from '../../../model/VariablesManager.js'\nimport { ActionsAuthorizationActions } from '../../../authorization/index.js'\n\nexport class VariablesQueryResolver implements QueryResolvers<ActionsContext> {\n\tconstructor(\n\t\tprivate readonly variablesManager: VariablesManager,\n\t) {\n\t}\n\n\tasync variables(parent: unknown, args: unknown, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.VARIABLES_VIEW)\n\n\t\treturn Object.entries(await this.variablesManager.fetchVariables(ctx.db)).map(([name, value]) => ({\n\t\t\tname,\n\t\t\tvalue,\n\t\t}))\n\t}\n}\n"],"names":["ActionsAuthorizationActions"],"mappings":";;;;;AAKO,MAAM,uBAAiE;AAAA,EAC7E,YACkB,kBAChB;AADgB,SAAA,mBAAA;AAAA,EAElB;AAAA,EAEA,MAAM,UAAU,QAAiB,MAAe,KAAqB;AACpE,UAAM,IAAI,cAAcA,4BAAAA,4BAA4B,cAAc;AAElE,WAAO,OAAO,QAAQ,MAAM,KAAK,iBAAiB,eAAe,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO;AAAA,MACjG;AAAA,MACA;AAAA,IAAA,EACC;AAAA,EACH;AACD;;"}
1
+ {"version":3,"file":"VariablesQueryResolver.cjs","sources":["../../../../../../../packages/engine-actions/src/graphql/resolvers/query/VariablesQueryResolver.ts"],"sourcesContent":["import { QueryResolvers } from '../../schema/index.js'\nimport { ActionsContext } from '../ActionsContext.js'\nimport { VariablesManager } from '../../../model/VariablesManager.js'\nimport { ActionsAuthorizationActions } from '../../../authorization/index.js'\n\nexport class VariablesQueryResolver implements QueryResolvers<ActionsContext> {\n\tconstructor(\n\t\tprivate readonly variablesManager: VariablesManager,\n\t) {\n\t}\n\n\tasync variables(parent: unknown, args: unknown, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.VARIABLES_VIEW)\n\n\t\treturn await this.variablesManager.listVariables(ctx.db, ctx.project.slug)\n\t}\n}\n"],"names":["ActionsAuthorizationActions"],"mappings":";;;;;AAKO,MAAM,uBAAiE;AAAA,EAC7E,YACkB,kBAChB;AADgB,SAAA,mBAAA;AAAA,EAElB;AAAA,EAEA,MAAM,UAAU,QAAiB,MAAe,KAAqB;AACpE,UAAM,IAAI,cAAcA,4BAAAA,4BAA4B,cAAc;AAElE,WAAO,MAAM,KAAK,iBAAiB,cAAc,IAAI,IAAI,IAAI,QAAQ,IAAI;AAAA,EAC1E;AACD;;"}
@@ -7,10 +7,7 @@ class VariablesQueryResolver {
7
7
  }
8
8
  async variables(parent, args, ctx) {
9
9
  await ctx.requireAccess(ActionsAuthorizationActions.VARIABLES_VIEW);
10
- return Object.entries(await this.variablesManager.fetchVariables(ctx.db)).map(([name, value]) => ({
11
- name,
12
- value
13
- }));
10
+ return await this.variablesManager.listVariables(ctx.db, ctx.project.slug);
14
11
  }
15
12
  }
16
13
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"VariablesQueryResolver.js","sources":["../../../../../../../packages/engine-actions/src/graphql/resolvers/query/VariablesQueryResolver.ts"],"sourcesContent":["import { QueryResolvers } from '../../schema/index.js'\nimport { ActionsContext } from '../ActionsContext.js'\nimport { VariablesManager } from '../../../model/VariablesManager.js'\nimport { ActionsAuthorizationActions } from '../../../authorization/index.js'\n\nexport class VariablesQueryResolver implements QueryResolvers<ActionsContext> {\n\tconstructor(\n\t\tprivate readonly variablesManager: VariablesManager,\n\t) {\n\t}\n\n\tasync variables(parent: unknown, args: unknown, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.VARIABLES_VIEW)\n\n\t\treturn Object.entries(await this.variablesManager.fetchVariables(ctx.db)).map(([name, value]) => ({\n\t\t\tname,\n\t\t\tvalue,\n\t\t}))\n\t}\n}\n"],"names":[],"mappings":";;;AAKO,MAAM,uBAAiE;AAAA,EAC7E,YACkB,kBAChB;AADgB,SAAA,mBAAA;AAAA,EAElB;AAAA,EAEA,MAAM,UAAU,QAAiB,MAAe,KAAqB;AACpE,UAAM,IAAI,cAAc,4BAA4B,cAAc;AAElE,WAAO,OAAO,QAAQ,MAAM,KAAK,iBAAiB,eAAe,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO;AAAA,MACjG;AAAA,MACA;AAAA,IAAA,EACC;AAAA,EACH;AACD;"}
1
+ {"version":3,"file":"VariablesQueryResolver.js","sources":["../../../../../../../packages/engine-actions/src/graphql/resolvers/query/VariablesQueryResolver.ts"],"sourcesContent":["import { QueryResolvers } from '../../schema/index.js'\nimport { ActionsContext } from '../ActionsContext.js'\nimport { VariablesManager } from '../../../model/VariablesManager.js'\nimport { ActionsAuthorizationActions } from '../../../authorization/index.js'\n\nexport class VariablesQueryResolver implements QueryResolvers<ActionsContext> {\n\tconstructor(\n\t\tprivate readonly variablesManager: VariablesManager,\n\t) {\n\t}\n\n\tasync variables(parent: unknown, args: unknown, ctx: ActionsContext) {\n\t\tawait ctx.requireAccess(ActionsAuthorizationActions.VARIABLES_VIEW)\n\n\t\treturn await this.variablesManager.listVariables(ctx.db, ctx.project.slug)\n\t}\n}\n"],"names":[],"mappings":";;;AAKO,MAAM,uBAAiE;AAAA,EAC7E,YACkB,kBAChB;AADgB,SAAA,mBAAA;AAAA,EAElB;AAAA,EAEA,MAAM,UAAU,QAAiB,MAAe,KAAqB;AACpE,UAAM,IAAI,cAAc,4BAA4B,cAAc;AAElE,WAAO,MAAM,KAAK,iBAAiB,cAAc,IAAI,IAAI,IAAI,QAAQ,IAAI;AAAA,EAC1E;AACD;"}
@@ -4,7 +4,7 @@ const graphqlTag = require("graphql-tag");
4
4
  const schema = graphqlTag.gql`
5
5
  scalar DateTime
6
6
  scalar Json
7
- scalar Uuid
7
+ scalar UUID
8
8
 
9
9
  schema {
10
10
  query: Query
@@ -15,14 +15,14 @@ const schema = graphqlTag.gql`
15
15
  failedEvents(args: EventArgs): [Event!]!
16
16
  eventsToProcess(args: EventArgs): [Event!]!
17
17
  eventsInProcessing(args: EventArgs): [Event!]!
18
- event(id: Uuid!): Event
18
+ event(id: UUID!): Event
19
19
  variables: [Variable!]!
20
20
  }
21
21
 
22
22
  type Mutation {
23
23
  processBatch: ProcessBatchResponse!
24
- retryEvent(id: Uuid!): RetryEventResponse!
25
- stopEvent(id: Uuid!): StopEventResponse!
24
+ retryEvent(id: UUID!): RetryEventResponse!
25
+ stopEvent(id: UUID!): StopEventResponse!
26
26
  setVariables(args: SetVariablesArgs!): SetVariablesResponse!
27
27
  }
28
28
 
@@ -33,9 +33,9 @@ const schema = graphqlTag.gql`
33
33
  }
34
34
 
35
35
  type Event {
36
- id: Uuid!
37
- transactionId: Uuid!
38
- identityId: Uuid
36
+ id: UUID!
37
+ transactionId: UUID!
38
+ identityId: UUID
39
39
  ipAddress: String
40
40
  userAgent: String
41
41
  createdAt: DateTime!
@@ -99,9 +99,21 @@ const schema = graphqlTag.gql`
99
99
 
100
100
  type Variable {
101
101
  name: String!
102
- value: String!
102
+ """Null when the value is not readable, which is every ENVIRONMENT one."""
103
+ value: String
104
+ source: VariableSource!
103
105
  }
104
106
 
107
+ """
108
+ Where the value comes from.
109
+ - DATABASE is stored in the project database, readable and writable with setVariables
110
+ - ENVIRONMENT is supplied by the engine environment, overrides a stored value of the same name, and is neither readable nor writable
111
+ """
112
+ enum VariableSource {
113
+ DATABASE
114
+ ENVIRONMENT
115
+ }
116
+
105
117
  `;
106
118
  exports.schema = schema;
107
119
  //# sourceMappingURL=actions.graphql.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"actions.graphql.cjs","sources":["../../../../../../packages/engine-actions/src/graphql/schema/actions.graphql.ts"],"sourcesContent":["import { gql } from 'graphql-tag'\nimport { DocumentNode } from 'graphql'\n\nexport const schema: DocumentNode = gql`\n scalar DateTime\n scalar Json\n scalar Uuid\n\n schema {\n query: Query\n mutation: Mutation\n }\n\n type Query {\n failedEvents(args: EventArgs): [Event!]!\n eventsToProcess(args: EventArgs): [Event!]!\n eventsInProcessing(args: EventArgs): [Event!]!\n event(id: Uuid!): Event\n variables: [Variable!]!\n }\n\n type Mutation {\n processBatch: ProcessBatchResponse!\n retryEvent(id: Uuid!): RetryEventResponse!\n stopEvent(id: Uuid!): StopEventResponse!\n setVariables(args: SetVariablesArgs!): SetVariablesResponse!\n }\n\n input EventArgs {\n offset: Int\n \"Max 10000\"\n limit: Int\n }\n\n type Event {\n id: Uuid!\n transactionId: Uuid!\n identityId: Uuid\n ipAddress: String\n userAgent: String\n createdAt: DateTime!\n lastStateChange: DateTime!\n resolvedAt: DateTime\n visibleAt: DateTime\n numRetries: Int!\n state: EventState!\n stage: String!\n target: String!\n payload: Json!\n log: Json!\n }\n\n enum EventState {\n created\n retrying\n processing\n succeed\n failed\n stopped\n }\n\n type ProcessBatchResponse {\n ok: Boolean!\n }\n\n type RetryEventResponse {\n ok: Boolean!\n }\n\n type StopEventResponse {\n ok: Boolean!\n }\n\n input SetVariablesArgs {\n variables: [VariableInput!]!\n mode: SetVariablesMode\n }\n\n\t\"\"\"\n\tDefines how it handles original variables.\n\t- MERGE merges with new values (default behaviour)\n\t- SET replaces all variables\n\t- APPEND_ONLY_MISSING appends values if not already exist\n\t\"\"\"\n\tenum SetVariablesMode {\n\t\tMERGE\n\t\tSET\n\t\tAPPEND_ONLY_MISSING\n\t}\n\n input VariableInput {\n name: String!\n value: String!\n }\n\n\ttype SetVariablesResponse {\n\t\tok: Boolean!\n\t}\n\n type Variable {\n name: String!\n value: String!\n }\n\n`\n"],"names":["gql"],"mappings":";;;AAGO,MAAM,SAAuBA,WAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;;"}
1
+ {"version":3,"file":"actions.graphql.cjs","sources":["../../../../../../packages/engine-actions/src/graphql/schema/actions.graphql.ts"],"sourcesContent":["import { gql } from 'graphql-tag'\nimport { DocumentNode } from 'graphql'\n\nexport const schema: DocumentNode = gql`\n scalar DateTime\n scalar Json\n scalar UUID\n\n schema {\n query: Query\n mutation: Mutation\n }\n\n type Query {\n failedEvents(args: EventArgs): [Event!]!\n eventsToProcess(args: EventArgs): [Event!]!\n eventsInProcessing(args: EventArgs): [Event!]!\n event(id: UUID!): Event\n variables: [Variable!]!\n }\n\n type Mutation {\n processBatch: ProcessBatchResponse!\n retryEvent(id: UUID!): RetryEventResponse!\n stopEvent(id: UUID!): StopEventResponse!\n setVariables(args: SetVariablesArgs!): SetVariablesResponse!\n }\n\n input EventArgs {\n offset: Int\n \"Max 10000\"\n limit: Int\n }\n\n type Event {\n id: UUID!\n transactionId: UUID!\n identityId: UUID\n ipAddress: String\n userAgent: String\n createdAt: DateTime!\n lastStateChange: DateTime!\n resolvedAt: DateTime\n visibleAt: DateTime\n numRetries: Int!\n state: EventState!\n stage: String!\n target: String!\n payload: Json!\n log: Json!\n }\n\n enum EventState {\n created\n retrying\n processing\n succeed\n failed\n stopped\n }\n\n type ProcessBatchResponse {\n ok: Boolean!\n }\n\n type RetryEventResponse {\n ok: Boolean!\n }\n\n type StopEventResponse {\n ok: Boolean!\n }\n\n input SetVariablesArgs {\n variables: [VariableInput!]!\n mode: SetVariablesMode\n }\n\n\t\"\"\"\n\tDefines how it handles original variables.\n\t- MERGE merges with new values (default behaviour)\n\t- SET replaces all variables\n\t- APPEND_ONLY_MISSING appends values if not already exist\n\t\"\"\"\n\tenum SetVariablesMode {\n\t\tMERGE\n\t\tSET\n\t\tAPPEND_ONLY_MISSING\n\t}\n\n input VariableInput {\n name: String!\n value: String!\n }\n\n\ttype SetVariablesResponse {\n\t\tok: Boolean!\n\t}\n\n type Variable {\n name: String!\n \"\"\"Null when the value is not readable, which is every ENVIRONMENT one.\"\"\"\n value: String\n source: VariableSource!\n }\n\n\t\"\"\"\n\tWhere the value comes from.\n\t- DATABASE is stored in the project database, readable and writable with setVariables\n\t- ENVIRONMENT is supplied by the engine environment, overrides a stored value of the same name, and is neither readable nor writable\n\t\"\"\"\n\tenum VariableSource {\n\t\tDATABASE\n\t\tENVIRONMENT\n\t}\n\n`\n"],"names":["gql"],"mappings":";;;AAGO,MAAM,SAAuBA,WAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;AAAAA;;"}
@@ -2,7 +2,7 @@ import { gql } from "graphql-tag";
2
2
  const schema = gql`
3
3
  scalar DateTime
4
4
  scalar Json
5
- scalar Uuid
5
+ scalar UUID
6
6
 
7
7
  schema {
8
8
  query: Query
@@ -13,14 +13,14 @@ const schema = gql`
13
13
  failedEvents(args: EventArgs): [Event!]!
14
14
  eventsToProcess(args: EventArgs): [Event!]!
15
15
  eventsInProcessing(args: EventArgs): [Event!]!
16
- event(id: Uuid!): Event
16
+ event(id: UUID!): Event
17
17
  variables: [Variable!]!
18
18
  }
19
19
 
20
20
  type Mutation {
21
21
  processBatch: ProcessBatchResponse!
22
- retryEvent(id: Uuid!): RetryEventResponse!
23
- stopEvent(id: Uuid!): StopEventResponse!
22
+ retryEvent(id: UUID!): RetryEventResponse!
23
+ stopEvent(id: UUID!): StopEventResponse!
24
24
  setVariables(args: SetVariablesArgs!): SetVariablesResponse!
25
25
  }
26
26
 
@@ -31,9 +31,9 @@ const schema = gql`
31
31
  }
32
32
 
33
33
  type Event {
34
- id: Uuid!
35
- transactionId: Uuid!
36
- identityId: Uuid
34
+ id: UUID!
35
+ transactionId: UUID!
36
+ identityId: UUID
37
37
  ipAddress: String
38
38
  userAgent: String
39
39
  createdAt: DateTime!
@@ -97,9 +97,21 @@ const schema = gql`
97
97
 
98
98
  type Variable {
99
99
  name: String!
100
- value: String!
100
+ """Null when the value is not readable, which is every ENVIRONMENT one."""
101
+ value: String
102
+ source: VariableSource!
101
103
  }
102
104
 
105
+ """
106
+ Where the value comes from.
107
+ - DATABASE is stored in the project database, readable and writable with setVariables
108
+ - ENVIRONMENT is supplied by the engine environment, overrides a stored value of the same name, and is neither readable nor writable
109
+ """
110
+ enum VariableSource {
111
+ DATABASE
112
+ ENVIRONMENT
113
+ }
114
+
103
115
  `;
104
116
  export {
105
117
  schema
@@ -1 +1 @@
1
- {"version":3,"file":"actions.graphql.js","sources":["../../../../../../packages/engine-actions/src/graphql/schema/actions.graphql.ts"],"sourcesContent":["import { gql } from 'graphql-tag'\nimport { DocumentNode } from 'graphql'\n\nexport const schema: DocumentNode = gql`\n scalar DateTime\n scalar Json\n scalar Uuid\n\n schema {\n query: Query\n mutation: Mutation\n }\n\n type Query {\n failedEvents(args: EventArgs): [Event!]!\n eventsToProcess(args: EventArgs): [Event!]!\n eventsInProcessing(args: EventArgs): [Event!]!\n event(id: Uuid!): Event\n variables: [Variable!]!\n }\n\n type Mutation {\n processBatch: ProcessBatchResponse!\n retryEvent(id: Uuid!): RetryEventResponse!\n stopEvent(id: Uuid!): StopEventResponse!\n setVariables(args: SetVariablesArgs!): SetVariablesResponse!\n }\n\n input EventArgs {\n offset: Int\n \"Max 10000\"\n limit: Int\n }\n\n type Event {\n id: Uuid!\n transactionId: Uuid!\n identityId: Uuid\n ipAddress: String\n userAgent: String\n createdAt: DateTime!\n lastStateChange: DateTime!\n resolvedAt: DateTime\n visibleAt: DateTime\n numRetries: Int!\n state: EventState!\n stage: String!\n target: String!\n payload: Json!\n log: Json!\n }\n\n enum EventState {\n created\n retrying\n processing\n succeed\n failed\n stopped\n }\n\n type ProcessBatchResponse {\n ok: Boolean!\n }\n\n type RetryEventResponse {\n ok: Boolean!\n }\n\n type StopEventResponse {\n ok: Boolean!\n }\n\n input SetVariablesArgs {\n variables: [VariableInput!]!\n mode: SetVariablesMode\n }\n\n\t\"\"\"\n\tDefines how it handles original variables.\n\t- MERGE merges with new values (default behaviour)\n\t- SET replaces all variables\n\t- APPEND_ONLY_MISSING appends values if not already exist\n\t\"\"\"\n\tenum SetVariablesMode {\n\t\tMERGE\n\t\tSET\n\t\tAPPEND_ONLY_MISSING\n\t}\n\n input VariableInput {\n name: String!\n value: String!\n }\n\n\ttype SetVariablesResponse {\n\t\tok: Boolean!\n\t}\n\n type Variable {\n name: String!\n value: String!\n }\n\n`\n"],"names":[],"mappings":";AAGO,MAAM,SAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
1
+ {"version":3,"file":"actions.graphql.js","sources":["../../../../../../packages/engine-actions/src/graphql/schema/actions.graphql.ts"],"sourcesContent":["import { gql } from 'graphql-tag'\nimport { DocumentNode } from 'graphql'\n\nexport const schema: DocumentNode = gql`\n scalar DateTime\n scalar Json\n scalar UUID\n\n schema {\n query: Query\n mutation: Mutation\n }\n\n type Query {\n failedEvents(args: EventArgs): [Event!]!\n eventsToProcess(args: EventArgs): [Event!]!\n eventsInProcessing(args: EventArgs): [Event!]!\n event(id: UUID!): Event\n variables: [Variable!]!\n }\n\n type Mutation {\n processBatch: ProcessBatchResponse!\n retryEvent(id: UUID!): RetryEventResponse!\n stopEvent(id: UUID!): StopEventResponse!\n setVariables(args: SetVariablesArgs!): SetVariablesResponse!\n }\n\n input EventArgs {\n offset: Int\n \"Max 10000\"\n limit: Int\n }\n\n type Event {\n id: UUID!\n transactionId: UUID!\n identityId: UUID\n ipAddress: String\n userAgent: String\n createdAt: DateTime!\n lastStateChange: DateTime!\n resolvedAt: DateTime\n visibleAt: DateTime\n numRetries: Int!\n state: EventState!\n stage: String!\n target: String!\n payload: Json!\n log: Json!\n }\n\n enum EventState {\n created\n retrying\n processing\n succeed\n failed\n stopped\n }\n\n type ProcessBatchResponse {\n ok: Boolean!\n }\n\n type RetryEventResponse {\n ok: Boolean!\n }\n\n type StopEventResponse {\n ok: Boolean!\n }\n\n input SetVariablesArgs {\n variables: [VariableInput!]!\n mode: SetVariablesMode\n }\n\n\t\"\"\"\n\tDefines how it handles original variables.\n\t- MERGE merges with new values (default behaviour)\n\t- SET replaces all variables\n\t- APPEND_ONLY_MISSING appends values if not already exist\n\t\"\"\"\n\tenum SetVariablesMode {\n\t\tMERGE\n\t\tSET\n\t\tAPPEND_ONLY_MISSING\n\t}\n\n input VariableInput {\n name: String!\n value: String!\n }\n\n\ttype SetVariablesResponse {\n\t\tok: Boolean!\n\t}\n\n type Variable {\n name: String!\n \"\"\"Null when the value is not readable, which is every ENVIRONMENT one.\"\"\"\n value: String\n source: VariableSource!\n }\n\n\t\"\"\"\n\tWhere the value comes from.\n\t- DATABASE is stored in the project database, readable and writable with setVariables\n\t- ENVIRONMENT is supplied by the engine environment, overrides a stored value of the same name, and is neither readable nor writable\n\t\"\"\"\n\tenum VariableSource {\n\t\tDATABASE\n\t\tENVIRONMENT\n\t}\n\n`\n"],"names":[],"mappings":";AAGO,MAAM,SAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
@@ -3,13 +3,41 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const VariablesQuery = require("./VariablesQuery.cjs");
4
4
  const Database = require("@contember/database");
5
5
  const SetVariableCommand = require("./SetVariableCommand.cjs");
6
+ const engineHttp = require("@contember/engine-http");
7
+ const graphqlUtils = require("@contember/graphql-utils");
8
+ var __defProp = Object.defineProperty;
9
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
+ var __publicField = (obj, key, value) => __defNormalProp(obj, key + "", value);
11
+ const ENV_NAME_INFIX = "_ACTIONS_VARIABLE_";
6
12
  class VariablesManager {
7
- async fetchVariables(db) {
8
- return Object.fromEntries((await db.queryHandler.fetch(new VariablesQuery.VariablesQuery())).map((it) => [it.name, it.value]));
13
+ constructor(env) {
14
+ this.env = env;
15
+ __publicField(this, "envVariablesCache", /* @__PURE__ */ new Map());
16
+ }
17
+ /** Values for dispatch. A variable supplied by the environment shadows a stored row of the same name. */
18
+ async fetchVariables(db, projectSlug) {
19
+ return { ...await this.fetchStoredVariables(db), ...this.fetchEnvVariables(projectSlug) };
20
+ }
21
+ /**
22
+ * The listing is an inventory, not a way to read secrets: an environment value stays in the operator's
23
+ * secret store and is reported as a name with no value.
24
+ */
25
+ async listVariables(db, projectSlug) {
26
+ const envVariables = this.fetchEnvVariables(projectSlug);
27
+ const stored = await this.fetchStoredVariables(db);
28
+ return [
29
+ ...Object.entries(stored).filter(([name]) => !Object.hasOwn(envVariables, name)).map(([name, value]) => ({ name, value, source: "DATABASE" })),
30
+ ...Object.keys(envVariables).map((name) => ({ name, value: null, source: "ENVIRONMENT" }))
31
+ ].sort((a, b) => a.name.localeCompare(b.name));
9
32
  }
10
- async setVariables(db, args) {
33
+ async setVariables(db, args, projectSlug) {
34
+ const envVariables = this.fetchEnvVariables(projectSlug);
35
+ const readOnly = args.variables.map((it) => it.name).filter((it) => Object.hasOwn(envVariables, it));
36
+ if (readOnly.length > 0) {
37
+ throw new graphqlUtils.UserInputError(`Variables supplied by the environment are read-only: ${readOnly.join(", ")}`);
38
+ }
11
39
  return await db.transaction(async (db2) => {
12
- const current = await this.fetchVariables(db2);
40
+ const current = await this.fetchStoredVariables(db2);
13
41
  const mode = args.mode ?? "MERGE";
14
42
  const inputVariables = Object.fromEntries(args.variables.map((it) => [it.name, it.value]));
15
43
  let newVariables = {};
@@ -24,7 +52,7 @@ class VariablesManager {
24
52
  newVariables = inputVariables;
25
53
  break;
26
54
  }
27
- const toDelete = Object.keys(current).filter((it) => !(it in newVariables));
55
+ const toDelete = Object.keys(current).filter((it) => !Object.hasOwn(newVariables, it));
28
56
  if (toDelete.length > 0) {
29
57
  await Database.DeleteBuilder.create().from("actions_variable").where((it) => it.in("name", toDelete)).execute(db2.client);
30
58
  }
@@ -36,6 +64,27 @@ class VariablesManager {
36
64
  }
37
65
  });
38
66
  }
67
+ async fetchStoredVariables(db) {
68
+ return Object.fromEntries((await db.queryHandler.fetch(new VariablesQuery.VariablesQuery())).map((it) => [it.name, it.value]));
69
+ }
70
+ fetchEnvVariables(projectSlug) {
71
+ const cached = this.envVariablesCache.get(projectSlug);
72
+ if (cached !== void 0) {
73
+ return cached;
74
+ }
75
+ const prefixes = [`DEFAULT${ENV_NAME_INFIX}`, engineHttp.projectNameToEnvName(projectSlug) + ENV_NAME_INFIX];
76
+ const result = {};
77
+ for (const prefix of prefixes) {
78
+ for (const [name, value] of Object.entries(this.env)) {
79
+ if (!name.startsWith(prefix) || name.length === prefix.length || value === "") {
80
+ continue;
81
+ }
82
+ result[name.slice(prefix.length)] = value;
83
+ }
84
+ }
85
+ this.envVariablesCache.set(projectSlug, result);
86
+ return result;
87
+ }
39
88
  }
40
89
  exports.VariablesManager = VariablesManager;
41
90
  //# sourceMappingURL=VariablesManager.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"VariablesManager.cjs","sources":["../../../../../packages/engine-actions/src/model/VariablesManager.ts"],"sourcesContent":["import { DatabaseContext } from '@contember/engine-system-api'\nimport { VariablesQuery } from './VariablesQuery.js'\nimport { SetVariablesArgs } from '../graphql/schema/index.js'\nimport { DeleteBuilder } from '@contember/database'\nimport { SetVariableCommand } from './SetVariableCommand.js'\n\nexport type VariablesMap = Record<string, string>\n\nexport class VariablesManager {\n\tpublic async fetchVariables(db: DatabaseContext): Promise<VariablesMap> {\n\t\treturn Object.fromEntries((await db.queryHandler.fetch(new VariablesQuery())).map(it => [it.name, it.value]))\n\t}\n\n\tpublic async setVariables(db: DatabaseContext, args: SetVariablesArgs) {\n\t\treturn await db.transaction(async db => {\n\t\t\tconst current = await this.fetchVariables(db)\n\t\t\tconst mode = args.mode ?? 'MERGE'\n\t\t\tconst inputVariables = Object.fromEntries(args.variables.map(it => [it.name, it.value]))\n\n\t\t\tlet newVariables: VariablesMap = {}\n\t\t\tswitch (mode) {\n\t\t\t\tcase 'APPEND_ONLY_MISSING':\n\t\t\t\t\tnewVariables = { ...inputVariables, ...current }\n\t\t\t\t\tbreak\n\t\t\t\tcase 'MERGE':\n\t\t\t\t\tnewVariables = { ...current, ...inputVariables }\n\t\t\t\t\tbreak\n\t\t\t\tcase 'SET':\n\t\t\t\t\tnewVariables = inputVariables\n\t\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tconst toDelete = Object.keys(current).filter(it => !(it in newVariables))\n\t\t\tif (toDelete.length > 0) {\n\t\t\t\tawait DeleteBuilder.create()\n\t\t\t\t\t.from('actions_variable')\n\t\t\t\t\t.where(it => it.in('name', toDelete))\n\t\t\t\t\t.execute(db.client)\n\t\t\t}\n\n\t\t\tfor (const [name, value] of Object.entries(newVariables)) {\n\t\t\t\tif (value === current[name]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tawait db.commandBus.execute(new SetVariableCommand(name, value))\n\t\t\t}\n\t\t})\n\t}\n}\n"],"names":["VariablesQuery","db","DeleteBuilder","SetVariableCommand"],"mappings":";;;;;AAQO,MAAM,iBAAiB;AAAA,EAC7B,MAAa,eAAe,IAA4C;AACvE,WAAO,OAAO,aAAa,MAAM,GAAG,aAAa,MAAM,IAAIA,eAAAA,eAAA,CAAgB,GAAG,IAAI,QAAM,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC;AAAA,EAC7G;AAAA,EAEA,MAAa,aAAa,IAAqB,MAAwB;AACtE,WAAO,MAAM,GAAG,YAAY,OAAMC,QAAM;AACvC,YAAM,UAAU,MAAM,KAAK,eAAeA,GAAE;AAC5C,YAAM,OAAO,KAAK,QAAQ;AAC1B,YAAM,iBAAiB,OAAO,YAAY,KAAK,UAAU,IAAI,CAAA,OAAM,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC;AAEvF,UAAI,eAA6B,CAAA;AACjC,cAAQ,MAAA;AAAA,QACP,KAAK;AACJ,yBAAe,EAAE,GAAG,gBAAgB,GAAG,QAAA;AACvC;AAAA,QACD,KAAK;AACJ,yBAAe,EAAE,GAAG,SAAS,GAAG,eAAA;AAChC;AAAA,QACD,KAAK;AACJ,yBAAe;AACf;AAAA,MAAA;AAGF,YAAM,WAAW,OAAO,KAAK,OAAO,EAAE,OAAO,CAAA,OAAM,EAAE,MAAM,aAAa;AACxE,UAAI,SAAS,SAAS,GAAG;AACxB,cAAMC,SAAAA,cAAc,OAAA,EAClB,KAAK,kBAAkB,EACvB,MAAM,CAAA,OAAM,GAAG,GAAG,QAAQ,QAAQ,CAAC,EACnC,QAAQD,IAAG,MAAM;AAAA,MACpB;AAEA,iBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACzD,YAAI,UAAU,QAAQ,IAAI,GAAG;AAC5B;AAAA,QACD;AACA,cAAMA,IAAG,WAAW,QAAQ,IAAIE,mBAAAA,mBAAmB,MAAM,KAAK,CAAC;AAAA,MAChE;AAAA,IACD,CAAC;AAAA,EACF;AACD;;"}
1
+ {"version":3,"file":"VariablesManager.cjs","sources":["../../../../../packages/engine-actions/src/model/VariablesManager.ts"],"sourcesContent":["import { DatabaseContext } from '@contember/engine-system-api'\nimport { VariablesQuery } from './VariablesQuery.js'\nimport { SetVariablesArgs, Variable } from '../graphql/schema/index.js'\nimport { DeleteBuilder } from '@contember/database'\nimport { SetVariableCommand } from './SetVariableCommand.js'\nimport { Env, projectNameToEnvName } from '@contember/engine-http'\nimport { UserInputError } from '@contember/graphql-utils'\n\nexport type VariablesMap = Record<string, string>\n\n/** Between the project (or DEFAULT) prefix and the variable name: `MY_PROJECT_ACTIONS_VARIABLE_API_KEY`. */\nconst ENV_NAME_INFIX = '_ACTIONS_VARIABLE_'\n\nexport class VariablesManager {\n\t/** The environment does not change while the process runs, so each project resolves its prefixes once. */\n\tprivate readonly envVariablesCache = new Map<string, VariablesMap>()\n\n\tconstructor(\n\t\tprivate readonly env: Env,\n\t) {\n\t}\n\n\t/** Values for dispatch. A variable supplied by the environment shadows a stored row of the same name. */\n\tpublic async fetchVariables(db: DatabaseContext, projectSlug: string): Promise<VariablesMap> {\n\t\treturn { ...await this.fetchStoredVariables(db), ...this.fetchEnvVariables(projectSlug) }\n\t}\n\n\t/**\n\t * The listing is an inventory, not a way to read secrets: an environment value stays in the operator's\n\t * secret store and is reported as a name with no value.\n\t */\n\tpublic async listVariables(db: DatabaseContext, projectSlug: string): Promise<Variable[]> {\n\t\tconst envVariables = this.fetchEnvVariables(projectSlug)\n\t\tconst stored = await this.fetchStoredVariables(db)\n\t\treturn [\n\t\t\t...Object.entries(stored)\n\t\t\t\t.filter(([name]) => !Object.hasOwn(envVariables, name))\n\t\t\t\t.map(([name, value]): Variable => ({ name, value, source: 'DATABASE' })),\n\t\t\t...Object.keys(envVariables).map((name): Variable => ({ name, value: null, source: 'ENVIRONMENT' })),\n\t\t].sort((a, b) => a.name.localeCompare(b.name))\n\t}\n\n\tpublic async setVariables(db: DatabaseContext, args: SetVariablesArgs, projectSlug: string) {\n\t\tconst envVariables = this.fetchEnvVariables(projectSlug)\n\t\tconst readOnly = args.variables.map(it => it.name).filter(it => Object.hasOwn(envVariables, it))\n\t\tif (readOnly.length > 0) {\n\t\t\tthrow new UserInputError(`Variables supplied by the environment are read-only: ${readOnly.join(', ')}`)\n\t\t}\n\n\t\treturn await db.transaction(async db => {\n\t\t\tconst current = await this.fetchStoredVariables(db)\n\t\t\tconst mode = args.mode ?? 'MERGE'\n\t\t\tconst inputVariables = Object.fromEntries(args.variables.map(it => [it.name, it.value]))\n\n\t\t\tlet newVariables: VariablesMap = {}\n\t\t\tswitch (mode) {\n\t\t\t\tcase 'APPEND_ONLY_MISSING':\n\t\t\t\t\tnewVariables = { ...inputVariables, ...current }\n\t\t\t\t\tbreak\n\t\t\t\tcase 'MERGE':\n\t\t\t\t\tnewVariables = { ...current, ...inputVariables }\n\t\t\t\t\tbreak\n\t\t\t\tcase 'SET':\n\t\t\t\t\tnewVariables = inputVariables\n\t\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tconst toDelete = Object.keys(current).filter(it => !Object.hasOwn(newVariables, it))\n\t\t\tif (toDelete.length > 0) {\n\t\t\t\tawait DeleteBuilder.create()\n\t\t\t\t\t.from('actions_variable')\n\t\t\t\t\t.where(it => it.in('name', toDelete))\n\t\t\t\t\t.execute(db.client)\n\t\t\t}\n\n\t\t\tfor (const [name, value] of Object.entries(newVariables)) {\n\t\t\t\tif (value === current[name]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tawait db.commandBus.execute(new SetVariableCommand(name, value))\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate async fetchStoredVariables(db: DatabaseContext): Promise<VariablesMap> {\n\t\treturn Object.fromEntries((await db.queryHandler.fetch(new VariablesQuery())).map(it => [it.name, it.value]))\n\t}\n\n\tprivate fetchEnvVariables(projectSlug: string): VariablesMap {\n\t\tconst cached = this.envVariablesCache.get(projectSlug)\n\t\tif (cached !== undefined) {\n\t\t\treturn cached\n\t\t}\n\t\t// the project prefix is read last, so it overrides the shared DEFAULT_ one\n\t\tconst prefixes = [`DEFAULT${ENV_NAME_INFIX}`, projectNameToEnvName(projectSlug) + ENV_NAME_INFIX]\n\t\tconst result: VariablesMap = {}\n\t\tfor (const prefix of prefixes) {\n\t\t\tfor (const [name, value] of Object.entries(this.env)) {\n\t\t\t\t// an empty value counts as unset, the same as the `||` fallback of the config parameter resolver\n\t\t\t\tif (!name.startsWith(prefix) || name.length === prefix.length || value === '') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tresult[name.slice(prefix.length)] = value\n\t\t\t}\n\t\t}\n\t\tthis.envVariablesCache.set(projectSlug, result)\n\t\treturn result\n\t}\n}\n"],"names":["UserInputError","db","DeleteBuilder","SetVariableCommand","VariablesQuery","projectNameToEnvName"],"mappings":"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"}
@@ -1,13 +1,41 @@
1
1
  import { VariablesQuery } from "./VariablesQuery.js";
2
2
  import { DeleteBuilder } from "@contember/database";
3
3
  import { SetVariableCommand } from "./SetVariableCommand.js";
4
+ import { projectNameToEnvName } from "@contember/engine-http";
5
+ import { UserInputError } from "@contember/graphql-utils";
6
+ var __defProp = Object.defineProperty;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __publicField = (obj, key, value) => __defNormalProp(obj, key + "", value);
9
+ const ENV_NAME_INFIX = "_ACTIONS_VARIABLE_";
4
10
  class VariablesManager {
5
- async fetchVariables(db) {
6
- return Object.fromEntries((await db.queryHandler.fetch(new VariablesQuery())).map((it) => [it.name, it.value]));
11
+ constructor(env) {
12
+ this.env = env;
13
+ __publicField(this, "envVariablesCache", /* @__PURE__ */ new Map());
14
+ }
15
+ /** Values for dispatch. A variable supplied by the environment shadows a stored row of the same name. */
16
+ async fetchVariables(db, projectSlug) {
17
+ return { ...await this.fetchStoredVariables(db), ...this.fetchEnvVariables(projectSlug) };
18
+ }
19
+ /**
20
+ * The listing is an inventory, not a way to read secrets: an environment value stays in the operator's
21
+ * secret store and is reported as a name with no value.
22
+ */
23
+ async listVariables(db, projectSlug) {
24
+ const envVariables = this.fetchEnvVariables(projectSlug);
25
+ const stored = await this.fetchStoredVariables(db);
26
+ return [
27
+ ...Object.entries(stored).filter(([name]) => !Object.hasOwn(envVariables, name)).map(([name, value]) => ({ name, value, source: "DATABASE" })),
28
+ ...Object.keys(envVariables).map((name) => ({ name, value: null, source: "ENVIRONMENT" }))
29
+ ].sort((a, b) => a.name.localeCompare(b.name));
7
30
  }
8
- async setVariables(db, args) {
31
+ async setVariables(db, args, projectSlug) {
32
+ const envVariables = this.fetchEnvVariables(projectSlug);
33
+ const readOnly = args.variables.map((it) => it.name).filter((it) => Object.hasOwn(envVariables, it));
34
+ if (readOnly.length > 0) {
35
+ throw new UserInputError(`Variables supplied by the environment are read-only: ${readOnly.join(", ")}`);
36
+ }
9
37
  return await db.transaction(async (db2) => {
10
- const current = await this.fetchVariables(db2);
38
+ const current = await this.fetchStoredVariables(db2);
11
39
  const mode = args.mode ?? "MERGE";
12
40
  const inputVariables = Object.fromEntries(args.variables.map((it) => [it.name, it.value]));
13
41
  let newVariables = {};
@@ -22,7 +50,7 @@ class VariablesManager {
22
50
  newVariables = inputVariables;
23
51
  break;
24
52
  }
25
- const toDelete = Object.keys(current).filter((it) => !(it in newVariables));
53
+ const toDelete = Object.keys(current).filter((it) => !Object.hasOwn(newVariables, it));
26
54
  if (toDelete.length > 0) {
27
55
  await DeleteBuilder.create().from("actions_variable").where((it) => it.in("name", toDelete)).execute(db2.client);
28
56
  }
@@ -34,6 +62,27 @@ class VariablesManager {
34
62
  }
35
63
  });
36
64
  }
65
+ async fetchStoredVariables(db) {
66
+ return Object.fromEntries((await db.queryHandler.fetch(new VariablesQuery())).map((it) => [it.name, it.value]));
67
+ }
68
+ fetchEnvVariables(projectSlug) {
69
+ const cached = this.envVariablesCache.get(projectSlug);
70
+ if (cached !== void 0) {
71
+ return cached;
72
+ }
73
+ const prefixes = [`DEFAULT${ENV_NAME_INFIX}`, projectNameToEnvName(projectSlug) + ENV_NAME_INFIX];
74
+ const result = {};
75
+ for (const prefix of prefixes) {
76
+ for (const [name, value] of Object.entries(this.env)) {
77
+ if (!name.startsWith(prefix) || name.length === prefix.length || value === "") {
78
+ continue;
79
+ }
80
+ result[name.slice(prefix.length)] = value;
81
+ }
82
+ }
83
+ this.envVariablesCache.set(projectSlug, result);
84
+ return result;
85
+ }
37
86
  }
38
87
  export {
39
88
  VariablesManager
@@ -1 +1 @@
1
- {"version":3,"file":"VariablesManager.js","sources":["../../../../../packages/engine-actions/src/model/VariablesManager.ts"],"sourcesContent":["import { DatabaseContext } from '@contember/engine-system-api'\nimport { VariablesQuery } from './VariablesQuery.js'\nimport { SetVariablesArgs } from '../graphql/schema/index.js'\nimport { DeleteBuilder } from '@contember/database'\nimport { SetVariableCommand } from './SetVariableCommand.js'\n\nexport type VariablesMap = Record<string, string>\n\nexport class VariablesManager {\n\tpublic async fetchVariables(db: DatabaseContext): Promise<VariablesMap> {\n\t\treturn Object.fromEntries((await db.queryHandler.fetch(new VariablesQuery())).map(it => [it.name, it.value]))\n\t}\n\n\tpublic async setVariables(db: DatabaseContext, args: SetVariablesArgs) {\n\t\treturn await db.transaction(async db => {\n\t\t\tconst current = await this.fetchVariables(db)\n\t\t\tconst mode = args.mode ?? 'MERGE'\n\t\t\tconst inputVariables = Object.fromEntries(args.variables.map(it => [it.name, it.value]))\n\n\t\t\tlet newVariables: VariablesMap = {}\n\t\t\tswitch (mode) {\n\t\t\t\tcase 'APPEND_ONLY_MISSING':\n\t\t\t\t\tnewVariables = { ...inputVariables, ...current }\n\t\t\t\t\tbreak\n\t\t\t\tcase 'MERGE':\n\t\t\t\t\tnewVariables = { ...current, ...inputVariables }\n\t\t\t\t\tbreak\n\t\t\t\tcase 'SET':\n\t\t\t\t\tnewVariables = inputVariables\n\t\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tconst toDelete = Object.keys(current).filter(it => !(it in newVariables))\n\t\t\tif (toDelete.length > 0) {\n\t\t\t\tawait DeleteBuilder.create()\n\t\t\t\t\t.from('actions_variable')\n\t\t\t\t\t.where(it => it.in('name', toDelete))\n\t\t\t\t\t.execute(db.client)\n\t\t\t}\n\n\t\t\tfor (const [name, value] of Object.entries(newVariables)) {\n\t\t\t\tif (value === current[name]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tawait db.commandBus.execute(new SetVariableCommand(name, value))\n\t\t\t}\n\t\t})\n\t}\n}\n"],"names":["db"],"mappings":";;;AAQO,MAAM,iBAAiB;AAAA,EAC7B,MAAa,eAAe,IAA4C;AACvE,WAAO,OAAO,aAAa,MAAM,GAAG,aAAa,MAAM,IAAI,eAAA,CAAgB,GAAG,IAAI,QAAM,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC;AAAA,EAC7G;AAAA,EAEA,MAAa,aAAa,IAAqB,MAAwB;AACtE,WAAO,MAAM,GAAG,YAAY,OAAMA,QAAM;AACvC,YAAM,UAAU,MAAM,KAAK,eAAeA,GAAE;AAC5C,YAAM,OAAO,KAAK,QAAQ;AAC1B,YAAM,iBAAiB,OAAO,YAAY,KAAK,UAAU,IAAI,CAAA,OAAM,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC;AAEvF,UAAI,eAA6B,CAAA;AACjC,cAAQ,MAAA;AAAA,QACP,KAAK;AACJ,yBAAe,EAAE,GAAG,gBAAgB,GAAG,QAAA;AACvC;AAAA,QACD,KAAK;AACJ,yBAAe,EAAE,GAAG,SAAS,GAAG,eAAA;AAChC;AAAA,QACD,KAAK;AACJ,yBAAe;AACf;AAAA,MAAA;AAGF,YAAM,WAAW,OAAO,KAAK,OAAO,EAAE,OAAO,CAAA,OAAM,EAAE,MAAM,aAAa;AACxE,UAAI,SAAS,SAAS,GAAG;AACxB,cAAM,cAAc,OAAA,EAClB,KAAK,kBAAkB,EACvB,MAAM,CAAA,OAAM,GAAG,GAAG,QAAQ,QAAQ,CAAC,EACnC,QAAQA,IAAG,MAAM;AAAA,MACpB;AAEA,iBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACzD,YAAI,UAAU,QAAQ,IAAI,GAAG;AAC5B;AAAA,QACD;AACA,cAAMA,IAAG,WAAW,QAAQ,IAAI,mBAAmB,MAAM,KAAK,CAAC;AAAA,MAChE;AAAA,IACD,CAAC;AAAA,EACF;AACD;"}
1
+ {"version":3,"file":"VariablesManager.js","sources":["../../../../../packages/engine-actions/src/model/VariablesManager.ts"],"sourcesContent":["import { DatabaseContext } from '@contember/engine-system-api'\nimport { VariablesQuery } from './VariablesQuery.js'\nimport { SetVariablesArgs, Variable } from '../graphql/schema/index.js'\nimport { DeleteBuilder } from '@contember/database'\nimport { SetVariableCommand } from './SetVariableCommand.js'\nimport { Env, projectNameToEnvName } from '@contember/engine-http'\nimport { UserInputError } from '@contember/graphql-utils'\n\nexport type VariablesMap = Record<string, string>\n\n/** Between the project (or DEFAULT) prefix and the variable name: `MY_PROJECT_ACTIONS_VARIABLE_API_KEY`. */\nconst ENV_NAME_INFIX = '_ACTIONS_VARIABLE_'\n\nexport class VariablesManager {\n\t/** The environment does not change while the process runs, so each project resolves its prefixes once. */\n\tprivate readonly envVariablesCache = new Map<string, VariablesMap>()\n\n\tconstructor(\n\t\tprivate readonly env: Env,\n\t) {\n\t}\n\n\t/** Values for dispatch. A variable supplied by the environment shadows a stored row of the same name. */\n\tpublic async fetchVariables(db: DatabaseContext, projectSlug: string): Promise<VariablesMap> {\n\t\treturn { ...await this.fetchStoredVariables(db), ...this.fetchEnvVariables(projectSlug) }\n\t}\n\n\t/**\n\t * The listing is an inventory, not a way to read secrets: an environment value stays in the operator's\n\t * secret store and is reported as a name with no value.\n\t */\n\tpublic async listVariables(db: DatabaseContext, projectSlug: string): Promise<Variable[]> {\n\t\tconst envVariables = this.fetchEnvVariables(projectSlug)\n\t\tconst stored = await this.fetchStoredVariables(db)\n\t\treturn [\n\t\t\t...Object.entries(stored)\n\t\t\t\t.filter(([name]) => !Object.hasOwn(envVariables, name))\n\t\t\t\t.map(([name, value]): Variable => ({ name, value, source: 'DATABASE' })),\n\t\t\t...Object.keys(envVariables).map((name): Variable => ({ name, value: null, source: 'ENVIRONMENT' })),\n\t\t].sort((a, b) => a.name.localeCompare(b.name))\n\t}\n\n\tpublic async setVariables(db: DatabaseContext, args: SetVariablesArgs, projectSlug: string) {\n\t\tconst envVariables = this.fetchEnvVariables(projectSlug)\n\t\tconst readOnly = args.variables.map(it => it.name).filter(it => Object.hasOwn(envVariables, it))\n\t\tif (readOnly.length > 0) {\n\t\t\tthrow new UserInputError(`Variables supplied by the environment are read-only: ${readOnly.join(', ')}`)\n\t\t}\n\n\t\treturn await db.transaction(async db => {\n\t\t\tconst current = await this.fetchStoredVariables(db)\n\t\t\tconst mode = args.mode ?? 'MERGE'\n\t\t\tconst inputVariables = Object.fromEntries(args.variables.map(it => [it.name, it.value]))\n\n\t\t\tlet newVariables: VariablesMap = {}\n\t\t\tswitch (mode) {\n\t\t\t\tcase 'APPEND_ONLY_MISSING':\n\t\t\t\t\tnewVariables = { ...inputVariables, ...current }\n\t\t\t\t\tbreak\n\t\t\t\tcase 'MERGE':\n\t\t\t\t\tnewVariables = { ...current, ...inputVariables }\n\t\t\t\t\tbreak\n\t\t\t\tcase 'SET':\n\t\t\t\t\tnewVariables = inputVariables\n\t\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tconst toDelete = Object.keys(current).filter(it => !Object.hasOwn(newVariables, it))\n\t\t\tif (toDelete.length > 0) {\n\t\t\t\tawait DeleteBuilder.create()\n\t\t\t\t\t.from('actions_variable')\n\t\t\t\t\t.where(it => it.in('name', toDelete))\n\t\t\t\t\t.execute(db.client)\n\t\t\t}\n\n\t\t\tfor (const [name, value] of Object.entries(newVariables)) {\n\t\t\t\tif (value === current[name]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tawait db.commandBus.execute(new SetVariableCommand(name, value))\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate async fetchStoredVariables(db: DatabaseContext): Promise<VariablesMap> {\n\t\treturn Object.fromEntries((await db.queryHandler.fetch(new VariablesQuery())).map(it => [it.name, it.value]))\n\t}\n\n\tprivate fetchEnvVariables(projectSlug: string): VariablesMap {\n\t\tconst cached = this.envVariablesCache.get(projectSlug)\n\t\tif (cached !== undefined) {\n\t\t\treturn cached\n\t\t}\n\t\t// the project prefix is read last, so it overrides the shared DEFAULT_ one\n\t\tconst prefixes = [`DEFAULT${ENV_NAME_INFIX}`, projectNameToEnvName(projectSlug) + ENV_NAME_INFIX]\n\t\tconst result: VariablesMap = {}\n\t\tfor (const prefix of prefixes) {\n\t\t\tfor (const [name, value] of Object.entries(this.env)) {\n\t\t\t\t// an empty value counts as unset, the same as the `||` fallback of the config parameter resolver\n\t\t\t\tif (!name.startsWith(prefix) || name.length === prefix.length || value === '') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tresult[name.slice(prefix.length)] = value\n\t\t\t}\n\t\t}\n\t\tthis.envVariablesCache.set(projectSlug, result)\n\t\treturn result\n\t}\n}\n"],"names":["db"],"mappings":"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"}
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const Database = require("@contember/database");
4
4
  const notifyChannel = require("../utils/notifyChannel.cjs");
5
5
  class TriggerPayloadPersister {
6
- constructor(mapper, client, providers, projectSlug, stageId, schemaId, identityId, userInfo, triggeredActionsCollector) {
6
+ constructor(mapper, client, providers, projectSlug, stageId, schemaId, identityId, userInfo, triggeredActionsCollector, metrics) {
7
7
  this.mapper = mapper;
8
8
  this.client = client;
9
9
  this.providers = providers;
@@ -13,6 +13,7 @@ class TriggerPayloadPersister {
13
13
  this.identityId = identityId;
14
14
  this.userInfo = userInfo;
15
15
  this.triggeredActionsCollector = triggeredActionsCollector;
16
+ this.metrics = metrics;
16
17
  }
17
18
  async persist(trigger, payloads) {
18
19
  const chunkSize = 100;
@@ -48,6 +49,7 @@ class TriggerPayloadPersister {
48
49
  };
49
50
  });
50
51
  await Database.InsertBuilder.create().into("actions_event").values(rows).execute(this.client);
52
+ this.metrics?.enqueued(rows.length);
51
53
  if (collected && collected.length > 0) {
52
54
  collector.add(collected);
53
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TriggerPayloadPersister.cjs","sources":["../../../../../packages/engine-actions/src/triggers/TriggerPayloadPersister.ts"],"sourcesContent":["import { Client, InsertBuilder } from '@contember/database'\nimport { Mapper, TriggeredActionEvent, TriggeredActionsCollector } from '@contember/engine-content-api'\nimport { Actions, ActionsPayload } from '@contember/schema'\nimport { EventRow } from '../model/types.js'\nimport { notify } from '../utils/notifyChannel.js'\n\ntype EventRowToInsert = Omit<EventRow, 'created_at' | 'visible_at' | 'last_state_change' | 'log'> & {\n\tcreated_at: string | Date\n\tvisible_at: string | Date\n\tlast_state_change: string | Date\n}\n\nexport class TriggerPayloadPersister {\n\tconstructor(\n\t\tprivate readonly mapper: Mapper,\n\t\tprivate readonly client: Client,\n\t\tprivate readonly providers: { uuid: () => string },\n\t\tprivate readonly projectSlug: string,\n\t\tprivate readonly stageId: string,\n\t\tprivate readonly schemaId: number | undefined,\n\t\tprivate readonly identityId: string,\n\t\tprivate readonly userInfo: { ipAddress: string | null; userAgent: string | null },\n\t\tprivate readonly triggeredActionsCollector: TriggeredActionsCollector | undefined,\n\t) {\n\t}\n\n\tpublic async persist(trigger: Actions.AnyTrigger, payloads: ActionsPayload.AnyEventPayload[]): Promise<void> {\n\t\tconst chunkSize = 100\n\t\tif (!this.schemaId) {\n\t\t\tthrow new Error('Schema id is not set')\n\t\t}\n\t\tconst collector = this.triggeredActionsCollector\n\t\tfor (let i = 0; i < payloads.length; i += chunkSize) {\n\t\t\tconst chunk = payloads.slice(i, i + chunkSize)\n\t\t\tconst collected: TriggeredActionEvent[] | undefined = collector ? [] : undefined\n\t\t\tconst rows = chunk.map((it): EventRowToInsert => {\n\t\t\t\tconst id = this.providers.uuid()\n\t\t\t\tconst transactionId = this.mapper.transactionId\n\t\t\t\tcollected?.push({ id, trigger: trigger.name, target: trigger.target, transactionId })\n\t\t\t\treturn {\n\t\t\t\t\tid,\n\t\t\t\t\ttransaction_id: transactionId,\n\t\t\t\t\tcreated_at: 'now',\n\t\t\t\t\tvisible_at: 'now',\n\t\t\t\t\tnum_retries: 0,\n\t\t\t\t\tstate: 'created',\n\t\t\t\t\tstage_id: this.stageId,\n\t\t\t\t\tschema_id: this.schemaId!,\n\t\t\t\t\ttarget: trigger.target,\n\t\t\t\t\ttrigger: trigger.name,\n\t\t\t\t\tpriority: trigger.priority ?? 0,\n\t\t\t\t\tpayload: it,\n\t\t\t\t\tresolved_at: null,\n\t\t\t\t\tlast_state_change: 'now',\n\t\t\t\t\tidentity_id: this.identityId,\n\t\t\t\t\tip_address: this.userInfo.ipAddress,\n\t\t\t\t\tuser_agent: this.userInfo.userAgent,\n\t\t\t\t}\n\t\t\t})\n\t\t\tawait InsertBuilder.create()\n\t\t\t\t.into('actions_event')\n\t\t\t\t.values(rows)\n\t\t\t\t.execute(this.client)\n\n\t\t\tif (collected && collected.length > 0) {\n\t\t\t\tcollector!.add(collected)\n\t\t\t}\n\t\t}\n\n\t\tawait notify(this.client, this.projectSlug)\n\t}\n}\n"],"names":["InsertBuilder","notify"],"mappings":";;;;AAYO,MAAM,wBAAwB;AAAA,EACpC,YACkB,QACA,QACA,WACA,aACA,SACA,UACA,YACA,UACA,2BAChB;AATgB,SAAA,SAAA;AACA,SAAA,SAAA;AACA,SAAA,YAAA;AACA,SAAA,cAAA;AACA,SAAA,UAAA;AACA,SAAA,WAAA;AACA,SAAA,aAAA;AACA,SAAA,WAAA;AACA,SAAA,4BAAA;AAAA,EAElB;AAAA,EAEA,MAAa,QAAQ,SAA6B,UAA2D;AAC5G,UAAM,YAAY;AAClB,QAAI,CAAC,KAAK,UAAU;AACnB,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACvC;AACA,UAAM,YAAY,KAAK;AACvB,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,WAAW;AACpD,YAAM,QAAQ,SAAS,MAAM,GAAG,IAAI,SAAS;AAC7C,YAAM,YAAgD,YAAY,CAAA,IAAK;AACvE,YAAM,OAAO,MAAM,IAAI,CAAC,OAAyB;AAChD,cAAM,KAAK,KAAK,UAAU,KAAA;AAC1B,cAAM,gBAAgB,KAAK,OAAO;AAClC,mBAAW,KAAK,EAAE,IAAI,SAAS,QAAQ,MAAM,QAAQ,QAAQ,QAAQ,cAAA,CAAe;AACpF,eAAO;AAAA,UACN;AAAA,UACA,gBAAgB;AAAA,UAChB,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ,aAAa;AAAA,UACb,OAAO;AAAA,UACP,UAAU,KAAK;AAAA,UACf,WAAW,KAAK;AAAA,UAChB,QAAQ,QAAQ;AAAA,UAChB,SAAS,QAAQ;AAAA,UACjB,UAAU,QAAQ,YAAY;AAAA,UAC9B,SAAS;AAAA,UACT,aAAa;AAAA,UACb,mBAAmB;AAAA,UACnB,aAAa,KAAK;AAAA,UAClB,YAAY,KAAK,SAAS;AAAA,UAC1B,YAAY,KAAK,SAAS;AAAA,QAAA;AAAA,MAE5B,CAAC;AACD,YAAMA,uBAAc,SAClB,KAAK,eAAe,EACpB,OAAO,IAAI,EACX,QAAQ,KAAK,MAAM;AAErB,UAAI,aAAa,UAAU,SAAS,GAAG;AACtC,kBAAW,IAAI,SAAS;AAAA,MACzB;AAAA,IACD;AAEA,UAAMC,cAAAA,OAAO,KAAK,QAAQ,KAAK,WAAW;AAAA,EAC3C;AACD;;"}
1
+ {"version":3,"file":"TriggerPayloadPersister.cjs","sources":["../../../../../packages/engine-actions/src/triggers/TriggerPayloadPersister.ts"],"sourcesContent":["import { Client, InsertBuilder } from '@contember/database'\nimport { Mapper, TriggeredActionEvent, TriggeredActionsCollector } from '@contember/engine-content-api'\nimport { Actions, ActionsPayload } from '@contember/schema'\nimport { EventRow } from '../model/types.js'\nimport { notify } from '../utils/notifyChannel.js'\nimport { ProjectActionsMetrics } from '../ActionsMetrics.js'\n\ntype EventRowToInsert = Omit<EventRow, 'created_at' | 'visible_at' | 'last_state_change' | 'log'> & {\n\tcreated_at: string | Date\n\tvisible_at: string | Date\n\tlast_state_change: string | Date\n}\n\nexport class TriggerPayloadPersister {\n\tconstructor(\n\t\tprivate readonly mapper: Mapper,\n\t\tprivate readonly client: Client,\n\t\tprivate readonly providers: { uuid: () => string },\n\t\tprivate readonly projectSlug: string,\n\t\tprivate readonly stageId: string,\n\t\tprivate readonly schemaId: number | undefined,\n\t\tprivate readonly identityId: string,\n\t\tprivate readonly userInfo: { ipAddress: string | null; userAgent: string | null },\n\t\tprivate readonly triggeredActionsCollector: TriggeredActionsCollector | undefined,\n\t\tprivate readonly metrics: ProjectActionsMetrics | undefined,\n\t) {\n\t}\n\n\tpublic async persist(trigger: Actions.AnyTrigger, payloads: ActionsPayload.AnyEventPayload[]): Promise<void> {\n\t\tconst chunkSize = 100\n\t\tif (!this.schemaId) {\n\t\t\tthrow new Error('Schema id is not set')\n\t\t}\n\t\tconst collector = this.triggeredActionsCollector\n\t\tfor (let i = 0; i < payloads.length; i += chunkSize) {\n\t\t\tconst chunk = payloads.slice(i, i + chunkSize)\n\t\t\tconst collected: TriggeredActionEvent[] | undefined = collector ? [] : undefined\n\t\t\tconst rows = chunk.map((it): EventRowToInsert => {\n\t\t\t\tconst id = this.providers.uuid()\n\t\t\t\tconst transactionId = this.mapper.transactionId\n\t\t\t\tcollected?.push({ id, trigger: trigger.name, target: trigger.target, transactionId })\n\t\t\t\treturn {\n\t\t\t\t\tid,\n\t\t\t\t\ttransaction_id: transactionId,\n\t\t\t\t\tcreated_at: 'now',\n\t\t\t\t\tvisible_at: 'now',\n\t\t\t\t\tnum_retries: 0,\n\t\t\t\t\tstate: 'created',\n\t\t\t\t\tstage_id: this.stageId,\n\t\t\t\t\tschema_id: this.schemaId!,\n\t\t\t\t\ttarget: trigger.target,\n\t\t\t\t\ttrigger: trigger.name,\n\t\t\t\t\tpriority: trigger.priority ?? 0,\n\t\t\t\t\tpayload: it,\n\t\t\t\t\tresolved_at: null,\n\t\t\t\t\tlast_state_change: 'now',\n\t\t\t\t\tidentity_id: this.identityId,\n\t\t\t\t\tip_address: this.userInfo.ipAddress,\n\t\t\t\t\tuser_agent: this.userInfo.userAgent,\n\t\t\t\t}\n\t\t\t})\n\t\t\tawait InsertBuilder.create()\n\t\t\t\t.into('actions_event')\n\t\t\t\t.values(rows)\n\t\t\t\t.execute(this.client)\n\n\t\t\t// Counted before commit (events are written in the mutation's transaction); a rollback\n\t\t\t// would over-count enqueued. Acceptable for a backlog *trend*, which is the intended use.\n\t\t\tthis.metrics?.enqueued(rows.length)\n\n\t\t\tif (collected && collected.length > 0) {\n\t\t\t\tcollector!.add(collected)\n\t\t\t}\n\t\t}\n\n\t\tawait notify(this.client, this.projectSlug)\n\t}\n}\n"],"names":["InsertBuilder","notify"],"mappings":";;;;AAaO,MAAM,wBAAwB;AAAA,EACpC,YACkB,QACA,QACA,WACA,aACA,SACA,UACA,YACA,UACA,2BACA,SAChB;AAVgB,SAAA,SAAA;AACA,SAAA,SAAA;AACA,SAAA,YAAA;AACA,SAAA,cAAA;AACA,SAAA,UAAA;AACA,SAAA,WAAA;AACA,SAAA,aAAA;AACA,SAAA,WAAA;AACA,SAAA,4BAAA;AACA,SAAA,UAAA;AAAA,EAElB;AAAA,EAEA,MAAa,QAAQ,SAA6B,UAA2D;AAC5G,UAAM,YAAY;AAClB,QAAI,CAAC,KAAK,UAAU;AACnB,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACvC;AACA,UAAM,YAAY,KAAK;AACvB,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,WAAW;AACpD,YAAM,QAAQ,SAAS,MAAM,GAAG,IAAI,SAAS;AAC7C,YAAM,YAAgD,YAAY,CAAA,IAAK;AACvE,YAAM,OAAO,MAAM,IAAI,CAAC,OAAyB;AAChD,cAAM,KAAK,KAAK,UAAU,KAAA;AAC1B,cAAM,gBAAgB,KAAK,OAAO;AAClC,mBAAW,KAAK,EAAE,IAAI,SAAS,QAAQ,MAAM,QAAQ,QAAQ,QAAQ,cAAA,CAAe;AACpF,eAAO;AAAA,UACN;AAAA,UACA,gBAAgB;AAAA,UAChB,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ,aAAa;AAAA,UACb,OAAO;AAAA,UACP,UAAU,KAAK;AAAA,UACf,WAAW,KAAK;AAAA,UAChB,QAAQ,QAAQ;AAAA,UAChB,SAAS,QAAQ;AAAA,UACjB,UAAU,QAAQ,YAAY;AAAA,UAC9B,SAAS;AAAA,UACT,aAAa;AAAA,UACb,mBAAmB;AAAA,UACnB,aAAa,KAAK;AAAA,UAClB,YAAY,KAAK,SAAS;AAAA,UAC1B,YAAY,KAAK,SAAS;AAAA,QAAA;AAAA,MAE5B,CAAC;AACD,YAAMA,uBAAc,SAClB,KAAK,eAAe,EACpB,OAAO,IAAI,EACX,QAAQ,KAAK,MAAM;AAIrB,WAAK,SAAS,SAAS,KAAK,MAAM;AAElC,UAAI,aAAa,UAAU,SAAS,GAAG;AACtC,kBAAW,IAAI,SAAS;AAAA,MACzB;AAAA,IACD;AAEA,UAAMC,cAAAA,OAAO,KAAK,QAAQ,KAAK,WAAW;AAAA,EAC3C;AACD;;"}
@@ -1,7 +1,7 @@
1
1
  import { InsertBuilder as InsertBuilder$1 } from "@contember/database";
2
2
  import { notify } from "../utils/notifyChannel.js";
3
3
  class TriggerPayloadPersister {
4
- constructor(mapper, client, providers, projectSlug, stageId, schemaId, identityId, userInfo, triggeredActionsCollector) {
4
+ constructor(mapper, client, providers, projectSlug, stageId, schemaId, identityId, userInfo, triggeredActionsCollector, metrics) {
5
5
  this.mapper = mapper;
6
6
  this.client = client;
7
7
  this.providers = providers;
@@ -11,6 +11,7 @@ class TriggerPayloadPersister {
11
11
  this.identityId = identityId;
12
12
  this.userInfo = userInfo;
13
13
  this.triggeredActionsCollector = triggeredActionsCollector;
14
+ this.metrics = metrics;
14
15
  }
15
16
  async persist(trigger, payloads) {
16
17
  const chunkSize = 100;
@@ -46,6 +47,7 @@ class TriggerPayloadPersister {
46
47
  };
47
48
  });
48
49
  await InsertBuilder$1.create().into("actions_event").values(rows).execute(this.client);
50
+ this.metrics?.enqueued(rows.length);
49
51
  if (collected && collected.length > 0) {
50
52
  collector.add(collected);
51
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TriggerPayloadPersister.js","sources":["../../../../../packages/engine-actions/src/triggers/TriggerPayloadPersister.ts"],"sourcesContent":["import { Client, InsertBuilder } from '@contember/database'\nimport { Mapper, TriggeredActionEvent, TriggeredActionsCollector } from '@contember/engine-content-api'\nimport { Actions, ActionsPayload } from '@contember/schema'\nimport { EventRow } from '../model/types.js'\nimport { notify } from '../utils/notifyChannel.js'\n\ntype EventRowToInsert = Omit<EventRow, 'created_at' | 'visible_at' | 'last_state_change' | 'log'> & {\n\tcreated_at: string | Date\n\tvisible_at: string | Date\n\tlast_state_change: string | Date\n}\n\nexport class TriggerPayloadPersister {\n\tconstructor(\n\t\tprivate readonly mapper: Mapper,\n\t\tprivate readonly client: Client,\n\t\tprivate readonly providers: { uuid: () => string },\n\t\tprivate readonly projectSlug: string,\n\t\tprivate readonly stageId: string,\n\t\tprivate readonly schemaId: number | undefined,\n\t\tprivate readonly identityId: string,\n\t\tprivate readonly userInfo: { ipAddress: string | null; userAgent: string | null },\n\t\tprivate readonly triggeredActionsCollector: TriggeredActionsCollector | undefined,\n\t) {\n\t}\n\n\tpublic async persist(trigger: Actions.AnyTrigger, payloads: ActionsPayload.AnyEventPayload[]): Promise<void> {\n\t\tconst chunkSize = 100\n\t\tif (!this.schemaId) {\n\t\t\tthrow new Error('Schema id is not set')\n\t\t}\n\t\tconst collector = this.triggeredActionsCollector\n\t\tfor (let i = 0; i < payloads.length; i += chunkSize) {\n\t\t\tconst chunk = payloads.slice(i, i + chunkSize)\n\t\t\tconst collected: TriggeredActionEvent[] | undefined = collector ? [] : undefined\n\t\t\tconst rows = chunk.map((it): EventRowToInsert => {\n\t\t\t\tconst id = this.providers.uuid()\n\t\t\t\tconst transactionId = this.mapper.transactionId\n\t\t\t\tcollected?.push({ id, trigger: trigger.name, target: trigger.target, transactionId })\n\t\t\t\treturn {\n\t\t\t\t\tid,\n\t\t\t\t\ttransaction_id: transactionId,\n\t\t\t\t\tcreated_at: 'now',\n\t\t\t\t\tvisible_at: 'now',\n\t\t\t\t\tnum_retries: 0,\n\t\t\t\t\tstate: 'created',\n\t\t\t\t\tstage_id: this.stageId,\n\t\t\t\t\tschema_id: this.schemaId!,\n\t\t\t\t\ttarget: trigger.target,\n\t\t\t\t\ttrigger: trigger.name,\n\t\t\t\t\tpriority: trigger.priority ?? 0,\n\t\t\t\t\tpayload: it,\n\t\t\t\t\tresolved_at: null,\n\t\t\t\t\tlast_state_change: 'now',\n\t\t\t\t\tidentity_id: this.identityId,\n\t\t\t\t\tip_address: this.userInfo.ipAddress,\n\t\t\t\t\tuser_agent: this.userInfo.userAgent,\n\t\t\t\t}\n\t\t\t})\n\t\t\tawait InsertBuilder.create()\n\t\t\t\t.into('actions_event')\n\t\t\t\t.values(rows)\n\t\t\t\t.execute(this.client)\n\n\t\t\tif (collected && collected.length > 0) {\n\t\t\t\tcollector!.add(collected)\n\t\t\t}\n\t\t}\n\n\t\tawait notify(this.client, this.projectSlug)\n\t}\n}\n"],"names":["InsertBuilder"],"mappings":";;AAYO,MAAM,wBAAwB;AAAA,EACpC,YACkB,QACA,QACA,WACA,aACA,SACA,UACA,YACA,UACA,2BAChB;AATgB,SAAA,SAAA;AACA,SAAA,SAAA;AACA,SAAA,YAAA;AACA,SAAA,cAAA;AACA,SAAA,UAAA;AACA,SAAA,WAAA;AACA,SAAA,aAAA;AACA,SAAA,WAAA;AACA,SAAA,4BAAA;AAAA,EAElB;AAAA,EAEA,MAAa,QAAQ,SAA6B,UAA2D;AAC5G,UAAM,YAAY;AAClB,QAAI,CAAC,KAAK,UAAU;AACnB,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACvC;AACA,UAAM,YAAY,KAAK;AACvB,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,WAAW;AACpD,YAAM,QAAQ,SAAS,MAAM,GAAG,IAAI,SAAS;AAC7C,YAAM,YAAgD,YAAY,CAAA,IAAK;AACvE,YAAM,OAAO,MAAM,IAAI,CAAC,OAAyB;AAChD,cAAM,KAAK,KAAK,UAAU,KAAA;AAC1B,cAAM,gBAAgB,KAAK,OAAO;AAClC,mBAAW,KAAK,EAAE,IAAI,SAAS,QAAQ,MAAM,QAAQ,QAAQ,QAAQ,cAAA,CAAe;AACpF,eAAO;AAAA,UACN;AAAA,UACA,gBAAgB;AAAA,UAChB,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ,aAAa;AAAA,UACb,OAAO;AAAA,UACP,UAAU,KAAK;AAAA,UACf,WAAW,KAAK;AAAA,UAChB,QAAQ,QAAQ;AAAA,UAChB,SAAS,QAAQ;AAAA,UACjB,UAAU,QAAQ,YAAY;AAAA,UAC9B,SAAS;AAAA,UACT,aAAa;AAAA,UACb,mBAAmB;AAAA,UACnB,aAAa,KAAK;AAAA,UAClB,YAAY,KAAK,SAAS;AAAA,UAC1B,YAAY,KAAK,SAAS;AAAA,QAAA;AAAA,MAE5B,CAAC;AACD,YAAMA,gBAAc,SAClB,KAAK,eAAe,EACpB,OAAO,IAAI,EACX,QAAQ,KAAK,MAAM;AAErB,UAAI,aAAa,UAAU,SAAS,GAAG;AACtC,kBAAW,IAAI,SAAS;AAAA,MACzB;AAAA,IACD;AAEA,UAAM,OAAO,KAAK,QAAQ,KAAK,WAAW;AAAA,EAC3C;AACD;"}
1
+ {"version":3,"file":"TriggerPayloadPersister.js","sources":["../../../../../packages/engine-actions/src/triggers/TriggerPayloadPersister.ts"],"sourcesContent":["import { Client, InsertBuilder } from '@contember/database'\nimport { Mapper, TriggeredActionEvent, TriggeredActionsCollector } from '@contember/engine-content-api'\nimport { Actions, ActionsPayload } from '@contember/schema'\nimport { EventRow } from '../model/types.js'\nimport { notify } from '../utils/notifyChannel.js'\nimport { ProjectActionsMetrics } from '../ActionsMetrics.js'\n\ntype EventRowToInsert = Omit<EventRow, 'created_at' | 'visible_at' | 'last_state_change' | 'log'> & {\n\tcreated_at: string | Date\n\tvisible_at: string | Date\n\tlast_state_change: string | Date\n}\n\nexport class TriggerPayloadPersister {\n\tconstructor(\n\t\tprivate readonly mapper: Mapper,\n\t\tprivate readonly client: Client,\n\t\tprivate readonly providers: { uuid: () => string },\n\t\tprivate readonly projectSlug: string,\n\t\tprivate readonly stageId: string,\n\t\tprivate readonly schemaId: number | undefined,\n\t\tprivate readonly identityId: string,\n\t\tprivate readonly userInfo: { ipAddress: string | null; userAgent: string | null },\n\t\tprivate readonly triggeredActionsCollector: TriggeredActionsCollector | undefined,\n\t\tprivate readonly metrics: ProjectActionsMetrics | undefined,\n\t) {\n\t}\n\n\tpublic async persist(trigger: Actions.AnyTrigger, payloads: ActionsPayload.AnyEventPayload[]): Promise<void> {\n\t\tconst chunkSize = 100\n\t\tif (!this.schemaId) {\n\t\t\tthrow new Error('Schema id is not set')\n\t\t}\n\t\tconst collector = this.triggeredActionsCollector\n\t\tfor (let i = 0; i < payloads.length; i += chunkSize) {\n\t\t\tconst chunk = payloads.slice(i, i + chunkSize)\n\t\t\tconst collected: TriggeredActionEvent[] | undefined = collector ? [] : undefined\n\t\t\tconst rows = chunk.map((it): EventRowToInsert => {\n\t\t\t\tconst id = this.providers.uuid()\n\t\t\t\tconst transactionId = this.mapper.transactionId\n\t\t\t\tcollected?.push({ id, trigger: trigger.name, target: trigger.target, transactionId })\n\t\t\t\treturn {\n\t\t\t\t\tid,\n\t\t\t\t\ttransaction_id: transactionId,\n\t\t\t\t\tcreated_at: 'now',\n\t\t\t\t\tvisible_at: 'now',\n\t\t\t\t\tnum_retries: 0,\n\t\t\t\t\tstate: 'created',\n\t\t\t\t\tstage_id: this.stageId,\n\t\t\t\t\tschema_id: this.schemaId!,\n\t\t\t\t\ttarget: trigger.target,\n\t\t\t\t\ttrigger: trigger.name,\n\t\t\t\t\tpriority: trigger.priority ?? 0,\n\t\t\t\t\tpayload: it,\n\t\t\t\t\tresolved_at: null,\n\t\t\t\t\tlast_state_change: 'now',\n\t\t\t\t\tidentity_id: this.identityId,\n\t\t\t\t\tip_address: this.userInfo.ipAddress,\n\t\t\t\t\tuser_agent: this.userInfo.userAgent,\n\t\t\t\t}\n\t\t\t})\n\t\t\tawait InsertBuilder.create()\n\t\t\t\t.into('actions_event')\n\t\t\t\t.values(rows)\n\t\t\t\t.execute(this.client)\n\n\t\t\t// Counted before commit (events are written in the mutation's transaction); a rollback\n\t\t\t// would over-count enqueued. Acceptable for a backlog *trend*, which is the intended use.\n\t\t\tthis.metrics?.enqueued(rows.length)\n\n\t\t\tif (collected && collected.length > 0) {\n\t\t\t\tcollector!.add(collected)\n\t\t\t}\n\t\t}\n\n\t\tawait notify(this.client, this.projectSlug)\n\t}\n}\n"],"names":["InsertBuilder"],"mappings":";;AAaO,MAAM,wBAAwB;AAAA,EACpC,YACkB,QACA,QACA,WACA,aACA,SACA,UACA,YACA,UACA,2BACA,SAChB;AAVgB,SAAA,SAAA;AACA,SAAA,SAAA;AACA,SAAA,YAAA;AACA,SAAA,cAAA;AACA,SAAA,UAAA;AACA,SAAA,WAAA;AACA,SAAA,aAAA;AACA,SAAA,WAAA;AACA,SAAA,4BAAA;AACA,SAAA,UAAA;AAAA,EAElB;AAAA,EAEA,MAAa,QAAQ,SAA6B,UAA2D;AAC5G,UAAM,YAAY;AAClB,QAAI,CAAC,KAAK,UAAU;AACnB,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACvC;AACA,UAAM,YAAY,KAAK;AACvB,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,WAAW;AACpD,YAAM,QAAQ,SAAS,MAAM,GAAG,IAAI,SAAS;AAC7C,YAAM,YAAgD,YAAY,CAAA,IAAK;AACvE,YAAM,OAAO,MAAM,IAAI,CAAC,OAAyB;AAChD,cAAM,KAAK,KAAK,UAAU,KAAA;AAC1B,cAAM,gBAAgB,KAAK,OAAO;AAClC,mBAAW,KAAK,EAAE,IAAI,SAAS,QAAQ,MAAM,QAAQ,QAAQ,QAAQ,cAAA,CAAe;AACpF,eAAO;AAAA,UACN;AAAA,UACA,gBAAgB;AAAA,UAChB,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ,aAAa;AAAA,UACb,OAAO;AAAA,UACP,UAAU,KAAK;AAAA,UACf,WAAW,KAAK;AAAA,UAChB,QAAQ,QAAQ;AAAA,UAChB,SAAS,QAAQ;AAAA,UACjB,UAAU,QAAQ,YAAY;AAAA,UAC9B,SAAS;AAAA,UACT,aAAa;AAAA,UACb,mBAAmB;AAAA,UACnB,aAAa,KAAK;AAAA,UAClB,YAAY,KAAK,SAAS;AAAA,UAC1B,YAAY,KAAK,SAAS;AAAA,QAAA;AAAA,MAE5B,CAAC;AACD,YAAMA,gBAAc,SAClB,KAAK,eAAe,EACpB,OAAO,IAAI,EACX,QAAQ,KAAK,MAAM;AAIrB,WAAK,SAAS,SAAS,KAAK,MAAM;AAElC,UAAI,aAAa,UAAU,SAAS,GAAG;AACtC,kBAAW,IAAI,SAAS;AAAA,MACzB;AAAA,IACD;AAEA,UAAM,OAAO,KAAK,QAAQ,KAAK,WAAW;AAAA,EAC3C;AACD;"}