@youversion/platform-core 0.4.3 → 0.5.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.
- package/.env.example +1 -1
- package/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +12 -0
- package/dist/index.cjs +2 -4
- package/dist/index.js +2 -4
- package/package.json +1 -1
- package/src/__tests__/MockLangauges.ts +95 -0
- package/src/__tests__/authentication.test.ts +1 -0
- package/src/__tests__/bible.test.ts +1 -0
- package/src/__tests__/handlers.ts +50 -1
- package/src/__tests__/highlights.test.ts +1 -0
- package/src/__tests__/languages.test.ts +1 -33
- package/src/client.ts +2 -4
package/.env.example
CHANGED
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @youversion/platform-core@0.
|
|
2
|
+
> @youversion/platform-core@0.5.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
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
[34mCLI[39m Target: es2022
|
|
9
9
|
[34mCJS[39m Build start
|
|
10
10
|
[34mESM[39m Build start
|
|
11
|
-
[32mESM[39m [1mdist/index.js [22m[32m37.
|
|
11
|
+
[32mESM[39m [1mdist/index.js [22m[32m37.59 KB[39m
|
|
12
12
|
[32mESM[39m ⚡️ Build success in 37ms
|
|
13
|
-
[32mCJS[39m [1mdist/index.cjs [22m[32m39.
|
|
13
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m39.59 KB[39m
|
|
14
14
|
[32mCJS[39m ⚡️ Build success in 37ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 2331ms
|
|
17
17
|
[32mDTS[39m [1mdist/index.d.cts [22m[32m34.08 KB[39m
|
|
18
18
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m34.08 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @youversion/platform-core
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e07208d: feat(ui): add share button to verse of the day component
|
|
8
|
+
|
|
9
|
+
## 0.4.4
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 8dee8f6: chore: allow setting apiHost from React code
|
|
14
|
+
|
|
3
15
|
## 0.4.3
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -56,11 +56,9 @@ var ApiClient = class {
|
|
|
56
56
|
this.config = {
|
|
57
57
|
...config
|
|
58
58
|
};
|
|
59
|
-
const apiHost = config.apiHost
|
|
59
|
+
const apiHost = config.apiHost || "api.youversion.com";
|
|
60
60
|
if (!apiHost) {
|
|
61
|
-
throw new Error(
|
|
62
|
-
"ApiClient requires a host name. Provide an apiHost in the config or set the YVP_API_HOST environment variable."
|
|
63
|
-
);
|
|
61
|
+
throw new Error("ApiClient requires a host name. Provide an apiHost in the config.");
|
|
64
62
|
}
|
|
65
63
|
this.baseURL = "https://" + apiHost;
|
|
66
64
|
this.timeout = config.timeout || 1e4;
|
package/dist/index.js
CHANGED
|
@@ -13,11 +13,9 @@ var ApiClient = class {
|
|
|
13
13
|
this.config = {
|
|
14
14
|
...config
|
|
15
15
|
};
|
|
16
|
-
const apiHost = config.apiHost
|
|
16
|
+
const apiHost = config.apiHost || "api.youversion.com";
|
|
17
17
|
if (!apiHost) {
|
|
18
|
-
throw new Error(
|
|
19
|
-
"ApiClient requires a host name. Provide an apiHost in the config or set the YVP_API_HOST environment variable."
|
|
20
|
-
);
|
|
18
|
+
throw new Error("ApiClient requires a host name. Provide an apiHost in the config.");
|
|
21
19
|
}
|
|
22
20
|
this.baseURL = "https://" + apiHost;
|
|
23
21
|
this.timeout = config.timeout || 1e4;
|
package/package.json
CHANGED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { Language } from '../types';
|
|
2
|
+
|
|
3
|
+
export const mockLanguages: Language[] = [
|
|
4
|
+
{
|
|
5
|
+
id: 'en',
|
|
6
|
+
language: 'en',
|
|
7
|
+
script: 'Latn',
|
|
8
|
+
script_name: 'Latin',
|
|
9
|
+
aliases: ['eng'],
|
|
10
|
+
display_names: { en: 'English' },
|
|
11
|
+
scripts: ['Latn'],
|
|
12
|
+
variants: [],
|
|
13
|
+
countries: ['US', 'GB', 'CA', 'AU'],
|
|
14
|
+
text_direction: 'ltr',
|
|
15
|
+
writing_population: 1500000000,
|
|
16
|
+
speaking_population: 1500000000,
|
|
17
|
+
default_bible_version_id: null,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 'es',
|
|
21
|
+
language: 'es',
|
|
22
|
+
script: 'Latn',
|
|
23
|
+
script_name: 'Latin',
|
|
24
|
+
aliases: ['spa'],
|
|
25
|
+
display_names: { en: 'Spanish', es: 'español' },
|
|
26
|
+
scripts: ['Latn'],
|
|
27
|
+
variants: [],
|
|
28
|
+
countries: ['ES', 'MX', 'AR', 'CO'],
|
|
29
|
+
text_direction: 'ltr',
|
|
30
|
+
writing_population: 500000000,
|
|
31
|
+
speaking_population: 500000000,
|
|
32
|
+
default_bible_version_id: null,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'fr',
|
|
36
|
+
language: 'fr',
|
|
37
|
+
script: 'Latn',
|
|
38
|
+
script_name: 'Latin',
|
|
39
|
+
aliases: ['fra', 'fre'],
|
|
40
|
+
display_names: { en: 'French', fr: 'français' },
|
|
41
|
+
scripts: ['Latn'],
|
|
42
|
+
variants: [],
|
|
43
|
+
countries: ['FR', 'CA', 'BE', 'CH'],
|
|
44
|
+
text_direction: 'ltr',
|
|
45
|
+
writing_population: 300000000,
|
|
46
|
+
speaking_population: 300000000,
|
|
47
|
+
default_bible_version_id: null,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 'de',
|
|
51
|
+
language: 'de',
|
|
52
|
+
script: 'Latn',
|
|
53
|
+
script_name: 'Latin',
|
|
54
|
+
aliases: ['deu', 'ger'],
|
|
55
|
+
display_names: { en: 'German', de: 'Deutsch' },
|
|
56
|
+
scripts: ['Latn'],
|
|
57
|
+
variants: [],
|
|
58
|
+
countries: ['DE', 'AT', 'CH'],
|
|
59
|
+
text_direction: 'ltr',
|
|
60
|
+
writing_population: 100000000,
|
|
61
|
+
speaking_population: 100000000,
|
|
62
|
+
default_bible_version_id: null,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'sr-Latn',
|
|
66
|
+
language: 'sr',
|
|
67
|
+
script: 'Latn',
|
|
68
|
+
script_name: 'latinica',
|
|
69
|
+
aliases: ['srp'],
|
|
70
|
+
display_names: { en: 'Serbian (Latin)', sr: 'srpski' },
|
|
71
|
+
scripts: ['Latn', 'Cyrl'],
|
|
72
|
+
variants: [],
|
|
73
|
+
countries: ['RS', 'BA', 'ME'],
|
|
74
|
+
text_direction: 'ltr',
|
|
75
|
+
writing_population: 8000000,
|
|
76
|
+
speaking_population: 8000000,
|
|
77
|
+
default_bible_version_id: null,
|
|
78
|
+
},
|
|
79
|
+
// Add more languages to reach 25 for default page size when filtering by 'US'
|
|
80
|
+
...Array.from({ length: 24 }, (_, i) => ({
|
|
81
|
+
id: `lang${i + 1}`,
|
|
82
|
+
language: `lang${i + 1}`,
|
|
83
|
+
script: 'Latn',
|
|
84
|
+
script_name: null,
|
|
85
|
+
aliases: [],
|
|
86
|
+
display_names: {},
|
|
87
|
+
scripts: ['Latn'],
|
|
88
|
+
variants: [],
|
|
89
|
+
countries: ['US'],
|
|
90
|
+
text_direction: 'ltr' as const,
|
|
91
|
+
writing_population: 1000000,
|
|
92
|
+
speaking_population: 1000000,
|
|
93
|
+
default_bible_version_id: null,
|
|
94
|
+
})),
|
|
95
|
+
];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { http, HttpResponse } from 'msw';
|
|
2
|
-
import type { Collection, Highlight } from '../types';
|
|
2
|
+
import type { Collection, Highlight, Language } from '../types';
|
|
3
|
+
import { mockLanguages } from './MockLangauges';
|
|
3
4
|
|
|
4
5
|
const apiHost = process.env.YVP_API_HOST;
|
|
5
6
|
if (!apiHost) {
|
|
@@ -7,6 +8,54 @@ if (!apiHost) {
|
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
export const handlers = [
|
|
11
|
+
// Languages endpoints
|
|
12
|
+
http.get(`https://${apiHost}/v1/languages/:languageId`, ({ params }) => {
|
|
13
|
+
const { languageId } = params;
|
|
14
|
+
const language = mockLanguages.find((lang) => lang.id === languageId);
|
|
15
|
+
|
|
16
|
+
if (!language) {
|
|
17
|
+
return new HttpResponse(null, { status: 404 });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return HttpResponse.json(language);
|
|
21
|
+
}),
|
|
22
|
+
|
|
23
|
+
http.get(`https://${apiHost}/v1/languages`, ({ request }) => {
|
|
24
|
+
const url = new URL(request.url);
|
|
25
|
+
const country = url.searchParams.get('country');
|
|
26
|
+
const pageSize = url.searchParams.get('page_size');
|
|
27
|
+
const pageToken = url.searchParams.get('page_token');
|
|
28
|
+
|
|
29
|
+
const filteredLanguages = country
|
|
30
|
+
? mockLanguages.filter((lang) => lang.countries?.includes(country))
|
|
31
|
+
: mockLanguages;
|
|
32
|
+
|
|
33
|
+
const defaultPageSize = 25;
|
|
34
|
+
const size = pageSize ? parseInt(pageSize, 10) : defaultPageSize;
|
|
35
|
+
let start = 0;
|
|
36
|
+
|
|
37
|
+
if (pageToken) {
|
|
38
|
+
try {
|
|
39
|
+
const decoded = JSON.parse(atob(pageToken)) as { start?: number };
|
|
40
|
+
start = decoded.start || 0;
|
|
41
|
+
} catch {
|
|
42
|
+
start = 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const end = start + size;
|
|
47
|
+
const paginatedLanguages = filteredLanguages.slice(start, end);
|
|
48
|
+
const hasMore = end < filteredLanguages.length;
|
|
49
|
+
|
|
50
|
+
const response: Collection<Language> = {
|
|
51
|
+
data: paginatedLanguages,
|
|
52
|
+
next_page_token: hasMore ? btoa(`{"start": ${end}}`) : null,
|
|
53
|
+
total_size: filteredLanguages.length,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return HttpResponse.json(response);
|
|
57
|
+
}),
|
|
58
|
+
|
|
10
59
|
// Highlights endpoints
|
|
11
60
|
http.get(`https://${apiHost}/v1/highlights`, ({ request }) => {
|
|
12
61
|
const url = new URL(request.url);
|
|
@@ -9,6 +9,7 @@ describe('LanguagesClient', () => {
|
|
|
9
9
|
|
|
10
10
|
beforeEach(() => {
|
|
11
11
|
apiClient = new ApiClient({
|
|
12
|
+
apiHost: process.env.YVP_API_HOST || '',
|
|
12
13
|
appKey: process.env.YVP_APP_KEY || '',
|
|
13
14
|
installationId: 'test-installation',
|
|
14
15
|
});
|
|
@@ -34,23 +35,6 @@ describe('LanguagesClient', () => {
|
|
|
34
35
|
expect(languages.next_page_token).toBe('eyJzdGFydCI6IDEwfQ==');
|
|
35
36
|
});
|
|
36
37
|
|
|
37
|
-
it('should fetch languages with page_token option', async () => {
|
|
38
|
-
const languages = await languagesClient.getLanguages({
|
|
39
|
-
country: 'US',
|
|
40
|
-
page_token: 'eyJzdGFydCI6IDEwMH0=',
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const { success } = LanguageSchema.safeParse(languages.data[0]);
|
|
44
|
-
expect(success).toBe(true);
|
|
45
|
-
expect(languages.data).toHaveLength(25);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('should uppercase country code', async () => {
|
|
49
|
-
const languages = await languagesClient.getLanguages({ country: 'us' });
|
|
50
|
-
|
|
51
|
-
expect(languages.data[0]?.countries).toContain('US');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
38
|
it('should throw an error for invalid country code - empty string', async () => {
|
|
55
39
|
await expect(languagesClient.getLanguages({ country: '' })).rejects.toThrow(
|
|
56
40
|
'Country code must be a 2-character ISO 3166-1 alpha-2 code',
|
|
@@ -71,22 +55,6 @@ describe('LanguagesClient', () => {
|
|
|
71
55
|
'Country code must be a 2-character ISO 3166-1 alpha-2 code',
|
|
72
56
|
);
|
|
73
57
|
});
|
|
74
|
-
|
|
75
|
-
it('should throw an error for invalid page_size - zero', async () => {
|
|
76
|
-
await expect(languagesClient.getLanguages({ country: 'US', page_size: 0 })).rejects.toThrow();
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('should throw an error for invalid page_size - negative', async () => {
|
|
80
|
-
await expect(
|
|
81
|
-
languagesClient.getLanguages({ country: 'US', page_size: -1 }),
|
|
82
|
-
).rejects.toThrow();
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('should throw an error for invalid page_size - non-integer', async () => {
|
|
86
|
-
await expect(
|
|
87
|
-
languagesClient.getLanguages({ country: 'US', page_size: 1.5 }),
|
|
88
|
-
).rejects.toThrow();
|
|
89
|
-
});
|
|
90
58
|
});
|
|
91
59
|
|
|
92
60
|
describe('getLanguage', () => {
|
package/src/client.ts
CHANGED
|
@@ -23,11 +23,9 @@ export class ApiClient {
|
|
|
23
23
|
this.config = {
|
|
24
24
|
...config,
|
|
25
25
|
};
|
|
26
|
-
const apiHost = config.apiHost
|
|
26
|
+
const apiHost = config.apiHost || 'api.youversion.com';
|
|
27
27
|
if (!apiHost) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
'ApiClient requires a host name. Provide an apiHost in the config or set the YVP_API_HOST environment variable.',
|
|
30
|
-
);
|
|
28
|
+
throw new Error('ApiClient requires a host name. Provide an apiHost in the config.');
|
|
31
29
|
}
|
|
32
30
|
this.baseURL = 'https://' + apiHost;
|
|
33
31
|
this.timeout = config.timeout || 10000;
|