@lorenzopant/tmdb 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,21 @@
1
1
  import { ApiClient } from "../client";
2
2
  import { MovieResultItem } from "../types/movies";
3
- import { PaginatedResponse } from "../types/params";
3
+ import { MovieListParams, PaginatedResponse } from "../types/params";
4
+ import { TMDBOptions } from "../tmdb";
5
+ export declare enum MovieListEndpoints {
6
+ NOW_PLAYING = "/now_playing",
7
+ POPULAR = "/popular",
8
+ TOP_RATED = "/top_rated",
9
+ UPCOMING = "/upcoming"
10
+ }
4
11
  export declare class MovieListsAPI {
5
12
  private client;
6
- constructor(client: ApiClient);
13
+ private defaultOptions;
14
+ constructor(client: ApiClient, defaultOptions?: TMDBOptions);
7
15
  /**
8
16
  * Fetch Movie List Wrapper
9
17
  * @param endpoint Endpoint to call
10
- * @param language Language (Defaults to en-US)
11
- * @param page Page (Defaults to 1)
12
- * @param region ISO-3166-1 code
18
+ * @param params Params for the request (language, page, region, etc)
13
19
  * @returns Specific to endpoint (MovieListResult)
14
20
  */
15
21
  private fetch_movie_list;
@@ -18,39 +24,39 @@ export declare class MovieListsAPI {
18
24
  * GET - https://api.themoviedb.org/3/movie/now_playing
19
25
  *
20
26
  * Get a list of movies that are currently in theatres.
21
- * @param language Language (Defaults to en-US)
27
+ * @param language Language (Defaults to en-US or TMDB default)
22
28
  * @param page Page (Defaults to 1)
23
29
  * @param region ISO-3166-1 code
24
30
  */
25
- now_playing(language?: string, page?: number, region?: string): Promise<PaginatedResponse<MovieResultItem>>;
31
+ now_playing(params?: MovieListParams): Promise<PaginatedResponse<MovieResultItem>>;
26
32
  /**
27
33
  * Popular
28
34
  * GET - https://api.themoviedb.org/3/movie/popular
29
35
  *
30
36
  * Get a list of movies ordered by popularity.
31
- * @param language Language (Defaults to en-US)
37
+ * @param language Language (Defaults to en-US or TMDB default)
32
38
  * @param page Page (Defaults to 1)
33
39
  * @param region ISO-3166-1 code
34
40
  */
35
- popular(language?: string, page?: number, region?: string): Promise<PaginatedResponse<MovieResultItem>>;
41
+ popular(params?: MovieListParams): Promise<PaginatedResponse<MovieResultItem>>;
36
42
  /**
37
43
  * Top Rated
38
44
  * GET - https://api.themoviedb.org/3/movie/top_rated
39
45
  *
40
46
  * Get a list of movies ordered by rating.
41
- * @param language Language (Defaults to en-US)
47
+ * @param language Language (Defaults to en-US or TMDB default)
42
48
  * @param page Page (Defaults to 1)
43
49
  * @param region ISO-3166-1 code
44
50
  */
45
- top_rated(language?: string, page?: number, region?: string): Promise<PaginatedResponse<MovieResultItem>>;
51
+ top_rated(params?: MovieListParams): Promise<PaginatedResponse<MovieResultItem>>;
46
52
  /**
47
53
  * Upcoming
48
54
  * GET - https://api.themoviedb.org/3/movie/upcoming
49
55
  *
50
56
  * Get a list of movies that are being released soon.
51
- * @param language Language (Defaults to en-US)
57
+ * @param language Language (Defaults to en-US or TMDB default)
52
58
  * @param page Page (Defaults to 1)
53
59
  * @param region ISO-3166-1 code
54
60
  */
55
- upcoming(language?: string, page?: number, region?: string): Promise<PaginatedResponse<MovieResultItem>>;
61
+ upcoming(params?: MovieListParams): Promise<PaginatedResponse<MovieResultItem>>;
56
62
  }
@@ -1,73 +1,74 @@
1
1
  import { MOVIE_ENDPOINTS } from "./movies";
2
- const MOVIE_LISTS_ENDPOINTS = {
3
- NOW_PLAYING: "/now_playing",
4
- POPULAR: "/popular",
5
- TOP_RATED: "/top_rated",
6
- UPCOMING: "/upcoming",
7
- };
2
+ export var MovieListEndpoints;
3
+ (function (MovieListEndpoints) {
4
+ MovieListEndpoints["NOW_PLAYING"] = "/now_playing";
5
+ MovieListEndpoints["POPULAR"] = "/popular";
6
+ MovieListEndpoints["TOP_RATED"] = "/top_rated";
7
+ MovieListEndpoints["UPCOMING"] = "/upcoming";
8
+ })(MovieListEndpoints || (MovieListEndpoints = {}));
8
9
  export class MovieListsAPI {
9
10
  client;
10
- constructor(client) {
11
+ defaultOptions;
12
+ constructor(client, defaultOptions = {}) {
11
13
  this.client = client;
14
+ this.defaultOptions = defaultOptions;
12
15
  }
13
16
  /**
14
17
  * Fetch Movie List Wrapper
15
18
  * @param endpoint Endpoint to call
16
- * @param language Language (Defaults to en-US)
17
- * @param page Page (Defaults to 1)
18
- * @param region ISO-3166-1 code
19
+ * @param params Params for the request (language, page, region, etc)
19
20
  * @returns Specific to endpoint (MovieListResult)
20
21
  */
21
- fetch_movie_list(endpoint, language, page, region) {
22
- const params = { page, language, region };
23
- return this.client.request(MOVIE_ENDPOINTS.MOVIE + endpoint, params);
22
+ fetch_movie_list(endpoint, params = {}) {
23
+ const mergedParams = { ...this.defaultOptions, ...params };
24
+ return this.client.request(MOVIE_ENDPOINTS.MOVIE + endpoint, mergedParams);
24
25
  }
25
26
  /**
26
27
  * Now Playing
27
28
  * GET - https://api.themoviedb.org/3/movie/now_playing
28
29
  *
29
30
  * Get a list of movies that are currently in theatres.
30
- * @param language Language (Defaults to en-US)
31
+ * @param language Language (Defaults to en-US or TMDB default)
31
32
  * @param page Page (Defaults to 1)
32
33
  * @param region ISO-3166-1 code
33
34
  */
34
- async now_playing(language = "en-US", page = 1, region) {
35
- return this.fetch_movie_list(MOVIE_LISTS_ENDPOINTS.NOW_PLAYING, language, page, region);
35
+ async now_playing(params = {}) {
36
+ return this.fetch_movie_list(MovieListEndpoints.NOW_PLAYING, params);
36
37
  }
37
38
  /**
38
39
  * Popular
39
40
  * GET - https://api.themoviedb.org/3/movie/popular
40
41
  *
41
42
  * Get a list of movies ordered by popularity.
42
- * @param language Language (Defaults to en-US)
43
+ * @param language Language (Defaults to en-US or TMDB default)
43
44
  * @param page Page (Defaults to 1)
44
45
  * @param region ISO-3166-1 code
45
46
  */
46
- async popular(language = "en-US", page = 1, region) {
47
- return this.fetch_movie_list(MOVIE_LISTS_ENDPOINTS.POPULAR, language, page, region);
47
+ async popular(params = {}) {
48
+ return this.fetch_movie_list(MovieListEndpoints.POPULAR, params);
48
49
  }
49
50
  /**
50
51
  * Top Rated
51
52
  * GET - https://api.themoviedb.org/3/movie/top_rated
52
53
  *
53
54
  * Get a list of movies ordered by rating.
54
- * @param language Language (Defaults to en-US)
55
+ * @param language Language (Defaults to en-US or TMDB default)
55
56
  * @param page Page (Defaults to 1)
56
57
  * @param region ISO-3166-1 code
57
58
  */
58
- async top_rated(language = "en-US", page = 1, region) {
59
- return this.fetch_movie_list(MOVIE_LISTS_ENDPOINTS.TOP_RATED, language, page, region);
59
+ async top_rated(params = {}) {
60
+ return this.fetch_movie_list(MovieListEndpoints.TOP_RATED, params);
60
61
  }
61
62
  /**
62
63
  * Upcoming
63
64
  * GET - https://api.themoviedb.org/3/movie/upcoming
64
65
  *
65
66
  * Get a list of movies that are being released soon.
66
- * @param language Language (Defaults to en-US)
67
+ * @param language Language (Defaults to en-US or TMDB default)
67
68
  * @param page Page (Defaults to 1)
68
69
  * @param region ISO-3166-1 code
69
70
  */
70
- async upcoming(language = "en-US", page = 1, region) {
71
- return this.fetch_movie_list(MOVIE_LISTS_ENDPOINTS.UPCOMING, language, page, region);
71
+ async upcoming(params = {}) {
72
+ return this.fetch_movie_list(MovieListEndpoints.UPCOMING, params);
72
73
  }
73
74
  }
@@ -1,7 +1,8 @@
1
1
  import { ApiClient } from "../client";
2
+ import { TMDBOptions } from "../tmdb";
2
3
  import { Changes } from "../types/common";
3
4
  import { MovieAlternativeTitles, MovieCredits, MovieDetails, MovieExternalIDs, MovieImages, MovieKeywords, MovieReleaseDates, MovieResultItem, MovieTranslations, MovieVideos, MovieWatchProvider } from "../types/movies";
4
- import { PaginatedResponse } from "../types/params";
5
+ import { MovieAlternativeTitlesParams, MovieDetailsParams, PaginatedResponse } from "../types/params";
5
6
  export declare const MOVIE_ENDPOINTS: {
6
7
  MOVIE: string;
7
8
  ALTERNATIVE_TITLES: string;
@@ -20,7 +21,8 @@ export declare const MOVIE_ENDPOINTS: {
20
21
  };
21
22
  export declare class MoviesAPI {
22
23
  private client;
23
- constructor(client: ApiClient);
24
+ private defaultOptions;
25
+ constructor(client: ApiClient, options?: TMDBOptions);
24
26
  /**
25
27
  * Details
26
28
  * GET - https://api.themoviedb.org/3/movie/{movie_id}
@@ -32,7 +34,7 @@ export declare class MoviesAPI {
32
34
  * @returns A promise that resolves to the movie details.
33
35
  * @reference https://developer.themoviedb.org/reference/movie-details
34
36
  */
35
- details(movie_id: number, append_to_response?: string[], language?: string): Promise<MovieDetails>;
37
+ details(params: MovieDetailsParams): Promise<MovieDetails>;
36
38
  /**
37
39
  * Alternative Titles
38
40
  * GET - https://api.themoviedb.org/3/movie/{movie_id}/alternative_titles
@@ -43,7 +45,7 @@ export declare class MoviesAPI {
43
45
  * @returns A promise that resolves to the movie alternative titles.
44
46
  * @reference https://developer.themoviedb.org/reference/movie-alternative-titles
45
47
  */
46
- alternative_titles(movie_id: number, country?: string): Promise<MovieAlternativeTitles>;
48
+ alternative_titles(params: MovieAlternativeTitlesParams): Promise<MovieAlternativeTitles>;
47
49
  /**
48
50
  * Credits
49
51
  * GET - https://api.themoviedb.org/3/movie/{movie_id}/credits
@@ -1,3 +1,4 @@
1
+ import { mergeParams } from "../utils/params";
1
2
  export const MOVIE_ENDPOINTS = {
2
3
  MOVIE: "/movie",
3
4
  ALTERNATIVE_TITLES: "/alternative_titles",
@@ -22,8 +23,10 @@ export const MOVIE_ENDPOINTS = {
22
23
  };
23
24
  export class MoviesAPI {
24
25
  client;
25
- constructor(client) {
26
+ defaultOptions;
27
+ constructor(client, options = {}) {
26
28
  this.client = client;
29
+ this.defaultOptions = options;
27
30
  }
28
31
  /**
29
32
  * Details
@@ -36,10 +39,10 @@ export class MoviesAPI {
36
39
  * @returns A promise that resolves to the movie details.
37
40
  * @reference https://developer.themoviedb.org/reference/movie-details
38
41
  */
39
- async details(movie_id, append_to_response, language) {
40
- const params = { append_to_response, language };
41
- const endpoint = `${MOVIE_ENDPOINTS.MOVIE}/${movie_id}`;
42
- return this.client.request(endpoint, params);
42
+ async details(params) {
43
+ const mergedParams = { ...this.defaultOptions, ...params };
44
+ const endpoint = `${MOVIE_ENDPOINTS.MOVIE}/${mergedParams.movie_id}`;
45
+ return this.client.request(endpoint, mergedParams);
43
46
  }
44
47
  /**
45
48
  * Alternative Titles
@@ -51,10 +54,10 @@ export class MoviesAPI {
51
54
  * @returns A promise that resolves to the movie alternative titles.
52
55
  * @reference https://developer.themoviedb.org/reference/movie-alternative-titles
53
56
  */
54
- async alternative_titles(movie_id, country) {
55
- const params = { country: country || "" };
56
- const endpoint = `${MOVIE_ENDPOINTS.MOVIE}/${movie_id}${MOVIE_ENDPOINTS.ALTERNATIVE_TITLES}`;
57
- return this.client.request(endpoint, params);
57
+ async alternative_titles(params) {
58
+ const mergedParams = mergeParams(this.defaultOptions, params);
59
+ const endpoint = `${MOVIE_ENDPOINTS.MOVIE}/${mergedParams.movie_id}${MOVIE_ENDPOINTS.ALTERNATIVE_TITLES}`;
60
+ return this.client.request(endpoint, mergedParams);
58
61
  }
59
62
  /**
60
63
  * Credits
@@ -1,12 +1,14 @@
1
1
  import { ApiClient } from "../client";
2
2
  import { MovieResultItem } from "../types/movies";
3
3
  import { PaginatedResponse, SearchMoviesParams } from "../types/params";
4
+ import { TMDBOptions } from "../tmdb";
4
5
  export declare const SEARCH_ENDPOINTS: {
5
6
  MOVIE: string;
6
7
  };
7
8
  export declare class SearchAPI {
8
9
  private client;
9
- constructor(client: ApiClient);
10
+ private defaultOptions;
11
+ constructor(client: ApiClient, defaultOptions?: TMDBOptions);
10
12
  /**
11
13
  * Search
12
14
  * GET - https://api.themoviedb.org/3/search/movie
@@ -3,8 +3,10 @@ export const SEARCH_ENDPOINTS = {
3
3
  };
4
4
  export class SearchAPI {
5
5
  client;
6
- constructor(client) {
6
+ defaultOptions; // ** Default options for all requests
7
+ constructor(client, defaultOptions = {}) {
7
8
  this.client = client;
9
+ this.defaultOptions = defaultOptions;
8
10
  }
9
11
  /**
10
12
  * Search
@@ -22,6 +24,8 @@ export class SearchAPI {
22
24
  */
23
25
  async movies(params) {
24
26
  const endpoint = `${SEARCH_ENDPOINTS.MOVIE}`;
25
- return this.client.request(endpoint, params);
27
+ // Merge defaultOptions with params, giving precedence to params
28
+ const mergedParams = { ...this.defaultOptions, ...params };
29
+ return this.client.request(endpoint, mergedParams);
26
30
  }
27
31
  }
package/dist/index.d.ts CHANGED
@@ -2,3 +2,8 @@ export { TMDB } from "./tmdb";
2
2
  export { TMDBError } from "./errors/tmdb";
3
3
  export type { MovieDetails, MovieAlternativeTitle, MovieAlternativeTitles, MovieCredits, MovieExternalIDs, MovieImages, MovieKeywords, MovieReleaseDates, MovieTranslations, MovieVideos, } from "./types/movies";
4
4
  export type { Changes, Collection, Genre, ImageItem, Keyword, ProductionCompany, ProductionCountry, SpokenLanguage, VideoItem, Cast, Crew, } from "./types/common";
5
+ export type { SearchMoviesParams, MovieDetailsParams, MovieListParams, PaginatedResponse, MovieAlternativeTitlesParams, } from "./types/params";
6
+ export type { CountryISO3166_1 } from "./types/countries";
7
+ export { TMDBCountries } from "./types/countries";
8
+ export type { LanguageISO6391 } from "./types/lang";
9
+ export { Languages } from "./types/lang";
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
1
  // src/index.ts
2
2
  export { TMDB } from "./tmdb";
3
3
  export { TMDBError } from "./errors/tmdb";
4
+ export { TMDBCountries } from "./types/countries";
5
+ export { Languages } from "./types/lang";
@@ -3,7 +3,7 @@ import { TMDB } from "../../tmdb";
3
3
  const token = process.env.TMDB_ACCESS_TOKEN;
4
4
  if (!token)
5
5
  throw new Error("TMDB_ACCESS_TOKEN is not set, plaase set it in your enviroment variables.");
6
- const tmdb = new TMDB(token);
6
+ const tmdb = new TMDB(token, { language: "it-IT", region: "IT", country: "IT" });
7
7
  describe("Movie List (integration)", () => {
8
8
  it("(NOW PLAYING) should get now playing movies", async () => {
9
9
  const now_playing = await tmdb.movie_lists.now_playing();
@@ -9,7 +9,7 @@ const tmdb = new TMDB(token);
9
9
  describe("Movies (integration)", () => {
10
10
  it("(MOVIE DETAILS) should get movie details", async () => {
11
11
  const movie_id = 550; // Fight Club
12
- const movie = await tmdb.movies.details(movie_id);
12
+ const movie = await tmdb.movies.details({ movie_id });
13
13
  expect(movie).toBeDefined();
14
14
  expect(movie.id).toBe(movie_id);
15
15
  expect(movie.title).toBe("Fight Club");
@@ -18,7 +18,7 @@ describe("Movies (integration)", () => {
18
18
  const invalid_movie_id = -1; // Invalid movie ID
19
19
  // ** Can't test the specific error because API is not returning the same error for the same request
20
20
  try {
21
- await tmdb.movies.details(invalid_movie_id);
21
+ await tmdb.movies.details({ movie_id: invalid_movie_id });
22
22
  throw new Error("Expected TMDBError was not thrown");
23
23
  }
24
24
  catch (error) {
@@ -27,7 +27,7 @@ describe("Movies (integration)", () => {
27
27
  });
28
28
  it("(MOVIE ALTERNATIVE TITLES) should get movie alternative titles", async () => {
29
29
  const movie_id = 550; // Fight Club
30
- const movie_titles = await tmdb.movies.alternative_titles(movie_id);
30
+ const movie_titles = await tmdb.movies.alternative_titles({ movie_id });
31
31
  expect(movie_titles).toBeDefined();
32
32
  expect(movie_titles.id).toBe(movie_id);
33
33
  expect(movie_titles.titles.length).toBeGreaterThan(0);
@@ -14,19 +14,21 @@ describe("MoviesAPI", () => {
14
14
  it("should call client.request with the correct parameters", async () => {
15
15
  const movie_id = 550;
16
16
  const append_to_response = ["credits", "images"];
17
- const language = "en-US";
18
- await moviesAPI.details(movie_id, append_to_response, language);
17
+ const language = "en";
18
+ await moviesAPI.details({ movie_id, append_to_response, language });
19
19
  expect(clientMock.request).toHaveBeenCalledOnce();
20
20
  expect(clientMock.request).toHaveBeenCalledWith("/movie/550", {
21
+ movie_id,
21
22
  append_to_response,
22
23
  language,
23
24
  });
24
25
  });
25
26
  it("should work correctly without optional parameters", async () => {
26
27
  const movie_id = 550;
27
- await moviesAPI.details(movie_id);
28
+ await moviesAPI.details({ movie_id });
28
29
  expect(clientMock.request).toHaveBeenCalledOnce();
29
30
  expect(clientMock.request).toHaveBeenCalledWith("/movie/550", {
31
+ movie_id,
30
32
  append_to_response: undefined,
31
33
  language: undefined,
32
34
  });
@@ -34,7 +36,7 @@ describe("MoviesAPI", () => {
34
36
  it("should return the result from client.request", async () => {
35
37
  const fakeResponse = { id: 550, title: "Fight Club" };
36
38
  clientMock.request.mockResolvedValue(fakeResponse);
37
- const result = await moviesAPI.details(550);
39
+ const result = await moviesAPI.details({ movie_id: 550 });
38
40
  expect(result).toEqual(fakeResponse);
39
41
  });
40
42
  });
@@ -12,4 +12,12 @@ describe("Search (integration)", () => {
12
12
  expect(movies.results.length).toBeGreaterThan(0);
13
13
  expect(movies.results[0].title).toBe("Fight Club");
14
14
  });
15
+ it("(SEARCH MOVIE) should search for a movie with default options", async () => {
16
+ const tmdb = new TMDB(token, { language: "it-IT", region: "IT" });
17
+ const movies = await tmdb.search.movies({ query: "Fight Club" });
18
+ expect(movies.page).toBe(1);
19
+ expect(movies.total_results).toBeGreaterThan(0);
20
+ expect(movies.results.length).toBeGreaterThan(0);
21
+ expect(movies.results[0].title).toBe("Fight Club");
22
+ });
15
23
  });
package/dist/tmdb.d.ts CHANGED
@@ -1,10 +1,26 @@
1
1
  import { MovieListsAPI } from "./endpoints/movie_lists";
2
2
  import { MoviesAPI } from "./endpoints/movies";
3
3
  import { SearchAPI } from "./endpoints/search";
4
+ export type TMDBOptions = {
5
+ language?: string;
6
+ region?: string;
7
+ country?: string;
8
+ };
4
9
  export declare class TMDB {
5
10
  private client;
11
+ private options;
6
12
  movies: MoviesAPI;
7
13
  movie_lists: MovieListsAPI;
8
14
  search: SearchAPI;
9
- constructor(accessToken: string);
15
+ /**
16
+ * Creates a new TMDB instance.
17
+ * @param accessToken The TMDB API access token.
18
+ * @param options Optional default options (e.g., language) for all requests.
19
+ */
20
+ constructor(accessToken: string, options?: TMDBOptions);
21
+ /**
22
+ * Helper to merge default options with method-specific params.
23
+ * Method-level params override defaults.
24
+ */
25
+ withDefaults<T extends object>(params?: T): T & TMDBOptions;
10
26
  }
package/dist/tmdb.js CHANGED
@@ -6,16 +6,30 @@ import { SearchAPI } from "./endpoints/search";
6
6
  import { Errors } from "./errors/messages";
7
7
  export class TMDB {
8
8
  client;
9
+ options; // ** Default options for all requests
9
10
  movies;
10
11
  movie_lists;
11
12
  search;
12
13
  // etc...
13
- constructor(accessToken) {
14
+ /**
15
+ * Creates a new TMDB instance.
16
+ * @param accessToken The TMDB API access token.
17
+ * @param options Optional default options (e.g., language) for all requests.
18
+ */
19
+ constructor(accessToken, options = {}) {
14
20
  if (!accessToken)
15
21
  throw new Error(Errors.NO_ACCESS_TOKEN);
22
+ this.options = options;
16
23
  this.client = new ApiClient(accessToken);
17
- this.movies = new MoviesAPI(this.client);
18
- this.movie_lists = new MovieListsAPI(this.client);
19
- this.search = new SearchAPI(this.client);
24
+ this.movies = new MoviesAPI(this.client, options);
25
+ this.movie_lists = new MovieListsAPI(this.client, options);
26
+ this.search = new SearchAPI(this.client, options);
27
+ }
28
+ /**
29
+ * Helper to merge default options with method-specific params.
30
+ * Method-level params override defaults.
31
+ */
32
+ withDefaults(params) {
33
+ return { ...this.options, ...params };
20
34
  }
21
35
  }
@@ -0,0 +1,6 @@
1
+ export declare const TMDBCountries: {
2
+ iso_3166_1: CountryISO3166_1;
3
+ english_name: string;
4
+ native_name: string;
5
+ }[];
6
+ export type CountryISO3166_1 = "AD" | "AE" | "AF" | "AG" | "AI" | "AL" | "AM" | "AN" | "AO" | "AQ" | "AR" | "AS" | "AT" | "AU" | "AW" | "AZ" | "BA" | "BB" | "BD" | "BE" | "BF" | "BG" | "BH" | "BI" | "BJ" | "BM" | "BN" | "BO" | "BR" | "BS" | "BT" | "BU" | "BV" | "BW" | "BY" | "BZ" | "CA" | "CC" | "CD" | "CF" | "CG" | "CH" | "CI" | "CK" | "CL" | "CM" | "CN" | "CO" | "CR" | "CS" | "CU" | "CV" | "CX" | "CY" | "CZ" | "DE" | "DJ" | "DK" | "DM" | "DO" | "DZ" | "EC" | "EE" | "EG" | "EH" | "ER" | "ES" | "ET" | "FI" | "FJ" | "FK" | "FM" | "FO" | "FR" | "GA" | "GB" | "GD" | "GE" | "GF" | "GH" | "GI" | "GL" | "GM" | "GN" | "GP" | "GQ" | "GR" | "GS" | "GT" | "GU" | "GW" | "GY" | "HK" | "HM" | "HN" | "HR" | "HT" | "HU" | "ID" | "IE" | "IL" | "IN" | "IO" | "IQ" | "IR" | "IS" | "IT" | "JM" | "JO" | "JP" | "KE" | "KG" | "KH" | "KI" | "KM" | "KN" | "KP" | "KR" | "KW" | "KY" | "KZ" | "LA" | "LB" | "LC" | "LI" | "LK" | "LR" | "LS" | "LT" | "LU" | "LV" | "LY" | "MA" | "MC" | "MD" | "ME" | "MG" | "MH" | "MK" | "ML" | "MM" | "MN" | "MO" | "MP" | "MQ" | "MR" | "MS" | "MT" | "MU" | "MV" | "MW" | "MX" | "MY" | "MZ" | "NA" | "NC" | "NE" | "NF" | "NG" | "NI" | "NL" | "NO" | "NP" | "NR" | "NU" | "NZ" | "OM" | "PA" | "PE" | "PF" | "PG" | "PH" | "PK" | "PL" | "PM" | "PN" | "PR" | "PS" | "PT" | "PW" | "PY" | "QA" | "RE" | "RO" | "RS" | "RU" | "RW" | "SA" | "SB" | "SC" | "SD" | "SE" | "SG" | "SH" | "SI" | "SJ" | "SK" | "SL" | "SM" | "SN" | "SO" | "SR" | "SS" | "ST" | "SU" | "SV" | "SY" | "SZ" | "TC" | "TD" | "TF" | "TG" | "TH" | "TJ" | "TK" | "TL" | "TM" | "TN" | "TO" | "TP" | "TR" | "TT" | "TV" | "TW" | "TZ" | "UA" | "UG" | "UM" | "US" | "UY" | "UZ" | "VA" | "VC" | "VE" | "VG" | "VI" | "VN" | "VU" | "WF" | "WS" | "XC" | "XG" | "XI" | "XK" | "YE" | "YT" | "YU" | "ZA" | "ZM" | "ZR" | "ZW";