A Deno-powered backend service for Plants vs. Zombies: MODDED. [Read-only GitHub mirror] docs.pvzm.net
express typescript expressjs plant deno jspvz pvzm game online backend plants-vs-zombies zombie javascript plants modded vs plantsvszombies openapi pvz noads
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

0.6.4 - 🛠️ Fix requests hanging when a logging provider fails or is slow

Clay a93ae47e 41d11a59

+37 -25
+4
CHANGELOG.md
··· 1 1 # Changelog 2 2 3 + ## 0.6.4 4 + 5 + - 🛠️ Fix requests hanging when a logging provider fails or is slow 6 + 3 7 ## 0.6.3 4 8 5 9 - 🛠️ Simplified featured sort
+1 -1
README.md
··· 1 - # PVZM Backend ![v0.6.3](https://img.shields.io/badge/version-v0.6.3-darklime) 1 + # PVZM Backend ![v0.6.4](https://img.shields.io/badge/version-v0.6.4-darklime) 2 2 3 3 > A Deno-powered backend service for [Plants vs. Zombies: MODDED](https://github.com/roblnet13/pvz). This service provides APIs for uploading, downloading, listing, favoriting, and reporting user-created _I, Zombie_ levels. 4 4
+1 -1
deno.json
··· 1 1 { 2 - "version": "0.6.3", 2 + "version": "0.6.4", 3 3 "tasks": { 4 4 "dev": "deno run --watch -P=dev --env-file=.env main.ts", 5 5 "start": "deno run -P --env-file=.env main.ts",
+20 -14
modules/routes/admin.ts
··· 272 272 273 273 const updatedLevel = dbCtx.db.prepare("SELECT * FROM levels WHERE id = ?").get(levelId) as LevelRecord; 274 274 275 - await deps.loggingManager.sendAuditLog({ 275 + deps.loggingManager.sendAuditLog({ 276 276 action: "feature", 277 277 levelId, 278 278 levelName: updatedLevel.name, 279 279 author: updatedLevel.author, 280 - }); 280 + }).catch((err) => console.error("Warning: Failed to send audit log for level feature", levelId, err)); 281 281 282 282 // send featured message to logging providers (e.g., bluesky) 283 - const loggingData = await deps.loggingManager.sendFeaturedMessage( 283 + deps.loggingManager.sendFeaturedMessage( 284 284 { 285 285 id: levelId, 286 286 name: updatedLevel.name, ··· 290 290 featuredAt: now, 291 291 }, 292 292 exists.logging_data 293 - ); 294 - 295 - if (loggingData) { 296 - dbCtx.db.prepare("UPDATE levels SET logging_data = ? WHERE id = ?").run(loggingData, levelId); 297 - } 293 + ).then((loggingData) => { 294 + if (loggingData) { 295 + dbCtx.db.prepare("UPDATE levels SET logging_data = ? WHERE id = ?").run(loggingData, levelId); 296 + } 297 + }).catch((err) => console.error("Warning: Failed to send featured message for level", levelId, err)); 298 298 299 299 // send to posthog 300 300 if (postHogClient) { ··· 331 331 return res.status(404).json({ error: "Level not found" }); 332 332 } 333 333 334 - // delete featured message from logging providers (e.g., bluesky) 335 - const loggingData = await deps.loggingManager.deleteFeaturedMessage(levelRow.logging_data); 334 + dbCtx.db.prepare("UPDATE levels SET featured = 0, featured_at = NULL WHERE id = ?").run(levelId); 336 335 337 - dbCtx.db.prepare("UPDATE levels SET featured = 0, featured_at = NULL, logging_data = ? WHERE id = ?").run(loggingData, levelId); 336 + const updatedLevel = dbCtx.db.prepare("SELECT * FROM levels WHERE id = ?").get(levelId) as LevelRecord; 338 337 339 - const updatedLevel = dbCtx.db.prepare("SELECT * FROM levels WHERE id = ?").get(levelId) as LevelRecord; 338 + // delete featured message from logging providers (e.g., bluesky) 339 + deps.loggingManager.deleteFeaturedMessage(levelRow.logging_data) 340 + .then((loggingData) => { 341 + if (loggingData) { 342 + dbCtx.db.prepare("UPDATE levels SET logging_data = ? WHERE id = ?").run(loggingData, levelId); 343 + } 344 + }) 345 + .catch((err) => console.error("Warning: Failed to delete featured message for level", levelId, err)); 340 346 341 - await deps.loggingManager.sendAuditLog({ 347 + deps.loggingManager.sendAuditLog({ 342 348 action: "unfeature", 343 349 levelId, 344 350 levelName: updatedLevel.name, 345 351 author: updatedLevel.author, 346 - }); 352 + }).catch((err) => console.error("Warning: Failed to send audit log for level unfeature", levelId, err)); 347 353 348 354 // send to posthog 349 355 if (postHogClient) {
+10 -8
modules/routes/levels.ts
··· 295 295 )}&action=delete&level=${levelId}`, 296 296 }; 297 297 298 - let loggingData = await deps.loggingManager.sendLevelMessage(levelInfo); 299 - loggingData = await deps.loggingManager.sendAdminLevelMessage(adminLevelInfo, loggingData); 300 - 301 - if (loggingData) { 302 - dbCtx.db.prepare("UPDATE levels SET logging_data = ? WHERE id = ?").run(loggingData, levelId); 303 - } 298 + deps.loggingManager.sendLevelMessage(levelInfo) 299 + .then((loggingData) => deps.loggingManager.sendAdminLevelMessage(adminLevelInfo, loggingData)) 300 + .then((loggingData) => { 301 + if (loggingData) { 302 + dbCtx.db.prepare("UPDATE levels SET logging_data = ? WHERE id = ?").run(loggingData, levelId); 303 + } 304 + }) 305 + .catch((err) => console.error("Warning: Failed to send logging messages for level", levelId, err)); 304 306 } 305 307 306 308 res.status(201).json({ ··· 631 633 console.error("Error reading level file for report:", fileError); 632 634 } 633 635 634 - await deps.loggingManager.sendReportMessage({ 636 + deps.loggingManager.sendReportMessage({ 635 637 levelId, 636 638 levelName: typedLevel.name, 637 639 author: typedLevel.author, ··· 649 651 fileName: `${safeName}.${fileExtension}`, 650 652 } 651 653 : undefined, 652 - }); 654 + }).catch((err) => console.error("Warning: Failed to send report message for level", levelId, err)); 653 655 654 656 // send to posthog 655 657 const clientIP = getClientIP(req);
+1 -1
openapi.yaml
··· 2 2 info: 3 3 title: PVZM Backend API 4 4 description: "API for the Plants vs. Zombies: MODDED level sharing platform. Supports level uploading, downloading, browsing, favoriting, reporting, and admin management." 5 - version: 0.6.3 5 + version: 0.6.4 6 6 contact: 7 7 url: https://pvzm.net 8 8