Browse Source

feat: start implementing 'noResults' response type

Sv443 4 months ago
parent
commit
4a4a6db8c8
5 changed files with 27 additions and 21 deletions
  1. 2 2
      src/routes/album.ts
  2. 5 4
      src/routes/search.ts
  3. 4 4
      src/routes/translations.ts
  4. 1 1
      src/types.ts
  5. 15 10
      src/utils.ts

+ 2 - 2
src/routes/album.ts

@@ -23,8 +23,8 @@ export function initAlbumRoutes(router: Router) {
 
       const album = await getAlbum(Number(songId));
 
-      if(!album)
-        return respond(res, "clientError", "Couldn't find any associated album for this song", format, 0);
+      if(!album) // TODO: verify
+        return respond(res, "noResults", {}, format);
 
       return respond(res, "success", { album }, format, 1);
     }

+ 5 - 4
src/routes/search.ts

@@ -22,8 +22,8 @@ export function initSearchRoutes(router: Router) {
           }),
         });
 
-        if(!meta || meta.all.length < 1)
-          return respond(res, "clientError", "Found no results matching your search query", format, 0);
+        if(!meta || meta.all.length < 1) // TODO: verify
+          return respond(res, "noResults",  format !== "xml" ? { top: null, all: [] } : { top: null, all: { "result": [] } }, format);
 
         // js2xmlparser needs special treatment when using arrays to produce a decent XML structure
         const response = format !== "xml" ? meta : { ...meta, all: { "result": meta.all } };
@@ -56,8 +56,8 @@ export function initSearchRoutes(router: Router) {
           }),
         });
 
-        if(!meta || !meta.top)
-          return respond(res, "clientError", "Found no results matching your search query", format, 0);
+        if(!meta || !meta.top) // TODO: verify
+          return respond(res, "noResults", {}, format);
 
         return respond(res, "success", meta.top, format, 1);
       }
@@ -69,6 +69,7 @@ export function initSearchRoutes(router: Router) {
     }
   });
 
+  // TODO: adjust
   //#region /search/manual
   router.get("/search/manual", (_req, res) => {
     res.sendFile("index.html", {

+ 4 - 4
src/routes/translations.ts

@@ -23,11 +23,11 @@ export function initTranslationsRoutes(router: Router) {
 
       const translations = await getTranslations(Number(songId));
 
-      if(translations === null || (Array.isArray(translations) && translations.length === 0))
-        return respond(res, "clientError", "Couldn't find translations for this song", format, 0);
+      if(translations === null || (Array.isArray(translations) && translations.length === 0)) // TODO: verify
+        return respond(res, "noResults", {}, format);
 
-      if(translations === undefined)
-        return respond(res, "clientError", "Couldn't find a song with the provided ID", format, undefined);
+      if(translations === undefined) // TODO: verify
+        return respond(res, "noResults", {}, format);
 
       return respond(res, "success", { translations }, format, translations.length);
     }

+ 1 - 1
src/types.ts

@@ -87,7 +87,7 @@ export interface SongTranslation {
 //#region server
 
 /** geniURL response type */
-export type ResponseType = "serverError" | "clientError" | "success";
+export type ResponseType = "serverError" | "clientError" | "success" | "noResults";
 
 /** geniURL response file format */
 export type ResponseFormat = "json" | "xml";

+ 15 - 10
src/utils.ts

@@ -13,10 +13,12 @@ export function paramValid(val: unknown): boolean {
 }
 
 /**
- * Responds to an incoming request
+ * Responds to a request in a uniform way
+ * @param res Express response object
  * @param type Type of response or status code
  * @param data The data to send in the response body
- * @param format json / xml
+ * @param format Response format "json" or "xml"
+ * @param matchesAmt Amount of matches / datasets returned in this response
  */
 export function respond(res: Response, type: ResponseType | number, data: Stringifiable | Record<string, unknown>, format = "json", matchesAmt?: number) {
   let statusCode = 500;
@@ -25,19 +27,23 @@ export function respond(res: Response, type: ResponseType | number, data: String
 
   let resData = {};
 
-  if(typeof format !== "string" || !["json", "xml"].includes(format.toLowerCase()))
-    format = "json";
+  format = format?.toLowerCase();
 
-  format = format.toLowerCase();
+  if(typeof format !== "string" || !["json", "xml"].includes(format))
+    format = "json";
 
-  switch(type)
-  {
+  switch(type) {
   case "success":
     error = false;
     matches = matchesAmt;
     statusCode = 200;
     resData = data;
     break;
+  case "noResults":
+    error = false;
+    matches = matchesAmt ?? 0;
+    statusCode = 200;
+    resData = data;
   case "clientError":
     error = true;
     matches = matchesAmt ?? null;
@@ -51,8 +57,7 @@ export function respond(res: Response, type: ResponseType | number, data: String
     resData = { message: data };
     break;
   default:
-    if(typeof type === "number")
-    {
+    if(typeof type === "number") {
       error = false;
       matches = matchesAmt ?? 0;
       statusCode = type;
@@ -75,7 +80,7 @@ export function respond(res: Response, type: ResponseType | number, data: String
   res.status(statusCode).send(finalData);
 }
 
-/** Redirects to the documentation page at the given path (homepage by default) */
+/** Redirects to the documentation page at the given relative path (homepage by default) */
 export function redirectToDocs(res: Response, path?: string) {
   res.redirect(`/v${verMajor}/docs/${path ? path.replace(/^\//, "") : ""}`);
 }