free-use-bible-api 0.1.2 → 0.2.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.
Files changed (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +101 -70
  3. package/dist/cjs/FreeUseBibleApi.cjs +296 -0
  4. package/dist/cjs/FreeUseBibleApi.cjs.map +7 -0
  5. package/dist/cjs/index.cjs +25 -0
  6. package/dist/cjs/index.cjs.map +7 -0
  7. package/dist/cjs/types.gen.cjs +17 -0
  8. package/dist/cjs/types.gen.cjs.map +7 -0
  9. package/dist/esm/FreeUseBibleApi.js +270 -0
  10. package/dist/esm/FreeUseBibleApi.js.map +7 -0
  11. package/dist/esm/index.js +2 -3
  12. package/dist/esm/index.js.map +2 -2
  13. package/dist/esm/types.gen.js +2 -0
  14. package/dist/esm/types.gen.js.map +7 -0
  15. package/dist/types/FreeUseBibleApi.d.ts +247 -0
  16. package/dist/types/index.d.ts +2 -3
  17. package/dist/types/types.gen.d.ts +1147 -0
  18. package/package.json +33 -31
  19. package/dist/esm/apis/DefaultApi.js +0 -416
  20. package/dist/esm/apis/DefaultApi.js.map +0 -7
  21. package/dist/esm/apis/FreeUseBibleApi.js +0 -61
  22. package/dist/esm/apis/FreeUseBibleApi.js.map +0 -7
  23. package/dist/esm/apis/index.js +0 -4
  24. package/dist/esm/apis/index.js.map +0 -7
  25. package/dist/esm/models/ApiAvailableCommentaries.js +0 -32
  26. package/dist/esm/models/ApiAvailableCommentaries.js.map +0 -7
  27. package/dist/esm/models/ApiAvailableDatasets.js +0 -32
  28. package/dist/esm/models/ApiAvailableDatasets.js.map +0 -7
  29. package/dist/esm/models/ApiAvailableTranslations.js +0 -32
  30. package/dist/esm/models/ApiAvailableTranslations.js.map +0 -7
  31. package/dist/esm/models/ApiCommentary.js +0 -81
  32. package/dist/esm/models/ApiCommentary.js.map +0 -7
  33. package/dist/esm/models/ApiCommentaryBook.js +0 -63
  34. package/dist/esm/models/ApiCommentaryBook.js.map +0 -7
  35. package/dist/esm/models/ApiCommentaryBookChapter.js +0 -58
  36. package/dist/esm/models/ApiCommentaryBookChapter.js.map +0 -7
  37. package/dist/esm/models/ApiCommentaryBookChapterChapter.js +0 -37
  38. package/dist/esm/models/ApiCommentaryBookChapterChapter.js.map +0 -7
  39. package/dist/esm/models/ApiCommentaryBooks.js +0 -39
  40. package/dist/esm/models/ApiCommentaryBooks.js.map +0 -7
  41. package/dist/esm/models/ApiDataset.js +0 -77
  42. package/dist/esm/models/ApiDataset.js.map +0 -7
  43. package/dist/esm/models/ApiDatasetBook.js +0 -56
  44. package/dist/esm/models/ApiDatasetBook.js.map +0 -7
  45. package/dist/esm/models/ApiDatasetBookChapter.js +0 -61
  46. package/dist/esm/models/ApiDatasetBookChapter.js.map +0 -7
  47. package/dist/esm/models/ApiDatasetBooks.js +0 -39
  48. package/dist/esm/models/ApiDatasetBooks.js.map +0 -7
  49. package/dist/esm/models/ApiTranslation.js +0 -87
  50. package/dist/esm/models/ApiTranslation.js.map +0 -7
  51. package/dist/esm/models/ApiTranslationBook.js +0 -64
  52. package/dist/esm/models/ApiTranslationBook.js.map +0 -7
  53. package/dist/esm/models/ApiTranslationBookChapter.js +0 -67
  54. package/dist/esm/models/ApiTranslationBookChapter.js.map +0 -7
  55. package/dist/esm/models/ApiTranslationBookChapterChapter.js +0 -42
  56. package/dist/esm/models/ApiTranslationBookChapterChapter.js.map +0 -7
  57. package/dist/esm/models/ApiTranslationBooks.js +0 -39
  58. package/dist/esm/models/ApiTranslationBooks.js.map +0 -7
  59. package/dist/esm/models/ApiTranslationComplete.js +0 -39
  60. package/dist/esm/models/ApiTranslationComplete.js.map +0 -7
  61. package/dist/esm/models/ApiTranslationCompleteBook.js +0 -59
  62. package/dist/esm/models/ApiTranslationCompleteBook.js.map +0 -7
  63. package/dist/esm/models/BookId.js +0 -127
  64. package/dist/esm/models/BookId.js.map +0 -7
  65. package/dist/esm/models/ChapterContent.js +0 -58
  66. package/dist/esm/models/ChapterContent.js.map +0 -7
  67. package/dist/esm/models/ChapterFootnote.js +0 -44
  68. package/dist/esm/models/ChapterFootnote.js.map +0 -7
  69. package/dist/esm/models/ChapterFootnoteCaller.js +0 -17
  70. package/dist/esm/models/ChapterFootnoteCaller.js.map +0 -7
  71. package/dist/esm/models/ChapterFootnoteReference.js +0 -31
  72. package/dist/esm/models/ChapterFootnoteReference.js.map +0 -7
  73. package/dist/esm/models/ChapterHeading.js +0 -34
  74. package/dist/esm/models/ChapterHeading.js.map +0 -7
  75. package/dist/esm/models/ChapterHebrewSubtitle.js +0 -38
  76. package/dist/esm/models/ChapterHebrewSubtitle.js.map +0 -7
  77. package/dist/esm/models/ChapterHebrewSubtitleContentInner.js +0 -35
  78. package/dist/esm/models/ChapterHebrewSubtitleContentInner.js.map +0 -7
  79. package/dist/esm/models/ChapterLineBreak.js +0 -31
  80. package/dist/esm/models/ChapterLineBreak.js.map +0 -7
  81. package/dist/esm/models/ChapterVerse.js +0 -41
  82. package/dist/esm/models/ChapterVerse.js.map +0 -7
  83. package/dist/esm/models/ChapterVerseContentInner.js +0 -44
  84. package/dist/esm/models/ChapterVerseContentInner.js.map +0 -7
  85. package/dist/esm/models/DatasetChapterData.js +0 -35
  86. package/dist/esm/models/DatasetChapterData.js.map +0 -7
  87. package/dist/esm/models/DatasetChapterVerseContent.js +0 -35
  88. package/dist/esm/models/DatasetChapterVerseContent.js.map +0 -7
  89. package/dist/esm/models/FormattedText.js +0 -32
  90. package/dist/esm/models/FormattedText.js.map +0 -7
  91. package/dist/esm/models/InlineHeading.js +0 -28
  92. package/dist/esm/models/InlineHeading.js.map +0 -7
  93. package/dist/esm/models/InlineLineBreak.js +0 -31
  94. package/dist/esm/models/InlineLineBreak.js.map +0 -7
  95. package/dist/esm/models/ScoredVerseRef.js +0 -47
  96. package/dist/esm/models/ScoredVerseRef.js.map +0 -7
  97. package/dist/esm/models/TranslationBookChapter.js +0 -35
  98. package/dist/esm/models/TranslationBookChapter.js.map +0 -7
  99. package/dist/esm/models/VerseFootnoteReference.js +0 -28
  100. package/dist/esm/models/VerseFootnoteReference.js.map +0 -7
  101. package/dist/esm/models/index.js +0 -40
  102. package/dist/esm/models/index.js.map +0 -7
  103. package/dist/esm/runtime.js +0 -304
  104. package/dist/esm/runtime.js.map +0 -7
  105. package/dist/types/apis/DefaultApi.d.ts +0 -176
  106. package/dist/types/apis/FreeUseBibleApi.d.ts +0 -34
  107. package/dist/types/apis/index.d.ts +0 -3
  108. package/dist/types/models/ApiAvailableCommentaries.d.ts +0 -34
  109. package/dist/types/models/ApiAvailableDatasets.d.ts +0 -34
  110. package/dist/types/models/ApiAvailableTranslations.d.ts +0 -34
  111. package/dist/types/models/ApiCommentary.d.ts +0 -145
  112. package/dist/types/models/ApiCommentaryBook.d.ts +0 -100
  113. package/dist/types/models/ApiCommentaryBookChapter.d.ts +0 -72
  114. package/dist/types/models/ApiCommentaryBookChapterChapter.d.ts +0 -46
  115. package/dist/types/models/ApiCommentaryBooks.d.ts +0 -41
  116. package/dist/types/models/ApiDataset.d.ts +0 -138
  117. package/dist/types/models/ApiDatasetBook.d.ts +0 -82
  118. package/dist/types/models/ApiDatasetBookChapter.d.ts +0 -78
  119. package/dist/types/models/ApiDatasetBooks.d.ts +0 -41
  120. package/dist/types/models/ApiTranslation.d.ts +0 -169
  121. package/dist/types/models/ApiTranslationBook.d.ts +0 -100
  122. package/dist/types/models/ApiTranslationBookChapter.d.ts +0 -96
  123. package/dist/types/models/ApiTranslationBookChapterChapter.d.ts +0 -47
  124. package/dist/types/models/ApiTranslationBooks.d.ts +0 -41
  125. package/dist/types/models/ApiTranslationComplete.d.ts +0 -41
  126. package/dist/types/models/ApiTranslationCompleteBook.d.ts +0 -83
  127. package/dist/types/models/BookId.d.ts +0 -125
  128. package/dist/types/models/ChapterContent.d.ts +0 -34
  129. package/dist/types/models/ChapterFootnote.d.ts +0 -53
  130. package/dist/types/models/ChapterFootnoteCaller.d.ts +0 -27
  131. package/dist/types/models/ChapterFootnoteReference.d.ts +0 -39
  132. package/dist/types/models/ChapterHeading.d.ts +0 -46
  133. package/dist/types/models/ChapterHebrewSubtitle.d.ts +0 -47
  134. package/dist/types/models/ChapterHebrewSubtitleContentInner.d.ts +0 -51
  135. package/dist/types/models/ChapterLineBreak.d.ts +0 -40
  136. package/dist/types/models/ChapterVerse.d.ts +0 -53
  137. package/dist/types/models/ChapterVerseContentInner.d.ts +0 -70
  138. package/dist/types/models/DatasetChapterData.d.ts +0 -40
  139. package/dist/types/models/DatasetChapterVerseContent.d.ts +0 -40
  140. package/dist/types/models/FormattedText.d.ts +0 -45
  141. package/dist/types/models/InlineHeading.d.ts +0 -33
  142. package/dist/types/models/InlineLineBreak.d.ts +0 -40
  143. package/dist/types/models/ScoredVerseRef.d.ts +0 -70
  144. package/dist/types/models/TranslationBookChapter.d.ts +0 -42
  145. package/dist/types/models/VerseFootnoteReference.d.ts +0 -33
  146. package/dist/types/models/index.d.ts +0 -39
  147. package/dist/types/runtime.d.ts +0 -185
package/LICENSE ADDED
@@ -0,0 +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.
package/README.md CHANGED
@@ -1,15 +1,11 @@
1
1
  # Free Use Bible API
2
2
 
3
- The Free Use Bible API provides access to over 1000 Bible translations in hundreds of languages.
3
+ TypeScript and JavaScript client for the public Free Use Bible API:
4
4
 
5
- This package is an auto-generated TypeScript and JavaScript client for the public API hosted at:
6
-
7
- - https://bible.helloao.org
5
+ - `https://bible.helloao.org`
8
6
 
9
7
  ## Installation
10
8
 
11
- Install with your preferred package manager:
12
-
13
9
  ```bash
14
10
  npm install free-use-bible-api
15
11
  ```
@@ -24,94 +20,127 @@ yarn add free-use-bible-api
24
20
 
25
21
  ## Quick Start
26
22
 
27
- Create a client and point it at the production API:
23
+ ```ts
24
+ import { FreeUseBibleApi } from 'free-use-bible-api';
25
+
26
+ const api = new FreeUseBibleApi();
27
+
28
+ const available = await api.getAvailableTranslations();
29
+ console.log('Total translations:', available.translations.length);
30
+
31
+ const books = await api.getTranslationBooks('BSB');
32
+ console.log('Books in BSB:', books.books.length);
33
+
34
+ const chapter = await api.getTranslationBookChapter('BSB', 'GEN', 1);
35
+ console.log('Verses in Genesis 1:', chapter.numberOfVerses);
36
+ ```
37
+
38
+ ## Client Options
39
+
40
+ You can customize the client with `FreeUseBibleApiOptions`:
28
41
 
29
42
  ```ts
30
- import { Configuration, FreeUseBibleApi } from 'free-use-bible-api';
43
+ import { FreeUseBibleApi } from 'free-use-bible-api';
31
44
 
32
- const config = new Configuration({
33
- basePath: 'https://bible.helloao.org',
45
+ const api = new FreeUseBibleApi({
46
+ endpoint: 'https://bible.helloao.org/',
47
+ useCache: true,
34
48
  });
35
-
36
- const api = new FreeUseBibleApi(config);
37
49
  ```
38
50
 
39
- ## Translation Usage Guide
51
+ - `endpoint`: Base API endpoint.
52
+ - `useCache`: Enables in-memory response caching (default: `true`).
40
53
 
41
- This section covers the most common translation flow:
54
+ ## API Methods
42
55
 
43
- 1. Get available translations.
44
- 2. Pick a translation ID.
45
- 3. Get books for that translation.
46
- 4. Fetch a chapter.
47
- 5. Optionally fetch the full translation payload.
56
+ ### Translations
48
57
 
49
- ### 1. Get Available Translations
58
+ - `getAvailableTranslations(endpoint?)`
59
+ - `getTranslationBooks(translation, endpoint?)`
60
+ - `getTranslationBookChapter(translation, book, chapter, endpoint?)`
61
+ - `getCompleteTranslation(translation, endpoint?)`
50
62
 
51
- ```ts
52
- import { Configuration, FreeUseBibleApi } from 'free-use-bible-api';
63
+ `getCompleteTranslation()` disables per-request cache internally because payloads are typically large.
53
64
 
54
- const api = new FreeUseBibleApi(
55
- new Configuration({ basePath: 'https://bible.helloao.org' })
56
- );
65
+ ### Commentaries
57
66
 
58
- const result = await api.getAvailableTranslations();
67
+ - `getAvailableCommentaries(endpoint?)`
68
+ - `getCommentaryBooks(commentary, endpoint?)`
69
+ - `getCommentaryBookChapter(commentary, book, chapter, endpoint?)`
59
70
 
60
- console.log('Total translations:', result.translations.length);
61
- console.log('First translation:', result.translations[0]);
62
- ```
71
+ ### Datasets
63
72
 
64
- ### 2. Get Books For A Translation
73
+ - `getAvailableDatasets(endpoint?)`
74
+ - `getDatasetBooks(dataset, endpoint?)`
75
+ - `getDatasetBookChapter(dataset, book, chapter, endpoint?)`
65
76
 
66
- Use a translation ID from the previous step, for example `BSB`:
77
+ ### Chapter Navigation Helpers
67
78
 
68
- ```ts
69
- const books = await api.getTranslationBooks({
70
- translation: 'BSB',
71
- });
79
+ - `getNextChapter(chapter, endpoint?)`
80
+ - `getPreviousChapter(chapter, endpoint?)`
72
81
 
73
- console.log('Books in translation:', books.books.length);
74
- console.log('First book:', books.books[0]);
75
- ```
82
+ These helpers work with translation, commentary, and dataset chapter responses.
76
83
 
77
- ### 3. Get A Translation Chapter
84
+ ## Examples
78
85
 
79
- Use a USFM book ID and chapter number:
86
+ ### Get a complete translation
80
87
 
81
88
  ```ts
82
- import { BookId } from 'free-use-bible-api';
89
+ const complete = await api.getCompleteTranslation('BSB');
90
+ console.log(complete.translation.id);
91
+ console.log(complete.books.length);
92
+ ```
83
93
 
84
- const chapter = await api.getTranslationBookChapter({
85
- translation: 'BSB',
86
- book: BookId.GEN,
87
- chapter: 1,
88
- });
94
+ ### Read a commentary chapter
89
95
 
90
- console.log('Chapter number:', chapter.chapter.number);
91
- console.log('Verse count:', chapter.numberOfVerses);
96
+ ```ts
97
+ const comm = await api.getCommentaryBookChapter('matthew_henry', 'GEN', 1);
98
+ console.log(comm.book.name);
92
99
  ```
93
100
 
94
- ### 4. Get A Complete Translation
101
+ ### Read a dataset chapter
102
+
103
+ ```ts
104
+ const dataChapter = await api.getDatasetBookChapter(
105
+ 'cross_references',
106
+ 'JHN',
107
+ 3
108
+ );
109
+ console.log(dataChapter.book.name);
110
+ ```
95
111
 
96
- Some workflows need the entire translation document in one call:
112
+ ### Navigate to next/previous chapter
97
113
 
98
114
  ```ts
99
- const complete = await api.getTranslationComplete({
100
- translation: 'BSB',
101
- });
115
+ const current = await api.getTranslationBookChapter('BSB', 'GEN', 1);
116
+
117
+ const next = await api.getNextChapter(current);
118
+ const previous = await api.getPreviousChapter(current);
102
119
 
103
- console.log('Translation:', complete.translation.id);
104
- console.log('Book count:', complete.books.length);
120
+ console.log(next?.chapter.number);
121
+ console.log(previous?.chapter.number);
105
122
  ```
106
123
 
107
- ## Direct HTTP Examples For Translations
124
+ ## Direct HTTP Endpoints
125
+
126
+ ### Translation endpoints
127
+
128
+ - `GET /api/available_translations.json`
129
+ - `GET /api/{translation}/books.json`
130
+ - `GET /api/{translation}/{book}/{chapter}.json`
131
+ - `GET /api/{translation}/complete.json`
108
132
 
109
- If you do not want to use the SDK, these translation endpoints are available directly:
133
+ ### Commentary endpoints
110
134
 
111
- - GET `/api/available_translations.json`
112
- - GET `/api/{translation}/books.json`
113
- - GET `/api/{translation}/{book}/{chapter}.json`
114
- - GET `/api/{translation}/complete.json`
135
+ - `GET /api/available_commentaries.json`
136
+ - `GET /api/{commentary}/books.json`
137
+ - `GET /api/{commentary}/{book}/{chapter}.json`
138
+
139
+ ### Dataset endpoints
140
+
141
+ - `GET /api/available_datasets.json`
142
+ - `GET /api/d/{dataset}/books.json`
143
+ - `GET /api/d/{dataset}/{book}/{chapter}.json`
115
144
 
116
145
  Example requests:
117
146
 
@@ -119,21 +148,23 @@ Example requests:
119
148
  curl https://bible.helloao.org/api/available_translations.json
120
149
  curl https://bible.helloao.org/api/BSB/books.json
121
150
  curl https://bible.helloao.org/api/BSB/GEN/1.json
151
+ curl https://bible.helloao.org/api/available_commentaries.json
152
+ curl https://bible.helloao.org/api/available_datasets.json
122
153
  ```
123
154
 
124
155
  ## Error Handling
125
156
 
126
- A 404 response usually means one of these values is invalid:
157
+ Methods throw on non-2xx responses.
127
158
 
128
- - translation
129
- - book
130
- - chapter
159
+ A 404 response usually means one of the path values is invalid, for example:
131
160
 
132
- Use available translations and books responses to drive your UI selections and reduce bad requests.
161
+ - translation
162
+ - commentary
163
+ - dataset
164
+ - book
165
+ - chapter
133
166
 
134
167
  ## Notes
135
168
 
136
- - This client uses fetch under the hood.
137
- - In modern Node.js versions, fetch is available globally.
138
- - For custom environments, pass a custom fetch implementation in `Configuration`.
139
-
169
+ - Uses the global `fetch` API.
170
+ - For Node.js, use a runtime that provides `fetch` (Node 18+ recommended) or polyfill it.
@@ -0,0 +1,296 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var FreeUseBibleApi_exports = {};
20
+ __export(FreeUseBibleApi_exports, {
21
+ FreeUseBibleApi: () => FreeUseBibleApi
22
+ });
23
+ module.exports = __toCommonJS(FreeUseBibleApi_exports);
24
+ class FreeUseBibleApi {
25
+ endpoint = "https://bible.helloao.org/";
26
+ _responseCache = /* @__PURE__ */ new Map();
27
+ _useCache = true;
28
+ constructor(options) {
29
+ this.endpoint = options?.endpoint ?? this.endpoint;
30
+ this._useCache = options?.useCache ?? this._useCache;
31
+ }
32
+ /**
33
+ * Gets the list of available Bible translations from the API.
34
+ * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
35
+ */
36
+ async getAvailableTranslations(endpoint) {
37
+ return this._getJson(
38
+ "api/available_translations.json",
39
+ endpoint
40
+ );
41
+ }
42
+ /**
43
+ * Gets the complete content of a specific Bible translation.
44
+ *
45
+ * The results of this endpoint are very large, so the response is not cached.
46
+ * @param translation The ID of the translation to get the complete content for.
47
+ * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
48
+ */
49
+ async getCompleteTranslation(translation, endpoint) {
50
+ const encodedTranslation = encodeURIComponent(translation);
51
+ return this._getJson(
52
+ `api/${encodedTranslation}/complete.json`,
53
+ endpoint,
54
+ false
55
+ );
56
+ }
57
+ /**
58
+ * Gets the list of available Bible commentaries from the API.
59
+ * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
60
+ */
61
+ async getAvailableCommentaries(endpoint) {
62
+ return this._getJson(
63
+ "api/available_commentaries.json",
64
+ endpoint
65
+ );
66
+ }
67
+ /**
68
+ * Gets the list of available datasets from the API.
69
+ * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
70
+ */
71
+ async getAvailableDatasets(endpoint) {
72
+ return this._getJson(
73
+ "api/available_datasets.json",
74
+ endpoint
75
+ );
76
+ }
77
+ /**
78
+ * Gets the list of books for a given Bible translation.
79
+ * @param translation The ID of the translation to get the books for.
80
+ * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
81
+ */
82
+ async getTranslationBooks(translation, endpoint) {
83
+ const encodedTranslation = encodeURIComponent(translation);
84
+ return this._getJson(
85
+ `api/${encodedTranslation}/books.json`,
86
+ endpoint
87
+ );
88
+ }
89
+ /**
90
+ * Gets the list of books for a given Bible commentary.
91
+ * @param commentary The ID of the commentary to get the books for.
92
+ * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
93
+ */
94
+ async getCommentaryBooks(commentary, endpoint) {
95
+ const encodedCommentary = encodeURIComponent(commentary);
96
+ return this._getJson(
97
+ `api/${encodedCommentary}/books.json`,
98
+ endpoint
99
+ );
100
+ }
101
+ /**
102
+ * Gets the list of books for a given dataset.
103
+ * @param dataset The ID of the dataset to get the books for.
104
+ * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
105
+ */
106
+ async getDatasetBooks(dataset, endpoint) {
107
+ const encodedDataset = encodeURIComponent(dataset);
108
+ return this._getJson(
109
+ `api/d/${encodedDataset}/books.json`,
110
+ endpoint
111
+ );
112
+ }
113
+ /**
114
+ * Gets the content of a specific chapter of a specific book for a specific Bible translation.
115
+ * @param translation The ID of the translation to get the chapter for.
116
+ * @param book The ID of the book to get the chapter for.
117
+ * @param chapter The chapter number to get.
118
+ * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
119
+ */
120
+ async getTranslationBookChapter(translation, book, chapter, endpoint) {
121
+ const encodedTranslation = encodeURIComponent(translation);
122
+ const encodedBook = encodeURIComponent(book);
123
+ const encodedChapter = encodeURIComponent(String(chapter));
124
+ return this._getJson(
125
+ `api/${encodedTranslation}/${encodedBook}/${encodedChapter}.json`,
126
+ endpoint
127
+ );
128
+ }
129
+ /**
130
+ * Gets the content of a specific chapter of a specific book for a specific Bible commentary.
131
+ * @param commentary The ID of the commentary to get the chapter for.
132
+ * @param book The ID of the book to get the chapter for.
133
+ * @param chapter The chapter number to get.
134
+ * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
135
+ */
136
+ async getCommentaryBookChapter(commentary, book, chapter, endpoint) {
137
+ const encodedCommentary = encodeURIComponent(commentary);
138
+ const encodedBook = encodeURIComponent(book);
139
+ const encodedChapter = encodeURIComponent(String(chapter));
140
+ return this._getJson(
141
+ `api/${encodedCommentary}/${encodedBook}/${encodedChapter}.json`,
142
+ endpoint
143
+ );
144
+ }
145
+ /**
146
+ * Gets the content of a specific chapter of a specific book for a specific dataset.
147
+ * @param dataset The ID of the dataset to get the chapter for.
148
+ * @param book The ID of the book to get the chapter for.
149
+ * @param chapter The chapter number to get.
150
+ * @param endpoint The API endpoint to use for the request. If not provided, the default endpoint will be used.
151
+ */
152
+ async getDatasetBookChapter(dataset, book, chapter, endpoint) {
153
+ const encodedDataset = encodeURIComponent(dataset);
154
+ const encodedBook = encodeURIComponent(book);
155
+ const encodedChapter = encodeURIComponent(String(chapter));
156
+ return this._getJson(
157
+ `api/d/${encodedDataset}/${encodedBook}/${encodedChapter}.json`,
158
+ endpoint
159
+ );
160
+ }
161
+ async getNextChapter(chapter, endpoint) {
162
+ if (!chapter.nextChapterApiLink) {
163
+ return null;
164
+ }
165
+ return this._getJson(chapter.nextChapterApiLink, endpoint);
166
+ }
167
+ async getPreviousChapter(chapter, endpoint) {
168
+ if (!chapter.previousChapterApiLink) {
169
+ return null;
170
+ }
171
+ return this._getJson(chapter.previousChapterApiLink, endpoint);
172
+ }
173
+ async getFirstChapter(book, endpoint) {
174
+ if (!book.firstChapterApiLink) {
175
+ return null;
176
+ }
177
+ return this._getJson(book.firstChapterApiLink, endpoint);
178
+ }
179
+ async getLastChapter(book, endpoint) {
180
+ if (!book.lastChapterApiLink) {
181
+ return null;
182
+ }
183
+ return this._getJson(book.lastChapterApiLink, endpoint);
184
+ }
185
+ /**
186
+ * Formats a verse reference as a human-readable string.
187
+ *
188
+ * e.g. Genesis 1:1-2, John 3:16, Exodus 20-22, etc.
189
+ *
190
+ * @param book The book that the reference is for.
191
+ * @param reference The reference to format.
192
+ */
193
+ formatReference(book, reference) {
194
+ const bookName = book.name;
195
+ const chapter = reference.chapter;
196
+ const verse = reference.verse;
197
+ const endChapter = reference.endChapter;
198
+ const endVerse = reference.endVerse;
199
+ let referenceStr = `${bookName} ${chapter}`;
200
+ if (endChapter) {
201
+ referenceStr += `-${endChapter}`;
202
+ } else if (verse) {
203
+ referenceStr += `:${verse}`;
204
+ if (endVerse) {
205
+ referenceStr += `-${endVerse}`;
206
+ }
207
+ }
208
+ return referenceStr;
209
+ }
210
+ /**
211
+ * Gets the text for a verse.
212
+ * @param verse The verse to get the text for.
213
+ * @param options Options for getting the verse text.
214
+ */
215
+ getVerseText(verse) {
216
+ let content = "";
217
+ for (let part of verse.content) {
218
+ if (typeof part === "string") {
219
+ content += part;
220
+ } else if (typeof part === "object" && "text" in part) {
221
+ if (part.poem) {
222
+ content += "\n";
223
+ for (let i = 0; i < part.poem; i++) {
224
+ content += " ";
225
+ }
226
+ }
227
+ content += part.text;
228
+ } else if (typeof part === "object" && "lineBreak" in part) {
229
+ content += "\n";
230
+ } else if (typeof part === "object") {
231
+ content += " ";
232
+ }
233
+ }
234
+ return content.trim();
235
+ }
236
+ /**
237
+ * Gets the verse text for the given chapter.
238
+ * 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.
239
+ * @param chapter The chapter to get the text for.
240
+ * @param options Options for getting the chapter text.
241
+ */
242
+ getChapterVerseText(chapter, options = {}) {
243
+ let content = "";
244
+ for (let chapterContent of chapter.chapter.content) {
245
+ if (chapterContent.type === "verse") {
246
+ if (!options.omitVerseNumbers) {
247
+ content += `[${chapterContent.number}] `;
248
+ }
249
+ content += this.getVerseText(chapterContent) + " ";
250
+ } else if (chapterContent.type === "line_break") {
251
+ content = content.trim() + "\n";
252
+ }
253
+ }
254
+ if (!options.omitReference) {
255
+ content = `${this.formatReference(chapter.book, {
256
+ chapter: chapter.chapter.number
257
+ })}
258
+ ${content.trim()}`;
259
+ }
260
+ return content.trim();
261
+ }
262
+ _getJson(path, endpoint, useCache = true) {
263
+ const url = this._buildUrl(path, endpoint);
264
+ const existing = this._responseCache.get(url);
265
+ if (existing) {
266
+ return existing;
267
+ }
268
+ const request = fetch(url).then(async (response) => {
269
+ if (response.status < 200 || response.status >= 300) {
270
+ throw new Error(
271
+ `Failed request to ${url}. Status: ${response.status} ${response.statusText}`
272
+ );
273
+ }
274
+ return await response.json();
275
+ }).catch((error) => {
276
+ this._responseCache.delete(url);
277
+ throw error;
278
+ });
279
+ if (this._useCache && useCache) {
280
+ this._responseCache.set(url, request);
281
+ }
282
+ return request;
283
+ }
284
+ _buildUrl(path, endpoint) {
285
+ if (/^https?:\/\//i.test(path)) {
286
+ return path;
287
+ }
288
+ const baseEndpoint = endpoint ?? this.endpoint;
289
+ return new URL(path, baseEndpoint).href;
290
+ }
291
+ }
292
+ // Annotate the CommonJS export names for ESM import in node:
293
+ 0 && (module.exports = {
294
+ FreeUseBibleApi
295
+ });
296
+ //# sourceMappingURL=FreeUseBibleApi.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 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 ApiTranslationBook,\r\n ApiTranslationBookChapter,\r\n ApiTranslationBooks,\r\n ApiTranslationComplete,\r\n ChapterVerse,\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 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 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/${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 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/${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 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 async getNextChapter(\r\n chapter:\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter,\r\n endpoint?: string\r\n ): Promise<\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\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 >(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 async getPreviousChapter(\r\n chapter:\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter,\r\n endpoint?: string\r\n ): Promise<\r\n | ApiTranslationBookChapter\r\n | ApiCommentaryBookChapter\r\n | ApiDatasetBookChapter\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 >(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 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": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
15
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
+ var free_use_bible_api_exports = {};
17
+ module.exports = __toCommonJS(free_use_bible_api_exports);
18
+ __reExport(free_use_bible_api_exports, require("./FreeUseBibleApi.js"), module.exports);
19
+ __reExport(free_use_bible_api_exports, require("./types.gen.js"), module.exports);
20
+ // Annotate the CommonJS export names for ESM import in node:
21
+ 0 && (module.exports = {
22
+ ...require("./FreeUseBibleApi.js"),
23
+ ...require("./types.gen.js")
24
+ });
25
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../index.ts"],
4
+ "sourcesContent": ["export * from './FreeUseBibleApi.js';\r\nexport * from './types.gen.js';\r\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,uCAAc,iCAAd;AACA,uCAAc,2BADd;",
6
+ "names": []
7
+ }