@contember/engine-actions 2.2.0-alpha.3 → 2.2.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +58 -0
- package/dist/development/index.cjs +19 -7
- package/dist/development/index.cjs.map +1 -1
- package/dist/development/index.js +19 -7
- package/dist/development/index.js.map +1 -1
- package/dist/development/src/ActionsExecutionContainerHookFactory.cjs +5 -2
- package/dist/development/src/ActionsExecutionContainerHookFactory.cjs.map +1 -1
- package/dist/development/src/ActionsExecutionContainerHookFactory.js +5 -2
- package/dist/development/src/ActionsExecutionContainerHookFactory.js.map +1 -1
- package/dist/development/src/ActionsMetrics.cjs +98 -0
- package/dist/development/src/ActionsMetrics.cjs.map +1 -0
- package/dist/development/src/ActionsMetrics.js +98 -0
- package/dist/development/src/ActionsMetrics.js.map +1 -0
- package/dist/development/src/dispatch/EventDispatcher.cjs +27 -9
- package/dist/development/src/dispatch/EventDispatcher.cjs.map +1 -1
- package/dist/development/src/dispatch/EventDispatcher.js +27 -9
- package/dist/development/src/dispatch/EventDispatcher.js.map +1 -1
- package/dist/development/src/dispatch/EventsRepository.cjs +49 -20
- package/dist/development/src/dispatch/EventsRepository.cjs.map +1 -1
- package/dist/development/src/dispatch/EventsRepository.js +49 -20
- package/dist/development/src/dispatch/EventsRepository.js.map +1 -1
- package/dist/development/src/dispatch/ProjectDispatcher.cjs +21 -13
- package/dist/development/src/dispatch/ProjectDispatcher.cjs.map +1 -1
- package/dist/development/src/dispatch/ProjectDispatcher.js +21 -13
- package/dist/development/src/dispatch/ProjectDispatcher.js.map +1 -1
- package/dist/development/src/dispatch/WebhookTargetHandler.cjs +29 -2
- package/dist/development/src/dispatch/WebhookTargetHandler.cjs.map +1 -1
- package/dist/development/src/dispatch/WebhookTargetHandler.js +29 -2
- package/dist/development/src/dispatch/WebhookTargetHandler.js.map +1 -1
- package/dist/development/src/graphql/resolvers/ResolversFactory.cjs +1 -1
- package/dist/development/src/graphql/resolvers/ResolversFactory.cjs.map +1 -1
- package/dist/development/src/graphql/resolvers/ResolversFactory.js +1 -1
- package/dist/development/src/graphql/resolvers/ResolversFactory.js.map +1 -1
- package/dist/development/src/graphql/resolvers/mutation/SetVariablesMutationResolver.cjs +1 -1
- package/dist/development/src/graphql/resolvers/mutation/SetVariablesMutationResolver.cjs.map +1 -1
- package/dist/development/src/graphql/resolvers/mutation/SetVariablesMutationResolver.js +1 -1
- package/dist/development/src/graphql/resolvers/mutation/SetVariablesMutationResolver.js.map +1 -1
- package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.cjs +1 -1
- package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.cjs.map +1 -1
- package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.js +1 -1
- package/dist/development/src/graphql/resolvers/query/EventsQueryResolver.js.map +1 -1
- package/dist/development/src/graphql/resolvers/query/VariablesQueryResolver.cjs +1 -4
- package/dist/development/src/graphql/resolvers/query/VariablesQueryResolver.cjs.map +1 -1
- package/dist/development/src/graphql/resolvers/query/VariablesQueryResolver.js +1 -4
- package/dist/development/src/graphql/resolvers/query/VariablesQueryResolver.js.map +1 -1
- package/dist/development/src/graphql/schema/actions.graphql.cjs +20 -8
- package/dist/development/src/graphql/schema/actions.graphql.cjs.map +1 -1
- package/dist/development/src/graphql/schema/actions.graphql.js +20 -8
- package/dist/development/src/graphql/schema/actions.graphql.js.map +1 -1
- package/dist/development/src/model/VariablesManager.cjs +54 -5
- package/dist/development/src/model/VariablesManager.cjs.map +1 -1
- package/dist/development/src/model/VariablesManager.js +54 -5
- package/dist/development/src/model/VariablesManager.js.map +1 -1
- package/dist/development/src/triggers/TriggerPayloadPersister.cjs +3 -1
- package/dist/development/src/triggers/TriggerPayloadPersister.cjs.map +1 -1
- package/dist/development/src/triggers/TriggerPayloadPersister.js +3 -1
- package/dist/development/src/triggers/TriggerPayloadPersister.js.map +1 -1
- package/dist/production/index.cjs +19 -7
- package/dist/production/index.cjs.map +1 -1
- package/dist/production/index.js +19 -7
- package/dist/production/index.js.map +1 -1
- package/dist/production/src/ActionsExecutionContainerHookFactory.cjs +5 -2
- package/dist/production/src/ActionsExecutionContainerHookFactory.cjs.map +1 -1
- package/dist/production/src/ActionsExecutionContainerHookFactory.js +5 -2
- package/dist/production/src/ActionsExecutionContainerHookFactory.js.map +1 -1
- package/dist/production/src/ActionsMetrics.cjs +98 -0
- package/dist/production/src/ActionsMetrics.cjs.map +1 -0
- package/dist/production/src/ActionsMetrics.js +98 -0
- package/dist/production/src/ActionsMetrics.js.map +1 -0
- package/dist/production/src/dispatch/EventDispatcher.cjs +27 -9
- package/dist/production/src/dispatch/EventDispatcher.cjs.map +1 -1
- package/dist/production/src/dispatch/EventDispatcher.js +27 -9
- package/dist/production/src/dispatch/EventDispatcher.js.map +1 -1
- package/dist/production/src/dispatch/EventsRepository.cjs +49 -20
- package/dist/production/src/dispatch/EventsRepository.cjs.map +1 -1
- package/dist/production/src/dispatch/EventsRepository.js +49 -20
- package/dist/production/src/dispatch/EventsRepository.js.map +1 -1
- package/dist/production/src/dispatch/ProjectDispatcher.cjs +21 -13
- package/dist/production/src/dispatch/ProjectDispatcher.cjs.map +1 -1
- package/dist/production/src/dispatch/ProjectDispatcher.js +21 -13
- package/dist/production/src/dispatch/ProjectDispatcher.js.map +1 -1
- package/dist/production/src/dispatch/WebhookTargetHandler.cjs +29 -2
- package/dist/production/src/dispatch/WebhookTargetHandler.cjs.map +1 -1
- package/dist/production/src/dispatch/WebhookTargetHandler.js +29 -2
- package/dist/production/src/dispatch/WebhookTargetHandler.js.map +1 -1
- package/dist/production/src/graphql/resolvers/ResolversFactory.cjs +1 -1
- package/dist/production/src/graphql/resolvers/ResolversFactory.cjs.map +1 -1
- package/dist/production/src/graphql/resolvers/ResolversFactory.js +1 -1
- package/dist/production/src/graphql/resolvers/ResolversFactory.js.map +1 -1
- package/dist/production/src/graphql/resolvers/mutation/SetVariablesMutationResolver.cjs +1 -1
- package/dist/production/src/graphql/resolvers/mutation/SetVariablesMutationResolver.cjs.map +1 -1
- package/dist/production/src/graphql/resolvers/mutation/SetVariablesMutationResolver.js +1 -1
- package/dist/production/src/graphql/resolvers/mutation/SetVariablesMutationResolver.js.map +1 -1
- package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.cjs +1 -1
- package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.cjs.map +1 -1
- package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.js +1 -1
- package/dist/production/src/graphql/resolvers/query/EventsQueryResolver.js.map +1 -1
- package/dist/production/src/graphql/resolvers/query/VariablesQueryResolver.cjs +1 -4
- package/dist/production/src/graphql/resolvers/query/VariablesQueryResolver.cjs.map +1 -1
- package/dist/production/src/graphql/resolvers/query/VariablesQueryResolver.js +1 -4
- package/dist/production/src/graphql/resolvers/query/VariablesQueryResolver.js.map +1 -1
- package/dist/production/src/graphql/schema/actions.graphql.cjs +20 -8
- package/dist/production/src/graphql/schema/actions.graphql.cjs.map +1 -1
- package/dist/production/src/graphql/schema/actions.graphql.js +20 -8
- package/dist/production/src/graphql/schema/actions.graphql.js.map +1 -1
- package/dist/production/src/model/VariablesManager.cjs +54 -5
- package/dist/production/src/model/VariablesManager.cjs.map +1 -1
- package/dist/production/src/model/VariablesManager.js +54 -5
- package/dist/production/src/model/VariablesManager.js.map +1 -1
- package/dist/production/src/triggers/TriggerPayloadPersister.cjs +3 -1
- package/dist/production/src/triggers/TriggerPayloadPersister.cjs.map +1 -1
- package/dist/production/src/triggers/TriggerPayloadPersister.js +3 -1
- package/dist/production/src/triggers/TriggerPayloadPersister.js.map +1 -1
- package/dist/tests/cases/unit/actionsMetrics.test.d.ts +2 -0
- package/dist/tests/cases/unit/actionsMetrics.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/eventsRepository.test.d.ts +2 -0
- package/dist/tests/cases/unit/eventsRepository.test.d.ts.map +1 -0
- package/dist/tests/cases/unit/variablesManager.test.d.ts +2 -0
- package/dist/tests/cases/unit/variablesManager.test.d.ts.map +1 -0
- package/dist/tests/src/event.d.ts +4 -0
- package/dist/tests/src/event.d.ts.map +1 -0
- package/dist/tests/src/gql.d.ts.map +1 -1
- package/dist/tests/src/uuid.d.ts.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/dist/types/ActionsExecutionContainerHookFactory.d.ts +3 -1
- package/dist/types/ActionsExecutionContainerHookFactory.d.ts.map +1 -1
- package/dist/types/ActionsMetrics.d.ts +59 -0
- package/dist/types/ActionsMetrics.d.ts.map +1 -0
- package/dist/types/ListenerStoreProvider.d.ts.map +1 -1
- package/dist/types/authorization/ActionsPermissionsFactory.d.ts.map +1 -1
- package/dist/types/dispatch/DispatchWorkerSupervisor.d.ts.map +1 -1
- package/dist/types/dispatch/EventDispatcher.d.ts +12 -3
- package/dist/types/dispatch/EventDispatcher.d.ts.map +1 -1
- package/dist/types/dispatch/EventsRepository.d.ts +14 -2
- package/dist/types/dispatch/EventsRepository.d.ts.map +1 -1
- package/dist/types/dispatch/LazyDispatchWorker.d.ts.map +1 -1
- package/dist/types/dispatch/ProjectDispatcher.d.ts +5 -2
- package/dist/types/dispatch/ProjectDispatcher.d.ts.map +1 -1
- package/dist/types/dispatch/TargetHandlerResolver.d.ts.map +1 -1
- package/dist/types/dispatch/WebhookFetcher.d.ts.map +1 -1
- package/dist/types/dispatch/WebhookTargetHandler.d.ts.map +1 -1
- package/dist/types/graphql/http/ActionsApiMiddlewareFactory.d.ts.map +1 -1
- package/dist/types/graphql/http/ActionsContextResolver.d.ts.map +1 -1
- package/dist/types/graphql/http/ActionsGraphQLHandlerFactory.d.ts.map +1 -1
- package/dist/types/graphql/http/ActionsWebsocketControllerFactory.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/ResolversFactory.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/mutation/ProcessBatchMutationResolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/mutation/RetryEventMutationResolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/mutation/SetVariablesMutationResolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/mutation/StopEventMutationResolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/query/EventsQueryResolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/query/VariablesQueryResolver.d.ts +1 -4
- package/dist/types/graphql/resolvers/query/VariablesQueryResolver.d.ts.map +1 -1
- package/dist/types/graphql/schema/actions.graphql.d.ts.map +1 -1
- package/dist/types/graphql/schema/index.d.ts +27 -17
- package/dist/types/graphql/schema/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/model/EventByIdQuery.d.ts.map +1 -1
- package/dist/types/model/EventsInProcessingQuery.d.ts.map +1 -1
- package/dist/types/model/EventsToProcessQuery.d.ts.map +1 -1
- package/dist/types/model/FailedEventsQuery.d.ts.map +1 -1
- package/dist/types/model/SetVariableCommand.d.ts.map +1 -1
- package/dist/types/model/VariablesManager.d.ts +16 -3
- package/dist/types/model/VariablesManager.d.ts.map +1 -1
- package/dist/types/model/VariablesQuery.d.ts.map +1 -1
- package/dist/types/triggers/TriggerHandler.d.ts.map +1 -1
- package/dist/types/triggers/TriggerIndirectChangesFetcher.d.ts.map +1 -1
- package/dist/types/triggers/TriggerListenersBuilder.d.ts.map +1 -1
- package/dist/types/triggers/TriggerListenersFactory.d.ts.map +1 -1
- package/dist/types/triggers/TriggerListenersStore.d.ts.map +1 -1
- package/dist/types/triggers/TriggerPayloadBuilder.d.ts.map +1 -1
- package/dist/types/triggers/TriggerPayloadManager.d.ts.map +1 -1
- package/dist/types/triggers/TriggerPayloadPersister.d.ts +3 -1
- package/dist/types/triggers/TriggerPayloadPersister.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dist/types/utils/map.d.ts.map +1 -1
- package/dist/types/utils/notifyChannel.d.ts.map +1 -1
- package/graphql.codegen.yml +1 -1
- package/package.json +18 -16
- package/src/ActionsExecutionContainerHookFactory.ts +6 -0
- package/src/ActionsMetrics.ts +135 -0
- package/src/dispatch/EventDispatcher.ts +36 -11
- package/src/dispatch/EventsRepository.ts +68 -26
- package/src/dispatch/ProjectDispatcher.ts +27 -11
- package/src/dispatch/WebhookTargetHandler.ts +36 -1
- package/src/graphql/resolvers/ResolversFactory.ts +1 -1
- package/src/graphql/resolvers/mutation/SetVariablesMutationResolver.ts +1 -1
- package/src/graphql/resolvers/query/EventsQueryResolver.ts +1 -1
- package/src/graphql/resolvers/query/VariablesQueryResolver.ts +1 -4
- package/src/graphql/schema/actions.graphql.ts +20 -8
- package/src/graphql/schema/index.ts +30 -17
- package/src/index.ts +27 -5
- package/src/model/VariablesManager.ts +66 -6
- package/src/triggers/TriggerPayloadPersister.ts +6 -0
- package/tests/cases/unit/actionsMetrics.test.ts +76 -0
- package/tests/cases/unit/eventsRepository.test.ts +136 -0
- package/tests/cases/unit/variablesManager.test.ts +154 -0
- package/tests/cases/unit/webhookHandler.test.ts +80 -24
- 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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
18
|
+
event(id: UUID!): Event
|
|
19
19
|
variables: [Variable!]!
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
type Mutation {
|
|
23
23
|
processBatch: ProcessBatchResponse!
|
|
24
|
-
retryEvent(id:
|
|
25
|
-
stopEvent(id:
|
|
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:
|
|
37
|
-
transactionId:
|
|
38
|
-
identityId:
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
16
|
+
event(id: UUID!): Event
|
|
17
17
|
variables: [Variable!]!
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
type Mutation {
|
|
21
21
|
processBatch: ProcessBatchResponse!
|
|
22
|
-
retryEvent(id:
|
|
23
|
-
stopEvent(id:
|
|
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:
|
|
35
|
-
transactionId:
|
|
36
|
-
identityId:
|
|
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
|
|
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
|
|
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
|
-
|
|
8
|
-
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
|
|
6
|
-
|
|
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.
|
|
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
|
|
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
|
|
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":";;;;;;;;AAWA,MAAM,iBAAiB;AAEhB,MAAM,iBAAiB;AAAA,EAI7B,YACkB,KAChB;AADgB,SAAA,MAAA;AAHlB,kBAAA,MAAiB,yCAAwB,IAAA,CAA0B;AAAA,EAKnE;AAAA;AAAA,EAGA,MAAa,eAAe,IAAqB,aAA4C;AAC5F,WAAO,EAAE,GAAG,MAAM,KAAK,qBAAqB,EAAE,GAAG,GAAG,KAAK,kBAAkB,WAAW,EAAA;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,cAAc,IAAqB,aAA0C;AACzF,UAAM,eAAe,KAAK,kBAAkB,WAAW;AACvD,UAAM,SAAS,MAAM,KAAK,qBAAqB,EAAE;AACjD,WAAO;AAAA,MACN,GAAG,OAAO,QAAQ,MAAM,EACtB,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,OAAO,cAAc,IAAI,CAAC,EACrD,IAAI,CAAC,CAAC,MAAM,KAAK,OAAiB,EAAE,MAAM,OAAO,QAAQ,WAAA,EAAa;AAAA,MACxE,GAAG,OAAO,KAAK,YAAY,EAAE,IAAI,CAAC,UAAoB,EAAE,MAAM,OAAO,MAAM,QAAQ,gBAAgB;AAAA,IAAA,EAClG,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAAA,EAC9C;AAAA,EAEA,MAAa,aAAa,IAAqB,MAAwB,aAAqB;AAC3F,UAAM,eAAe,KAAK,kBAAkB,WAAW;AACvD,UAAM,WAAW,KAAK,UAAU,IAAI,QAAM,GAAG,IAAI,EAAE,OAAO,CAAA,OAAM,OAAO,OAAO,cAAc,EAAE,CAAC;AAC/F,QAAI,SAAS,SAAS,GAAG;AACxB,YAAM,IAAI,eAAe,wDAAwD,SAAS,KAAK,IAAI,CAAC,EAAE;AAAA,IACvG;AAEA,WAAO,MAAM,GAAG,YAAY,OAAMA,QAAM;AACvC,YAAM,UAAU,MAAM,KAAK,qBAAqBA,GAAE;AAClD,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,CAAC,OAAO,OAAO,cAAc,EAAE,CAAC;AACnF,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;AAAA,EAEA,MAAc,qBAAqB,IAA4C;AAC9E,WAAO,OAAO,aAAa,MAAM,GAAG,aAAa,MAAM,IAAI,eAAA,CAAgB,GAAG,IAAI,QAAM,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC;AAAA,EAC7G;AAAA,EAEQ,kBAAkB,aAAmC;AAC5D,UAAM,SAAS,KAAK,kBAAkB,IAAI,WAAW;AACrD,QAAI,WAAW,QAAW;AACzB,aAAO;AAAA,IACR;AAEA,UAAM,WAAW,CAAC,UAAU,cAAc,IAAI,qBAAqB,WAAW,IAAI,cAAc;AAChG,UAAM,SAAuB,CAAA;AAC7B,eAAW,UAAU,UAAU;AAC9B,iBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG,GAAG;AAErD,YAAI,CAAC,KAAK,WAAW,MAAM,KAAK,KAAK,WAAW,OAAO,UAAU,UAAU,IAAI;AAC9E;AAAA,QACD;AACA,eAAO,KAAK,MAAM,OAAO,MAAM,CAAC,IAAI;AAAA,MACrC;AAAA,IACD;AACA,SAAK,kBAAkB,IAAI,aAAa,MAAM;AAC9C,WAAO;AAAA,EACR;AACD;"}
|
|
@@ -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":";;;;
|
|
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":";;
|
|
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;"}
|