@library-pals/isbn 0.2.0 → 1.0.1
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 +20 -41
- package/package.json +18 -22
- package/src/index.d.ts +84 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +36 -42
- package/src/provider-resolvers.d.ts +33 -0
- package/src/provider-resolvers.d.ts.map +1 -0
- package/src/provider-resolvers.js +16 -11
- package/src/providers/google.d.ts +187 -0
- package/src/providers/google.d.ts.map +1 -0
- package/src/providers/google.js +110 -15
- package/src/providers/isbndb.d.ts +184 -0
- package/src/providers/isbndb.d.ts.map +1 -0
- package/src/providers/isbndb.js +95 -27
- package/src/providers/open-library.d.ts +256 -0
- package/src/providers/open-library.d.ts.map +1 -0
- package/src/providers/open-library.js +173 -41
- package/.gitattributes +0 -2
- package/.github/workflows/npm-publish.yml +0 -30
- package/.github/workflows/test.yml +0 -16
- package/src/cli.js +0 -41
- package/src/providers/worldcat.js +0 -63
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('../index.js').Book} Book
|
|
3
|
+
* @typedef {import('axios').AxiosRequestConfig} AxiosRequestConfig
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Resolves a book from the Open Library API using the provided ISBN.
|
|
7
|
+
* @param {string} isbn - The ISBN of the book.
|
|
8
|
+
* @param {AxiosRequestConfig} options - Additional options for the request.
|
|
9
|
+
* @returns {Promise<Book>} A promise that resolves to the standardized book object.
|
|
10
|
+
* @throws {Error} If the response code is not 200 or if no books are found with the provided ISBN.
|
|
11
|
+
*/
|
|
12
|
+
export function resolveOpenLibrary(isbn: string, options: AxiosRequestConfig): Promise<Book>;
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {object} Author
|
|
15
|
+
* @property {string} key - The key of the author.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {object} Language
|
|
19
|
+
* @property {string} key - The key of the language.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {object} Type
|
|
23
|
+
* @property {string} key - The key of the type.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {object} FirstSentence
|
|
27
|
+
* @property {string} type - The type of the first sentence.
|
|
28
|
+
* @property {string} value - The value of the first sentence.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {object} Work
|
|
32
|
+
* @property {string} key - The key of the work.
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* @typedef {object} DateTime
|
|
36
|
+
* @property {string} type - The type of the datetime.
|
|
37
|
+
* @property {string} value - The value of the datetime.
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* @typedef {object} OpenLibraryBook
|
|
41
|
+
* @property {object} identifiers - The identifiers of the book.
|
|
42
|
+
* @property {string} title - The title of the book.
|
|
43
|
+
* @property {Author[]} authors - The authors of the book.
|
|
44
|
+
* @property {string} publish_date - The publish date of the book.
|
|
45
|
+
* @property {string[]} publishers - The publishers of the book.
|
|
46
|
+
* @property {number[]} covers - The covers of the book.
|
|
47
|
+
* @property {string[]} contributions - The contributions to the book.
|
|
48
|
+
* @property {Language[]} languages - The languages of the book.
|
|
49
|
+
* @property {string[]} source_records - The source records of the book.
|
|
50
|
+
* @property {string[]} local_id - The local IDs of the book.
|
|
51
|
+
* @property {Type} type - The type of the book.
|
|
52
|
+
* @property {FirstSentence} first_sentence - The first sentence of the book.
|
|
53
|
+
* @property {string} key - The key of the book.
|
|
54
|
+
* @property {number} number_of_pages - The number of pages in the book.
|
|
55
|
+
* @property {Work[]} works - The works related to the book.
|
|
56
|
+
* @property {object} classifications - The classifications of the book.
|
|
57
|
+
* @property {string} ocaid - The Open Content Alliance ID of the book.
|
|
58
|
+
* @property {string[]} isbn_10 - The ISBN-10 of the book.
|
|
59
|
+
* @property {string[]} isbn_13 - The ISBN-13 of the book.
|
|
60
|
+
* @property {number} latest_revision - The latest revision of the book.
|
|
61
|
+
* @property {number} revision - The revision of the book.
|
|
62
|
+
* @property {DateTime} created - The creation datetime of the book.
|
|
63
|
+
* @property {DateTime} last_modified - The last modified datetime of the book.
|
|
64
|
+
*/
|
|
65
|
+
/**
|
|
66
|
+
* Standardizes a book object by extracting relevant information from the provided book object.
|
|
67
|
+
* @param {OpenLibraryBook} book - The book object to be standardized.
|
|
68
|
+
* @param {string} isbn - The book's isbn.
|
|
69
|
+
* @returns {Promise<Book>} - The standardized book object.
|
|
70
|
+
*/
|
|
71
|
+
export function standardize(book: OpenLibraryBook, isbn: string): Promise<Book>;
|
|
72
|
+
/**
|
|
73
|
+
* Retrieves the author names from OpenLibrary.
|
|
74
|
+
* @param {{key: string}[]} rawAuthors - List of author keys.
|
|
75
|
+
* @returns {Promise<string[]>} - List of author names.
|
|
76
|
+
*/
|
|
77
|
+
export function getAuthors(rawAuthors: {
|
|
78
|
+
key: string;
|
|
79
|
+
}[]): Promise<string[]>;
|
|
80
|
+
/**
|
|
81
|
+
* @typedef {object} OpenLibraryResponse
|
|
82
|
+
* @property {string} description - The description of the book.
|
|
83
|
+
* @property {string[]} subjects - The subjects of the book.
|
|
84
|
+
* @property {{author: {key: string}}[]} authors - The authors of the book.
|
|
85
|
+
*/
|
|
86
|
+
/**
|
|
87
|
+
* Retrieves the description of the book from OpenLibrary.
|
|
88
|
+
* @param {OpenLibraryBook} book - The book object from OpenLibrary.
|
|
89
|
+
* @returns {Promise<{description: string, subjects: string[], rawAuthors: {key: string}[]}>} - Description of the book.
|
|
90
|
+
*/
|
|
91
|
+
export function getWorks(book: OpenLibraryBook): Promise<{
|
|
92
|
+
description: string;
|
|
93
|
+
subjects: string[];
|
|
94
|
+
rawAuthors: {
|
|
95
|
+
key: string;
|
|
96
|
+
}[];
|
|
97
|
+
}>;
|
|
98
|
+
export type Book = import('../index.js').Book;
|
|
99
|
+
export type AxiosRequestConfig = import('axios').AxiosRequestConfig;
|
|
100
|
+
export type Author = {
|
|
101
|
+
/**
|
|
102
|
+
* - The key of the author.
|
|
103
|
+
*/
|
|
104
|
+
key: string;
|
|
105
|
+
};
|
|
106
|
+
export type Language = {
|
|
107
|
+
/**
|
|
108
|
+
* - The key of the language.
|
|
109
|
+
*/
|
|
110
|
+
key: string;
|
|
111
|
+
};
|
|
112
|
+
export type Type = {
|
|
113
|
+
/**
|
|
114
|
+
* - The key of the type.
|
|
115
|
+
*/
|
|
116
|
+
key: string;
|
|
117
|
+
};
|
|
118
|
+
export type FirstSentence = {
|
|
119
|
+
/**
|
|
120
|
+
* - The type of the first sentence.
|
|
121
|
+
*/
|
|
122
|
+
type: string;
|
|
123
|
+
/**
|
|
124
|
+
* - The value of the first sentence.
|
|
125
|
+
*/
|
|
126
|
+
value: string;
|
|
127
|
+
};
|
|
128
|
+
export type Work = {
|
|
129
|
+
/**
|
|
130
|
+
* - The key of the work.
|
|
131
|
+
*/
|
|
132
|
+
key: string;
|
|
133
|
+
};
|
|
134
|
+
export type DateTime = {
|
|
135
|
+
/**
|
|
136
|
+
* - The type of the datetime.
|
|
137
|
+
*/
|
|
138
|
+
type: string;
|
|
139
|
+
/**
|
|
140
|
+
* - The value of the datetime.
|
|
141
|
+
*/
|
|
142
|
+
value: string;
|
|
143
|
+
};
|
|
144
|
+
export type OpenLibraryBook = {
|
|
145
|
+
/**
|
|
146
|
+
* - The identifiers of the book.
|
|
147
|
+
*/
|
|
148
|
+
identifiers: object;
|
|
149
|
+
/**
|
|
150
|
+
* - The title of the book.
|
|
151
|
+
*/
|
|
152
|
+
title: string;
|
|
153
|
+
/**
|
|
154
|
+
* - The authors of the book.
|
|
155
|
+
*/
|
|
156
|
+
authors: Author[];
|
|
157
|
+
/**
|
|
158
|
+
* - The publish date of the book.
|
|
159
|
+
*/
|
|
160
|
+
publish_date: string;
|
|
161
|
+
/**
|
|
162
|
+
* - The publishers of the book.
|
|
163
|
+
*/
|
|
164
|
+
publishers: string[];
|
|
165
|
+
/**
|
|
166
|
+
* - The covers of the book.
|
|
167
|
+
*/
|
|
168
|
+
covers: number[];
|
|
169
|
+
/**
|
|
170
|
+
* - The contributions to the book.
|
|
171
|
+
*/
|
|
172
|
+
contributions: string[];
|
|
173
|
+
/**
|
|
174
|
+
* - The languages of the book.
|
|
175
|
+
*/
|
|
176
|
+
languages: Language[];
|
|
177
|
+
/**
|
|
178
|
+
* - The source records of the book.
|
|
179
|
+
*/
|
|
180
|
+
source_records: string[];
|
|
181
|
+
/**
|
|
182
|
+
* - The local IDs of the book.
|
|
183
|
+
*/
|
|
184
|
+
local_id: string[];
|
|
185
|
+
/**
|
|
186
|
+
* - The type of the book.
|
|
187
|
+
*/
|
|
188
|
+
type: Type;
|
|
189
|
+
/**
|
|
190
|
+
* - The first sentence of the book.
|
|
191
|
+
*/
|
|
192
|
+
first_sentence: FirstSentence;
|
|
193
|
+
/**
|
|
194
|
+
* - The key of the book.
|
|
195
|
+
*/
|
|
196
|
+
key: string;
|
|
197
|
+
/**
|
|
198
|
+
* - The number of pages in the book.
|
|
199
|
+
*/
|
|
200
|
+
number_of_pages: number;
|
|
201
|
+
/**
|
|
202
|
+
* - The works related to the book.
|
|
203
|
+
*/
|
|
204
|
+
works: Work[];
|
|
205
|
+
/**
|
|
206
|
+
* - The classifications of the book.
|
|
207
|
+
*/
|
|
208
|
+
classifications: object;
|
|
209
|
+
/**
|
|
210
|
+
* - The Open Content Alliance ID of the book.
|
|
211
|
+
*/
|
|
212
|
+
ocaid: string;
|
|
213
|
+
/**
|
|
214
|
+
* - The ISBN-10 of the book.
|
|
215
|
+
*/
|
|
216
|
+
isbn_10: string[];
|
|
217
|
+
/**
|
|
218
|
+
* - The ISBN-13 of the book.
|
|
219
|
+
*/
|
|
220
|
+
isbn_13: string[];
|
|
221
|
+
/**
|
|
222
|
+
* - The latest revision of the book.
|
|
223
|
+
*/
|
|
224
|
+
latest_revision: number;
|
|
225
|
+
/**
|
|
226
|
+
* - The revision of the book.
|
|
227
|
+
*/
|
|
228
|
+
revision: number;
|
|
229
|
+
/**
|
|
230
|
+
* - The creation datetime of the book.
|
|
231
|
+
*/
|
|
232
|
+
created: DateTime;
|
|
233
|
+
/**
|
|
234
|
+
* - The last modified datetime of the book.
|
|
235
|
+
*/
|
|
236
|
+
last_modified: DateTime;
|
|
237
|
+
};
|
|
238
|
+
export type OpenLibraryResponse = {
|
|
239
|
+
/**
|
|
240
|
+
* - The description of the book.
|
|
241
|
+
*/
|
|
242
|
+
description: string;
|
|
243
|
+
/**
|
|
244
|
+
* - The subjects of the book.
|
|
245
|
+
*/
|
|
246
|
+
subjects: string[];
|
|
247
|
+
/**
|
|
248
|
+
* - The authors of the book.
|
|
249
|
+
*/
|
|
250
|
+
authors: {
|
|
251
|
+
author: {
|
|
252
|
+
key: string;
|
|
253
|
+
};
|
|
254
|
+
}[];
|
|
255
|
+
};
|
|
256
|
+
//# sourceMappingURL=open-library.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-library.d.ts","sourceRoot":"","sources":["open-library.js"],"names":[],"mappings":"AAOA;;;GAGG;AAEH;;;;;;GAMG;AACH,yCALW,MAAM,WACN,kBAAkB,GAChB,QAAQ,IAAI,CAAC,CAuBzB;AAED;;;GAGG;AAEH;;;GAGG;AAEH;;;GAGG;AAEH;;;;GAIG;AAEH;;;GAGG;AAEH;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;GAKG;AACH,kCAJW,eAAe,QACf,MAAM,GACJ,QAAQ,IAAI,CAAC,CAoBzB;AAED;;;;GAIG;AACH,uCAHW;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,EAAE,GACb,QAAQ,MAAM,EAAE,CAAC,CAuB7B;AAED;;;;;GAKG;AAEH;;;;GAIG;AACH,+BAHW,eAAe,GACb,QAAQ;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE;QAAC,GAAG,EAAE,MAAM,CAAA;KAAC,EAAE,CAAA;CAAC,CAAC,CAuC3F;mBAnMY,OAAO,aAAa,EAAE,IAAI;iCAC1B,OAAO,OAAO,EAAE,kBAAkB;;;;;SAkCjC,MAAM;;;;;;SAKN,MAAM;;;;;;SAKN,MAAM;;;;;;UAKN,MAAM;;;;WACN,MAAM;;;;;;SAKN,MAAM;;;;;;UAKN,MAAM;;;;WACN,MAAM;;;;;;iBAKN,MAAM;;;;WACN,MAAM;;;;aACN,MAAM,EAAE;;;;kBACR,MAAM;;;;gBACN,MAAM,EAAE;;;;YACR,MAAM,EAAE;;;;mBACR,MAAM,EAAE;;;;eACR,QAAQ,EAAE;;;;oBACV,MAAM,EAAE;;;;cACR,MAAM,EAAE;;;;UACR,IAAI;;;;oBACJ,aAAa;;;;SACb,MAAM;;;;qBACN,MAAM;;;;WACN,IAAI,EAAE;;;;qBACN,MAAM;;;;WACN,MAAM;;;;aACN,MAAM,EAAE;;;;aACR,MAAM,EAAE;;;;qBACR,MAAM;;;;cACN,MAAM;;;;aACN,QAAQ;;;;mBACR,QAAQ;;;;;;iBA2DR,MAAM;;;;cACN,MAAM,EAAE;;;;aACR;QAAC,MAAM,EAAE;YAAC,GAAG,EAAE,MAAM,CAAA;SAAC,CAAA;KAAC,EAAE"}
|
|
@@ -5,68 +5,200 @@ import {
|
|
|
5
5
|
OPENLIBRARY_API_BOOK,
|
|
6
6
|
} from "../provider-resolvers.js";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {import('../index.js').Book} Book
|
|
10
|
+
* @typedef {import('axios').AxiosRequestConfig} AxiosRequestConfig
|
|
11
|
+
*/
|
|
12
|
+
|
|
8
13
|
/**
|
|
9
14
|
* Resolves a book from the Open Library API using the provided ISBN.
|
|
10
15
|
* @param {string} isbn - The ISBN of the book.
|
|
11
|
-
* @param {
|
|
12
|
-
* @returns {Promise<
|
|
16
|
+
* @param {AxiosRequestConfig} options - Additional options for the request.
|
|
17
|
+
* @returns {Promise<Book>} A promise that resolves to the standardized book object.
|
|
13
18
|
* @throws {Error} If the response code is not 200 or if no books are found with the provided ISBN.
|
|
14
19
|
*/
|
|
15
20
|
export async function resolveOpenLibrary(isbn, options) {
|
|
16
21
|
const requestOptions = {
|
|
17
22
|
...defaultOptions,
|
|
18
23
|
...options,
|
|
19
|
-
url: `${OPENLIBRARY_API_BASE}${OPENLIBRARY_API_BOOK}?bibkeys=ISBN:${isbn}&format=json&jscmd=details`,
|
|
20
24
|
};
|
|
25
|
+
const url = `${OPENLIBRARY_API_BASE}${OPENLIBRARY_API_BOOK}/${isbn}.json`;
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
`Wrong response code: ${status}
|
|
26
|
-
|
|
27
|
+
try {
|
|
28
|
+
const response = await axios.get(url, requestOptions);
|
|
29
|
+
if (response.status !== 200) {
|
|
30
|
+
throw new Error(`Wrong response code: ${response.status}`);
|
|
31
|
+
}
|
|
32
|
+
const book = response.data;
|
|
33
|
+
if (!book || Object.keys(book).length === 0) {
|
|
34
|
+
throw new Error(`No books found with ISBN: ${isbn}`);
|
|
35
|
+
}
|
|
36
|
+
return await standardize(book, isbn);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
throw new Error(error.message);
|
|
27
39
|
}
|
|
28
|
-
const books = data;
|
|
29
|
-
const book = books[`ISBN:${isbn}`];
|
|
30
|
-
if (!book) {
|
|
31
|
-
throw new Error(`No books found with ISBN: ${isbn}`);
|
|
32
|
-
}
|
|
33
|
-
return standardize(book);
|
|
34
40
|
}
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {object} Author
|
|
44
|
+
* @property {string} key - The key of the author.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @typedef {object} Language
|
|
49
|
+
* @property {string} key - The key of the language.
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @typedef {object} Type
|
|
54
|
+
* @property {string} key - The key of the type.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @typedef {object} FirstSentence
|
|
59
|
+
* @property {string} type - The type of the first sentence.
|
|
60
|
+
* @property {string} value - The value of the first sentence.
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @typedef {object} Work
|
|
65
|
+
* @property {string} key - The key of the work.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @typedef {object} DateTime
|
|
70
|
+
* @property {string} type - The type of the datetime.
|
|
71
|
+
* @property {string} value - The value of the datetime.
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @typedef {object} OpenLibraryBook
|
|
76
|
+
* @property {object} identifiers - The identifiers of the book.
|
|
77
|
+
* @property {string} title - The title of the book.
|
|
78
|
+
* @property {Author[]} authors - The authors of the book.
|
|
79
|
+
* @property {string} publish_date - The publish date of the book.
|
|
80
|
+
* @property {string[]} publishers - The publishers of the book.
|
|
81
|
+
* @property {number[]} covers - The covers of the book.
|
|
82
|
+
* @property {string[]} contributions - The contributions to the book.
|
|
83
|
+
* @property {Language[]} languages - The languages of the book.
|
|
84
|
+
* @property {string[]} source_records - The source records of the book.
|
|
85
|
+
* @property {string[]} local_id - The local IDs of the book.
|
|
86
|
+
* @property {Type} type - The type of the book.
|
|
87
|
+
* @property {FirstSentence} first_sentence - The first sentence of the book.
|
|
88
|
+
* @property {string} key - The key of the book.
|
|
89
|
+
* @property {number} number_of_pages - The number of pages in the book.
|
|
90
|
+
* @property {Work[]} works - The works related to the book.
|
|
91
|
+
* @property {object} classifications - The classifications of the book.
|
|
92
|
+
* @property {string} ocaid - The Open Content Alliance ID of the book.
|
|
93
|
+
* @property {string[]} isbn_10 - The ISBN-10 of the book.
|
|
94
|
+
* @property {string[]} isbn_13 - The ISBN-13 of the book.
|
|
95
|
+
* @property {number} latest_revision - The latest revision of the book.
|
|
96
|
+
* @property {number} revision - The revision of the book.
|
|
97
|
+
* @property {DateTime} created - The creation datetime of the book.
|
|
98
|
+
* @property {DateTime} last_modified - The last modified datetime of the book.
|
|
99
|
+
*/
|
|
41
100
|
|
|
42
101
|
/**
|
|
43
102
|
* Standardizes a book object by extracting relevant information from the provided book object.
|
|
44
|
-
* @param {
|
|
45
|
-
* @
|
|
103
|
+
* @param {OpenLibraryBook} book - The book object to be standardized.
|
|
104
|
+
* @param {string} isbn - The book's isbn.
|
|
105
|
+
* @returns {Promise<Book>} - The standardized book object.
|
|
46
106
|
*/
|
|
47
|
-
function standardize(book) {
|
|
107
|
+
export async function standardize(book, isbn) {
|
|
108
|
+
const { description, subjects, rawAuthors } = await getWorks(book);
|
|
109
|
+
const authors = await getAuthors(rawAuthors);
|
|
48
110
|
const standardBook = {
|
|
49
|
-
title: book.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
: [],
|
|
54
|
-
description: book.details.subtitle,
|
|
55
|
-
industryIdentifiers: [],
|
|
56
|
-
pageCount: book.details.number_of_pages,
|
|
111
|
+
title: book.title,
|
|
112
|
+
authors,
|
|
113
|
+
description,
|
|
114
|
+
pageCount: book.number_of_pages,
|
|
57
115
|
printType: "BOOK",
|
|
58
|
-
categories:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
infoLink: book.info_url,
|
|
65
|
-
publisher: book.details.publishers ? book.details.publishers[0] : "",
|
|
66
|
-
language: book.details.languages
|
|
67
|
-
? LANGUAGE_MAP[book.details.languages[0].key] || "unknown"
|
|
68
|
-
: "unknown",
|
|
116
|
+
categories: subjects,
|
|
117
|
+
thumbnail: `https://covers.openlibrary.org/b/id/${book.covers[0]}-L.jpg`,
|
|
118
|
+
link: book.key
|
|
119
|
+
? `${OPENLIBRARY_API_BASE}${book.key}`
|
|
120
|
+
: `${OPENLIBRARY_API_BASE}${OPENLIBRARY_API_BOOK}/${isbn}`,
|
|
121
|
+
isbn,
|
|
69
122
|
};
|
|
70
123
|
|
|
71
124
|
return standardBook;
|
|
72
125
|
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Retrieves the author names from OpenLibrary.
|
|
129
|
+
* @param {{key: string}[]} rawAuthors - List of author keys.
|
|
130
|
+
* @returns {Promise<string[]>} - List of author names.
|
|
131
|
+
*/
|
|
132
|
+
export async function getAuthors(rawAuthors) {
|
|
133
|
+
const promises = rawAuthors
|
|
134
|
+
.filter((author) => author && author.key)
|
|
135
|
+
.map((author) =>
|
|
136
|
+
axios
|
|
137
|
+
.get(`https://openlibrary.org/${author.key}.json`)
|
|
138
|
+
.then((response) => {
|
|
139
|
+
if (response.status !== 200) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`Unable to get author ${author.key}: ${response.status}`,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
return response.data && response.data.name;
|
|
145
|
+
}),
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
return await Promise.all(promises);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
throw new Error(error.message);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @typedef {object} OpenLibraryResponse
|
|
157
|
+
* @property {string} description - The description of the book.
|
|
158
|
+
* @property {string[]} subjects - The subjects of the book.
|
|
159
|
+
* @property {{author: {key: string}}[]} authors - The authors of the book.
|
|
160
|
+
*/
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Retrieves the description of the book from OpenLibrary.
|
|
164
|
+
* @param {OpenLibraryBook} book - The book object from OpenLibrary.
|
|
165
|
+
* @returns {Promise<{description: string, subjects: string[], rawAuthors: {key: string}[]}>} - Description of the book.
|
|
166
|
+
*/
|
|
167
|
+
export async function getWorks(book) {
|
|
168
|
+
const defaultResponse = {
|
|
169
|
+
description: "",
|
|
170
|
+
subjects: [],
|
|
171
|
+
rawAuthors: [],
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
if (!book.works) {
|
|
175
|
+
return defaultResponse;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const [work] = book.works;
|
|
179
|
+
|
|
180
|
+
if (!work || !work.key) {
|
|
181
|
+
return defaultResponse;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
const response = await axios.get(
|
|
186
|
+
`https://openlibrary.org/${work.key}.json`,
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
if (response.status !== 200) {
|
|
190
|
+
throw new Error(`Unable to get ${work.key}: ${response.status}`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** @type {OpenLibraryResponse} */
|
|
194
|
+
const data = response.data;
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
description: data.description || "",
|
|
198
|
+
subjects: data.subjects || [],
|
|
199
|
+
rawAuthors: data.authors?.map((a) => a.author) || [],
|
|
200
|
+
};
|
|
201
|
+
} catch (error) {
|
|
202
|
+
throw new Error(error.message);
|
|
203
|
+
}
|
|
204
|
+
}
|
package/.gitattributes
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
name: Publish npm package
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
release:
|
|
5
|
-
types: [created]
|
|
6
|
-
|
|
7
|
-
jobs:
|
|
8
|
-
build:
|
|
9
|
-
runs-on: ubuntu-latest
|
|
10
|
-
steps:
|
|
11
|
-
- uses: actions/checkout@v4
|
|
12
|
-
- uses: actions/setup-node@v4
|
|
13
|
-
with:
|
|
14
|
-
node-version: 20.x
|
|
15
|
-
- run: npm ci
|
|
16
|
-
- run: npm test
|
|
17
|
-
|
|
18
|
-
publish-npm:
|
|
19
|
-
needs: build
|
|
20
|
-
runs-on: ubuntu-latest
|
|
21
|
-
steps:
|
|
22
|
-
- uses: actions/checkout@v4
|
|
23
|
-
- uses: actions/setup-node@v4
|
|
24
|
-
with:
|
|
25
|
-
node-version: 20.x
|
|
26
|
-
registry-url: https://registry.npmjs.org/
|
|
27
|
-
- run: npm ci
|
|
28
|
-
- run: npm publish --access public
|
|
29
|
-
env:
|
|
30
|
-
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
package/src/cli.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import meow from "meow";
|
|
3
|
-
import isbn from "./index.js";
|
|
4
|
-
|
|
5
|
-
const cli = meow(
|
|
6
|
-
`
|
|
7
|
-
Usage
|
|
8
|
-
$ isbn <input>
|
|
9
|
-
|
|
10
|
-
Options
|
|
11
|
-
--isbn, -i The ISBN for the book
|
|
12
|
-
|
|
13
|
-
Examples
|
|
14
|
-
$ isbn 9780374104092
|
|
15
|
-
|
|
16
|
-
This script will resolve the provided ISBN to a book. The ISBN must be a valid ISBN-10 or ISBN-13.
|
|
17
|
-
`,
|
|
18
|
-
{
|
|
19
|
-
importMeta: import.meta,
|
|
20
|
-
flags: {
|
|
21
|
-
isbn: {
|
|
22
|
-
type: "string",
|
|
23
|
-
shortFlag: "i",
|
|
24
|
-
isRequired: true,
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
}
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
if (!/^(\d{10}|\d{13})$/.test(cli.flags.isbn)) {
|
|
31
|
-
console.error("Invalid ISBN. Please provide a valid ISBN-10 or ISBN-13.");
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
const book = await isbn.resolve(cli.flags.isbn);
|
|
37
|
-
console.log(book);
|
|
38
|
-
} catch (error) {
|
|
39
|
-
console.error("An error occurred while trying to resolve the ISBN:", error);
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import axios from "axios";
|
|
2
|
-
import {
|
|
3
|
-
defaultOptions,
|
|
4
|
-
WORLDCAT_API_BASE,
|
|
5
|
-
WORLDCAT_API_BOOK,
|
|
6
|
-
} from "../provider-resolvers.js";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Resolves a book using the Worldcat API based on the provided ISBN.
|
|
10
|
-
* @param {string} isbn - The ISBN of the book to resolve.
|
|
11
|
-
* @param {object} options - Additional options for the request.
|
|
12
|
-
* @returns {Promise<object>} A promise that resolves to the standardized book object.
|
|
13
|
-
* @throws {Error} If the response code is not 200 or if no books are found with the provided ISBN.
|
|
14
|
-
*/
|
|
15
|
-
export async function resolveWorldcat(isbn, options) {
|
|
16
|
-
const requestOptions = {
|
|
17
|
-
...defaultOptions,
|
|
18
|
-
...options,
|
|
19
|
-
url: `${WORLDCAT_API_BASE}${WORLDCAT_API_BOOK}/${isbn}?method=getMetadata&fl=*&format=json`,
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const { status, data } = await axios.request(requestOptions);
|
|
23
|
-
if (status !== 200) {
|
|
24
|
-
throw new Error(
|
|
25
|
-
`Wrong response code: ${status}. Response data: ${JSON.stringify(data)}`
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
const books = data;
|
|
29
|
-
if (books.stat !== "ok") {
|
|
30
|
-
throw new Error(`No books found with ISBN: ${isbn}`);
|
|
31
|
-
}
|
|
32
|
-
const [book] = books.list;
|
|
33
|
-
return standardize(book);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const LANGUAGE_MAP = {
|
|
37
|
-
eng: "en",
|
|
38
|
-
spa: "es",
|
|
39
|
-
fre: "fr",
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Standardizes a book object by extracting relevant information from the provided book object.
|
|
44
|
-
* @param {object} book - The book object to be standardized.
|
|
45
|
-
* @returns {object} - The standardized book object.
|
|
46
|
-
*/
|
|
47
|
-
function standardize(book) {
|
|
48
|
-
const standardBook = {
|
|
49
|
-
title: book.title,
|
|
50
|
-
publishedDate: book.year,
|
|
51
|
-
authors: book.author ? [book.author] : [],
|
|
52
|
-
description: null,
|
|
53
|
-
industryIdentifiers: [],
|
|
54
|
-
pageCount: null,
|
|
55
|
-
printType: "BOOK",
|
|
56
|
-
categories: [],
|
|
57
|
-
imageLinks: {},
|
|
58
|
-
publisher: book.publisher,
|
|
59
|
-
language: LANGUAGE_MAP[book.lang] || "unknown",
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
return standardBook;
|
|
63
|
-
}
|