@youversion/platform-core 1.2.0 → 1.3.0

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,5 +1,5 @@
1
1
 
2
- > @youversion/platform-core@1.2.0 build /home/runner/work/platform-sdk-react/platform-sdk-react/packages/core
2
+ > @youversion/platform-core@1.3.0 build /home/runner/work/platform-sdk-react/platform-sdk-react/packages/core
3
3
  > tsup src/index.ts --format cjs,esm --dts
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -8,11 +8,11 @@
8
8
  CLI Target: es2022
9
9
  CJS Build start
10
10
  ESM Build start
11
- CJS dist/index.cjs 42.87 KB
12
- CJS ⚡️ Build success in 31ms
13
- ESM dist/index.js 41.06 KB
14
- ESM ⚡️ Build success in 32ms
11
+ ESM dist/index.js 41.47 KB
12
+ ESM ⚡️ Build success in 34ms
13
+ CJS dist/index.cjs 43.29 KB
14
+ CJS ⚡️ Build success in 35ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 1751ms
17
- DTS dist/index.d.cts 32.80 KB
18
- DTS dist/index.d.ts 32.80 KB
16
+ DTS ⚡️ Build success in 1804ms
17
+ DTS dist/index.d.cts 32.84 KB
18
+ DTS dist/index.d.ts 32.84 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @youversion/platform-core
2
2
 
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b2b86c2: Add support for array query parameters in API client and improve language range handling
8
+ - **API Client**: Enhanced query string serialization to support array parameters, properly formatting them as repeated keys (e.g., `?param=one&param=two`)
9
+ - **Bible Client**: Updated `getVersions()` method to accept either a single language range string or an array of language ranges, providing more flexibility for filtering Bible versions
10
+ - **Schema**: Renamed language range schema to use plural naming convention for consistency
11
+ - **Testing**: Added comprehensive test coverage for query string building with both scalar and array parameters
12
+
13
+ This change maintains backward compatibility while providing more flexible API parameter handling.
14
+
15
+ ## 1.2.1
16
+
17
+ ### Patch Changes
18
+
19
+ - e845974: fix: make country parameter optional for getLanguages
20
+
21
+ The country parameter is now optional when fetching languages, allowing developers to retrieve all available languages without filtering by country. This improves developer experience by providing a more flexible API while maintaining backward compatibility for existing code that provides a country filter.
22
+
3
23
  ## 1.2.0
4
24
 
5
25
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -69,9 +69,15 @@ var ApiClient = class {
69
69
  */
70
70
  buildQueryString(params) {
71
71
  if (!params) return "";
72
- const queryString = new URLSearchParams(
73
- Object.entries(params).map(([key, value]) => [key, String(value)])
74
- ).toString();
72
+ const searchParams = new URLSearchParams();
73
+ Object.entries(params).forEach(([key, value]) => {
74
+ if (Array.isArray(value)) {
75
+ value.forEach((item) => searchParams.append(key, String(item)));
76
+ } else {
77
+ searchParams.append(key, String(value));
78
+ }
79
+ });
80
+ const queryString = searchParams.toString();
75
81
  return queryString ? `?${queryString}` : "";
76
82
  }
77
83
  /**
@@ -205,14 +211,15 @@ var BibleClient = class {
205
211
  /**
206
212
  * Fetches a collection of Bible versions filtered by language ranges.
207
213
  *
208
- * @param language_ranges - A comma-separated list of language codes or ranges to filter the versions (required).
214
+ * @param language_ranges - One or more language codes or ranges to filter the versions (required).
209
215
  * @param license_id - Optional license ID to filter versions by license.
210
216
  * @returns A promise that resolves to a collection of BibleVersion objects.
211
217
  */
212
218
  async getVersions(language_ranges, license_id) {
213
- this.languageRangesSchema.parse(language_ranges);
219
+ const languageRangeArray = Array.isArray(language_ranges) ? language_ranges : [language_ranges];
220
+ const parsedLanguageRanges = import_zod.z.array(this.languageRangesSchema).nonempty("At least one language range is required").parse(languageRangeArray);
214
221
  const params = {
215
- "language_ranges[]": language_ranges
222
+ "language_ranges[]": parsedLanguageRanges
216
223
  };
217
224
  if (license_id !== void 0) {
218
225
  params.license_id = license_id;
@@ -409,13 +416,15 @@ var LanguagesClient = class {
409
416
  }
410
417
  /**
411
418
  * Fetches a collection of languages supported in the Platform.
412
- * @param options Query parameters for pagination and filtering (country is required).
419
+ * @param options Query parameters for pagination and filtering.
413
420
  * @returns A collection of Language objects.
414
421
  */
415
- async getLanguages(options) {
422
+ async getLanguages(options = {}) {
416
423
  const params = {};
417
- const country = this.countrySchema.parse(options.country);
418
- params.country = country;
424
+ if (options.country !== void 0) {
425
+ const country = this.countrySchema.parse(options.country);
426
+ params.country = country;
427
+ }
419
428
  if (options.page_size !== void 0) {
420
429
  const pageSizeSchema = import_zod2.z.number().int().positive();
421
430
  pageSizeSchema.parse(options.page_size);
package/dist/index.d.cts CHANGED
@@ -258,7 +258,8 @@ interface HighlightColor {
258
258
  label: string;
259
259
  }
260
260
 
261
- type QueryParams = Record<string, string | number | boolean>;
261
+ type PrimitiveQueryParam = string | number | boolean;
262
+ type QueryParams = Record<string, PrimitiveQueryParam | PrimitiveQueryParam[]>;
262
263
  type RequestData = Record<string, string | number | boolean | object>;
263
264
  type RequestHeaders = Record<string, string>;
264
265
  /**
@@ -333,11 +334,11 @@ declare class BibleClient {
333
334
  /**
334
335
  * Fetches a collection of Bible versions filtered by language ranges.
335
336
  *
336
- * @param language_ranges - A comma-separated list of language codes or ranges to filter the versions (required).
337
+ * @param language_ranges - One or more language codes or ranges to filter the versions (required).
337
338
  * @param license_id - Optional license ID to filter versions by license.
338
339
  * @returns A promise that resolves to a collection of BibleVersion objects.
339
340
  */
340
- getVersions(language_ranges: string, license_id?: string | number): Promise<Collection<BibleVersion>>;
341
+ getVersions(language_ranges: string | string[], license_id?: string | number): Promise<Collection<BibleVersion>>;
341
342
  /**
342
343
  * Fetches a Bible version by its ID.
343
344
  * @param id The version ID.
@@ -449,7 +450,7 @@ declare class BibleClient {
449
450
  type GetLanguagesOptions = {
450
451
  page_size?: number;
451
452
  page_token?: string;
452
- country: string;
453
+ country?: string;
453
454
  };
454
455
  /**
455
456
  * Client for interacting with Languages API endpoints.
@@ -465,10 +466,10 @@ declare class LanguagesClient {
465
466
  constructor(client: ApiClient);
466
467
  /**
467
468
  * Fetches a collection of languages supported in the Platform.
468
- * @param options Query parameters for pagination and filtering (country is required).
469
+ * @param options Query parameters for pagination and filtering.
469
470
  * @returns A collection of Language objects.
470
471
  */
471
- getLanguages(options: GetLanguagesOptions): Promise<Collection<Language>>;
472
+ getLanguages(options?: GetLanguagesOptions): Promise<Collection<Language>>;
472
473
  /**
473
474
  * Fetches details about a specific language in the Platform.
474
475
  * @param languageId The BCP 47 language code (optionally including script, e.g., "en" or "sr-Latn").
package/dist/index.d.ts CHANGED
@@ -258,7 +258,8 @@ interface HighlightColor {
258
258
  label: string;
259
259
  }
260
260
 
261
- type QueryParams = Record<string, string | number | boolean>;
261
+ type PrimitiveQueryParam = string | number | boolean;
262
+ type QueryParams = Record<string, PrimitiveQueryParam | PrimitiveQueryParam[]>;
262
263
  type RequestData = Record<string, string | number | boolean | object>;
263
264
  type RequestHeaders = Record<string, string>;
264
265
  /**
@@ -333,11 +334,11 @@ declare class BibleClient {
333
334
  /**
334
335
  * Fetches a collection of Bible versions filtered by language ranges.
335
336
  *
336
- * @param language_ranges - A comma-separated list of language codes or ranges to filter the versions (required).
337
+ * @param language_ranges - One or more language codes or ranges to filter the versions (required).
337
338
  * @param license_id - Optional license ID to filter versions by license.
338
339
  * @returns A promise that resolves to a collection of BibleVersion objects.
339
340
  */
340
- getVersions(language_ranges: string, license_id?: string | number): Promise<Collection<BibleVersion>>;
341
+ getVersions(language_ranges: string | string[], license_id?: string | number): Promise<Collection<BibleVersion>>;
341
342
  /**
342
343
  * Fetches a Bible version by its ID.
343
344
  * @param id The version ID.
@@ -449,7 +450,7 @@ declare class BibleClient {
449
450
  type GetLanguagesOptions = {
450
451
  page_size?: number;
451
452
  page_token?: string;
452
- country: string;
453
+ country?: string;
453
454
  };
454
455
  /**
455
456
  * Client for interacting with Languages API endpoints.
@@ -465,10 +466,10 @@ declare class LanguagesClient {
465
466
  constructor(client: ApiClient);
466
467
  /**
467
468
  * Fetches a collection of languages supported in the Platform.
468
- * @param options Query parameters for pagination and filtering (country is required).
469
+ * @param options Query parameters for pagination and filtering.
469
470
  * @returns A collection of Language objects.
470
471
  */
471
- getLanguages(options: GetLanguagesOptions): Promise<Collection<Language>>;
472
+ getLanguages(options?: GetLanguagesOptions): Promise<Collection<Language>>;
472
473
  /**
473
474
  * Fetches details about a specific language in the Platform.
474
475
  * @param languageId The BCP 47 language code (optionally including script, e.g., "en" or "sr-Latn").
package/dist/index.js CHANGED
@@ -30,9 +30,15 @@ var ApiClient = class {
30
30
  */
31
31
  buildQueryString(params) {
32
32
  if (!params) return "";
33
- const queryString = new URLSearchParams(
34
- Object.entries(params).map(([key, value]) => [key, String(value)])
35
- ).toString();
33
+ const searchParams = new URLSearchParams();
34
+ Object.entries(params).forEach(([key, value]) => {
35
+ if (Array.isArray(value)) {
36
+ value.forEach((item) => searchParams.append(key, String(item)));
37
+ } else {
38
+ searchParams.append(key, String(value));
39
+ }
40
+ });
41
+ const queryString = searchParams.toString();
36
42
  return queryString ? `?${queryString}` : "";
37
43
  }
38
44
  /**
@@ -166,14 +172,15 @@ var BibleClient = class {
166
172
  /**
167
173
  * Fetches a collection of Bible versions filtered by language ranges.
168
174
  *
169
- * @param language_ranges - A comma-separated list of language codes or ranges to filter the versions (required).
175
+ * @param language_ranges - One or more language codes or ranges to filter the versions (required).
170
176
  * @param license_id - Optional license ID to filter versions by license.
171
177
  * @returns A promise that resolves to a collection of BibleVersion objects.
172
178
  */
173
179
  async getVersions(language_ranges, license_id) {
174
- this.languageRangesSchema.parse(language_ranges);
180
+ const languageRangeArray = Array.isArray(language_ranges) ? language_ranges : [language_ranges];
181
+ const parsedLanguageRanges = z.array(this.languageRangesSchema).nonempty("At least one language range is required").parse(languageRangeArray);
175
182
  const params = {
176
- "language_ranges[]": language_ranges
183
+ "language_ranges[]": parsedLanguageRanges
177
184
  };
178
185
  if (license_id !== void 0) {
179
186
  params.license_id = license_id;
@@ -370,13 +377,15 @@ var LanguagesClient = class {
370
377
  }
371
378
  /**
372
379
  * Fetches a collection of languages supported in the Platform.
373
- * @param options Query parameters for pagination and filtering (country is required).
380
+ * @param options Query parameters for pagination and filtering.
374
381
  * @returns A collection of Language objects.
375
382
  */
376
- async getLanguages(options) {
383
+ async getLanguages(options = {}) {
377
384
  const params = {};
378
- const country = this.countrySchema.parse(options.country);
379
- params.country = country;
385
+ if (options.country !== void 0) {
386
+ const country = this.countrySchema.parse(options.country);
387
+ params.country = country;
388
+ }
380
389
  if (options.page_size !== void 0) {
381
390
  const pageSizeSchema = z2.number().int().positive();
382
391
  pageSizeSchema.parse(options.page_size);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@youversion/platform-core",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -76,8 +76,8 @@ export const mockLanguages: Language[] = [
76
76
  speaking_population: 8000000,
77
77
  default_bible_version_id: null,
78
78
  },
79
- // Add more languages to reach 25 for default page size when filtering by 'US'
80
- ...Array.from({ length: 24 }, (_, i) => ({
79
+ // Add more languages to exceed the maximum page size and exercise pagination
80
+ ...Array.from({ length: 120 }, (_, i) => ({
81
81
  id: `lang${i + 1}`,
82
82
  language: `lang${i + 1}`,
83
83
  script: 'Latn',
@@ -86,7 +86,7 @@ export const mockLanguages: Language[] = [
86
86
  display_names: {},
87
87
  scripts: ['Latn'],
88
88
  variants: [],
89
- countries: ['US'],
89
+ countries: i % 2 === 0 ? ['US', 'CA'] : ['BR'],
90
90
  text_direction: 'ltr' as const,
91
91
  writing_population: 1000000,
92
92
  speaking_population: 1000000,
@@ -1,4 +1,5 @@
1
1
  import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { http, HttpResponse } from 'msw';
2
3
  import { ApiClient } from '../client';
3
4
  import { BibleClient } from '../bible';
4
5
  import {
@@ -9,6 +10,8 @@ import {
9
10
  BibleVersionSchema,
10
11
  VOTDSchema,
11
12
  } from '../schemas';
13
+ import { server } from './setup';
14
+ import { mockVersions } from './MockVersions';
12
15
 
13
16
  describe('BibleClient', () => {
14
17
  let apiClient: ApiClient;
@@ -34,6 +37,50 @@ describe('BibleClient', () => {
34
37
  expect(hasNIV).toBe(true);
35
38
  });
36
39
 
40
+ it('should send multiple language ranges when provided', async () => {
41
+ server.use(
42
+ http.get('https://api.youversion.com/v1/bibles', ({ request }) => {
43
+ const url = new URL(request.url);
44
+ const languageRanges = url.searchParams.getAll('language_ranges[]');
45
+
46
+ expect(languageRanges).toEqual(['en*', 'es*']);
47
+
48
+ return HttpResponse.json({
49
+ data: mockVersions,
50
+ next_page_token: null,
51
+ total_size: mockVersions.length,
52
+ });
53
+ }),
54
+ );
55
+
56
+ const versions = await bibleClient.getVersions(['en*', 'es*']);
57
+
58
+ const { success } = BibleVersionSchema.safeParse(versions.data[0]);
59
+ expect(success).toBe(true);
60
+ });
61
+
62
+ it('should accept a wildcard language range', async () => {
63
+ server.use(
64
+ http.get('https://api.youversion.com/v1/bibles', ({ request }) => {
65
+ const url = new URL(request.url);
66
+ const languageRanges = url.searchParams.getAll('language_ranges[]');
67
+
68
+ expect(languageRanges).toEqual(['*']);
69
+
70
+ return HttpResponse.json({
71
+ data: mockVersions,
72
+ next_page_token: null,
73
+ total_size: mockVersions.length,
74
+ });
75
+ }),
76
+ );
77
+
78
+ const versions = await bibleClient.getVersions('*');
79
+
80
+ const { success } = BibleVersionSchema.safeParse(versions.data[0]);
81
+ expect(success).toBe(true);
82
+ });
83
+
37
84
  it('should throw an error for invalid language ranges', async () => {
38
85
  await expect(bibleClient.getVersions('')).rejects.toThrow(
39
86
  'Language ranges must be a non-empty string',
@@ -41,6 +88,9 @@ describe('BibleClient', () => {
41
88
  await expect(bibleClient.getVersions(' ')).rejects.toThrow(
42
89
  'Language ranges must be a non-empty string',
43
90
  );
91
+ await expect(bibleClient.getVersions([])).rejects.toThrow(
92
+ 'At least one language range is required',
93
+ );
44
94
  });
45
95
  });
46
96
 
@@ -43,6 +43,45 @@ describe('ApiClient', () => {
43
43
  });
44
44
  });
45
45
 
46
+ describe('buildQueryString', () => {
47
+ const buildQueryString = (params?: Parameters<ApiClient['get']>[1]) =>
48
+ (
49
+ apiClient as unknown as {
50
+ buildQueryString: (params?: Parameters<ApiClient['get']>[1]) => string;
51
+ }
52
+ ).buildQueryString(params);
53
+
54
+ it('should serialize single scalar parameter', () => {
55
+ const query = buildQueryString({ param: 'value' });
56
+
57
+ expect(query).toBe('?param=value');
58
+ });
59
+
60
+ it('should serialize an array of length 1 as repeated key', () => {
61
+ const query = buildQueryString({ param: ['only'] });
62
+
63
+ expect(query).toBe('?param=only');
64
+ });
65
+
66
+ it('should serialize an array of length 2 as repeated keys', () => {
67
+ const query = buildQueryString({ param: ['one', 'two'] });
68
+
69
+ expect(query).toBe('?param=one&param=two');
70
+ });
71
+
72
+ it('should serialize an array of length 3 as repeated keys', () => {
73
+ const query = buildQueryString({ param: ['one', 'two', 'three'] });
74
+
75
+ expect(query).toBe('?param=one&param=two&param=three');
76
+ });
77
+
78
+ it('should handle both scalar and array parameters together', () => {
79
+ const query = buildQueryString({ param: 'value', list: ['one', 'two'] });
80
+
81
+ expect(query).toBe('?param=value&list=one&list=two');
82
+ });
83
+ });
84
+
46
85
  describe('get', () => {
47
86
  it('should make GET request and return data', async () => {
48
87
  server.use(
@@ -71,6 +110,22 @@ describe('ApiClient', () => {
71
110
 
72
111
  expect(result).toEqual({ param: 'value' });
73
112
  });
113
+
114
+ it('should include array query parameters as repeated keys', async () => {
115
+ server.use(
116
+ http.get('https://test_placeholder.youversion.com/test', ({ request }) => {
117
+ const url = new URL(request.url);
118
+ const params = url.searchParams.getAll('param');
119
+ return HttpResponse.json({ params });
120
+ }),
121
+ );
122
+
123
+ const result = await apiClient.get<{ params: string[] }>('/test', {
124
+ param: ['one', 'two'],
125
+ });
126
+
127
+ expect(result).toEqual({ params: ['one', 'two'] });
128
+ });
74
129
  });
75
130
 
76
131
  describe('post', () => {
@@ -1,6 +1,6 @@
1
1
  import { http, HttpResponse } from 'msw';
2
2
  import type { Collection, Highlight, Language } from '../types';
3
- import { mockLanguages } from './MockLangauges';
3
+ import { mockLanguages } from './MockLanguages';
4
4
  import { mockVersions, mockVersionKJV } from './MockVersions';
5
5
  import { mockBibleGenesis, mockBibleBooks } from './MockBibles';
6
6
  import { mockChapterGenesis1, mockGenesisChapters } from './MockChapters';
@@ -17,22 +17,23 @@ describe('LanguagesClient', () => {
17
17
  });
18
18
 
19
19
  describe('getLanguages', () => {
20
- it('should fetch languages with required country param', async () => {
21
- const languages = await languagesClient.getLanguages({ country: 'US' });
20
+ it('should fetch languages without country filter', async () => {
21
+ const languages = await languagesClient.getLanguages({ page_size: 99 });
22
22
 
23
23
  const { success } = LanguageSchema.safeParse(languages.data[0]);
24
24
  expect(success).toBe(true);
25
- expect(languages.data).toHaveLength(25);
26
- expect(languages.data[0]).toHaveProperty('countries', expect.arrayContaining(['US']));
25
+ expect(languages.data).toHaveLength(99);
26
+ expect(languages.next_page_token).not.toBeNull();
27
27
  });
28
28
 
29
- it('should fetch languages with page_size option', async () => {
30
- const languages = await languagesClient.getLanguages({ country: 'US', page_size: 10 });
29
+ it('should fetch languages with country filter', async () => {
30
+ const languages = await languagesClient.getLanguages({ country: 'US', page_size: 20 });
31
31
 
32
32
  const { success } = LanguageSchema.safeParse(languages.data[0]);
33
33
  expect(success).toBe(true);
34
- expect(languages.data).toHaveLength(10);
35
- expect(languages.next_page_token).toBe('eyJzdGFydCI6IDEwfQ==');
34
+ expect(languages.data).toHaveLength(20);
35
+ expect(languages.data.every((language) => language.countries?.includes('US'))).toBe(true);
36
+ expect(languages.next_page_token).not.toBeNull();
36
37
  });
37
38
 
38
39
  it('should throw an error for invalid country code - empty string', async () => {
package/src/bible.ts CHANGED
@@ -50,17 +50,23 @@ export class BibleClient {
50
50
  /**
51
51
  * Fetches a collection of Bible versions filtered by language ranges.
52
52
  *
53
- * @param language_ranges - A comma-separated list of language codes or ranges to filter the versions (required).
53
+ * @param language_ranges - One or more language codes or ranges to filter the versions (required).
54
54
  * @param license_id - Optional license ID to filter versions by license.
55
55
  * @returns A promise that resolves to a collection of BibleVersion objects.
56
56
  */
57
57
  async getVersions(
58
- language_ranges: string,
58
+ language_ranges: string | string[],
59
59
  license_id?: string | number,
60
60
  ): Promise<Collection<BibleVersion>> {
61
- this.languageRangesSchema.parse(language_ranges);
62
- const params: Record<string, string | number> = {
63
- 'language_ranges[]': language_ranges,
61
+ const languageRangeArray = Array.isArray(language_ranges) ? language_ranges : [language_ranges];
62
+
63
+ const parsedLanguageRanges = z
64
+ .array(this.languageRangesSchema)
65
+ .nonempty('At least one language range is required')
66
+ .parse(languageRangeArray);
67
+
68
+ const params: Record<string, string | number | string[]> = {
69
+ 'language_ranges[]': parsedLanguageRanges,
64
70
  };
65
71
  if (license_id !== undefined) {
66
72
  params.license_id = license_id;
package/src/client.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { ApiConfig } from './types';
2
2
 
3
- type QueryParams = Record<string, string | number | boolean>;
3
+ type PrimitiveQueryParam = string | number | boolean;
4
+ type QueryParams = Record<string, PrimitiveQueryParam | PrimitiveQueryParam[]>;
4
5
  type RequestData = Record<string, string | number | boolean | object>;
5
6
  type RequestHeaders = Record<string, string>;
6
7
 
@@ -41,9 +42,18 @@ export class ApiClient {
41
42
  */
42
43
  private buildQueryString(params?: QueryParams): string {
43
44
  if (!params) return '';
44
- const queryString = new URLSearchParams(
45
- Object.entries(params).map(([key, value]) => [key, String(value)]),
46
- ).toString();
45
+
46
+ const searchParams = new URLSearchParams();
47
+
48
+ Object.entries(params).forEach(([key, value]) => {
49
+ if (Array.isArray(value)) {
50
+ value.forEach((item) => searchParams.append(key, String(item)));
51
+ } else {
52
+ searchParams.append(key, String(value));
53
+ }
54
+ });
55
+
56
+ const queryString = searchParams.toString();
47
57
  return queryString ? `?${queryString}` : '';
48
58
  }
49
59
 
package/src/languages.ts CHANGED
@@ -8,7 +8,7 @@ import type { Collection, Language } from './types';
8
8
  export type GetLanguagesOptions = {
9
9
  page_size?: number;
10
10
  page_token?: string;
11
- country: string; // ISO 3166-1 alpha-2 country code (required per OpenAPI spec)
11
+ country?: string; // ISO 3166-1 alpha-2 country code
12
12
  };
13
13
 
14
14
  /**
@@ -41,15 +41,16 @@ export class LanguagesClient {
41
41
 
42
42
  /**
43
43
  * Fetches a collection of languages supported in the Platform.
44
- * @param options Query parameters for pagination and filtering (country is required).
44
+ * @param options Query parameters for pagination and filtering.
45
45
  * @returns A collection of Language objects.
46
46
  */
47
- async getLanguages(options: GetLanguagesOptions): Promise<Collection<Language>> {
47
+ async getLanguages(options: GetLanguagesOptions = {}): Promise<Collection<Language>> {
48
48
  const params: Record<string, string | number> = {};
49
49
 
50
- // Country is required per OpenAPI spec
51
- const country = this.countrySchema.parse(options.country);
52
- params.country = country;
50
+ if (options.country !== undefined) {
51
+ const country = this.countrySchema.parse(options.country);
52
+ params.country = country;
53
+ }
53
54
 
54
55
  if (options.page_size !== undefined) {
55
56
  const pageSizeSchema = z.number().int().positive();