chore(server): automate IoC 3 - validateAndUpdateAutomationFactory
This commit is contained in:
@@ -7,6 +7,8 @@ import { InsertableAutomationRevision } from '@/modules/automate/repositories/au
|
||||
import { AuthCodePayload } from '@/modules/automate/services/authCode'
|
||||
import { ProjectAutomationCreateInput } from '@/modules/core/graph/generated/graphql'
|
||||
import { ContextResourceAccessRules } from '@/modules/core/helpers/token'
|
||||
import { Nullable } from '@speckle/shared'
|
||||
import { SetRequired } from 'type-fest'
|
||||
|
||||
export type StoreAutomation = (
|
||||
automation: AutomationRecord
|
||||
@@ -20,6 +22,20 @@ export type StoreAutomationRevision = (
|
||||
revision: InsertableAutomationRevision
|
||||
) => Promise<AutomationRevisionWithTriggersFunctions>
|
||||
|
||||
export type GetAutomations = (params: {
|
||||
automationIds: string[]
|
||||
projectId?: string
|
||||
}) => Promise<AutomationRecord[]>
|
||||
|
||||
export type GetAutomation = (params: {
|
||||
automationId: string
|
||||
projectId?: string
|
||||
}) => Promise<Nullable<AutomationRecord>>
|
||||
|
||||
export type UpdateAutomation = (
|
||||
automation: SetRequired<Partial<AutomationRecord>, 'id'>
|
||||
) => Promise<AutomationRecord>
|
||||
|
||||
export type CreateStoredAuthCode = (
|
||||
params: Omit<AuthCodePayload, 'code'>
|
||||
) => Promise<AuthCodePayload>
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from '@/modules/automate/clients/executionEngine'
|
||||
import {
|
||||
GetProjectAutomationsParams,
|
||||
getAutomation,
|
||||
getAutomationFactory,
|
||||
getAutomationRunsItems,
|
||||
getAutomationRunsTotalCount,
|
||||
getAutomationTriggerDefinitions,
|
||||
@@ -24,8 +24,8 @@ import {
|
||||
storeAutomationFactory,
|
||||
storeAutomationRevisionFactory,
|
||||
storeAutomationTokenFactory,
|
||||
updateAutomationFactory,
|
||||
updateAutomationRun,
|
||||
updateAutomation as updateDbAutomation,
|
||||
upsertAutomationFunctionRun
|
||||
} from '@/modules/automate/repositories/automations'
|
||||
import {
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
createAutomationRevision,
|
||||
createTestAutomationFactory,
|
||||
getAutomationsStatus,
|
||||
updateAutomation
|
||||
validateAndUpdateAutomationFactory
|
||||
} from '@/modules/automate/services/automationManagement'
|
||||
import {
|
||||
AuthCodePayloadAction,
|
||||
@@ -111,6 +111,8 @@ const { FF_AUTOMATE_MODULE_ENABLED } = getFeatureFlags()
|
||||
const storeAutomation = storeAutomationFactory({ db })
|
||||
const storeAutomationToken = storeAutomationTokenFactory({ db })
|
||||
const storeAutomationRevision = storeAutomationRevisionFactory({ db })
|
||||
const getAutomation = getAutomationFactory({ db })
|
||||
const updateDbAutomation = updateAutomationFactory({ db })
|
||||
|
||||
export = (FF_AUTOMATE_MODULE_ENABLED
|
||||
? {
|
||||
@@ -481,7 +483,7 @@ export = (FF_AUTOMATE_MODULE_ENABLED
|
||||
).automation
|
||||
},
|
||||
async update(parent, { input }, ctx) {
|
||||
const update = updateAutomation({
|
||||
const update = validateAndUpdateAutomationFactory({
|
||||
getAutomation,
|
||||
updateAutomation: updateDbAutomation
|
||||
})
|
||||
|
||||
@@ -9,9 +9,9 @@ import {
|
||||
getActiveTriggerDefinitions,
|
||||
getAutomationRunFullTriggers,
|
||||
getFullAutomationRevisionMetadata,
|
||||
getAutomation,
|
||||
getAutomationRevision,
|
||||
getFullAutomationRunById
|
||||
getFullAutomationRunById,
|
||||
getAutomationFactory
|
||||
} from '@/modules/automate/repositories/automations'
|
||||
import { Scopes } from '@speckle/shared'
|
||||
import { registerOrUpdateScopeFactory } from '@/modules/shared/repositories/scopes'
|
||||
@@ -80,6 +80,7 @@ const initializeEventListeners = () => {
|
||||
getCommit,
|
||||
getFullAutomationRunById
|
||||
})
|
||||
const getAutomation = getAutomationFactory({ db })
|
||||
|
||||
const quitters = [
|
||||
VersionsEmitter.listen(
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import {
|
||||
GetAutomation,
|
||||
GetAutomations,
|
||||
StoreAutomation,
|
||||
StoreAutomationRevision,
|
||||
StoreAutomationToken
|
||||
StoreAutomationToken,
|
||||
UpdateAutomation
|
||||
} from '@/modules/automate/domain/operations'
|
||||
import {
|
||||
AutomationRecord,
|
||||
@@ -409,47 +412,49 @@ export async function getAutomationToken(
|
||||
return token || null
|
||||
}
|
||||
|
||||
export async function getAutomations(params: {
|
||||
automationIds: string[]
|
||||
projectId?: string
|
||||
}) {
|
||||
const { automationIds, projectId } = params
|
||||
if (!automationIds.length) return []
|
||||
export const getAutomationsFactory =
|
||||
(deps: { db: Knex }): GetAutomations =>
|
||||
async (params: { automationIds: string[]; projectId?: string }) => {
|
||||
const { automationIds, projectId } = params
|
||||
if (!automationIds.length) return []
|
||||
|
||||
const q = Automations.knex<AutomationRecord[]>()
|
||||
.select()
|
||||
.whereIn(Automations.col.id, automationIds)
|
||||
const q = tables
|
||||
.automations(deps.db)
|
||||
.select()
|
||||
.whereIn(Automations.col.id, automationIds)
|
||||
|
||||
if (projectId?.length) {
|
||||
q.andWhere(Automations.col.projectId, projectId)
|
||||
if (projectId?.length) {
|
||||
q.andWhere(Automations.col.projectId, projectId)
|
||||
}
|
||||
|
||||
return await q
|
||||
}
|
||||
|
||||
return await q
|
||||
}
|
||||
export const getAutomationFactory =
|
||||
(deps: { db: Knex }): GetAutomation =>
|
||||
async (params: { automationId: string; projectId?: string }) => {
|
||||
const { automationId, projectId } = params
|
||||
return (
|
||||
(
|
||||
await getAutomationsFactory(deps)({ automationIds: [automationId], projectId })
|
||||
)?.[0] || null
|
||||
)
|
||||
}
|
||||
|
||||
export async function getAutomation(params: {
|
||||
automationId: string
|
||||
projectId?: string
|
||||
}): Promise<Nullable<AutomationRecord>> {
|
||||
const { automationId, projectId } = params
|
||||
return (
|
||||
(await getAutomations({ automationIds: [automationId], projectId }))?.[0] || null
|
||||
)
|
||||
}
|
||||
export const updateAutomationFactory =
|
||||
(deps: { db: Knex }): UpdateAutomation =>
|
||||
async (automation: SetRequired<Partial<AutomationRecord>, 'id'>) => {
|
||||
const [ret] = await tables
|
||||
.automations(deps.db)
|
||||
.where(Automations.col.id, automation.id)
|
||||
.update({
|
||||
...pick(automation, Automations.withoutTablePrefix.cols),
|
||||
[Automations.withoutTablePrefix.col.updatedAt]: new Date()
|
||||
})
|
||||
.returning('*')
|
||||
|
||||
export async function updateAutomation(
|
||||
automation: SetRequired<Partial<AutomationRecord>, 'id'>
|
||||
) {
|
||||
const [ret] = await Automations.knex()
|
||||
.where(Automations.col.id, automation.id)
|
||||
.update({
|
||||
...pick(automation, Automations.withoutTablePrefix.cols),
|
||||
[Automations.withoutTablePrefix.col.updatedAt]: new Date()
|
||||
})
|
||||
.returning<AutomationRecord[]>('*')
|
||||
|
||||
return ret
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
export async function getAutomationTriggerDefinitions<
|
||||
T extends AutomationTriggerType = AutomationTriggerType
|
||||
|
||||
@@ -2,9 +2,7 @@ import {
|
||||
InsertableAutomationRevision,
|
||||
InsertableAutomationRevisionFunction,
|
||||
InsertableAutomationRevisionTrigger,
|
||||
getAutomation,
|
||||
getLatestVersionAutomationRuns,
|
||||
updateAutomation as updateDbAutomation
|
||||
getLatestVersionAutomationRuns
|
||||
} from '@/modules/automate/repositories/automations'
|
||||
import { getServerOrigin } from '@/modules/shared/helpers/envHelper'
|
||||
import cryptoRandomString from 'crypto-random-string'
|
||||
@@ -51,10 +49,12 @@ import { validateAutomationName } from '@/modules/automate/utils/automationConfi
|
||||
import {
|
||||
CreateAutomation,
|
||||
CreateStoredAuthCode,
|
||||
GetAutomation,
|
||||
GetEncryptionKeyPair,
|
||||
StoreAutomation,
|
||||
StoreAutomationRevision,
|
||||
StoreAutomationToken
|
||||
StoreAutomationToken,
|
||||
UpdateAutomation
|
||||
} from '@/modules/automate/domain/operations'
|
||||
|
||||
export type CreateAutomationDeps = {
|
||||
@@ -243,13 +243,13 @@ export const createTestAutomationFactory =
|
||||
return automationRecord
|
||||
}
|
||||
|
||||
export type UpdateAutomationDeps = {
|
||||
getAutomation: typeof getAutomation
|
||||
updateAutomation: typeof updateDbAutomation
|
||||
export type ValidateAndUpdateAutomationDeps = {
|
||||
getAutomation: GetAutomation
|
||||
updateAutomation: UpdateAutomation
|
||||
}
|
||||
|
||||
export const updateAutomation =
|
||||
(deps: UpdateAutomationDeps) =>
|
||||
export const validateAndUpdateAutomationFactory =
|
||||
(deps: ValidateAndUpdateAutomationDeps) =>
|
||||
async (params: {
|
||||
input: ProjectAutomationUpdateInput
|
||||
userId: string
|
||||
@@ -383,7 +383,7 @@ const validateNewRevisionFunctions =
|
||||
}
|
||||
|
||||
export type CreateAutomationRevisionDeps = {
|
||||
getAutomation: typeof getAutomation
|
||||
getAutomation: GetAutomation
|
||||
storeAutomationRevision: StoreAutomationRevision
|
||||
getEncryptionKeyPair: GetEncryptionKeyPair
|
||||
getFunctionInputDecryptor: ReturnType<typeof getFunctionInputDecryptor>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
InsertableAutomationRun,
|
||||
getActiveTriggerDefinitions,
|
||||
getAutomation,
|
||||
getFullAutomationRevisionMetadata,
|
||||
getAutomationToken,
|
||||
getAutomationTriggerDefinitions,
|
||||
@@ -43,10 +42,13 @@ import { automateLogger } from '@/logging/logging'
|
||||
import { getFunctionInputDecryptor } from '@/modules/automate/services/encryption'
|
||||
import { LibsodiumEncryptionError } from '@/modules/shared/errors/encryption'
|
||||
import { AutomateRunsEmitter } from '@/modules/automate/events/runs'
|
||||
import { GetEncryptionKeyPairFor } from '@/modules/automate/domain/operations'
|
||||
import {
|
||||
GetAutomation,
|
||||
GetEncryptionKeyPairFor
|
||||
} from '@/modules/automate/domain/operations'
|
||||
|
||||
export type OnModelVersionCreateDeps = {
|
||||
getAutomation: typeof getAutomation
|
||||
getAutomation: GetAutomation
|
||||
getAutomationRevision: typeof getAutomationRevision
|
||||
getTriggers: typeof getActiveTriggerDefinitions
|
||||
triggerFunction: ReturnType<typeof triggerAutomationRevisionRun>
|
||||
@@ -440,7 +442,7 @@ async function composeTriggerData(params: {
|
||||
|
||||
export type ManuallyTriggerAutomationDeps = {
|
||||
getAutomationTriggerDefinitions: typeof getAutomationTriggerDefinitions
|
||||
getAutomation: typeof getAutomation
|
||||
getAutomation: GetAutomation
|
||||
getBranchLatestCommits: typeof getBranchLatestCommits
|
||||
triggerFunction: ReturnType<typeof triggerAutomationRevisionRun>
|
||||
}
|
||||
@@ -512,7 +514,7 @@ export const manuallyTriggerAutomation =
|
||||
}
|
||||
|
||||
export type CreateTestAutomationRunDeps = {
|
||||
getAutomation: typeof getAutomation
|
||||
getAutomation: GetAutomation
|
||||
getLatestAutomationRevision: typeof getLatestAutomationRevision
|
||||
getFullAutomationRevisionMetadata: typeof getFullAutomationRevisionMetadata
|
||||
} & CreateAutomationRunDataDeps
|
||||
|
||||
@@ -3,10 +3,10 @@ import {
|
||||
AutomationUpdateError
|
||||
} from '@/modules/automate/errors/management'
|
||||
import {
|
||||
getAutomation,
|
||||
updateAutomation as updateDbAutomation
|
||||
getAutomationFactory,
|
||||
updateAutomationFactory
|
||||
} from '@/modules/automate/repositories/automations'
|
||||
import { updateAutomation } from '@/modules/automate/services/automationManagement'
|
||||
import { validateAndUpdateAutomationFactory } from '@/modules/automate/services/automationManagement'
|
||||
import {
|
||||
AuthCodePayloadAction,
|
||||
createStoredAuthCodeFactory
|
||||
@@ -42,6 +42,7 @@ import { Automate, Roles } from '@speckle/shared'
|
||||
import { expect } from 'chai'
|
||||
import { times } from 'lodash'
|
||||
import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
|
||||
import { db } from '@/db/knex'
|
||||
|
||||
/**
|
||||
* TODO: Extra test ideas
|
||||
@@ -52,7 +53,9 @@ import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
|
||||
const { FF_AUTOMATE_MODULE_ENABLED } = getFeatureFlags()
|
||||
|
||||
const buildAutomationUpdate = () => {
|
||||
const update = updateAutomation({
|
||||
const getAutomation = getAutomationFactory({ db })
|
||||
const updateDbAutomation = updateAutomationFactory({ db })
|
||||
const update = validateAndUpdateAutomationFactory({
|
||||
getAutomation,
|
||||
updateAutomation: updateDbAutomation
|
||||
})
|
||||
|
||||
@@ -33,18 +33,18 @@ import {
|
||||
import { createTestCommit } from '@/test/speckle-helpers/commitHelper'
|
||||
import {
|
||||
InsertableAutomationRun,
|
||||
getAutomation,
|
||||
getFullAutomationRunById,
|
||||
getAutomationTriggerDefinitions,
|
||||
getFunctionRun,
|
||||
updateAutomation,
|
||||
updateAutomationRevision,
|
||||
updateAutomationRun,
|
||||
upsertAutomationRun,
|
||||
upsertAutomationFunctionRun,
|
||||
storeAutomationFactory,
|
||||
storeAutomationTokenFactory,
|
||||
storeAutomationRevisionFactory
|
||||
storeAutomationRevisionFactory,
|
||||
getAutomationFactory,
|
||||
updateAutomationFactory
|
||||
} from '@/modules/automate/repositories/automations'
|
||||
import { beforeEachContext, truncateTables } from '@/test/hooks'
|
||||
import { Automate } from '@speckle/shared'
|
||||
@@ -78,6 +78,8 @@ const { FF_AUTOMATE_MODULE_ENABLED } = getFeatureFlags()
|
||||
const storeAutomation = storeAutomationFactory({ db })
|
||||
const storeAutomationToken = storeAutomationTokenFactory({ db })
|
||||
const storeAutomationRevision = storeAutomationRevisionFactory({ db })
|
||||
const getAutomation = getAutomationFactory({ db })
|
||||
const updateAutomation = updateAutomationFactory({ db })
|
||||
|
||||
;(FF_AUTOMATE_MODULE_ENABLED ? describe : describe.skip)(
|
||||
'Automate triggers @automate',
|
||||
|
||||
@@ -63,7 +63,7 @@ import {
|
||||
import {
|
||||
getAutomationRevisions,
|
||||
getAutomationRunsTriggers,
|
||||
getAutomations,
|
||||
getAutomationsFactory,
|
||||
getFunctionAutomationCounts,
|
||||
getLatestAutomationRevisions,
|
||||
getRevisionsFunctions,
|
||||
@@ -90,6 +90,7 @@ const simpleTupleCacheKey = (key: [string, string]) => `${key[0]}:${key[1]}`
|
||||
|
||||
const getStreamPendingModels = getStreamPendingModelsFactory({ db })
|
||||
const getAppScopes = getAppScopesFactory({ db })
|
||||
const getAutomations = getAutomationsFactory({ db })
|
||||
|
||||
/**
|
||||
* TODO: Lazy load DataLoaders to reduce memory usage
|
||||
|
||||
Reference in New Issue
Block a user