free-use-bible-api 0.3.0 → 1.15.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/{LICENSE → LICENSE.txt} +21 -21
- package/README.md +36 -1
- package/dist/cjs/FreeUseBibleApi.cjs +137 -14
- package/dist/cjs/FreeUseBibleApi.cjs.map +2 -2
- package/dist/cjs/index.cjs +604 -5
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/types.gen.cjs +2 -0
- package/dist/cjs/types.gen.cjs.map +2 -2
- package/dist/esm/FreeUseBibleApi.js +133 -12
- package/dist/esm/FreeUseBibleApi.js.map +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/types/FreeUseBibleApi.d.ts +95 -9
- package/dist/types/types.gen.d.ts +1134 -214
- package/package.json +21 -1
package/{LICENSE → LICENSE.txt}
RENAMED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2022 AO Lab
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 AO Lab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Free Use Bible API
|
|
2
2
|
|
|
3
|
+
<!-- #region docs -->
|
|
4
|
+
|
|
3
5
|
TypeScript and JavaScript client for the public Free Use Bible API:
|
|
4
6
|
|
|
5
7
|
- `https://bible.helloao.org`
|
|
@@ -35,6 +37,14 @@ const chapter = await api.getTranslationBookChapter('BSB', 'GEN', 1);
|
|
|
35
37
|
console.log('Verses in Genesis 1:', chapter.numberOfVerses);
|
|
36
38
|
```
|
|
37
39
|
|
|
40
|
+
CommonJS is also supported:
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
const { FreeUseBibleApi } = require('free-use-bible-api');
|
|
44
|
+
|
|
45
|
+
const api = new FreeUseBibleApi();
|
|
46
|
+
```
|
|
47
|
+
|
|
38
48
|
## Client Options
|
|
39
49
|
|
|
40
50
|
You can customize the client with `FreeUseBibleApiOptions`:
|
|
@@ -58,6 +68,7 @@ const api = new FreeUseBibleApi({
|
|
|
58
68
|
- `getAvailableTranslations(endpoint?)`
|
|
59
69
|
- `getTranslationBooks(translation, endpoint?)`
|
|
60
70
|
- `getTranslationBookChapter(translation, book, chapter, endpoint?)`
|
|
71
|
+
- `getTranslationBookChapterAudioTimings(translation, book, chapter, reader, endpoint?)`
|
|
61
72
|
- `getTranslationBookChapterWords(translation, book, chapter, endpoint?)`
|
|
62
73
|
- `getCompleteTranslation(translation, endpoint?)`
|
|
63
74
|
- `getSimpleTranslationBookChapter(translation, book, chapter, endpoint?)`
|
|
@@ -66,6 +77,10 @@ const api = new FreeUseBibleApi({
|
|
|
66
77
|
|
|
67
78
|
`getCompleteTranslation()` and `getSimpleCompleteTranslation()` disable per-request cache internally because payloads are typically large.
|
|
68
79
|
|
|
80
|
+
Only some chapters have audio timings. The keys of a chapter's `thisChapterAudioTimings` property identify the readers available to pass to `getTranslationBookChapterAudioTimings()`.
|
|
81
|
+
|
|
82
|
+
The client provides callable methods for all 24 public API operations.
|
|
83
|
+
|
|
69
84
|
### Commentaries
|
|
70
85
|
|
|
71
86
|
- `getAvailableCommentaries(endpoint?)`
|
|
@@ -77,7 +92,15 @@ const api = new FreeUseBibleApi({
|
|
|
77
92
|
|
|
78
93
|
- `getAvailableDatasets(endpoint?)`
|
|
79
94
|
- `getDatasetBooks(dataset, endpoint?)`
|
|
80
|
-
- `getDatasetBookChapter(dataset, book, chapter, endpoint?)`
|
|
95
|
+
- `getDatasetBookChapter(dataset, book, chapter, endpoint?)` - returns cross references for cross reference datasets, or the people, places, and events that appear in the chapter for entity datasets (such as `theographic`)
|
|
96
|
+
- `getDatasetPeople(dataset, endpoint?)`
|
|
97
|
+
- `getDatasetPerson(dataset, person, endpoint?)`
|
|
98
|
+
- `getDatasetPlaces(dataset, endpoint?)`
|
|
99
|
+
- `getDatasetPlace(dataset, place, endpoint?)`
|
|
100
|
+
- `getDatasetEvents(dataset, endpoint?)`
|
|
101
|
+
- `getDatasetEvent(dataset, event, endpoint?)`
|
|
102
|
+
- `getDatasetPeopleGroups(dataset, endpoint?)`
|
|
103
|
+
- `getDatasetPeopleGroup(dataset, group, endpoint?)`
|
|
81
104
|
|
|
82
105
|
### Chapter Navigation Helpers
|
|
83
106
|
|
|
@@ -206,6 +229,7 @@ for (const content of chapter.chapter.content) {
|
|
|
206
229
|
- `GET /api/available_translations.json`
|
|
207
230
|
- `GET /api/{translation}/books.json`
|
|
208
231
|
- `GET /api/{translation}/{book}/{chapter}.json`
|
|
232
|
+
- `GET /api/{translation}/{book}/{chapter}.{reader}.audioTimings.json`
|
|
209
233
|
- `GET /api/{translation}/{book}/{chapter}.words.json`
|
|
210
234
|
- `GET /api/{translation}/complete.json`
|
|
211
235
|
- `GET /api/{translation}/{book}/{chapter}.simple.json`
|
|
@@ -224,6 +248,14 @@ for (const content of chapter.chapter.content) {
|
|
|
224
248
|
- `GET /api/available_datasets.json`
|
|
225
249
|
- `GET /api/d/{dataset}/books.json`
|
|
226
250
|
- `GET /api/d/{dataset}/{book}/{chapter}.json`
|
|
251
|
+
- `GET /api/d/{dataset}/people.json`
|
|
252
|
+
- `GET /api/d/{dataset}/people/{person}.json`
|
|
253
|
+
- `GET /api/d/{dataset}/places.json`
|
|
254
|
+
- `GET /api/d/{dataset}/places/{place}.json`
|
|
255
|
+
- `GET /api/d/{dataset}/events.json`
|
|
256
|
+
- `GET /api/d/{dataset}/events/{event}.json`
|
|
257
|
+
- `GET /api/d/{dataset}/groups.json`
|
|
258
|
+
- `GET /api/d/{dataset}/groups/{group}.json`
|
|
227
259
|
|
|
228
260
|
Example requests:
|
|
229
261
|
|
|
@@ -251,3 +283,6 @@ A 404 response usually means one of the path values is invalid, for example:
|
|
|
251
283
|
|
|
252
284
|
- Uses the global `fetch` API.
|
|
253
285
|
- For Node.js, use a runtime that provides `fetch` (Node 18+ recommended) or polyfill it.
|
|
286
|
+
|
|
287
|
+
<!-- #endregion docs -->
|
|
288
|
+
|
|
@@ -16,12 +16,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// packages/free-use-bible-api/FreeUseBibleApi.ts
|
|
19
21
|
var FreeUseBibleApi_exports = {};
|
|
20
22
|
__export(FreeUseBibleApi_exports, {
|
|
21
23
|
FreeUseBibleApi: () => FreeUseBibleApi
|
|
22
24
|
});
|
|
23
25
|
module.exports = __toCommonJS(FreeUseBibleApi_exports);
|
|
24
|
-
|
|
26
|
+
var FreeUseBibleApi = class {
|
|
25
27
|
endpoint = "https://bible.helloao.org/";
|
|
26
28
|
_responseCache = /* @__PURE__ */ new Map();
|
|
27
29
|
_useCache = true;
|
|
@@ -125,6 +127,115 @@ class FreeUseBibleApi {
|
|
|
125
127
|
endpoint
|
|
126
128
|
);
|
|
127
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Gets the list of people for a given dataset.
|
|
132
|
+
* @param dataset The ID of the dataset to get the people for.
|
|
133
|
+
* @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.
|
|
134
|
+
*/
|
|
135
|
+
async getDatasetPeople(dataset, endpoint) {
|
|
136
|
+
const encodedDataset = encodeURIComponent(dataset);
|
|
137
|
+
return this._getJson(
|
|
138
|
+
`api/d/${encodedDataset}/people.json`,
|
|
139
|
+
endpoint
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Gets the information about a specific person for a given dataset.
|
|
144
|
+
* Includes the Bible references that mention the person and their relationships
|
|
145
|
+
* to other people, places, events, and people groups.
|
|
146
|
+
* @param dataset The ID of the dataset to get the person for.
|
|
147
|
+
* @param person The ID of the person to get.
|
|
148
|
+
* @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.
|
|
149
|
+
*/
|
|
150
|
+
async getDatasetPerson(dataset, person, endpoint) {
|
|
151
|
+
const encodedDataset = encodeURIComponent(dataset);
|
|
152
|
+
const encodedPerson = encodeURIComponent(person);
|
|
153
|
+
return this._getJson(
|
|
154
|
+
`api/d/${encodedDataset}/people/${encodedPerson}.json`,
|
|
155
|
+
endpoint
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Gets the list of places for a given dataset.
|
|
160
|
+
* @param dataset The ID of the dataset to get the places for.
|
|
161
|
+
* @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.
|
|
162
|
+
*/
|
|
163
|
+
async getDatasetPlaces(dataset, endpoint) {
|
|
164
|
+
const encodedDataset = encodeURIComponent(dataset);
|
|
165
|
+
return this._getJson(
|
|
166
|
+
`api/d/${encodedDataset}/places.json`,
|
|
167
|
+
endpoint
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Gets the information about a specific place for a given dataset.
|
|
172
|
+
* Includes the Bible references that mention the place and its related people and events.
|
|
173
|
+
* @param dataset The ID of the dataset to get the place for.
|
|
174
|
+
* @param place The ID of the place to get.
|
|
175
|
+
* @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.
|
|
176
|
+
*/
|
|
177
|
+
async getDatasetPlace(dataset, place, endpoint) {
|
|
178
|
+
const encodedDataset = encodeURIComponent(dataset);
|
|
179
|
+
const encodedPlace = encodeURIComponent(place);
|
|
180
|
+
return this._getJson(
|
|
181
|
+
`api/d/${encodedDataset}/places/${encodedPlace}.json`,
|
|
182
|
+
endpoint
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Gets the list of events for a given dataset.
|
|
187
|
+
* @param dataset The ID of the dataset to get the events for.
|
|
188
|
+
* @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.
|
|
189
|
+
*/
|
|
190
|
+
async getDatasetEvents(dataset, endpoint) {
|
|
191
|
+
const encodedDataset = encodeURIComponent(dataset);
|
|
192
|
+
return this._getJson(
|
|
193
|
+
`api/d/${encodedDataset}/events.json`,
|
|
194
|
+
endpoint
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Gets the information about a specific event for a given dataset.
|
|
199
|
+
* Includes the Bible references that describe the event and its related people, places, and people groups.
|
|
200
|
+
* @param dataset The ID of the dataset to get the event for.
|
|
201
|
+
* @param event The ID of the event to get.
|
|
202
|
+
* @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.
|
|
203
|
+
*/
|
|
204
|
+
async getDatasetEvent(dataset, event, endpoint) {
|
|
205
|
+
const encodedDataset = encodeURIComponent(dataset);
|
|
206
|
+
const encodedEvent = encodeURIComponent(event);
|
|
207
|
+
return this._getJson(
|
|
208
|
+
`api/d/${encodedDataset}/events/${encodedEvent}.json`,
|
|
209
|
+
endpoint
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Gets the list of people groups for a given dataset.
|
|
214
|
+
* @param dataset The ID of the dataset to get the people groups for.
|
|
215
|
+
* @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.
|
|
216
|
+
*/
|
|
217
|
+
async getDatasetPeopleGroups(dataset, endpoint) {
|
|
218
|
+
const encodedDataset = encodeURIComponent(dataset);
|
|
219
|
+
return this._getJson(
|
|
220
|
+
`api/d/${encodedDataset}/groups.json`,
|
|
221
|
+
endpoint
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Gets the information about a specific people group for a given dataset.
|
|
226
|
+
* Includes the members of the group and the events that the group participated in.
|
|
227
|
+
* @param dataset The ID of the dataset to get the people group for.
|
|
228
|
+
* @param group The ID of the people group to get.
|
|
229
|
+
* @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.
|
|
230
|
+
*/
|
|
231
|
+
async getDatasetPeopleGroup(dataset, group, endpoint) {
|
|
232
|
+
const encodedDataset = encodeURIComponent(dataset);
|
|
233
|
+
const encodedGroup = encodeURIComponent(group);
|
|
234
|
+
return this._getJson(
|
|
235
|
+
`api/d/${encodedDataset}/groups/${encodedGroup}.json`,
|
|
236
|
+
endpoint
|
|
237
|
+
);
|
|
238
|
+
}
|
|
128
239
|
/**
|
|
129
240
|
* Gets the content of a specific chapter of a specific book for a specific Bible translation.
|
|
130
241
|
* @param translation The ID of the translation to get the chapter for.
|
|
@@ -141,6 +252,26 @@ class FreeUseBibleApi {
|
|
|
141
252
|
endpoint
|
|
142
253
|
);
|
|
143
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Gets the audio timings for a specific chapter, read by a specific reader.
|
|
257
|
+
*
|
|
258
|
+
* Only some chapters have audio timings. Available readers are the keys of the chapter's `thisChapterAudioTimings` property.
|
|
259
|
+
* @param translation The ID of the translation to get the audio timings for.
|
|
260
|
+
* @param book The ID of the book to get the audio timings for.
|
|
261
|
+
* @param chapter The chapter number to get the audio timings for.
|
|
262
|
+
* @param reader The ID of the reader to get the audio timings for.
|
|
263
|
+
* @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
|
|
264
|
+
*/
|
|
265
|
+
async getTranslationBookChapterAudioTimings(translation, book, chapter, reader, endpoint) {
|
|
266
|
+
const encodedTranslation = encodeURIComponent(translation);
|
|
267
|
+
const encodedBook = encodeURIComponent(book);
|
|
268
|
+
const encodedChapter = encodeURIComponent(String(chapter));
|
|
269
|
+
const encodedReader = encodeURIComponent(reader);
|
|
270
|
+
return this._getJson(
|
|
271
|
+
`api/${encodedTranslation}/${encodedBook}/${encodedChapter}.${encodedReader}.audioTimings.json`,
|
|
272
|
+
endpoint
|
|
273
|
+
);
|
|
274
|
+
}
|
|
144
275
|
/**
|
|
145
276
|
* Gets the word-level annotations (Strong's numbers and related source data) for a specific chapter of a specific book for a specific Bible translation.
|
|
146
277
|
*
|
|
@@ -160,12 +291,6 @@ class FreeUseBibleApi {
|
|
|
160
291
|
endpoint
|
|
161
292
|
);
|
|
162
293
|
}
|
|
163
|
-
/**
|
|
164
|
-
* Gets the word-level annotations for the given chapter, if it has any.
|
|
165
|
-
* @param chapter The chapter to get the annotations for.
|
|
166
|
-
* @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
|
|
167
|
-
* @returns The annotations for the chapter, or null if the chapter doesn't have any.
|
|
168
|
-
*/
|
|
169
294
|
async getChapterWords(chapter, endpoint) {
|
|
170
295
|
if (!chapter.thisChapterWordsLink) {
|
|
171
296
|
return null;
|
|
@@ -218,12 +343,6 @@ class FreeUseBibleApi {
|
|
|
218
343
|
}
|
|
219
344
|
return this._getJson(chapter.simpleChapterApiLink, endpoint);
|
|
220
345
|
}
|
|
221
|
-
/**
|
|
222
|
-
* Gets the word-level annotations for the given simplified chapter, if it has any.
|
|
223
|
-
* @param chapter The simplified chapter to get the annotations for.
|
|
224
|
-
* @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
|
|
225
|
-
* @returns The annotations for the chapter, or null if the chapter doesn't have any.
|
|
226
|
-
*/
|
|
227
346
|
async getSimpleChapterWords(chapter, endpoint) {
|
|
228
347
|
if (!chapter.thisChapterWordsLink) {
|
|
229
348
|
return null;
|
|
@@ -267,6 +386,10 @@ class FreeUseBibleApi {
|
|
|
267
386
|
}
|
|
268
387
|
/**
|
|
269
388
|
* Gets the content of a specific chapter of a specific book for a specific dataset.
|
|
389
|
+
*
|
|
390
|
+
* For cross reference datasets, this is the list of cross references for each verse
|
|
391
|
+
* in the chapter. For entity datasets (such as "theographic"), this is the people,
|
|
392
|
+
* places, and events that appear in the chapter.
|
|
270
393
|
* @param dataset The ID of the dataset to get the chapter for.
|
|
271
394
|
* @param book The ID of the book to get the chapter for.
|
|
272
395
|
* @param chapter The chapter number to get.
|
|
@@ -491,7 +614,7 @@ ${content.trim()}`;
|
|
|
491
614
|
const baseEndpoint = endpoint ?? this.endpoint;
|
|
492
615
|
return new URL(path, baseEndpoint).href;
|
|
493
616
|
}
|
|
494
|
-
}
|
|
617
|
+
};
|
|
495
618
|
// Annotate the CommonJS export names for ESM import in node:
|
|
496
619
|
0 && (module.exports = {
|
|
497
620
|
FreeUseBibleApi
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../FreeUseBibleApi.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\r\n ApiAvailableDatasets,\r\n ApiAvailableTranslations,\r\n ApiCommentaryBook,\r\n ApiCommentaryBookChapter,\r\n ApiDatasetBook,\r\n ApiDatasetBookChapter,\r\n ApiDatasetBooks,\r\n ApiSimpleCommentaryBookChapter,\r\n ApiSimpleTranslationBookChapter,\r\n ApiSimpleTranslationBookChapterWords,\r\n ApiSimpleTranslationComplete,\r\n ApiTranslationBook,\r\n ApiTranslationBookChapter,\r\n ApiTranslationBookChapterWords,\r\n ApiTranslationBooks,\r\n ApiTranslationComplete,\r\n ChapterVerse,\r\n ChapterWord,\r\n SimpleChapterVerse,\r\n SimpleChapterWord,\r\n TranslationChapterReference,\r\n} from './types.gen.js';\r\n\r\n/**\r\n * Options for the FreeUseBibleApi class.\r\n */\r\nexport interface FreeUseBibleApiOptions {\r\n /**\r\n * The API endpoint to use for the requests. If not provided, the default endpoint will be used.\r\n */\r\n endpoint?: string;\r\n\r\n /**\r\n * Whether to cache responses in memory.\r\n *\r\n * Defaults to `true`.\r\n */\r\n useCache?: boolean;\r\n}\r\n\r\n/**\r\n * Options for the `getChapterText` method.\r\n */\r\nexport interface GetChapterTextOptions {\r\n /**\r\n * Whether to omit verse numbers from the returned text.\r\n * Defaults to `false`.\r\n */\r\n omitVerseNumbers?: boolean;\r\n\r\n /**\r\n * Whether to omit the chapter reference from the returned text.\r\n */\r\n omitReference?: boolean;\r\n}\r\n\r\n/**\r\n * Options for the `getVerseText` method.\r\n */\r\nexport interface GetVerseTextOptions {\r\n /**\r\n * Whether to omit the chapter reference from the returned text.\r\n */\r\n omitReference?: boolean;\r\n}\r\n\r\n/**\r\n * A word-level annotation, paired with the text of the verse that it covers.\r\n */\r\nexport interface AnnotatedWord extends ChapterWord {\r\n /**\r\n * The text that the annotation applies to.\r\n */\r\n text: string;\r\n}\r\n\r\n/**\r\n * A word-level annotation in a simplified chapter, paired with the text of the verse that it covers.\r\n */\r\nexport interface SimpleAnnotatedWord extends SimpleChapterWord {\r\n /**\r\n * The text that the annotation applies to.\r\n */\r\n text: string;\r\n}\r\n\r\n/**\r\n * A reference to a specific verse in a Bible translation, commentary, or dataset.\r\n */\r\nexport interface VerseReference {\r\n /**\r\n * The chapter number of the reference. This should be a positive integer.\r\n */\r\n chapter: number;\r\n\r\n /**\r\n * The verse number of the reference.\r\n *\r\n * If omitted, then the reference refers to the entire chapter rather than a specific verse.\r\n */\r\n verse?: number;\r\n\r\n /**\r\n * The ending verse number of the reference, for references that span multiple verses. This should be greater than or equal to the `verse` property if it is provided.\r\n */\r\n endVerse?: number;\r\n\r\n /**\r\n * The ending chapter number of the reference, for references that span multiple chapters. This should be greater than or equal to the `chapter` property if it is provided.\r\n */\r\n endChapter?: number;\r\n}\r\n\r\n/**\r\n * A client for interacting with the [Free Use Bible API](https://bible.helloao.org/).\r\n *\r\n * This API provides access to a large collection of Bible translations, commentaries, and datasets that are free to use.\r\n */\r\nexport class FreeUseBibleApi {\r\n endpoint: string = 'https://bible.helloao.org/';\r\n private _responseCache = new Map<string, Promise<unknown>>();\r\n private _useCache: boolean = true;\r\n\r\n constructor(options?: FreeUseBibleApiOptions) {\r\n this.endpoint = options?.endpoint ?? this.endpoint;\r\n this._useCache = options?.useCache ?? this._useCache;\r\n }\r\n\r\n /**\r\n * Gets the list of available Bible translations from the API.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getAvailableTranslations(\r\n endpoint?: string\r\n ): Promise<ApiAvailableTranslations> {\r\n return this._getJson<ApiAvailableTranslations>(\r\n 'api/available_translations.json',\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the complete content of a specific Bible translation.\r\n *\r\n * The results of this endpoint are very large, so the response is not cached.\r\n * @param translation The ID of the translation to get the complete content for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getCompleteTranslation(\r\n translation: string,\r\n endpoint?: string\r\n ): Promise<ApiTranslationComplete> {\r\n const encodedTranslation = encodeURIComponent(translation);\r\n return this._getJson<ApiTranslationComplete>(\r\n `api/${encodedTranslation}/complete.json`,\r\n endpoint,\r\n false\r\n );\r\n }\r\n\r\n /**\r\n * Gets the complete content of a specific Bible translation, using the simplified chapter format.\r\n *\r\n * The results of this endpoint are very large, so the response is not cached.\r\n * @param translation The ID of the translation to get the complete content for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getSimpleCompleteTranslation(\r\n translation: string,\r\n endpoint?: string\r\n ): Promise<ApiSimpleTranslationComplete> {\r\n const encodedTranslation = encodeURIComponent(translation);\r\n return this._getJson<ApiSimpleTranslationComplete>(\r\n `api/${encodedTranslation}/complete.simple.json`,\r\n endpoint,\r\n false\r\n );\r\n }\r\n\r\n /**\r\n * Gets the list of available Bible commentaries from the API.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getAvailableCommentaries(\r\n endpoint?: string\r\n ): Promise<ApiAvailableTranslations> {\r\n return this._getJson<ApiAvailableTranslations>(\r\n 'api/available_commentaries.json',\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the list of available datasets from the API.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getAvailableDatasets(\r\n endpoint?: string\r\n ): Promise<ApiAvailableDatasets> {\r\n return this._getJson<ApiAvailableDatasets>(\r\n 'api/available_datasets.json',\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the list of books for a given Bible translation.\r\n * @param translation The ID of the translation to get the books for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getTranslationBooks(\r\n translation: string,\r\n endpoint?: string\r\n ): Promise<ApiTranslationBooks> {\r\n const encodedTranslation = encodeURIComponent(translation);\r\n return this._getJson<ApiTranslationBooks>(\r\n `api/${encodedTranslation}/books.json`,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the list of books for a given Bible commentary.\r\n * @param commentary The ID of the commentary to get the books for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getCommentaryBooks(\r\n commentary: string,\r\n endpoint?: string\r\n ): Promise<ApiTranslationBooks> {\r\n const encodedCommentary = encodeURIComponent(commentary);\r\n return this._getJson<ApiTranslationBooks>(\r\n `api/c/${encodedCommentary}/books.json`,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the list of books for a given dataset.\r\n * @param dataset The ID of the dataset to get the books for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getDatasetBooks(\r\n dataset: string,\r\n endpoint?: string\r\n ): Promise<ApiDatasetBooks> {\r\n const encodedDataset = encodeURIComponent(dataset);\r\n return this._getJson<ApiDatasetBooks>(\r\n `api/d/${encodedDataset}/books.json`,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the content of a specific chapter of a specific book for a specific Bible translation.\r\n * @param translation The ID of the translation to get the chapter for.\r\n * @param book The ID of the book to get the chapter for.\r\n * @param chapter The chapter number to get.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getTranslationBookChapter(\r\n translation: string,\r\n book: string,\r\n chapter: number | string,\r\n endpoint?: string\r\n ): Promise<ApiTranslationBookChapter> {\r\n const encodedTranslation = encodeURIComponent(translation);\r\n const encodedBook = encodeURIComponent(book);\r\n const encodedChapter = encodeURIComponent(String(chapter));\r\n return this._getJson<ApiTranslationBookChapter>(\r\n `api/${encodedTranslation}/${encodedBook}/${encodedChapter}.json`,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the word-level annotations (Strong's numbers and related source data) for a specific chapter of a specific book for a specific Bible translation.\r\n *\r\n * Only some translations have word-level annotations. This request will fail for chapters that don't have any.\r\n * Use `getChapterWords()` to get the annotations for a chapter that you have already loaded, which returns null instead of failing.\r\n * @param translation The ID of the translation to get the annotations for.\r\n * @param book The ID of the book to get the annotations for.\r\n * @param chapter The chapter number to get the annotations for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getTranslationBookChapterWords(\r\n translation: string,\r\n book: string,\r\n chapter: number | string,\r\n endpoint?: string\r\n ): Promise<ApiTranslationBookChapterWords> {\r\n const encodedTranslation = encodeURIComponent(translation);\r\n const encodedBook = encodeURIComponent(book);\r\n const encodedChapter = encodeURIComponent(String(chapter));\r\n return this._getJson<ApiTranslationBookChapterWords>(\r\n `api/${encodedTranslation}/${encodedBook}/${encodedChapter}.words.json`,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the word-level annotations for the given chapter, if it has any.\r\n * @param chapter The chapter to get the annotations for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The annotations for the chapter, or null if the chapter doesn't have any.\r\n */\r\n async getChapterWords(\r\n chapter: ApiTranslationBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiTranslationBookChapterWords | null> {\r\n if (!chapter.thisChapterWordsLink) {\r\n return null;\r\n }\r\n return this._getJson<ApiTranslationBookChapterWords>(\r\n chapter.thisChapterWordsLink,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the content of a specific chapter of a specific book for a specific Bible translation, using the simplified chapter format.\r\n *\r\n * In the simplified format, each verse's content is a single string instead of a list of formatted content, and footnotes, inline headings, the Words of Jesus, and poetry are represented as offset ranges into that string.\r\n * @param translation The ID of the translation to get the chapter for.\r\n * @param book The ID of the book to get the chapter for.\r\n * @param chapter The chapter number to get.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getSimpleTranslationBookChapter(\r\n translation: string,\r\n book: string,\r\n chapter: number | string,\r\n endpoint?: string\r\n ): Promise<ApiSimpleTranslationBookChapter> {\r\n const encodedTranslation = encodeURIComponent(translation);\r\n const encodedBook = encodeURIComponent(book);\r\n const encodedChapter = encodeURIComponent(String(chapter));\r\n return this._getJson<ApiSimpleTranslationBookChapter>(\r\n `api/${encodedTranslation}/${encodedBook}/${encodedChapter}.simple.json`,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the word-level annotations (Strong's numbers and related source data) for a specific chapter of a specific book for a specific Bible translation, with their offsets remapped onto the text of each simplified verse.\r\n *\r\n * Use this instead of `getTranslationBookChapterWords()` when working with the simplified chapter format, since the offsets in the regular annotations are anchored to a verse's content array instead of its plain text.\r\n * Use `getSimpleChapterWords()` to get the annotations for a simplified chapter that you have already loaded, which returns null instead of failing.\r\n * @param translation The ID of the translation to get the annotations for.\r\n * @param book The ID of the book to get the annotations for.\r\n * @param chapter The chapter number to get the annotations for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getSimpleTranslationBookChapterWords(\r\n translation: string,\r\n book: string,\r\n chapter: number | string,\r\n endpoint?: string\r\n ): Promise<ApiSimpleTranslationBookChapterWords> {\r\n const encodedTranslation = encodeURIComponent(translation);\r\n const encodedBook = encodeURIComponent(book);\r\n const encodedChapter = encodeURIComponent(String(chapter));\r\n return this._getJson<ApiSimpleTranslationBookChapterWords>(\r\n `api/${encodedTranslation}/${encodedBook}/${encodedChapter}.words.simple.json`,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the simplified version of a given chapter, if available.\r\n * @param chapter The chapter to get the simplified version of.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The simplified chapter, or null if simplified chapters aren't available for it.\r\n */\r\n getSimpleChapter(\r\n chapter: ApiCommentaryBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiSimpleCommentaryBookChapter | null>;\r\n /**\r\n * Gets the simplified version of a given chapter, if available.\r\n * @param chapter The chapter to get the simplified version of.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The simplified chapter, or null if simplified chapters aren't available for it.\r\n */\r\n getSimpleChapter(\r\n chapter: ApiTranslationBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiSimpleTranslationBookChapter | null>;\r\n async getSimpleChapter(\r\n chapter: ApiTranslationBookChapter | ApiCommentaryBookChapter,\r\n endpoint?: string\r\n ): Promise<\r\n ApiSimpleTranslationBookChapter | ApiSimpleCommentaryBookChapter | null\r\n > {\r\n if (!chapter.simpleChapterApiLink) {\r\n return null;\r\n }\r\n return this._getJson<\r\n ApiSimpleTranslationBookChapter | ApiSimpleCommentaryBookChapter\r\n >(chapter.simpleChapterApiLink, endpoint);\r\n }\r\n\r\n /**\r\n * Gets the word-level annotations for the given simplified chapter, if it has any.\r\n * @param chapter The simplified chapter to get the annotations for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The annotations for the chapter, or null if the chapter doesn't have any.\r\n */\r\n async getSimpleChapterWords(\r\n chapter: ApiSimpleTranslationBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiSimpleTranslationBookChapterWords | null> {\r\n if (!chapter.thisChapterWordsLink) {\r\n return null;\r\n }\r\n return this._getJson<ApiSimpleTranslationBookChapterWords>(\r\n chapter.thisChapterWordsLink,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the content of a specific chapter of a specific book for a specific Bible commentary.\r\n * @param commentary The ID of the commentary to get the chapter for.\r\n * @param book The ID of the book to get the chapter for.\r\n * @param chapter The chapter number to get.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getCommentaryBookChapter(\r\n commentary: string,\r\n book: string,\r\n chapter: number | string,\r\n endpoint?: string\r\n ): Promise<ApiTranslationBookChapter> {\r\n const encodedCommentary = encodeURIComponent(commentary);\r\n const encodedBook = encodeURIComponent(book);\r\n const encodedChapter = encodeURIComponent(String(chapter));\r\n return this._getJson<ApiTranslationBookChapter>(\r\n `api/c/${encodedCommentary}/${encodedBook}/${encodedChapter}.json`,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the content of a specific chapter of a specific book for a specific Bible commentary, using the simplified chapter format.\r\n * @param commentary The ID of the commentary to get the chapter for.\r\n * @param book The ID of the book to get the chapter for.\r\n * @param chapter The chapter number to get.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getSimpleCommentaryBookChapter(\r\n commentary: string,\r\n book: string,\r\n chapter: number | string,\r\n endpoint?: string\r\n ): Promise<ApiSimpleCommentaryBookChapter> {\r\n const encodedCommentary = encodeURIComponent(commentary);\r\n const encodedBook = encodeURIComponent(book);\r\n const encodedChapter = encodeURIComponent(String(chapter));\r\n return this._getJson<ApiSimpleCommentaryBookChapter>(\r\n `api/c/${encodedCommentary}/${encodedBook}/${encodedChapter}.simple.json`,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the content of a specific chapter of a specific book for a specific dataset.\r\n * @param dataset The ID of the dataset to get the chapter for.\r\n * @param book The ID of the book to get the chapter for.\r\n * @param chapter The chapter number to get.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n */\r\n async getDatasetBookChapter(\r\n dataset: string,\r\n book: string,\r\n chapter: number | string,\r\n endpoint?: string\r\n ): Promise<ApiDatasetBookChapter> {\r\n const encodedDataset = encodeURIComponent(dataset);\r\n const encodedBook = encodeURIComponent(book);\r\n const encodedChapter = encodeURIComponent(String(chapter));\r\n return this._getJson<ApiDatasetBookChapter>(\r\n `api/d/${encodedDataset}/${encodedBook}/${encodedChapter}.json`,\r\n endpoint\r\n );\r\n }\r\n\r\n /**\r\n * Gets the next chapter for a given chapter, if available.\r\n * @param chapter The chapter to get the next chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The next chapter, or null if there is no next chapter.\r\n */\r\n getNextChapter(\r\n chapter: ApiCommentaryBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiCommentaryBookChapter | null>;\r\n /**\r\n * Gets the next chapter for a given chapter, if available.\r\n * @param chapter The chapter to get the next chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The next chapter, or null if there is no next chapter.\r\n */\r\n getNextChapter(\r\n chapter: ApiTranslationBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiTranslationBookChapter | null>;\r\n /**\r\n * Gets the next chapter for a given chapter, if available.\r\n * @param chapter The chapter to get the next chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The next chapter, or null if there is no next chapter.\r\n */\r\n getNextChapter(\r\n chapter: ApiDatasetBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiDatasetBookChapter | null>;\r\n /**\r\n * Gets the next chapter for a given chapter, if available.\r\n * @param chapter The chapter to get the next chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The next chapter, or null if there is no next chapter.\r\n */\r\n getNextChapter(\r\n chapter: ApiSimpleCommentaryBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiSimpleCommentaryBookChapter | null>;\r\n /**\r\n * Gets the next chapter for a given chapter, if available.\r\n * @param chapter The chapter to get the next chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The next chapter, or null if there is no next chapter.\r\n */\r\n getNextChapter(\r\n chapter: ApiSimpleTranslationBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiSimpleTranslationBookChapter | null>;\r\n async getNextChapter(\r\n chapter:\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\r\n | ApiSimpleTranslationBookChapter\r\n | ApiSimpleCommentaryBookChapter,\r\n endpoint?: string\r\n ): Promise<\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\r\n | ApiSimpleTranslationBookChapter\r\n | ApiSimpleCommentaryBookChapter\r\n | null\r\n > {\r\n if (!chapter.nextChapterApiLink) {\r\n return null;\r\n }\r\n return this._getJson<\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\r\n | ApiSimpleTranslationBookChapter\r\n | ApiSimpleCommentaryBookChapter\r\n >(chapter.nextChapterApiLink, endpoint);\r\n }\r\n\r\n /**\r\n * Gets the previous chapter for a given chapter, if available.\r\n * @param chapter The chapter to get the previous chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The previous chapter, or null if there is no previous chapter.\r\n */\r\n getPreviousChapter(\r\n chapter: ApiCommentaryBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiCommentaryBookChapter | null>;\r\n /**\r\n * Gets the previous chapter for a given chapter, if available.\r\n * @param chapter The chapter to get the previous chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The previous chapter, or null if there is no previous chapter.\r\n */\r\n getPreviousChapter(\r\n chapter: ApiTranslationBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiTranslationBookChapter | null>;\r\n /**\r\n * Gets the previous chapter for a given chapter, if available.\r\n * @param chapter The chapter to get the previous chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The previous chapter, or null if there is no previous chapter.\r\n */\r\n getPreviousChapter(\r\n chapter: ApiDatasetBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiDatasetBookChapter | null>;\r\n /**\r\n * Gets the previous chapter for a given chapter, if available.\r\n * @param chapter The chapter to get the previous chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The previous chapter, or null if there is no previous chapter.\r\n */\r\n getPreviousChapter(\r\n chapter: ApiSimpleCommentaryBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiSimpleCommentaryBookChapter | null>;\r\n /**\r\n * Gets the previous chapter for a given chapter, if available.\r\n * @param chapter The chapter to get the previous chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The previous chapter, or null if there is no previous chapter.\r\n */\r\n getPreviousChapter(\r\n chapter: ApiSimpleTranslationBookChapter,\r\n endpoint?: string\r\n ): Promise<ApiSimpleTranslationBookChapter | null>;\r\n async getPreviousChapter(\r\n chapter:\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\r\n | ApiSimpleTranslationBookChapter\r\n | ApiSimpleCommentaryBookChapter,\r\n endpoint?: string\r\n ): Promise<\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\r\n | ApiSimpleTranslationBookChapter\r\n | ApiSimpleCommentaryBookChapter\r\n | null\r\n > {\r\n if (!chapter.previousChapterApiLink) {\r\n return null;\r\n }\r\n return this._getJson<\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\r\n | ApiSimpleTranslationBookChapter\r\n | ApiSimpleCommentaryBookChapter\r\n >(chapter.previousChapterApiLink, endpoint);\r\n }\r\n\r\n /**\r\n * Gets the first chapter for a given book, if available.\r\n * @param book The book to get the first chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The first chapter, or null if there is no first chapter.\r\n */\r\n getFirstChapter(\r\n book: ApiCommentaryBook,\r\n endpoint?: string\r\n ): Promise<ApiCommentaryBookChapter | null>;\r\n /**\r\n * Gets the first chapter for a given book, if available.\r\n * @param book The book to get the first chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The first chapter, or null if there is no first chapter.\r\n */\r\n getFirstChapter(\r\n book: ApiTranslationBook,\r\n endpoint?: string\r\n ): Promise<ApiTranslationBookChapter>;\r\n /**\r\n * Gets the first chapter for a given book, if available.\r\n * @param book The book to get the first chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The first chapter, or null if there is no first chapter.\r\n */\r\n getFirstChapter(\r\n book: ApiDatasetBook,\r\n endpoint?: string\r\n ): Promise<ApiDatasetBookChapter>;\r\n async getFirstChapter(\r\n book: ApiTranslationBook | ApiCommentaryBook | ApiDatasetBook,\r\n endpoint?: string\r\n ): Promise<\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\r\n | null\r\n > {\r\n if (!book.firstChapterApiLink) {\r\n return null;\r\n }\r\n return this._getJson<\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\r\n >(book.firstChapterApiLink, endpoint);\r\n }\r\n\r\n /**\r\n * Gets the last chapter for a given book, if available.\r\n * @param book The book to get the last chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The last chapter, or null if there is no last chapter.\r\n */\r\n getLastChapter(\r\n book: ApiCommentaryBook,\r\n endpoint?: string\r\n ): Promise<ApiCommentaryBookChapter | null>;\r\n /**\r\n * Gets the last chapter for a given book, if available.\r\n * @param book The book to get the last chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The last chapter, or null if there is no last chapter.\r\n */\r\n getLastChapter(\r\n book: ApiTranslationBook,\r\n endpoint?: string\r\n ): Promise<ApiTranslationBookChapter>;\r\n /**\r\n * Gets the last chapter for a given book, if available.\r\n * @param book The book to get the last chapter for.\r\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\r\n * @returns The last chapter, or null if there is no last chapter.\r\n */\r\n getLastChapter(\r\n book: ApiDatasetBook,\r\n endpoint?: string\r\n ): Promise<ApiDatasetBookChapter>;\r\n async getLastChapter(\r\n book: ApiTranslationBook | ApiCommentaryBook | ApiDatasetBook,\r\n endpoint?: string\r\n ): Promise<\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\r\n | null\r\n > {\r\n if (!book.lastChapterApiLink) {\r\n return null;\r\n }\r\n return this._getJson<\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\r\n >(book.lastChapterApiLink, endpoint);\r\n }\r\n\r\n /**\r\n * Formats a verse reference as a human-readable string.\r\n *\r\n * e.g. Genesis 1:1-2, John 3:16, Exodus 20-22, etc.\r\n *\r\n * @param book The book that the reference is for.\r\n * @param reference The reference to format.\r\n */\r\n formatReference(\r\n book: ApiTranslationBook,\r\n reference: VerseReference\r\n ): string {\r\n const bookName = book.name;\r\n const chapter = reference.chapter;\r\n const verse = reference.verse;\r\n const endChapter = reference.endChapter;\r\n const endVerse = reference.endVerse;\r\n\r\n let referenceStr = `${bookName} ${chapter}`;\r\n if (endChapter) {\r\n referenceStr += `-${endChapter}`;\r\n } else if (verse) {\r\n referenceStr += `:${verse}`;\r\n if (endVerse) {\r\n referenceStr += `-${endVerse}`;\r\n }\r\n }\r\n return referenceStr;\r\n }\r\n\r\n /**\r\n * Gets the text for a verse.\r\n * @param verse The verse to get the text for.\r\n * @param options Options for getting the verse text.\r\n */\r\n getVerseText(verse: ChapterVerse): string {\r\n let content = '';\r\n for (let part of verse.content) {\r\n if (typeof part === 'string') {\r\n content += part;\r\n } else if (typeof part === 'object' && 'text' in part) {\r\n if (part.poem) {\r\n content += '\\n';\r\n for (let i = 0; i < part.poem; i++) {\r\n content += '\\t';\r\n }\r\n }\r\n content += part.text;\r\n } else if (typeof part === 'object' && 'lineBreak' in part) {\r\n content += '\\n';\r\n } else if (typeof part === 'object') {\r\n content += ' ';\r\n }\r\n }\r\n return content.trim();\r\n }\r\n\r\n /**\r\n * Gets the verse text for the given chapter.\r\n * By default, the returned text includes markers for verse numbers and a reference to the chapter, but these can be omitted by passing options to the `options` parameter.\r\n * @param chapter The chapter to get the text for.\r\n * @param options Options for getting the chapter text.\r\n */\r\n getChapterVerseText(\r\n chapter: ApiTranslationBookChapter,\r\n options: GetChapterTextOptions = {}\r\n ): string {\r\n let content = '';\r\n for (let chapterContent of chapter.chapter.content) {\r\n if (chapterContent.type === 'verse') {\r\n if (!options.omitVerseNumbers) {\r\n content += `[${chapterContent.number}] `;\r\n }\r\n content += this.getVerseText(chapterContent) + ' ';\r\n } else if (chapterContent.type === 'line_break') {\r\n content = content.trim() + '\\n';\r\n }\r\n }\r\n\r\n if (!options.omitReference) {\r\n content = `${this.formatReference(chapter.book, {\r\n chapter: chapter.chapter.number,\r\n })}\\n${content.trim()}`;\r\n }\r\n\r\n return content.trim();\r\n }\r\n\r\n /**\r\n * Gets the verse text for the given simplified chapter.\r\n * By default, the returned text includes markers for verse numbers and a reference to the chapter, but these can be omitted by passing options to the `options` parameter.\r\n * @param chapter The simplified chapter to get the text for.\r\n * @param options Options for getting the chapter text.\r\n */\r\n getSimpleChapterVerseText(\r\n chapter: ApiSimpleTranslationBookChapter,\r\n options: GetChapterTextOptions = {}\r\n ): string {\r\n let content = '';\r\n for (let chapterContent of chapter.chapter.content) {\r\n if (chapterContent.type === 'verse') {\r\n if (!options.omitVerseNumbers) {\r\n content += `[${chapterContent.number}] `;\r\n }\r\n content += chapterContent.text.trim() + ' ';\r\n } else if (chapterContent.type === 'line_break') {\r\n content = content.trim() + '\\n';\r\n }\r\n }\r\n\r\n if (!options.omitReference) {\r\n content = `${this.formatReference(chapter.book, {\r\n chapter: chapter.chapter.number,\r\n })}\\n${content.trim()}`;\r\n }\r\n\r\n return content.trim();\r\n }\r\n\r\n /**\r\n * Gets the text that the given word-level annotation applies to.\r\n *\r\n * Annotations are anchored to a range of characters in a single item of the verse's content,\r\n * so that the ranges stay correct for verses whose content is split into multiple items,\r\n * such as poem lines and the words of Jesus.\r\n * @param verse The verse that the annotation is in.\r\n * @param word The annotation to get the text for.\r\n * @returns The annotated text, or an empty string if the annotation doesn't point at any text.\r\n */\r\n getWordText(verse: ChapterVerse, word: ChapterWord): string {\r\n const content = verse.content[word.contentIndex];\r\n\r\n if (typeof content === 'string') {\r\n return content.slice(word.start, word.end);\r\n } else if (\r\n typeof content === 'object' &&\r\n content !== null &&\r\n 'text' in content\r\n ) {\r\n return content.text.slice(word.start, word.end);\r\n }\r\n\r\n // Line breaks, inline headings, and footnote references have no text of their own.\r\n return '';\r\n }\r\n\r\n /**\r\n * Gets the word-level annotations for the given verse, paired with the text that each one applies to.\r\n * @param verse The verse to get the annotations for.\r\n * @param words The annotations for the chapter that the verse is in.\r\n * @returns The annotations for the verse, in the order that they occur. Empty if the verse has no annotations.\r\n */\r\n getVerseWords(\r\n verse: ChapterVerse,\r\n words: ApiTranslationBookChapterWords\r\n ): AnnotatedWord[] {\r\n const verseWords = words.verses[verse.number.toString()] ?? [];\r\n\r\n return verseWords.map((word) => ({\r\n ...word,\r\n text: this.getWordText(verse, word),\r\n }));\r\n }\r\n\r\n /**\r\n * Gets the text that the given simplified word-level annotation applies to.\r\n * @param verse The simplified verse that the annotation is in.\r\n * @param word The annotation to get the text for.\r\n * @returns The annotated text.\r\n */\r\n getSimpleWordText(\r\n verse: SimpleChapterVerse,\r\n word: SimpleChapterWord\r\n ): string {\r\n return verse.text.slice(word.start, word.end);\r\n }\r\n\r\n /**\r\n * Gets the word-level annotations for the given simplified verse, paired with the text that each one applies to.\r\n * @param verse The simplified verse to get the annotations for.\r\n * @param words The simplified annotations for the chapter that the verse is in.\r\n * @returns The annotations for the verse, in the order that they occur. Empty if the verse has no annotations.\r\n */\r\n getSimpleVerseWords(\r\n verse: SimpleChapterVerse,\r\n words: ApiSimpleTranslationBookChapterWords\r\n ): SimpleAnnotatedWord[] {\r\n const verseWords = words.verses[verse.number.toString()] ?? [];\r\n\r\n return verseWords.map((word) => ({\r\n ...word,\r\n text: this.getSimpleWordText(verse, word),\r\n }));\r\n }\r\n\r\n private _getJson<T>(\r\n path: string,\r\n endpoint: string | undefined,\r\n useCache: boolean = true\r\n ): Promise<T> {\r\n const url = this._buildUrl(path, endpoint);\r\n const existing = this._responseCache.get(url) as Promise<T> | undefined;\r\n if (existing) {\r\n return existing;\r\n }\r\n\r\n const request: Promise<T> = fetch(url)\r\n .then(async (response) => {\r\n if (response.status < 200 || response.status >= 300) {\r\n throw new Error(\r\n `Failed request to ${url}. Status: ${response.status} ${response.statusText}`\r\n );\r\n }\r\n return await response.json();\r\n })\r\n .catch((error) => {\r\n this._responseCache.delete(url);\r\n throw error;\r\n });\r\n\r\n if (this._useCache && useCache) {\r\n this._responseCache.set(url, request);\r\n }\r\n return request;\r\n }\r\n\r\n private _buildUrl(path: string, endpoint?: string): string {\r\n if (/^https?:\\/\\//i.test(path)) {\r\n return path;\r\n }\r\n\r\n const baseEndpoint = endpoint ?? this.endpoint;\r\n return new URL(path, baseEndpoint).href;\r\n }\r\n}\r\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import type {\n ApiAvailableCommentaries,\n ApiAvailableDatasets,\n ApiAvailableTranslations,\n ApiCommentaryBook,\n ApiCommentaryBookChapter,\n ApiCommentaryBooks,\n ApiDatasetBook,\n ApiDatasetBookChapter,\n ApiDatasetBooks,\n ApiDatasetEntityBookChapter,\n ApiDatasetEvent,\n ApiDatasetEvents,\n ApiDatasetPeople,\n ApiDatasetPeopleGroup,\n ApiDatasetPeopleGroups,\n ApiDatasetPerson,\n ApiDatasetPlace,\n ApiDatasetPlaces,\n ApiSimpleCommentaryBookChapter,\n ApiSimpleTranslationBookChapter,\n ApiSimpleTranslationBookChapterWords,\n ApiSimpleTranslationComplete,\n ApiTranslationBook,\n ApiTranslationBookChapter,\n ApiTranslationBookChapterAudioTimings,\n ApiTranslationBookChapterWords,\n ApiTranslationBooks,\n ApiTranslationComplete,\n ChapterVerse,\n ChapterWord,\n SimpleChapterVerse,\n SimpleChapterWord,\n SimpleTranslationCompleteChapter,\n TranslationChapterReference,\n TranslationCompleteChapter,\n} from './types.gen.js';\n\n/**\n * Options for the FreeUseBibleApi class.\n */\nexport interface FreeUseBibleApiOptions {\n /**\n * The API endpoint to use for the requests. If not provided, the default endpoint will be used.\n */\n endpoint?: string;\n\n /**\n * Whether to cache responses in memory.\n *\n * Defaults to `true`.\n */\n useCache?: boolean;\n}\n\n/**\n * Options for the `getChapterText` method.\n */\nexport interface GetChapterTextOptions {\n /**\n * Whether to omit verse numbers from the returned text.\n * Defaults to `false`.\n */\n omitVerseNumbers?: boolean;\n\n /**\n * Whether to omit the chapter reference from the returned text.\n */\n omitReference?: boolean;\n}\n\n/**\n * Options for the `getVerseText` method.\n */\nexport interface GetVerseTextOptions {\n /**\n * Whether to omit the chapter reference from the returned text.\n */\n omitReference?: boolean;\n}\n\n/**\n * A word-level annotation, paired with the text of the verse that it covers.\n */\nexport interface AnnotatedWord extends ChapterWord {\n /**\n * The text that the annotation applies to.\n */\n text: string;\n}\n\n/**\n * A word-level annotation in a simplified chapter, paired with the text of the verse that it covers.\n */\nexport interface SimpleAnnotatedWord extends SimpleChapterWord {\n /**\n * The text that the annotation applies to.\n */\n text: string;\n}\n\n/**\n * A reference to a specific verse in a Bible translation, commentary, or dataset.\n */\nexport interface VerseReference {\n /**\n * The chapter number of the reference. This should be a positive integer.\n */\n chapter: number;\n\n /**\n * The verse number of the reference.\n *\n * If omitted, then the reference refers to the entire chapter rather than a specific verse.\n */\n verse?: number;\n\n /**\n * The ending verse number of the reference, for references that span multiple verses. This should be greater than or equal to the `verse` property if it is provided.\n */\n endVerse?: number;\n\n /**\n * The ending chapter number of the reference, for references that span multiple chapters. This should be greater than or equal to the `chapter` property if it is provided.\n */\n endChapter?: number;\n}\n\n/**\n * A client for interacting with the [Free Use Bible API](https://bible.helloao.org/).\n *\n * This API provides access to a large collection of Bible translations, commentaries, and datasets that are free to use.\n */\nexport class FreeUseBibleApi {\n endpoint: string = 'https://bible.helloao.org/';\n private _responseCache = new Map<string, Promise<unknown>>();\n private _useCache: boolean = true;\n\n constructor(options?: FreeUseBibleApiOptions) {\n this.endpoint = options?.endpoint ?? this.endpoint;\n this._useCache = options?.useCache ?? this._useCache;\n }\n\n /**\n * Gets the list of available Bible translations from the API.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getAvailableTranslations(\n endpoint?: string\n ): Promise<ApiAvailableTranslations> {\n return this._getJson<ApiAvailableTranslations>(\n 'api/available_translations.json',\n endpoint\n );\n }\n\n /**\n * Gets the complete content of a specific Bible translation.\n *\n * The results of this endpoint are very large, so the response is not cached.\n * @param translation The ID of the translation to get the complete content for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getCompleteTranslation(\n translation: string,\n endpoint?: string\n ): Promise<ApiTranslationComplete> {\n const encodedTranslation = encodeURIComponent(translation);\n return this._getJson<ApiTranslationComplete>(\n `api/${encodedTranslation}/complete.json`,\n endpoint,\n false\n );\n }\n\n /**\n * Gets the complete content of a specific Bible translation, using the simplified chapter format.\n *\n * The results of this endpoint are very large, so the response is not cached.\n * @param translation The ID of the translation to get the complete content for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getSimpleCompleteTranslation(\n translation: string,\n endpoint?: string\n ): Promise<ApiSimpleTranslationComplete> {\n const encodedTranslation = encodeURIComponent(translation);\n return this._getJson<ApiSimpleTranslationComplete>(\n `api/${encodedTranslation}/complete.simple.json`,\n endpoint,\n false\n );\n }\n\n /**\n * Gets the list of available Bible commentaries from the API.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getAvailableCommentaries(\n endpoint?: string\n ): Promise<ApiAvailableCommentaries> {\n return this._getJson<ApiAvailableCommentaries>(\n 'api/available_commentaries.json',\n endpoint\n );\n }\n\n /**\n * Gets the list of available datasets from the API.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getAvailableDatasets(\n endpoint?: string\n ): Promise<ApiAvailableDatasets> {\n return this._getJson<ApiAvailableDatasets>(\n 'api/available_datasets.json',\n endpoint\n );\n }\n\n /**\n * Gets the list of books for a given Bible translation.\n * @param translation The ID of the translation to get the books for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getTranslationBooks(\n translation: string,\n endpoint?: string\n ): Promise<ApiTranslationBooks> {\n const encodedTranslation = encodeURIComponent(translation);\n return this._getJson<ApiTranslationBooks>(\n `api/${encodedTranslation}/books.json`,\n endpoint\n );\n }\n\n /**\n * Gets the list of books for a given Bible commentary.\n * @param commentary The ID of the commentary to get the books for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getCommentaryBooks(\n commentary: string,\n endpoint?: string\n ): Promise<ApiCommentaryBooks> {\n const encodedCommentary = encodeURIComponent(commentary);\n return this._getJson<ApiCommentaryBooks>(\n `api/c/${encodedCommentary}/books.json`,\n endpoint\n );\n }\n\n /**\n * Gets the list of books for a given dataset.\n * @param dataset The ID of the dataset to get the books for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getDatasetBooks(\n dataset: string,\n endpoint?: string\n ): Promise<ApiDatasetBooks> {\n const encodedDataset = encodeURIComponent(dataset);\n return this._getJson<ApiDatasetBooks>(\n `api/d/${encodedDataset}/books.json`,\n endpoint\n );\n }\n\n /**\n * Gets the list of people for a given dataset.\n * @param dataset The ID of the dataset to get the people for.\n * @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.\n */\n async getDatasetPeople(\n dataset: string,\n endpoint?: string\n ): Promise<ApiDatasetPeople> {\n const encodedDataset = encodeURIComponent(dataset);\n return this._getJson<ApiDatasetPeople>(\n `api/d/${encodedDataset}/people.json`,\n endpoint\n );\n }\n\n /**\n * Gets the information about a specific person for a given dataset.\n * Includes the Bible references that mention the person and their relationships\n * to other people, places, events, and people groups.\n * @param dataset The ID of the dataset to get the person for.\n * @param person The ID of the person to get.\n * @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.\n */\n async getDatasetPerson(\n dataset: string,\n person: string,\n endpoint?: string\n ): Promise<ApiDatasetPerson> {\n const encodedDataset = encodeURIComponent(dataset);\n const encodedPerson = encodeURIComponent(person);\n return this._getJson<ApiDatasetPerson>(\n `api/d/${encodedDataset}/people/${encodedPerson}.json`,\n endpoint\n );\n }\n\n /**\n * Gets the list of places for a given dataset.\n * @param dataset The ID of the dataset to get the places for.\n * @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.\n */\n async getDatasetPlaces(\n dataset: string,\n endpoint?: string\n ): Promise<ApiDatasetPlaces> {\n const encodedDataset = encodeURIComponent(dataset);\n return this._getJson<ApiDatasetPlaces>(\n `api/d/${encodedDataset}/places.json`,\n endpoint\n );\n }\n\n /**\n * Gets the information about a specific place for a given dataset.\n * Includes the Bible references that mention the place and its related people and events.\n * @param dataset The ID of the dataset to get the place for.\n * @param place The ID of the place to get.\n * @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.\n */\n async getDatasetPlace(\n dataset: string,\n place: string,\n endpoint?: string\n ): Promise<ApiDatasetPlace> {\n const encodedDataset = encodeURIComponent(dataset);\n const encodedPlace = encodeURIComponent(place);\n return this._getJson<ApiDatasetPlace>(\n `api/d/${encodedDataset}/places/${encodedPlace}.json`,\n endpoint\n );\n }\n\n /**\n * Gets the list of events for a given dataset.\n * @param dataset The ID of the dataset to get the events for.\n * @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.\n */\n async getDatasetEvents(\n dataset: string,\n endpoint?: string\n ): Promise<ApiDatasetEvents> {\n const encodedDataset = encodeURIComponent(dataset);\n return this._getJson<ApiDatasetEvents>(\n `api/d/${encodedDataset}/events.json`,\n endpoint\n );\n }\n\n /**\n * Gets the information about a specific event for a given dataset.\n * Includes the Bible references that describe the event and its related people, places, and people groups.\n * @param dataset The ID of the dataset to get the event for.\n * @param event The ID of the event to get.\n * @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.\n */\n async getDatasetEvent(\n dataset: string,\n event: string,\n endpoint?: string\n ): Promise<ApiDatasetEvent> {\n const encodedDataset = encodeURIComponent(dataset);\n const encodedEvent = encodeURIComponent(event);\n return this._getJson<ApiDatasetEvent>(\n `api/d/${encodedDataset}/events/${encodedEvent}.json`,\n endpoint\n );\n }\n\n /**\n * Gets the list of people groups for a given dataset.\n * @param dataset The ID of the dataset to get the people groups for.\n * @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.\n */\n async getDatasetPeopleGroups(\n dataset: string,\n endpoint?: string\n ): Promise<ApiDatasetPeopleGroups> {\n const encodedDataset = encodeURIComponent(dataset);\n return this._getJson<ApiDatasetPeopleGroups>(\n `api/d/${encodedDataset}/groups.json`,\n endpoint\n );\n }\n\n /**\n * Gets the information about a specific people group for a given dataset.\n * Includes the members of the group and the events that the group participated in.\n * @param dataset The ID of the dataset to get the people group for.\n * @param group The ID of the people group to get.\n * @param endpoint The endpoint to use for the request. If not provided, then the default endpoint will be used.\n */\n async getDatasetPeopleGroup(\n dataset: string,\n group: string,\n endpoint?: string\n ): Promise<ApiDatasetPeopleGroup> {\n const encodedDataset = encodeURIComponent(dataset);\n const encodedGroup = encodeURIComponent(group);\n return this._getJson<ApiDatasetPeopleGroup>(\n `api/d/${encodedDataset}/groups/${encodedGroup}.json`,\n endpoint\n );\n }\n\n /**\n * Gets the content of a specific chapter of a specific book for a specific Bible translation.\n * @param translation The ID of the translation to get the chapter for.\n * @param book The ID of the book to get the chapter for.\n * @param chapter The chapter number to get.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getTranslationBookChapter(\n translation: string,\n book: string,\n chapter: number | string,\n endpoint?: string\n ): Promise<ApiTranslationBookChapter> {\n const encodedTranslation = encodeURIComponent(translation);\n const encodedBook = encodeURIComponent(book);\n const encodedChapter = encodeURIComponent(String(chapter));\n return this._getJson<ApiTranslationBookChapter>(\n `api/${encodedTranslation}/${encodedBook}/${encodedChapter}.json`,\n endpoint\n );\n }\n\n /**\n * Gets the audio timings for a specific chapter, read by a specific reader.\n *\n * Only some chapters have audio timings. Available readers are the keys of the chapter's `thisChapterAudioTimings` property.\n * @param translation The ID of the translation to get the audio timings for.\n * @param book The ID of the book to get the audio timings for.\n * @param chapter The chapter number to get the audio timings for.\n * @param reader The ID of the reader to get the audio timings for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getTranslationBookChapterAudioTimings(\n translation: string,\n book: string,\n chapter: number | string,\n reader: string,\n endpoint?: string\n ): Promise<ApiTranslationBookChapterAudioTimings> {\n const encodedTranslation = encodeURIComponent(translation);\n const encodedBook = encodeURIComponent(book);\n const encodedChapter = encodeURIComponent(String(chapter));\n const encodedReader = encodeURIComponent(reader);\n return this._getJson<ApiTranslationBookChapterAudioTimings>(\n `api/${encodedTranslation}/${encodedBook}/${encodedChapter}.${encodedReader}.audioTimings.json`,\n endpoint\n );\n }\n\n /**\n * Gets the word-level annotations (Strong's numbers and related source data) for a specific chapter of a specific book for a specific Bible translation.\n *\n * Only some translations have word-level annotations. This request will fail for chapters that don't have any.\n * Use `getChapterWords()` to get the annotations for a chapter that you have already loaded, which returns null instead of failing.\n * @param translation The ID of the translation to get the annotations for.\n * @param book The ID of the book to get the annotations for.\n * @param chapter The chapter number to get the annotations for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getTranslationBookChapterWords(\n translation: string,\n book: string,\n chapter: number | string,\n endpoint?: string\n ): Promise<ApiTranslationBookChapterWords> {\n const encodedTranslation = encodeURIComponent(translation);\n const encodedBook = encodeURIComponent(book);\n const encodedChapter = encodeURIComponent(String(chapter));\n return this._getJson<ApiTranslationBookChapterWords>(\n `api/${encodedTranslation}/${encodedBook}/${encodedChapter}.words.json`,\n endpoint\n );\n }\n\n /**\n * Gets the word-level annotations for the given chapter, if it has any.\n * @param chapter The chapter to get the annotations for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The annotations for the chapter, or null if the chapter doesn't have any.\n */\n getChapterWords(\n chapter: ApiTranslationBookChapter,\n endpoint?: string\n ): Promise<ApiTranslationBookChapterWords | null>;\n /**\n * Gets the word-level annotations for the given chapter of a complete translation download, if it has any.\n * @param chapter The chapter to get the annotations for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The annotations for the chapter, or null if the chapter doesn't have any.\n */\n getChapterWords(\n chapter: TranslationCompleteChapter,\n endpoint?: string\n ): Promise<ApiTranslationBookChapterWords | null>;\n async getChapterWords(\n chapter: ApiTranslationBookChapter | TranslationCompleteChapter,\n endpoint?: string\n ): Promise<ApiTranslationBookChapterWords | null> {\n if (!chapter.thisChapterWordsLink) {\n return null;\n }\n return this._getJson<ApiTranslationBookChapterWords>(\n chapter.thisChapterWordsLink,\n endpoint\n );\n }\n\n /**\n * Gets the content of a specific chapter of a specific book for a specific Bible translation, using the simplified chapter format.\n *\n * In the simplified format, each verse's content is a single string instead of a list of formatted content, and footnotes, inline headings, the Words of Jesus, and poetry are represented as offset ranges into that string.\n * @param translation The ID of the translation to get the chapter for.\n * @param book The ID of the book to get the chapter for.\n * @param chapter The chapter number to get.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getSimpleTranslationBookChapter(\n translation: string,\n book: string,\n chapter: number | string,\n endpoint?: string\n ): Promise<ApiSimpleTranslationBookChapter> {\n const encodedTranslation = encodeURIComponent(translation);\n const encodedBook = encodeURIComponent(book);\n const encodedChapter = encodeURIComponent(String(chapter));\n return this._getJson<ApiSimpleTranslationBookChapter>(\n `api/${encodedTranslation}/${encodedBook}/${encodedChapter}.simple.json`,\n endpoint\n );\n }\n\n /**\n * Gets the word-level annotations (Strong's numbers and related source data) for a specific chapter of a specific book for a specific Bible translation, with their offsets remapped onto the text of each simplified verse.\n *\n * Use this instead of `getTranslationBookChapterWords()` when working with the simplified chapter format, since the offsets in the regular annotations are anchored to a verse's content array instead of its plain text.\n * Use `getSimpleChapterWords()` to get the annotations for a simplified chapter that you have already loaded, which returns null instead of failing.\n * @param translation The ID of the translation to get the annotations for.\n * @param book The ID of the book to get the annotations for.\n * @param chapter The chapter number to get the annotations for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getSimpleTranslationBookChapterWords(\n translation: string,\n book: string,\n chapter: number | string,\n endpoint?: string\n ): Promise<ApiSimpleTranslationBookChapterWords> {\n const encodedTranslation = encodeURIComponent(translation);\n const encodedBook = encodeURIComponent(book);\n const encodedChapter = encodeURIComponent(String(chapter));\n return this._getJson<ApiSimpleTranslationBookChapterWords>(\n `api/${encodedTranslation}/${encodedBook}/${encodedChapter}.words.simple.json`,\n endpoint\n );\n }\n\n /**\n * Gets the simplified version of a given chapter, if available.\n * @param chapter The chapter to get the simplified version of.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The simplified chapter, or null if simplified chapters aren't available for it.\n */\n getSimpleChapter(\n chapter: ApiCommentaryBookChapter,\n endpoint?: string\n ): Promise<ApiSimpleCommentaryBookChapter | null>;\n /**\n * Gets the simplified version of a given chapter, if available.\n * @param chapter The chapter to get the simplified version of.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The simplified chapter, or null if simplified chapters aren't available for it.\n */\n getSimpleChapter(\n chapter: ApiTranslationBookChapter,\n endpoint?: string\n ): Promise<ApiSimpleTranslationBookChapter | null>;\n async getSimpleChapter(\n chapter: ApiTranslationBookChapter | ApiCommentaryBookChapter,\n endpoint?: string\n ): Promise<\n ApiSimpleTranslationBookChapter | ApiSimpleCommentaryBookChapter | null\n > {\n if (!chapter.simpleChapterApiLink) {\n return null;\n }\n return this._getJson<\n ApiSimpleTranslationBookChapter | ApiSimpleCommentaryBookChapter\n >(chapter.simpleChapterApiLink, endpoint);\n }\n\n /**\n * Gets the word-level annotations for the given simplified chapter, if it has any.\n * @param chapter The simplified chapter to get the annotations for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The annotations for the chapter, or null if the chapter doesn't have any.\n */\n getSimpleChapterWords(\n chapter: ApiSimpleTranslationBookChapter,\n endpoint?: string\n ): Promise<ApiSimpleTranslationBookChapterWords | null>;\n /**\n * Gets the word-level annotations for the given chapter of a simplified complete translation download, if it has any.\n * @param chapter The chapter to get the annotations for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The annotations for the chapter, or null if the chapter doesn't have any.\n */\n getSimpleChapterWords(\n chapter: SimpleTranslationCompleteChapter,\n endpoint?: string\n ): Promise<ApiSimpleTranslationBookChapterWords | null>;\n async getSimpleChapterWords(\n chapter:\n | ApiSimpleTranslationBookChapter\n | SimpleTranslationCompleteChapter,\n endpoint?: string\n ): Promise<ApiSimpleTranslationBookChapterWords | null> {\n if (!chapter.thisChapterWordsLink) {\n return null;\n }\n return this._getJson<ApiSimpleTranslationBookChapterWords>(\n chapter.thisChapterWordsLink,\n endpoint\n );\n }\n\n /**\n * Gets the content of a specific chapter of a specific book for a specific Bible commentary.\n * @param commentary The ID of the commentary to get the chapter for.\n * @param book The ID of the book to get the chapter for.\n * @param chapter The chapter number to get.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getCommentaryBookChapter(\n commentary: string,\n book: string,\n chapter: number | string,\n endpoint?: string\n ): Promise<ApiCommentaryBookChapter> {\n const encodedCommentary = encodeURIComponent(commentary);\n const encodedBook = encodeURIComponent(book);\n const encodedChapter = encodeURIComponent(String(chapter));\n return this._getJson<ApiCommentaryBookChapter>(\n `api/c/${encodedCommentary}/${encodedBook}/${encodedChapter}.json`,\n endpoint\n );\n }\n\n /**\n * Gets the content of a specific chapter of a specific book for a specific Bible commentary, using the simplified chapter format.\n * @param commentary The ID of the commentary to get the chapter for.\n * @param book The ID of the book to get the chapter for.\n * @param chapter The chapter number to get.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getSimpleCommentaryBookChapter(\n commentary: string,\n book: string,\n chapter: number | string,\n endpoint?: string\n ): Promise<ApiSimpleCommentaryBookChapter> {\n const encodedCommentary = encodeURIComponent(commentary);\n const encodedBook = encodeURIComponent(book);\n const encodedChapter = encodeURIComponent(String(chapter));\n return this._getJson<ApiSimpleCommentaryBookChapter>(\n `api/c/${encodedCommentary}/${encodedBook}/${encodedChapter}.simple.json`,\n endpoint\n );\n }\n\n /**\n * Gets the content of a specific chapter of a specific book for a specific dataset.\n *\n * For cross reference datasets, this is the list of cross references for each verse\n * in the chapter. For entity datasets (such as \"theographic\"), this is the people,\n * places, and events that appear in the chapter.\n * @param dataset The ID of the dataset to get the chapter for.\n * @param book The ID of the book to get the chapter for.\n * @param chapter The chapter number to get.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n */\n async getDatasetBookChapter(\n dataset: string,\n book: string,\n chapter: number | string,\n endpoint?: string\n ): Promise<ApiDatasetBookChapter | ApiDatasetEntityBookChapter> {\n const encodedDataset = encodeURIComponent(dataset);\n const encodedBook = encodeURIComponent(book);\n const encodedChapter = encodeURIComponent(String(chapter));\n return this._getJson<\n ApiDatasetBookChapter | ApiDatasetEntityBookChapter\n >(\n `api/d/${encodedDataset}/${encodedBook}/${encodedChapter}.json`,\n endpoint\n );\n }\n\n /**\n * Gets the next chapter for a given chapter, if available.\n * @param chapter The chapter to get the next chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The next chapter, or null if there is no next chapter.\n */\n getNextChapter(\n chapter: ApiCommentaryBookChapter,\n endpoint?: string\n ): Promise<ApiCommentaryBookChapter | null>;\n /**\n * Gets the next chapter for a given chapter, if available.\n * @param chapter The chapter to get the next chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The next chapter, or null if there is no next chapter.\n */\n getNextChapter(\n chapter: ApiTranslationBookChapter,\n endpoint?: string\n ): Promise<ApiTranslationBookChapter | null>;\n /**\n * Gets the next chapter for a given chapter, if available.\n * @param chapter The chapter to get the next chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The next chapter, or null if there is no next chapter.\n */\n getNextChapter(\n chapter: ApiDatasetBookChapter | ApiDatasetEntityBookChapter,\n endpoint?: string\n ): Promise<\n ApiDatasetBookChapter | ApiDatasetEntityBookChapter | null\n >;\n /**\n * Gets the next chapter for a given chapter, if available.\n * @param chapter The chapter to get the next chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The next chapter, or null if there is no next chapter.\n */\n getNextChapter(\n chapter: ApiSimpleCommentaryBookChapter,\n endpoint?: string\n ): Promise<ApiSimpleCommentaryBookChapter | null>;\n /**\n * Gets the next chapter for a given chapter, if available.\n * @param chapter The chapter to get the next chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The next chapter, or null if there is no next chapter.\n */\n getNextChapter(\n chapter: ApiSimpleTranslationBookChapter,\n endpoint?: string\n ): Promise<ApiSimpleTranslationBookChapter | null>;\n async getNextChapter(\n chapter:\n | ApiTranslationBookChapter\n | ApiCommentaryBookChapter\n | ApiDatasetBookChapter\n | ApiDatasetEntityBookChapter\n | ApiSimpleTranslationBookChapter\n | ApiSimpleCommentaryBookChapter,\n endpoint?: string\n ): Promise<\n | ApiTranslationBookChapter\n | ApiCommentaryBookChapter\n | ApiDatasetBookChapter\n | ApiDatasetEntityBookChapter\n | ApiSimpleTranslationBookChapter\n | ApiSimpleCommentaryBookChapter\n | null\n > {\n if (!chapter.nextChapterApiLink) {\n return null;\n }\n return this._getJson<\n | ApiTranslationBookChapter\n | ApiCommentaryBookChapter\n | ApiDatasetBookChapter\n | ApiDatasetEntityBookChapter\n | ApiSimpleTranslationBookChapter\n | ApiSimpleCommentaryBookChapter\n >(chapter.nextChapterApiLink, endpoint);\n }\n\n /**\n * Gets the previous chapter for a given chapter, if available.\n * @param chapter The chapter to get the previous chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The previous chapter, or null if there is no previous chapter.\n */\n getPreviousChapter(\n chapter: ApiCommentaryBookChapter,\n endpoint?: string\n ): Promise<ApiCommentaryBookChapter | null>;\n /**\n * Gets the previous chapter for a given chapter, if available.\n * @param chapter The chapter to get the previous chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The previous chapter, or null if there is no previous chapter.\n */\n getPreviousChapter(\n chapter: ApiTranslationBookChapter,\n endpoint?: string\n ): Promise<ApiTranslationBookChapter | null>;\n /**\n * Gets the previous chapter for a given chapter, if available.\n * @param chapter The chapter to get the previous chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The previous chapter, or null if there is no previous chapter.\n */\n getPreviousChapter(\n chapter: ApiDatasetBookChapter | ApiDatasetEntityBookChapter,\n endpoint?: string\n ): Promise<\n ApiDatasetBookChapter | ApiDatasetEntityBookChapter | null\n >;\n /**\n * Gets the previous chapter for a given chapter, if available.\n * @param chapter The chapter to get the previous chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The previous chapter, or null if there is no previous chapter.\n */\n getPreviousChapter(\n chapter: ApiSimpleCommentaryBookChapter,\n endpoint?: string\n ): Promise<ApiSimpleCommentaryBookChapter | null>;\n /**\n * Gets the previous chapter for a given chapter, if available.\n * @param chapter The chapter to get the previous chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The previous chapter, or null if there is no previous chapter.\n */\n getPreviousChapter(\n chapter: ApiSimpleTranslationBookChapter,\n endpoint?: string\n ): Promise<ApiSimpleTranslationBookChapter | null>;\n async getPreviousChapter(\n chapter:\n | ApiTranslationBookChapter\n | ApiCommentaryBookChapter\n | ApiDatasetBookChapter\n | ApiDatasetEntityBookChapter\n | ApiSimpleTranslationBookChapter\n | ApiSimpleCommentaryBookChapter,\n endpoint?: string\n ): Promise<\n | ApiTranslationBookChapter\n | ApiCommentaryBookChapter\n | ApiDatasetBookChapter\n | ApiDatasetEntityBookChapter\n | ApiSimpleTranslationBookChapter\n | ApiSimpleCommentaryBookChapter\n | null\n > {\n if (!chapter.previousChapterApiLink) {\n return null;\n }\n return this._getJson<\n | ApiTranslationBookChapter\n | ApiCommentaryBookChapter\n | ApiDatasetBookChapter\n | ApiDatasetEntityBookChapter\n | ApiSimpleTranslationBookChapter\n | ApiSimpleCommentaryBookChapter\n >(chapter.previousChapterApiLink, endpoint);\n }\n\n /**\n * Gets the first chapter for a given book, if available.\n * @param book The book to get the first chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The first chapter, or null if there is no first chapter.\n */\n getFirstChapter(\n book: ApiCommentaryBook,\n endpoint?: string\n ): Promise<ApiCommentaryBookChapter | null>;\n /**\n * Gets the first chapter for a given book, if available.\n * @param book The book to get the first chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The first chapter, or null if there is no first chapter.\n */\n getFirstChapter(\n book: ApiTranslationBook,\n endpoint?: string\n ): Promise<ApiTranslationBookChapter>;\n /**\n * Gets the first chapter for a given book, if available.\n * @param book The book to get the first chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The first chapter, or null if there is no first chapter.\n */\n getFirstChapter(\n book: ApiDatasetBook,\n endpoint?: string\n ): Promise<ApiDatasetBookChapter | ApiDatasetEntityBookChapter>;\n async getFirstChapter(\n book: ApiTranslationBook | ApiCommentaryBook | ApiDatasetBook,\n endpoint?: string\n ): Promise<\n | ApiTranslationBookChapter\n | ApiCommentaryBookChapter\n | ApiDatasetBookChapter\n | ApiDatasetEntityBookChapter\n | null\n > {\n if (!book.firstChapterApiLink) {\n return null;\n }\n return this._getJson<\n | ApiTranslationBookChapter\n | ApiCommentaryBookChapter\n | ApiDatasetBookChapter\n | ApiDatasetEntityBookChapter\n >(book.firstChapterApiLink, endpoint);\n }\n\n /**\n * Gets the last chapter for a given book, if available.\n * @param book The book to get the last chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The last chapter, or null if there is no last chapter.\n */\n getLastChapter(\n book: ApiCommentaryBook,\n endpoint?: string\n ): Promise<ApiCommentaryBookChapter | null>;\n /**\n * Gets the last chapter for a given book, if available.\n * @param book The book to get the last chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The last chapter, or null if there is no last chapter.\n */\n getLastChapter(\n book: ApiTranslationBook,\n endpoint?: string\n ): Promise<ApiTranslationBookChapter>;\n /**\n * Gets the last chapter for a given book, if available.\n * @param book The book to get the last chapter for.\n * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.\n * @returns The last chapter, or null if there is no last chapter.\n */\n getLastChapter(\n book: ApiDatasetBook,\n endpoint?: string\n ): Promise<ApiDatasetBookChapter | ApiDatasetEntityBookChapter>;\n async getLastChapter(\n book: ApiTranslationBook | ApiCommentaryBook | ApiDatasetBook,\n endpoint?: string\n ): Promise<\n | ApiTranslationBookChapter\n | ApiCommentaryBookChapter\n | ApiDatasetBookChapter\n | ApiDatasetEntityBookChapter\n | null\n > {\n if (!book.lastChapterApiLink) {\n return null;\n }\n return this._getJson<\n | ApiTranslationBookChapter\n | ApiCommentaryBookChapter\n | ApiDatasetBookChapter\n | ApiDatasetEntityBookChapter\n >(book.lastChapterApiLink, endpoint);\n }\n\n /**\n * Formats a verse reference as a human-readable string.\n *\n * e.g. Genesis 1:1-2, John 3:16, Exodus 20-22, etc.\n *\n * @param book The book that the reference is for.\n * @param reference The reference to format.\n */\n formatReference(\n book: ApiTranslationBook,\n reference: VerseReference\n ): string {\n const bookName = book.name;\n const chapter = reference.chapter;\n const verse = reference.verse;\n const endChapter = reference.endChapter;\n const endVerse = reference.endVerse;\n\n let referenceStr = `${bookName} ${chapter}`;\n if (endChapter) {\n referenceStr += `-${endChapter}`;\n } else if (verse) {\n referenceStr += `:${verse}`;\n if (endVerse) {\n referenceStr += `-${endVerse}`;\n }\n }\n return referenceStr;\n }\n\n /**\n * Gets the text for a verse.\n * @param verse The verse to get the text for.\n * @param options Options for getting the verse text.\n */\n getVerseText(verse: ChapterVerse): string {\n let content = '';\n for (let part of verse.content) {\n if (typeof part === 'string') {\n content += part;\n } else if (typeof part === 'object' && 'text' in part) {\n if (part.poem) {\n content += '\\n';\n for (let i = 0; i < part.poem; i++) {\n content += '\\t';\n }\n }\n content += part.text;\n } else if (typeof part === 'object' && 'lineBreak' in part) {\n content += '\\n';\n } else if (typeof part === 'object') {\n content += ' ';\n }\n }\n return content.trim();\n }\n\n /**\n * Gets the verse text for the given chapter.\n * By default, the returned text includes markers for verse numbers and a reference to the chapter, but these can be omitted by passing options to the `options` parameter.\n * @param chapter The chapter to get the text for.\n * @param options Options for getting the chapter text.\n */\n getChapterVerseText(\n chapter: ApiTranslationBookChapter,\n options: GetChapterTextOptions = {}\n ): string {\n let content = '';\n for (let chapterContent of chapter.chapter.content) {\n if (chapterContent.type === 'verse') {\n if (!options.omitVerseNumbers) {\n content += `[${chapterContent.number}] `;\n }\n content += this.getVerseText(chapterContent) + ' ';\n } else if (chapterContent.type === 'line_break') {\n content = content.trim() + '\\n';\n }\n }\n\n if (!options.omitReference) {\n content = `${this.formatReference(chapter.book, {\n chapter: chapter.chapter.number,\n })}\\n${content.trim()}`;\n }\n\n return content.trim();\n }\n\n /**\n * Gets the verse text for the given simplified chapter.\n * By default, the returned text includes markers for verse numbers and a reference to the chapter, but these can be omitted by passing options to the `options` parameter.\n * @param chapter The simplified chapter to get the text for.\n * @param options Options for getting the chapter text.\n */\n getSimpleChapterVerseText(\n chapter: ApiSimpleTranslationBookChapter,\n options: GetChapterTextOptions = {}\n ): string {\n let content = '';\n for (let chapterContent of chapter.chapter.content) {\n if (chapterContent.type === 'verse') {\n if (!options.omitVerseNumbers) {\n content += `[${chapterContent.number}] `;\n }\n content += chapterContent.text.trim() + ' ';\n } else if (chapterContent.type === 'line_break') {\n content = content.trim() + '\\n';\n }\n }\n\n if (!options.omitReference) {\n content = `${this.formatReference(chapter.book, {\n chapter: chapter.chapter.number,\n })}\\n${content.trim()}`;\n }\n\n return content.trim();\n }\n\n /**\n * Gets the text that the given word-level annotation applies to.\n *\n * Annotations are anchored to a range of characters in a single item of the verse's content,\n * so that the ranges stay correct for verses whose content is split into multiple items,\n * such as poem lines and the words of Jesus.\n * @param verse The verse that the annotation is in.\n * @param word The annotation to get the text for.\n * @returns The annotated text, or an empty string if the annotation doesn't point at any text.\n */\n getWordText(verse: ChapterVerse, word: ChapterWord): string {\n const content = verse.content[word.contentIndex];\n\n if (typeof content === 'string') {\n return content.slice(word.start, word.end);\n } else if (\n typeof content === 'object' &&\n content !== null &&\n 'text' in content\n ) {\n return content.text.slice(word.start, word.end);\n }\n\n // Line breaks, inline headings, and footnote references have no text of their own.\n return '';\n }\n\n /**\n * Gets the word-level annotations for the given verse, paired with the text that each one applies to.\n * @param verse The verse to get the annotations for.\n * @param words The annotations for the chapter that the verse is in.\n * @returns The annotations for the verse, in the order that they occur. Empty if the verse has no annotations.\n */\n getVerseWords(\n verse: ChapterVerse,\n words: ApiTranslationBookChapterWords\n ): AnnotatedWord[] {\n const verseWords = words.verses[verse.number.toString()] ?? [];\n\n return verseWords.map((word) => ({\n ...word,\n text: this.getWordText(verse, word),\n }));\n }\n\n /**\n * Gets the text that the given simplified word-level annotation applies to.\n * @param verse The simplified verse that the annotation is in.\n * @param word The annotation to get the text for.\n * @returns The annotated text.\n */\n getSimpleWordText(\n verse: SimpleChapterVerse,\n word: SimpleChapterWord\n ): string {\n return verse.text.slice(word.start, word.end);\n }\n\n /**\n * Gets the word-level annotations for the given simplified verse, paired with the text that each one applies to.\n * @param verse The simplified verse to get the annotations for.\n * @param words The simplified annotations for the chapter that the verse is in.\n * @returns The annotations for the verse, in the order that they occur. Empty if the verse has no annotations.\n */\n getSimpleVerseWords(\n verse: SimpleChapterVerse,\n words: ApiSimpleTranslationBookChapterWords\n ): SimpleAnnotatedWord[] {\n const verseWords = words.verses[verse.number.toString()] ?? [];\n\n return verseWords.map((word) => ({\n ...word,\n text: this.getSimpleWordText(verse, word),\n }));\n }\n\n private _getJson<T>(\n path: string,\n endpoint: string | undefined,\n useCache: boolean = true\n ): Promise<T> {\n const url = this._buildUrl(path, endpoint);\n const existing = this._responseCache.get(url) as Promise<T> | undefined;\n if (existing) {\n return existing;\n }\n\n const request: Promise<T> = fetch(url)\n .then(async (response) => {\n if (response.status < 200 || response.status >= 300) {\n throw new Error(\n `Failed request to ${url}. Status: ${response.status} ${response.statusText}`\n );\n }\n return await response.json();\n })\n .catch((error) => {\n this._responseCache.delete(url);\n throw error;\n });\n\n if (this._useCache && useCache) {\n this._responseCache.set(url, request);\n }\n return request;\n }\n\n private _buildUrl(path: string, endpoint?: string): string {\n if (/^https?:\\/\\//i.test(path)) {\n return path;\n }\n\n const baseEndpoint = endpoint ?? this.endpoint;\n return new URL(path, baseEndpoint).href;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|