pnwkit 3.0 - v4.3.0
    Preparing search index...

    Class NationsQuery<F, I>

    Query builder for fetching nation data from the Politics & War API.

    Create new instances using the factory method: pnwkit.queries.nations() Each call creates a fresh instance with no shared state, preventing filter pollution.

    Features:

    • Type-safe field selection and filtering
    • Unlimited recursive nesting with automatic type inference
    • Automatic cardinality detection (singular vs array relations)
    • Pagination support with optional paginatorInfo

    Return types:

    • execute() → Returns array of nations
    • execute(true) → Returns { data: Nation[], paginatorInfo: {...} }
    // Basic query with filtering and pagination
    const nations = await pnwkit.queries.nations()
    .select('id', 'nation_name', 'score', 'alliance_id')
    .where({
    min_score: 1000,
    max_score: 5000,
    orderBy: [{ column: Enum('SCORE'), order: Enum('DESC') }]
    })
    .first(100)
    .execute();
    // Type: { id: number, nation_name: string, score: number, alliance_id: number }[]

    // Nested query with singular and array relations
    const nations = await pnwkit.queries.nations()
    .select('id', 'nation_name')
    .include('alliance', builder => builder // Singular: returns object
    .select('id', 'name', 'score')
    .where({ min_score: 5000 })
    )
    .include('cities', builder => builder // Array: returns array
    .select('id', 'name', 'infrastructure')
    )
    .first(50)
    .execute();
    // Type: {
    // id: number,
    // nation_name: string,
    // alliance: { id: number, name: string, score: number },
    // cities: { id: number, name: string, infrastructure: number }[]
    // }[]

    // Unlimited nesting depth
    const nations = await pnwkit.queries.nations()
    .select('id', 'nation_name')
    .include('alliance', b1 => b1
    .select('id', 'name')
    .include('nations', b2 => b2 // Nested nations
    .select('id', 'nation_name')
    .include('cities', b3 => b3 // Unlimited depth!
    .select('id', 'name')
    )
    )
    )
    .execute();

    // With pagination info
    const result = await pnwkit.queries.nations()
    .select('id', 'nation_name')
    .first(500)
    .page(2)
    .execute(true);
    console.log(result.data); // Nations array
    console.log(result.paginatorInfo); // { currentPage, total, hasMorePages, ... }

    Type Parameters

    • F extends readonly Exclude<keyof NationFields, "__typename">[] = []

      Selected field names (tracked through chaining for precise autocomplete)

    • I extends Record<string, any> = {}

      Included relations (tracked through chaining with proper cardinality)

    Hierarchy

    • QueryBuilder<NationFields, NationQueryParams>
      • NationsQuery
    Index
    apiKeyOverride?: string

    Per-call API key override, set via apiKey.

    filters: NationQueryParams = ...
    queryName: string = 'nations'
    selectedFields: (
        | "id"
        | "leader_name"
        | "nation_name"
        | "alliance_id"
        | "alliance_position"
        | "alliance_position_id"
        | "color"
        | "discord"
        | "discord_id"
        | "tax_id"
        | "continent"
        | "war_policy"
        | "war_policy_turns"
        | "domestic_policy"
        | "domestic_policy_turns"
        | "num_cities"
        | "score"
        | "update_tz"
        | "population"
        | "flag"
        | "vacation_mode_turns"
        | "beige_turns"
        | "espionage_available"
        | "last_active"
        | "date"
        | "soldiers"
        | "tanks"
        | "aircraft"
        | "ships"
        | "missiles"
        | "nukes"
        | "spies"
        | "soldiers_today"
        | "tanks_today"
        | "aircraft_today"
        | "ships_today"
        | "missiles_today"
        | "nukes_today"
        | "spies_today"
        | "turns_since_last_city"
        | "turns_since_last_project"
        | "money"
        | "coal"
        | "oil"
        | "uranium"
        | "iron"
        | "bauxite"
        | "lead"
        | "gasoline"
        | "munitions"
        | "steel"
        | "aluminum"
        | "food"
        | "credits"
        | "projects"
        | "project_bits"
        | "iron_works"
        | "bauxite_works"
        | "arms_stockpile"
        | "emergency_gasoline_reserve"
        | "mass_irrigation"
        | "international_trade_center"
        | "missile_launch_pad"
        | "nuclear_research_facility"
        | "iron_dome"
        | "vital_defense_system"
        | "central_intelligence_agency"
        | "center_for_civil_engineering"
        | "propaganda_bureau"
        | "uranium_enrichment_program"
        | "urban_planning"
        | "advanced_urban_planning"
        | "space_program"
        | "spy_satellite"
        | "moon_landing"
        | "pirate_economy"
        | "recycling_initiative"
        | "telecommunications_satellite"
        | "green_technologies"
        | "arable_land_agency"
        | "clinical_research_center"
        | "specialized_police_training_program"
        | "advanced_engineering_corps"
        | "government_support_agency"
        | "research_and_development_center"
        | "metropolitan_planning"
        | "military_salvage"
        | "fallout_shelter"
        | "activity_center"
        | "bureau_of_domestic_affairs"
        | "advanced_pirate_economy"
        | "mars_landing"
        | "surveillance_network"
        | "guiding_satellite"
        | "nuclear_launch_facility"
        | "military_research_center"
        | "military_doctrine"
        | "moon_landing_date"
        | "mars_landing_date"
        | "wars_won"
        | "wars_lost"
        | "alliance_seniority"
        | "gross_national_income"
        | "gross_domestic_product"
        | "soldier_casualties"
        | "soldier_kills"
        | "tank_casualties"
        | "tank_kills"
        | "aircraft_casualties"
        | "aircraft_kills"
        | "ship_casualties"
        | "ship_kills"
        | "missile_casualties"
        | "missile_kills"
        | "nuke_casualties"
        | "nuke_kills"
        | "spy_casualties"
        | "spy_kills"
        | "spy_attacks"
        | "money_looted"
        | "total_infrastructure_destroyed"
        | "total_infrastructure_lost"
        | "vip"
        | "commendations"
        | "denouncements"
        | "offensive_wars_count"
        | "defensive_wars_count"
        | "economic_policy"
        | "social_policy"
        | "government_type"
        | "credits_redeemed_this_month"
        | "alliance_join_date"
        | "cities_discount"
    )[] = []
    skipCacheFlag: boolean = false

    When true, this call bypasses the response cache. Set via skipCache.

    subqueries: Map<string, SubqueryConfig<any, {}, Record<string, any>>> = ...
    MAX_ARRAY_SIZE: 1000
    MAX_FIELD_NAME_LENGTH: 100
    MAX_FIELDS_PER_LEVEL: 100
    MAX_NESTING_DEPTH: 10
    MAX_QUERY_SIZE: 50000
    MAX_STRING_LENGTH: 10000
    QUERIES_WITHOUT_DATA_WRAPPER: Set<string> = ...

    Queries that return data directly without wrapping in a 'data' object. These queries follow a different GraphQL schema structure.

    • Use a specific API key for this call instead of the client's default key.

      Parameters

      • key: string

        The Politics & War API key to authenticate this query with.

      Returns this

      This query builder instance for method chaining.

      await pnwkit.queries.nations()
      .select('id', 'nation_name')
      .apiKey('another-api-key')
      .execute();
    • Build the final GraphQL query string with comprehensive validation.

      Constructs a complete GraphQL query including:

      • Main fields and subqueries with proper formatting
      • Pagination variables (first, page)
      • Filter parameters with type-safe serialization
      • Optional paginator info fields

      Validation includes:

      • Field count limits (max 100 per level)
      • Field name format and length validation (max 100 chars)
      • Query size validation (max 50KB)
      • All filter values properly sanitized and escaped

      Parameters

      • includePaginator: boolean

        Whether to include pagination info in response

      Returns string

      Complete GraphQL query string ready for execution

      Error if field count/name/size limits exceeded or filters contain invalid values

    • Execute the nations query and return results.

      Return type changes based on withPaginator parameter:

      • execute() or execute(false) → Returns array of nations
      • execute(true) → Returns object with data array and paginatorInfo

      Results only include selected fields and included relations. All other fields are excluded from the response.

      Returns Promise<SelectFields<NationFields, F, I>[]>

      Array of nations, or object with data and paginatorInfo if withPaginator is true

      Error if the query fails or returns no data

      // Returns array directly
      const nations = await query.execute();
      // Type: { id: number, nation_name: string }[]
      nations.forEach(nation => console.log(nation.id, nation.nation_name));

      // Returns object with pagination info
      const result = await query.execute(true);
      // Type: { data: {...}[], paginatorInfo: {...} }
      console.log(result.data); // Nations array
      console.log(result.paginatorInfo.total); // Total count
      console.log(result.paginatorInfo.hasMorePages); // Boolean
    • Execute the nations query and return results.

      Return type changes based on withPaginator parameter:

      • execute() or execute(false) → Returns array of nations
      • execute(true) → Returns object with data array and paginatorInfo

      Results only include selected fields and included relations. All other fields are excluded from the response.

      Parameters

      • withPaginator: true

      Returns Promise<
          {
              data: SelectFields<NationFields, F, I>[];
              paginatorInfo: paginatorInfo;
          },
      >

      Array of nations, or object with data and paginatorInfo if withPaginator is true

      Error if the query fails or returns no data

      // Returns array directly
      const nations = await query.execute();
      // Type: { id: number, nation_name: string }[]
      nations.forEach(nation => console.log(nation.id, nation.nation_name));

      // Returns object with pagination info
      const result = await query.execute(true);
      // Type: { data: {...}[], paginatorInfo: {...} }
      console.log(result.data); // Nations array
      console.log(result.paginatorInfo.total); // Total count
      console.log(result.paginatorInfo.hasMorePages); // Boolean
    • Include related data in the query results

      Supports unlimited recursive nesting with full type inference at every level. Each nested builder receives complete type safety for fields, relations, and query parameters.

      Type Parameters

      • K extends keyof NationRelations
      • TConfig extends SubqueryConfig<
            NationRelations[K],
            GetRelationsFor<NationRelations[K]>,
            GetQueryParamsFor<NationRelations[K]>,
        >
      • TNestedResult = InferSubqueryType<ReturnType<TConfig>>
      • TWrappedResult = NationRelations[K] extends any[] ? TNestedResult[] : TNestedResult

      Parameters

      • relation: K

        The relation name to include

      • config: TConfig

        A builder function for configuring the subquery

      Returns NationsQuery<F, I & Record<K, TWrappedResult>>

      New query instance with included relation

      // Basic subquery with field selection
      .include('cities', builder => builder
      .select('id', 'name', 'infrastructure')
      )

      // Subquery with filtering
      .include('alliance', builder => builder
      .select('id', 'name', 'score')
      .where({ id: [1234] })
      )

      // Deeply nested subquery with unlimited depth
      .include('alliance', builder => builder
      .select('id', 'name', 'score')
      .where({ min_score: 1000 })
      .include('nations', builder2 => builder2 // Unlimited nesting!
      .select('id', 'nation_name')
      .where({ min_score: 500 })
      .include('cities', builder3 => builder3
      .select('id', 'name', 'infrastructure')
      )
      )
      )

      // Important: Always select at least one scalar field at each level
      // GraphQL requires this - you cannot query an object without selecting fields
    • Sanitize and escape a string value for safe GraphQL usage.

      Validates input type and length, checks for null bytes, and escapes special characters including backslashes, quotes, newlines, carriage returns, tabs, form feeds, and backspaces.

      Parameters

      • str: string

        The string to sanitize

      Returns string

      Sanitized string with all special characters properly escaped

      Error if input is not a string, exceeds maximum length (10KB), or contains null bytes

    • Select specific fields to retrieve from nations

      Type Parameters

      • const Fields extends readonly (
            | "id"
            | "leader_name"
            | "nation_name"
            | "alliance_id"
            | "alliance_position"
            | "alliance_position_id"
            | "color"
            | "discord"
            | "discord_id"
            | "tax_id"
            | "continent"
            | "war_policy"
            | "war_policy_turns"
            | "domestic_policy"
            | "domestic_policy_turns"
            | "num_cities"
            | "score"
            | "update_tz"
            | "population"
            | "flag"
            | "vacation_mode_turns"
            | "beige_turns"
            | "espionage_available"
            | "last_active"
            | "date"
            | "soldiers"
            | "tanks"
            | "aircraft"
            | "ships"
            | "missiles"
            | "nukes"
            | "spies"
            | "soldiers_today"
            | "tanks_today"
            | "aircraft_today"
            | "ships_today"
            | "missiles_today"
            | "nukes_today"
            | "spies_today"
            | "turns_since_last_city"
            | "turns_since_last_project"
            | "money"
            | "coal"
            | "oil"
            | "uranium"
            | "iron"
            | "bauxite"
            | "lead"
            | "gasoline"
            | "munitions"
            | "steel"
            | "aluminum"
            | "food"
            | "credits"
            | "projects"
            | "project_bits"
            | "iron_works"
            | "bauxite_works"
            | "arms_stockpile"
            | "emergency_gasoline_reserve"
            | "mass_irrigation"
            | "international_trade_center"
            | "missile_launch_pad"
            | "nuclear_research_facility"
            | "iron_dome"
            | "vital_defense_system"
            | "central_intelligence_agency"
            | "center_for_civil_engineering"
            | "propaganda_bureau"
            | "uranium_enrichment_program"
            | "urban_planning"
            | "advanced_urban_planning"
            | "space_program"
            | "spy_satellite"
            | "moon_landing"
            | "pirate_economy"
            | "recycling_initiative"
            | "telecommunications_satellite"
            | "green_technologies"
            | "arable_land_agency"
            | "clinical_research_center"
            | "specialized_police_training_program"
            | "advanced_engineering_corps"
            | "government_support_agency"
            | "research_and_development_center"
            | "metropolitan_planning"
            | "military_salvage"
            | "fallout_shelter"
            | "activity_center"
            | "bureau_of_domestic_affairs"
            | "advanced_pirate_economy"
            | "mars_landing"
            | "surveillance_network"
            | "guiding_satellite"
            | "nuclear_launch_facility"
            | "military_research_center"
            | "military_doctrine"
            | "moon_landing_date"
            | "mars_landing_date"
            | "wars_won"
            | "wars_lost"
            | "alliance_seniority"
            | "gross_national_income"
            | "gross_domestic_product"
            | "soldier_casualties"
            | "soldier_kills"
            | "tank_casualties"
            | "tank_kills"
            | "aircraft_casualties"
            | "aircraft_kills"
            | "ship_casualties"
            | "ship_kills"
            | "missile_casualties"
            | "missile_kills"
            | "nuke_casualties"
            | "nuke_kills"
            | "spy_casualties"
            | "spy_kills"
            | "spy_attacks"
            | "money_looted"
            | "total_infrastructure_destroyed"
            | "total_infrastructure_lost"
            | "vip"
            | "commendations"
            | "denouncements"
            | "offensive_wars_count"
            | "defensive_wars_count"
            | "economic_policy"
            | "social_policy"
            | "government_type"
            | "credits_redeemed_this_month"
            | "alliance_join_date"
            | "cities_discount"
        )[]

      Parameters

      • ...fields: Fields

        Field names to select

      Returns NationsQuery<Fields>

      New query instance with selected fields

      Error if no fields are provided

      .select('id', 'nation_name', 'score')
      
    • Serialize an object to GraphQL format (enum values without quotes).

      Validates object structure and prevents prototype pollution by:

      • Using own properties only (not inherited)
      • Blocking dangerous keys (proto, constructor, prototype)
      • Validating GraphQL field name format
      • Validating enum value format (uppercase with underscores)
      • Ensuring numbers are finite (rejecting NaN, Infinity)

      Parameters

      • obj: Record<string, any>

        Plain object to serialize (not arrays)

      Returns string

      GraphQL-formatted object string in format {key:value, ...}

      Error if object is null/undefined/array, contains invalid field names, or has unsafe values

    • Bypass the response cache for this call.

      Only meaningful when caching is enabled on the client (cache.enabled). The result is fetched fresh from the API and is neither read from nor written to the cache. No effect when caching is disabled.

      Returns this

      This query builder instance for method chaining.

      await pnwkit.queries.nations()
      .select('id', 'nation_name')
      .skipCache()
      .execute();
    • Apply filters to the query

      Parameters

      • filters: NationQueryParams

        Query parameters for filtering results

      Returns this

      This query instance for method chaining

      .where({ min_score: 1000, max_score: 5000 })