feat: function update flow re-introduced (#2410)
This commit is contained in:
committed by
GitHub
parent
04dd67aa4f
commit
689bb4e941
@@ -69,7 +69,10 @@ const onSubmit = handleSubmit(async (values) => {
|
||||
})
|
||||
|
||||
const reset = () => {
|
||||
setValues(props.model)
|
||||
// Temp hack while FormSelectBase has a bug where it rewrites form value with initialValue
|
||||
nextTick(() => {
|
||||
setValues(props.model)
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
|
||||
@@ -17,11 +17,17 @@
|
||||
Edit
|
||||
</FormButton>
|
||||
</div>
|
||||
<div class="flex gap-2 shrink-0">
|
||||
<div
|
||||
v-tippy="
|
||||
hasReleases ? undefined : 'Your function needs to have at least one release'
|
||||
"
|
||||
class="flex gap-2 shrink-0"
|
||||
>
|
||||
<FormButton
|
||||
:icon-left="BoltIcon"
|
||||
class="shrink-0"
|
||||
full-width
|
||||
:disabled="!hasReleases"
|
||||
@click="$emit('createAutomation')"
|
||||
>
|
||||
Use in an Automation
|
||||
@@ -54,11 +60,16 @@ graphql(`
|
||||
owner
|
||||
name
|
||||
}
|
||||
releases(limit: 1) {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
fn: AutomateFunctionPageHeader_FunctionFragment
|
||||
isOwner: boolean
|
||||
}>()
|
||||
|
||||
const hasReleases = computed(() => props.fn.releases.totalCount > 0)
|
||||
</script>
|
||||
|
||||
@@ -76,13 +76,21 @@
|
||||
Use this function to create an automation on your project.
|
||||
</div>
|
||||
</div>
|
||||
<FormButton
|
||||
:icon-left="BoltIcon"
|
||||
<div
|
||||
v-tippy="
|
||||
hasReleases ? undefined : 'Your function needs to have at least one release'
|
||||
"
|
||||
class="shrink-0"
|
||||
@click="$emit('createAutomation')"
|
||||
>
|
||||
Use in an Automation
|
||||
</FormButton>
|
||||
<FormButton
|
||||
:icon-left="BoltIcon"
|
||||
class="shrink-0"
|
||||
:disabled="!hasReleases"
|
||||
@click="$emit('createAutomation')"
|
||||
>
|
||||
Use in an Automation
|
||||
</FormButton>
|
||||
</div>
|
||||
</div>
|
||||
<AutomateFunctionPageParametersDialog
|
||||
v-if="latestRelease"
|
||||
@@ -163,6 +171,7 @@ const publishedAt = computed(() => dayjs(latestRelease.value?.createdAt).from(da
|
||||
const description = computed(() =>
|
||||
props.fn.description?.length ? props.fn.description : 'No description provided.'
|
||||
)
|
||||
const hasReleases = computed(() => !!latestRelease.value)
|
||||
|
||||
const onViewParameters = () => {
|
||||
if (!latestRelease.value) return
|
||||
|
||||
@@ -25,7 +25,7 @@ const documents = {
|
||||
"\n fragment AutomationsFunctionsCard_AutomateFunction on AutomateFunction {\n id\n name\n isFeatured\n description\n logo\n repo {\n id\n url\n owner\n name\n }\n }\n": types.AutomationsFunctionsCard_AutomateFunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionCreateDialogDoneStep_AutomateFunction on AutomateFunction {\n id\n repo {\n id\n url\n owner\n name\n }\n ...AutomationsFunctionsCard_AutomateFunction\n }\n": types.AutomateFunctionCreateDialogDoneStep_AutomateFunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionCreateDialogTemplateStep_AutomateFunctionTemplate on AutomateFunctionTemplate {\n id\n title\n logo\n url\n }\n": types.AutomateFunctionCreateDialogTemplateStep_AutomateFunctionTemplateFragmentDoc,
|
||||
"\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n }\n": types.AutomateFunctionPageHeader_FunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n releases(limit: 1) {\n totalCount\n }\n }\n": types.AutomateFunctionPageHeader_FunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionPageInfo_AutomateFunction on AutomateFunction {\n id\n repo {\n id\n url\n owner\n name\n }\n automationCount\n description\n releases(limit: 1) {\n items {\n id\n inputSchema\n createdAt\n commitId\n ...AutomateFunctionPageParametersDialog_AutomateFunctionRelease\n }\n }\n }\n": types.AutomateFunctionPageInfo_AutomateFunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionPageParametersDialog_AutomateFunctionRelease on AutomateFunctionRelease {\n id\n inputSchema\n }\n": types.AutomateFunctionPageParametersDialog_AutomateFunctionReleaseFragmentDoc,
|
||||
"\n fragment AutomateFunctionsPageHeader_Query on Query {\n activeUser {\n id\n automateInfo {\n hasAutomateGithubApp\n availableGithubOrgs\n }\n }\n serverInfo {\n automate {\n availableFunctionTemplates {\n ...AutomateFunctionCreateDialogTemplateStep_AutomateFunctionTemplate\n }\n }\n }\n }\n": types.AutomateFunctionsPageHeader_QueryFragmentDoc,
|
||||
@@ -231,7 +231,7 @@ const documents = {
|
||||
"\n query LegacyBranchRedirectMetadata($streamId: String!, $branchName: String!) {\n stream(id: $streamId) {\n branch(name: $branchName) {\n id\n }\n }\n }\n": types.LegacyBranchRedirectMetadataDocument,
|
||||
"\n query LegacyViewerCommitRedirectMetadata($streamId: String!, $commitId: String!) {\n stream(id: $streamId) {\n commit(id: $commitId) {\n id\n branch {\n id\n }\n }\n }\n }\n": types.LegacyViewerCommitRedirectMetadataDocument,
|
||||
"\n query ResolveCommentLink($commentId: String!, $projectId: String!) {\n comment(id: $commentId, streamId: $projectId) {\n ...LinkableComment\n }\n }\n": types.ResolveCommentLinkDocument,
|
||||
"\n fragment AutomateFunctionPage_AutomateFunction on AutomateFunction {\n id\n name\n description\n logo\n supportedSourceApps\n tags\n ...AutomateFunctionPageHeader_Function\n ...AutomateFunctionPageInfo_AutomateFunction\n ...AutomateAutomationCreateDialog_AutomateFunction\n }\n": types.AutomateFunctionPage_AutomateFunctionFragmentDoc,
|
||||
"\n fragment AutomateFunctionPage_AutomateFunction on AutomateFunction {\n id\n name\n description\n logo\n supportedSourceApps\n tags\n ...AutomateFunctionPageHeader_Function\n ...AutomateFunctionPageInfo_AutomateFunction\n ...AutomateAutomationCreateDialog_AutomateFunction\n creator {\n id\n }\n }\n": types.AutomateFunctionPage_AutomateFunctionFragmentDoc,
|
||||
"\n query AutomateFunctionPage($functionId: ID!) {\n automateFunction(id: $functionId) {\n ...AutomateFunctionPage_AutomateFunction\n }\n }\n": types.AutomateFunctionPageDocument,
|
||||
"\n query AutomateFunctionsPage($search: String, $cursor: String = null) {\n ...AutomateFunctionsPageItems_Query\n ...AutomateFunctionsPageHeader_Query\n }\n": types.AutomateFunctionsPageDocument,
|
||||
"\n fragment ProjectPageProject on Project {\n id\n createdAt\n modelCount: models(limit: 0) {\n totalCount\n }\n commentThreadCount: commentThreads(limit: 0) {\n totalCount\n }\n ...ProjectPageProjectHeader\n ...ProjectPageTeamDialog\n }\n": types.ProjectPageProjectFragmentDoc,
|
||||
@@ -305,7 +305,7 @@ export function graphql(source: "\n fragment AutomateFunctionCreateDialogTempla
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n }\n"): (typeof documents)["\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n }\n"];
|
||||
export function graphql(source: "\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n releases(limit: 1) {\n totalCount\n }\n }\n"): (typeof documents)["\n fragment AutomateFunctionPageHeader_Function on AutomateFunction {\n id\n name\n logo\n repo {\n id\n url\n owner\n name\n }\n releases(limit: 1) {\n totalCount\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
@@ -1129,7 +1129,7 @@ export function graphql(source: "\n query ResolveCommentLink($commentId: String
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n fragment AutomateFunctionPage_AutomateFunction on AutomateFunction {\n id\n name\n description\n logo\n supportedSourceApps\n tags\n ...AutomateFunctionPageHeader_Function\n ...AutomateFunctionPageInfo_AutomateFunction\n ...AutomateAutomationCreateDialog_AutomateFunction\n }\n"): (typeof documents)["\n fragment AutomateFunctionPage_AutomateFunction on AutomateFunction {\n id\n name\n description\n logo\n supportedSourceApps\n tags\n ...AutomateFunctionPageHeader_Function\n ...AutomateFunctionPageInfo_AutomateFunction\n ...AutomateAutomationCreateDialog_AutomateFunction\n }\n"];
|
||||
export function graphql(source: "\n fragment AutomateFunctionPage_AutomateFunction on AutomateFunction {\n id\n name\n description\n logo\n supportedSourceApps\n tags\n ...AutomateFunctionPageHeader_Function\n ...AutomateFunctionPageInfo_AutomateFunction\n ...AutomateAutomationCreateDialog_AutomateFunction\n creator {\n id\n }\n }\n"): (typeof documents)["\n fragment AutomateFunctionPage_AutomateFunction on AutomateFunction {\n id\n name\n description\n logo\n supportedSourceApps\n tags\n ...AutomateFunctionPageHeader_Function\n ...AutomateFunctionPageInfo_AutomateFunction\n ...AutomateAutomationCreateDialog_AutomateFunction\n creator {\n id\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -46,6 +46,9 @@ graphql(`
|
||||
...AutomateFunctionPageHeader_Function
|
||||
...AutomateFunctionPageInfo_AutomateFunction
|
||||
...AutomateAutomationCreateDialog_AutomateFunction
|
||||
creator {
|
||||
id
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
@@ -60,6 +63,8 @@ const pageQuery = graphql(`
|
||||
definePageMeta({
|
||||
middleware: ['auth', 'require-valid-function']
|
||||
})
|
||||
|
||||
const { activeUser } = useActiveUser()
|
||||
const pageFetchPolicy = usePageQueryStandardFetchPolicy()
|
||||
const route = useRoute()
|
||||
const functionId = computed(() => route.params.fid as string)
|
||||
@@ -80,12 +85,12 @@ const showNewAutomationDialog = ref(false)
|
||||
|
||||
const fn = computed(() => result.value?.automateFunction)
|
||||
const isOwner = computed(
|
||||
() => false // TODO: Gergo rethinking function auth logic
|
||||
// !!(
|
||||
// activeUser.value?.id &&
|
||||
// fn.value?.creator &&
|
||||
// activeUser.value.id === fn.value.creator.id
|
||||
// )
|
||||
() =>
|
||||
!!(
|
||||
activeUser.value?.id &&
|
||||
fn.value?.creator &&
|
||||
activeUser.value.id === fn.value.creator.id
|
||||
)
|
||||
)
|
||||
|
||||
const { html: plaintextDescription } = useMarkdown(
|
||||
|
||||
@@ -144,6 +144,10 @@ type AutomateFunction {
|
||||
"""
|
||||
supportedSourceApps: [String!]!
|
||||
tags: [String!]!
|
||||
"""
|
||||
Only returned if user is a part of this speckle server
|
||||
"""
|
||||
creator: LimitedUser
|
||||
}
|
||||
|
||||
type AutomateFunctionRelease {
|
||||
|
||||
@@ -17,10 +17,7 @@ import {
|
||||
VersionCreationTriggerType,
|
||||
isVersionCreatedTriggerManifest
|
||||
} from '@/modules/automate/helpers/types'
|
||||
import type {
|
||||
AuthCodePayload,
|
||||
AuthCodePayloadWithOrigin
|
||||
} from '@/modules/automate/services/authCode'
|
||||
import type { AuthCodePayload } from '@/modules/automate/services/authCode'
|
||||
import { MisconfiguredEnvironmentError } from '@/modules/shared/errors'
|
||||
import { getServerOrigin, speckleAutomateUrl } from '@/modules/shared/helpers/envHelper'
|
||||
import {
|
||||
@@ -33,6 +30,13 @@ import {
|
||||
} from '@speckle/shared'
|
||||
import { has, isObjectLike } from 'lodash'
|
||||
|
||||
export type AuthCodePayloadWithOrigin = AuthCodePayload & { origin: string }
|
||||
|
||||
const addOrigin = (P: AuthCodePayload): AuthCodePayloadWithOrigin => {
|
||||
const origin = getServerOrigin()
|
||||
return { ...P, origin }
|
||||
}
|
||||
|
||||
const isErrorResponse = (e: unknown): e is ExecutionEngineErrorResponse =>
|
||||
isObjectLike(e) && has(e, 'statusCode') && has(e, 'statusMessage')
|
||||
|
||||
@@ -120,7 +124,14 @@ const invokeRequest = async (params: {
|
||||
url,
|
||||
body
|
||||
}
|
||||
const errorResponse = await response.json()
|
||||
|
||||
let errorResponse: unknown
|
||||
try {
|
||||
errorResponse = await response.json()
|
||||
} catch (e) {
|
||||
throw new ExecutionEngineBadResponseBodyError(errorReq)
|
||||
}
|
||||
|
||||
if (!isErrorResponse(errorResponse)) {
|
||||
throw new ExecutionEngineBadResponseBodyError(errorReq)
|
||||
}
|
||||
@@ -241,16 +252,17 @@ export enum ExecutionEngineFunctionTemplateId {
|
||||
TypeScript = 'typescript'
|
||||
}
|
||||
|
||||
export type CreateFunctionBody = {
|
||||
speckleServerAuthenticationPayload: AuthCodePayloadWithOrigin
|
||||
template: ExecutionEngineFunctionTemplateId
|
||||
functionName: string
|
||||
description: string
|
||||
supportedSourceApps: SourceAppName[]
|
||||
tags: string[]
|
||||
logo: Nullable<string>
|
||||
org: Nullable<string>
|
||||
}
|
||||
export type CreateFunctionBody<AP extends AuthCodePayload = AuthCodePayloadWithOrigin> =
|
||||
{
|
||||
speckleServerAuthenticationPayload: AP
|
||||
template: ExecutionEngineFunctionTemplateId
|
||||
functionName: string
|
||||
description: string
|
||||
supportedSourceApps: SourceAppName[]
|
||||
tags: string[]
|
||||
logo: Nullable<string>
|
||||
org: Nullable<string>
|
||||
}
|
||||
|
||||
export type CreateFunctionResponse = {
|
||||
functionId: string
|
||||
@@ -268,34 +280,55 @@ export type CreateFunctionResponse = {
|
||||
export const createFunction = async ({
|
||||
body
|
||||
}: {
|
||||
body: CreateFunctionBody
|
||||
body: CreateFunctionBody<AuthCodePayload>
|
||||
}): Promise<CreateFunctionResponse> => {
|
||||
const url = getApiUrl('/api/v2/functions/from-template')
|
||||
|
||||
const formattedBody: CreateFunctionBody = {
|
||||
...body,
|
||||
speckleServerAuthenticationPayload: addOrigin(
|
||||
body.speckleServerAuthenticationPayload
|
||||
)
|
||||
}
|
||||
return invokeJsonRequest<CreateFunctionResponse>({
|
||||
url,
|
||||
method: 'post',
|
||||
body,
|
||||
body: formattedBody,
|
||||
retry: false
|
||||
})
|
||||
}
|
||||
|
||||
export type UpdateFunctionBody = {
|
||||
//TODO add speckleServerAuthenticationPayload
|
||||
functionName?: string
|
||||
description?: string
|
||||
supportedSourceApps?: SourceAppName[]
|
||||
tags?: string[]
|
||||
logo?: string
|
||||
}
|
||||
export type UpdateFunctionBody<AP extends AuthCodePayload = AuthCodePayloadWithOrigin> =
|
||||
{
|
||||
speckleServerAuthenticationPayload: AP
|
||||
functionName?: string
|
||||
description?: string
|
||||
supportedSourceApps?: SourceAppName[]
|
||||
tags?: string[]
|
||||
logo?: string
|
||||
}
|
||||
|
||||
export type UpdateFunctionResponse = FunctionSchemaType
|
||||
|
||||
export const updateFunction = async (params: {
|
||||
functionId: string
|
||||
body: UpdateFunctionBody
|
||||
body: UpdateFunctionBody<AuthCodePayload>
|
||||
}): Promise<UpdateFunctionResponse> => {
|
||||
throw new Error('Not implemented! Needs re-thinking by Gergo & Iain')
|
||||
console.log(params)
|
||||
const { functionId, body } = params
|
||||
const url = getApiUrl(`/api/v2/functions/${functionId}`)
|
||||
|
||||
const formattedBody: UpdateFunctionBody = {
|
||||
...body,
|
||||
speckleServerAuthenticationPayload: addOrigin(
|
||||
body.speckleServerAuthenticationPayload
|
||||
)
|
||||
}
|
||||
return await invokeJsonRequest<UpdateFunctionResponse>({
|
||||
url,
|
||||
method: 'PATCH',
|
||||
body: formattedBody,
|
||||
retry: false
|
||||
})
|
||||
}
|
||||
|
||||
export type GetFunctionResponse = FunctionWithVersionsSchemaType & {
|
||||
|
||||
@@ -55,7 +55,7 @@ import { getUser } from '@/modules/core/repositories/users'
|
||||
import { createAutomation as clientCreateAutomation } from '@/modules/automate/clients/executionEngine'
|
||||
import { validateStreamAccess } from '@/modules/core/services/streams/streamAccessService'
|
||||
import { Automate, Roles, isNullOrUndefined, isNonNullable } from '@speckle/shared'
|
||||
import { getFeatureFlags } from '@/modules/shared/helpers/envHelper'
|
||||
import { getFeatureFlags, getServerOrigin } from '@/modules/shared/helpers/envHelper'
|
||||
import {
|
||||
getBranchLatestCommits,
|
||||
getBranchesByIds
|
||||
@@ -404,6 +404,16 @@ export = (FF_AUTOMATE_MODULE_ENABLED
|
||||
|
||||
throw e
|
||||
}
|
||||
},
|
||||
async creator(parent, _args, ctx) {
|
||||
if (
|
||||
!parent.functionCreator ||
|
||||
parent.functionCreator.speckleServerOrigin !== getServerOrigin()
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
return ctx.loaders.users.getUser.load(parent.functionCreator.speckleUserId)
|
||||
}
|
||||
},
|
||||
AutomateFunctionRelease: {
|
||||
@@ -434,7 +444,8 @@ export = (FF_AUTOMATE_MODULE_ENABLED
|
||||
async updateFunction(_parent, args, ctx) {
|
||||
const update = updateFunction({
|
||||
updateFunction: execEngineUpdateFunction,
|
||||
getFunction
|
||||
getFunction,
|
||||
createStoredAuthCode: createStoredAuthCode({ redis: getGenericRedis() })
|
||||
})
|
||||
return await update({ input: args.input, userId: ctx.userId! })
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@ export type FunctionSchemaType = {
|
||||
createdAt: string
|
||||
isFeatured: boolean
|
||||
logo: Nullable<string>
|
||||
functionCreator: Nullable<{
|
||||
speckleUserId: string
|
||||
speckleServerOrigin: string
|
||||
}>
|
||||
}
|
||||
|
||||
export type FunctionReleaseSchemaType = {
|
||||
|
||||
@@ -28,7 +28,12 @@ export type AutomateFunctionGraphQLReturn = Pick<
|
||||
| 'logo'
|
||||
| 'tags'
|
||||
| 'supportedSourceApps'
|
||||
>
|
||||
> & {
|
||||
functionCreator: Nullable<{
|
||||
speckleUserId: string
|
||||
speckleServerOrigin: string
|
||||
}>
|
||||
}
|
||||
|
||||
export type AutomateFunctionReleaseGraphQLReturn = Pick<
|
||||
AutomateFunctionRelease,
|
||||
|
||||
@@ -8,7 +8,8 @@ export enum AuthCodePayloadAction {
|
||||
CreateAutomation = 'createAutomation',
|
||||
CreateFunction = 'createFunction',
|
||||
BecomeFunctionAuthor = 'becomeFunctionAuthor',
|
||||
GetAvailableGithubOrganizations = 'getAvailableGithubOrganizations'
|
||||
GetAvailableGithubOrganizations = 'getAvailableGithubOrganizations',
|
||||
UpdateFunction = 'updateFunction'
|
||||
}
|
||||
|
||||
export type AuthCodePayload = {
|
||||
@@ -17,8 +18,6 @@ export type AuthCodePayload = {
|
||||
action: AuthCodePayloadAction
|
||||
}
|
||||
|
||||
export type AuthCodePayloadWithOrigin = AuthCodePayload & { origin: string }
|
||||
|
||||
const isPayload = (payload: unknown): payload is AuthCodePayload =>
|
||||
!!(
|
||||
payload &&
|
||||
|
||||
@@ -35,11 +35,17 @@ import {
|
||||
import { Request, Response } from 'express'
|
||||
import { UnauthorizedError } from '@/modules/shared/errors'
|
||||
import {
|
||||
AuthCodePayload,
|
||||
AuthCodePayloadAction,
|
||||
createStoredAuthCode
|
||||
} from '@/modules/automate/services/authCode'
|
||||
import { getServerOrigin, speckleAutomateUrl } from '@/modules/shared/helpers/envHelper'
|
||||
import {
|
||||
getServerOrigin,
|
||||
isDevEnv,
|
||||
speckleAutomateUrl
|
||||
} from '@/modules/shared/helpers/envHelper'
|
||||
import { getFunctionsMarketplaceUrl } from '@/modules/core/helpers/routeHelper'
|
||||
import { automateLogger } from '@/logging/logging'
|
||||
|
||||
const mapGqlTemplateIdToExecEngineTemplateId = (
|
||||
id: AutomateFunctionTemplateLanguage
|
||||
@@ -88,7 +94,8 @@ export const convertFunctionToGraphQLReturn = (
|
||||
description: fn.description,
|
||||
logo: cleanFunctionLogo(fn.logo),
|
||||
tags: fn.tags,
|
||||
supportedSourceApps: fn.supportedSourceApps
|
||||
supportedSourceApps: fn.supportedSourceApps,
|
||||
functionCreator: fn.functionCreator
|
||||
}
|
||||
|
||||
return ret
|
||||
@@ -131,12 +138,9 @@ export const createFunctionFromTemplate =
|
||||
userId: user.id,
|
||||
action: AuthCodePayloadAction.CreateFunction
|
||||
})
|
||||
const body: CreateFunctionBody = {
|
||||
const body: CreateFunctionBody<AuthCodePayload> = {
|
||||
...input,
|
||||
speckleServerAuthenticationPayload: {
|
||||
...authCode,
|
||||
origin: new URL(getServerOrigin()).origin
|
||||
},
|
||||
speckleServerAuthenticationPayload: authCode,
|
||||
functionName: input.name,
|
||||
template: mapGqlTemplateIdToExecEngineTemplateId(input.template),
|
||||
supportedSourceApps: input.supportedSourceApps as SourceAppName[],
|
||||
@@ -146,6 +150,10 @@ export const createFunctionFromTemplate =
|
||||
|
||||
const created = await createExecutionEngineFn({ body })
|
||||
|
||||
if (isDevEnv() && created) {
|
||||
automateLogger.info({ created }, `[dev] Created function #${created.functionId}`)
|
||||
}
|
||||
|
||||
// Don't want to pull the function w/ another req, so we'll just return the input
|
||||
const gqlReturn: AutomateFunctionGraphQLReturn = {
|
||||
id: created.functionId,
|
||||
@@ -160,7 +168,11 @@ export const createFunctionFromTemplate =
|
||||
description: body.description,
|
||||
logo: body.logo,
|
||||
tags: body.tags,
|
||||
supportedSourceApps: body.supportedSourceApps
|
||||
supportedSourceApps: body.supportedSourceApps,
|
||||
functionCreator: {
|
||||
speckleServerOrigin: getServerOrigin(),
|
||||
speckleUserId: user.id
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -172,15 +184,14 @@ export const createFunctionFromTemplate =
|
||||
export type UpdateFunctionDeps = {
|
||||
updateFunction: typeof updateExecEngineFunction
|
||||
getFunction: typeof getFunction
|
||||
createStoredAuthCode: ReturnType<typeof createStoredAuthCode>
|
||||
}
|
||||
|
||||
export const updateFunction =
|
||||
(deps: UpdateFunctionDeps) =>
|
||||
async (params: { input: UpdateAutomateFunctionInput; userId: string }) => {
|
||||
throw new AutomateFunctionUpdateError('Function update not supported yet')
|
||||
|
||||
const { updateFunction } = deps
|
||||
const { input } = params
|
||||
const { updateFunction, createStoredAuthCode } = deps
|
||||
const { input, userId } = params
|
||||
|
||||
const existingFn = await getFunction({ functionId: input.id })
|
||||
if (!existingFn) {
|
||||
@@ -200,11 +211,18 @@ export const updateFunction =
|
||||
return existingFn
|
||||
}
|
||||
|
||||
const authCode = await createStoredAuthCode({
|
||||
userId,
|
||||
action: AuthCodePayloadAction.UpdateFunction
|
||||
})
|
||||
|
||||
const apiResult = await updateFunction({
|
||||
functionId: updates.id,
|
||||
body: {
|
||||
...updates,
|
||||
supportedSourceApps: updates.supportedSourceApps as Optional<SourceAppName[]>
|
||||
functionName: updates.name,
|
||||
supportedSourceApps: updates.supportedSourceApps as Optional<SourceAppName[]>,
|
||||
speckleServerAuthenticationPayload: authCode
|
||||
}
|
||||
})
|
||||
|
||||
@@ -236,7 +254,7 @@ export const startAutomateFunctionCreatorAuth =
|
||||
)
|
||||
redirectUrl.searchParams.set(
|
||||
'speckleServerAuthenticationPayload',
|
||||
JSON.stringify({ ...authCode, origin: new URL(getServerOrigin()).origin })
|
||||
JSON.stringify({ ...authCode, origin: getServerOrigin() })
|
||||
)
|
||||
|
||||
return res.redirect(redirectUrl.toString())
|
||||
|
||||
@@ -210,6 +210,8 @@ export type AutomateAuthCodePayloadTest = {
|
||||
export type AutomateFunction = {
|
||||
__typename?: 'AutomateFunction';
|
||||
automationCount: Scalars['Int']['output'];
|
||||
/** Only returned if user is a part of this speckle server */
|
||||
creator?: Maybe<LimitedUser>;
|
||||
description: Scalars['String']['output'];
|
||||
id: Scalars['ID']['output'];
|
||||
isFeatured: Scalars['Boolean']['output'];
|
||||
@@ -4157,6 +4159,7 @@ export type AuthStrategyResolvers<ContextType = GraphQLContext, ParentType exten
|
||||
|
||||
export type AutomateFunctionResolvers<ContextType = GraphQLContext, ParentType extends ResolversParentTypes['AutomateFunction'] = ResolversParentTypes['AutomateFunction']> = {
|
||||
automationCount?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
|
||||
creator?: Resolver<Maybe<ResolversTypes['LimitedUser']>, ParentType, ContextType>;
|
||||
description?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
||||
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
|
||||
isFeatured?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
|
||||
|
||||
@@ -199,6 +199,8 @@ export type AutomateAuthCodePayloadTest = {
|
||||
export type AutomateFunction = {
|
||||
__typename?: 'AutomateFunction';
|
||||
automationCount: Scalars['Int']['output'];
|
||||
/** Only returned if user is a part of this speckle server */
|
||||
creator?: Maybe<LimitedUser>;
|
||||
description: Scalars['String']['output'];
|
||||
id: Scalars['ID']['output'];
|
||||
isFeatured: Scalars['Boolean']['output'];
|
||||
|
||||
@@ -169,7 +169,7 @@ export function getServerOrigin() {
|
||||
)
|
||||
}
|
||||
|
||||
return trimEnd(process.env.CANONICAL_URL, '/')
|
||||
return new URL(trimEnd(process.env.CANONICAL_URL, '/')).origin
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -200,6 +200,8 @@ export type AutomateAuthCodePayloadTest = {
|
||||
export type AutomateFunction = {
|
||||
__typename?: 'AutomateFunction';
|
||||
automationCount: Scalars['Int']['output'];
|
||||
/** Only returned if user is a part of this speckle server */
|
||||
creator?: Maybe<LimitedUser>;
|
||||
description: Scalars['String']['output'];
|
||||
id: Scalars['ID']['output'];
|
||||
isFeatured: Scalars['Boolean']['output'];
|
||||
|
||||
Reference in New Issue
Block a user