Skip to Content

TCGPlayer Suffix-Based Parsing

Date2026-03-24
StatusAccepted
Decision Makers@benjaminW78

Context and Problem Statement

TCGCSV product names for SWU cards follow a consistent suffix pattern to indicate variant and finish. We need a reliable way to parse these product names into a base card name, variant, and finish so we can create the correct printing records and match against the SWU API for enrichment.

TCGCSV provides several fields per product: name, subTypeName, productId, and boolean flags. However, subTypeName is inconsistent across sets. In some TCGCSV groups, subTypeName is "Normal" / "Foil". In others, it’s "Unit" / "Event" / "Leader" (card type instead of finish). This makes subTypeName unreliable for determining whether a product is Standard, Hyperspace, Foil, etc.

The product names consistently use a suffix pattern:

  • "Darth Vader - Dark Lord of the Sith" — Standard Normal (no suffix)
  • "Darth Vader - Dark Lord of the Sith (Foil)" — Standard Foil
  • "Darth Vader - Dark Lord of the Sith (Hyperspace)" — Hyperspace Normal
  • "Darth Vader - Dark Lord of the Sith (Hyperspace Foil)" — Hyperspace Foil
  • "Darth Vader - Dark Lord of the Sith (Showcase)" — Showcase Foil
  • "Darth Vader - Dark Lord of the Sith (Prestige)" — Prestige Normal
  • "Darth Vader - Dark Lord of the Sith (Prestige Foil)" — Prestige Foil
  • "Darth Vader - Dark Lord of the Sith (Serialized)" — Prestige Serialized

Decision Drivers

  • subTypeName from TCGCSV is inconsistent and cannot be relied upon
  • Product name suffixes are consistent across all SWU sets on TCGPlayer
  • We need to determine the exact variant+finish combo for each TCGCSV product
  • The solution should be maintainable and type-safe

Considered Options

  1. Suffix-based parsing: Parse the product name suffix and map it to variant+finish via a static map
  2. subTypeName parsing: Use the subTypeName field to determine variant/finish
  3. Boolean flag matching: Use TCGCSV boolean flags (if available) to determine card properties

Decision Outcome

Chosen option: suffix-based parsing, implemented via two functions on the importer class: parseTcgProductName() to extract the base name and suffix, and resolveVariantAndFinish() to map the suffix to the corresponding variant and finish enums.

The suffix constants are defined in a TCG_PLAYER_SUFFIX_MAP:

private static readonly TCG_PLAYER_SUFFIX_MAP: Record<string, Record<string, string | null>> = { [StarWarsUnlimitedVariant.STANDARD]: { [StarWarsUnlimitedFinish.NORMAL]: null, // no suffix [StarWarsUnlimitedFinish.FOIL]: "Foil", }, [StarWarsUnlimitedVariant.HYPERSPACE]: { [StarWarsUnlimitedFinish.NORMAL]: "Hyperspace", [StarWarsUnlimitedFinish.FOIL]: "Hyperspace Foil", }, [StarWarsUnlimitedVariant.SHOWCASE]: { [StarWarsUnlimitedFinish.FOIL]: "Showcase", }, [StarWarsUnlimitedVariant.PRESTIGE]: { [StarWarsUnlimitedFinish.NORMAL]: "Prestige", [StarWarsUnlimitedFinish.FOIL]: "Prestige Foil", [StarWarsUnlimitedFinish.SERIALIZED]: "Serialized", }, }

The parsing algorithm:

  1. parseTcgProductName() strips all known suffixes (checked in longest-first order via TCG_PLAYER_SUFFIXES) from the product name to extract the base name and suffix
  2. resolveVariantAndFinish() looks up the suffix in a reverse map built from TCG_PLAYER_SUFFIX_MAP to determine the variant and finish
  3. The base name is then normalized (lowercased, accent-stripped) and used to match against the SWU API enrichment index

Parsing Flow

Impacted Files

FileKey SymbolsRole
packages/games/game-importer/src/star-wars-unlimited-importer.tsTCG_PLAYER_SUFFIX_MAP, TCG_PLAYER_SUFFIXES, parseTcgProductName(), resolveVariantAndFinish(), normalizeCardName()Defines the suffix map, the ordered suffixes array, and the parsing/resolution functions

Consequences

Positive

  • Works reliably across all SWU sets — product name suffixes are consistent
  • Single source of truth for the suffix-to-variant+finish mapping
  • Type-safe: enum keys prevent typos and make the map exhaustive
  • Enables the TCGCSV-first architecture — every TCGCSV product can be parsed into variant+finish without relying on the SWU API

Negative

  • Relies on TCGPlayer maintaining their naming convention — if they change suffix patterns, the map needs updating
  • New suffixes (e.g., a future “Ultra Foil” variant) require a code change to add to both the map and the suffixes array
  • Does not handle edge cases where card names themselves contain parentheses (mitigated by only recognizing known suffixes)
Last updated on