188c333921
* fix(workspaces): non region enabled workspace project creation * fix(projects): remove duplicate getProject repo function This was the cause of the default project region switch bug, we had two almost identical implementations...
86 lines
2.7 KiB
TypeScript
86 lines
2.7 KiB
TypeScript
import { ProjectEvents } from '@/modules/core/domain/projects/events'
|
|
import { generateProjectName } from '@/modules/core/domain/projects/logic'
|
|
import {
|
|
CreateProject,
|
|
DeleteProject,
|
|
GetProject,
|
|
ProjectVisibility,
|
|
StoreModel,
|
|
StoreProject,
|
|
StoreProjectRole
|
|
} from '@/modules/core/domain/projects/operations'
|
|
import { Project } from '@/modules/core/domain/streams/types'
|
|
import { RegionalProjectCreationError } from '@/modules/core/errors/projects'
|
|
import { StreamNotFoundError } from '@/modules/core/errors/stream'
|
|
import { EventBusEmit } from '@/modules/shared/services/eventBus'
|
|
import { retry } from '@lifeomic/attempt'
|
|
import { Roles } from '@speckle/shared'
|
|
import cryptoRandomString from 'crypto-random-string'
|
|
|
|
export const createNewProjectFactory =
|
|
({
|
|
storeProject,
|
|
getProject,
|
|
deleteProject,
|
|
storeProjectRole,
|
|
storeModel,
|
|
emitEvent
|
|
}: {
|
|
storeProject: StoreProject
|
|
getProject: GetProject
|
|
deleteProject: DeleteProject
|
|
storeProjectRole: StoreProjectRole
|
|
emitEvent: EventBusEmit
|
|
storeModel: StoreModel
|
|
}): CreateProject =>
|
|
async ({ description, name, regionKey, visibility, workspaceId, ownerId }) => {
|
|
const publicVisibilities: ProjectVisibility[] = ['PUBLIC', 'UNLISTED']
|
|
const isPublic = !visibility || publicVisibilities.includes(visibility)
|
|
const isDiscoverable = visibility === 'PUBLIC'
|
|
const project: Project = {
|
|
id: cryptoRandomString({ length: 10 }),
|
|
name: name || generateProjectName(),
|
|
description: description || '',
|
|
isPublic,
|
|
isDiscoverable,
|
|
createdAt: new Date(),
|
|
clonedFrom: null,
|
|
updatedAt: new Date(),
|
|
workspaceId: workspaceId || null,
|
|
regionKey: regionKey || null,
|
|
allowPublicComments: false
|
|
}
|
|
|
|
await storeProject({ project })
|
|
const projectId = project.id
|
|
// if regionKey, we need to make sure it is actually written and synced
|
|
if (regionKey) {
|
|
try {
|
|
await retry(
|
|
async () => {
|
|
const replicatedProject = await getProject({ projectId })
|
|
if (!replicatedProject) throw new StreamNotFoundError()
|
|
},
|
|
{ maxAttempts: 10 }
|
|
)
|
|
} catch (err) {
|
|
if (err instanceof StreamNotFoundError) {
|
|
// delete from region
|
|
await deleteProject({ projectId })
|
|
throw new RegionalProjectCreationError()
|
|
}
|
|
// else throw as is
|
|
throw err
|
|
}
|
|
}
|
|
await storeProjectRole({ projectId, userId: ownerId, role: Roles.Stream.Owner })
|
|
await storeModel({
|
|
name: 'main',
|
|
description: 'default model',
|
|
projectId,
|
|
authorId: ownerId
|
|
})
|
|
await emitEvent({ eventName: ProjectEvents.Created, payload: { project, ownerId } })
|
|
return project
|
|
}
|