Skip to content

Commit 831b2b5

Browse files
authored
fix: delete config route (#82)
* move delete config to separate route
1 parent ea55227 commit 831b2b5

File tree

4 files changed

+114
-38
lines changed

4 files changed

+114
-38
lines changed

backend/src/controllers/tools.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,50 @@ export const getUserConfigByTag = async (req: Request, res: Response) => {
232232
}
233233
}
234234

235+
export const deleteUserConfigVersion = async (req: Request, res: Response) => {
236+
try {
237+
const { walletAddress, version } = req.params
238+
const cookieHeader = req.headers.cookie
239+
const session = await getSession(cookieHeader)
240+
241+
const validForWallet = session?.get('validForWallet')
242+
if (!walletAddress) {
243+
throw 'Wallet address is required'
244+
}
245+
if (!session || validForWallet !== walletAddress) {
246+
throw 'Grant confirmation is required'
247+
}
248+
if (version === 'default') {
249+
throw 'Cannot delete default version'
250+
}
251+
252+
const { s3, params } = getS3AndParams(walletAddress)
253+
254+
const existingData = await s3.send(new GetObjectCommand(params))
255+
const existingContentString = await streamToString(
256+
existingData.Body as NodeJS.ReadableStream
257+
)
258+
const existingConfig: ConfigVersions = JSON.parse(existingContentString)
259+
260+
if (existingConfig[version]) {
261+
delete existingConfig[version]
262+
263+
const fileContent = JSON.stringify(existingConfig)
264+
const extendedParams = { ...params, Body: fileContent }
265+
await s3.send(new PutObjectCommand(extendedParams))
266+
}
267+
268+
res.status(200).send(existingConfig)
269+
} catch (err) {
270+
console.log(err)
271+
const message =
272+
err === 'Cannot delete default version'
273+
? err
274+
: 'An error occurred when deleting config version'
275+
res.status(500).send(message)
276+
}
277+
}
278+
235279
const sanitizeConfigFields = <T extends Partial<SanitizedFields>>(
236280
config: T
237281
): T => {

backend/src/routes/tools.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
getUserConfig,
55
createUserConfig,
66
saveUserConfig,
7-
getUserConfigByTag
7+
getUserConfigByTag,
8+
deleteUserConfigVersion
89
} from '../controllers/tools.js'
910

1011
const userRoutes = (router: Router) => {
@@ -13,6 +14,7 @@ const userRoutes = (router: Router) => {
1314
router.get('/tools/:id/:tag', getUserConfigByTag)
1415
router.post('/tools', createUserConfig)
1516
router.put('/tools', saveUserConfig)
17+
router.delete('/tools/:walletAddress/:version', deleteUserConfigVersion)
1618

1719
return router
1820
}

frontend/app/lib/apiClient.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,31 @@ export class ApiClient {
132132
}
133133
}
134134
}
135+
136+
public static async deleteConfigVersion(
137+
walletAddress: string,
138+
version: string,
139+
cookieHeader: string
140+
): Promise<ApiResponse> {
141+
const wa = encodeURIComponent(walletAddress)
142+
const response = await axios.delete(`${apiUrl}tools/${wa}/${version}`, {
143+
httpsAgent,
144+
withCredentials: true,
145+
headers: {
146+
Cookie: cookieHeader
147+
}
148+
})
149+
150+
if (response.status === 200) {
151+
return {
152+
isFailure: false,
153+
payload: response.data
154+
}
155+
} else {
156+
return {
157+
errors: [`status ${response.status}: ${response.statusText}`],
158+
isFailure: true
159+
}
160+
}
161+
}
135162
}

frontend/app/routes/create.$type.tsx

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -162,20 +162,10 @@ export default function Create() {
162162

163163
const onConfirmRemove = () => {
164164
if (fullConfig) {
165-
const { [selectedVersion]: _, ...rest } = fullConfig
166-
setFullConfig(rest)
167-
const config = fullConfig['default']
168-
setToolConfig(config)
169-
170-
const filteredOptions = versionOptions.filter(
171-
(ver) => ver.value != selectedVersion
172-
)
173-
setVersionOptions(filteredOptions)
174-
setSelectedVersion('default')
175-
setModalOpen(undefined)
176-
177-
const formData = getFormData(rest, 'remove', 'default')
165+
// only create and submit form data
166+
const formData = getFormData(fullConfig, 'remove', selectedVersion)
178167
submitForm(formData, { method: 'post' })
168+
setModalOpen(undefined)
179169
}
180170
}
181171

@@ -243,30 +233,29 @@ export default function Create() {
243233
useEffect(() => {
244234
const errors = Object.keys(response?.errors?.fieldErrors || {})
245235

246-
if (response && !errors.length && response.displayScript) {
247-
setModalOpen('script')
248-
} else if (response && response.grantRequired) {
249-
setModalOpen('wallet-ownership')
250-
} else if (
251-
response &&
252-
response.apiResponse &&
253-
response.apiResponse.newversion
254-
) {
255-
const newVersion = response.apiResponse.newversion
256-
const userFullconfig = response.apiResponse?.payload
257-
258-
setConfigs(userFullconfig, newVersion)
259-
setModalOpen('info')
260-
} else if (
261-
response &&
262-
response.apiResponse &&
263-
response.apiResponse.isFailure == false
264-
) {
265-
setConfigs(response.apiResponse?.payload, 'default')
266-
267-
setModalOpen(undefined)
268-
if (response.intent != 'remove') {
269-
setModalOpen('info')
236+
if (response && !errors.length) {
237+
if (response.displayScript) {
238+
setModalOpen('script')
239+
} else if (response.grantRequired) {
240+
setModalOpen('wallet-ownership')
241+
} else if (response.apiResponse?.isFailure === false) {
242+
if (response.intent === 'remove') {
243+
// update state only after successful deletion
244+
const { [selectedVersion]: _, ...rest } = fullConfig || {}
245+
setFullConfig(rest)
246+
setToolConfig(rest['default'])
247+
248+
const filteredOptions = versionOptions.filter(
249+
(ver) => ver.value !== selectedVersion
250+
)
251+
setVersionOptions(filteredOptions)
252+
setSelectedVersion('default')
253+
} else {
254+
setConfigs(response.apiResponse?.payload, 'default')
255+
if (response.intent !== 'remove') {
256+
setModalOpen('info')
257+
}
258+
}
270259
}
271260
}
272261
}, [response])
@@ -510,6 +499,20 @@ export async function action({ request, params }: ActionFunctionArgs) {
510499
)
511500
apiResponse.newversion = versionName
512501

502+
actionResponse.apiResponse = apiResponse
503+
return json(actionResponse, {
504+
status: 200,
505+
headers: {
506+
'Set-Cookie': await commitSession(session)
507+
}
508+
})
509+
} else if (intent === 'remove') {
510+
apiResponse = await ApiClient.deleteConfigVersion(
511+
payload.walletAddress,
512+
payload.version,
513+
theCookie || ''
514+
)
515+
513516
actionResponse.apiResponse = apiResponse
514517
return json(actionResponse, {
515518
status: 200,

0 commit comments

Comments
 (0)