Skip to content

Commit

Permalink
feat: Support both unpublishing normal and world deployments
Browse files Browse the repository at this point in the history
  • Loading branch information
fzavalia committed Oct 5, 2023
1 parent 49602ee commit 49d150c
Showing 1 changed file with 46 additions and 12 deletions.
58 changes: 46 additions & 12 deletions src/modules/deployment/sagas.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { createFetchComponent } from '@well-known-components/fetch-component'
import { CatalystClient, ContentClient, createContentClient } from 'dcl-catalyst-client'
import { Authenticator, AuthIdentity } from '@dcl/crypto'
import { Entity, EntityType } from '@dcl/schemas'
import { createFetchComponent } from '@well-known-components/fetch-component'
import cryptoFetch from 'decentraland-crypto-fetch'
import { getAddress } from 'decentraland-dapps/dist/modules/wallet/selectors'
import { buildEntity } from 'dcl-catalyst-client/dist/client/utils/DeploymentBuilder'
import { takeLatest, put, select, call, take, all } from 'redux-saga/effects'
import { config } from 'config'
import { BuilderAPI, getPreviewUrl } from 'lib/api/builder'
import { Authorization } from 'lib/api/auth'
import { BuilderAPI, getEmptySceneUrl, getPreviewUrl } from 'lib/api/builder'
import { Deployment, SceneDefinition, Placement } from 'modules/deployment/types'
import { takeScreenshot } from 'modules/editor/actions'
import { fetchENSWorldStatusRequest } from 'modules/ens/actions'
Expand Down Expand Up @@ -60,11 +60,13 @@ import {
fetchWorldDeploymentsRequest
} from './actions'
import { makeContentFiles } from './contentUtils'
import { getThumbnail } from './utils'
import { UNPUBLISHED_PROJECT_ID, getEmptyDeployment, getThumbnail } from './utils'
import { ProgressStage } from './types'

const WORLDS_CONTENT_SERVER = config.get('WORLDS_CONTENT_SERVER', '')

type UnwrapPromise<T> = T extends PromiseLike<infer U> ? U : T

// TODO: Remove this. This is using the store directly which it shouldn't and causes a circular dependency.
const handleProgress = (type: ProgressStage) => (args: { loaded: number; total: number }) => {
const { loaded, total } = args
Expand Down Expand Up @@ -370,20 +372,52 @@ export function* deploymentSaga(builder: BuilderAPI, catalystClient: CatalystCli
const deployment = deployments[deploymentId]

if (!deployment) {
throw new Error('Deployment not found')
throw new Error('Unable to clear deployment: Invalid deployment')
}

const world = deployment.world
const identity: AuthIdentity = yield getIdentity()

if (!world) {
throw new Error('Deployment does not have a world')
if (!identity) {
throw new Error('Unable to clear deployment: Invalid identity')
}

const authorization: Authorization = new Authorization(store)
const path = `/entities/${world}`
const authHeaders: Record<string, string> = yield call([authorization, 'createAuthHeaders'], 'DELETE', path)
if (deployment.world) {
const response: Response = yield call(cryptoFetch, `${WORLDS_CONTENT_SERVER}/entities/${deployment.world}`, {
method: 'DELETE',
identity
})

if (!response.ok) {
throw new Error(`Unable to clear deployment: Response is not ok, status ${response.status}`)
}
} else {
const contentClient: ContentClient = yield call([catalystClient, 'getContentClient'])
const { placement } = deployment
const [emptyProject, emptyScene] = getEmptyDeployment(deployment.projectId || UNPUBLISHED_PROJECT_ID)
const files: UnwrapPromise<ReturnType<typeof createFiles>> = yield call(createFiles, {
project: emptyProject,
scene: emptyScene,
point: placement.point,
rotation: placement.rotation,
thumbnail: getEmptySceneUrl(),
author: null,
isDeploy: true,
isEmpty: true,
onProgress: handleProgress(ProgressStage.CREATE_FILES),
world: deployment.world ?? undefined
})
const contentFiles: Map<string, Buffer> = yield call(makeContentFiles, files)
const sceneDefinition: SceneDefinition = JSON.parse(files[EXPORT_PATH.SCENE_FILE])
const { entityId, files: hashedFiles } = yield call(buildEntity, {
type: EntityType.SCENE,
pointers: [...sceneDefinition.scene.parcels],
metadata: sceneDefinition,
files: contentFiles
})
const authChain = Authenticator.signPayload(identity, entityId)
yield call([contentClient, 'deploy'], { entityId, files: hashedFiles, authChain })
}

yield call(fetch, `${WORLDS_CONTENT_SERVER}${path}`, { method: 'DELETE', headers: { ...authHeaders } })
yield put(clearDeploymentSuccess(deploymentId))
} catch (e) {
yield put(clearDeploymentFailure(deploymentId, e.message))
Expand Down

0 comments on commit 49d150c

Please sign in to comment.