Skip to content

Commit c197c00

Browse files
authored
Merge pull request #262 from KenEucker/develop
fix(aws): deleteTag now updates the new latest tag information when deleting from the main folder
2 parents cf13804 + 3f76f7d commit c197c00

9 files changed

Lines changed: 135 additions & 53 deletions

File tree

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "biketag",
3-
"version": "3.5.22",
3+
"version": "3.5.23",
44
"description": "The Javascript client API for BikeTag Games",
55
"main": "./dist/index.js",
66
"module": "./dist/index.mjs",

src/aws/deleteTag.ts

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
S3Client,
33
DeleteObjectCommand,
44
DeleteObjectsCommand,
5+
CopyObjectCommand,
56
} from '@aws-sdk/client-s3'
67
import { deleteTagPayload } from '../common/payloads'
78
import { BikeTagApiResponse } from '../common/types'
@@ -12,8 +13,14 @@ import {
1213
listAllS3Objects,
1314
loadIndex,
1415
saveIndex,
16+
getKeyFromUrl,
17+
encodeMetadataValue,
1518
} from './helpers'
1619
import { Tag } from '../common/schema'
20+
import {
21+
getImgurMysteryTitleFromBikeTagData,
22+
getImgurMysteryDescriptionFromBikeTagData,
23+
} from '../common/getters'
1724

1825
export async function deleteTag(
1926
client: S3Client,
@@ -24,9 +31,8 @@ export async function deleteTag(
2431
payload
2532
const bucket = `${game}-biketag`
2633
const deleted: boolean[] = []
27-
2834
let success = true
29-
let errors = []
35+
let errors: string[] = []
3036

3137
if (!tagnumber) {
3238
success = false
@@ -43,10 +49,7 @@ export async function deleteTag(
4349
const deleteOps = list.map(async (obj) => {
4450
try {
4551
await client.send(
46-
new DeleteObjectCommand({
47-
Bucket: bucket,
48-
Key: obj.Key,
49-
})
52+
new DeleteObjectCommand({ Bucket: bucket, Key: obj.Key })
5053
)
5154
return true
5255
} catch (err) {
@@ -71,12 +74,10 @@ export async function deleteTag(
7174
'',
7275
folder
7376
)
74-
7577
const mysteryObjects = await listAllS3Objects(client, {
7678
Bucket: bucket,
7779
Prefix: mysteryKey,
7880
})
79-
8081
keysToDelete.push(...mysteryObjects.map((obj) => ({ Key: obj.Key! })))
8182
}
8283

@@ -89,12 +90,10 @@ export async function deleteTag(
8990
'',
9091
folder
9192
)
92-
9393
const foundObjects = await listAllS3Objects(client, {
9494
Bucket: bucket,
9595
Prefix: foundKey,
9696
})
97-
9897
keysToDelete.push(...foundObjects.map((obj) => ({ Key: obj.Key! })))
9998
}
10099

@@ -106,7 +105,6 @@ export async function deleteTag(
106105
Delete: { Objects: keysToDelete },
107106
})
108107
)
109-
110108
deleted.push(...keysToDelete.map(() => true))
111109

112110
if (result.Errors && result.Errors.length > 0) {
@@ -124,8 +122,60 @@ export async function deleteTag(
124122
let indexUpdateError = ''
125123
if (success && tagnumber) {
126124
try {
127-
const index = await loadIndex(client, bucket, folder, region)
125+
let index = await loadIndex(client, bucket, folder, region)
128126
const newIndex = index.filter((t) => t.tagnumber !== tagnumber)
127+
128+
if (folder === 'main' && newIndex.length > 0) {
129+
const idx = newIndex.findIndex((t) => t.tagnumber === tagnumber - 1)
130+
131+
if (idx === -1) {
132+
errors.push(`Previous tag ${tagnumber - 1} not found in index`)
133+
success = false
134+
} else {
135+
const latestTag = { ...newIndex[idx] }
136+
137+
// Reset fields to mystery state
138+
latestTag.gps = { lat: 0, long: 0, alt: 0 }
139+
latestTag.foundPlayer = ''
140+
latestTag.foundImageUrl = ''
141+
latestTag.foundTime = 0
142+
latestTag.foundLocation = ''
143+
144+
// Refresh metadata on mystery image
145+
if (latestTag.mysteryImageUrl) {
146+
const mysteryKey = getKeyFromUrl(latestTag.mysteryImageUrl)
147+
try {
148+
await client.send(
149+
new CopyObjectCommand({
150+
Bucket: bucket,
151+
CopySource: `${bucket}/${mysteryKey}`,
152+
Key: mysteryKey,
153+
ACL: 'public-read',
154+
MetadataDirective: 'REPLACE',
155+
Metadata: {
156+
title: encodeMetadataValue(
157+
getImgurMysteryTitleFromBikeTagData(latestTag).trim()
158+
),
159+
description: encodeMetadataValue(
160+
getImgurMysteryDescriptionFromBikeTagData(
161+
latestTag
162+
).trim()
163+
),
164+
},
165+
})
166+
)
167+
} catch (err: any) {
168+
success = false
169+
errors.push(
170+
`Failed to refresh metadata for mystery image: ${err.message}`
171+
)
172+
}
173+
}
174+
175+
newIndex[idx] = latestTag
176+
}
177+
}
178+
129179
await saveIndex(client, bucket, folder, newIndex)
130180
} catch (indexErr: any) {
131181
indexUpdateError = `Index update failed: ${indexErr.message}`
@@ -141,7 +191,7 @@ export async function deleteTag(
141191
return {
142192
data: deleted,
143193
success,
144-
error: errors.join(';'),
194+
error: errors.join('; '),
145195
source: AvailableApis[AvailableApis.aws],
146196
status: success ? HttpStatusCode.Ok : HttpStatusCode.BadRequest,
147197
}

src/aws/queueTag.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,15 @@ export async function queueTag(
5555
const mysteryTagPayload = payload
5656
const foundTagPayload = payload
5757
foundTagPayload.tagnumber = payload.tagnumber - 1
58+
const isBrowserRequest = typeof window !== 'undefined'
5859

5960
const [mysteryRes, foundRes] = await Promise.all([
60-
this.updateTag(client, mysteryTagPayload, cache),
61-
this.updateTag(client, foundTagPayload, cache),
61+
isBrowserRequest
62+
? this.biketagUpdate(mysteryTagPayload, cache)
63+
: this.updateTag(mysteryTagPayload, cache),
64+
isBrowserRequest
65+
? this.biketagUpdate(foundTagPayload, cache)
66+
: this.updateTag(foundTagPayload, cache),
6267
])
6368

6469
success = mysteryRes.success && foundRes.success
@@ -71,7 +76,7 @@ export async function queueTag(
7176
const image = isMystery ? payload.mysteryImage : payload.foundImage
7277
payload.contentType = (image as File)?.type ?? 'image/jpeg'
7378

74-
const uploadResponse = await this.uploadTagImage(client, payload)
79+
const uploadResponse = await this.uploadTagImage(payload)
7580

7681
if (uploadResponse.success) {
7782
const uploaded = uploadResponse.data

src/aws/updateTag.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export async function updateTag(
5050
const needsFound = !!(payload.foundImageUrl?.length || payload.foundImage)
5151

5252
if (needsMystery || needsFound) {
53-
const uploadResponse = await this.uploadTagImage(client, payload)
53+
const uploadResponse = await this.uploadTagImage(payload)
5454

5555
if (uploadResponse.success) {
5656
payload.mysteryImageUrl = uploadResponse.data.mysteryImageUrl

src/biketag/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ export { getQueue } from './getQueue'
77
export { getPlayers } from './getPlayers'
88
export { getAmbassadors } from './getAmbassadors'
99
export { getStats } from './getStats'
10+
export { updateTag } from './updateTag'
1011
export { fetchSignedUrl } from './fetchSignedUrl'

src/biketag/updateTag.ts

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
1-
// import { updateTagPayload } from '../common/payloads'
2-
// import { BikeTagApiResponse } from '../common/types'
3-
// import { Tag } from '../common/schema'
4-
// import { BikeTagGunClient } from '../common/types'
5-
// import { AvailableApis, HttpStatusCode } from '../common/enums'
1+
import { BikeTagClient } from '../client'
2+
import { UPDATE_ENDPOINT } from '../common/endpoints'
3+
import { AvailableApis, HttpStatusCode } from '../common/enums'
4+
import { updateTagPayload } from '../common/payloads'
5+
import { Tag } from '../common/schema'
6+
import { BikeTagApiResponse } from '../common/types'
7+
import { getApiUrl } from './helpers'
68

7-
// export async function updateTag(
8-
// client: BikeTagGunClient,
9-
// payload: updateTagPayload
10-
// ): Promise<BikeTagApiResponse<Tag>> {
11-
// const tag: Tag = await new Promise((r) => {
12-
// return client
13-
// .get(payload.game)
14-
// .get('tags')
15-
// .get(payload.tag.slug)
16-
// .put(payload.tag)
17-
// .once((t) => r(t as unknown as Tag))
18-
// })
9+
export async function updateTag(
10+
client: BikeTagClient,
11+
payload: updateTagPayload
12+
): Promise<BikeTagApiResponse<Tag>> {
13+
payload.source = undefined
1914

20-
// return {
21-
// data: tag,
22-
// status: HttpStatusCode.Ok,
23-
// success: true,
24-
// source: AvailableApis[AvailableApis.biketag],
25-
// }
26-
// }
15+
const opts = {
16+
url: getApiUrl(payload.host, UPDATE_ENDPOINT, payload.game),
17+
method: 'POST',
18+
headers: { 'Content-Type': 'application/json' },
19+
data: payload,
20+
}
21+
22+
const response = await client.request(opts)
23+
const success = response.status === 200
24+
25+
return {
26+
data: response.data as unknown as Tag,
27+
success,
28+
error: !success ? response.statusText : undefined,
29+
source: AvailableApis[AvailableApis.biketag],
30+
status: success ? HttpStatusCode.Ok : response.status,
31+
}
32+
}

src/client.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ export class BikeTagClient {
406406

407407
protected getPassthroughApiMethod(
408408
method: any,
409-
client: ImgurClient | BikeTagClient | SanityClient,
409+
client: ImgurClient | BikeTagClient | SanityClient | S3Client,
410410
dataType: DataTypes = DataTypes.tag,
411411
binding?: any
412412
): any {
@@ -839,20 +839,40 @@ export class BikeTagClient {
839839
let clientMethod = api.queueTag
840840

841841
switch (options.source) {
842-
case AvailableApis.aws:
843-
clientMethod = clientMethod.bind({
844-
getQueue: this.getPassthroughApiMethod(api.getQueue, client),
845-
getTags: this.getPassthroughApiMethod(api.getTags, client),
846-
updateTag: this.getPassthroughApiMethod(api.updateTag, client),
847-
uploadTagImage: api.uploadTagImage.bind({
842+
case AvailableApis.aws: {
843+
const getTags = this.getPassthroughApiMethod(api.getTags, client)
844+
const uploadTagImage = this.getPassthroughApiMethod(
845+
api.uploadTagImage,
846+
client,
847+
DataTypes.tag,
848+
{
848849
plainFetcher: this.plainFetcher,
849850
fetchSignedUrl: this.getPassthroughApiMethod(
850851
biketagApi.fetchSignedUrl,
851852
this
852853
),
853-
}),
854+
}
855+
)
856+
clientMethod = clientMethod.bind({
857+
getQueue: this.getPassthroughApiMethod(api.getQueue, client),
858+
getTags,
859+
biketagUpdate: this.getPassthroughApiMethod(
860+
biketagApi.updateTag,
861+
this
862+
),
863+
updateTag: this.getPassthroughApiMethod(
864+
api.updateTag,
865+
client,
866+
DataTypes.tag,
867+
{
868+
getTags,
869+
uploadTagImage,
870+
}
871+
),
872+
uploadTagImage,
854873
})
855874
break
875+
}
856876
case AvailableApis.imgur:
857877
clientMethod = clientMethod.bind({
858878
getQueue: this.getPassthroughApiMethod(api.getQueue, client),

src/common/payloads.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export type updatePlayerPayload = Partial<Player> & SanityUploadPayload
5353
export type updateTagPayload = Partial<Tag> &
5454
SanityUploadPayload & {
5555
resize?: boolean
56-
}
56+
} & CommonPayloadData
5757

5858
export type uploadTagImagePayload = {
5959
tagnumber: number

0 commit comments

Comments
 (0)