{"version":3,"sources":["../src/core/http-client.ts","../src/core/response-handler.ts","../src/v1/resources/base.ts","../src/v1/resources/cards.ts","../src/v1/resources/games.ts","../src/v1/resources/sets.ts","../src/v1/index.ts","../src/index.ts"],"sourcesContent":["import { BatchLookupItem } from \"../types\";\n\nexport interface HttpClientConfig {\n  apiKey: string;\n  baseUrl: string;\n  debug?: boolean;\n}\n\nexport interface QueryParams {\n  [key: string]: string | string[] | number | boolean | undefined | null;\n}\n\ninterface BatchLookupItemStringified {\n    /** A TCGplayer product ID. */\n    tcgplayerId?: string;\n    /** The TCGPlayer SKU of the specific variant. */\n    tcgplayerSkuId?: string;\n    /** A JustTCG card ID. */\n    cardId?: string;\n    /** A JustTCG variant ID. */\n    variantId?: string;\n    /** The Scryfall ID of the card. */\n    scryfallId?: string;\n    /** The MTGJSON ID of the card. */\n    mtgjsonId?: string;\n    /** Filer by Updated after a specific date in Unix timestamp format (seconds since epoch). */\n    updated_after?: string;\n    /** An array of card print types to filter by. */\n    printing?: string;\n    /** An array of card conditions to filter by. */\n    condition?: string;\n    /** Option to include price history in the response. */\n    include_price_history?: string;\n    /** Option to include specific timeframes for the price statistics. */\n    include_statistics?: string;\n}\n\nexport class HttpClient {\n  private readonly apiKey: string;\n  private readonly baseUrl: string;\n  private readonly debug: boolean;\n\n  constructor(config: HttpClientConfig) {\n    this.apiKey = config.apiKey;\n    this.baseUrl = config.baseUrl;\n    this.debug = config.debug ?? false;\n  }\n\n  /**\n   * Performs a GET request to a given path.\n   * @param path The endpoint path (e.g., '/games').\n   * @param params Optional query parameters.\n   * @returns The JSON response from the API.\n   */\n  public async get<T>(path: string, params?: QueryParams): Promise<T> {\n    const url = new URL(`${this.baseUrl}${path}`);\n\n    // Safely append query parameters\n    if (params) {\n      Object.entries(params).forEach(([key, value]) => {\n        if (value !== undefined && value !== null) {\n          url.searchParams.append(key, String(value));\n        }\n      });\n    }\n\n    const response = await fetch(url.toString(), {\n      method: 'GET',\n      headers: this.getHeaders(),\n    });\n\n    if (!response.ok) {\n      // For now, we'll throw a generic error. We will enhance this later.\n      const errorBody = await response.json();\n      throw new Error(errorBody.error || 'An API error occurred');\n    }\n\n    return response.json() as Promise<T>;\n  }\n\n  /**\n   * Performs a POST request to a given path.\n   * @param path The endpoint path (e.g., '/cards').\n   * @param body The JSON body for the request.\n   * @returns The JSON response from the API.\n   */\n  public async post<T>(path: string, body: BatchLookupItem[]): Promise<T> {\n    const url = new URL(`${this.baseUrl}${path}`);\n\n    // Convert BatchLookupItem[] to BatchLookupItemStringified[]\n    const stringifiedBody: BatchLookupItemStringified[] = body.map(item => {\n      const stringifiedItem: BatchLookupItemStringified = {};\n      if (item.tcgplayerId) stringifiedItem.tcgplayerId = item.tcgplayerId;\n      if (item.tcgplayerSkuId) stringifiedItem.tcgplayerSkuId = item.tcgplayerSkuId;\n      if (item.cardId) stringifiedItem.cardId = item.cardId;\n      if (item.variantId) stringifiedItem.variantId = item.variantId;\n      if (item.scryfallId) stringifiedItem.scryfallId = item.scryfallId;\n      if (item.mtgjsonId) stringifiedItem.mtgjsonId = item.mtgjsonId;\n      if (item.printing) stringifiedItem.printing = Array.isArray(item.printing) ? item.printing.join(',') : item.printing;\n      if (item.condition) stringifiedItem.condition = Array.isArray(item.condition) ? item.condition.join(',') : item.condition;\n      if (item.include_price_history !== undefined) stringifiedItem.include_price_history = String(item.include_price_history);\n      if (item.include_statistics) stringifiedItem.include_statistics = Array.isArray(item.include_statistics) ? item.include_statistics.join(',') : item.include_statistics;\n      if (item.updated_after !== undefined) stringifiedItem.updated_after = String(item.updated_after);\n      return stringifiedItem;\n    });\n\n      if (this.debug) {\n        console.log(stringifiedBody);\n      }\n    const response = await fetch(url.toString(), {\n      method: 'POST',\n      headers: this.getHeaders(),\n      body: JSON.stringify(stringifiedBody),\n    });\n\n    if (!response.ok) {\n      const errorBody = await response.json();\n      throw new Error(errorBody.error || 'An API error occurred');\n    }\n\n    return response.json() as Promise<T>;\n  }\n\n  private getHeaders(): Record<string, string> {\n    return {\n      'Content-Type': 'application/json',\n      'x-api-key': this.apiKey, // Add the API key header\n    };\n  }\n}\n","import { JustTCGApiResponse, PaginationMeta, UsageMeta } from '../types';\n\n/**\n * The raw shape of a successful response from the JustTCG API server.\n */\ninterface RawApiResponse<T> {\n  data: T;\n  meta?: {\n    total: number;\n    limit: number;\n    offset: number;\n    hasMore: boolean;\n  };\n  _metadata: {\n    apiRequestLimit: number;\n    apiRequestsUsed: number;\n    apiRequestsRemaining: number;\n    apiDailyLimit: number;\n    apiDailyRequestsUsed: number;\n    apiDailyRequestsRemaining: number;\n    apiRateLimit: number;\n    apiPlan: string;\n  };\n  error?: string;\n  code?: string;\n}\n\n/**\n * Transforms a raw API response into the clean, structured format for the SDK user.\n * @param rawResponse The raw response object from the API.\n * @returns A JustTCGApiResponse object.\n */\nexport function handleResponse<T>(rawResponse: RawApiResponse<T>): JustTCGApiResponse<T> {\n  const usage: UsageMeta = {\n    apiRequestLimit: rawResponse._metadata.apiRequestLimit,\n    apiDailyLimit: rawResponse._metadata.apiDailyLimit,\n    apiRateLimit: rawResponse._metadata.apiRateLimit,\n    apiRequestsUsed: rawResponse._metadata.apiRequestsUsed,\n    apiDailyRequestsUsed: rawResponse._metadata.apiDailyRequestsUsed,\n    apiRequestsRemaining: rawResponse._metadata.apiRequestsRemaining,\n    apiDailyRequestsRemaining: rawResponse._metadata.apiDailyRequestsRemaining,\n    apiPlan: rawResponse._metadata.apiPlan,\n  };\n\n  const pagination: PaginationMeta | undefined = rawResponse.meta\n    ? {\n        total: rawResponse.meta.total,\n        limit: rawResponse.meta.limit,\n        offset: rawResponse.meta.offset,\n        hasMore: rawResponse.meta.hasMore,\n      }\n    : undefined;\n\n  return {\n    data: rawResponse.data,\n    pagination,\n    usage,\n    ...(rawResponse.error && { error: rawResponse.error }),\n    ...(rawResponse.code && { code: rawResponse.code }),\n  };\n}\n","import { HttpClient, QueryParams } from '../../core/http-client';\nimport { BatchLookupItem } from '../../types';\n\nexport class BaseResource {\n  protected httpClient: HttpClient;\n  private pathPrefix: string;\n\n  constructor(httpClient: HttpClient, pathPrefix: string) {\n    this.httpClient = httpClient;\n    this.pathPrefix = pathPrefix;\n  }\n\n  protected async _get<T>(path: string, params?: QueryParams): Promise<T> {\n    // Parse 'query' parameter to the 'q' format expected by the API\n    if (params && 'query' in params && typeof params.query === 'string') {\n      params.q = params.query;\n      delete params.query;\n    }\n    return this.httpClient.get<T>(`${this.pathPrefix}${path}`, params);\n  }\n\n  protected async _post<T>(path: string, body: BatchLookupItem[]): Promise<T> {\n    return this.httpClient.post<T>(`${this.pathPrefix}${path}`, body);\n  }\n}\n","import { handleResponse } from '../../core/response-handler';\nimport { BatchLookupItem, Card, GetCardsParams, JustTCGApiResponse, PaginationMeta, SearchCardsOptions, UsageMeta } from '../../types';\nimport { BaseResource } from './base';\n\ninterface RawCardsApiResponse {\n  data: Card[];\n  meta?: PaginationMeta;\n  _metadata: UsageMeta;\n}\n\n/**\n * Provides access to the /cards API resource.\n */\nexport class CardsResource extends BaseResource {\n  /**\n   * Retrieves a paginated list of cards based on a flexible set of query parameters.\n   * @param params Parameters for searching, filtering, and paginating cards.\n   * @returns A Promise resolving to the JustTCG API response containing an array of Card objects.\n   */\n  public async get(params: GetCardsParams): Promise<JustTCGApiResponse<Card[]>> {\n    const rawResponse = await this._get<RawCardsApiResponse>('/cards', params);\n    return handleResponse(rawResponse);\n  }\n\n  /**\n   * Retrieves a list of cards based on a batch of specific identifiers.\n   * @param items An array of objects, each identifying a card to look up.\n   * @returns A Promise resolving to the JustTCG API response containing an array of the requested Card objects.\n   */\n  public async getByBatch(items: BatchLookupItem[]): Promise<JustTCGApiResponse<Card[]>> {\n    const rawResponse = await this._post<RawCardsApiResponse>('/cards', items);\n    return handleResponse(rawResponse);\n  }\n\n  /**\n   * A convenience method to search for cards by a query string.\n   * This is a wrapper around the more flexible `get` method.\n   * @param query A search query for the card's name.\n   * @param options Optional parameters to filter or paginate the search results.\n   * @returns A Promise resolving to the JustTCG API response containing an array of Card objects.\n   */\n  public async search(\n    query: string,\n    options?: SearchCardsOptions,\n  ): Promise<JustTCGApiResponse<Card[]>> {\n    // This helper calls our powerful 'get' method with a simplified set of options.\n    const params: GetCardsParams = {\n      query,\n      ...options,\n    };\n    return this.get(params);\n  }\n}\n","import { handleResponse } from '../../core/response-handler';\nimport { Game, JustTCGApiResponse, UsageMeta } from '../../types';\nimport { BaseResource } from './base';\n\n// Define the specific shape of the raw response for this endpoint\ninterface RawGamesApiResponse {\n  data: Game[];\n  _metadata: UsageMeta; // The games endpoint does not have pagination `meta`\n}\n\nexport class GamesResource extends BaseResource {\n  /**\n   * Retrieves a list of all supported games.\n   * @returns A JustTCG API response containing an array of Game objects.\n   */\n  public async list(): Promise<JustTCGApiResponse<Game[]>> {\n    // Use our new, strongly-typed interface instead of `any`\n    const rawResponse = await this._get<RawGamesApiResponse>('/games');\n    return handleResponse(rawResponse);\n  }\n}\n","import { handleResponse } from '../../core/response-handler';\nimport { JustTCGApiResponse, PaginationMeta, Set, UsageMeta } from '../../types';\nimport { BaseResource } from './base';\n\n// Define the specific shape of the raw response for this endpoint\ninterface RawSetsApiResponse {\n  data: Set[];\n  meta: PaginationMeta; // The sets endpoint is paginated\n  _metadata: UsageMeta;\n  error?: string;\n  code?: string;\n}\n\nexport class SetsResource extends BaseResource {\n  /**\n   * Retrieves a paginated list of sets, optionally filtered by game.\n   * @param params Optional parameters to filter the list of sets.\n   * @returns A JustTCG API response containing an array of Set objects.\n   */\n  public async list(params?: {\n    /** The name of the game to filter sets by (e.g., 'Pokemon'). */\n    game?: string;\n    /** Query string to search for sets by name. */\n    q?: string;\n    /** Order by a specific field. */\n    orderBy?: 'name' | 'release_date';\n    /** Order direction: ascending ('asc') or descending ('desc'). */\n    order?: 'asc' | 'desc';\n    /** The maximum number of results to return. Default is 20. */\n    limit?: number;\n    /** The number of results to skip for pagination. */\n    offset?: number;\n  }): Promise<JustTCGApiResponse<Set[]>> {\n    const rawResponse = await this._get<RawSetsApiResponse>('/sets', params);\n    return handleResponse(rawResponse);\n  }\n}\n","import { HttpClient } from '../core/http-client';\nimport { CardsResource } from './resources/cards';\nimport { GamesResource } from './resources/games';\nimport { SetsResource } from './resources/sets';\n\nexport class V1Client {\n  public readonly games: GamesResource;\n  public readonly sets: SetsResource;\n  public readonly cards: CardsResource;\n\n  constructor(httpClient: HttpClient) {\n    const pathPrefix = '/v1';\n\n    this.games = new GamesResource(httpClient, pathPrefix);\n    this.sets = new SetsResource(httpClient, pathPrefix);\n    this.cards = new CardsResource(httpClient, pathPrefix);\n  }\n}\n","import { HttpClient } from './core/http-client';\nimport { V1Client } from './v1'; // Import the new V1Client\n\nconst API_BASE_URL = 'https://api.justtcg.com';\n\nexport interface JustTCGConfig {\n  /**\n   * Your JustTCG API key.\n   * If not provided, the client will look for the `JUSTTCG_API_KEY` environment variable.\n   */\n  apiKey?: string;\n  /**\n   * Enable debug mode to log request details.\n   */\n  debug?: boolean;\n}\n\nexport class JustTCG {\n  /** Provides access to the v1 version of the JustTCG API. */\n  public readonly v1: V1Client;\n  private readonly httpClient: HttpClient;\n\n  /**\n   * Creates an instance of the JustTCG client.\n   * @param config Configuration options for the client.\n   */\n  constructor(config: JustTCGConfig = {}) {\n    const apiKey = config.apiKey ?? process.env.JUSTTCG_API_KEY;\n\n    if (!apiKey) {\n      // We will replace this with a custom error later\n      throw new Error('Authentication error: API key is missing.');\n    }\n\n    this.httpClient = new HttpClient({\n      apiKey: apiKey,\n      baseUrl: API_BASE_URL,\n      debug: config.debug ?? false,\n    });\n\n    // Pass the httpClient instance to the V1Client\n    this.v1 = new V1Client(this.httpClient);\n  }\n}\n\n// Also, export our public types from the main entry point for user convenience\nexport * from './types';\n"],"mappings":"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","names":[]}