@youversion/platform-core 0.8.2 → 0.9.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/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +14 -0
- package/dist/index.cjs +116 -169
- package/dist/index.d.cts +19 -25
- package/dist/index.d.ts +19 -25
- package/dist/index.js +116 -168
- package/package.json +1 -1
- package/src/SignInWithYouVersionPKCE.ts +7 -7
- package/src/SignInWithYouVersionResult.ts +0 -6
- package/src/Users.ts +5 -29
- package/src/__tests__/MockBibles.ts +67 -67
- package/src/__tests__/SignInWithYouVersionPKCE.test.ts +8 -77
- package/src/__tests__/SignInWithYouVersionResult.test.ts +0 -2
- package/src/__tests__/Users.test.ts +4 -38
- package/src/__tests__/bible.test.ts +2 -2
- package/src/bible.ts +1 -1
- package/src/index.ts +0 -1
- package/src/schemas/book.ts +1 -5
- package/src/types/auth.ts +2 -0
- package/src/types/index.ts +5 -1
- package/src/utils/constants.ts +103 -103
- package/src/URLBuilder.ts +0 -50
- package/src/__tests__/URLBuilder.test.ts +0 -190
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
2
|
import { SignInWithYouVersionPKCEAuthorizationRequestBuilder } from '../SignInWithYouVersionPKCE';
|
|
3
3
|
import { YouVersionPlatformConfiguration } from '../YouVersionPlatformConfiguration';
|
|
4
|
-
import { SignInWithYouVersionPermission } from '../SignInWithYouVersionResult';
|
|
5
|
-
import type { SignInWithYouVersionPermissionValues } from '../types/auth';
|
|
6
4
|
import { setupBrowserMocks, cleanupBrowserMocks } from './mocks/browser';
|
|
7
5
|
|
|
8
6
|
describe('SignInWithYouVersionPKCEAuthorizationRequestBuilder', () => {
|
|
@@ -61,15 +59,10 @@ describe('SignInWithYouVersionPKCEAuthorizationRequestBuilder', () => {
|
|
|
61
59
|
.mockReturnValueOnce('stateBase64==') // State
|
|
62
60
|
.mockReturnValueOnce('nonceBase64=='); // Nonce
|
|
63
61
|
|
|
64
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>([
|
|
65
|
-
SignInWithYouVersionPermission.bibles,
|
|
66
|
-
SignInWithYouVersionPermission.highlights,
|
|
67
|
-
]);
|
|
68
62
|
const redirectURL = new URL('https://example.com/callback');
|
|
69
63
|
|
|
70
64
|
const result = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
71
65
|
'test-app-key',
|
|
72
|
-
permissions,
|
|
73
66
|
redirectURL,
|
|
74
67
|
);
|
|
75
68
|
|
|
@@ -101,17 +94,14 @@ describe('SignInWithYouVersionPKCEAuthorizationRequestBuilder', () => {
|
|
|
101
94
|
mocks.crypto.subtle.digest.mockResolvedValue(new Uint8Array(32).buffer);
|
|
102
95
|
mocks.btoa.mockImplementation((str: string) => `base64_${callCount}_${str.length}`);
|
|
103
96
|
|
|
104
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>();
|
|
105
97
|
const redirectURL = new URL('https://example.com/callback');
|
|
106
98
|
|
|
107
99
|
const result1 = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
108
100
|
'app-key',
|
|
109
|
-
permissions,
|
|
110
101
|
redirectURL,
|
|
111
102
|
);
|
|
112
103
|
const result2 = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
113
104
|
'app-key',
|
|
114
|
-
permissions,
|
|
115
105
|
redirectURL,
|
|
116
106
|
);
|
|
117
107
|
|
|
@@ -136,14 +126,10 @@ describe('SignInWithYouVersionPKCEAuthorizationRequestBuilder', () => {
|
|
|
136
126
|
});
|
|
137
127
|
|
|
138
128
|
it('should build authorization URL with all required OAuth2 parameters', async () => {
|
|
139
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>([
|
|
140
|
-
SignInWithYouVersionPermission.bibles,
|
|
141
|
-
]);
|
|
142
129
|
const redirectURL = new URL('https://example.com/callback');
|
|
143
130
|
|
|
144
131
|
const result = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
145
132
|
'test-app-key',
|
|
146
|
-
permissions,
|
|
147
133
|
redirectURL,
|
|
148
134
|
);
|
|
149
135
|
|
|
@@ -163,12 +149,10 @@ describe('SignInWithYouVersionPKCEAuthorizationRequestBuilder', () => {
|
|
|
163
149
|
});
|
|
164
150
|
|
|
165
151
|
it('should handle redirect URL with trailing slash', async () => {
|
|
166
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>();
|
|
167
152
|
const redirectURL = new URL('https://example.com/callback/');
|
|
168
153
|
|
|
169
154
|
const result = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
170
155
|
'test-app-key',
|
|
171
|
-
permissions,
|
|
172
156
|
redirectURL,
|
|
173
157
|
);
|
|
174
158
|
|
|
@@ -177,12 +161,10 @@ describe('SignInWithYouVersionPKCEAuthorizationRequestBuilder', () => {
|
|
|
177
161
|
});
|
|
178
162
|
|
|
179
163
|
it('should include x-yvp-installation-id param', async () => {
|
|
180
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>();
|
|
181
164
|
const redirectURL = new URL('https://example.com/callback');
|
|
182
165
|
|
|
183
166
|
const result = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
184
167
|
'test-app-key',
|
|
185
|
-
permissions,
|
|
186
168
|
redirectURL,
|
|
187
169
|
);
|
|
188
170
|
|
|
@@ -190,73 +172,41 @@ describe('SignInWithYouVersionPKCEAuthorizationRequestBuilder', () => {
|
|
|
190
172
|
expect(params.get('x-yvp-installation-id')).not.toBeFalsy();
|
|
191
173
|
});
|
|
192
174
|
|
|
193
|
-
it('should create scope string with
|
|
194
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>([
|
|
195
|
-
SignInWithYouVersionPermission.bibles,
|
|
196
|
-
SignInWithYouVersionPermission.highlights,
|
|
197
|
-
]);
|
|
175
|
+
it('should create scope string with profile and openid', async () => {
|
|
198
176
|
const redirectURL = new URL('https://example.com/callback');
|
|
199
177
|
|
|
200
178
|
const result = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
201
179
|
'test-app-key',
|
|
202
|
-
permissions,
|
|
203
180
|
redirectURL,
|
|
181
|
+
['profile'],
|
|
204
182
|
);
|
|
205
183
|
|
|
206
184
|
const params = new URLSearchParams(result.url.search);
|
|
207
185
|
const scope = params.get('scope');
|
|
208
186
|
|
|
209
|
-
expect(scope).toContain('
|
|
210
|
-
expect(scope).toContain('highlights');
|
|
211
|
-
expect(scope).toContain('openid');
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it('should sort permissions alphabetically', async () => {
|
|
215
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>([
|
|
216
|
-
SignInWithYouVersionPermission.votd,
|
|
217
|
-
SignInWithYouVersionPermission.bibles,
|
|
218
|
-
SignInWithYouVersionPermission.demographics,
|
|
219
|
-
]);
|
|
220
|
-
const redirectURL = new URL('https://example.com/callback');
|
|
221
|
-
|
|
222
|
-
const result = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
223
|
-
'test-app-key',
|
|
224
|
-
permissions,
|
|
225
|
-
redirectURL,
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
const params = new URLSearchParams(result.url.search);
|
|
229
|
-
const scope = params.get('scope');
|
|
230
|
-
|
|
231
|
-
// Should be sorted: bibles demographics votd openid
|
|
232
|
-
expect(scope).toBe('bibles demographics votd openid');
|
|
187
|
+
expect(scope).toContain('profile');
|
|
233
188
|
});
|
|
234
189
|
|
|
235
190
|
it('should add openid when not present', async () => {
|
|
236
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>([
|
|
237
|
-
SignInWithYouVersionPermission.bibles,
|
|
238
|
-
]);
|
|
239
191
|
const redirectURL = new URL('https://example.com/callback');
|
|
240
192
|
|
|
241
193
|
const result = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
242
194
|
'test-app-key',
|
|
243
|
-
permissions,
|
|
244
195
|
redirectURL,
|
|
196
|
+
['profile'],
|
|
245
197
|
);
|
|
246
198
|
|
|
247
199
|
const params = new URLSearchParams(result.url.search);
|
|
248
200
|
const scope = params.get('scope');
|
|
249
201
|
|
|
250
|
-
expect(scope).toBe('
|
|
202
|
+
expect(scope).toBe('profile openid');
|
|
251
203
|
});
|
|
252
204
|
|
|
253
|
-
it('should handle empty
|
|
254
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>();
|
|
205
|
+
it('should handle empty scope params', async () => {
|
|
255
206
|
const redirectURL = new URL('https://example.com/callback');
|
|
256
207
|
|
|
257
208
|
const result = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
258
209
|
'test-app-key',
|
|
259
|
-
permissions,
|
|
260
210
|
redirectURL,
|
|
261
211
|
);
|
|
262
212
|
|
|
@@ -267,16 +217,10 @@ describe('SignInWithYouVersionPKCEAuthorizationRequestBuilder', () => {
|
|
|
267
217
|
});
|
|
268
218
|
|
|
269
219
|
it('should not duplicate openid if already present', async () => {
|
|
270
|
-
// This test simulates if openid was somehow in the permissions set
|
|
271
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>([
|
|
272
|
-
'openid' as SignInWithYouVersionPermissionValues,
|
|
273
|
-
SignInWithYouVersionPermission.bibles,
|
|
274
|
-
]);
|
|
275
220
|
const redirectURL = new URL('https://example.com/callback');
|
|
276
221
|
|
|
277
222
|
const result = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
278
223
|
'test-app-key',
|
|
279
|
-
permissions,
|
|
280
224
|
redirectURL,
|
|
281
225
|
);
|
|
282
226
|
|
|
@@ -347,14 +291,9 @@ describe('SignInWithYouVersionPKCEAuthorizationRequestBuilder', () => {
|
|
|
347
291
|
});
|
|
348
292
|
|
|
349
293
|
it('should use crypto.getRandomValues for secure random generation', async () => {
|
|
350
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>();
|
|
351
294
|
const redirectURL = new URL('https://example.com/callback');
|
|
352
295
|
|
|
353
|
-
await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
354
|
-
'test-app-key',
|
|
355
|
-
permissions,
|
|
356
|
-
redirectURL,
|
|
357
|
-
);
|
|
296
|
+
await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make('test-app-key', redirectURL);
|
|
358
297
|
|
|
359
298
|
// Should call crypto.getRandomValues for code verifier, state, and nonce
|
|
360
299
|
expect(mocks.crypto.getRandomValues).toHaveBeenCalledTimes(3);
|
|
@@ -367,14 +306,9 @@ describe('SignInWithYouVersionPKCEAuthorizationRequestBuilder', () => {
|
|
|
367
306
|
});
|
|
368
307
|
|
|
369
308
|
it('should use SHA-256 for code challenge', async () => {
|
|
370
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>();
|
|
371
309
|
const redirectURL = new URL('https://example.com/callback');
|
|
372
310
|
|
|
373
|
-
await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
374
|
-
'test-app-key',
|
|
375
|
-
permissions,
|
|
376
|
-
redirectURL,
|
|
377
|
-
);
|
|
311
|
+
await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make('test-app-key', redirectURL);
|
|
378
312
|
|
|
379
313
|
expect(mocks.crypto.subtle.digest).toHaveBeenCalledWith('SHA-256', expect.any(Uint8Array));
|
|
380
314
|
});
|
|
@@ -383,17 +317,14 @@ describe('SignInWithYouVersionPKCEAuthorizationRequestBuilder', () => {
|
|
|
383
317
|
// Use real crypto for this test to verify actual randomness
|
|
384
318
|
cleanupBrowserMocks();
|
|
385
319
|
|
|
386
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>();
|
|
387
320
|
const redirectURL = new URL('https://example.com/callback');
|
|
388
321
|
|
|
389
322
|
const result1 = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
390
323
|
'test-app-key',
|
|
391
|
-
permissions,
|
|
392
324
|
redirectURL,
|
|
393
325
|
);
|
|
394
326
|
const result2 = await SignInWithYouVersionPKCEAuthorizationRequestBuilder.make(
|
|
395
327
|
'test-app-key',
|
|
396
|
-
permissions,
|
|
397
328
|
redirectURL,
|
|
398
329
|
);
|
|
399
330
|
|
|
@@ -9,7 +9,6 @@ describe('SignInWithYouVersionResult', () => {
|
|
|
9
9
|
accessToken: 'test-access-token',
|
|
10
10
|
expiresIn: 3600,
|
|
11
11
|
refreshToken: 'test-refresh-token',
|
|
12
|
-
permissions: ['votd', 'bibles'],
|
|
13
12
|
yvpUserId: 'test-user-id',
|
|
14
13
|
name: 'test user',
|
|
15
14
|
profilePicture: 'https://this-is-a-test-picture.com',
|
|
@@ -19,7 +18,6 @@ describe('SignInWithYouVersionResult', () => {
|
|
|
19
18
|
expect(result.accessToken).toBe('test-access-token');
|
|
20
19
|
expect(result.expiryDate).toStrictEqual(new Date(fixedDate.getTime() + 60 * 60 * 1000));
|
|
21
20
|
expect(result.refreshToken).toBe('test-refresh-token');
|
|
22
|
-
expect(result.permissions).toStrictEqual(['votd', 'bibles']);
|
|
23
21
|
expect(result.yvpUserId).toBe('test-user-id');
|
|
24
22
|
expect(result.name).toBe('test user');
|
|
25
23
|
expect(result.profilePicture).toBe('https://this-is-a-test-picture.com');
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
2
|
import { YouVersionAPIUsers } from '../Users';
|
|
3
3
|
import { YouVersionPlatformConfiguration } from '../YouVersionPlatformConfiguration';
|
|
4
|
-
import { SignInWithYouVersionPermission } from '../SignInWithYouVersionResult';
|
|
5
4
|
import { YouVersionUserInfo } from '../YouVersionUserInfo';
|
|
6
|
-
import type { SignInWithYouVersionPermissionValues } from '../types/auth';
|
|
7
5
|
import { setupBrowserMocks, cleanupBrowserMocks } from './mocks/browser';
|
|
8
6
|
|
|
9
7
|
const mockFetch = vi.fn();
|
|
@@ -40,13 +38,9 @@ describe('YouVersionAPIUsers', () => {
|
|
|
40
38
|
it('should throw error when appKey is not set', async () => {
|
|
41
39
|
YouVersionPlatformConfiguration.appKey = null;
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
await expect(
|
|
48
|
-
YouVersionAPIUsers.signIn(permissions, 'https://example.com/callback'),
|
|
49
|
-
).rejects.toThrow('YouVersionPlatformConfiguration.appKey must be set before calling signIn');
|
|
41
|
+
await expect(YouVersionAPIUsers.signIn('https://example.com/callback')).rejects.toThrow(
|
|
42
|
+
'YouVersionPlatformConfiguration.appKey must be set before calling signIn',
|
|
43
|
+
);
|
|
50
44
|
});
|
|
51
45
|
|
|
52
46
|
it('should create authorization request and redirect on successful signIn', async () => {
|
|
@@ -62,13 +56,9 @@ describe('YouVersionAPIUsers', () => {
|
|
|
62
56
|
vi.spyOn(crypto.subtle, 'digest').mockResolvedValue(new Uint8Array(32).buffer);
|
|
63
57
|
mocks.btoa.mockReturnValue('mockBase64Value');
|
|
64
58
|
|
|
65
|
-
const permissions = new Set<SignInWithYouVersionPermissionValues>([
|
|
66
|
-
SignInWithYouVersionPermission.bibles,
|
|
67
|
-
SignInWithYouVersionPermission.highlights,
|
|
68
|
-
]);
|
|
69
59
|
const redirectURL = 'https://example.com/callback';
|
|
70
60
|
|
|
71
|
-
await YouVersionAPIUsers.signIn(
|
|
61
|
+
await YouVersionAPIUsers.signIn(redirectURL);
|
|
72
62
|
|
|
73
63
|
// Verify localStorage items stored
|
|
74
64
|
expect(mocks.localStorage.setItem).toHaveBeenCalledWith(
|
|
@@ -210,7 +200,6 @@ describe('YouVersionAPIUsers', () => {
|
|
|
210
200
|
expect(result).toBeTruthy();
|
|
211
201
|
expect(result?.accessToken).toBe('access-token-123');
|
|
212
202
|
expect(result?.refreshToken).toBe('refresh-token-456');
|
|
213
|
-
expect(result?.permissions).toEqual(['bibles', 'highlights']);
|
|
214
203
|
expect(result?.yvpUserId).toBe('1234567890');
|
|
215
204
|
expect(result?.name).toBe('John Doe');
|
|
216
205
|
expect(result?.email).toBe('john@example.com');
|
|
@@ -323,32 +312,11 @@ describe('YouVersionAPIUsers', () => {
|
|
|
323
312
|
expect(result.accessToken).toBe('access-token-123');
|
|
324
313
|
expect(result.expiryDate).toStrictEqual(new Date(fixedDate.getTime() + 60 * 60 * 1000));
|
|
325
314
|
expect(result.refreshToken).toBe('refresh-token-456');
|
|
326
|
-
expect(result.permissions).toEqual(['bibles', 'highlights']);
|
|
327
315
|
expect(result.yvpUserId).toBe('1234567890');
|
|
328
316
|
expect(result.name).toBe('John Doe');
|
|
329
317
|
expect(result.email).toBe('john@example.com');
|
|
330
318
|
expect(result.profilePicture).toBe('https://example.com/avatar.jpg');
|
|
331
319
|
});
|
|
332
|
-
|
|
333
|
-
it('should filter out unknown permissions', () => {
|
|
334
|
-
const tokens = {
|
|
335
|
-
access_token: 'token',
|
|
336
|
-
expires_in: 3600,
|
|
337
|
-
id_token:
|
|
338
|
-
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.Et9HFtf9R3GEMA0IICOfFMVXY7kkTX1wr4qCyhIf58U',
|
|
339
|
-
refresh_token: 'refresh',
|
|
340
|
-
scope: 'bibles unknown_permission highlights invalid_scope',
|
|
341
|
-
token_type: 'Bearer',
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
// Mock JWT decoding
|
|
345
|
-
vi.mocked(atob).mockReturnValue(JSON.stringify({ sub: 'user123' }));
|
|
346
|
-
|
|
347
|
-
// @ts-expect-error - accessing private method for testing
|
|
348
|
-
const result = YouVersionAPIUsers.extractSignInResult(tokens);
|
|
349
|
-
|
|
350
|
-
expect(result.permissions).toEqual(['bibles', 'highlights']);
|
|
351
|
-
});
|
|
352
320
|
});
|
|
353
321
|
|
|
354
322
|
describe('decodeJWT', () => {
|
|
@@ -557,8 +525,6 @@ describe('YouVersionAPIUsers', () => {
|
|
|
557
525
|
// Assert that id_token is preserved (same as original)
|
|
558
526
|
expect(result?.idToken).toBe(existingIdToken);
|
|
559
527
|
|
|
560
|
-
expect(result?.permissions).toEqual(['bibles', 'highlights']);
|
|
561
|
-
|
|
562
528
|
// Verify the refresh token request was made correctly
|
|
563
529
|
expect(mockFetch).toHaveBeenCalledTimes(1);
|
|
564
530
|
expect(mockFetch).toHaveBeenCalledWith(
|
|
@@ -77,7 +77,7 @@ describe('BibleClient', () => {
|
|
|
77
77
|
expect(books.data[0]).toHaveProperty('title', 'Genesis');
|
|
78
78
|
expect(books.data[0]).toHaveProperty('full_title', 'The First Book of Moses, Called Genesis');
|
|
79
79
|
expect(books.data[0]).toHaveProperty('abbreviation', 'Gen');
|
|
80
|
-
expect(books.data[0]).toHaveProperty('canon', '
|
|
80
|
+
expect(books.data[0]).toHaveProperty('canon', 'old_testament');
|
|
81
81
|
expect(books.data[0]?.chapters).toHaveLength(50);
|
|
82
82
|
});
|
|
83
83
|
});
|
|
@@ -93,7 +93,7 @@ describe('BibleClient', () => {
|
|
|
93
93
|
expect(book).toHaveProperty('id', 'GEN');
|
|
94
94
|
expect(book).toHaveProperty('title', 'Genesis');
|
|
95
95
|
expect(book).toHaveProperty('abbreviation', 'Gen');
|
|
96
|
-
expect(book).toHaveProperty('canon', '
|
|
96
|
+
expect(book).toHaveProperty('canon', 'old_testament');
|
|
97
97
|
});
|
|
98
98
|
|
|
99
99
|
it('should throw an error for invalid inputs', async () => {
|
package/src/bible.ts
CHANGED
|
@@ -81,7 +81,7 @@ export class BibleClient {
|
|
|
81
81
|
/**
|
|
82
82
|
* Fetches all books for a given Bible version.
|
|
83
83
|
* @param versionId The version ID.
|
|
84
|
-
* @param canon Optional canon filter (
|
|
84
|
+
* @param canon Optional canon filter ("old_testament", 'new_testament', 'deuterocanon').
|
|
85
85
|
* @returns An array of BibleBook objects.
|
|
86
86
|
*/
|
|
87
87
|
async getBooks(versionId: number, canon?: CANON): Promise<Collection<BibleBook>> {
|
package/src/index.ts
CHANGED
|
@@ -11,7 +11,6 @@ export * from './Users';
|
|
|
11
11
|
export * from './YouVersionUserInfo';
|
|
12
12
|
export * from './SignInWithYouVersionResult';
|
|
13
13
|
export * from './YouVersionAPI';
|
|
14
|
-
export * from './URLBuilder';
|
|
15
14
|
export * from './YouVersionPlatformConfiguration';
|
|
16
15
|
export * from './types';
|
|
17
16
|
export * from './utils/constants';
|
package/src/schemas/book.ts
CHANGED
|
@@ -2,11 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { BOOK_IDS } from '../utils/constants';
|
|
3
3
|
import { BibleChapterSchema } from './chapter';
|
|
4
4
|
|
|
5
|
-
export const CanonSchema = z.enum([
|
|
6
|
-
'ot', // Old Testament
|
|
7
|
-
'nt', // New Testament
|
|
8
|
-
'dc', // Deuterocanon (Apocrypha)
|
|
9
|
-
]);
|
|
5
|
+
export const CanonSchema = z.enum(['old_testament', 'new_testament', 'deuterocanon']);
|
|
10
6
|
export type Canon = z.infer<typeof CanonSchema>;
|
|
11
7
|
|
|
12
8
|
// https://github.com/colinhacks/zod/discussions/4934#discussioncomment-13858053
|
package/src/types/auth.ts
CHANGED
package/src/types/index.ts
CHANGED
|
@@ -18,5 +18,9 @@ export type { Collection } from '../schemas/collection';
|
|
|
18
18
|
|
|
19
19
|
// Re-export internal/non-API types
|
|
20
20
|
export type { ApiConfig } from './api-config';
|
|
21
|
-
export type {
|
|
21
|
+
export type {
|
|
22
|
+
AuthenticationState,
|
|
23
|
+
SignInWithYouVersionPermissionValues,
|
|
24
|
+
AuthenticationScopes,
|
|
25
|
+
} from './auth';
|
|
22
26
|
export type { HighlightColor } from './highlight';
|
package/src/utils/constants.ts
CHANGED
|
@@ -113,107 +113,107 @@ import type { Canon, BookUsfm } from '../schemas/book';
|
|
|
113
113
|
* @see https://github.com/youversion/usfm-references/blob/main/usfm_references/books.py
|
|
114
114
|
*/
|
|
115
115
|
export const BOOK_CANON: Record<BookUsfm, Canon> = {
|
|
116
|
-
GEN: '
|
|
117
|
-
EXO: '
|
|
118
|
-
LEV: '
|
|
119
|
-
NUM: '
|
|
120
|
-
DEU: '
|
|
121
|
-
JOS: '
|
|
122
|
-
JDG: '
|
|
123
|
-
RUT: '
|
|
124
|
-
'1SA': '
|
|
125
|
-
'2SA': '
|
|
126
|
-
'1KI': '
|
|
127
|
-
'2KI': '
|
|
128
|
-
'1CH': '
|
|
129
|
-
'2CH': '
|
|
130
|
-
EZR: '
|
|
131
|
-
NEH: '
|
|
132
|
-
EST: '
|
|
133
|
-
JOB: '
|
|
134
|
-
PSA: '
|
|
135
|
-
PRO: '
|
|
136
|
-
ECC: '
|
|
137
|
-
SNG: '
|
|
138
|
-
ISA: '
|
|
139
|
-
JER: '
|
|
140
|
-
LAM: '
|
|
141
|
-
EZK: '
|
|
142
|
-
DAN: '
|
|
143
|
-
HOS: '
|
|
144
|
-
JOL: '
|
|
145
|
-
AMO: '
|
|
146
|
-
OBA: '
|
|
147
|
-
JON: '
|
|
148
|
-
MIC: '
|
|
149
|
-
NAM: '
|
|
150
|
-
HAB: '
|
|
151
|
-
ZEP: '
|
|
152
|
-
HAG: '
|
|
153
|
-
ZEC: '
|
|
154
|
-
MAL: '
|
|
155
|
-
MAT: '
|
|
156
|
-
MRK: '
|
|
157
|
-
LUK: '
|
|
158
|
-
JHN: '
|
|
159
|
-
ACT: '
|
|
160
|
-
ROM: '
|
|
161
|
-
'1CO': '
|
|
162
|
-
'2CO': '
|
|
163
|
-
GAL: '
|
|
164
|
-
EPH: '
|
|
165
|
-
PHP: '
|
|
166
|
-
COL: '
|
|
167
|
-
'1TH': '
|
|
168
|
-
'2TH': '
|
|
169
|
-
'1TI': '
|
|
170
|
-
'2TI': '
|
|
171
|
-
TIT: '
|
|
172
|
-
PHM: '
|
|
173
|
-
HEB: '
|
|
174
|
-
JAS: '
|
|
175
|
-
'1PE': '
|
|
176
|
-
'2PE': '
|
|
177
|
-
'1JN': '
|
|
178
|
-
'2JN': '
|
|
179
|
-
'3JN': '
|
|
180
|
-
JUD: '
|
|
181
|
-
REV: '
|
|
182
|
-
TOB: '
|
|
183
|
-
JDT: '
|
|
184
|
-
ESG: '
|
|
185
|
-
WIS: '
|
|
186
|
-
SIR: '
|
|
187
|
-
BAR: '
|
|
188
|
-
LJE: '
|
|
189
|
-
S3Y: '
|
|
190
|
-
SUS: '
|
|
191
|
-
BEL: '
|
|
192
|
-
'1MA': '
|
|
193
|
-
'2MA': '
|
|
194
|
-
'3MA': '
|
|
195
|
-
'4MA': '
|
|
196
|
-
'1ES': '
|
|
197
|
-
'2ES': '
|
|
198
|
-
MAN: '
|
|
199
|
-
PS2: '
|
|
200
|
-
ODA: '
|
|
201
|
-
PSS: '
|
|
202
|
-
'3ES': '
|
|
203
|
-
EZA: '
|
|
204
|
-
'5EZ': '
|
|
205
|
-
'6EZ': '
|
|
206
|
-
DAG: '
|
|
207
|
-
PS3: '
|
|
208
|
-
'2BA': '
|
|
209
|
-
LBA: '
|
|
210
|
-
JUB: '
|
|
211
|
-
ENO: '
|
|
212
|
-
'1MQ': '
|
|
213
|
-
'2MQ': '
|
|
214
|
-
'3MQ': '
|
|
215
|
-
REP: '
|
|
216
|
-
'4BA': '
|
|
217
|
-
LAO: '
|
|
218
|
-
LKA: '
|
|
116
|
+
GEN: 'old_testament',
|
|
117
|
+
EXO: 'old_testament',
|
|
118
|
+
LEV: 'old_testament',
|
|
119
|
+
NUM: 'old_testament',
|
|
120
|
+
DEU: 'old_testament',
|
|
121
|
+
JOS: 'old_testament',
|
|
122
|
+
JDG: 'old_testament',
|
|
123
|
+
RUT: 'old_testament',
|
|
124
|
+
'1SA': 'old_testament',
|
|
125
|
+
'2SA': 'old_testament',
|
|
126
|
+
'1KI': 'old_testament',
|
|
127
|
+
'2KI': 'old_testament',
|
|
128
|
+
'1CH': 'old_testament',
|
|
129
|
+
'2CH': 'old_testament',
|
|
130
|
+
EZR: 'old_testament',
|
|
131
|
+
NEH: 'old_testament',
|
|
132
|
+
EST: 'old_testament',
|
|
133
|
+
JOB: 'old_testament',
|
|
134
|
+
PSA: 'old_testament',
|
|
135
|
+
PRO: 'old_testament',
|
|
136
|
+
ECC: 'old_testament',
|
|
137
|
+
SNG: 'old_testament',
|
|
138
|
+
ISA: 'old_testament',
|
|
139
|
+
JER: 'old_testament',
|
|
140
|
+
LAM: 'old_testament',
|
|
141
|
+
EZK: 'old_testament',
|
|
142
|
+
DAN: 'old_testament',
|
|
143
|
+
HOS: 'old_testament',
|
|
144
|
+
JOL: 'old_testament',
|
|
145
|
+
AMO: 'old_testament',
|
|
146
|
+
OBA: 'old_testament',
|
|
147
|
+
JON: 'old_testament',
|
|
148
|
+
MIC: 'old_testament',
|
|
149
|
+
NAM: 'old_testament',
|
|
150
|
+
HAB: 'old_testament',
|
|
151
|
+
ZEP: 'old_testament',
|
|
152
|
+
HAG: 'old_testament',
|
|
153
|
+
ZEC: 'old_testament',
|
|
154
|
+
MAL: 'old_testament',
|
|
155
|
+
MAT: 'new_testament',
|
|
156
|
+
MRK: 'new_testament',
|
|
157
|
+
LUK: 'new_testament',
|
|
158
|
+
JHN: 'new_testament',
|
|
159
|
+
ACT: 'new_testament',
|
|
160
|
+
ROM: 'new_testament',
|
|
161
|
+
'1CO': 'new_testament',
|
|
162
|
+
'2CO': 'new_testament',
|
|
163
|
+
GAL: 'new_testament',
|
|
164
|
+
EPH: 'new_testament',
|
|
165
|
+
PHP: 'new_testament',
|
|
166
|
+
COL: 'new_testament',
|
|
167
|
+
'1TH': 'new_testament',
|
|
168
|
+
'2TH': 'new_testament',
|
|
169
|
+
'1TI': 'new_testament',
|
|
170
|
+
'2TI': 'new_testament',
|
|
171
|
+
TIT: 'new_testament',
|
|
172
|
+
PHM: 'new_testament',
|
|
173
|
+
HEB: 'new_testament',
|
|
174
|
+
JAS: 'new_testament',
|
|
175
|
+
'1PE': 'new_testament',
|
|
176
|
+
'2PE': 'new_testament',
|
|
177
|
+
'1JN': 'new_testament',
|
|
178
|
+
'2JN': 'new_testament',
|
|
179
|
+
'3JN': 'new_testament',
|
|
180
|
+
JUD: 'new_testament',
|
|
181
|
+
REV: 'new_testament',
|
|
182
|
+
TOB: 'deuterocanon',
|
|
183
|
+
JDT: 'deuterocanon',
|
|
184
|
+
ESG: 'deuterocanon',
|
|
185
|
+
WIS: 'deuterocanon',
|
|
186
|
+
SIR: 'deuterocanon',
|
|
187
|
+
BAR: 'deuterocanon',
|
|
188
|
+
LJE: 'deuterocanon',
|
|
189
|
+
S3Y: 'deuterocanon',
|
|
190
|
+
SUS: 'deuterocanon',
|
|
191
|
+
BEL: 'deuterocanon',
|
|
192
|
+
'1MA': 'deuterocanon',
|
|
193
|
+
'2MA': 'deuterocanon',
|
|
194
|
+
'3MA': 'deuterocanon',
|
|
195
|
+
'4MA': 'deuterocanon',
|
|
196
|
+
'1ES': 'deuterocanon',
|
|
197
|
+
'2ES': 'deuterocanon',
|
|
198
|
+
MAN: 'deuterocanon',
|
|
199
|
+
PS2: 'deuterocanon',
|
|
200
|
+
ODA: 'deuterocanon',
|
|
201
|
+
PSS: 'deuterocanon',
|
|
202
|
+
'3ES': 'deuterocanon',
|
|
203
|
+
EZA: 'deuterocanon',
|
|
204
|
+
'5EZ': 'deuterocanon',
|
|
205
|
+
'6EZ': 'deuterocanon',
|
|
206
|
+
DAG: 'deuterocanon',
|
|
207
|
+
PS3: 'deuterocanon',
|
|
208
|
+
'2BA': 'deuterocanon',
|
|
209
|
+
LBA: 'deuterocanon',
|
|
210
|
+
JUB: 'deuterocanon',
|
|
211
|
+
ENO: 'deuterocanon',
|
|
212
|
+
'1MQ': 'deuterocanon',
|
|
213
|
+
'2MQ': 'deuterocanon',
|
|
214
|
+
'3MQ': 'deuterocanon',
|
|
215
|
+
REP: 'deuterocanon',
|
|
216
|
+
'4BA': 'deuterocanon',
|
|
217
|
+
LAO: 'deuterocanon',
|
|
218
|
+
LKA: 'new_testament', // Luke-Acts combo, treated canonically as New Testament
|
|
219
219
|
};
|