shamela 1.0.3 → 1.0.4

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/README.md CHANGED
@@ -1,27 +1,37 @@
1
1
  # Shamela
2
2
 
3
- [![wakatime](https://wakatime.com/badge/user/a0b906ce-b8e7-4463-8bce-383238df6d4b/project/faef70ab-efdb-448b-ab83-0fc66c95888e.svg)](https://wakatime.com/badge/user/a0b906ce-b8e7-4463-8bce-383238df6d4b/project/faef70ab-efdb-448b-ab83-0fc66c95888e) [![E2E](https://github.com/ragaeeb/shamela/actions/workflows/e2e.yml/badge.svg)](https://github.com/ragaeeb/shamela/actions/workflows/e2e.yml) [![Node.js CI](https://github.com/ragaeeb/shamela/actions/workflows/build.yml/badge.svg)](https://github.com/ragaeeb/shamela/actions/workflows/build.yml) ![GitHub License](https://img.shields.io/github/license/ragaeeb/shamela) ![GitHub Release](https://img.shields.io/github/v/release/ragaeeb/shamela) [![codecov](https://codecov.io/gh/ragaeeb/shamela/graph/badge.svg?token=PK55V1R324)](https://codecov.io/gh/ragaeeb/shamela) [![Size](https://deno.bundlejs.com/badge?q=shamela@1.0.3)](https://bundlejs.com/?q=shamela%401.0.3) ![typescript](https://badgen.net/badge/icon/typescript?icon=typescript&label&color=blue) ![npm](https://img.shields.io/npm/v/shamela) ![npm](https://img.shields.io/npm/dm/shamela) ![GitHub issues](https://img.shields.io/github/issues/ragaeeb/shamela) ![GitHub stars](https://img.shields.io/github/stars/ragaeeb/shamela?style=social)
3
+ [![wakatime](https://wakatime.com/badge/user/a0b906ce-b8e7-4463-8bce-383238df6d4b/project/faef70ab-efdb-448b-ab83-0fc66c95888e.svg)](https://wakatime.com/badge/user/a0b906ce-b8e7-4463-8bce-383238df6d4b/project/faef70ab-efdb-448b-ab83-0fc66c95888e)
4
+ [![E2E](https://github.com/ragaeeb/shamela/actions/workflows/e2e.yml/badge.svg)](https://github.com/ragaeeb/shamela/actions/workflows/e2e.yml)
5
+ [![Node.js CI](https://github.com/ragaeeb/shamela/actions/workflows/build.yml/badge.svg)](https://github.com/ragaeeb/shamela/actions/workflows/build.yml) ![GitHub License](https://img.shields.io/github/license/ragaeeb/shamela)
6
+ ![GitHub Release](https://img.shields.io/github/v/release/ragaeeb/shamela)
7
+ [![codecov](https://codecov.io/gh/ragaeeb/shamela/graph/badge.svg?token=PK55V1R324)](https://codecov.io/gh/ragaeeb/shamela)
8
+ [![Size](https://deno.bundlejs.com/badge?q=shamela@1.0.5)](https://bundlejs.com/?q=shamela%401.0.5)
9
+ ![typescript](https://badgen.net/badge/icon/typescript?icon=typescript&label&color=blue)
10
+ ![npm](https://img.shields.io/npm/v/shamela)
11
+ ![npm](https://img.shields.io/npm/dm/shamela)
12
+ ![GitHub issues](https://img.shields.io/github/issues/ragaeeb/shamela)
13
+ ![GitHub stars](https://img.shields.io/github/stars/ragaeeb/shamela?style=social)
4
14
 
5
15
  A `NodeJS` library for accessing and downloading Maktabah Shamela v4 APIs. This library provides easy-to-use functions to interact with the Shamela API, download master and book databases, and retrieve book data programmatically.
6
16
 
7
17
  ## Table of Contents
8
18
 
9
- - [Installation](#installation)
10
- - [Environment Variables](#environment-variables)
11
- - [Usage](#usage)
12
- - [Getting Started](#getting-started)
13
- - [API Functions](#api-functions)
14
- - [getMasterMetadata](#getmastermetadata)
15
- - [downloadMasterDatabase](#downloadmasterdatabase)
16
- - [getBookMetadata](#getbookmetadata)
17
- - [downloadBook](#downloadbook)
18
- - [getBook](#getbook)
19
- - [Examples](#examples)
20
- - [Downloading the Master Database](#downloading-the-master-database)
21
- - [Downloading a Book](#downloading-a-book)
22
- - [Retrieving Book Data](#retrieving-book-data)
23
- - [Testing](#testing)
24
- - [License](#license)
19
+ - [Installation](#installation)
20
+ - [Environment Variables](#environment-variables)
21
+ - [Usage](#usage)
22
+ - [Getting Started](#getting-started)
23
+ - [API Functions](#api-functions)
24
+ - [getMasterMetadata](#getmastermetadata)
25
+ - [downloadMasterDatabase](#downloadmasterdatabase)
26
+ - [getBookMetadata](#getbookmetadata)
27
+ - [downloadBook](#downloadbook)
28
+ - [getBook](#getbook)
29
+ - [Examples](#examples)
30
+ - [Downloading the Master Database](#downloading-the-master-database)
31
+ - [Downloading a Book](#downloading-a-book)
32
+ - [Retrieving Book Data](#retrieving-book-data)
33
+ - [Testing](#testing)
34
+ - [License](#license)
25
35
 
26
36
  ## Installation
27
37
 
@@ -77,7 +87,7 @@ getMasterMetadata(version?: number): Promise<GetMasterMetadataResponsePayload>
77
87
 
78
88
  ```
79
89
 
80
- - version (optional): The version number of the master database you want to fetch.
90
+ - version (optional): The version number of the master database you want to fetch.
81
91
 
82
92
  Example:
83
93
 
@@ -94,9 +104,9 @@ downloadMasterDatabase(options: DownloadMasterOptions): Promise<string>
94
104
 
95
105
  ```
96
106
 
97
- - options: An object containing:
98
- - masterMetadata (optional): The metadata obtained from getMasterMetadata.
99
- - outputFile: An object specifying the output path.
107
+ - options: An object containing:
108
+ - masterMetadata (optional): The metadata obtained from getMasterMetadata.
109
+ - outputFile: An object specifying the output path.
100
110
 
101
111
  Example:
102
112
 
@@ -114,10 +124,10 @@ Fetches metadata for a specific book.
114
124
  getBookMetadata(id: number, options?: GetBookMetadataOptions): Promise<GetBookMetadataResponsePayload>
115
125
  ```
116
126
 
117
- - id: The ID of the book.
118
- - options (optional): An object containing:
119
- - majorVersion: The major version of the book.
120
- - minorVersion: The minor version of the book.
127
+ - id: The ID of the book.
128
+ - options (optional): An object containing:
129
+ - majorVersion: The major version of the book.
130
+ - minorVersion: The minor version of the book.
121
131
 
122
132
  Example:
123
133
 
@@ -135,7 +145,7 @@ Retrieves the data of a book as a JavaScript object.
135
145
  getBook(id: number): Promise<BookData>
136
146
  ```
137
147
 
138
- - id: The ID of the book.
148
+ - id: The ID of the book.
139
149
 
140
150
  Example:
141
151
 
package/dist/main.js CHANGED
@@ -1,15 +1,15 @@
1
- import {createClient as $5oumB$createClient} from "@libsql/client";
2
- import {promises as $5oumB$promises, createWriteStream as $5oumB$createWriteStream} from "fs";
3
- import $5oumB$path from "path";
4
- import $5oumB$process from "process";
5
- import {URL as $5oumB$URL, URLSearchParams as $5oumB$URLSearchParams} from "url";
6
- import $5oumB$pino from "pino";
7
- import $5oumB$pinopretty from "pino-pretty";
8
- import $5oumB$https from "https";
9
- import $5oumB$os from "os";
10
- import {pipeline as $5oumB$pipeline} from "stream/promises";
11
- import $5oumB$unzipper from "unzipper";
12
- import {Buffer as $5oumB$Buffer} from "buffer";
1
+ import {createClient as $SK0tW$createClient} from "@libsql/client";
2
+ import {promises as $SK0tW$promises, createWriteStream as $SK0tW$createWriteStream} from "fs";
3
+ import $SK0tW$path from "path";
4
+ import $SK0tW$process from "process";
5
+ import {URL as $SK0tW$URL, URLSearchParams as $SK0tW$URLSearchParams} from "url";
6
+ import $SK0tW$pino from "pino";
7
+ import $SK0tW$pinopretty from "pino-pretty";
8
+ import $SK0tW$https from "https";
9
+ import $SK0tW$os from "os";
10
+ import {pipeline as $SK0tW$pipeline} from "stream/promises";
11
+ import $SK0tW$unzipper from "unzipper";
12
+ import {Buffer as $SK0tW$Buffer} from "buffer";
13
13
 
14
14
 
15
15
 
@@ -19,44 +19,50 @@ import {Buffer as $5oumB$Buffer} from "buffer";
19
19
 
20
20
 
21
21
 
22
- const $2d2b29d79cbbfeda$var$stream = (0, $5oumB$pinopretty)({
22
+ const $526b48a37e8a8ec6$var$stream = (0, $SK0tW$pinopretty)({
23
23
  colorize: true
24
24
  });
25
- const $2d2b29d79cbbfeda$var$logger = (0, $5oumB$pino)({
25
+ const $526b48a37e8a8ec6$var$logger = (0, $SK0tW$pino)({
26
26
  base: {
27
27
  pid: undefined,
28
28
  hostname: undefined
29
29
  },
30
- level: (0, $5oumB$process).env.LOG_LEVEL || "info"
31
- }, $2d2b29d79cbbfeda$var$stream);
32
- var $2d2b29d79cbbfeda$export$2e2bcd8739ae039 = $2d2b29d79cbbfeda$var$logger;
30
+ level: (0, $SK0tW$process).env.LOG_LEVEL || 'info'
31
+ }, $526b48a37e8a8ec6$var$stream);
32
+ var $526b48a37e8a8ec6$export$2e2bcd8739ae039 = $526b48a37e8a8ec6$var$logger;
33
33
 
34
34
 
35
- const $b142353d92e15b6f$export$1d57574773c8bc58 = async (db, dbName)=>{
36
- const { rows: tables } = await db.execute(`SELECT name FROM ${dbName}.sqlite_master WHERE type='table'`);
37
- return tables;
35
+ const $26460f21c4456828$export$1d57574773c8bc58 = async (db, dbName)=>{
36
+ const { rows: tables } = await db.execute(`SELECT name,sql FROM ${dbName}.sqlite_master WHERE type='table'`);
37
+ return tables.map((row)=>{
38
+ const fields = row.sql.split(', ').map((field)=>field.split(' ')[0]);
39
+ return {
40
+ fields: fields,
41
+ name: row.name
42
+ };
43
+ });
38
44
  };
39
- const $b142353d92e15b6f$export$3274d151f0598f1 = async (client, table)=>{
45
+ const $26460f21c4456828$export$3274d151f0598f1 = async (client, table)=>{
40
46
  const { rows: rows } = await client.execute(`SELECT * FROM ${table}`);
41
47
  return rows;
42
48
  };
43
49
 
44
50
 
45
- const $e6f751831b705ed8$var$MAIN_DB_ALIAS = "main";
46
- const $e6f751831b705ed8$export$ee56083bb7df7ecc = (dbFile, alias)=>`ATTACH DATABASE '${dbFile}' AS ${alias}`;
47
- const $e6f751831b705ed8$export$1f75c01d8a920a35 = (patchAlias, tableName, aslAlias = $e6f751831b705ed8$var$MAIN_DB_ALIAS)=>`
51
+ const $746504ca27eabe49$var$MAIN_DB_ALIAS = 'main';
52
+ const $746504ca27eabe49$export$ee56083bb7df7ecc = (dbFile, alias)=>`ATTACH DATABASE '${dbFile}' AS ${alias}`;
53
+ const $746504ca27eabe49$export$1f75c01d8a920a35 = (patchAlias, tableName, aslAlias = $746504ca27eabe49$var$MAIN_DB_ALIAS)=>`
48
54
  UPDATE ${aslAlias}.${tableName}
49
- SET content = ${$e6f751831b705ed8$var$updatePageColumn("content", aslAlias, patchAlias)},
50
- part = ${$e6f751831b705ed8$var$updatePageColumn("part", aslAlias, patchAlias)},
51
- page = ${$e6f751831b705ed8$var$updatePageColumn("page", aslAlias, patchAlias)},
52
- number = ${$e6f751831b705ed8$var$updatePageColumn("number", aslAlias, patchAlias)}
55
+ SET content = ${$746504ca27eabe49$var$updatePageColumn('content', aslAlias, patchAlias)},
56
+ part = ${$746504ca27eabe49$var$updatePageColumn('part', aslAlias, patchAlias)},
57
+ page = ${$746504ca27eabe49$var$updatePageColumn('page', aslAlias, patchAlias)},
58
+ number = ${$746504ca27eabe49$var$updatePageColumn('number', aslAlias, patchAlias)}
53
59
  WHERE EXISTS (
54
60
  SELECT 1
55
61
  FROM ${patchAlias}.${tableName}
56
62
  WHERE ${aslAlias}.${tableName}.id = ${patchAlias}.${tableName}.id
57
63
  );
58
64
  `;
59
- const $e6f751831b705ed8$var$updateTitleColumn = (columnName, aslAlias, patchAlias)=>`
65
+ const $746504ca27eabe49$var$updateTitleColumn = (columnName, aslAlias, patchAlias)=>`
60
66
  (SELECT CASE
61
67
  WHEN ${patchAlias}.title.${columnName} != '#' THEN ${patchAlias}.title.${columnName}
62
68
  ELSE ${aslAlias}.title.${columnName}
@@ -64,20 +70,20 @@ const $e6f751831b705ed8$var$updateTitleColumn = (columnName, aslAlias, patchAlia
64
70
  FROM ${patchAlias}.title
65
71
  WHERE ${aslAlias}.title.id = ${patchAlias}.title.id)
66
72
  `;
67
- const $e6f751831b705ed8$export$a38d1618b943c74f = (patchAlias, tableName, aslAlias = $e6f751831b705ed8$var$MAIN_DB_ALIAS)=>`
73
+ const $746504ca27eabe49$export$a38d1618b943c74f = (patchAlias, tableName, aslAlias = $746504ca27eabe49$var$MAIN_DB_ALIAS)=>`
68
74
  UPDATE ${aslAlias}.${tableName}
69
- SET content = ${$e6f751831b705ed8$var$updateTitleColumn("content", aslAlias, patchAlias)},
70
- page = ${$e6f751831b705ed8$var$updateTitleColumn("page", aslAlias, patchAlias)},
71
- parent = ${$e6f751831b705ed8$var$updateTitleColumn("parent", aslAlias, patchAlias)}
75
+ SET content = ${$746504ca27eabe49$var$updateTitleColumn('content', aslAlias, patchAlias)},
76
+ page = ${$746504ca27eabe49$var$updateTitleColumn('page', aslAlias, patchAlias)},
77
+ parent = ${$746504ca27eabe49$var$updateTitleColumn('parent', aslAlias, patchAlias)}
72
78
  WHERE EXISTS (
73
79
  SELECT 1
74
80
  FROM ${patchAlias}.${tableName}
75
81
  WHERE ${aslAlias}.${tableName}.id = ${patchAlias}.${tableName}.id
76
82
  );
77
83
  `;
78
- const $e6f751831b705ed8$export$33bbb3ec7652e187 = (name, fields)=>`CREATE TABLE IF NOT EXISTS ${name} (${fields.join(", ")})`;
79
- const $e6f751831b705ed8$export$7fec5208c714b262 = (alias)=>`DETACH DATABASE ${alias}`;
80
- const $e6f751831b705ed8$var$updatePageColumn = (columnName, aslAlias, patchAlias)=>`
84
+ const $746504ca27eabe49$export$33bbb3ec7652e187 = (name, fields)=>`CREATE TABLE IF NOT EXISTS ${name} (${fields.join(', ')})`;
85
+ const $746504ca27eabe49$export$7fec5208c714b262 = (alias)=>`DETACH DATABASE ${alias}`;
86
+ const $746504ca27eabe49$var$updatePageColumn = (columnName, aslAlias, patchAlias)=>`
81
87
  (SELECT CASE
82
88
  WHEN ${patchAlias}.page.${columnName} != '#' THEN ${patchAlias}.page.${columnName}
83
89
  ELSE ${aslAlias}.page.${columnName}
@@ -85,85 +91,97 @@ const $e6f751831b705ed8$var$updatePageColumn = (columnName, aslAlias, patchAlias
85
91
  FROM ${patchAlias}.page
86
92
  WHERE ${aslAlias}.page.id = ${patchAlias}.page.id)
87
93
  `;
88
- const $e6f751831b705ed8$export$3ef07b9580a45514 = (table, fieldToValue, isDeleted = false)=>{
94
+ const $746504ca27eabe49$export$3ef07b9580a45514 = (table, fieldToValue, isDeleted = false)=>{
89
95
  const combinedRecords = {
90
96
  ...fieldToValue,
91
- is_deleted: isDeleted ? "1" : "0"
97
+ is_deleted: isDeleted ? '1' : '0'
92
98
  };
93
99
  const sortedKeys = Object.keys(combinedRecords).sort();
94
100
  const sortedValues = sortedKeys.map((key)=>combinedRecords[key]);
95
101
  return `INSERT INTO ${table} (${sortedKeys.toString()}) VALUES (${sortedValues.map((val)=>{
96
- if (val === null) return "NULL";
97
- return typeof val === "string" ? `'${val}'` : val;
102
+ if (val === null) return 'NULL';
103
+ return typeof val === 'string' ? `'${val}'` : val;
98
104
  }).toString()})`;
99
105
  };
100
106
 
101
107
 
102
- var $167eb860ccdaab7d$export$a17a6870a08b950e;
103
- (function(Tables) {
108
+ var $e5a23c058b2763fa$export$a17a6870a08b950e = /*#__PURE__*/ function(Tables) {
104
109
  Tables["Authors"] = "authors";
105
110
  Tables["Books"] = "books";
106
111
  Tables["Categories"] = "categories";
107
112
  Tables["Page"] = "page";
108
113
  Tables["Title"] = "title";
109
- })($167eb860ccdaab7d$export$a17a6870a08b950e || ($167eb860ccdaab7d$export$a17a6870a08b950e = {}));
114
+ return Tables;
115
+ }({});
110
116
 
111
117
 
112
- const $2a3b237385dd2cff$var$PATCH_DB_ALIAS = "patch";
113
- const $2a3b237385dd2cff$var$ASL_DB_ALIAS = "asl";
114
- const $2a3b237385dd2cff$var$getPagesToCopy = (tables)=>{
115
- const statements = [];
116
- if (tables.find((t)=>t.name === (0, $167eb860ccdaab7d$export$a17a6870a08b950e).Page)) {
117
- statements.push(`INSERT INTO main.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Page} SELECT id,content,part,page,number FROM ${$2a3b237385dd2cff$var$ASL_DB_ALIAS}.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Page} WHERE id IN (SELECT id FROM ${$2a3b237385dd2cff$var$PATCH_DB_ALIAS}.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Page} WHERE is_deleted='0')`);
118
- statements.push((0, $e6f751831b705ed8$export$1f75c01d8a920a35)($2a3b237385dd2cff$var$PATCH_DB_ALIAS, (0, $167eb860ccdaab7d$export$a17a6870a08b950e).Page));
119
- } else statements.push(`INSERT INTO main.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Page} SELECT id,content,part,page,number FROM ${$2a3b237385dd2cff$var$ASL_DB_ALIAS}.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Page} WHERE is_deleted='0'`);
120
- return statements;
121
- };
122
- const $2a3b237385dd2cff$var$getTitlesToCopy = (tables)=>{
118
+ const $d7a7877f07ff6c69$var$PATCH_DB_ALIAS = 'patch';
119
+ const $d7a7877f07ff6c69$var$ASL_DB_ALIAS = 'asl';
120
+ const $d7a7877f07ff6c69$var$buildCopyStatements = (patchTables, aslTables, table, fields, patchQuery)=>{
123
121
  const statements = [];
124
- if (tables.find((t)=>t.name === (0, $167eb860ccdaab7d$export$a17a6870a08b950e).Title)) {
125
- statements.push(`INSERT INTO main.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Title} SELECT id,content,page,parent FROM ${$2a3b237385dd2cff$var$ASL_DB_ALIAS}.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Title} WHERE id IN (SELECT id FROM ${$2a3b237385dd2cff$var$PATCH_DB_ALIAS}.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Title} WHERE is_deleted='0')`);
126
- statements.push((0, $e6f751831b705ed8$export$a38d1618b943c74f)($2a3b237385dd2cff$var$PATCH_DB_ALIAS, (0, $167eb860ccdaab7d$export$a17a6870a08b950e).Title));
127
- } else statements.push(`INSERT INTO main.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Title} SELECT id,content,page,parent FROM ${$2a3b237385dd2cff$var$ASL_DB_ALIAS}.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Title} WHERE is_deleted='0'`);
122
+ if (patchTables.find((t)=>t.name === table)) {
123
+ statements.push(`INSERT INTO main.${table} SELECT ${fields.join(',')} FROM ${$d7a7877f07ff6c69$var$ASL_DB_ALIAS}.${table} WHERE id IN (SELECT id FROM ${$d7a7877f07ff6c69$var$PATCH_DB_ALIAS}.${table} WHERE is_deleted='0')`);
124
+ statements.push(patchQuery);
125
+ } else {
126
+ let copyStatement = `INSERT INTO main.${table} SELECT ${fields.join(',')} FROM ${$d7a7877f07ff6c69$var$ASL_DB_ALIAS}.${table}`;
127
+ if (aslTables.find((t)=>t.name === table)?.fields.includes('is_deleted')) copyStatement += ` WHERE is_deleted='0'`;
128
+ statements.push(copyStatement);
129
+ }
128
130
  return statements;
129
131
  };
130
- const $2a3b237385dd2cff$export$a8b8e03e6bbe5473 = async (db, aslDB, patchDB)=>{
131
- const statements = [
132
- (0, $e6f751831b705ed8$export$ee56083bb7df7ecc)(aslDB, $2a3b237385dd2cff$var$ASL_DB_ALIAS)
133
- ];
134
- if (patchDB) await db.execute((0, $e6f751831b705ed8$export$ee56083bb7df7ecc)(patchDB, $2a3b237385dd2cff$var$PATCH_DB_ALIAS));
135
- const tables = patchDB ? await (0, $b142353d92e15b6f$export$1d57574773c8bc58)(db, $2a3b237385dd2cff$var$PATCH_DB_ALIAS) : [];
136
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).debug({
137
- tables: tables
132
+ const $d7a7877f07ff6c69$export$a8b8e03e6bbe5473 = async (db, aslDB, patchDB)=>{
133
+ await Promise.all([
134
+ db.execute((0, $746504ca27eabe49$export$ee56083bb7df7ecc)(aslDB, $d7a7877f07ff6c69$var$ASL_DB_ALIAS)),
135
+ db.execute((0, $746504ca27eabe49$export$ee56083bb7df7ecc)(patchDB, $d7a7877f07ff6c69$var$PATCH_DB_ALIAS))
136
+ ]);
137
+ const [patchTables, aslTables] = await Promise.all([
138
+ (0, $26460f21c4456828$export$1d57574773c8bc58)(db, $d7a7877f07ff6c69$var$PATCH_DB_ALIAS),
139
+ (0, $26460f21c4456828$export$1d57574773c8bc58)(db, $d7a7877f07ff6c69$var$ASL_DB_ALIAS)
140
+ ]);
141
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).debug({
142
+ aslTables: aslTables,
143
+ patchTables: patchTables
138
144
  }, `Applying patches for...`);
139
- statements.push(...$2a3b237385dd2cff$var$getPagesToCopy(tables));
140
- statements.push(...$2a3b237385dd2cff$var$getTitlesToCopy(tables));
141
- await db.batch(statements);
142
- const detachStatements = [];
143
- detachStatements.push((0, $e6f751831b705ed8$export$7fec5208c714b262)($2a3b237385dd2cff$var$ASL_DB_ALIAS));
144
- if (patchDB) detachStatements.push((0, $e6f751831b705ed8$export$7fec5208c714b262)($2a3b237385dd2cff$var$PATCH_DB_ALIAS));
145
- return db.batch(detachStatements);
145
+ await db.batch([
146
+ ...$d7a7877f07ff6c69$var$buildCopyStatements(patchTables, aslTables, (0, $e5a23c058b2763fa$export$a17a6870a08b950e).Page, [
147
+ 'id',
148
+ 'content',
149
+ 'part',
150
+ 'page',
151
+ 'number'
152
+ ], (0, $746504ca27eabe49$export$1f75c01d8a920a35)($d7a7877f07ff6c69$var$PATCH_DB_ALIAS, (0, $e5a23c058b2763fa$export$a17a6870a08b950e).Page)),
153
+ ...$d7a7877f07ff6c69$var$buildCopyStatements(patchTables, aslTables, (0, $e5a23c058b2763fa$export$a17a6870a08b950e).Title, [
154
+ 'id',
155
+ 'content',
156
+ 'page',
157
+ 'parent'
158
+ ], (0, $746504ca27eabe49$export$a38d1618b943c74f)($d7a7877f07ff6c69$var$PATCH_DB_ALIAS, (0, $e5a23c058b2763fa$export$a17a6870a08b950e).Title))
159
+ ]);
160
+ return db.batch([
161
+ (0, $746504ca27eabe49$export$7fec5208c714b262)($d7a7877f07ff6c69$var$ASL_DB_ALIAS),
162
+ (0, $746504ca27eabe49$export$7fec5208c714b262)($d7a7877f07ff6c69$var$PATCH_DB_ALIAS)
163
+ ]);
146
164
  };
147
- const $2a3b237385dd2cff$export$61101aa23c771e7c = async (db, aslDB)=>{
148
- await db.execute((0, $e6f751831b705ed8$export$ee56083bb7df7ecc)(aslDB, $2a3b237385dd2cff$var$ASL_DB_ALIAS));
149
- const tables = await (0, $b142353d92e15b6f$export$1d57574773c8bc58)(db, $2a3b237385dd2cff$var$ASL_DB_ALIAS);
150
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).debug({
165
+ const $d7a7877f07ff6c69$export$61101aa23c771e7c = async (db, aslDB)=>{
166
+ await db.execute((0, $746504ca27eabe49$export$ee56083bb7df7ecc)(aslDB, $d7a7877f07ff6c69$var$ASL_DB_ALIAS));
167
+ const tables = await (0, $26460f21c4456828$export$1d57574773c8bc58)(db, $d7a7877f07ff6c69$var$ASL_DB_ALIAS);
168
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).debug({
151
169
  tables: tables
152
170
  }, `Applying patches for...`);
153
171
  await db.batch([
154
- `INSERT INTO main.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Title} SELECT id,content,page,parent FROM ${$2a3b237385dd2cff$var$ASL_DB_ALIAS}.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Title}`,
155
- `INSERT INTO main.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Page} SELECT id,content,part,page,number FROM ${$2a3b237385dd2cff$var$ASL_DB_ALIAS}.${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Page}`
172
+ `INSERT INTO main.${(0, $e5a23c058b2763fa$export$a17a6870a08b950e).Title} SELECT id,content,page,parent FROM ${$d7a7877f07ff6c69$var$ASL_DB_ALIAS}.${(0, $e5a23c058b2763fa$export$a17a6870a08b950e).Title}`,
173
+ `INSERT INTO main.${(0, $e5a23c058b2763fa$export$a17a6870a08b950e).Page} SELECT id,content,part,page,number FROM ${$d7a7877f07ff6c69$var$ASL_DB_ALIAS}.${(0, $e5a23c058b2763fa$export$a17a6870a08b950e).Page}`
156
174
  ]);
157
- return db.execute((0, $e6f751831b705ed8$export$7fec5208c714b262)($2a3b237385dd2cff$var$ASL_DB_ALIAS));
175
+ return db.execute((0, $746504ca27eabe49$export$7fec5208c714b262)($d7a7877f07ff6c69$var$ASL_DB_ALIAS));
158
176
  };
159
- const $2a3b237385dd2cff$export$5d28a6b0dd65e4c4 = async (db)=>{
177
+ const $d7a7877f07ff6c69$export$5d28a6b0dd65e4c4 = async (db)=>{
160
178
  return db.batch([
161
179
  `CREATE TABLE page (id INTEGER PRIMARY KEY, content TEXT, part INTEGER, page INTEGER, number INTEGER)`,
162
180
  `CREATE TABLE title (id INTEGER PRIMARY KEY, content TEXT, page INTEGER, parent INTEGER)`
163
181
  ]);
164
182
  };
165
- const $2a3b237385dd2cff$export$3bd13330ac8e761e = async (db)=>{
166
- const rows = await (0, $b142353d92e15b6f$export$3274d151f0598f1)(db, (0, $167eb860ccdaab7d$export$a17a6870a08b950e).Page);
183
+ const $d7a7877f07ff6c69$export$3bd13330ac8e761e = async (db)=>{
184
+ const rows = await (0, $26460f21c4456828$export$3274d151f0598f1)(db, (0, $e5a23c058b2763fa$export$a17a6870a08b950e).Page);
167
185
  const pages = rows.map((row)=>{
168
186
  const { content: content, id: id, number: number, page: page, part: part } = row;
169
187
  return {
@@ -182,8 +200,8 @@ const $2a3b237385dd2cff$export$3bd13330ac8e761e = async (db)=>{
182
200
  });
183
201
  return pages;
184
202
  };
185
- const $2a3b237385dd2cff$export$8987cf231214301f = async (db)=>{
186
- const rows = await (0, $b142353d92e15b6f$export$3274d151f0598f1)(db, (0, $167eb860ccdaab7d$export$a17a6870a08b950e).Title);
203
+ const $d7a7877f07ff6c69$export$8987cf231214301f = async (db)=>{
204
+ const rows = await (0, $26460f21c4456828$export$3274d151f0598f1)(db, (0, $e5a23c058b2763fa$export$a17a6870a08b950e).Title);
187
205
  const titles = rows.map((row)=>{
188
206
  const r = row;
189
207
  return {
@@ -197,10 +215,10 @@ const $2a3b237385dd2cff$export$8987cf231214301f = async (db)=>{
197
215
  });
198
216
  return titles;
199
217
  };
200
- const $2a3b237385dd2cff$export$7a171f172be0782e = async (db)=>{
218
+ const $d7a7877f07ff6c69$export$7a171f172be0782e = async (db)=>{
201
219
  const [pages, titles] = await Promise.all([
202
- $2a3b237385dd2cff$export$3bd13330ac8e761e(db),
203
- $2a3b237385dd2cff$export$8987cf231214301f(db)
220
+ $d7a7877f07ff6c69$export$3bd13330ac8e761e(db),
221
+ $d7a7877f07ff6c69$export$8987cf231214301f(db)
204
222
  ]);
205
223
  return {
206
224
  pages: pages,
@@ -210,41 +228,41 @@ const $2a3b237385dd2cff$export$7a171f172be0782e = async (db)=>{
210
228
 
211
229
 
212
230
 
213
- const $14c03a3c41757845$export$5bc725975f47e62c = 0;
214
- const $14c03a3c41757845$export$3deaf0b0365f781e = "99999";
231
+ const $1857efaf39b32304$export$5bc725975f47e62c = 0;
232
+ const $1857efaf39b32304$export$3deaf0b0365f781e = '99999';
215
233
 
216
234
 
217
235
 
218
236
 
219
237
 
220
- const $e19722dabbedc0a6$export$b3179f41dfd6e35b = async (db, sourceTables)=>{
238
+ const $09a9521c7a529893$export$b3179f41dfd6e35b = async (db, sourceTables)=>{
221
239
  const aliasToPath = sourceTables.reduce((acc, tablePath)=>{
222
- const { name: name } = (0, $5oumB$path).parse(tablePath);
240
+ const { name: name } = (0, $SK0tW$path).parse(tablePath);
223
241
  return {
224
242
  ...acc,
225
243
  [name]: tablePath
226
244
  };
227
245
  }, {});
228
- const attachStatements = Object.entries(aliasToPath).map(([alias, dbPath])=>(0, $e6f751831b705ed8$export$ee56083bb7df7ecc)(dbPath, alias));
246
+ const attachStatements = Object.entries(aliasToPath).map(([alias, dbPath])=>(0, $746504ca27eabe49$export$ee56083bb7df7ecc)(dbPath, alias));
229
247
  await db.batch(attachStatements);
230
248
  const insertStatements = [
231
- `INSERT INTO ${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Authors} SELECT id,name,biography,(CASE WHEN death_number = ${(0, $14c03a3c41757845$export$3deaf0b0365f781e)} THEN NULL ELSE death_number END) AS death_number FROM author WHERE is_deleted='0'`,
232
- `INSERT INTO ${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Books} SELECT id,name,category,type,(CASE WHEN date = ${(0, $14c03a3c41757845$export$3deaf0b0365f781e)} THEN NULL ELSE date END) AS date,author,printed,major_release,minor_release,bibliography,hint,pdf_links,metadata FROM book WHERE is_deleted='0'`,
233
- `INSERT INTO ${(0, $167eb860ccdaab7d$export$a17a6870a08b950e).Categories} SELECT id,name FROM category WHERE is_deleted='0'`
249
+ `INSERT INTO ${(0, $e5a23c058b2763fa$export$a17a6870a08b950e).Authors} SELECT id,name,biography,(CASE WHEN death_number = ${(0, $1857efaf39b32304$export$3deaf0b0365f781e)} THEN NULL ELSE death_number END) AS death_number FROM author WHERE is_deleted='0'`,
250
+ `INSERT INTO ${(0, $e5a23c058b2763fa$export$a17a6870a08b950e).Books} SELECT id,name,category,type,(CASE WHEN date = ${(0, $1857efaf39b32304$export$3deaf0b0365f781e)} THEN NULL ELSE date END) AS date,author,printed,major_release,minor_release,bibliography,hint,pdf_links,metadata FROM book WHERE is_deleted='0'`,
251
+ `INSERT INTO ${(0, $e5a23c058b2763fa$export$a17a6870a08b950e).Categories} SELECT id,name FROM category WHERE is_deleted='0'`
234
252
  ];
235
253
  await db.batch(insertStatements);
236
- const detachStatements = Object.keys(aliasToPath).map((0, $e6f751831b705ed8$export$7fec5208c714b262));
254
+ const detachStatements = Object.keys(aliasToPath).map((0, $746504ca27eabe49$export$7fec5208c714b262));
237
255
  await db.batch(detachStatements);
238
256
  };
239
- const $e19722dabbedc0a6$export$5d28a6b0dd65e4c4 = async (db)=>{
257
+ const $09a9521c7a529893$export$5d28a6b0dd65e4c4 = async (db)=>{
240
258
  return db.batch([
241
259
  `CREATE TABLE authors (id INTEGER PRIMARY KEY, name TEXT, biography TEXT, death INTEGER)`,
242
260
  `CREATE TABLE books (id INTEGER PRIMARY KEY, name TEXT, category INTEGER, type INTEGER, date INTEGER, author TEXT, printed INTEGER, major INTEGER, minor INTEGER, bibliography TEXT, hint TEXT, pdf_links TEXT, metadata TEXT)`,
243
261
  `CREATE TABLE categories (id INTEGER PRIMARY KEY, name TEXT)`
244
262
  ]);
245
263
  };
246
- const $e19722dabbedc0a6$export$b3b931905baa18df = async (db)=>{
247
- const rows = await (0, $b142353d92e15b6f$export$3274d151f0598f1)(db, (0, $167eb860ccdaab7d$export$a17a6870a08b950e).Authors);
264
+ const $09a9521c7a529893$export$b3b931905baa18df = async (db)=>{
265
+ const rows = await (0, $26460f21c4456828$export$3274d151f0598f1)(db, (0, $e5a23c058b2763fa$export$a17a6870a08b950e).Authors);
248
266
  const authors = rows.map((r)=>({
249
267
  ...r.biography && {
250
268
  biography: r.biography
@@ -257,12 +275,12 @@ const $e19722dabbedc0a6$export$b3b931905baa18df = async (db)=>{
257
275
  }));
258
276
  return authors;
259
277
  };
260
- const $e19722dabbedc0a6$export$7111c27bf38a004f = async (db)=>{
261
- const rows = await (0, $b142353d92e15b6f$export$3274d151f0598f1)(db, (0, $167eb860ccdaab7d$export$a17a6870a08b950e).Books);
278
+ const $09a9521c7a529893$export$7111c27bf38a004f = async (db)=>{
279
+ const rows = await (0, $26460f21c4456828$export$3274d151f0598f1)(db, (0, $e5a23c058b2763fa$export$a17a6870a08b950e).Books);
262
280
  const books = rows.map((row)=>{
263
281
  const r = row;
264
282
  return {
265
- author: $e19722dabbedc0a6$var$parseAuthor(r.author),
283
+ author: $09a9521c7a529893$var$parseAuthor(r.author),
266
284
  bibliography: r.bibliography,
267
285
  category: r.category,
268
286
  id: r.id,
@@ -271,14 +289,14 @@ const $e19722dabbedc0a6$export$7111c27bf38a004f = async (db)=>{
271
289
  name: r.name,
272
290
  printed: r.printed,
273
291
  type: r.type,
274
- ...r.date && r.date.toString() !== (0, $14c03a3c41757845$export$3deaf0b0365f781e) && {
292
+ ...r.date && r.date.toString() !== (0, $1857efaf39b32304$export$3deaf0b0365f781e) && {
275
293
  date: r.date
276
294
  },
277
295
  ...r.hint && {
278
296
  hint: r.hint
279
297
  },
280
298
  ...r.pdf_links && {
281
- pdfLinks: $e19722dabbedc0a6$var$parsePdfLinks(r.pdf_links)
299
+ pdfLinks: $09a9521c7a529893$var$parsePdfLinks(r.pdf_links)
282
300
  },
283
301
  ...r.minor && {
284
302
  minorRelease: r.minor
@@ -287,22 +305,22 @@ const $e19722dabbedc0a6$export$7111c27bf38a004f = async (db)=>{
287
305
  });
288
306
  return books;
289
307
  };
290
- const $e19722dabbedc0a6$export$36bfd9279b3a24b7 = async (db)=>{
291
- const rows = await (0, $b142353d92e15b6f$export$3274d151f0598f1)(db, (0, $167eb860ccdaab7d$export$a17a6870a08b950e).Categories);
308
+ const $09a9521c7a529893$export$36bfd9279b3a24b7 = async (db)=>{
309
+ const rows = await (0, $26460f21c4456828$export$3274d151f0598f1)(db, (0, $e5a23c058b2763fa$export$a17a6870a08b950e).Categories);
292
310
  const categories = rows.map((r)=>({
293
311
  id: r.id,
294
312
  name: r.name
295
313
  }));
296
314
  return categories;
297
315
  };
298
- const $e19722dabbedc0a6$var$parseAuthor = (value)=>{
299
- const result = value.split(",\\s+").map((id)=>parseInt(id.trim()));
316
+ const $09a9521c7a529893$var$parseAuthor = (value)=>{
317
+ const result = value.split(',\\s+').map((id)=>parseInt(id.trim()));
300
318
  return result.length > 1 ? result : result[0];
301
319
  };
302
- const $e19722dabbedc0a6$var$parsePdfLinks = (value)=>{
320
+ const $09a9521c7a529893$var$parsePdfLinks = (value)=>{
303
321
  const result = JSON.parse(value);
304
322
  if (result.files) result.files = result.files.map((f)=>{
305
- const [file, id] = f.split("|");
323
+ const [file, id] = f.split('|');
306
324
  return {
307
325
  ...id && {
308
326
  id: id
@@ -312,11 +330,11 @@ const $e19722dabbedc0a6$var$parsePdfLinks = (value)=>{
312
330
  });
313
331
  return result;
314
332
  };
315
- const $e19722dabbedc0a6$export$7a171f172be0782e = async (db)=>{
333
+ const $09a9521c7a529893$export$7a171f172be0782e = async (db)=>{
316
334
  const [authors, books, categories] = await Promise.all([
317
- $e19722dabbedc0a6$export$b3b931905baa18df(db),
318
- $e19722dabbedc0a6$export$7111c27bf38a004f(db),
319
- $e19722dabbedc0a6$export$36bfd9279b3a24b7(db)
335
+ $09a9521c7a529893$export$b3b931905baa18df(db),
336
+ $09a9521c7a529893$export$7111c27bf38a004f(db),
337
+ $09a9521c7a529893$export$36bfd9279b3a24b7(db)
320
338
  ]);
321
339
  return {
322
340
  authors: authors,
@@ -333,59 +351,59 @@ const $e19722dabbedc0a6$export$7a171f172be0782e = async (db)=>{
333
351
 
334
352
 
335
353
 
336
- const $e8ee15c0ce3f020d$export$1c500f521ad591da = async (prefix = "shamela")=>{
337
- const tempDirBase = (0, $5oumB$path).join((0, $5oumB$os).tmpdir(), prefix);
338
- return (0, $5oumB$promises).mkdtemp(tempDirBase);
354
+ const $fd2c9bc034ddc705$export$1c500f521ad591da = async (prefix = 'shamela')=>{
355
+ const tempDirBase = (0, $SK0tW$path).join((0, $SK0tW$os).tmpdir(), prefix);
356
+ return (0, $SK0tW$promises).mkdtemp(tempDirBase);
339
357
  };
340
- const $e8ee15c0ce3f020d$export$ffc21166d570a16 = async (path)=>!!await (0, $5oumB$promises).stat(path).catch(()=>false);
341
- async function $e8ee15c0ce3f020d$export$fb61e277af91ac0(url, outputDir) {
358
+ const $fd2c9bc034ddc705$export$ffc21166d570a16 = async (path)=>!!await (0, $SK0tW$promises).stat(path).catch(()=>false);
359
+ async function $fd2c9bc034ddc705$export$fb61e277af91ac0(url, outputDir) {
342
360
  const extractedFiles = [];
343
361
  const entryPromises = [];
344
362
  try {
345
363
  // Make HTTPS request and get the response stream
346
364
  const response = await new Promise((resolve, reject)=>{
347
- (0, $5oumB$https).get(url, (res)=>{
365
+ (0, $SK0tW$https).get(url, (res)=>{
348
366
  if (res.statusCode !== 200) reject(new Error(`Failed to download ZIP file: ${res.statusCode} ${res.statusMessage}`));
349
367
  else resolve(res);
350
- }).on("error", (err)=>{
368
+ }).on('error', (err)=>{
351
369
  reject(new Error(`HTTPS request failed: ${err.message}`));
352
370
  });
353
371
  });
354
372
  // Create unzip stream
355
- const unzipStream = (0, $5oumB$unzipper).Parse();
373
+ const unzipStream = (0, $SK0tW$unzipper).Parse();
356
374
  // Handle entries in the ZIP file
357
- unzipStream.on("entry", (entry)=>{
375
+ unzipStream.on('entry', (entry)=>{
358
376
  const entryPromise = (async ()=>{
359
- const filePath = (0, $5oumB$path).join(outputDir, entry.path);
360
- if (entry.type === "Directory") {
377
+ const filePath = (0, $SK0tW$path).join(outputDir, entry.path);
378
+ if (entry.type === 'Directory') {
361
379
  // Ensure the directory exists
362
- await (0, $5oumB$promises).mkdir(filePath, {
380
+ await (0, $SK0tW$promises).mkdir(filePath, {
363
381
  recursive: true
364
382
  });
365
383
  entry.autodrain();
366
384
  } else {
367
385
  // Ensure the parent directory exists
368
- const dir = (0, $5oumB$path).dirname(filePath);
369
- await (0, $5oumB$promises).mkdir(dir, {
386
+ const dir = (0, $SK0tW$path).dirname(filePath);
387
+ await (0, $SK0tW$promises).mkdir(dir, {
370
388
  recursive: true
371
389
  });
372
390
  // Pipe the entry to a file
373
- await (0, $5oumB$pipeline)(entry, (0, $5oumB$createWriteStream)(filePath));
391
+ await (0, $SK0tW$pipeline)(entry, (0, $SK0tW$createWriteStream)(filePath));
374
392
  extractedFiles.push(filePath);
375
393
  }
376
394
  })().catch((err)=>{
377
395
  // Emit errors to be handled by the unzipStream error handler
378
- unzipStream.emit("error", err);
396
+ unzipStream.emit('error', err);
379
397
  });
380
398
  // Collect the promises
381
399
  entryPromises.push(entryPromise);
382
400
  });
383
401
  // Handle errors in the unzip stream
384
- unzipStream.on("error", (err)=>{
402
+ unzipStream.on('error', (err)=>{
385
403
  throw new Error(`Error during extraction: ${err.message}`);
386
404
  });
387
405
  // Pipe the response into the unzip stream
388
- await (0, $5oumB$pipeline)(response, unzipStream);
406
+ await (0, $SK0tW$pipeline)(response, unzipStream);
389
407
  // Wait for all entry promises to complete
390
408
  await Promise.all(entryPromises);
391
409
  return extractedFiles;
@@ -400,37 +418,37 @@ async function $e8ee15c0ce3f020d$export$fb61e277af91ac0(url, outputDir) {
400
418
 
401
419
 
402
420
 
403
- const $932b4b3755196b46$export$b5cd97dee32de81d = (endpoint, params, useAuth = true)=>{
404
- const url = new (0, $5oumB$URL)(endpoint);
421
+ const $59b98b7fd5edf160$export$b5cd97dee32de81d = (endpoint, params, useAuth = true)=>{
422
+ const url = new (0, $SK0tW$URL)(endpoint);
405
423
  {
406
- const params = new (0, $5oumB$URLSearchParams)();
424
+ const params = new (0, $SK0tW$URLSearchParams)();
407
425
  Object.entries(params).forEach(([key, value])=>{
408
426
  params.append(key, value.toString());
409
427
  });
410
- if (useAuth) params.append("api_key", (0, $5oumB$process).env.SHAMELA_API_KEY);
428
+ if (useAuth) params.append('api_key', (0, $SK0tW$process).env.SHAMELA_API_KEY);
411
429
  url.search = params.toString();
412
430
  }
413
431
  return url;
414
432
  };
415
- const $932b4b3755196b46$export$c9e6217566c54f42 = (url)=>{
433
+ const $59b98b7fd5edf160$export$c9e6217566c54f42 = (url)=>{
416
434
  return new Promise((resolve, reject)=>{
417
- (0, $5oumB$https).get(url, (res)=>{
418
- const contentType = res.headers["content-type"] || "";
435
+ (0, $SK0tW$https).get(url, (res)=>{
436
+ const contentType = res.headers['content-type'] || '';
419
437
  const dataChunks = [];
420
- res.on("data", (chunk)=>{
438
+ res.on('data', (chunk)=>{
421
439
  dataChunks.push(chunk);
422
440
  });
423
- res.on("end", ()=>{
424
- const fullData = (0, $5oumB$Buffer).concat(dataChunks);
425
- if (contentType.includes("application/json")) try {
426
- const json = JSON.parse(fullData.toString("utf-8"));
441
+ res.on('end', ()=>{
442
+ const fullData = (0, $SK0tW$Buffer).concat(dataChunks);
443
+ if (contentType.includes('application/json')) try {
444
+ const json = JSON.parse(fullData.toString('utf-8'));
427
445
  resolve(json);
428
446
  } catch (error) {
429
447
  reject(new Error(`Failed to parse JSON: ${error.message}`));
430
448
  }
431
449
  else resolve(fullData);
432
450
  });
433
- }).on("error", (error)=>{
451
+ }).on('error', (error)=>{
434
452
  reject(new Error(`Error making request: ${error.message}`));
435
453
  });
436
454
  });
@@ -439,34 +457,34 @@ const $932b4b3755196b46$export$c9e6217566c54f42 = (url)=>{
439
457
 
440
458
 
441
459
 
442
- const $da18f5255cf003e1$var$SOURCE_TABLES = [
443
- "author.sqlite",
444
- "book.sqlite",
445
- "category.sqlite"
460
+ const $6605706916cc9c29$var$SOURCE_TABLES = [
461
+ 'author.sqlite',
462
+ 'book.sqlite',
463
+ 'category.sqlite'
446
464
  ];
447
- const $da18f5255cf003e1$export$37467b7f8cfc50b0 = ()=>{
448
- if (!(0, $5oumB$process).env.SHAMELA_API_MASTER_PATCH_ENDPOINT) throw new Error("SHAMELA_API_MASTER_PATCH_ENDPOINT environment variable not set");
449
- if (!(0, $5oumB$process).env.SHAMELA_API_KEY) throw new Error("SHAMELA_API_KEY environment variable not set");
465
+ const $6605706916cc9c29$export$37467b7f8cfc50b0 = ()=>{
466
+ if (!(0, $SK0tW$process).env.SHAMELA_API_MASTER_PATCH_ENDPOINT) throw new Error('SHAMELA_API_MASTER_PATCH_ENDPOINT environment variable not set');
467
+ if (!(0, $SK0tW$process).env.SHAMELA_API_KEY) throw new Error('SHAMELA_API_KEY environment variable not set');
450
468
  };
451
- const $da18f5255cf003e1$export$c7660b0cda39b7c3 = (sourceTablePaths)=>{
452
- const sourceTableNames = sourceTablePaths.map((tablePath)=>(0, $5oumB$path).parse(tablePath).base);
453
- return $da18f5255cf003e1$var$SOURCE_TABLES.every((table)=>sourceTableNames.includes(table));
469
+ const $6605706916cc9c29$export$c7660b0cda39b7c3 = (sourceTablePaths)=>{
470
+ const sourceTableNames = sourceTablePaths.map((tablePath)=>(0, $SK0tW$path).parse(tablePath).base);
471
+ return $6605706916cc9c29$var$SOURCE_TABLES.every((table)=>sourceTableNames.includes(table));
454
472
  };
455
473
 
456
474
 
457
- const $96cb7a03b537cb37$export$4c209aa17b4b3e57 = async (id, options)=>{
458
- (0, $da18f5255cf003e1$export$37467b7f8cfc50b0)();
459
- const url = new (0, $5oumB$URL)(`${(0, $5oumB$process).env.SHAMELA_API_BOOKS_ENDPOINT}/${id}`);
475
+ const $e6ba238abdbefe7a$export$4c209aa17b4b3e57 = async (id, options)=>{
476
+ (0, $6605706916cc9c29$export$37467b7f8cfc50b0)();
477
+ const url = new (0, $SK0tW$URL)(`${(0, $SK0tW$process).env.SHAMELA_API_BOOKS_ENDPOINT}/${id}`);
460
478
  {
461
- const params = new (0, $5oumB$URLSearchParams)();
462
- params.append("api_key", (0, $5oumB$process).env.SHAMELA_API_KEY);
463
- params.append("major_release", (options?.majorVersion || 0).toString());
464
- params.append("minor_release", (options?.minorVersion || 0).toString());
479
+ const params = new (0, $SK0tW$URLSearchParams)();
480
+ params.append('api_key', (0, $SK0tW$process).env.SHAMELA_API_KEY);
481
+ params.append('major_release', (options?.majorVersion || 0).toString());
482
+ params.append('minor_release', (options?.minorVersion || 0).toString());
465
483
  url.search = params.toString();
466
484
  }
467
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).info(`Fetching shamela.ws book link: ${url.toString()}`);
485
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).info(`Fetching shamela.ws book link: ${url.toString()}`);
468
486
  try {
469
- const response = await (0, $932b4b3755196b46$export$c9e6217566c54f42)(url);
487
+ const response = await (0, $59b98b7fd5edf160$export$c9e6217566c54f42)(url);
470
488
  return {
471
489
  majorRelease: response.major_release,
472
490
  majorReleaseUrl: response.major_release_url,
@@ -481,38 +499,38 @@ const $96cb7a03b537cb37$export$4c209aa17b4b3e57 = async (id, options)=>{
481
499
  throw new Error(`Error fetching master patch: ${error.message}`);
482
500
  }
483
501
  };
484
- const $96cb7a03b537cb37$export$3560c45fd9de930d = async (id, options)=>{
485
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).info(`downloadBook ${id} ${JSON.stringify(options)}`);
486
- const outputDir = await (0, $e8ee15c0ce3f020d$export$1c500f521ad591da)("shamela_downloadBook");
487
- const bookResponse = options?.bookMetadata || await $96cb7a03b537cb37$export$4c209aa17b4b3e57(id);
502
+ const $e6ba238abdbefe7a$export$3560c45fd9de930d = async (id, options)=>{
503
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).info(`downloadBook ${id} ${JSON.stringify(options)}`);
504
+ const outputDir = await (0, $fd2c9bc034ddc705$export$1c500f521ad591da)('shamela_downloadBook');
505
+ const bookResponse = options?.bookMetadata || await $e6ba238abdbefe7a$export$4c209aa17b4b3e57(id);
488
506
  const [[bookDatabase], [patchDatabase] = []] = await Promise.all([
489
- (0, $e8ee15c0ce3f020d$export$fb61e277af91ac0)(bookResponse.majorReleaseUrl, outputDir),
507
+ (0, $fd2c9bc034ddc705$export$fb61e277af91ac0)(bookResponse.majorReleaseUrl, outputDir),
490
508
  ...bookResponse.minorReleaseUrl ? [
491
- (0, $e8ee15c0ce3f020d$export$fb61e277af91ac0)(bookResponse.minorReleaseUrl, outputDir)
509
+ (0, $fd2c9bc034ddc705$export$fb61e277af91ac0)(bookResponse.minorReleaseUrl, outputDir)
492
510
  ] : []
493
511
  ]);
494
- const dbPath = (0, $5oumB$path).join(outputDir, "book.db");
495
- const client = (0, $5oumB$createClient)({
512
+ const dbPath = (0, $SK0tW$path).join(outputDir, 'book.db');
513
+ const client = (0, $SK0tW$createClient)({
496
514
  url: `file:${dbPath}`
497
515
  });
498
516
  try {
499
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).info(`Creating tables`);
500
- await (0, $2a3b237385dd2cff$export$5d28a6b0dd65e4c4)(client);
517
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).info(`Creating tables`);
518
+ await (0, $d7a7877f07ff6c69$export$5d28a6b0dd65e4c4)(client);
501
519
  if (patchDatabase) {
502
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).info(`Applying patches from ${patchDatabase} to ${bookDatabase}`);
503
- await (0, $2a3b237385dd2cff$export$a8b8e03e6bbe5473)(client, bookDatabase, patchDatabase);
520
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).info(`Applying patches from ${patchDatabase} to ${bookDatabase}`);
521
+ await (0, $d7a7877f07ff6c69$export$a8b8e03e6bbe5473)(client, bookDatabase, patchDatabase);
504
522
  } else {
505
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).info(`Copying table data from ${bookDatabase}`);
506
- await (0, $2a3b237385dd2cff$export$61101aa23c771e7c)(client, bookDatabase);
523
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).info(`Copying table data from ${bookDatabase}`);
524
+ await (0, $d7a7877f07ff6c69$export$61101aa23c771e7c)(client, bookDatabase);
507
525
  }
508
- const { ext: extension } = (0, $5oumB$path).parse(options.outputFile.path);
509
- if (extension === ".json") {
510
- const result = await (0, $2a3b237385dd2cff$export$7a171f172be0782e)(client);
511
- await (0, $5oumB$promises).writeFile(options.outputFile.path, JSON.stringify(result, undefined, 2), "utf8");
526
+ const { ext: extension } = (0, $SK0tW$path).parse(options.outputFile.path);
527
+ if (extension === '.json') {
528
+ const result = await (0, $d7a7877f07ff6c69$export$7a171f172be0782e)(client);
529
+ await (0, $SK0tW$promises).writeFile(options.outputFile.path, JSON.stringify(result, undefined, 2), 'utf8');
512
530
  }
513
531
  client.close();
514
- if (extension === ".db" || extension === ".sqlite") await (0, $5oumB$promises).rename(dbPath, options.outputFile.path);
515
- await (0, $5oumB$promises).rm(outputDir, {
532
+ if (extension === '.db' || extension === '.sqlite') await (0, $SK0tW$promises).rename(dbPath, options.outputFile.path);
533
+ await (0, $SK0tW$promises).rm(outputDir, {
516
534
  recursive: true
517
535
  });
518
536
  } finally{
@@ -520,18 +538,18 @@ const $96cb7a03b537cb37$export$3560c45fd9de930d = async (id, options)=>{
520
538
  }
521
539
  return options.outputFile.path;
522
540
  };
523
- const $96cb7a03b537cb37$export$b96de494209cdc35 = async (version = 0)=>{
524
- (0, $da18f5255cf003e1$export$37467b7f8cfc50b0)();
525
- const url = new (0, $5oumB$URL)((0, $5oumB$process).env.SHAMELA_API_MASTER_PATCH_ENDPOINT);
541
+ const $e6ba238abdbefe7a$export$b96de494209cdc35 = async (version = 0)=>{
542
+ (0, $6605706916cc9c29$export$37467b7f8cfc50b0)();
543
+ const url = new (0, $SK0tW$URL)((0, $SK0tW$process).env.SHAMELA_API_MASTER_PATCH_ENDPOINT);
526
544
  {
527
- const params = new (0, $5oumB$URLSearchParams)();
528
- params.append("api_key", (0, $5oumB$process).env.SHAMELA_API_KEY);
529
- params.append("version", version.toString());
545
+ const params = new (0, $SK0tW$URLSearchParams)();
546
+ params.append('api_key', (0, $SK0tW$process).env.SHAMELA_API_KEY);
547
+ params.append('version', version.toString());
530
548
  url.search = params.toString();
531
549
  }
532
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).info(`Fetching shamela.ws master database patch link: ${url.toString()}`);
550
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).info(`Fetching shamela.ws master database patch link: ${url.toString()}`);
533
551
  try {
534
- const response = await (0, $932b4b3755196b46$export$c9e6217566c54f42)(url);
552
+ const response = await (0, $59b98b7fd5edf160$export$c9e6217566c54f42)(url);
535
553
  return {
536
554
  url: response.patch_url,
537
555
  version: response.version
@@ -540,34 +558,34 @@ const $96cb7a03b537cb37$export$b96de494209cdc35 = async (version = 0)=>{
540
558
  throw new Error(`Error fetching master patch: ${error.message}`);
541
559
  }
542
560
  };
543
- const $96cb7a03b537cb37$export$fd8b6353fde3f1de = async (options)=>{
544
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).info(`downloadMasterDatabase ${JSON.stringify(options)}`);
545
- const outputDir = await (0, $e8ee15c0ce3f020d$export$1c500f521ad591da)("shamela_downloadMaster");
546
- const masterResponse = options.masterMetadata || await $96cb7a03b537cb37$export$b96de494209cdc35((0, $14c03a3c41757845$export$5bc725975f47e62c));
547
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).info(`Downloading master database from: ${JSON.stringify(masterResponse)}`);
548
- const sourceTables = await (0, $e8ee15c0ce3f020d$export$fb61e277af91ac0)(masterResponse.url, outputDir);
549
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).info(`sourceTables downloaded: ${sourceTables.toString()}`);
550
- if (!(0, $da18f5255cf003e1$export$c7660b0cda39b7c3)(sourceTables)) {
551
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).error(`Some source tables were not found: ${sourceTables.toString()}`);
552
- throw new Error("Expected tables not found!");
561
+ const $e6ba238abdbefe7a$export$fd8b6353fde3f1de = async (options)=>{
562
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).info(`downloadMasterDatabase ${JSON.stringify(options)}`);
563
+ const outputDir = await (0, $fd2c9bc034ddc705$export$1c500f521ad591da)('shamela_downloadMaster');
564
+ const masterResponse = options.masterMetadata || await $e6ba238abdbefe7a$export$b96de494209cdc35((0, $1857efaf39b32304$export$5bc725975f47e62c));
565
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).info(`Downloading master database from: ${JSON.stringify(masterResponse)}`);
566
+ const sourceTables = await (0, $fd2c9bc034ddc705$export$fb61e277af91ac0)(masterResponse.url, outputDir);
567
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).info(`sourceTables downloaded: ${sourceTables.toString()}`);
568
+ if (!(0, $6605706916cc9c29$export$c7660b0cda39b7c3)(sourceTables)) {
569
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).error(`Some source tables were not found: ${sourceTables.toString()}`);
570
+ throw new Error('Expected tables not found!');
553
571
  }
554
- const dbPath = (0, $5oumB$path).join(outputDir, "master.db");
555
- const client = (0, $5oumB$createClient)({
572
+ const dbPath = (0, $SK0tW$path).join(outputDir, 'master.db');
573
+ const client = (0, $SK0tW$createClient)({
556
574
  url: `file:${dbPath}`
557
575
  });
558
576
  try {
559
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).info(`Creating tables`);
560
- await (0, $e19722dabbedc0a6$export$5d28a6b0dd65e4c4)(client);
561
- (0, $2d2b29d79cbbfeda$export$2e2bcd8739ae039).info(`Copying data to master table`);
562
- await (0, $e19722dabbedc0a6$export$b3179f41dfd6e35b)(client, sourceTables);
563
- const { ext: extension } = (0, $5oumB$path).parse(options.outputFile.path);
564
- if (extension === ".json") {
565
- const result = await (0, $e19722dabbedc0a6$export$7a171f172be0782e)(client);
566
- await (0, $5oumB$promises).writeFile(options.outputFile.path, JSON.stringify(result, undefined, 2), "utf8");
577
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).info(`Creating tables`);
578
+ await (0, $09a9521c7a529893$export$5d28a6b0dd65e4c4)(client);
579
+ (0, $526b48a37e8a8ec6$export$2e2bcd8739ae039).info(`Copying data to master table`);
580
+ await (0, $09a9521c7a529893$export$b3179f41dfd6e35b)(client, sourceTables);
581
+ const { ext: extension } = (0, $SK0tW$path).parse(options.outputFile.path);
582
+ if (extension === '.json') {
583
+ const result = await (0, $09a9521c7a529893$export$7a171f172be0782e)(client);
584
+ await (0, $SK0tW$promises).writeFile(options.outputFile.path, JSON.stringify(result, undefined, 2), 'utf8');
567
585
  }
568
586
  client.close();
569
- if (extension === ".db" || extension === ".sqlite") await (0, $5oumB$promises).rename(dbPath, options.outputFile.path);
570
- await (0, $5oumB$promises).rm(outputDir, {
587
+ if (extension === '.db' || extension === '.sqlite') await (0, $SK0tW$promises).rename(dbPath, options.outputFile.path);
588
+ await (0, $SK0tW$promises).rm(outputDir, {
571
589
  recursive: true
572
590
  });
573
591
  } finally{
@@ -575,25 +593,25 @@ const $96cb7a03b537cb37$export$fd8b6353fde3f1de = async (options)=>{
575
593
  }
576
594
  return options.outputFile.path;
577
595
  };
578
- const $96cb7a03b537cb37$export$be7c2acc48adceee = async (id)=>{
579
- const outputDir = await (0, $e8ee15c0ce3f020d$export$1c500f521ad591da)("shamela_getBookData");
580
- const outputPath = await $96cb7a03b537cb37$export$3560c45fd9de930d(id, {
596
+ const $e6ba238abdbefe7a$export$be7c2acc48adceee = async (id)=>{
597
+ const outputDir = await (0, $fd2c9bc034ddc705$export$1c500f521ad591da)('shamela_getBookData');
598
+ const outputPath = await $e6ba238abdbefe7a$export$3560c45fd9de930d(id, {
581
599
  outputFile: {
582
- path: (0, $5oumB$path).join(outputDir, `${id}.json`)
600
+ path: (0, $SK0tW$path).join(outputDir, `${id}.json`)
583
601
  }
584
602
  });
585
- const data = JSON.parse(await (0, $5oumB$promises).readFile(outputPath, "utf8"));
586
- await (0, $5oumB$promises).rm(outputDir, {
603
+ const data = JSON.parse(await (0, $SK0tW$promises).readFile(outputPath, 'utf8'));
604
+ await (0, $SK0tW$promises).rm(outputDir, {
587
605
  recursive: true
588
606
  });
589
607
  return data;
590
608
  };
591
609
 
592
610
 
593
- var $b369a26e4279c768$exports = {};
611
+ var $e9528ebec83086b6$exports = {};
594
612
 
595
613
 
596
614
 
597
615
 
598
- export {$96cb7a03b537cb37$export$3560c45fd9de930d as downloadBook, $96cb7a03b537cb37$export$fd8b6353fde3f1de as downloadMasterDatabase, $96cb7a03b537cb37$export$be7c2acc48adceee as getBook, $96cb7a03b537cb37$export$4c209aa17b4b3e57 as getBookMetadata, $96cb7a03b537cb37$export$b96de494209cdc35 as getMasterMetadata};
616
+ export {$e6ba238abdbefe7a$export$3560c45fd9de930d as downloadBook, $e6ba238abdbefe7a$export$fd8b6353fde3f1de as downloadMasterDatabase, $e6ba238abdbefe7a$export$be7c2acc48adceee as getBook, $e6ba238abdbefe7a$export$4c209aa17b4b3e57 as getBookMetadata, $e6ba238abdbefe7a$export$b96de494209cdc35 as getMasterMetadata};
599
617
  //# sourceMappingURL=main.js.map
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"mappings":"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","sources":["src/index.ts","src/api.ts","src/db/book.ts","src/utils/logger.ts","src/db/common.ts","src/db/queryBuilder.ts","src/db/types.ts","src/db/master.ts","src/utils/constants.ts","src/utils/io.ts","src/utils/network.ts","src/utils/validation.ts","src/types.ts"],"sourcesContent":["import { downloadBook, downloadMasterDatabase, getBook, getBookMetadata, getMasterMetadata } from './api';\n\nexport { downloadBook, downloadMasterDatabase, getBook, getBookMetadata, getMasterMetadata };\n\nexport * from './types';\n","import { Client, createClient } from '@libsql/client';\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport process from 'process';\nimport { URL, URLSearchParams } from 'url';\n\nimport { applyPatches, copyTableData, createTables as createBookTables, getData as getBookData } from './db/book.js';\nimport {\n copyForeignMasterTableData,\n createTables as createMasterTables,\n getData as getMasterData,\n} from './db/master.js';\nimport {\n BookData,\n DownloadBookOptions,\n DownloadMasterOptions,\n GetBookMetadataOptions,\n GetBookMetadataResponsePayload,\n GetMasterMetadataResponsePayload,\n} from './types.js';\nimport { DEFAULT_MASTER_METADATA_VERSION } from './utils/constants.js';\nimport { createTempDir, unzipFromUrl } from './utils/io.js';\nimport logger from './utils/logger.js';\nimport { httpsGet } from './utils/network.js';\nimport { validateEnvVariables, validateMasterSourceTables } from './utils/validation.js';\n\nexport const getBookMetadata = async (\n id: number,\n options?: GetBookMetadataOptions,\n): Promise<GetBookMetadataResponsePayload> => {\n validateEnvVariables();\n\n const url = new URL(`${process.env.SHAMELA_API_BOOKS_ENDPOINT}/${id}`);\n {\n const params = new URLSearchParams();\n params.append('api_key', process.env.SHAMELA_API_KEY as string);\n params.append('major_release', (options?.majorVersion || 0).toString());\n params.append('minor_release', (options?.minorVersion || 0).toString());\n url.search = params.toString();\n }\n\n logger.info(`Fetching shamela.ws book link: ${url.toString()}`);\n\n try {\n const response: Record<string, any> = await httpsGet(url);\n return {\n majorRelease: response.major_release,\n majorReleaseUrl: response.major_release_url,\n ...(response.minor_release_url && { minorReleaseUrl: response.minor_release_url }),\n ...(response.minor_release_url && { minorRelease: response.minor_release }),\n };\n } catch (error: any) {\n throw new Error(`Error fetching master patch: ${error.message}`);\n }\n};\n\nexport const downloadBook = async (id: number, options: DownloadBookOptions): Promise<string> => {\n logger.info(`downloadBook ${id} ${JSON.stringify(options)}`);\n\n const outputDir = await createTempDir('shamela_downloadBook');\n\n const bookResponse: GetBookMetadataResponsePayload = options?.bookMetadata || (await getBookMetadata(id));\n const [[bookDatabase], [patchDatabase] = []]: string[][] = await Promise.all([\n unzipFromUrl(bookResponse.majorReleaseUrl, outputDir),\n ...(bookResponse.minorReleaseUrl ? [unzipFromUrl(bookResponse.minorReleaseUrl, outputDir)] : []),\n ]);\n const dbPath = path.join(outputDir, 'book.db');\n\n const client: Client = createClient({\n url: `file:${dbPath}`,\n });\n\n try {\n logger.info(`Creating tables`);\n await createBookTables(client);\n\n if (patchDatabase) {\n logger.info(`Applying patches from ${patchDatabase} to ${bookDatabase}`);\n await applyPatches(client, bookDatabase, patchDatabase);\n } else {\n logger.info(`Copying table data from ${bookDatabase}`);\n await copyTableData(client, bookDatabase);\n }\n\n const { ext: extension } = path.parse(options.outputFile.path);\n\n if (extension === '.json') {\n const result = await getBookData(client);\n await fs.writeFile(options.outputFile.path, JSON.stringify(result, undefined, 2), 'utf8');\n }\n\n client.close();\n\n if (extension === '.db' || extension === '.sqlite') {\n await fs.rename(dbPath, options.outputFile.path);\n }\n\n await fs.rm(outputDir, { recursive: true });\n } finally {\n client.close();\n }\n\n return options.outputFile.path;\n};\n\nexport const getMasterMetadata = async (version: number = 0): Promise<GetMasterMetadataResponsePayload> => {\n validateEnvVariables();\n\n const url = new URL(process.env.SHAMELA_API_MASTER_PATCH_ENDPOINT as string);\n {\n const params = new URLSearchParams();\n params.append('api_key', process.env.SHAMELA_API_KEY as string);\n params.append('version', version.toString());\n url.search = params.toString();\n }\n\n logger.info(`Fetching shamela.ws master database patch link: ${url.toString()}`);\n\n try {\n const response: Record<string, any> = await httpsGet(url);\n return { url: response.patch_url, version: response.version };\n } catch (error: any) {\n throw new Error(`Error fetching master patch: ${error.message}`);\n }\n};\n\nexport const downloadMasterDatabase = async (options: DownloadMasterOptions): Promise<string> => {\n logger.info(`downloadMasterDatabase ${JSON.stringify(options)}`);\n\n const outputDir = await createTempDir('shamela_downloadMaster');\n\n const masterResponse: GetMasterMetadataResponsePayload =\n options.masterMetadata || (await getMasterMetadata(DEFAULT_MASTER_METADATA_VERSION));\n\n logger.info(`Downloading master database from: ${JSON.stringify(masterResponse)}`);\n const sourceTables: string[] = await unzipFromUrl(masterResponse.url, outputDir);\n\n logger.info(`sourceTables downloaded: ${sourceTables.toString()}`);\n\n if (!validateMasterSourceTables(sourceTables)) {\n logger.error(`Some source tables were not found: ${sourceTables.toString()}`);\n throw new Error('Expected tables not found!');\n }\n\n const dbPath = path.join(outputDir, 'master.db');\n\n const client: Client = createClient({\n url: `file:${dbPath}`,\n });\n\n try {\n logger.info(`Creating tables`);\n await createMasterTables(client);\n\n logger.info(`Copying data to master table`);\n await copyForeignMasterTableData(client, sourceTables);\n\n const { ext: extension } = path.parse(options.outputFile.path);\n\n if (extension === '.json') {\n const result = await getMasterData(client);\n await fs.writeFile(options.outputFile.path, JSON.stringify(result, undefined, 2), 'utf8');\n }\n\n client.close();\n\n if (extension === '.db' || extension === '.sqlite') {\n await fs.rename(dbPath, options.outputFile.path);\n }\n\n await fs.rm(outputDir, { recursive: true });\n } finally {\n client.close();\n }\n\n return options.outputFile.path;\n};\n\nexport const getBook = async (id: number): Promise<BookData> => {\n const outputDir = await createTempDir('shamela_getBookData');\n const outputPath = await downloadBook(id, { outputFile: { path: path.join(outputDir, `${id}.json`) } });\n\n const data = JSON.parse(await fs.readFile(outputPath, 'utf8')) as BookData;\n await fs.rm(outputDir, { recursive: true });\n\n return data;\n};\n","import { Client } from '@libsql/client';\n\nimport { BookData, Page, Title } from '../types';\nimport logger from '../utils/logger';\nimport { getInternalTables, InternalTable, selectAllRows } from './common';\nimport { attachDB, buildPagePatchQuery, buildTitlePatchQuery, detachDB } from './queryBuilder';\nimport { PageRow, Tables, TitleRow } from './types';\n\nconst PATCH_DB_ALIAS = 'patch';\nconst ASL_DB_ALIAS = 'asl';\n\nconst getPagesToCopy = (tables: InternalTable[]): string[] => {\n const statements = [];\n\n if (tables.find((t) => t.name === Tables.Page)) {\n statements.push(\n `INSERT INTO main.${Tables.Page} SELECT id,content,part,page,number FROM ${ASL_DB_ALIAS}.${Tables.Page} WHERE id IN (SELECT id FROM ${PATCH_DB_ALIAS}.${Tables.Page} WHERE is_deleted='0')`,\n );\n statements.push(buildPagePatchQuery(PATCH_DB_ALIAS, Tables.Page));\n } else {\n statements.push(\n `INSERT INTO main.${Tables.Page} SELECT id,content,part,page,number FROM ${ASL_DB_ALIAS}.${Tables.Page} WHERE is_deleted='0'`,\n );\n }\n\n return statements;\n};\n\nconst getTitlesToCopy = (tables: InternalTable[]): string[] => {\n const statements = [];\n\n if (tables.find((t) => t.name === Tables.Title)) {\n statements.push(\n `INSERT INTO main.${Tables.Title} SELECT id,content,page,parent FROM ${ASL_DB_ALIAS}.${Tables.Title} WHERE id IN (SELECT id FROM ${PATCH_DB_ALIAS}.${Tables.Title} WHERE is_deleted='0')`,\n );\n statements.push(buildTitlePatchQuery(PATCH_DB_ALIAS, Tables.Title));\n } else {\n statements.push(\n `INSERT INTO main.${Tables.Title} SELECT id,content,page,parent FROM ${ASL_DB_ALIAS}.${Tables.Title} WHERE is_deleted='0'`,\n );\n }\n\n return statements;\n};\n\nexport const applyPatches = async (db: Client, aslDB: string, patchDB?: string) => {\n const statements: string[] = [attachDB(aslDB, ASL_DB_ALIAS)];\n\n if (patchDB) {\n await db.execute(attachDB(patchDB, PATCH_DB_ALIAS));\n }\n\n const tables = patchDB ? await getInternalTables(db, PATCH_DB_ALIAS) : [];\n\n logger.debug({ tables }, `Applying patches for...`);\n\n statements.push(...getPagesToCopy(tables));\n statements.push(...getTitlesToCopy(tables));\n\n await db.batch(statements);\n\n const detachStatements = [];\n detachStatements.push(detachDB(ASL_DB_ALIAS));\n\n if (patchDB) {\n detachStatements.push(detachDB(PATCH_DB_ALIAS));\n }\n\n return db.batch(detachStatements);\n};\n\nexport const copyTableData = async (db: Client, aslDB: string) => {\n await db.execute(attachDB(aslDB, ASL_DB_ALIAS));\n const tables = await getInternalTables(db, ASL_DB_ALIAS);\n\n logger.debug({ tables }, `Applying patches for...`);\n\n await db.batch([\n `INSERT INTO main.${Tables.Title} SELECT id,content,page,parent FROM ${ASL_DB_ALIAS}.${Tables.Title}`,\n `INSERT INTO main.${Tables.Page} SELECT id,content,part,page,number FROM ${ASL_DB_ALIAS}.${Tables.Page}`,\n ]);\n\n return db.execute(detachDB(ASL_DB_ALIAS));\n};\n\nexport const createTables = async (db: Client) => {\n return db.batch([\n `CREATE TABLE page (id INTEGER PRIMARY KEY, content TEXT, part INTEGER, page INTEGER, number INTEGER)`,\n `CREATE TABLE title (id INTEGER PRIMARY KEY, content TEXT, page INTEGER, parent INTEGER)`,\n ]);\n};\n\nexport const getAllPages = async (db: Client): Promise<Page[]> => {\n const rows = await selectAllRows(db, Tables.Page);\n\n const pages: Page[] = rows.map((row: any) => {\n const { content, id, number, page, part } = row as PageRow;\n\n return {\n content,\n id,\n ...(page && { page }),\n ...(number && { number }),\n ...(part && { part }),\n };\n });\n\n return pages;\n};\n\nexport const getAllTitles = async (db: Client): Promise<Title[]> => {\n const rows = await selectAllRows(db, Tables.Title);\n\n const titles: Title[] = rows.map((row: any) => {\n const r = row as TitleRow;\n\n return {\n content: r.content,\n id: r.id,\n page: r.page,\n ...(r.parent && { number: r.parent }),\n };\n });\n\n return titles;\n};\n\nexport const getData = async (db: Client): Promise<BookData> => {\n const [pages, titles] = await Promise.all([getAllPages(db), getAllTitles(db)]);\n return { pages, titles };\n};\n","import pino, { Logger } from 'pino';\nimport pretty, { PrettyOptions } from 'pino-pretty';\nimport process from 'process';\n\nconst stream = pretty({\n colorize: true,\n} as PrettyOptions);\n\nconst logger: Logger = pino(\n {\n base: { pid: undefined, hostname: undefined }, // This will remove pid and hostname but keep time\n level: process.env.LOG_LEVEL || 'info',\n },\n stream,\n);\n\nexport default logger;\n","import { Client, Row } from '@libsql/client';\n\nexport type InternalTable = {\n name: string;\n};\n\nexport const getInternalTables = async (db: Client, dbName: string): Promise<InternalTable[]> => {\n const { rows: tables } = await db.execute(`SELECT name FROM ${dbName}.sqlite_master WHERE type='table'`);\n\n return tables as unknown as InternalTable[];\n};\n\nexport const selectAllRows = async (client: Client, table: string): Promise<Row[]> => {\n const { rows } = await client.execute(`SELECT * FROM ${table}`);\n return rows;\n};\n","const MAIN_DB_ALIAS = 'main';\n\nexport const attachDB = (dbFile: string, alias: string) => `ATTACH DATABASE '${dbFile}' AS ${alias}`;\n\nexport const buildPagePatchQuery = (\n patchAlias: string,\n tableName: string,\n aslAlias: string = MAIN_DB_ALIAS,\n): string => `\n UPDATE ${aslAlias}.${tableName}\n SET content = ${updatePageColumn('content', aslAlias, patchAlias)},\n part = ${updatePageColumn('part', aslAlias, patchAlias)},\n page = ${updatePageColumn('page', aslAlias, patchAlias)},\n number = ${updatePageColumn('number', aslAlias, patchAlias)}\n WHERE EXISTS (\n SELECT 1\n FROM ${patchAlias}.${tableName}\n WHERE ${aslAlias}.${tableName}.id = ${patchAlias}.${tableName}.id\n );\n`;\n\nconst updateTitleColumn = (columnName: string, aslAlias: string, patchAlias: string) => `\n (SELECT CASE \n WHEN ${patchAlias}.title.${columnName} != '#' THEN ${patchAlias}.title.${columnName}\n ELSE ${aslAlias}.title.${columnName}\n END \n FROM ${patchAlias}.title\n WHERE ${aslAlias}.title.id = ${patchAlias}.title.id)\n`;\n\nexport const buildTitlePatchQuery = (\n patchAlias: string,\n tableName: string,\n aslAlias: string = MAIN_DB_ALIAS,\n): string => `\n UPDATE ${aslAlias}.${tableName}\n SET content = ${updateTitleColumn('content', aslAlias, patchAlias)},\n page = ${updateTitleColumn('page', aslAlias, patchAlias)},\n parent = ${updateTitleColumn('parent', aslAlias, patchAlias)}\n WHERE EXISTS (\n SELECT 1\n FROM ${patchAlias}.${tableName}\n WHERE ${aslAlias}.${tableName}.id = ${patchAlias}.${tableName}.id\n );\n`;\n\nexport const createTable = (name: string, fields: string[]): string =>\n `CREATE TABLE IF NOT EXISTS ${name} (${fields.join(', ')})`;\n\nexport const detachDB = (alias: string) => `DETACH DATABASE ${alias}`;\n\nconst updatePageColumn = (columnName: string, aslAlias: string, patchAlias: string): string => `\n (SELECT CASE \n WHEN ${patchAlias}.page.${columnName} != '#' THEN ${patchAlias}.page.${columnName}\n ELSE ${aslAlias}.page.${columnName}\n END \n FROM ${patchAlias}.page\n WHERE ${aslAlias}.page.id = ${patchAlias}.page.id)\n`;\n\nexport const insertUnsafely = (table: string, fieldToValue: Record<string, any>, isDeleted = false): string => {\n const combinedRecords: Record<string, any> = { ...fieldToValue, is_deleted: isDeleted ? '1' : '0' };\n\n const sortedKeys = Object.keys(combinedRecords).sort();\n\n const sortedValues = sortedKeys.map((key) => combinedRecords[key]);\n\n return `INSERT INTO ${table} (${sortedKeys.toString()}) VALUES (${sortedValues\n .map((val) => {\n if (val === null) {\n return 'NULL';\n }\n\n return typeof val === 'string' ? `'${val}'` : val;\n })\n .toString()})`;\n};\n","export type AuthorRow = {\n biography: string;\n death: number;\n id: number;\n name: string;\n};\n\nexport type BookRow = {\n author: string;\n bibliography: string;\n category: number;\n date?: null | number;\n hint: null | string;\n id: number;\n major: number;\n metadata: string;\n minor?: number;\n name: string;\n pdf_links: null | string;\n printed: number;\n type: number;\n};\n\nexport type PageRow = {\n content: string;\n id: number;\n number: null | number;\n page: null | number;\n part: null | number;\n};\n\nexport type TitleRow = {\n content: string;\n id: number;\n page: number;\n parent: null | number;\n};\n\nexport type CategoryRow = {\n id: number;\n name: string;\n};\n\nexport enum Tables {\n Authors = 'authors',\n Books = 'books',\n Categories = 'categories',\n Page = 'page',\n Title = 'title',\n}\n","import { Client } from '@libsql/client';\nimport path from 'path';\n\nimport { Author, Book, Category, MasterData, PDFLinks } from '../types';\nimport { UNKNOWN_VALUE_PLACEHOLDER } from '../utils/constants';\nimport { selectAllRows } from './common';\nimport { attachDB, detachDB } from './queryBuilder';\nimport { BookRow, Tables } from './types';\n\nexport const copyForeignMasterTableData = async (db: Client, sourceTables: string[]) => {\n const aliasToPath: Record<string, string> = sourceTables.reduce((acc, tablePath) => {\n const { name } = path.parse(tablePath);\n return { ...acc, [name]: tablePath };\n }, {});\n\n const attachStatements: string[] = Object.entries(aliasToPath).map(([alias, dbPath]) => attachDB(dbPath, alias));\n await db.batch(attachStatements);\n\n const insertStatements: string[] = [\n `INSERT INTO ${Tables.Authors} SELECT id,name,biography,(CASE WHEN death_number = ${UNKNOWN_VALUE_PLACEHOLDER} THEN NULL ELSE death_number END) AS death_number FROM author WHERE is_deleted='0'`,\n `INSERT INTO ${Tables.Books} SELECT id,name,category,type,(CASE WHEN date = ${UNKNOWN_VALUE_PLACEHOLDER} THEN NULL ELSE date END) AS date,author,printed,major_release,minor_release,bibliography,hint,pdf_links,metadata FROM book WHERE is_deleted='0'`,\n `INSERT INTO ${Tables.Categories} SELECT id,name FROM category WHERE is_deleted='0'`,\n ];\n await db.batch(insertStatements);\n\n const detachStatements: string[] = Object.keys(aliasToPath).map(detachDB);\n await db.batch(detachStatements);\n};\n\nexport const createTables = async (db: Client) => {\n return db.batch([\n `CREATE TABLE authors (id INTEGER PRIMARY KEY, name TEXT, biography TEXT, death INTEGER)`,\n `CREATE TABLE books (id INTEGER PRIMARY KEY, name TEXT, category INTEGER, type INTEGER, date INTEGER, author TEXT, printed INTEGER, major INTEGER, minor INTEGER, bibliography TEXT, hint TEXT, pdf_links TEXT, metadata TEXT)`,\n `CREATE TABLE categories (id INTEGER PRIMARY KEY, name TEXT)`,\n ]);\n};\n\nexport const getAllAuthors = async (db: Client): Promise<Author[]> => {\n const rows = await selectAllRows(db, Tables.Authors);\n\n const authors: Author[] = rows.map((r: any) => ({\n ...(r.biography && { biography: r.biography }),\n ...(r.death && { death: r.death }),\n id: r.id,\n name: r.name,\n }));\n\n return authors;\n};\n\nexport const getAllBooks = async (db: Client): Promise<Book[]> => {\n const rows = await selectAllRows(db, Tables.Books);\n\n const books: Book[] = rows.map((row: any) => {\n const r = row as BookRow;\n\n return {\n author: parseAuthor(r.author),\n bibliography: r.bibliography,\n category: r.category,\n id: r.id,\n major: r.major,\n metadata: JSON.parse(r.metadata),\n name: r.name,\n printed: r.printed,\n type: r.type,\n ...(r.date && r.date.toString() !== UNKNOWN_VALUE_PLACEHOLDER && { date: r.date }),\n ...(r.hint && { hint: r.hint }),\n ...(r.pdf_links && { pdfLinks: parsePdfLinks(r.pdf_links) }),\n ...(r.minor && { minorRelease: r.minor }),\n };\n });\n\n return books;\n};\n\nexport const getAllCategories = async (db: Client): Promise<Category[]> => {\n const rows = await selectAllRows(db, Tables.Categories);\n\n const categories: Category[] = rows.map((r: any) => ({\n id: r.id,\n name: r.name,\n }));\n\n return categories;\n};\n\nconst parseAuthor = (value: string): number | number[] => {\n const result: number[] = value.split(',\\\\s+').map((id) => parseInt(id.trim()));\n return result.length > 1 ? result : result[0];\n};\n\nconst parsePdfLinks = (value: string): PDFLinks => {\n const result = JSON.parse(value);\n\n if (result.files) {\n result.files = (result.files as string[]).map((f: string) => {\n const [file, id] = f.split('|');\n return { ...(id && { id }), file };\n });\n }\n\n return result as PDFLinks;\n};\n\nexport const getData = async (db: Client): Promise<MasterData> => {\n const [authors, books, categories] = await Promise.all([getAllAuthors(db), getAllBooks(db), getAllCategories(db)]);\n return { authors, books, categories };\n};\n","export const DEFAULT_MASTER_METADATA_VERSION = 0;\n\nexport const UNKNOWN_VALUE_PLACEHOLDER = '99999';\n","import { createWriteStream, promises as fs } from 'fs';\nimport { IncomingMessage } from 'http';\nimport https from 'https';\nimport os from 'os';\nimport path from 'path';\nimport { pipeline } from 'stream/promises';\nimport unzipper, { Entry } from 'unzipper';\n\nexport const createTempDir = async (prefix = 'shamela') => {\n const tempDirBase = path.join(os.tmpdir(), prefix);\n return fs.mkdtemp(tempDirBase);\n};\n\nexport const fileExists = async (path: string) => !!(await fs.stat(path).catch(() => false));\n\n/**\n * Downloads and extracts a ZIP file from a given URL without loading the entire file into memory.\n *\n * @param url - The URL of the ZIP file to download and extract.\n * @param outputDir - The directory where the files should be extracted.\n * @returns A promise that resolves with the list of all extracted files.\n */\nexport async function unzipFromUrl(url: string, outputDir: string): Promise<string[]> {\n const extractedFiles: string[] = [];\n const entryPromises: Promise<void>[] = [];\n\n try {\n // Make HTTPS request and get the response stream\n const response = await new Promise<IncomingMessage>((resolve, reject) => {\n https\n .get(url, (res) => {\n if (res.statusCode !== 200) {\n reject(new Error(`Failed to download ZIP file: ${res.statusCode} ${res.statusMessage}`));\n } else {\n resolve(res);\n }\n })\n .on('error', (err) => {\n reject(new Error(`HTTPS request failed: ${err.message}`));\n });\n });\n\n // Create unzip stream\n const unzipStream = unzipper.Parse();\n\n // Handle entries in the ZIP file\n unzipStream.on('entry', (entry: Entry) => {\n const entryPromise = (async () => {\n const filePath = path.join(outputDir, entry.path);\n\n if (entry.type === 'Directory') {\n // Ensure the directory exists\n await fs.mkdir(filePath, { recursive: true });\n entry.autodrain();\n } else {\n // Ensure the parent directory exists\n const dir = path.dirname(filePath);\n await fs.mkdir(dir, { recursive: true });\n\n // Pipe the entry to a file\n await pipeline(entry, createWriteStream(filePath));\n extractedFiles.push(filePath);\n }\n })().catch((err) => {\n // Emit errors to be handled by the unzipStream error handler\n unzipStream.emit('error', err);\n });\n\n // Collect the promises\n entryPromises.push(entryPromise);\n });\n\n // Handle errors in the unzip stream\n unzipStream.on('error', (err) => {\n throw new Error(`Error during extraction: ${err.message}`);\n });\n\n // Pipe the response into the unzip stream\n await pipeline(response, unzipStream);\n\n // Wait for all entry promises to complete\n await Promise.all(entryPromises);\n\n return extractedFiles;\n } catch (error: any) {\n throw new Error(`Error processing URL: ${error.message}`);\n }\n}\n","import { Buffer } from 'buffer';\nimport { IncomingMessage } from 'http';\nimport https from 'https';\nimport process from 'process';\nimport { URL, URLSearchParams } from 'url';\n\nexport const buildUrl = (endpoint: string, params: Record<string, any>, useAuth: boolean = true): URL => {\n const url = new URL(endpoint);\n {\n const params = new URLSearchParams();\n\n Object.entries(params).forEach(([key, value]) => {\n params.append(key, value.toString());\n });\n\n if (useAuth) {\n params.append('api_key', process.env.SHAMELA_API_KEY as string);\n }\n\n url.search = params.toString();\n }\n\n return url;\n};\n\nexport const httpsGet = (url: string | URL): Promise<Buffer | Record<string, any>> => {\n return new Promise((resolve, reject) => {\n https\n .get(url, (res: IncomingMessage) => {\n const contentType = res.headers['content-type'] || '';\n const dataChunks: Buffer[] = [];\n\n res.on('data', (chunk: Buffer) => {\n dataChunks.push(chunk);\n });\n\n res.on('end', () => {\n const fullData = Buffer.concat(dataChunks);\n\n if (contentType.includes('application/json')) {\n try {\n const json = JSON.parse(fullData.toString('utf-8'));\n resolve(json);\n } catch (error: any) {\n reject(new Error(`Failed to parse JSON: ${error.message}`));\n }\n } else {\n resolve(fullData);\n }\n });\n })\n .on('error', (error) => {\n reject(new Error(`Error making request: ${error.message}`));\n });\n });\n};\n","import path from 'path';\nimport process from 'process';\n\nconst SOURCE_TABLES = ['author.sqlite', 'book.sqlite', 'category.sqlite'];\n\nexport const validateEnvVariables = () => {\n if (!process.env.SHAMELA_API_MASTER_PATCH_ENDPOINT) {\n throw new Error('SHAMELA_API_MASTER_PATCH_ENDPOINT environment variable not set');\n }\n\n if (!process.env.SHAMELA_API_KEY) {\n throw new Error('SHAMELA_API_KEY environment variable not set');\n }\n};\n\nexport const validateMasterSourceTables = (sourceTablePaths: string[]) => {\n const sourceTableNames = sourceTablePaths.map((tablePath) => path.parse(tablePath).base);\n return SOURCE_TABLES.every((table) => sourceTableNames.includes(table));\n};\n","export type GetMasterMetadataResponsePayload = {\n url: string;\n version: number;\n};\n\nexport interface OutputOptions {\n path: string;\n}\n\nexport type DownloadMasterOptions = {\n masterMetadata?: GetMasterMetadataResponsePayload;\n outputFile: OutputOptions;\n};\n\nexport type GetBookMetadataOptions = {\n majorVersion: number;\n minorVersion: number;\n};\n\nexport type GetBookMetadataResponsePayload = {\n majorRelease: number;\n majorReleaseUrl: string;\n minorRelease?: number;\n minorReleaseUrl?: string;\n};\n\nexport type DownloadBookOptions = {\n bookMetadata?: GetBookMetadataResponsePayload;\n outputFile: OutputOptions;\n};\n\nexport type Author = {\n biography?: string;\n death?: number;\n id: number;\n name: string;\n};\n\ntype PDFFile = {\n file: string;\n id?: string;\n};\n\nexport type PDFLinks = {\n alias?: number;\n cover?: number;\n cover_alias?: number;\n files?: PDFFile[];\n root?: string;\n size?: number;\n};\n\nexport type Metadata = {\n coauthor?: number[];\n date: string;\n group?: number;\n hide_diacritic?: boolean;\n min_ver?: number;\n prefix?: string;\n shorts: Record<string, string>;\n sub_books: number[];\n suffix?: string;\n};\n\nexport type Book = {\n author: number | number[];\n bibliography: string;\n category: number;\n date?: number;\n hint?: string;\n id: number;\n major: number;\n metadata: Metadata;\n minor?: number;\n name: string;\n pdfLinks?: PDFLinks;\n printed: number;\n type: number;\n};\n\nexport type Category = {\n id: number;\n name: string;\n};\n\nexport type MasterData = {\n authors: Author[];\n books: Book[];\n categories: Category[];\n};\n\nexport type Page = {\n content: string;\n id: number;\n number?: number;\n page?: number;\n part?: number;\n};\n\nexport type Title = {\n content: string;\n id: number;\n page: number;\n parent?: number;\n};\n\nexport type BookData = {\n pages: Page[];\n titles?: Title[];\n};\n"],"names":[],"version":3,"file":"main.js.map","sourceRoot":"../"}
1
+ {"mappings":"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","sources":["src/index.ts","src/api.ts","src/db/book.ts","src/utils/logger.ts","src/db/common.ts","src/db/queryBuilder.ts","src/db/types.ts","src/db/master.ts","src/utils/constants.ts","src/utils/io.ts","src/utils/network.ts","src/utils/validation.ts","src/types.ts"],"sourcesContent":["import { downloadBook, downloadMasterDatabase, getBook, getBookMetadata, getMasterMetadata } from './api';\n\nexport { downloadBook, downloadMasterDatabase, getBook, getBookMetadata, getMasterMetadata };\n\nexport * from './types';\n","import { Client, createClient } from '@libsql/client';\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport process from 'process';\nimport { URL, URLSearchParams } from 'url';\n\nimport { applyPatches, copyTableData, createTables as createBookTables, getData as getBookData } from './db/book.js';\nimport {\n copyForeignMasterTableData,\n createTables as createMasterTables,\n getData as getMasterData,\n} from './db/master.js';\nimport {\n BookData,\n DownloadBookOptions,\n DownloadMasterOptions,\n GetBookMetadataOptions,\n GetBookMetadataResponsePayload,\n GetMasterMetadataResponsePayload,\n} from './types.js';\nimport { DEFAULT_MASTER_METADATA_VERSION } from './utils/constants.js';\nimport { createTempDir, unzipFromUrl } from './utils/io.js';\nimport logger from './utils/logger.js';\nimport { httpsGet } from './utils/network.js';\nimport { validateEnvVariables, validateMasterSourceTables } from './utils/validation.js';\n\nexport const getBookMetadata = async (\n id: number,\n options?: GetBookMetadataOptions,\n): Promise<GetBookMetadataResponsePayload> => {\n validateEnvVariables();\n\n const url = new URL(`${process.env.SHAMELA_API_BOOKS_ENDPOINT}/${id}`);\n {\n const params = new URLSearchParams();\n params.append('api_key', process.env.SHAMELA_API_KEY as string);\n params.append('major_release', (options?.majorVersion || 0).toString());\n params.append('minor_release', (options?.minorVersion || 0).toString());\n url.search = params.toString();\n }\n\n logger.info(`Fetching shamela.ws book link: ${url.toString()}`);\n\n try {\n const response: Record<string, any> = await httpsGet(url);\n return {\n majorRelease: response.major_release,\n majorReleaseUrl: response.major_release_url,\n ...(response.minor_release_url && { minorReleaseUrl: response.minor_release_url }),\n ...(response.minor_release_url && { minorRelease: response.minor_release }),\n };\n } catch (error: any) {\n throw new Error(`Error fetching master patch: ${error.message}`);\n }\n};\n\nexport const downloadBook = async (id: number, options: DownloadBookOptions): Promise<string> => {\n logger.info(`downloadBook ${id} ${JSON.stringify(options)}`);\n\n const outputDir = await createTempDir('shamela_downloadBook');\n\n const bookResponse: GetBookMetadataResponsePayload = options?.bookMetadata || (await getBookMetadata(id));\n const [[bookDatabase], [patchDatabase] = []]: string[][] = await Promise.all([\n unzipFromUrl(bookResponse.majorReleaseUrl, outputDir),\n ...(bookResponse.minorReleaseUrl ? [unzipFromUrl(bookResponse.minorReleaseUrl, outputDir)] : []),\n ]);\n const dbPath = path.join(outputDir, 'book.db');\n\n const client: Client = createClient({\n url: `file:${dbPath}`,\n });\n\n try {\n logger.info(`Creating tables`);\n await createBookTables(client);\n\n if (patchDatabase) {\n logger.info(`Applying patches from ${patchDatabase} to ${bookDatabase}`);\n await applyPatches(client, bookDatabase, patchDatabase);\n } else {\n logger.info(`Copying table data from ${bookDatabase}`);\n await copyTableData(client, bookDatabase);\n }\n\n const { ext: extension } = path.parse(options.outputFile.path);\n\n if (extension === '.json') {\n const result = await getBookData(client);\n await fs.writeFile(options.outputFile.path, JSON.stringify(result, undefined, 2), 'utf8');\n }\n\n client.close();\n\n if (extension === '.db' || extension === '.sqlite') {\n await fs.rename(dbPath, options.outputFile.path);\n }\n\n await fs.rm(outputDir, { recursive: true });\n } finally {\n client.close();\n }\n\n return options.outputFile.path;\n};\n\nexport const getMasterMetadata = async (version: number = 0): Promise<GetMasterMetadataResponsePayload> => {\n validateEnvVariables();\n\n const url = new URL(process.env.SHAMELA_API_MASTER_PATCH_ENDPOINT as string);\n {\n const params = new URLSearchParams();\n params.append('api_key', process.env.SHAMELA_API_KEY as string);\n params.append('version', version.toString());\n url.search = params.toString();\n }\n\n logger.info(`Fetching shamela.ws master database patch link: ${url.toString()}`);\n\n try {\n const response: Record<string, any> = await httpsGet(url);\n return { url: response.patch_url, version: response.version };\n } catch (error: any) {\n throw new Error(`Error fetching master patch: ${error.message}`);\n }\n};\n\nexport const downloadMasterDatabase = async (options: DownloadMasterOptions): Promise<string> => {\n logger.info(`downloadMasterDatabase ${JSON.stringify(options)}`);\n\n const outputDir = await createTempDir('shamela_downloadMaster');\n\n const masterResponse: GetMasterMetadataResponsePayload =\n options.masterMetadata || (await getMasterMetadata(DEFAULT_MASTER_METADATA_VERSION));\n\n logger.info(`Downloading master database from: ${JSON.stringify(masterResponse)}`);\n const sourceTables: string[] = await unzipFromUrl(masterResponse.url, outputDir);\n\n logger.info(`sourceTables downloaded: ${sourceTables.toString()}`);\n\n if (!validateMasterSourceTables(sourceTables)) {\n logger.error(`Some source tables were not found: ${sourceTables.toString()}`);\n throw new Error('Expected tables not found!');\n }\n\n const dbPath = path.join(outputDir, 'master.db');\n\n const client: Client = createClient({\n url: `file:${dbPath}`,\n });\n\n try {\n logger.info(`Creating tables`);\n await createMasterTables(client);\n\n logger.info(`Copying data to master table`);\n await copyForeignMasterTableData(client, sourceTables);\n\n const { ext: extension } = path.parse(options.outputFile.path);\n\n if (extension === '.json') {\n const result = await getMasterData(client);\n await fs.writeFile(options.outputFile.path, JSON.stringify(result, undefined, 2), 'utf8');\n }\n\n client.close();\n\n if (extension === '.db' || extension === '.sqlite') {\n await fs.rename(dbPath, options.outputFile.path);\n }\n\n await fs.rm(outputDir, { recursive: true });\n } finally {\n client.close();\n }\n\n return options.outputFile.path;\n};\n\nexport const getBook = async (id: number): Promise<BookData> => {\n const outputDir = await createTempDir('shamela_getBookData');\n const outputPath = await downloadBook(id, { outputFile: { path: path.join(outputDir, `${id}.json`) } });\n\n const data = JSON.parse(await fs.readFile(outputPath, 'utf8')) as BookData;\n await fs.rm(outputDir, { recursive: true });\n\n return data;\n};\n","import { Client } from '@libsql/client';\n\nimport { BookData, Page, Title } from '../types';\nimport logger from '../utils/logger';\nimport { getInternalTables, InternalTable, selectAllRows } from './common';\nimport { attachDB, buildPagePatchQuery, buildTitlePatchQuery, detachDB } from './queryBuilder';\nimport { PageRow, Tables, TitleRow } from './types';\n\nconst PATCH_DB_ALIAS = 'patch';\nconst ASL_DB_ALIAS = 'asl';\n\nconst buildCopyStatements = (\n patchTables: InternalTable[],\n aslTables: InternalTable[],\n table: Tables,\n fields: string[],\n patchQuery: string,\n): string[] => {\n const statements = [];\n\n if (patchTables.find((t) => t.name === table)) {\n statements.push(\n `INSERT INTO main.${table} SELECT ${fields.join(',')} FROM ${ASL_DB_ALIAS}.${table} WHERE id IN (SELECT id FROM ${PATCH_DB_ALIAS}.${table} WHERE is_deleted='0')`,\n );\n statements.push(patchQuery);\n } else {\n let copyStatement = `INSERT INTO main.${table} SELECT ${fields.join(',')} FROM ${ASL_DB_ALIAS}.${table}`;\n\n if (aslTables.find((t) => t.name === table)?.fields.includes('is_deleted')) {\n copyStatement += ` WHERE is_deleted='0'`;\n }\n\n statements.push(copyStatement);\n }\n\n return statements;\n};\n\nexport const applyPatches = async (db: Client, aslDB: string, patchDB: string) => {\n await Promise.all([db.execute(attachDB(aslDB, ASL_DB_ALIAS)), db.execute(attachDB(patchDB, PATCH_DB_ALIAS))]);\n\n const [patchTables, aslTables] = await Promise.all([\n getInternalTables(db, PATCH_DB_ALIAS),\n getInternalTables(db, ASL_DB_ALIAS),\n ]);\n\n logger.debug({ aslTables, patchTables }, `Applying patches for...`);\n\n await db.batch([\n ...buildCopyStatements(\n patchTables,\n aslTables,\n Tables.Page,\n ['id', 'content', 'part', 'page', 'number'],\n buildPagePatchQuery(PATCH_DB_ALIAS, Tables.Page),\n ),\n ...buildCopyStatements(\n patchTables,\n aslTables,\n Tables.Title,\n ['id', 'content', 'page', 'parent'],\n buildTitlePatchQuery(PATCH_DB_ALIAS, Tables.Title),\n ),\n ]);\n\n return db.batch([detachDB(ASL_DB_ALIAS), detachDB(PATCH_DB_ALIAS)]);\n};\n\nexport const copyTableData = async (db: Client, aslDB: string) => {\n await db.execute(attachDB(aslDB, ASL_DB_ALIAS));\n const tables = await getInternalTables(db, ASL_DB_ALIAS);\n\n logger.debug({ tables }, `Applying patches for...`);\n\n await db.batch([\n `INSERT INTO main.${Tables.Title} SELECT id,content,page,parent FROM ${ASL_DB_ALIAS}.${Tables.Title}`,\n `INSERT INTO main.${Tables.Page} SELECT id,content,part,page,number FROM ${ASL_DB_ALIAS}.${Tables.Page}`,\n ]);\n\n return db.execute(detachDB(ASL_DB_ALIAS));\n};\n\nexport const createTables = async (db: Client) => {\n return db.batch([\n `CREATE TABLE page (id INTEGER PRIMARY KEY, content TEXT, part INTEGER, page INTEGER, number INTEGER)`,\n `CREATE TABLE title (id INTEGER PRIMARY KEY, content TEXT, page INTEGER, parent INTEGER)`,\n ]);\n};\n\nexport const getAllPages = async (db: Client): Promise<Page[]> => {\n const rows = await selectAllRows(db, Tables.Page);\n\n const pages: Page[] = rows.map((row: any) => {\n const { content, id, number, page, part } = row as PageRow;\n\n return {\n content,\n id,\n ...(page && { page }),\n ...(number && { number }),\n ...(part && { part }),\n };\n });\n\n return pages;\n};\n\nexport const getAllTitles = async (db: Client): Promise<Title[]> => {\n const rows = await selectAllRows(db, Tables.Title);\n\n const titles: Title[] = rows.map((row: any) => {\n const r = row as TitleRow;\n\n return {\n content: r.content,\n id: r.id,\n page: r.page,\n ...(r.parent && { number: r.parent }),\n };\n });\n\n return titles;\n};\n\nexport const getData = async (db: Client): Promise<BookData> => {\n const [pages, titles] = await Promise.all([getAllPages(db), getAllTitles(db)]);\n return { pages, titles };\n};\n","import pino, { Logger } from 'pino';\nimport pretty, { PrettyOptions } from 'pino-pretty';\nimport process from 'process';\n\nconst stream = pretty({\n colorize: true,\n} as PrettyOptions);\n\nconst logger: Logger = pino(\n {\n base: { pid: undefined, hostname: undefined }, // This will remove pid and hostname but keep time\n level: process.env.LOG_LEVEL || 'info',\n },\n stream,\n);\n\nexport default logger;\n","import { Client, Row } from '@libsql/client';\n\nexport type InternalTable = {\n fields: string[];\n name: string;\n};\n\nexport const getInternalTables = async (db: Client, dbName: string): Promise<InternalTable[]> => {\n const { rows: tables } = await db.execute(`SELECT name,sql FROM ${dbName}.sqlite_master WHERE type='table'`);\n\n return tables.map((row: any) => {\n const fields = row.sql.split(', ').map((field: string) => field.split(' ')[0]);\n\n return { fields, name: row.name };\n });\n};\n\nexport const selectAllRows = async (client: Client, table: string): Promise<Row[]> => {\n const { rows } = await client.execute(`SELECT * FROM ${table}`);\n return rows;\n};\n","const MAIN_DB_ALIAS = 'main';\n\nexport const attachDB = (dbFile: string, alias: string) => `ATTACH DATABASE '${dbFile}' AS ${alias}`;\n\nexport const buildPagePatchQuery = (\n patchAlias: string,\n tableName: string,\n aslAlias: string = MAIN_DB_ALIAS,\n): string => `\n UPDATE ${aslAlias}.${tableName}\n SET content = ${updatePageColumn('content', aslAlias, patchAlias)},\n part = ${updatePageColumn('part', aslAlias, patchAlias)},\n page = ${updatePageColumn('page', aslAlias, patchAlias)},\n number = ${updatePageColumn('number', aslAlias, patchAlias)}\n WHERE EXISTS (\n SELECT 1\n FROM ${patchAlias}.${tableName}\n WHERE ${aslAlias}.${tableName}.id = ${patchAlias}.${tableName}.id\n );\n`;\n\nconst updateTitleColumn = (columnName: string, aslAlias: string, patchAlias: string) => `\n (SELECT CASE \n WHEN ${patchAlias}.title.${columnName} != '#' THEN ${patchAlias}.title.${columnName}\n ELSE ${aslAlias}.title.${columnName}\n END \n FROM ${patchAlias}.title\n WHERE ${aslAlias}.title.id = ${patchAlias}.title.id)\n`;\n\nexport const buildTitlePatchQuery = (\n patchAlias: string,\n tableName: string,\n aslAlias: string = MAIN_DB_ALIAS,\n): string => `\n UPDATE ${aslAlias}.${tableName}\n SET content = ${updateTitleColumn('content', aslAlias, patchAlias)},\n page = ${updateTitleColumn('page', aslAlias, patchAlias)},\n parent = ${updateTitleColumn('parent', aslAlias, patchAlias)}\n WHERE EXISTS (\n SELECT 1\n FROM ${patchAlias}.${tableName}\n WHERE ${aslAlias}.${tableName}.id = ${patchAlias}.${tableName}.id\n );\n`;\n\nexport const createTable = (name: string, fields: string[]): string =>\n `CREATE TABLE IF NOT EXISTS ${name} (${fields.join(', ')})`;\n\nexport const detachDB = (alias: string) => `DETACH DATABASE ${alias}`;\n\nconst updatePageColumn = (columnName: string, aslAlias: string, patchAlias: string): string => `\n (SELECT CASE \n WHEN ${patchAlias}.page.${columnName} != '#' THEN ${patchAlias}.page.${columnName}\n ELSE ${aslAlias}.page.${columnName}\n END \n FROM ${patchAlias}.page\n WHERE ${aslAlias}.page.id = ${patchAlias}.page.id)\n`;\n\nexport const insertUnsafely = (table: string, fieldToValue: Record<string, any>, isDeleted = false): string => {\n const combinedRecords: Record<string, any> = { ...fieldToValue, is_deleted: isDeleted ? '1' : '0' };\n\n const sortedKeys = Object.keys(combinedRecords).sort();\n\n const sortedValues = sortedKeys.map((key) => combinedRecords[key]);\n\n return `INSERT INTO ${table} (${sortedKeys.toString()}) VALUES (${sortedValues\n .map((val) => {\n if (val === null) {\n return 'NULL';\n }\n\n return typeof val === 'string' ? `'${val}'` : val;\n })\n .toString()})`;\n};\n","export enum Tables {\n Authors = 'authors',\n Books = 'books',\n Categories = 'categories',\n Page = 'page',\n Title = 'title',\n}\n\nexport type AuthorRow = {\n biography: string;\n death: number;\n id: number;\n name: string;\n};\n\nexport type BookRow = {\n author: string;\n bibliography: string;\n category: number;\n date?: null | number;\n hint: null | string;\n id: number;\n major: number;\n metadata: string;\n minor?: number;\n name: string;\n pdf_links: null | string;\n printed: number;\n type: number;\n};\n\nexport type CategoryRow = {\n id: number;\n name: string;\n};\n\nexport type PageRow = {\n content: string;\n id: number;\n number: null | number;\n page: null | number;\n part: null | number;\n};\n\nexport type TitleRow = {\n content: string;\n id: number;\n page: number;\n parent: null | number;\n};\n","import { Client } from '@libsql/client';\nimport path from 'path';\n\nimport { Author, Book, Category, MasterData, PDFLinks } from '../types';\nimport { UNKNOWN_VALUE_PLACEHOLDER } from '../utils/constants';\nimport { selectAllRows } from './common';\nimport { attachDB, detachDB } from './queryBuilder';\nimport { BookRow, Tables } from './types';\n\nexport const copyForeignMasterTableData = async (db: Client, sourceTables: string[]) => {\n const aliasToPath: Record<string, string> = sourceTables.reduce((acc, tablePath) => {\n const { name } = path.parse(tablePath);\n return { ...acc, [name]: tablePath };\n }, {});\n\n const attachStatements: string[] = Object.entries(aliasToPath).map(([alias, dbPath]) => attachDB(dbPath, alias));\n await db.batch(attachStatements);\n\n const insertStatements: string[] = [\n `INSERT INTO ${Tables.Authors} SELECT id,name,biography,(CASE WHEN death_number = ${UNKNOWN_VALUE_PLACEHOLDER} THEN NULL ELSE death_number END) AS death_number FROM author WHERE is_deleted='0'`,\n `INSERT INTO ${Tables.Books} SELECT id,name,category,type,(CASE WHEN date = ${UNKNOWN_VALUE_PLACEHOLDER} THEN NULL ELSE date END) AS date,author,printed,major_release,minor_release,bibliography,hint,pdf_links,metadata FROM book WHERE is_deleted='0'`,\n `INSERT INTO ${Tables.Categories} SELECT id,name FROM category WHERE is_deleted='0'`,\n ];\n await db.batch(insertStatements);\n\n const detachStatements: string[] = Object.keys(aliasToPath).map(detachDB);\n await db.batch(detachStatements);\n};\n\nexport const createTables = async (db: Client) => {\n return db.batch([\n `CREATE TABLE authors (id INTEGER PRIMARY KEY, name TEXT, biography TEXT, death INTEGER)`,\n `CREATE TABLE books (id INTEGER PRIMARY KEY, name TEXT, category INTEGER, type INTEGER, date INTEGER, author TEXT, printed INTEGER, major INTEGER, minor INTEGER, bibliography TEXT, hint TEXT, pdf_links TEXT, metadata TEXT)`,\n `CREATE TABLE categories (id INTEGER PRIMARY KEY, name TEXT)`,\n ]);\n};\n\nexport const getAllAuthors = async (db: Client): Promise<Author[]> => {\n const rows = await selectAllRows(db, Tables.Authors);\n\n const authors: Author[] = rows.map((r: any) => ({\n ...(r.biography && { biography: r.biography }),\n ...(r.death && { death: r.death }),\n id: r.id,\n name: r.name,\n }));\n\n return authors;\n};\n\nexport const getAllBooks = async (db: Client): Promise<Book[]> => {\n const rows = await selectAllRows(db, Tables.Books);\n\n const books: Book[] = rows.map((row: any) => {\n const r = row as BookRow;\n\n return {\n author: parseAuthor(r.author),\n bibliography: r.bibliography,\n category: r.category,\n id: r.id,\n major: r.major,\n metadata: JSON.parse(r.metadata),\n name: r.name,\n printed: r.printed,\n type: r.type,\n ...(r.date && r.date.toString() !== UNKNOWN_VALUE_PLACEHOLDER && { date: r.date }),\n ...(r.hint && { hint: r.hint }),\n ...(r.pdf_links && { pdfLinks: parsePdfLinks(r.pdf_links) }),\n ...(r.minor && { minorRelease: r.minor }),\n };\n });\n\n return books;\n};\n\nexport const getAllCategories = async (db: Client): Promise<Category[]> => {\n const rows = await selectAllRows(db, Tables.Categories);\n\n const categories: Category[] = rows.map((r: any) => ({\n id: r.id,\n name: r.name,\n }));\n\n return categories;\n};\n\nconst parseAuthor = (value: string): number | number[] => {\n const result: number[] = value.split(',\\\\s+').map((id) => parseInt(id.trim()));\n return result.length > 1 ? result : result[0];\n};\n\nconst parsePdfLinks = (value: string): PDFLinks => {\n const result = JSON.parse(value);\n\n if (result.files) {\n result.files = (result.files as string[]).map((f: string) => {\n const [file, id] = f.split('|');\n return { ...(id && { id }), file };\n });\n }\n\n return result as PDFLinks;\n};\n\nexport const getData = async (db: Client): Promise<MasterData> => {\n const [authors, books, categories] = await Promise.all([getAllAuthors(db), getAllBooks(db), getAllCategories(db)]);\n return { authors, books, categories };\n};\n","export const DEFAULT_MASTER_METADATA_VERSION = 0;\n\nexport const UNKNOWN_VALUE_PLACEHOLDER = '99999';\n","import { createWriteStream, promises as fs } from 'fs';\nimport { IncomingMessage } from 'http';\nimport https from 'https';\nimport os from 'os';\nimport path from 'path';\nimport { pipeline } from 'stream/promises';\nimport unzipper, { Entry } from 'unzipper';\n\nexport const createTempDir = async (prefix = 'shamela') => {\n const tempDirBase = path.join(os.tmpdir(), prefix);\n return fs.mkdtemp(tempDirBase);\n};\n\nexport const fileExists = async (path: string) => !!(await fs.stat(path).catch(() => false));\n\n/**\n * Downloads and extracts a ZIP file from a given URL without loading the entire file into memory.\n *\n * @param url - The URL of the ZIP file to download and extract.\n * @param outputDir - The directory where the files should be extracted.\n * @returns A promise that resolves with the list of all extracted files.\n */\nexport async function unzipFromUrl(url: string, outputDir: string): Promise<string[]> {\n const extractedFiles: string[] = [];\n const entryPromises: Promise<void>[] = [];\n\n try {\n // Make HTTPS request and get the response stream\n const response = await new Promise<IncomingMessage>((resolve, reject) => {\n https\n .get(url, (res) => {\n if (res.statusCode !== 200) {\n reject(new Error(`Failed to download ZIP file: ${res.statusCode} ${res.statusMessage}`));\n } else {\n resolve(res);\n }\n })\n .on('error', (err) => {\n reject(new Error(`HTTPS request failed: ${err.message}`));\n });\n });\n\n // Create unzip stream\n const unzipStream = unzipper.Parse();\n\n // Handle entries in the ZIP file\n unzipStream.on('entry', (entry: Entry) => {\n const entryPromise = (async () => {\n const filePath = path.join(outputDir, entry.path);\n\n if (entry.type === 'Directory') {\n // Ensure the directory exists\n await fs.mkdir(filePath, { recursive: true });\n entry.autodrain();\n } else {\n // Ensure the parent directory exists\n const dir = path.dirname(filePath);\n await fs.mkdir(dir, { recursive: true });\n\n // Pipe the entry to a file\n await pipeline(entry, createWriteStream(filePath));\n extractedFiles.push(filePath);\n }\n })().catch((err) => {\n // Emit errors to be handled by the unzipStream error handler\n unzipStream.emit('error', err);\n });\n\n // Collect the promises\n entryPromises.push(entryPromise);\n });\n\n // Handle errors in the unzip stream\n unzipStream.on('error', (err) => {\n throw new Error(`Error during extraction: ${err.message}`);\n });\n\n // Pipe the response into the unzip stream\n await pipeline(response, unzipStream);\n\n // Wait for all entry promises to complete\n await Promise.all(entryPromises);\n\n return extractedFiles;\n } catch (error: any) {\n throw new Error(`Error processing URL: ${error.message}`);\n }\n}\n","import { Buffer } from 'buffer';\nimport { IncomingMessage } from 'http';\nimport https from 'https';\nimport process from 'process';\nimport { URL, URLSearchParams } from 'url';\n\nexport const buildUrl = (endpoint: string, params: Record<string, any>, useAuth: boolean = true): URL => {\n const url = new URL(endpoint);\n {\n const params = new URLSearchParams();\n\n Object.entries(params).forEach(([key, value]) => {\n params.append(key, value.toString());\n });\n\n if (useAuth) {\n params.append('api_key', process.env.SHAMELA_API_KEY as string);\n }\n\n url.search = params.toString();\n }\n\n return url;\n};\n\nexport const httpsGet = (url: string | URL): Promise<Buffer | Record<string, any>> => {\n return new Promise((resolve, reject) => {\n https\n .get(url, (res: IncomingMessage) => {\n const contentType = res.headers['content-type'] || '';\n const dataChunks: Buffer[] = [];\n\n res.on('data', (chunk: Buffer) => {\n dataChunks.push(chunk);\n });\n\n res.on('end', () => {\n const fullData = Buffer.concat(dataChunks);\n\n if (contentType.includes('application/json')) {\n try {\n const json = JSON.parse(fullData.toString('utf-8'));\n resolve(json);\n } catch (error: any) {\n reject(new Error(`Failed to parse JSON: ${error.message}`));\n }\n } else {\n resolve(fullData);\n }\n });\n })\n .on('error', (error) => {\n reject(new Error(`Error making request: ${error.message}`));\n });\n });\n};\n","import path from 'path';\nimport process from 'process';\n\nconst SOURCE_TABLES = ['author.sqlite', 'book.sqlite', 'category.sqlite'];\n\nexport const validateEnvVariables = () => {\n if (!process.env.SHAMELA_API_MASTER_PATCH_ENDPOINT) {\n throw new Error('SHAMELA_API_MASTER_PATCH_ENDPOINT environment variable not set');\n }\n\n if (!process.env.SHAMELA_API_KEY) {\n throw new Error('SHAMELA_API_KEY environment variable not set');\n }\n};\n\nexport const validateMasterSourceTables = (sourceTablePaths: string[]) => {\n const sourceTableNames = sourceTablePaths.map((tablePath) => path.parse(tablePath).base);\n return SOURCE_TABLES.every((table) => sourceTableNames.includes(table));\n};\n","export type GetMasterMetadataResponsePayload = {\n url: string;\n version: number;\n};\n\nexport interface OutputOptions {\n path: string;\n}\n\nexport type DownloadMasterOptions = {\n masterMetadata?: GetMasterMetadataResponsePayload;\n outputFile: OutputOptions;\n};\n\nexport type GetBookMetadataOptions = {\n majorVersion: number;\n minorVersion: number;\n};\n\nexport type GetBookMetadataResponsePayload = {\n majorRelease: number;\n majorReleaseUrl: string;\n minorRelease?: number;\n minorReleaseUrl?: string;\n};\n\nexport type DownloadBookOptions = {\n bookMetadata?: GetBookMetadataResponsePayload;\n outputFile: OutputOptions;\n};\n\nexport type Author = {\n biography?: string;\n death?: number;\n id: number;\n name: string;\n};\n\ntype PDFFile = {\n file: string;\n id?: string;\n};\n\nexport type PDFLinks = {\n alias?: number;\n cover?: number;\n cover_alias?: number;\n files?: PDFFile[];\n root?: string;\n size?: number;\n};\n\nexport type Metadata = {\n coauthor?: number[];\n date: string;\n group?: number;\n hide_diacritic?: boolean;\n min_ver?: number;\n prefix?: string;\n shorts: Record<string, string>;\n sub_books: number[];\n suffix?: string;\n};\n\nexport type Book = {\n author: number | number[];\n bibliography: string;\n category: number;\n date?: number;\n hint?: string;\n id: number;\n major: number;\n metadata: Metadata;\n minor?: number;\n name: string;\n pdfLinks?: PDFLinks;\n printed: number;\n type: number;\n};\n\nexport type Category = {\n id: number;\n name: string;\n};\n\nexport type MasterData = {\n authors: Author[];\n books: Book[];\n categories: Category[];\n};\n\nexport type Page = {\n content: string;\n id: number;\n number?: number;\n page?: number;\n part?: number;\n};\n\nexport type Title = {\n content: string;\n id: number;\n page: number;\n parent?: number;\n};\n\nexport type BookData = {\n pages: Page[];\n titles?: Title[];\n};\n"],"names":[],"version":3,"file":"main.js.map","sourceRoot":"../"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shamela",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Library to interact with the Maktabah Shamela v4 APIs",
5
5
  "repository": {
6
6
  "type": "git",
@@ -12,13 +12,13 @@
12
12
  "source": "src/index.ts",
13
13
  "type": "module",
14
14
  "engines": {
15
- "node": ">=20.0.0"
15
+ "node": ">=22.0.0"
16
16
  },
17
17
  "scripts": {
18
18
  "build": "parcel build",
19
19
  "test": "vitest run --coverage",
20
- "e2e": "node --env-file .env $(which pnpm) exec vitest run --coverage --config vitest.e2e.config.ts",
21
- "e2e:ci": "pnpm exec vitest --config vitest.e2e.config.ts --run"
20
+ "e2e": "bun run --env-file .env vitest run --coverage --config vitest.e2e.config.ts",
21
+ "e2e:ci": "bun run vitest --config vitest.e2e.config.ts --run"
22
22
  },
23
23
  "files": [
24
24
  "dist/main.js",
@@ -34,35 +34,34 @@
34
34
  "author": "Ragaeeb Haq",
35
35
  "license": "MIT",
36
36
  "devDependencies": {
37
- "@eslint/js": "^9.12.0",
38
- "@parcel/packager-ts": "^2.12.0",
39
- "@parcel/transformer-typescript-types": "^2.12.0",
37
+ "@eslint/js": "^9.17.0",
38
+ "@parcel/packager-ts": "^2.13.3",
39
+ "@parcel/transformer-typescript-types": "^2.13.3",
40
40
  "@semantic-release/changelog": "^6.0.3",
41
41
  "@semantic-release/git": "^10.0.1",
42
42
  "@types/eslint__js": "^8.42.3",
43
- "@types/node": "^22.7.5",
43
+ "@types/node": "^22.10.2",
44
44
  "@types/unzipper": "^0.10.10",
45
- "@vitest/coverage-v8": "^2.1.2",
45
+ "@vitest/coverage-v8": "^2.1.8",
46
46
  "dotenv-vault": "^1.26.2",
47
- "eslint": "^9.12.0",
47
+ "eslint": "^9.17.0",
48
48
  "eslint-config-prettier": "^9.1.0",
49
49
  "eslint-plugin-orderly-functions": "^1.1.0",
50
- "eslint-plugin-perfectionist": "^3.8.0",
50
+ "eslint-plugin-perfectionist": "^4.4.0",
51
51
  "eslint-plugin-prettier": "^5.2.1",
52
52
  "eslint-plugin-vitest": "^0.5.4",
53
53
  "eslint-plugin-vitest-globals": "^1.5.0",
54
- "parcel": "^2.12.0",
55
- "prettier": "^3.3.3",
56
- "semantic-release": "^24.1.2",
57
- "typescript": "^5.6.3",
58
- "typescript-eslint": "^8.8.1",
59
- "vitest": "^2.1.2"
54
+ "parcel": "^2.13.3",
55
+ "prettier": "^3.4.2",
56
+ "semantic-release": "^24.2.0",
57
+ "typescript": "^5.7.2",
58
+ "typescript-eslint": "^8.19.0",
59
+ "vitest": "^2.1.8"
60
60
  },
61
61
  "dependencies": {
62
62
  "@libsql/client": "^0.14.0",
63
- "pino": "^9.4.0",
64
- "pino-pretty": "^11.2.2",
63
+ "pino": "^9.6.0",
64
+ "pino-pretty": "^13.0.0",
65
65
  "unzipper": "^0.12.3"
66
- },
67
- "packageManager": "pnpm@9.12.1+sha512.e5a7e52a4183a02d5931057f7a0dbff9d5e9ce3161e33fa68ae392125b79282a8a8a470a51dfc8a0ed86221442eb2fb57019b0990ed24fab519bf0e1bc5ccfc4"
66
+ }
68
67
  }