Files
speckle-server/packages/server/modules/previews/services/createObjectPreview.ts
T

75 lines
2.2 KiB
TypeScript

import { DefaultAppIds } from '@/modules/auth/defaultApps'
import type { GetStreamCollaborators } from '@/modules/core/domain/streams/operations'
import type { CreateAndStoreAppToken } from '@/modules/core/domain/tokens/operations'
import type {
CreateObjectPreview,
RequestObjectPreview,
StoreObjectPreview
} from '@/modules/previews/domain/operations'
import { Roles, Scopes, TIME_MS } from '@speckle/shared'
import { TokenResourceIdentifierType } from '@/modules/core/domain/tokens/types'
import { toJobId } from '@speckle/shared/workers/previews'
import { PreviewProjectOwnerNotFoundError } from '@/modules/previews/errors/errors'
export const createObjectPreviewFactory =
({
getStreamCollaborators,
createAppToken,
requestObjectPreview,
storeObjectPreview,
serverOrigin
}: {
getStreamCollaborators: GetStreamCollaborators
serverOrigin: string
createAppToken: CreateAndStoreAppToken
requestObjectPreview: RequestObjectPreview
storeObjectPreview: StoreObjectPreview
}): CreateObjectPreview =>
async ({ streamId, objectId, priority }) => {
const owners = await getStreamCollaborators(streamId, Roles.Stream.Owner)
if (!owners || owners.length === 0) {
throw new PreviewProjectOwnerNotFoundError('No project owners found')
}
const userId = owners[0].id
// use the database as a lock to prevent multiple jobs being created
try {
await storeObjectPreview({
streamId,
objectId,
priority
})
} catch {
return false
}
const jobId = toJobId({ projectId: streamId, objectId })
// we're running the preview generation in the name of a project owner
const token = await createAppToken({
appId: DefaultAppIds.Web,
name: `preview-${jobId}`,
userId,
scopes: [Scopes.Streams.Read],
lifespan: 2 * TIME_MS.hour,
limitResources: [
{
id: streamId,
type: TokenResourceIdentifierType.Project
}
]
})
const url = new URL(
`/projects/${streamId}/models/${objectId}`,
serverOrigin
).toString()
await requestObjectPreview({
jobId,
token,
url
})
return true
}