berea
Version:
A promise-wrapped library and ORM for using https://scripture.api.bible
774 lines (659 loc) • 25.9 kB
JavaScript
;
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
const Axios = require('axios');
const {
RequestParameters,
BibleTypes
} = require('./constants');
/**
* @typedef ParsedApiRequest
* @property {string} id bibleId
* @property {string} bookId bibleId
* @property {string} chapterId bibleId
* @property {string} sectionId bibleId
* @property {object} params additional parameters to submit to api
*/
/**
* @typedef BiblesRequestParam
* @property {string} language ISO 639-3 three digit language code used to filter results
* @property {string} abbreviation Bible abbreviation to search for
* @property {string} name Bible name to search for
* @property {Array<string>} ids Comma separated list of Bible Ids to return
* @see {@link https://scripture.api.bible/livedocs#/Bibles/getBibles|Bibles}
*/
/**
* @typedef BooksRequestParam
* @property {string} id id of the Bible whose book to fetch
* @property {boolean} [includeChapters=false] An array of chapter summaries should be in the results.
* @property {boolean} [includeChaptersAndSections=false] Arrays of chapter summaries and sections should be in the results
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Books/getBooks|Books}
*/
/**
* @typedef BookRequestParam
* @property {string} id id of the Bible whose book to fetch
* @property {string} bookId id of the book to fetch (e.g. GEN)
* @property {boolean} [includeChapters=false] Array of chapter summaries should be in the results.
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Books/getBook|Book}
*/
/**
* @typedef ChaptersRequestParam
* @property {string} id id of the Bible whose book to fetch
* @property {string} chapterId id of the chapter to fetch (e.g. GEN.1)
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Chapters/getChapters|Chapters}
*/
/**
* @typedef ChapterRequestParam
* @property {string} id id of the Bible whose book to fetch
* @property {string} chapterId id of the chapter to fetch (e.g. GEN.1)
* @property {string} [contentType=html] html, json, text
* @property {boolean} [includeNotes=false] include footnotes in content
* @property {boolean} [includeTitles=true] include section titles in content
* @property {boolean} [includeChapterNumbers=false] include chapter numbers in content
* @property {boolean} [includeVerseNumbers=true] include verse numbers in content
* @property {boolean} [includeVerseSpans=false] include spans that wrap verse numbers and verse text for bible content
* @property {Array<string>} [parallels] comma separated list of bibleIds
* @property {boolean} [includeChapters=false] Boolean indicating if an array of chapter summaries should be in the results.
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Chapters/getChapter|Chapter}
*/
/**
* @typedef PassageRequestParam
* @property {string} id id of the Bible whose book to fetch
* @property {string} passageId id of the passage to fetch (e.g. GEN.1.1-GEN.2.20)
* @property {string} [contentType=html] html, json, text
* @property {boolean} [includeNotes] include footnotes in content
* @property {boolean} [includeTitles=true] include section titles in content
* @property {boolean} [includeChapterNumbers=false] include chapter numbers in content
* @property {boolean} [includeVerseNumbers=true] include verse numbers in content
* @property {boolean} [includeVerseSpans=false] include spans that wrap verse numbers and verse text for bible content
* @property {Array<string>} [parallels] comma separated list of bibleIds
* @property {boolean} [useOrgId=false] Use the supplied id(s) to match the verseOrgId instead of verseId.
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Passages/getPassage|Passage}
*/
/**
* @typedef VersesRequestParam
* @property {string} id id of the Bible whose book to fetch
* @property {string} chapterId id of the chapter from which to fetch verses (e.g. GEN)
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Verses/getVerses|Verses}
*/
/**
* @typedef VerseRequestParam
* @property {string} id id of the Bible whose book to fetch
* @property {string} verseId id of the verse to fetch (e.g. GEN.1.1)
* @property {string} [contentType=html] html, json, text
* @property {boolean} [includeNotes=false] include footnotes in content
* @property {boolean} [includeTitles=true] include section titles in content
* @property {boolean} [includeChapterNumbers=false] include chapter numbers in content
* @property {boolean} [includeVerseNumbers=false] include verse numbers in content
* @property {boolean} [includeVerseSpans=false] include spans that wrap verse numbers and verse text for bible content
* @property {Array<string>} [parallels] comma separated list of bibleIds
* @property {boolean} [useOrgId=false] Use the supplied id(s) to match the verseOrgId instead of verseId.
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Verses/getVerse|Verse}
*/
/**
* @typedef SearchRequestParam
* @property {string} id id of the Bible to search
* @property {string} query Search keywords or passage reference. Supported wildcards are * and ?.
* @property {string} q Search keywords or passage reference. Supported wildcards are * and ?.
* @property {number} [limit=10] Integer limit for how many matching results to return.
* @property {number} [l=10] Integer limit for how many matching results to return.
* @property {number} [offset] used to paginate results
* @property {number} [o] used to paginate results
* @property {'relevance'|'canonical'|'reverse-canonical'} [sort='relevance'] Sort order of results.
* @property {'relevance'|'canonical'|'reverse-canonical'} [s='relevance'] Sort order of results.
* @property {string} range Comma separated passage ids the search will be limited to.
* @property {string} r Comma separated passage ids the search will be limited to.
* @property {string} passage Comma separated passage ids the search will be limited to.
* @property {string} passages Comma separated passage ids the search will be limited to.
* @property {'AUTO'|0|1|2} fuzziness of a search to account for misspellings.
* @property {'AUTO'|0|1|2} f of a search to account for misspellings.
*/
/**
* @typedef BibleResponse
* @property {string} id unique identifier of the bible
* @property {string} dblId not sure. Similar to id, but without trailing -01
* @property {string} abbreviation 3-letter common abbreviation (e.g. ASV, KJV, NIV)
* @property {string} abbreviationLocal localized abbreviation
* @property {string} copyright copyright notice
* @property {object} language ISO language
* @property {Array<object>} countries countries bible was published for
* @property {string} name name of bible
* @property {string} nameLocal localized (translated) name
* @property {string} description Summary of the bible
* @property {string} descriptionLocal localized (Translated) summary
* @property {string} info metadata
* @property {string} type kind of bible
* @property {Date} updatedAt last time content was updated
* @property {string} relatedDbl not sure
* @property {Array<object>} audioBibles audio versions of this bible
* @see {@link https://scripture.api.bible/livedocs#/Bibles/getBibles|Bibles}
*/
/**
* @typedef BookResponse
* @property {string} id 3-letter identifier of the book
* @property {string} bibleId id of the bible
* @property {string} abbreviation user readable abbreviation
* @property {string} name name of the book
* @property {string} nameLong extended name
* @property {Array<ChapterSummaryResponse>} chapters Small details of the chapters within the book
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Books/getBooks|Books}
*/
/**
* @typedef ChapterSummaryResponse chapter data without verses
* @property {string} id 3-letter identifier for book and integer (e.g. GEN.1)
* @property {string} bibleId id of the containing bible
* @property {string} number integer; chapter number
* @property {string} bookId 3-letter identifier for book
* @property {string} content text
* @property {string} reference reader friendly version (e.g. Genesis 1)
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Chapters/getChapters|Chapters}
*/
/**
* @typedef ChapterResponse chapter data with verse info
* @property {string} id 3-letter identifier for book and integer (e.g. GEN.1)
* @property {string} bibleId id of the containing bible
* @property {string} number integer; chapter number
* @property {string} bookId 3-letter identifier for book
* @property {string} content text
* @property {string} reference reader friendly version (e.g. Genesis 1)
* @property {number} verseCount quantity of verses
* @property {string} copyright copyright information
* @property {object} next chapter number and ID of the next chapter in the book
* @property {object} previous chapter number and ID of the previous chapter in the book
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Chapters/getChapter|Chapter}
*/
/**
* @typedef VerseSummaryResponse
* @property {string} id 3-letter identifier for book and integer (e.g. GEN.1.1)
* @property {string} bibleId id of the containing bible
* @property {string} bookId 3-letter identifier for book
* @property {string} chapterId 3-letter book name with chapter number (e.g. GEN.1)
* @property {string} orgId no idea
* @property {string} reference reader friendly version (e.g. Genesis 1.1)
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Verses/getVerses|Verses}
*/
/**
* @typedef PassageResponse
* @property {string} id 3-letter identifier for book and integer (e.g. GEN.1.1-GEN.2.1)
* @property {string} bibleId id of the containing bible
* @property {string} orgId no idea
* @property {string} reference reader friendly version (e.g. Genesis 1:1-21)
* @property {string} content text content
* @property {number} verseCount quantity of verses
* @property {string} copyright copyright information
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Passages/getPassage|Passage}
*/
/**
* @typedef VerseResponse
* @property {string} id 3-letter identifier for book and integer (e.g. GEN.1)
* @property {string} bibleId id of the containing bible
* @property {string} bookId 3-letter identifier for book
* @property {string} chapterId 3-letter book name with chapter number (e.g. GEN.1)
* @property {string} orgId no idea
* @property {string} content text content
* @property {string} reference reader friendly version (e.g. Genesis 1:1)
* @property {number} verseCount quantity of verses
* @property {string} copyright copyright information
* @property {object} next verse number and ID of the next verse in the book
* @property {object} previous verse number and ID of the previous verse in the book
* @see {@link https://scripture.api.bible/livedocs#/Bibles/Verses/getVerse|Verse}
*/
/**
* @typedef SearchResponse
* @property {string} query Search keywords or passage reference. Supported wildcards are * and ?.
* @property {number} [limit=10] Integer limit for how many matching results to return.
* @property {number} [offset] used to paginate results
* @property {number} total amount of results
* @property {number} verseCount amount of verses
* @property {Array<VerseResponse>} verses the matching verses
* @property {Array<PassageResponse>} passages the matching passages
*/
var _apikey = /*#__PURE__*/new WeakMap();
class BibleService {
/**
* @param {string} apikey api key needed
* @param {number|string} [version=1] version of api
* @param {BibleTypes} [medium='text'] audio or text bible
* @param {object} [dependencies={Axios}] axios library
*/
constructor(apikey, version = 1, medium = 'text', dependencies = {
Axios
}) {
_apikey.set(this, {
writable: true,
value: ''
});
/**
* @type {string}
* @public
*/
this.version = version;
/**
* @type {string}
* @private
*/
this.medium = medium;
/**
* @type {object}
* @public
*/
this.dependencies = dependencies;
/**
* @type {string}
* @public
*/
this.apikey = apikey;
/**
* @type {object}
* @public
*/
this.axios = BibleService.getAxiosInstance(dependencies, apikey, version);
}
get apikey() {
return _classPrivateFieldGet(this, _apikey);
}
set apikey(key) {
_classPrivateFieldSet(this, _apikey, key);
this.axios = BibleService.getAxiosInstance(this.dependencies, key, this.version);
}
/**
* @param {object} dependencies the dependencies object passed it, containing an Axios
* @param {string} apiKey apikey needed for.. the api
* @param {number} version version of the api
* @returns {object} Axios instance
*/
static getAxiosInstance(dependencies, apiKey, version) {
return dependencies.Axios.create({
baseURL: `https://api.scripture.api.bible/v${version}`,
headers: {
'api-key': apiKey
}
});
}
/**
* @type {import('./constants/index.js').BibleTypes}
*/
get bibleType() {
return BibleService.BibleTypes.get(this.medium);
}
/**
* Converts camelcased parameters into hyphenated ones
*
* @param {object} params object with camelcased parameters
* @returns {object} object with hyphenated properties
*/
static hyphenateParameters(params) {
const newParams = {};
Object.entries(params).forEach(([k, v]) => {
if (BibleService.RequestParameters.has(k)) {
newParams[BibleService.RequestParameters.get(k)] = v;
}
if ([...BibleService.RequestParameters.values()].includes(k)) {
newParams[k] = v;
}
});
return newParams;
}
/**
* extracts all the different ids and parameters from an object
*
* @param {object} request the options request to go to the api
* @returns {ParsedApiRequest} object with each id identified, and remaining options
*/
static getRoutesAndParamFromRequest(request) {
let {
bookId,
chapterId,
sectionId,
verseId,
passageId
} = request;
const {
id
} = request;
const params = { ...request
};
delete params.id;
if (bookId) {
delete params.bookId;
bookId = bookId.toUpperCase();
}
if (chapterId) {
delete params.chapterId;
chapterId = chapterId.toUpperCase();
}
if (sectionId) {
delete params.sectionId;
sectionId = sectionId.toUpperCase();
}
if (verseId) {
delete params.verseId;
verseId = verseId.toUpperCase();
}
if (passageId) {
delete params.passageId;
passageId = passageId.toUpperCase();
}
const hyphenatedParams = BibleService.hyphenateParameters(params);
return {
id,
params: hyphenatedParams,
bookId,
chapterId,
sectionId,
verseId,
passageId
};
}
/**
* @param {BiblesRequestParam} [request] options to send
* @returns {Promise<Array<BibleResponse>>} An array of bibles
*/
async getBibles(request) {
const {
axios
} = this;
let result = null;
try {
const response = await axios.get(`/${this.bibleType}`, {
params: request
});
result = response.data.data;
} catch (getError) {
result = getError;
}
return result;
}
/**
* @param {string} id Gets Bible by Id
* @returns {Promise<BibleResponse>} Bible data
*/
async getBible(id) {
if (!id) throw Error('id must be provided');
const {
axios
} = this;
let result = null;
try {
const response = await axios.get(`/${this.bibleType}/${id}`);
result = response.data.data;
} catch (getError) {
result = getError;
}
return result;
}
/**
* @param {BooksRequestParam|string} request id of the bible or object containing id and parameters
* @returns {Promise<Array<BookResponse>>} an array of bookdata
*/
async getBooks(request) {
const {
axios
} = this;
let id = request;
let params = null;
let result = null;
if (typeof request !== 'string') {
const temp = BibleService.getRoutesAndParamFromRequest(request);
id = temp.id;
params = temp.params;
}
try {
const response = await axios.get(`/${this.bibleType}/${id}/books`, {
params
});
result = response.data.data;
} catch (getError) {
result = getError;
}
return result;
}
/**
* @param {string|BookRequestParam} request id of the bible or object containing id, bookId, and parameters
* @param {string} [bookIdStr] id of the book to fetch. Not required if the request is an object.
* @returns {Promise<BookResponse>} book data
*/
async getBook(request, bookIdStr) {
const {
axios
} = this;
let id;
let bookId;
let params;
let result = null;
if (typeof request === 'string') {
if (!bookIdStr) throw new Error('bibleId provided as string without bookId as second parameter');
id = request;
bookId = bookIdStr.toUpperCase();
}
if (typeof request === 'object') {
const temp = BibleService.getRoutesAndParamFromRequest(request);
id = temp.id;
bookId = temp.bookId;
params = temp.params;
}
try {
const response = await axios.get(`/${this.bibleType}/${id}/books/${bookId}`, {
params
});
result = response.data.data;
} catch (getError) {
result = getError;
}
return result;
}
/**
* Gets chapters from a single book
*
* @param {ChaptersRequestParam|string} request id of the bible or object containing id, bookId, and parameters
* @param {string} [bookIdStr=''] id for the book. Not needed if request is an object and has bookId
* @returns {Promise<Array<ChapterSummaryResponse>>} Chapterdata
*/
async getChaptersFromBook(request, bookIdStr) {
let id;
let bookId;
let params;
let result = null;
if (typeof request === 'string') {
if (!bookIdStr) throw new Error('bibleId provided as string without bookId as second parameter');
bookId = bookIdStr;
id = request;
}
if (typeof request === 'object') {
const temp = BibleService.getRoutesAndParamFromRequest(request);
id = temp.id;
bookId = temp.bookId;
params = temp.params;
}
try {
const response = await this.axios.get(`/${this.bibleType}/${id}/books/${bookId}/chapters`, {
params
});
result = response.data.data;
} catch (getError) {
result = getError;
}
return result;
}
/**
* @param {ChapterRequestParam|string} request options object
* @param {string} chapterIdStr chapter id. not needed if request has chapterId
* @returns {Promise<ChapterResponse>} The chapter
*/
async getChapter(request, chapterIdStr) {
let id;
let chapterId;
let params;
let result = null;
if (typeof request === 'string') {
if (!chapterIdStr) throw new Error('bibleId provided as string without chapterId as second parameter');
chapterId = chapterIdStr.toLowerCase(); // if the chapter is .intro it must be lowercase
id = request;
}
if (typeof request === 'object') {
const temp = BibleService.getRoutesAndParamFromRequest(request);
id = temp.id;
chapterId = temp.chapterId.toLowerCase();
params = temp.params;
}
try {
const response = await this.axios.get(`/${this.bibleType}/${id}/chapters/${chapterId}`, {
params
});
result = response.data.data;
} catch (getError) {
result = getError;
}
return result;
}
/**
* @param {PassageRequestParam|string} request options or string with bible id
* @param {string} passageIdStr id of passage (e.g. GEN.1.1-GEN.2.2)
* @returns {Promise<PassageResponse>} passageData
*/
async getPassage(request, passageIdStr) {
let id;
let passageId;
let params;
let result = null;
if (typeof request === 'string') {
if (!passageIdStr) throw new Error('bibleId provided as string without passageId as second parameter');
passageId = passageIdStr.toUpperCase();
id = request;
}
if (typeof request === 'object') {
const temp = BibleService.getRoutesAndParamFromRequest(request);
id = temp.id;
passageId = temp.passageId;
params = temp.params;
}
try {
const response = await this.axios.get(`/${this.bibleType}/${id}/passages/${passageId}`, {
params
});
result = response.data.data;
} catch (getError) {
result = getError;
}
return result;
}
/**
* Alias for getPassage
*
* @param {PassageRequestParam|string} request options or string with bible id
* @param {string} passageIdStr id of passage (e.g. GEN.1.1-GEN.2.2)
* @returns {Promise<PassageResponse>} passageData
*/
async getVerses(request, passageIdStr) {
return this.getPassage(request, passageIdStr);
}
/**
* Gets verses from a single chapter
*
* @param {VersesRequestParam|string} request id of the bible or object containing id, bookId, and parameters
* @param {string} [chapterIdStr] chapterId (e.g. GEN.1)
* @returns {Promise<Array<VerseSummaryResponse>>} chapterdata
*/
async getVersesFromChapter(request, chapterIdStr) {
let id;
let chapterId;
let params;
let result = null;
if (typeof request === 'string') {
if (!chapterIdStr) throw new Error('bibleId provided as string without chapterId as second parameter');
chapterId = chapterIdStr.toLowerCase(); // if the chapter is .intro it must be lowercase
id = request;
}
if (typeof request === 'object') {
const temp = BibleService.getRoutesAndParamFromRequest(request);
id = temp.id;
chapterId = temp.chapterId.toLowerCase();
params = temp.params;
}
try {
const response = await this.axios.get(`/${this.bibleType}/${id}/chapters/${chapterId}/verses`, {
params
});
result = response.data.data;
} catch (getError) {
result = getError;
}
return result;
}
/**
* Get a verse
*
* @param {VerseRequestParam|string} request id of the bible or object containing id, bookId, and parameters
* @param {string} [verseIdStr] verseId (e.g. GEN.1.1) not needed if the request parameter has verseId
* @returns {Promise<Array<VerseResponse>>} versedata
*/
async getVerse(request, verseIdStr) {
let id;
let verseId;
let params;
let result = null;
if (typeof request === 'string') {
if (!verseIdStr) throw new Error('bibleId provided as string without verseId as second parameter');
verseId = verseIdStr.toLowerCase(); // if the chapter is .intro it must be lowercase
id = request;
}
if (typeof request === 'object') {
const temp = BibleService.getRoutesAndParamFromRequest(request);
id = temp.id;
verseId = temp.verseId.toLowerCase();
params = temp.params;
}
try {
const response = await this.axios.get(`/${this.bibleType}/${id}/verses/${verseId}`, {
params
});
result = response.data.data;
} catch (getError) {
result = getError;
}
return result;
}
/**
* Get search Results
*
* @param {SearchRequestParam|string} request id of the bible or object containing id, bookId, and parameters
* @param {string} [queryString] Search keywords or passage reference. Supported wildcards are * and ?.
* @returns {Promise<SearchResponse>} search response
*/
async search(request, queryString) {
let id;
let query;
let params = {};
let result = null;
if (typeof request === 'string') {
if (!queryString) throw new Error('bibleId provided as string without query as second parameter');
query = queryString;
id = request;
params = {
query
};
}
if (typeof request === 'object') {
const temp = BibleService.getRoutesAndParamFromRequest(request);
id = temp.id;
params = temp.params;
delete params.id;
}
try {
const response = await this.axios.get(`/${this.bibleType}/${id}/search`, {
params
});
result = response.data.data;
} catch (getError) {
result = getError;
}
return result;
}
}
_defineProperty(BibleService, "BibleTypes", BibleTypes);
_defineProperty(BibleService, "RequestParameters", RequestParameters);
module.exports = BibleService;