@youversion/platform-core 0.4.1 → 0.4.3
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 +3 -5
- package/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +12 -0
- package/README.md +62 -322
- package/dist/index.cjs +44 -51
- package/dist/index.d.cts +7 -12
- package/dist/index.d.ts +7 -12
- package/dist/index.js +44 -51
- package/package.json +1 -1
- package/src/URLBuilder.ts +4 -4
- package/src/Users.ts +4 -4
- package/src/YouVersionAPI.ts +4 -6
- package/src/YouVersionPlatformConfiguration.ts +6 -6
- package/src/__tests__/URLBuilder.test.ts +34 -30
- package/src/__tests__/YouVersionPlatformConfiguration.test.ts +22 -13
- package/src/__tests__/authentication.test.ts +1 -3
- package/src/__tests__/bible.test.ts +1 -3
- package/src/__tests__/client.test.ts +12 -16
- package/src/__tests__/handlers.ts +7 -4
- package/src/__tests__/highlights.test.ts +1 -3
- package/src/__tests__/languages.test.ts +1 -3
- package/src/bible.ts +12 -19
- package/src/client.ts +9 -4
- package/src/highlights.ts +3 -7
- package/src/languages.ts +2 -6
- package/src/types/api-config.ts +2 -4
- package/.env.local +0 -10
|
@@ -8,40 +8,36 @@ describe('ApiClient', () => {
|
|
|
8
8
|
|
|
9
9
|
beforeEach(() => {
|
|
10
10
|
apiClient = new ApiClient({
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
version: 'v1',
|
|
11
|
+
apiHost: 'test_placeholder.youversion.com',
|
|
12
|
+
appKey: 'test-app',
|
|
14
13
|
installationId: 'test-installation',
|
|
15
14
|
});
|
|
16
15
|
});
|
|
17
16
|
|
|
18
17
|
describe('constructor', () => {
|
|
19
|
-
it('should set
|
|
18
|
+
it('should set remember the appKey', () => {
|
|
20
19
|
const client = new ApiClient({
|
|
21
|
-
|
|
22
|
-
appId: 'test-app',
|
|
20
|
+
appKey: 'test-app1',
|
|
23
21
|
installationId: 'test-installation',
|
|
24
22
|
});
|
|
25
23
|
|
|
26
|
-
expect(client.config.
|
|
24
|
+
expect(client.config.appKey).toBe('test-app1');
|
|
27
25
|
});
|
|
28
26
|
|
|
29
|
-
it('should use provided
|
|
27
|
+
it('should use provided appKey', () => {
|
|
30
28
|
const client = new ApiClient({
|
|
31
|
-
|
|
32
|
-
appId: 'test-app',
|
|
33
|
-
version: 'v2',
|
|
29
|
+
appKey: 'test-app2',
|
|
34
30
|
installationId: 'test-installation',
|
|
35
31
|
});
|
|
36
32
|
|
|
37
|
-
expect(client.config.
|
|
33
|
+
expect(client.config.appKey).toBe('test-app2');
|
|
38
34
|
});
|
|
39
35
|
});
|
|
40
36
|
|
|
41
37
|
describe('get', () => {
|
|
42
38
|
it('should make GET request and return data', async () => {
|
|
43
39
|
server.use(
|
|
44
|
-
http.get('https://
|
|
40
|
+
http.get('https://test_placeholder.youversion.com/test', () => {
|
|
45
41
|
return HttpResponse.json({ message: 'success' });
|
|
46
42
|
}),
|
|
47
43
|
);
|
|
@@ -53,7 +49,7 @@ describe('ApiClient', () => {
|
|
|
53
49
|
|
|
54
50
|
it('should include query parameters', async () => {
|
|
55
51
|
server.use(
|
|
56
|
-
http.get('https://
|
|
52
|
+
http.get('https://test_placeholder.youversion.com/test', ({ request }) => {
|
|
57
53
|
const url = new URL(request.url);
|
|
58
54
|
const param = url.searchParams.get('param');
|
|
59
55
|
return HttpResponse.json({ param });
|
|
@@ -71,7 +67,7 @@ describe('ApiClient', () => {
|
|
|
71
67
|
describe('post', () => {
|
|
72
68
|
it('should make POST request and return data', async () => {
|
|
73
69
|
server.use(
|
|
74
|
-
http.post('https://
|
|
70
|
+
http.post('https://test_placeholder.youversion.com/test', async ({ request }) => {
|
|
75
71
|
const body = await request.json();
|
|
76
72
|
return HttpResponse.json({ received: body });
|
|
77
73
|
}),
|
|
@@ -86,7 +82,7 @@ describe('ApiClient', () => {
|
|
|
86
82
|
|
|
87
83
|
it('should include query parameters in POST request', async () => {
|
|
88
84
|
server.use(
|
|
89
|
-
http.post('https://
|
|
85
|
+
http.post('https://test_placeholder.youversion.com/test', async ({ request }) => {
|
|
90
86
|
const url = new URL(request.url);
|
|
91
87
|
const param = url.searchParams.get('param');
|
|
92
88
|
const body = await request.json();
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { http, HttpResponse } from 'msw';
|
|
2
2
|
import type { Collection, Highlight } from '../types';
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const apiHost = process.env.YVP_API_HOST;
|
|
5
|
+
if (!apiHost) {
|
|
6
|
+
throw new Error('YVP_API_HOST environment variable must be set to run handler tests.');
|
|
7
|
+
}
|
|
5
8
|
|
|
6
9
|
export const handlers = [
|
|
7
10
|
// Highlights endpoints
|
|
8
|
-
http.get(
|
|
11
|
+
http.get(`https://${apiHost}/v1/highlights`, ({ request }) => {
|
|
9
12
|
const url = new URL(request.url);
|
|
10
13
|
const bibleId = url.searchParams.get('version_id');
|
|
11
14
|
const passageId = url.searchParams.get('passage_id');
|
|
@@ -29,13 +32,13 @@ export const handlers = [
|
|
|
29
32
|
return HttpResponse.json(highlights);
|
|
30
33
|
}),
|
|
31
34
|
|
|
32
|
-
http.post(
|
|
35
|
+
http.post(`https://${apiHost}/v1/highlights`, async ({ request }) => {
|
|
33
36
|
const body = (await request.json()) as Highlight;
|
|
34
37
|
|
|
35
38
|
return HttpResponse.json(body, { status: 201 });
|
|
36
39
|
}),
|
|
37
40
|
|
|
38
|
-
http.delete(
|
|
41
|
+
http.delete(`https://${apiHost}/v1/highlights/:passageId`, () => {
|
|
39
42
|
return new HttpResponse(null, { status: 204 });
|
|
40
43
|
}),
|
|
41
44
|
];
|
|
@@ -9,9 +9,7 @@ describe('HighlightsClient', () => {
|
|
|
9
9
|
|
|
10
10
|
beforeEach(() => {
|
|
11
11
|
apiClient = new ApiClient({
|
|
12
|
-
|
|
13
|
-
appId: 'test-app',
|
|
14
|
-
version: 'v1',
|
|
12
|
+
appKey: 'test-app',
|
|
15
13
|
installationId: 'test-installation',
|
|
16
14
|
});
|
|
17
15
|
highlightsClient = new HighlightsClient(apiClient);
|
|
@@ -9,9 +9,7 @@ describe('LanguagesClient', () => {
|
|
|
9
9
|
|
|
10
10
|
beforeEach(() => {
|
|
11
11
|
apiClient = new ApiClient({
|
|
12
|
-
|
|
13
|
-
appId: process.env.YVP_APP_ID || '',
|
|
14
|
-
version: 'v1',
|
|
12
|
+
appKey: process.env.YVP_APP_KEY || '',
|
|
15
13
|
installationId: 'test-installation',
|
|
16
14
|
});
|
|
17
15
|
languagesClient = new LanguagesClient(apiClient);
|
package/src/bible.ts
CHANGED
|
@@ -47,10 +47,6 @@ export class BibleClient {
|
|
|
47
47
|
this.client = client;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
private get rootPath(): string {
|
|
51
|
-
return `/${this.client.config.version}`;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
50
|
/**
|
|
55
51
|
* Fetches a collection of Bible versions filtered by language ranges.
|
|
56
52
|
*
|
|
@@ -69,7 +65,7 @@ export class BibleClient {
|
|
|
69
65
|
if (license_id !== undefined) {
|
|
70
66
|
params.license_id = license_id;
|
|
71
67
|
}
|
|
72
|
-
return this.client.get<Collection<BibleVersion>>(
|
|
68
|
+
return this.client.get<Collection<BibleVersion>>(`/v1/bibles`, params);
|
|
73
69
|
}
|
|
74
70
|
|
|
75
71
|
/**
|
|
@@ -79,7 +75,7 @@ export class BibleClient {
|
|
|
79
75
|
*/
|
|
80
76
|
async getVersion(id: number): Promise<BibleVersion> {
|
|
81
77
|
this.versionIdSchema.parse(id);
|
|
82
|
-
return this.client.get<BibleVersion>(
|
|
78
|
+
return this.client.get<BibleVersion>(`/v1/bibles/${id}`);
|
|
83
79
|
}
|
|
84
80
|
|
|
85
81
|
/**
|
|
@@ -90,7 +86,7 @@ export class BibleClient {
|
|
|
90
86
|
*/
|
|
91
87
|
async getBooks(versionId: number, canon?: CANON): Promise<Collection<BibleBook>> {
|
|
92
88
|
this.versionIdSchema.parse(versionId);
|
|
93
|
-
return this.client.get<Collection<BibleBook>>(
|
|
89
|
+
return this.client.get<Collection<BibleBook>>(`/v1/bibles/${versionId}/books`, {
|
|
94
90
|
...(canon && { canon }),
|
|
95
91
|
});
|
|
96
92
|
}
|
|
@@ -104,7 +100,7 @@ export class BibleClient {
|
|
|
104
100
|
async getBook(versionId: number, book: string): Promise<BibleBook> {
|
|
105
101
|
this.versionIdSchema.parse(versionId);
|
|
106
102
|
this.bookSchema.parse(book);
|
|
107
|
-
return this.client.get<BibleBook>(
|
|
103
|
+
return this.client.get<BibleBook>(`/v1/bibles/${versionId}/books/${book}`);
|
|
108
104
|
}
|
|
109
105
|
|
|
110
106
|
/**
|
|
@@ -117,7 +113,7 @@ export class BibleClient {
|
|
|
117
113
|
this.versionIdSchema.parse(versionId);
|
|
118
114
|
this.bookSchema.parse(book);
|
|
119
115
|
return this.client.get<Collection<BibleChapter>>(
|
|
120
|
-
|
|
116
|
+
`/v1/bibles/${versionId}/books/${book}/chapters`,
|
|
121
117
|
);
|
|
122
118
|
}
|
|
123
119
|
|
|
@@ -134,7 +130,7 @@ export class BibleClient {
|
|
|
134
130
|
this.chapterSchema.parse(chapter);
|
|
135
131
|
|
|
136
132
|
return this.client.get<BibleChapter>(
|
|
137
|
-
|
|
133
|
+
`/v1/bibles/${versionId}/books/${book}/chapters/${chapter}`,
|
|
138
134
|
);
|
|
139
135
|
}
|
|
140
136
|
|
|
@@ -155,7 +151,7 @@ export class BibleClient {
|
|
|
155
151
|
this.chapterSchema.parse(chapter);
|
|
156
152
|
|
|
157
153
|
return this.client.get<Collection<BibleVerse>>(
|
|
158
|
-
|
|
154
|
+
`/v1/bibles/${versionId}/books/${book}/chapters/${chapter}/verses`,
|
|
159
155
|
);
|
|
160
156
|
}
|
|
161
157
|
|
|
@@ -179,7 +175,7 @@ export class BibleClient {
|
|
|
179
175
|
this.verseSchema.parse(verse);
|
|
180
176
|
|
|
181
177
|
return this.client.get<BibleVerse>(
|
|
182
|
-
|
|
178
|
+
`/v1/bibles/${versionId}/books/${book}/chapters/${chapter}/verses/${verse}`,
|
|
183
179
|
);
|
|
184
180
|
}
|
|
185
181
|
|
|
@@ -227,10 +223,7 @@ export class BibleClient {
|
|
|
227
223
|
if (include_notes !== undefined) {
|
|
228
224
|
params.include_notes = include_notes;
|
|
229
225
|
}
|
|
230
|
-
return this.client.get<BiblePassage>(
|
|
231
|
-
`${this.rootPath}/bibles/${versionId}/passages/${usfm}`,
|
|
232
|
-
params,
|
|
233
|
-
);
|
|
226
|
+
return this.client.get<BiblePassage>(`/v1/bibles/${versionId}/passages/${usfm}`, params);
|
|
234
227
|
}
|
|
235
228
|
|
|
236
229
|
/**
|
|
@@ -240,7 +233,7 @@ export class BibleClient {
|
|
|
240
233
|
*/
|
|
241
234
|
async getIndex(versionId: number): Promise<BibleIndex> {
|
|
242
235
|
this.versionIdSchema.parse(versionId);
|
|
243
|
-
return this.client.get<BibleIndex>(
|
|
236
|
+
return this.client.get<BibleIndex>(`/v1/bibles/${versionId}/index`);
|
|
244
237
|
}
|
|
245
238
|
|
|
246
239
|
/**
|
|
@@ -248,7 +241,7 @@ export class BibleClient {
|
|
|
248
241
|
* @returns A collection of VOTD objects for all days of the year.
|
|
249
242
|
*/
|
|
250
243
|
async getAllVOTDs(): Promise<Collection<VOTD>> {
|
|
251
|
-
return this.client.get<Collection<VOTD>>(
|
|
244
|
+
return this.client.get<Collection<VOTD>>(`/v1/verse_of_the_days`);
|
|
252
245
|
}
|
|
253
246
|
|
|
254
247
|
/**
|
|
@@ -267,6 +260,6 @@ export class BibleClient {
|
|
|
267
260
|
async getVOTD(day: number): Promise<VOTD> {
|
|
268
261
|
const daySchema = z.number().int().min(1).max(366);
|
|
269
262
|
daySchema.parse(day);
|
|
270
|
-
return this.client.get<VOTD>(
|
|
263
|
+
return this.client.get<VOTD>(`/v1/verse_of_the_days/${day}`);
|
|
271
264
|
}
|
|
272
265
|
}
|
package/src/client.ts
CHANGED
|
@@ -17,18 +17,23 @@ export class ApiClient {
|
|
|
17
17
|
/**
|
|
18
18
|
* Creates an instance of ApiClient.
|
|
19
19
|
*
|
|
20
|
-
* @param config - The API configuration object containing baseUrl, timeout, and
|
|
20
|
+
* @param config - The API configuration object containing baseUrl, timeout, and appKey.
|
|
21
21
|
*/
|
|
22
22
|
constructor(config: ApiConfig) {
|
|
23
23
|
this.config = {
|
|
24
|
-
version: config.version || 'v1',
|
|
25
24
|
...config,
|
|
26
25
|
};
|
|
27
|
-
|
|
26
|
+
const apiHost = config.apiHost ?? process.env.YVP_API_HOST ?? 'api.youversion.com';
|
|
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
|
+
);
|
|
31
|
+
}
|
|
32
|
+
this.baseURL = 'https://' + apiHost;
|
|
28
33
|
this.timeout = config.timeout || 10000;
|
|
29
34
|
this.defaultHeaders = {
|
|
30
35
|
'Content-Type': 'application/json',
|
|
31
|
-
'X-YVP-App-Key': this.config.
|
|
36
|
+
'X-YVP-App-Key': this.config.appKey,
|
|
32
37
|
'X-YVP-Installation-Id': this.config.installationId || 'web-sdk-default',
|
|
33
38
|
};
|
|
34
39
|
}
|
package/src/highlights.ts
CHANGED
|
@@ -39,10 +39,6 @@ export class HighlightsClient {
|
|
|
39
39
|
this.client = client;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
private get rootPath(): string {
|
|
43
|
-
return `/${this.client.config.version}`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
42
|
/**
|
|
47
43
|
* Gets the authentication token, either from the provided parameter or from the platform configuration.
|
|
48
44
|
* @param lat Optional explicit long access token. If not provided, retrieves from YouVersionPlatformConfiguration.
|
|
@@ -122,7 +118,7 @@ export class HighlightsClient {
|
|
|
122
118
|
params.passage_id = options.passage_id;
|
|
123
119
|
}
|
|
124
120
|
|
|
125
|
-
return this.client.get<Collection<Highlight>>(
|
|
121
|
+
return this.client.get<Collection<Highlight>>(`/v1/highlights`, params);
|
|
126
122
|
}
|
|
127
123
|
|
|
128
124
|
/**
|
|
@@ -140,7 +136,7 @@ export class HighlightsClient {
|
|
|
140
136
|
|
|
141
137
|
const token = this.getAuthToken(lat);
|
|
142
138
|
|
|
143
|
-
return this.client.post<Highlight>(
|
|
139
|
+
return this.client.post<Highlight>(`/v1/highlights`, data, { lat: token });
|
|
144
140
|
}
|
|
145
141
|
|
|
146
142
|
/**
|
|
@@ -168,6 +164,6 @@ export class HighlightsClient {
|
|
|
168
164
|
params.version_id = options.version_id;
|
|
169
165
|
}
|
|
170
166
|
|
|
171
|
-
await this.client.delete<void>(
|
|
167
|
+
await this.client.delete<void>(`/v1/highlights/${passageId}`, params);
|
|
172
168
|
}
|
|
173
169
|
}
|
package/src/languages.ts
CHANGED
|
@@ -39,10 +39,6 @@ export class LanguagesClient {
|
|
|
39
39
|
this.client = client;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
private get rootPath(): string {
|
|
43
|
-
return `/${this.client.config.version}`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
42
|
/**
|
|
47
43
|
* Fetches a collection of languages supported in the Platform.
|
|
48
44
|
* @param options Query parameters for pagination and filtering (country is required).
|
|
@@ -65,7 +61,7 @@ export class LanguagesClient {
|
|
|
65
61
|
params.page_token = options.page_token;
|
|
66
62
|
}
|
|
67
63
|
|
|
68
|
-
return this.client.get<Collection<Language>>(
|
|
64
|
+
return this.client.get<Collection<Language>>(`/v1/languages`, params);
|
|
69
65
|
}
|
|
70
66
|
|
|
71
67
|
/**
|
|
@@ -75,6 +71,6 @@ export class LanguagesClient {
|
|
|
75
71
|
*/
|
|
76
72
|
async getLanguage(languageId: string): Promise<Language> {
|
|
77
73
|
this.languageIdSchema.parse(languageId);
|
|
78
|
-
return this.client.get<Language>(
|
|
74
|
+
return this.client.get<Language>(`/v1/languages/${languageId}`);
|
|
79
75
|
}
|
|
80
76
|
}
|
package/src/types/api-config.ts
CHANGED
package/.env.local
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
YVP_API_BASE_URL=https://api-dev.youversion.com
|
|
2
|
-
|
|
3
|
-
# Your application ID from YouVersion Platform
|
|
4
|
-
YVP_APP_ID=Or8moGBK6GSh61OUOX7fUHgEsBsmVGMqAweZbydAgXnWj3nF
|
|
5
|
-
|
|
6
|
-
# Your installation ID
|
|
7
|
-
YVP_INSTALLATION_ID=a93b6749-7932-4bac-92ad-3e308f8a4bc4
|
|
8
|
-
|
|
9
|
-
# Optional: Authentication token for endpoints that require it
|
|
10
|
-
YVP_AUTH_TOKEN=
|