xBiggs / fightcade-api

An unofficial TypeScript wrapper for the Fightcade API.
MIT License
7 stars 2 forks source link

Make some GameSchema fields optional #13

Closed altcake closed 2 months ago

altcake commented 2 months ago

Change some fields in GameSchema to be optional since not all games contain them. This avoids crashes due to zod being unable to parse missing fields.

xBiggs commented 2 months ago

@altcake Please include some quarkids so I can verify that these fields are optional

altcake commented 2 months ago

Not sure what you mean by quarkids. I noticed this issue when I was trying to obtain game names using the GetGame function. This is the data returned by the FIghtcade API for two popular games on the platform:

{
  game: {
    name: 'Capcom Vs. SNK 2 Mark Of The Millennium 2001 (Flycast) (NAOMI)',
    gameid: 'flycast_cvs2',
    emulator: 'flycast',
    system: 'NAOMI',
    ranked: true,
    available_for: 1
  },
  res: 'OK'
}
{
  game: {
    name: 'Street Fighter III 3rd Strike: Fight for the Future (Japan 990512, NO CD)',
    gameid: 'sfiii3nr1',
    emulator: 'fbneo',
    system: 'Arcade FC2',
    ranked: true,
    training: true,
    available_for: 1
  },
  res: 'OK'
}

GameSchema in 3.0.5 dictates that the year, publisher, and genres fields must be present. Since these fields are not present in all games, zod will throw an exception due to a type mismatch from incoming API data (e.g. expecting a string and receiving null).

xBiggs commented 2 months ago

Minimum example:

#! /usr/bin/env node

import { GetGame } from "fightcade-api";

const game = await GetGame("sfiii3nr1");

console.log(game);

Output:

159 |     const json = JSON.stringify(obj, null, 2);
160 |     return json.replace(/"([^"]+)":/g, "$1:");
161 | };
162 | class ZodError extends Error {
163 |     constructor(issues) {
164 |         super();
              ^
ZodError: [
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "game",
      "year"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "game",
      "publisher"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "array",
    "received": "undefined",
    "path": [
      "game",
      "genres"
    ],
    "message": "Required"
  }
]
 errors: [
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "game",
      "year"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "game",
      "publisher"
    ],
    "message": "Required"
  },
  {
    "code": "invalid_type",
    "expected": "array",
    "received": "undefined",
    "path": [
      "game",
      "genres"
    ],
    "message": "Required"
  }
]

Looks like @altcake was correct year, publisher and genre should be optional in GameSchema.

After fixing, I get:

{
  gameid: "sfiii3nr1",
  name: "Street Fighter III 3rd Strike: Fight for the Future (Japan 990512, NO CD)",
  emulator: "fbneo",
  available_for: 1,
  system: "Arcade FC2",
  ranked: true,
  training: true,
}