shamela
Version:
Library to interact with the Maktabah Shamela v4 APIs
449 lines (448 loc) • 14.1 kB
TypeScript
//#region src/db/types.d.ts
/**
* A record that can be deleted by patches.
*/
type Deletable = {
/** Indicates if it was deleted in the patch if it is set to '1 */
is_deleted?: string;
};
type Unique = {
/** Unique identifier */
id: number;
};
/**
* Database row structure for the author table.
*/
type AuthorRow = Deletable & Unique & {
/** Author biography */
biography: string;
/** Death year */
death_number: string;
/** The death year as a text */
death_text: string;
/** Author name */
name: string;
};
/**
* Database row structure for the book table.
*/
type BookRow = Deletable & Unique & {
/** Serialized author ID(s) "2747, 3147" or "513" */
author: string;
/** Bibliography information */
bibliography: string;
/** Category ID */
category: string;
/** Publication date (or 99999 for unavailable) */
date: string;
/** Hint or description */
hint: string;
/** Major version */
major_release: string;
/** Serialized metadata */
metadata: string;
/** Minor version */
minor_release: string;
/** Book name */
name: string;
/** Serialized PDF links */
pdf_links: string;
/** Printed flag */
printed: string;
/** Book type */
type: string;
};
/**
* Database row structure for the category table.
*/
type CategoryRow = Deletable & Unique & {
/** Category name */
name: string;
/** Category order in the list to show. */
order: string;
};
/**
* Database row structure for the page table.
*/
type PageRow = Deletable & Unique & {
/** Page content */
content: string;
/** Page number */
number: string | null;
/** Page reference */
page: string | null;
/** Part number */
part: string | null;
/** Additional metadata */
services: string | null;
};
/**
* Database row structure for the title table.
*/
type TitleRow = Deletable & Unique & {
/** Title content */
content: string;
/** Page number */
page: string;
/** Parent title ID */
parent: string | null;
};
//#endregion
//#region src/types.d.ts
/**
* Represents an author entity.
*/
type Author = AuthorRow;
/**
* Represents a book entity.
*/
type Book = BookRow;
/**
* A category for a book.
*/
type Category = CategoryRow;
/**
* A page in a book.
*/
type Page = Pick<PageRow, 'id' | 'content'> & {
page?: number;
part?: string;
number?: string;
};
/**
* A title heading in a book.
*/
type Title = Pick<TitleRow, 'id' | 'content'> & {
page: number;
parent?: number;
};
/**
* Represents book content data.
*/
type BookData = {
/** Array of pages in the book */
pages: Page[];
/** Array of titles/chapters */
titles: Title[];
};
/**
* Master data structure containing all core entities.
*/
type MasterData = {
/** Array of all authors */
authors: Author[];
/** Array of all books */
books: Book[];
/** Array of all categories */
categories: Category[];
/** Version number for the downloaded master database */
version: number;
};
/**
* Options for downloading a book.
*/
type DownloadBookOptions = {
/** Optional book metadata */
bookMetadata?: GetBookMetadataResponsePayload;
/** Output file configuration */
outputFile: OutputOptions;
};
/**
* Options for downloading master data.
*/
type DownloadMasterOptions = {
/** Optional master metadata */
masterMetadata?: GetMasterMetadataResponsePayload;
/** Output file configuration */
outputFile: OutputOptions;
};
/**
* Options for getting book metadata.
*/
type GetBookMetadataOptions = {
/** Major version number */
majorVersion: number;
/** Minor version number */
minorVersion: number;
};
/**
* Response payload for book metadata requests.
*/
type GetBookMetadataResponsePayload = {
/** Major release version */
majorRelease: number;
/** URL for major release download */
majorReleaseUrl: string;
/** Optional minor release version */
minorRelease?: number;
/** Optional URL for minor release download */
minorReleaseUrl?: string;
};
/**
* Response payload for master metadata requests.
*/
type GetMasterMetadataResponsePayload = {
/** Download URL */
url: string;
/** Version number */
version: number;
};
type NodeJSOutput = {
/** Output file path (Node.js only) */
path: string;
writer?: never;
};
type CustomOutput = {
/** Custom writer used when path is not provided */
writer: (payload: string | Uint8Array) => Promise<void> | void;
path?: undefined;
};
/**
* Output file options.
*/
type OutputOptions = NodeJSOutput | CustomOutput;
/**
* Runtime configuration for the library.
*/
type ShamelaConfig = {
/** API key used to authenticate against Shamela services */
apiKey?: string;
/** Endpoint used for book metadata */
booksEndpoint?: string;
/** Endpoint used for master metadata */
masterPatchEndpoint?: string;
/** Optional override for the sql.js wasm asset location */
sqlJsWasmUrl?: string;
/** Optional custom fetch implementation for environments without a global fetch */
fetchImplementation?: typeof fetch;
};
/**
* Valid configuration keys.
*/
type ShamelaConfigKey = keyof ShamelaConfig;
//#endregion
//#region src/api.d.ts
/**
* Retrieves metadata for a specific book from the Shamela API.
*
* This function fetches book release information including major and minor release
* URLs and version numbers from the Shamela web service.
*
* @param id - The unique identifier of the book to fetch metadata for
* @param options - Optional parameters for specifying major and minor versions
* @returns A promise that resolves to book metadata including release URLs and versions
*
* @throws {Error} When environment variables are not set or API request fails
*
* @example
* ```typescript
* const metadata = await getBookMetadata(123, { majorVersion: 1, minorVersion: 2 });
* console.log(metadata.majorReleaseUrl); // Download URL for the book
* ```
*/
declare const getBookMetadata: (id: number, options?: GetBookMetadataOptions) => Promise<GetBookMetadataResponsePayload>;
/**
* Downloads and processes a book from the Shamela database.
*
* This function downloads the book's database files, applies patches if available,
* creates the necessary database tables, and exports the data to the specified format.
* The output can be either a JSON file or a SQLite database file.
*
* @param id - The unique identifier of the book to download
* @param options - Configuration options including output file path and optional book metadata
* @returns A promise that resolves to the path of the created output file
*
* @throws {Error} When download fails, database operations fail, or file operations fail
*
* @example
* ```typescript
* // Download as JSON
* const jsonPath = await downloadBook(123, {
* outputFile: { path: './book.json' }
* });
*
* // Download as SQLite database
* const dbPath = await downloadBook(123, {
* outputFile: { path: './book.db' }
* });
* ```
*/
declare const downloadBook: (id: number, options: DownloadBookOptions) => Promise<string>;
/**
* Retrieves metadata for the master database from the Shamela API.
*
* The master database contains information about all books, authors, and categories
* in the Shamela library. This function fetches the download URL and version
* information for the master database patches.
*
* @param version - The version number to check for updates (defaults to 0)
* @returns A promise that resolves to master database metadata including download URL and version
*
* @throws {Error} When environment variables are not set or API request fails
*
* @example
* ```typescript
* const masterMetadata = await getMasterMetadata(5);
* console.log(masterMetadata.url); // URL to download master database patch
* console.log(masterMetadata.version); // Latest version number
* ```
*/
declare const getMasterMetadata: (version?: number) => Promise<GetMasterMetadataResponsePayload>;
/**
* Generates the URL for a book's cover image.
*
* This function constructs the URL to access the cover image for a specific book
* using the book's ID and the API endpoint host.
*
* @param bookId - The unique identifier of the book
* @returns The complete URL to the book's cover image
*
* @example
* ```typescript
* const coverUrl = getCoverUrl(123);
* console.log(coverUrl); // "https://api.shamela.ws/covers/123.jpg"
* ```
*/
declare const getCoverUrl: (bookId: number) => string;
/**
* Downloads and processes the master database from the Shamela service.
*
* The master database contains comprehensive information about all books, authors,
* and categories available in the Shamela library. This function downloads the
* database files, creates the necessary tables, and exports the data in the
* specified format (JSON or SQLite).
*
* @param options - Configuration options including output file path and optional master metadata
* @returns A promise that resolves to the path of the created output file
*
* @throws {Error} When download fails, expected tables are missing, database operations fail, or file operations fail
*
* @example
* ```typescript
* // Download master database as JSON
* const jsonPath = await downloadMasterDatabase({
* outputFile: { path: './master.json' }
* });
*
* // Download master database as SQLite
* const dbPath = await downloadMasterDatabase({
* outputFile: { path: './master.db' }
* });
* ```
*/
declare const downloadMasterDatabase: (options: DownloadMasterOptions) => Promise<string>;
/**
* Retrieves complete book data including pages and titles.
*
* This is a convenience function that downloads a book's data and returns it
* as a structured JavaScript object. The function handles the temporary file
* creation and cleanup automatically.
*
* @param id - The unique identifier of the book to retrieve
* @returns A promise that resolves to the complete book data including pages and titles
*
* @throws {Error} When download fails, file operations fail, or JSON parsing fails
*
* @example
* ```typescript
* const bookData = await getBook(123);
* console.log(bookData.pages.length); // Number of pages in the book
* console.log(bookData.titles?.length); // Number of title entries
* ```
*/
declare const getBook: (id: number) => Promise<BookData>;
/**
* Retrieves complete master data including authors, books, and categories.
*
* This convenience function downloads the master database archive, builds an in-memory
* SQLite database, and returns structured data for immediate consumption alongside
* the version number of the snapshot.
*
* @returns A promise that resolves to the complete master dataset and its version
*/
declare const getMaster: () => Promise<MasterData>;
//#endregion
//#region src/utils/logger.d.ts
/**
* Signature accepted by logger methods.
*/
type LogFunction = (...args: unknown[]) => void;
/**
* Contract expected from logger implementations consumed by the library.
*/
interface Logger {
debug: LogFunction;
error: LogFunction;
info: LogFunction;
warn: LogFunction;
}
//#endregion
//#region src/config.d.ts
/**
* Runtime configuration options accepted by {@link configure}.
*/
type ConfigureOptions = Partial<ShamelaConfig> & {
logger?: Logger;
};
/**
* Updates the runtime configuration for the library.
*
* This function merges the provided options with existing overrides and optionally
* configures a custom logger implementation.
*
* @param config - Runtime configuration overrides and optional logger instance
*/
declare const configure: (config: ConfigureOptions) => void;
/**
* Clears runtime configuration overrides and restores the default logger.
*/
declare const resetConfig: () => void;
//#endregion
//#region src/content.d.ts
type Line = {
id?: string;
text: string;
};
/**
* Parses Shamela HTML content into structured lines while preserving headings.
*
* @param content - The raw HTML markup representing a page
* @returns An array of {@link Line} objects containing text and optional IDs
*/
declare const parseContentRobust: (content: string) => Line[];
/**
* Sanitises page content by applying regex replacement rules.
*
* @param text - The text to clean
* @param rules - Optional custom replacements, defaults to {@link DEFAULT_SANITIZATION_RULES}
* @returns The sanitised content
*/
declare const sanitizePageContent: (text: string, rules?: Record<string, string>) => string;
/**
* Splits a page body from its trailing footnotes using a marker string.
*
* @param content - Combined body and footnote text
* @param footnoteMarker - Marker indicating the start of footnotes
* @returns A tuple containing the page body followed by the footnote section
*/
declare const splitPageBodyFromFooter: (content: string, footnoteMarker?: string) => readonly [string, string];
/**
* Removes Arabic numeral page markers enclosed in turtle ⦗ ⦘ brackets.
* Replaces the marker along with up to two preceding whitespace characters
* (space or carriage return) and up to one following whitespace character
* with a single space.
*
* @param text - Text potentially containing page markers
* @returns The text with numeric markers replaced by a single space
*/
declare const removeArabicNumericPageMarkers: (text: string) => string;
/**
* Removes anchor and hadeeth tags from the content while preserving spans.
*
* @param content - HTML string containing various tags
* @returns The content with only span tags retained
*/
declare const removeTagsExceptSpan: (content: string) => string;
//#endregion
export { Author, Book, BookData, Category, type ConfigureOptions, DownloadBookOptions, DownloadMasterOptions, GetBookMetadataOptions, GetBookMetadataResponsePayload, GetMasterMetadataResponsePayload, Line, type Logger, MasterData, OutputOptions, Page, ShamelaConfig, ShamelaConfigKey, Title, configure, downloadBook, downloadMasterDatabase, getBook, getBookMetadata, getCoverUrl, getMaster, getMasterMetadata, parseContentRobust, removeArabicNumericPageMarkers, removeTagsExceptSpan, resetConfig, sanitizePageContent, splitPageBodyFromFooter };
//# sourceMappingURL=index.d.ts.map