@openzim/libzim 3.0.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +1 -1
- package/.eslintignore +3 -0
- package/.eslintrc.js +39 -0
- package/Changelog +13 -0
- package/README.md +1 -1
- package/binding.gyp +1 -1
- package/bundle-libzim.js +22 -16
- package/dist/index.d.ts +72 -52
- package/dist/index.js +3 -4
- package/download-libzim.js +63 -56
- package/package.json +11 -3
- package/src/archive.h +9 -0
- package/src/blob.h +6 -3
- package/src/index.d.ts +72 -52
- package/src/index.js +3 -4
- package/src/search.h +0 -9
- package/src/writerItem.h +16 -1
package/.env
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
LIBZIM_VERSION=
|
|
1
|
+
LIBZIM_VERSION=9.0.0
|
package/.eslintignore
ADDED
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
env: {
|
|
3
|
+
es6: true,
|
|
4
|
+
node: true,
|
|
5
|
+
},
|
|
6
|
+
rules: {
|
|
7
|
+
"prettier/prettier": "error",
|
|
8
|
+
eqeqeq: "error",
|
|
9
|
+
},
|
|
10
|
+
extends: [
|
|
11
|
+
"eslint:recommended",
|
|
12
|
+
"plugin:@typescript-eslint/eslint-recommended",
|
|
13
|
+
"plugin:@typescript-eslint/recommended",
|
|
14
|
+
"prettier",
|
|
15
|
+
],
|
|
16
|
+
parser: "@typescript-eslint/parser",
|
|
17
|
+
parserOptions: {
|
|
18
|
+
project: "tsconfig.json",
|
|
19
|
+
sourceType: "module",
|
|
20
|
+
},
|
|
21
|
+
plugins: ["prettier"],
|
|
22
|
+
root: true,
|
|
23
|
+
overrides: [
|
|
24
|
+
{
|
|
25
|
+
files: ["*.ts", "*.js"],
|
|
26
|
+
rules: {
|
|
27
|
+
"@typescript-eslint/no-var-requires": "off",
|
|
28
|
+
"no-import-assign": "off",
|
|
29
|
+
"no-useless-escape": "off",
|
|
30
|
+
},
|
|
31
|
+
parserOptions: {
|
|
32
|
+
sourceType: "module",
|
|
33
|
+
},
|
|
34
|
+
extends: ["plugin:@typescript-eslint/recommended"],
|
|
35
|
+
parser: "@typescript-eslint/parser",
|
|
36
|
+
plugins: ["@typescript-eslint"],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
package/Changelog
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
3.2.0:
|
|
2
|
+
* NEW: Use libzim v9.0.0
|
|
3
|
+
* NEW: Added mediaCount to Archive
|
|
4
|
+
* FIX: Simplify a lot the CI
|
|
5
|
+
* FIX: Nlob allocation and warning
|
|
6
|
+
* DEL: Deprecated getSize from SearchIterator
|
|
7
|
+
|
|
8
|
+
3.1.0:
|
|
9
|
+
* NEW: Use libzim v8.2.1
|
|
10
|
+
* FIX: Handling of binary data in the creator
|
|
11
|
+
* FIX: Use ESLint instead of TSLint
|
|
12
|
+
* REMOVE: Node.js 16 from the CI
|
|
13
|
+
|
|
1
14
|
3.0.0:
|
|
2
15
|
* NEW: Use libzim v8.2.0
|
|
3
16
|
* NEW: Calling API (to follow libzim changes)
|
package/README.md
CHANGED
package/binding.gyp
CHANGED
package/bundle-libzim.js
CHANGED
|
@@ -1,26 +1,32 @@
|
|
|
1
|
-
require(
|
|
2
|
-
const mkdirp = require(
|
|
3
|
-
const exec = require(
|
|
4
|
-
const os = require(
|
|
1
|
+
require("dotenv").config();
|
|
2
|
+
const mkdirp = require("mkdirp");
|
|
3
|
+
const exec = require("exec-then");
|
|
4
|
+
const os = require("os");
|
|
5
5
|
|
|
6
|
-
mkdirp.sync(
|
|
6
|
+
mkdirp.sync("./build/Release");
|
|
7
7
|
|
|
8
|
-
const isMacOS = os.type() ===
|
|
9
|
-
const isLinux = os.type() ===
|
|
8
|
+
const isMacOS = os.type() === "Darwin";
|
|
9
|
+
const isLinux = os.type() === "Linux";
|
|
10
10
|
|
|
11
11
|
if (!isMacOS && !isLinux) {
|
|
12
|
-
|
|
12
|
+
console.warn(
|
|
13
|
+
"\x1b[41m\n================================ README \n\nlibzim bundle with prebuilt binaries only available for macOS and Linux:\n\n\thttps://github.com/openzim/libzim/\n\n================================\x1b[0m\n"
|
|
14
|
+
);
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
if (isLinux) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
console.info("Copying libzim.so.9 to build folder");
|
|
19
|
+
exec(
|
|
20
|
+
"cp download/lib/x86_64-linux-gnu/libzim.so.9 build/Release/libzim.so.9"
|
|
21
|
+
);
|
|
22
|
+
exec("ln -sf build/Release/libzim.so.9 build/Release/libzim.so"); // convienience only, not required
|
|
19
23
|
}
|
|
20
24
|
if (isMacOS) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
console.info("Copying libzim.9.dylib to build folder");
|
|
26
|
+
exec("cp download/lib/libzim.9.dylib build/Release/libzim.9.dylib");
|
|
27
|
+
exec("ln -sf build/Release/libzim.9.dylib build/Release/libzim.dylib"); // convienience only, not required
|
|
28
|
+
console.info("Fixing rpath");
|
|
29
|
+
exec(
|
|
30
|
+
"install_name_tool -change libzim.9.dylib @loader_path/libzim.9.dylib build/Release/zim_binding.node"
|
|
31
|
+
);
|
|
26
32
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
export class IntegrityCheck {
|
|
3
2
|
static CHECKSUM: symbol;
|
|
4
3
|
static DIRENT_PTRS: symbol;
|
|
@@ -6,7 +5,7 @@ export class IntegrityCheck {
|
|
|
6
5
|
static TITLE_INDEX: symbol;
|
|
7
6
|
static CLUSTER_PTRS: symbol;
|
|
8
7
|
static DIRENT_MIMETYPES: symbol;
|
|
9
|
-
static COUNT: symbol;
|
|
8
|
+
static COUNT: symbol; // DO NOT USE THIS. See libzim docs.
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
export class Compression {
|
|
@@ -23,25 +22,25 @@ export class Blob {
|
|
|
23
22
|
|
|
24
23
|
export type ContentProvider = {
|
|
25
24
|
size: number | bigint;
|
|
26
|
-
feed()
|
|
27
|
-
}
|
|
25
|
+
feed(): Blob;
|
|
26
|
+
};
|
|
28
27
|
|
|
29
28
|
export class StringProvider {
|
|
30
29
|
constructor(content: string);
|
|
31
30
|
get size(): number;
|
|
32
|
-
feed()
|
|
31
|
+
feed(): Blob;
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
export class FileProvider {
|
|
36
35
|
constructor(filepath: string);
|
|
37
36
|
get size(): number | bigint;
|
|
38
|
-
feed()
|
|
37
|
+
feed(): Blob;
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
export type Hint = {
|
|
42
41
|
COMPRESS?: number;
|
|
43
42
|
FRONT_ARTICLE?: number;
|
|
44
|
-
}
|
|
43
|
+
};
|
|
45
44
|
|
|
46
45
|
export interface IndexData {
|
|
47
46
|
hasIndexData?: boolean;
|
|
@@ -56,44 +55,65 @@ export interface WriterItem {
|
|
|
56
55
|
path: string;
|
|
57
56
|
title: string;
|
|
58
57
|
mimeType: string;
|
|
59
|
-
getContentProvider()
|
|
58
|
+
getContentProvider(): ContentProvider;
|
|
60
59
|
hints: Hint;
|
|
61
60
|
getIndexData?: () => IndexData;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
export class StringItem {
|
|
65
|
-
constructor(
|
|
64
|
+
constructor(
|
|
65
|
+
path: string,
|
|
66
|
+
mimeType: string,
|
|
67
|
+
title: string,
|
|
68
|
+
hint: Hint,
|
|
69
|
+
content: ArrayBuffer | Buffer | string
|
|
70
|
+
);
|
|
66
71
|
readonly path: string;
|
|
67
72
|
readonly title: string;
|
|
68
73
|
readonly mimeType: string;
|
|
69
|
-
getContentProvider()
|
|
74
|
+
getContentProvider(): StringProvider;
|
|
70
75
|
readonly hints: Hint;
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
export class FileItem {
|
|
74
|
-
constructor(
|
|
79
|
+
constructor(
|
|
80
|
+
path: string,
|
|
81
|
+
mimeType: string,
|
|
82
|
+
title: string,
|
|
83
|
+
hints: Hint,
|
|
84
|
+
filePath: string
|
|
85
|
+
);
|
|
75
86
|
readonly path: string;
|
|
76
87
|
readonly title: string;
|
|
77
88
|
readonly mimeType: string;
|
|
78
|
-
getContentProvider()
|
|
89
|
+
getContentProvider(): StringProvider;
|
|
79
90
|
readonly hints: Hint;
|
|
80
91
|
}
|
|
81
92
|
|
|
82
93
|
export class Creator {
|
|
83
94
|
constructor();
|
|
84
|
-
configVerbose(verbose: boolean)
|
|
85
|
-
configCompression(value: Compression)
|
|
86
|
-
configClusterSize(size: number)
|
|
87
|
-
configIndexing(indexing: boolean, language: string)
|
|
88
|
-
configNbWorkers(num: number)
|
|
95
|
+
configVerbose(verbose: boolean): this;
|
|
96
|
+
configCompression(value: Compression): this;
|
|
97
|
+
configClusterSize(size: number): this;
|
|
98
|
+
configIndexing(indexing: boolean, language: string): this;
|
|
99
|
+
configNbWorkers(num: number): this;
|
|
89
100
|
startZimCreation(filepath: string): this;
|
|
90
101
|
addItem(item: WriterItem): Promise<void>;
|
|
91
|
-
addMetadata(
|
|
102
|
+
addMetadata(
|
|
103
|
+
name: string,
|
|
104
|
+
content: string | ContentProvider,
|
|
105
|
+
mimetype?: string
|
|
106
|
+
): void;
|
|
92
107
|
addIllustration(size: number, content: string | ContentProvider): void;
|
|
93
|
-
addRedirection(
|
|
108
|
+
addRedirection(
|
|
109
|
+
path: string,
|
|
110
|
+
title: string,
|
|
111
|
+
targetPath: string,
|
|
112
|
+
hints?: Hint
|
|
113
|
+
): void;
|
|
94
114
|
setMainPath(mainPath: string): void;
|
|
95
115
|
setUuid(uuid: string): void;
|
|
96
|
-
finishZimCreation()
|
|
116
|
+
finishZimCreation(): Promise<void>;
|
|
97
117
|
}
|
|
98
118
|
|
|
99
119
|
export class Item {
|
|
@@ -101,11 +121,11 @@ export class Item {
|
|
|
101
121
|
get path(): string;
|
|
102
122
|
get mimetype(): string;
|
|
103
123
|
get data(): Blob;
|
|
104
|
-
getData(offset?: number | bigint, limit?: number | bigint)
|
|
124
|
+
getData(offset?: number | bigint, limit?: number | bigint): Blob;
|
|
105
125
|
get size(): number | bigint;
|
|
106
126
|
get directAccessInformation(): {
|
|
107
|
-
filename: string
|
|
108
|
-
|
|
127
|
+
filename: string;
|
|
128
|
+
offset: number;
|
|
109
129
|
};
|
|
110
130
|
get index(): number | bigint;
|
|
111
131
|
}
|
|
@@ -115,7 +135,7 @@ export class Entry {
|
|
|
115
135
|
get title(): string;
|
|
116
136
|
get path(): string;
|
|
117
137
|
get item(): Item;
|
|
118
|
-
getItem(followRedirect?: boolean)
|
|
138
|
+
getItem(followRedirect?: boolean): Item;
|
|
119
139
|
get redirect(): Item;
|
|
120
140
|
get redirectEntry(): Entry;
|
|
121
141
|
get index(): number;
|
|
@@ -123,7 +143,7 @@ export class Entry {
|
|
|
123
143
|
|
|
124
144
|
export interface EntryRange extends Iterable<Entry> {
|
|
125
145
|
size: number;
|
|
126
|
-
offset(start: number, maxResults: number)
|
|
146
|
+
offset(start: number, maxResults: number): EntryRange;
|
|
127
147
|
}
|
|
128
148
|
|
|
129
149
|
export class Archive {
|
|
@@ -133,36 +153,37 @@ export class Archive {
|
|
|
133
153
|
get allEntryCount(): number;
|
|
134
154
|
get entryCount(): number;
|
|
135
155
|
get articleCount(): number;
|
|
156
|
+
get mediaCount(): number;
|
|
136
157
|
get uuid(): string;
|
|
137
|
-
getMetadata(name: string)
|
|
138
|
-
getMetadataItem(name: string)
|
|
158
|
+
getMetadata(name: string): string;
|
|
159
|
+
getMetadataItem(name: string): Item;
|
|
139
160
|
get metadataKeys(): string[];
|
|
140
|
-
getIllustrationItem(size: number)
|
|
141
|
-
get illustrationSizes()
|
|
142
|
-
getEntryByPath(path_or_idx: string | number)
|
|
143
|
-
getEntryByTitle(title_or_idx: string | number)
|
|
144
|
-
getEntryByClusterOrder(idx: number)
|
|
161
|
+
getIllustrationItem(size: number): Item;
|
|
162
|
+
get illustrationSizes(): Set<number>;
|
|
163
|
+
getEntryByPath(path_or_idx: string | number): Entry;
|
|
164
|
+
getEntryByTitle(title_or_idx: string | number): Entry;
|
|
165
|
+
getEntryByClusterOrder(idx: number): Entry;
|
|
145
166
|
get mainEntry(): Entry;
|
|
146
167
|
get randomEntry(): Entry;
|
|
147
|
-
hasEntryByPath(path: string)
|
|
148
|
-
hasEntryByTitle(title: string)
|
|
168
|
+
hasEntryByPath(path: string): boolean;
|
|
169
|
+
hasEntryByTitle(title: string): boolean;
|
|
149
170
|
hasMainEntry(): boolean;
|
|
150
|
-
hasIllustration(size: number)
|
|
151
|
-
hasFulltextIndex()
|
|
171
|
+
hasIllustration(size: number): boolean;
|
|
172
|
+
hasFulltextIndex(): boolean;
|
|
152
173
|
hasTitleIndex(): boolean;
|
|
153
|
-
iterByPath()
|
|
154
|
-
iterByTitle()
|
|
155
|
-
iterEfficient()
|
|
156
|
-
findByPath(path: string)
|
|
157
|
-
findByTitle(title: string)
|
|
174
|
+
iterByPath(): EntryRange;
|
|
175
|
+
iterByTitle(): EntryRange;
|
|
176
|
+
iterEfficient(): EntryRange;
|
|
177
|
+
findByPath(path: string): EntryRange;
|
|
178
|
+
findByTitle(title: string): EntryRange;
|
|
158
179
|
get hasChecksum(): boolean;
|
|
159
180
|
get checksum(): string;
|
|
160
|
-
check()
|
|
161
|
-
checkIntegrity(checkType: symbol)
|
|
181
|
+
check(): boolean;
|
|
182
|
+
checkIntegrity(checkType: symbol): boolean; // one of IntegrityCheck
|
|
162
183
|
get isMultiPart(): boolean;
|
|
163
184
|
get hasNewNamespaceScheme(): boolean;
|
|
164
185
|
|
|
165
|
-
static validate(zimPath: string, checksToRun: symbol[])
|
|
186
|
+
static validate(zimPath: string, checksToRun: symbol[]): boolean; // list of IntegrityCheck
|
|
166
187
|
}
|
|
167
188
|
|
|
168
189
|
interface Georange {
|
|
@@ -175,10 +196,10 @@ export class Query {
|
|
|
175
196
|
constructor(query: string);
|
|
176
197
|
setQuery(query: string): this;
|
|
177
198
|
setGeorange(latitude: number, longitude: number, distance: number): this;
|
|
178
|
-
get query()
|
|
199
|
+
get query(): string;
|
|
179
200
|
set query(query: string);
|
|
180
201
|
toString(): string;
|
|
181
|
-
get georange()
|
|
202
|
+
get georange(): Georange;
|
|
182
203
|
set georange(range: Georange);
|
|
183
204
|
}
|
|
184
205
|
|
|
@@ -188,7 +209,6 @@ export class SearchIterator {
|
|
|
188
209
|
get score(): number;
|
|
189
210
|
get snippet(): string;
|
|
190
211
|
get wordCount(): number;
|
|
191
|
-
get size() : number;
|
|
192
212
|
get fileIndex(): number;
|
|
193
213
|
get zimId(): string;
|
|
194
214
|
get entry(): Entry;
|
|
@@ -199,15 +219,15 @@ export interface SearchResultSet extends Iterable<SearchIterator> {
|
|
|
199
219
|
}
|
|
200
220
|
|
|
201
221
|
export class Search {
|
|
202
|
-
getResults(start: number, maxResults: number)
|
|
222
|
+
getResults(start: number, maxResults: number): SearchResultSet;
|
|
203
223
|
get estimatedMatches(): number;
|
|
204
224
|
}
|
|
205
225
|
|
|
206
226
|
export class Searcher {
|
|
207
227
|
constructor(archives: Archive | Archive[]);
|
|
208
228
|
addArchive(archive: Archive): this;
|
|
209
|
-
search(query: string | Query)
|
|
210
|
-
setVerbose(verbose: boolean)
|
|
229
|
+
search(query: string | Query): Search;
|
|
230
|
+
setVerbose(verbose: boolean): this;
|
|
211
231
|
}
|
|
212
232
|
|
|
213
233
|
export class SuggestionIterator {
|
|
@@ -223,12 +243,12 @@ export interface SuggestionResultSet extends Iterable<SuggestionIterator> {
|
|
|
223
243
|
}
|
|
224
244
|
|
|
225
245
|
export class SuggestionSearch {
|
|
226
|
-
getResults(start: number, maxResults: number)
|
|
246
|
+
getResults(start: number, maxResults: number): SuggestionResultSet;
|
|
227
247
|
get estimatedMatches(): number;
|
|
228
248
|
}
|
|
229
249
|
|
|
230
250
|
export class SuggestionSearcher {
|
|
231
251
|
constructor(archives: Archive);
|
|
232
252
|
suggest(query: string): SuggestionSearch;
|
|
233
|
-
setVerbose(verbose: boolean)
|
|
253
|
+
setVerbose(verbose: boolean): this;
|
|
234
254
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
const bindings = require('bindings');
|
|
1
|
+
import bindings from "bindings";
|
|
3
2
|
|
|
4
3
|
const {
|
|
5
4
|
Archive,
|
|
@@ -15,7 +14,7 @@ const {
|
|
|
15
14
|
FileProvider,
|
|
16
15
|
StringItem,
|
|
17
16
|
FileItem,
|
|
18
|
-
} = bindings(
|
|
17
|
+
} = bindings("zim_binding");
|
|
19
18
|
|
|
20
19
|
module.exports = {
|
|
21
20
|
Archive,
|
|
@@ -31,4 +30,4 @@ module.exports = {
|
|
|
31
30
|
FileProvider,
|
|
32
31
|
StringItem,
|
|
33
32
|
FileItem,
|
|
34
|
-
}
|
|
33
|
+
};
|
package/download-libzim.js
CHANGED
|
@@ -1,74 +1,81 @@
|
|
|
1
|
-
require(
|
|
2
|
-
const axios = require(
|
|
3
|
-
const mkdirp = require(
|
|
4
|
-
const exec = require(
|
|
5
|
-
const os = require(
|
|
6
|
-
const fs = require(
|
|
7
|
-
const urlParser = require(
|
|
1
|
+
require("dotenv").config();
|
|
2
|
+
const axios = require("axios");
|
|
3
|
+
const mkdirp = require("mkdirp");
|
|
4
|
+
const exec = require("exec-then");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const urlParser = require("url");
|
|
8
8
|
|
|
9
|
-
mkdirp.sync(
|
|
9
|
+
mkdirp.sync("./download");
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const
|
|
11
|
+
console.info("os.type() is:", os.type());
|
|
12
|
+
console.info("os.arch() is:", os.arch());
|
|
13
|
+
const isMacOS = os.type() === "Darwin";
|
|
14
|
+
const isLinux = os.type() === "Linux";
|
|
15
|
+
const rawArch = os.arch();
|
|
16
|
+
|
|
17
|
+
const isAvailableArch =
|
|
18
|
+
rawArch === "x64" || rawArch === "arm" || rawArch === "arm64";
|
|
15
19
|
|
|
16
20
|
if (!isMacOS && !isLinux) {
|
|
17
|
-
|
|
21
|
+
console.warn(
|
|
22
|
+
`\x1b[41m\n================================ README \n\nPre-built binaries only available on Linux and MacOS for now...\nPlease ensure you have libzim installed globally on this machine:\n\n\thttps://github.com/openzim/libzim/\n\n================================\x1b[0m\n`
|
|
23
|
+
);
|
|
18
24
|
}
|
|
19
25
|
if (!isAvailableArch) {
|
|
20
|
-
|
|
26
|
+
console.warn(
|
|
27
|
+
`\x1b[41m\n================================ README \n\nPre-built binaries only available on x86_64, arm and arm64 for now...\nPlease ensure you have libzim installed globally on this machine:\n\n\thttps://github.com/openzim/libzim/\n\n================================\x1b[0m\n`
|
|
28
|
+
);
|
|
21
29
|
}
|
|
22
30
|
|
|
23
|
-
let osPrefix =
|
|
24
|
-
let osArch =
|
|
31
|
+
let osPrefix = isMacOS ? "macos" : "linux";
|
|
32
|
+
let osArch = isLinux ? "x86_64-bionic" : "x86_64";
|
|
25
33
|
|
|
26
|
-
if (rawArch
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
if (rawArch !== "x64") {
|
|
35
|
+
if (isLinux) {
|
|
36
|
+
osArch = rawArch === "arm64" ? "aarch64-bionic" : "armhf";
|
|
37
|
+
} else {
|
|
38
|
+
osArch = rawArch;
|
|
39
|
+
}
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
const urls = [
|
|
35
|
-
|
|
36
|
-
].filter(a => a);
|
|
43
|
+
`https://download.openzim.org/release/libzim/libzim_${osPrefix}-${osArch}-${process.env.LIBZIM_VERSION}.tar.gz`,
|
|
44
|
+
].filter((a) => a);
|
|
37
45
|
|
|
38
46
|
for (let url of urls) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
console.info(`Downloading Libzim from: `, url);
|
|
48
|
+
const filename = urlParser.parse(url).pathname.split("/").slice(-1)[0];
|
|
49
|
+
const dlFile = `./download/${filename}`;
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
51
|
+
try {
|
|
52
|
+
fs.statSync(dlFile);
|
|
53
|
+
console.warn(`File [${dlFile}] already exists, not downloading`);
|
|
54
|
+
return;
|
|
55
|
+
} catch (err) {
|
|
56
|
+
//
|
|
57
|
+
}
|
|
48
58
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
axios({
|
|
60
|
+
url,
|
|
61
|
+
method: "get",
|
|
62
|
+
responseType: "stream",
|
|
63
|
+
})
|
|
64
|
+
.then(function (response) {
|
|
65
|
+
const ws = fs.createWriteStream(dlFile);
|
|
66
|
+
return new Promise((resolve, reject) => {
|
|
67
|
+
response.data.pipe(ws).on("error", reject).on("close", resolve);
|
|
68
|
+
});
|
|
69
|
+
})
|
|
70
|
+
.then(() => {
|
|
71
|
+
const cmd = `tar --strip-components 1 -xf ${dlFile} -C ./download`;
|
|
72
|
+
console.log(`Running Extract:`, `[${cmd}]`);
|
|
73
|
+
return exec(cmd);
|
|
74
|
+
})
|
|
75
|
+
.then(() => {
|
|
76
|
+
console.info(`Successfully downloaded and extracted file`);
|
|
53
77
|
})
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
response.data
|
|
58
|
-
.pipe(ws)
|
|
59
|
-
.on('error', reject)
|
|
60
|
-
.on('close', resolve);
|
|
61
|
-
});
|
|
62
|
-
})
|
|
63
|
-
.then(() => {
|
|
64
|
-
const cmd = `tar --strip-components 1 -xf ${dlFile} -C ./download`;
|
|
65
|
-
console.log(`Running Extract:`, `[${cmd}]`);
|
|
66
|
-
return exec(cmd);
|
|
67
|
-
})
|
|
68
|
-
.then(() => {
|
|
69
|
-
console.info(`Successfully downloaded and extracted file`);
|
|
70
|
-
})
|
|
71
|
-
.catch(err => {
|
|
72
|
-
console.error(`Failed to download and extract file:`, err);
|
|
73
|
-
});
|
|
78
|
+
.catch((err) => {
|
|
79
|
+
console.error(`Failed to download and extract file:`, err);
|
|
80
|
+
});
|
|
74
81
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@openzim/libzim",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
4
|
"types": "dist/index.d.js",
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.2.0",
|
|
6
6
|
"description": "Libzim bindings for NodeJS",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"clean": "rm -rf dist build/native/build",
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
"download": "node ./download-libzim.js",
|
|
15
15
|
"bundle": "node ./bundle-libzim.js",
|
|
16
16
|
"test": "jest",
|
|
17
|
-
"test-mem-leak": "node -r ts-node/register test/makeLargeZim.ts"
|
|
17
|
+
"test-mem-leak": "node -r ts-node/register test/makeLargeZim.ts",
|
|
18
|
+
"lint": "npx eslint .",
|
|
19
|
+
"lint:fix": "npx eslint . --fix"
|
|
18
20
|
},
|
|
19
21
|
"nyc": {
|
|
20
22
|
"extension": [
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
"@types/bindings": "^1.5.1",
|
|
41
43
|
"@types/jest": "^28.1.6",
|
|
42
44
|
"@types/node": "^18.0.6",
|
|
43
|
-
"axios": "^
|
|
45
|
+
"axios": "^1.6.0",
|
|
44
46
|
"bindings": "^1.5.0",
|
|
45
47
|
"dotenv": "^16.0.1",
|
|
46
48
|
"exec-then": "^1.3.1",
|
|
@@ -53,8 +55,14 @@
|
|
|
53
55
|
},
|
|
54
56
|
"devDependencies": {
|
|
55
57
|
"@faker-js/faker": "^7.6.0",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
|
59
|
+
"@typescript-eslint/parser": "^5.59.2",
|
|
60
|
+
"eslint": "^8.39.0",
|
|
61
|
+
"eslint-config-prettier": "^8.8.0",
|
|
62
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
56
63
|
"jest": "^28.1.3",
|
|
57
64
|
"nyc": "^15.1.0",
|
|
65
|
+
"prettier": "^2.8.8",
|
|
58
66
|
"ts-jest": "^28.0.7",
|
|
59
67
|
"typescript": "^4.7.4"
|
|
60
68
|
},
|
package/src/archive.h
CHANGED
|
@@ -69,6 +69,14 @@ class Archive : public Napi::ObjectWrap<Archive> {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
Napi::Value getMediaCount(const Napi::CallbackInfo &info) {
|
|
73
|
+
try {
|
|
74
|
+
return Napi::Value::From(info.Env(), archive_->getMediaCount());
|
|
75
|
+
} catch (const std::exception &err) {
|
|
76
|
+
throw Napi::Error::New(info.Env(), err.what());
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
72
80
|
Napi::Value getUuid(const Napi::CallbackInfo &info) {
|
|
73
81
|
try {
|
|
74
82
|
// TODO(kelvinhammond): convert this to
|
|
@@ -446,6 +454,7 @@ class Archive : public Napi::ObjectWrap<Archive> {
|
|
|
446
454
|
InstanceAccessor<&Archive::getAllEntryCount>("allEntryCount"),
|
|
447
455
|
InstanceAccessor<&Archive::getEntryCount>("entryCount"),
|
|
448
456
|
InstanceAccessor<&Archive::getArticleCount>("articleCount"),
|
|
457
|
+
InstanceAccessor<&Archive::getMediaCount>("mediaCount"),
|
|
449
458
|
InstanceAccessor<&Archive::getUuid>("uuid"),
|
|
450
459
|
InstanceMethod<&Archive::getMetadata>("getMetadata"),
|
|
451
460
|
InstanceMethod<&Archive::getMetadataItem>("getMetadataItem"),
|
package/src/blob.h
CHANGED
|
@@ -29,17 +29,20 @@ class Blob : public Napi::ObjectWrap<Blob> {
|
|
|
29
29
|
if (info[0].IsArrayBuffer()) { // handle ArrayBuffer
|
|
30
30
|
auto buf = info[0].As<Napi::ArrayBuffer>();
|
|
31
31
|
size = buf.ByteLength();
|
|
32
|
-
data = std::shared_ptr<char>(new char[size]
|
|
32
|
+
data = std::shared_ptr<char>(new char[size],
|
|
33
|
+
std::default_delete<char[]>());
|
|
33
34
|
memcpy(data.get(), buf.Data(), size);
|
|
34
35
|
} else if (info[0].IsBuffer()) { // handle Buffer
|
|
35
36
|
auto buf = info[0].As<Napi::Buffer<char>>();
|
|
36
37
|
size = buf.Length();
|
|
37
|
-
data = std::shared_ptr<char>(new char[size]
|
|
38
|
+
data = std::shared_ptr<char>(new char[size],
|
|
39
|
+
std::default_delete<char[]>());
|
|
38
40
|
memcpy(data.get(), buf.Data(), size);
|
|
39
41
|
} else { // all others toString()
|
|
40
42
|
auto str = info[0].ToString().Utf8Value(); // coerce to string
|
|
41
43
|
size = str.size();
|
|
42
|
-
data = std::shared_ptr<char>(new char[size]
|
|
44
|
+
data = std::shared_ptr<char>(new char[size],
|
|
45
|
+
std::default_delete<char[]>());
|
|
43
46
|
memcpy(data.get(), str.c_str(), size);
|
|
44
47
|
}
|
|
45
48
|
|
package/src/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
export class IntegrityCheck {
|
|
3
2
|
static CHECKSUM: symbol;
|
|
4
3
|
static DIRENT_PTRS: symbol;
|
|
@@ -6,7 +5,7 @@ export class IntegrityCheck {
|
|
|
6
5
|
static TITLE_INDEX: symbol;
|
|
7
6
|
static CLUSTER_PTRS: symbol;
|
|
8
7
|
static DIRENT_MIMETYPES: symbol;
|
|
9
|
-
static COUNT: symbol;
|
|
8
|
+
static COUNT: symbol; // DO NOT USE THIS. See libzim docs.
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
export class Compression {
|
|
@@ -23,25 +22,25 @@ export class Blob {
|
|
|
23
22
|
|
|
24
23
|
export type ContentProvider = {
|
|
25
24
|
size: number | bigint;
|
|
26
|
-
feed()
|
|
27
|
-
}
|
|
25
|
+
feed(): Blob;
|
|
26
|
+
};
|
|
28
27
|
|
|
29
28
|
export class StringProvider {
|
|
30
29
|
constructor(content: string);
|
|
31
30
|
get size(): number;
|
|
32
|
-
feed()
|
|
31
|
+
feed(): Blob;
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
export class FileProvider {
|
|
36
35
|
constructor(filepath: string);
|
|
37
36
|
get size(): number | bigint;
|
|
38
|
-
feed()
|
|
37
|
+
feed(): Blob;
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
export type Hint = {
|
|
42
41
|
COMPRESS?: number;
|
|
43
42
|
FRONT_ARTICLE?: number;
|
|
44
|
-
}
|
|
43
|
+
};
|
|
45
44
|
|
|
46
45
|
export interface IndexData {
|
|
47
46
|
hasIndexData?: boolean;
|
|
@@ -56,44 +55,65 @@ export interface WriterItem {
|
|
|
56
55
|
path: string;
|
|
57
56
|
title: string;
|
|
58
57
|
mimeType: string;
|
|
59
|
-
getContentProvider()
|
|
58
|
+
getContentProvider(): ContentProvider;
|
|
60
59
|
hints: Hint;
|
|
61
60
|
getIndexData?: () => IndexData;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
export class StringItem {
|
|
65
|
-
constructor(
|
|
64
|
+
constructor(
|
|
65
|
+
path: string,
|
|
66
|
+
mimeType: string,
|
|
67
|
+
title: string,
|
|
68
|
+
hint: Hint,
|
|
69
|
+
content: ArrayBuffer | Buffer | string
|
|
70
|
+
);
|
|
66
71
|
readonly path: string;
|
|
67
72
|
readonly title: string;
|
|
68
73
|
readonly mimeType: string;
|
|
69
|
-
getContentProvider()
|
|
74
|
+
getContentProvider(): StringProvider;
|
|
70
75
|
readonly hints: Hint;
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
export class FileItem {
|
|
74
|
-
constructor(
|
|
79
|
+
constructor(
|
|
80
|
+
path: string,
|
|
81
|
+
mimeType: string,
|
|
82
|
+
title: string,
|
|
83
|
+
hints: Hint,
|
|
84
|
+
filePath: string
|
|
85
|
+
);
|
|
75
86
|
readonly path: string;
|
|
76
87
|
readonly title: string;
|
|
77
88
|
readonly mimeType: string;
|
|
78
|
-
getContentProvider()
|
|
89
|
+
getContentProvider(): StringProvider;
|
|
79
90
|
readonly hints: Hint;
|
|
80
91
|
}
|
|
81
92
|
|
|
82
93
|
export class Creator {
|
|
83
94
|
constructor();
|
|
84
|
-
configVerbose(verbose: boolean)
|
|
85
|
-
configCompression(value: Compression)
|
|
86
|
-
configClusterSize(size: number)
|
|
87
|
-
configIndexing(indexing: boolean, language: string)
|
|
88
|
-
configNbWorkers(num: number)
|
|
95
|
+
configVerbose(verbose: boolean): this;
|
|
96
|
+
configCompression(value: Compression): this;
|
|
97
|
+
configClusterSize(size: number): this;
|
|
98
|
+
configIndexing(indexing: boolean, language: string): this;
|
|
99
|
+
configNbWorkers(num: number): this;
|
|
89
100
|
startZimCreation(filepath: string): this;
|
|
90
101
|
addItem(item: WriterItem): Promise<void>;
|
|
91
|
-
addMetadata(
|
|
102
|
+
addMetadata(
|
|
103
|
+
name: string,
|
|
104
|
+
content: string | ContentProvider,
|
|
105
|
+
mimetype?: string
|
|
106
|
+
): void;
|
|
92
107
|
addIllustration(size: number, content: string | ContentProvider): void;
|
|
93
|
-
addRedirection(
|
|
108
|
+
addRedirection(
|
|
109
|
+
path: string,
|
|
110
|
+
title: string,
|
|
111
|
+
targetPath: string,
|
|
112
|
+
hints?: Hint
|
|
113
|
+
): void;
|
|
94
114
|
setMainPath(mainPath: string): void;
|
|
95
115
|
setUuid(uuid: string): void;
|
|
96
|
-
finishZimCreation()
|
|
116
|
+
finishZimCreation(): Promise<void>;
|
|
97
117
|
}
|
|
98
118
|
|
|
99
119
|
export class Item {
|
|
@@ -101,11 +121,11 @@ export class Item {
|
|
|
101
121
|
get path(): string;
|
|
102
122
|
get mimetype(): string;
|
|
103
123
|
get data(): Blob;
|
|
104
|
-
getData(offset?: number | bigint, limit?: number | bigint)
|
|
124
|
+
getData(offset?: number | bigint, limit?: number | bigint): Blob;
|
|
105
125
|
get size(): number | bigint;
|
|
106
126
|
get directAccessInformation(): {
|
|
107
|
-
filename: string
|
|
108
|
-
|
|
127
|
+
filename: string;
|
|
128
|
+
offset: number;
|
|
109
129
|
};
|
|
110
130
|
get index(): number | bigint;
|
|
111
131
|
}
|
|
@@ -115,7 +135,7 @@ export class Entry {
|
|
|
115
135
|
get title(): string;
|
|
116
136
|
get path(): string;
|
|
117
137
|
get item(): Item;
|
|
118
|
-
getItem(followRedirect?: boolean)
|
|
138
|
+
getItem(followRedirect?: boolean): Item;
|
|
119
139
|
get redirect(): Item;
|
|
120
140
|
get redirectEntry(): Entry;
|
|
121
141
|
get index(): number;
|
|
@@ -123,7 +143,7 @@ export class Entry {
|
|
|
123
143
|
|
|
124
144
|
export interface EntryRange extends Iterable<Entry> {
|
|
125
145
|
size: number;
|
|
126
|
-
offset(start: number, maxResults: number)
|
|
146
|
+
offset(start: number, maxResults: number): EntryRange;
|
|
127
147
|
}
|
|
128
148
|
|
|
129
149
|
export class Archive {
|
|
@@ -133,36 +153,37 @@ export class Archive {
|
|
|
133
153
|
get allEntryCount(): number;
|
|
134
154
|
get entryCount(): number;
|
|
135
155
|
get articleCount(): number;
|
|
156
|
+
get mediaCount(): number;
|
|
136
157
|
get uuid(): string;
|
|
137
|
-
getMetadata(name: string)
|
|
138
|
-
getMetadataItem(name: string)
|
|
158
|
+
getMetadata(name: string): string;
|
|
159
|
+
getMetadataItem(name: string): Item;
|
|
139
160
|
get metadataKeys(): string[];
|
|
140
|
-
getIllustrationItem(size: number)
|
|
141
|
-
get illustrationSizes()
|
|
142
|
-
getEntryByPath(path_or_idx: string | number)
|
|
143
|
-
getEntryByTitle(title_or_idx: string | number)
|
|
144
|
-
getEntryByClusterOrder(idx: number)
|
|
161
|
+
getIllustrationItem(size: number): Item;
|
|
162
|
+
get illustrationSizes(): Set<number>;
|
|
163
|
+
getEntryByPath(path_or_idx: string | number): Entry;
|
|
164
|
+
getEntryByTitle(title_or_idx: string | number): Entry;
|
|
165
|
+
getEntryByClusterOrder(idx: number): Entry;
|
|
145
166
|
get mainEntry(): Entry;
|
|
146
167
|
get randomEntry(): Entry;
|
|
147
|
-
hasEntryByPath(path: string)
|
|
148
|
-
hasEntryByTitle(title: string)
|
|
168
|
+
hasEntryByPath(path: string): boolean;
|
|
169
|
+
hasEntryByTitle(title: string): boolean;
|
|
149
170
|
hasMainEntry(): boolean;
|
|
150
|
-
hasIllustration(size: number)
|
|
151
|
-
hasFulltextIndex()
|
|
171
|
+
hasIllustration(size: number): boolean;
|
|
172
|
+
hasFulltextIndex(): boolean;
|
|
152
173
|
hasTitleIndex(): boolean;
|
|
153
|
-
iterByPath()
|
|
154
|
-
iterByTitle()
|
|
155
|
-
iterEfficient()
|
|
156
|
-
findByPath(path: string)
|
|
157
|
-
findByTitle(title: string)
|
|
174
|
+
iterByPath(): EntryRange;
|
|
175
|
+
iterByTitle(): EntryRange;
|
|
176
|
+
iterEfficient(): EntryRange;
|
|
177
|
+
findByPath(path: string): EntryRange;
|
|
178
|
+
findByTitle(title: string): EntryRange;
|
|
158
179
|
get hasChecksum(): boolean;
|
|
159
180
|
get checksum(): string;
|
|
160
|
-
check()
|
|
161
|
-
checkIntegrity(checkType: symbol)
|
|
181
|
+
check(): boolean;
|
|
182
|
+
checkIntegrity(checkType: symbol): boolean; // one of IntegrityCheck
|
|
162
183
|
get isMultiPart(): boolean;
|
|
163
184
|
get hasNewNamespaceScheme(): boolean;
|
|
164
185
|
|
|
165
|
-
static validate(zimPath: string, checksToRun: symbol[])
|
|
186
|
+
static validate(zimPath: string, checksToRun: symbol[]): boolean; // list of IntegrityCheck
|
|
166
187
|
}
|
|
167
188
|
|
|
168
189
|
interface Georange {
|
|
@@ -175,10 +196,10 @@ export class Query {
|
|
|
175
196
|
constructor(query: string);
|
|
176
197
|
setQuery(query: string): this;
|
|
177
198
|
setGeorange(latitude: number, longitude: number, distance: number): this;
|
|
178
|
-
get query()
|
|
199
|
+
get query(): string;
|
|
179
200
|
set query(query: string);
|
|
180
201
|
toString(): string;
|
|
181
|
-
get georange()
|
|
202
|
+
get georange(): Georange;
|
|
182
203
|
set georange(range: Georange);
|
|
183
204
|
}
|
|
184
205
|
|
|
@@ -188,7 +209,6 @@ export class SearchIterator {
|
|
|
188
209
|
get score(): number;
|
|
189
210
|
get snippet(): string;
|
|
190
211
|
get wordCount(): number;
|
|
191
|
-
get size() : number;
|
|
192
212
|
get fileIndex(): number;
|
|
193
213
|
get zimId(): string;
|
|
194
214
|
get entry(): Entry;
|
|
@@ -199,15 +219,15 @@ export interface SearchResultSet extends Iterable<SearchIterator> {
|
|
|
199
219
|
}
|
|
200
220
|
|
|
201
221
|
export class Search {
|
|
202
|
-
getResults(start: number, maxResults: number)
|
|
222
|
+
getResults(start: number, maxResults: number): SearchResultSet;
|
|
203
223
|
get estimatedMatches(): number;
|
|
204
224
|
}
|
|
205
225
|
|
|
206
226
|
export class Searcher {
|
|
207
227
|
constructor(archives: Archive | Archive[]);
|
|
208
228
|
addArchive(archive: Archive): this;
|
|
209
|
-
search(query: string | Query)
|
|
210
|
-
setVerbose(verbose: boolean)
|
|
229
|
+
search(query: string | Query): Search;
|
|
230
|
+
setVerbose(verbose: boolean): this;
|
|
211
231
|
}
|
|
212
232
|
|
|
213
233
|
export class SuggestionIterator {
|
|
@@ -223,12 +243,12 @@ export interface SuggestionResultSet extends Iterable<SuggestionIterator> {
|
|
|
223
243
|
}
|
|
224
244
|
|
|
225
245
|
export class SuggestionSearch {
|
|
226
|
-
getResults(start: number, maxResults: number)
|
|
246
|
+
getResults(start: number, maxResults: number): SuggestionResultSet;
|
|
227
247
|
get estimatedMatches(): number;
|
|
228
248
|
}
|
|
229
249
|
|
|
230
250
|
export class SuggestionSearcher {
|
|
231
251
|
constructor(archives: Archive);
|
|
232
252
|
suggest(query: string): SuggestionSearch;
|
|
233
|
-
setVerbose(verbose: boolean)
|
|
253
|
+
setVerbose(verbose: boolean): this;
|
|
234
254
|
}
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
const bindings = require('bindings');
|
|
1
|
+
import bindings from "bindings";
|
|
3
2
|
|
|
4
3
|
const {
|
|
5
4
|
Archive,
|
|
@@ -15,7 +14,7 @@ const {
|
|
|
15
14
|
FileProvider,
|
|
16
15
|
StringItem,
|
|
17
16
|
FileItem,
|
|
18
|
-
} = bindings(
|
|
17
|
+
} = bindings("zim_binding");
|
|
19
18
|
|
|
20
19
|
module.exports = {
|
|
21
20
|
Archive,
|
|
@@ -31,4 +30,4 @@ module.exports = {
|
|
|
31
30
|
FileProvider,
|
|
32
31
|
StringItem,
|
|
33
32
|
FileItem,
|
|
34
|
-
}
|
|
33
|
+
};
|
package/src/search.h
CHANGED
|
@@ -200,14 +200,6 @@ class SearchIterator : public Napi::ObjectWrap<SearchIterator> {
|
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
Napi::Value getSize(const Napi::CallbackInfo &info) {
|
|
204
|
-
try {
|
|
205
|
-
return Napi::Value::From(info.Env(), searchIterator_.getSize());
|
|
206
|
-
} catch (const std::exception &err) {
|
|
207
|
-
throw Napi::Error::New(info.Env(), err.what());
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
203
|
Napi::Value getFileIndex(const Napi::CallbackInfo &info) {
|
|
212
204
|
try {
|
|
213
205
|
return Napi::Value::From(info.Env(), searchIterator_.getFileIndex());
|
|
@@ -250,7 +242,6 @@ class SearchIterator : public Napi::ObjectWrap<SearchIterator> {
|
|
|
250
242
|
InstanceAccessor<&SearchIterator::getScore>("score"),
|
|
251
243
|
InstanceAccessor<&SearchIterator::getSnippet>("snippet"),
|
|
252
244
|
InstanceAccessor<&SearchIterator::getWordCount>("wordCount"),
|
|
253
|
-
InstanceAccessor<&SearchIterator::getSize>("size"),
|
|
254
245
|
InstanceAccessor<&SearchIterator::getFileIndex>("fileIndex"),
|
|
255
246
|
InstanceAccessor<&SearchIterator::getZimId>("zimId"),
|
|
256
247
|
InstanceAccessor<&SearchIterator::getEntry>("entry"),
|
package/src/writerItem.h
CHANGED
|
@@ -262,7 +262,22 @@ class StringItem : public Napi::ObjectWrap<StringItem> {
|
|
|
262
262
|
auto mimetype = info[1].ToString().Utf8Value();
|
|
263
263
|
auto title = info[2].ToString().Utf8Value();
|
|
264
264
|
auto hints = Object2Hints(info[3].ToObject());
|
|
265
|
-
|
|
265
|
+
|
|
266
|
+
const auto &&cval = info[4];
|
|
267
|
+
std::string content;
|
|
268
|
+
|
|
269
|
+
if (cval.IsArrayBuffer()) { // handle ArrayBuffer
|
|
270
|
+
auto buf = cval.As<Napi::ArrayBuffer>();
|
|
271
|
+
auto size = buf.ByteLength();
|
|
272
|
+
content = std::string(reinterpret_cast<const char *>(buf.Data()), size);
|
|
273
|
+
} else if (cval.IsBuffer()) { // handle Buffer
|
|
274
|
+
auto buf = cval.As<Napi::Buffer<char>>();
|
|
275
|
+
auto size = buf.Length();
|
|
276
|
+
content = std::string(reinterpret_cast<const char *>(buf.Data()), size);
|
|
277
|
+
} else {
|
|
278
|
+
content = cval.ToString().Utf8Value();
|
|
279
|
+
}
|
|
280
|
+
|
|
266
281
|
item_ = zim::writer::StringItem::create(path, mimetype, title, hints,
|
|
267
282
|
content);
|
|
268
283
|
} catch (const std::exception &e) {
|