@helloao/cli 0.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/actions.d.ts +57 -0
- package/actions.js +262 -0
- package/cli.d.ts +2 -0
- package/cli.js +139 -0
- package/db.d.ts +110 -0
- package/db.js +754 -0
- package/downloads.d.ts +2 -0
- package/downloads.js +12 -0
- package/files.d.ts +56 -0
- package/files.js +232 -0
- package/index.d.ts +8 -0
- package/index.js +38 -0
- package/migrations/20240420231455_initial/migration.sql +66 -0
- package/migrations/20240623183848_add_book_order/migration.sql +26 -0
- package/migrations/20240629194121_add_chapter_links/migration.sql +45 -0
- package/migrations/20240629194513_add_chapter_content/migration.sql +30 -0
- package/migrations/20240705221833_remove_unused_columns/migration.sql +27 -0
- package/migrations/20240711173108_add_chapter_audio/migration.sql +13 -0
- package/migrations/20240724212651_add_hashing/migration.sql +25 -0
- package/node_modules/@zip.js/zip.js/LICENSE +28 -0
- package/node_modules/@zip.js/zip.js/README.md +173 -0
- package/node_modules/@zip.js/zip.js/deno.json +8 -0
- package/node_modules/@zip.js/zip.js/dist/README.md +28 -0
- package/node_modules/@zip.js/zip.js/dist/z-worker-fflate.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/z-worker-pako.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/z-worker.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-fs-full.js +11935 -0
- package/node_modules/@zip.js/zip.js/dist/zip-fs-full.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-fs.js +6079 -0
- package/node_modules/@zip.js/zip.js/dist/zip-fs.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-full.js +9463 -0
- package/node_modules/@zip.js/zip.js/dist/zip-full.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-no-worker-deflate.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-no-worker-inflate.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-no-worker.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip.js +5240 -0
- package/node_modules/@zip.js/zip.js/dist/zip.min.js +1 -0
- package/node_modules/@zip.js/zip.js/index-fflate.js +82 -0
- package/node_modules/@zip.js/zip.js/index.cjs +11927 -0
- package/node_modules/@zip.js/zip.js/index.d.ts +2048 -0
- package/node_modules/@zip.js/zip.js/index.js +87 -0
- package/node_modules/@zip.js/zip.js/index.min.js +1 -0
- package/node_modules/@zip.js/zip.js/lib/core/codec-pool.js +127 -0
- package/node_modules/@zip.js/zip.js/lib/core/codec-worker.js +348 -0
- package/node_modules/@zip.js/zip.js/lib/core/configuration.js +127 -0
- package/node_modules/@zip.js/zip.js/lib/core/constants.js +114 -0
- package/node_modules/@zip.js/zip.js/lib/core/io.js +749 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/aes-crypto-stream.js +326 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/codec-stream.js +154 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/codecs/crc32.js +63 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/codecs/deflate.js +2063 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/codecs/inflate.js +2167 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/codecs/sjcl.js +827 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/common-crypto.js +55 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/crc32-stream.js +56 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/stream-adapter.js +55 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/zip-crypto-stream.js +162 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/zip-entry-stream.js +165 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/cp437-decode.js +48 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/decode-text.js +43 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/default-mime-type.js +38 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/encode-text.js +48 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/mime-type.js +1639 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/stream-codec-shim.js +91 -0
- package/node_modules/@zip.js/zip.js/lib/core/z-worker-core.js +176 -0
- package/node_modules/@zip.js/zip.js/lib/core/zip-entry.js +86 -0
- package/node_modules/@zip.js/zip.js/lib/core/zip-fs-core.js +865 -0
- package/node_modules/@zip.js/zip.js/lib/core/zip-reader.js +757 -0
- package/node_modules/@zip.js/zip.js/lib/core/zip-writer.js +1186 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker-bootstrap-fflate.js +40 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker-bootstrap-pako.js +39 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker-fflate.js +40 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker-inline-template.js +42 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker-inline.js +1 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker.js +38 -0
- package/node_modules/@zip.js/zip.js/lib/zip-data-uri.js +53 -0
- package/node_modules/@zip.js/zip.js/lib/zip-fflate-shim.js +37 -0
- package/node_modules/@zip.js/zip.js/lib/zip-fs.js +53 -0
- package/node_modules/@zip.js/zip.js/lib/zip-full-fflate.js +53 -0
- package/node_modules/@zip.js/zip.js/lib/zip-full.js +54 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker-deflate.js +42 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker-fflate-deflate.js +42 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker-fflate-inflate.js +42 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker-fflate.js +43 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker-inflate.js +42 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker.js +44 -0
- package/node_modules/@zip.js/zip.js/lib/zip.js +52 -0
- package/node_modules/@zip.js/zip.js/package.json +86 -0
- package/package.json +43 -0
- package/prisma-gen/default.d.ts +1 -0
- package/prisma-gen/default.js +1 -0
- package/prisma-gen/edge.d.ts +1 -0
- package/prisma-gen/edge.js +242 -0
- package/prisma-gen/index-browser.js +236 -0
- package/prisma-gen/index.d.ts +13248 -0
- package/prisma-gen/index.js +265 -0
- package/prisma-gen/runtime/edge-esm.js +28 -0
- package/prisma-gen/runtime/edge.js +28 -0
- package/prisma-gen/runtime/index-browser.d.ts +365 -0
- package/prisma-gen/runtime/index-browser.js +13 -0
- package/prisma-gen/runtime/library.d.ts +3168 -0
- package/prisma-gen/runtime/library.js +140 -0
- package/prisma-gen/runtime/wasm.js +29 -0
- package/prisma-gen/wasm.d.ts +1 -0
- package/prisma-gen/wasm.js +236 -0
- package/s3.d.ts +14 -0
- package/s3.js +76 -0
- package/schema.prisma +154 -0
- package/uploads.d.ts +54 -0
- package/uploads.js +141 -0
|
@@ -0,0 +1,865 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
8
|
+
this list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
11
|
+
notice, this list of conditions and the following disclaimer in
|
|
12
|
+
the documentation and/or other materials provided with the distribution.
|
|
13
|
+
|
|
14
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
15
|
+
derived from this software without specific prior written permission.
|
|
16
|
+
|
|
17
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
18
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
20
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
21
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
22
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
23
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
24
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
25
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
26
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/* global WritableStream */
|
|
30
|
+
// deno-lint-ignore-file no-this-alias
|
|
31
|
+
|
|
32
|
+
import {
|
|
33
|
+
initStream,
|
|
34
|
+
Reader,
|
|
35
|
+
TextReader,
|
|
36
|
+
TextWriter,
|
|
37
|
+
Data64URIReader,
|
|
38
|
+
Data64URIWriter,
|
|
39
|
+
Uint8ArrayReader,
|
|
40
|
+
Uint8ArrayWriter,
|
|
41
|
+
BlobReader,
|
|
42
|
+
BlobWriter,
|
|
43
|
+
HttpReader
|
|
44
|
+
} from "./io.js";
|
|
45
|
+
import {
|
|
46
|
+
ZipReader,
|
|
47
|
+
ERR_INVALID_PASSWORD
|
|
48
|
+
} from "./zip-reader.js";
|
|
49
|
+
import {
|
|
50
|
+
ZipWriter
|
|
51
|
+
} from "./zip-writer.js";
|
|
52
|
+
import {
|
|
53
|
+
Entry
|
|
54
|
+
} from "./zip-entry.js";
|
|
55
|
+
import { UNDEFINED_VALUE } from "./constants.js";
|
|
56
|
+
|
|
57
|
+
class ZipEntry {
|
|
58
|
+
|
|
59
|
+
constructor(fs, name, params, parent) {
|
|
60
|
+
const zipEntry = this;
|
|
61
|
+
if (fs.root && parent && parent.getChildByName(name)) {
|
|
62
|
+
throw new Error("Entry filename already exists");
|
|
63
|
+
}
|
|
64
|
+
if (!params) {
|
|
65
|
+
params = {};
|
|
66
|
+
}
|
|
67
|
+
Object.assign(zipEntry, {
|
|
68
|
+
fs,
|
|
69
|
+
name,
|
|
70
|
+
data: params.data,
|
|
71
|
+
options: params.options,
|
|
72
|
+
id: fs.entries.length,
|
|
73
|
+
parent,
|
|
74
|
+
children: [],
|
|
75
|
+
uncompressedSize: params.uncompressedSize || 0
|
|
76
|
+
});
|
|
77
|
+
fs.entries.push(zipEntry);
|
|
78
|
+
if (parent) {
|
|
79
|
+
zipEntry.parent.children.push(zipEntry);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
moveTo(target) {
|
|
84
|
+
// deprecated
|
|
85
|
+
const zipEntry = this;
|
|
86
|
+
zipEntry.fs.move(zipEntry, target);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
getFullname() {
|
|
90
|
+
return this.getRelativeName();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
getRelativeName(ancestor = this.fs.root) {
|
|
94
|
+
const zipEntry = this;
|
|
95
|
+
let relativeName = zipEntry.name;
|
|
96
|
+
let entry = zipEntry.parent;
|
|
97
|
+
while (entry && entry != ancestor) {
|
|
98
|
+
relativeName = (entry.name ? entry.name + "/" : "") + relativeName;
|
|
99
|
+
entry = entry.parent;
|
|
100
|
+
}
|
|
101
|
+
return relativeName;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
isDescendantOf(ancestor) {
|
|
105
|
+
let entry = this.parent;
|
|
106
|
+
while (entry && entry.id != ancestor.id) {
|
|
107
|
+
entry = entry.parent;
|
|
108
|
+
}
|
|
109
|
+
return Boolean(entry);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
rename(name) {
|
|
113
|
+
const parent = this.parent;
|
|
114
|
+
if (parent && parent.getChildByName(name)) {
|
|
115
|
+
throw new Error("Entry filename already exists");
|
|
116
|
+
} else {
|
|
117
|
+
this.name = name;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
class ZipFileEntry extends ZipEntry {
|
|
123
|
+
|
|
124
|
+
constructor(fs, name, params, parent) {
|
|
125
|
+
super(fs, name, params, parent);
|
|
126
|
+
const zipEntry = this;
|
|
127
|
+
zipEntry.Reader = params.Reader;
|
|
128
|
+
zipEntry.Writer = params.Writer;
|
|
129
|
+
if (params.getData) {
|
|
130
|
+
zipEntry.getData = params.getData;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
clone() {
|
|
135
|
+
return new ZipFileEntry(this.fs, this.name, this);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async getData(writer, options = {}) {
|
|
139
|
+
const zipEntry = this;
|
|
140
|
+
if (!writer || (writer.constructor == zipEntry.Writer && zipEntry.data)) {
|
|
141
|
+
return zipEntry.data;
|
|
142
|
+
} else {
|
|
143
|
+
const reader = zipEntry.reader = new zipEntry.Reader(zipEntry.data, options);
|
|
144
|
+
const uncompressedSize = zipEntry.data ? zipEntry.data.uncompressedSize : reader.size;
|
|
145
|
+
await Promise.all([initStream(reader), initStream(writer, uncompressedSize)]);
|
|
146
|
+
const readable = reader.readable;
|
|
147
|
+
readable.size = zipEntry.uncompressedSize = reader.size;
|
|
148
|
+
await readable.pipeTo(writer.writable);
|
|
149
|
+
return writer.getData ? writer.getData() : writer.writable;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
isPasswordProtected() {
|
|
154
|
+
return this.data.encrypted;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async checkPassword(password, options = {}) {
|
|
158
|
+
const zipEntry = this;
|
|
159
|
+
if (zipEntry.isPasswordProtected()) {
|
|
160
|
+
options.password = password;
|
|
161
|
+
options.checkPasswordOnly = true;
|
|
162
|
+
try {
|
|
163
|
+
await zipEntry.data.getData(null, options);
|
|
164
|
+
return true;
|
|
165
|
+
} catch (error) {
|
|
166
|
+
if (error.message == ERR_INVALID_PASSWORD) {
|
|
167
|
+
return false;
|
|
168
|
+
} else {
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
} else {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
getText(encoding, options) {
|
|
178
|
+
return this.getData(new TextWriter(encoding), options);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
getBlob(mimeType, options) {
|
|
182
|
+
return this.getData(new BlobWriter(mimeType), options);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
getData64URI(mimeType, options) {
|
|
186
|
+
return this.getData(new Data64URIWriter(mimeType), options);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
getUint8Array(options) {
|
|
190
|
+
return this.getData(new Uint8ArrayWriter(), options);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
getWritable(writable = new WritableStream(), options) {
|
|
194
|
+
return this.getData({ writable }, options);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
replaceBlob(blob) {
|
|
198
|
+
Object.assign(this, {
|
|
199
|
+
data: blob,
|
|
200
|
+
Reader: BlobReader,
|
|
201
|
+
Writer: BlobWriter,
|
|
202
|
+
reader: null
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
replaceText(text) {
|
|
207
|
+
Object.assign(this, {
|
|
208
|
+
data: text,
|
|
209
|
+
Reader: TextReader,
|
|
210
|
+
Writer: TextWriter,
|
|
211
|
+
reader: null
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
replaceData64URI(dataURI) {
|
|
216
|
+
Object.assign(this, {
|
|
217
|
+
data: dataURI,
|
|
218
|
+
Reader: Data64URIReader,
|
|
219
|
+
Writer: Data64URIWriter,
|
|
220
|
+
reader: null
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
replaceUint8Array(array) {
|
|
225
|
+
Object.assign(this, {
|
|
226
|
+
data: array,
|
|
227
|
+
Reader: Uint8ArrayReader,
|
|
228
|
+
Writer: Uint8ArrayWriter,
|
|
229
|
+
reader: null
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
replaceReadable(readable) {
|
|
234
|
+
Object.assign(this, {
|
|
235
|
+
data: null,
|
|
236
|
+
Reader: function () { return { readable }; },
|
|
237
|
+
Writer: null,
|
|
238
|
+
reader: null
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
class ZipDirectoryEntry extends ZipEntry {
|
|
244
|
+
|
|
245
|
+
constructor(fs, name, params, parent) {
|
|
246
|
+
super(fs, name, params, parent);
|
|
247
|
+
this.directory = true;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
clone(deepClone) {
|
|
251
|
+
const zipEntry = this;
|
|
252
|
+
const clonedEntry = new ZipDirectoryEntry(zipEntry.fs, zipEntry.name);
|
|
253
|
+
if (deepClone) {
|
|
254
|
+
clonedEntry.children = zipEntry.children.map(child => {
|
|
255
|
+
const childClone = child.clone(deepClone);
|
|
256
|
+
childClone.parent = clonedEntry;
|
|
257
|
+
return childClone;
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
return clonedEntry;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
addDirectory(name, options) {
|
|
264
|
+
return addChild(this, name, { options }, true);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
addText(name, text, options = {}) {
|
|
268
|
+
return addChild(this, name, {
|
|
269
|
+
data: text,
|
|
270
|
+
Reader: TextReader,
|
|
271
|
+
Writer: TextWriter,
|
|
272
|
+
options,
|
|
273
|
+
uncompressedSize: text.length
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
addBlob(name, blob, options = {}) {
|
|
278
|
+
return addChild(this, name, {
|
|
279
|
+
data: blob,
|
|
280
|
+
Reader: BlobReader,
|
|
281
|
+
Writer: BlobWriter,
|
|
282
|
+
options,
|
|
283
|
+
uncompressedSize: blob.size
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
addData64URI(name, dataURI, options = {}) {
|
|
288
|
+
let dataEnd = dataURI.length;
|
|
289
|
+
while (dataURI.charAt(dataEnd - 1) == "=") {
|
|
290
|
+
dataEnd--;
|
|
291
|
+
}
|
|
292
|
+
const dataStart = dataURI.indexOf(",") + 1;
|
|
293
|
+
return addChild(this, name, {
|
|
294
|
+
data: dataURI,
|
|
295
|
+
Reader: Data64URIReader,
|
|
296
|
+
Writer: Data64URIWriter,
|
|
297
|
+
options,
|
|
298
|
+
uncompressedSize: Math.floor((dataEnd - dataStart) * 0.75)
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
addUint8Array(name, array, options = {}) {
|
|
303
|
+
return addChild(this, name, {
|
|
304
|
+
data: array,
|
|
305
|
+
Reader: Uint8ArrayReader,
|
|
306
|
+
Writer: Uint8ArrayWriter,
|
|
307
|
+
options,
|
|
308
|
+
uncompressedSize: array.length
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
addHttpContent(name, url, options = {}) {
|
|
313
|
+
return addChild(this, name, {
|
|
314
|
+
data: url,
|
|
315
|
+
Reader: class extends HttpReader {
|
|
316
|
+
constructor(url) {
|
|
317
|
+
super(url, options);
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
options
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
addReadable(name, readable, options = {}) {
|
|
325
|
+
return addChild(this, name, {
|
|
326
|
+
Reader: function () { return { readable }; },
|
|
327
|
+
options
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
addFileSystemEntry(fileSystemEntry, options = {}) {
|
|
332
|
+
return addFileSystemHandle(this, fileSystemEntry, options);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
addFileSystemHandle(handle, options = {}) {
|
|
336
|
+
return addFileSystemHandle(this, handle, options);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
addFile(file, options = {}) {
|
|
340
|
+
if (!options.lastModDate) {
|
|
341
|
+
options.lastModDate = new Date(file.lastModified);
|
|
342
|
+
}
|
|
343
|
+
return addChild(this, file.name, {
|
|
344
|
+
data: file,
|
|
345
|
+
Reader: function () {
|
|
346
|
+
const readable = file.stream();
|
|
347
|
+
const size = file.size;
|
|
348
|
+
return { readable, size };
|
|
349
|
+
},
|
|
350
|
+
options,
|
|
351
|
+
uncompressedSize: file.size
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
addData(name, params) {
|
|
356
|
+
return addChild(this, name, params);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
importBlob(blob, options) {
|
|
360
|
+
return this.importZip(new BlobReader(blob), options);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
importData64URI(dataURI, options) {
|
|
364
|
+
return this.importZip(new Data64URIReader(dataURI), options);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
importUint8Array(array, options) {
|
|
368
|
+
return this.importZip(new Uint8ArrayReader(array), options);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
importHttpContent(url, options) {
|
|
372
|
+
return this.importZip(new HttpReader(url, options), options);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
importReadable(readable, options) {
|
|
376
|
+
return this.importZip({ readable }, options);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
exportBlob(options = {}) {
|
|
380
|
+
return this.exportZip(new BlobWriter(options.mimeType || "application/zip"), options);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
exportData64URI(options = {}) {
|
|
384
|
+
return this.exportZip(new Data64URIWriter(options.mimeType || "application/zip"), options);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
exportUint8Array(options = {}) {
|
|
388
|
+
return this.exportZip(new Uint8ArrayWriter(), options);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
async exportWritable(writable = new WritableStream(), options = {}) {
|
|
392
|
+
await this.exportZip({ writable }, options);
|
|
393
|
+
return writable;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
async importZip(reader, options = {}) {
|
|
397
|
+
await initStream(reader);
|
|
398
|
+
const zipReader = new ZipReader(reader, options);
|
|
399
|
+
const importedEntries = [];
|
|
400
|
+
const entries = await zipReader.getEntries();
|
|
401
|
+
for (const entry of entries) {
|
|
402
|
+
let parent = this;
|
|
403
|
+
try {
|
|
404
|
+
const path = entry.filename.split("/");
|
|
405
|
+
const name = path.pop();
|
|
406
|
+
path.forEach((pathPart, pathIndex) => {
|
|
407
|
+
const previousParent = parent;
|
|
408
|
+
parent = parent.getChildByName(pathPart);
|
|
409
|
+
if (!parent) {
|
|
410
|
+
parent = new ZipDirectoryEntry(this.fs, pathPart, { data: pathIndex == path.length - 1 ? entry : null }, previousParent);
|
|
411
|
+
importedEntries.push(parent);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
if (!entry.directory) {
|
|
415
|
+
importedEntries.push(addChild(parent, name, {
|
|
416
|
+
data: entry,
|
|
417
|
+
Reader: getZipBlobReader(Object.assign({}, options)),
|
|
418
|
+
uncompressedSize: entry.uncompressedSize
|
|
419
|
+
}));
|
|
420
|
+
}
|
|
421
|
+
} catch (error) {
|
|
422
|
+
try {
|
|
423
|
+
error.cause = {
|
|
424
|
+
entry
|
|
425
|
+
};
|
|
426
|
+
} catch (_error) {
|
|
427
|
+
// ignored
|
|
428
|
+
}
|
|
429
|
+
throw error;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return importedEntries;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
async exportZip(writer, options) {
|
|
436
|
+
const zipEntry = this;
|
|
437
|
+
if (options.bufferedWrite === UNDEFINED_VALUE) {
|
|
438
|
+
options.bufferedWrite = true;
|
|
439
|
+
}
|
|
440
|
+
await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
|
|
441
|
+
const zipWriter = new ZipWriter(writer, options);
|
|
442
|
+
await exportZip(zipWriter, zipEntry, getTotalSize([zipEntry], "uncompressedSize"), options);
|
|
443
|
+
await zipWriter.close();
|
|
444
|
+
return writer.getData ? writer.getData() : writer.writable;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
getChildByName(name) {
|
|
448
|
+
const children = this.children;
|
|
449
|
+
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
450
|
+
const child = children[childIndex];
|
|
451
|
+
if (child.name == name) {
|
|
452
|
+
return child;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
isPasswordProtected() {
|
|
458
|
+
const children = this.children;
|
|
459
|
+
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
460
|
+
const child = children[childIndex];
|
|
461
|
+
if (child.isPasswordProtected()) {
|
|
462
|
+
return true;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return false;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
async checkPassword(password, options = {}) {
|
|
469
|
+
const children = this.children;
|
|
470
|
+
const result = await Promise.all(children.map(child => child.checkPassword(password, options)));
|
|
471
|
+
return !result.includes(false);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
class FS {
|
|
477
|
+
|
|
478
|
+
constructor() {
|
|
479
|
+
resetFS(this);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
get children() {
|
|
483
|
+
return this.root.children;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
remove(entry) {
|
|
487
|
+
detach(entry);
|
|
488
|
+
this.entries[entry.id] = null;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
move(entry, destination) {
|
|
492
|
+
if (entry == this.root) {
|
|
493
|
+
throw new Error("Root directory cannot be moved");
|
|
494
|
+
} else {
|
|
495
|
+
if (destination.directory) {
|
|
496
|
+
if (!destination.isDescendantOf(entry)) {
|
|
497
|
+
if (entry != destination) {
|
|
498
|
+
if (destination.getChildByName(entry.name)) {
|
|
499
|
+
throw new Error("Entry filename already exists");
|
|
500
|
+
}
|
|
501
|
+
detach(entry);
|
|
502
|
+
entry.parent = destination;
|
|
503
|
+
destination.children.push(entry);
|
|
504
|
+
}
|
|
505
|
+
} else {
|
|
506
|
+
throw new Error("Entry is a ancestor of target entry");
|
|
507
|
+
}
|
|
508
|
+
} else {
|
|
509
|
+
throw new Error("Target entry is not a directory");
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
find(fullname) {
|
|
515
|
+
const path = fullname.split("/");
|
|
516
|
+
let node = this.root;
|
|
517
|
+
for (let index = 0; node && index < path.length; index++) {
|
|
518
|
+
node = node.getChildByName(path[index]);
|
|
519
|
+
}
|
|
520
|
+
return node;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
getById(id) {
|
|
524
|
+
return this.entries[id];
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
getChildByName(name) {
|
|
528
|
+
return this.root.getChildByName(name);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
addDirectory(name, options) {
|
|
532
|
+
return this.root.addDirectory(name, options);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
addText(name, text, options) {
|
|
536
|
+
return this.root.addText(name, text, options);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
addBlob(name, blob, options) {
|
|
540
|
+
return this.root.addBlob(name, blob, options);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
addData64URI(name, dataURI, options) {
|
|
544
|
+
return this.root.addData64URI(name, dataURI, options);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
addUint8Array(name, array, options) {
|
|
548
|
+
return this.root.addUint8Array(name, array, options);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
addHttpContent(name, url, options) {
|
|
552
|
+
return this.root.addHttpContent(name, url, options);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
addReadable(name, readable, options) {
|
|
556
|
+
return this.root.addReadable(name, readable, options);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
addFileSystemEntry(fileSystemEntry, options) {
|
|
560
|
+
return this.root.addFileSystemEntry(fileSystemEntry, options);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
addFileSystemHandle(handle, options) {
|
|
564
|
+
return this.root.addFileSystemHandle(handle, options);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
addFile(file, options) {
|
|
568
|
+
return this.root.addFile(file, options);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
addData(name, params) {
|
|
572
|
+
return this.root.addData(name, params);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
importBlob(blob, options) {
|
|
576
|
+
resetFS(this);
|
|
577
|
+
return this.root.importBlob(blob, options);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
importData64URI(dataURI, options) {
|
|
581
|
+
resetFS(this);
|
|
582
|
+
return this.root.importData64URI(dataURI, options);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
importUint8Array(array, options) {
|
|
586
|
+
resetFS(this);
|
|
587
|
+
return this.root.importUint8Array(array, options);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
importHttpContent(url, options) {
|
|
591
|
+
resetFS(this);
|
|
592
|
+
return this.root.importHttpContent(url, options);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
importReadable(readable, options) {
|
|
596
|
+
resetFS(this);
|
|
597
|
+
return this.root.importReadable(readable, options);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
importZip(reader, options) {
|
|
601
|
+
return this.root.importZip(reader, options);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
exportBlob(options) {
|
|
605
|
+
return this.root.exportBlob(options);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
exportData64URI(options) {
|
|
609
|
+
return this.root.exportData64URI(options);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
exportUint8Array(options) {
|
|
613
|
+
return this.root.exportUint8Array(options);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
exportWritable(writable, options) {
|
|
617
|
+
return this.root.exportWritable(writable, options);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
isPasswordProtected() {
|
|
621
|
+
return this.root.isPasswordProtected();
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
async checkPassword(password, options) {
|
|
625
|
+
return this.root.checkPassword(password, options);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
|
|
630
|
+
export { fs };
|
|
631
|
+
|
|
632
|
+
function getTotalSize(entries, propertyName) {
|
|
633
|
+
let size = 0;
|
|
634
|
+
entries.forEach(process);
|
|
635
|
+
return size;
|
|
636
|
+
|
|
637
|
+
function process(entry) {
|
|
638
|
+
size += entry[propertyName];
|
|
639
|
+
if (entry.children) {
|
|
640
|
+
entry.children.forEach(process);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
function getZipBlobReader(options) {
|
|
646
|
+
return class extends Reader {
|
|
647
|
+
|
|
648
|
+
constructor(entry, options = {}) {
|
|
649
|
+
super();
|
|
650
|
+
this.entry = entry;
|
|
651
|
+
this.options = options;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
async init() {
|
|
655
|
+
const zipBlobReader = this;
|
|
656
|
+
zipBlobReader.size = zipBlobReader.entry.uncompressedSize;
|
|
657
|
+
const data = await zipBlobReader.entry.getData(new BlobWriter(), Object.assign({}, zipBlobReader.options, options));
|
|
658
|
+
zipBlobReader.data = data;
|
|
659
|
+
zipBlobReader.blobReader = new BlobReader(data);
|
|
660
|
+
super.init();
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
readUint8Array(index, length) {
|
|
664
|
+
return this.blobReader.readUint8Array(index, length);
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
async function initReaders(entry, options) {
|
|
670
|
+
if (entry.children.length) {
|
|
671
|
+
await Promise.all(entry.children.map(async child => {
|
|
672
|
+
if (child.directory) {
|
|
673
|
+
await initReaders(child, options);
|
|
674
|
+
} else {
|
|
675
|
+
const reader = child.reader = new child.Reader(child.data, options);
|
|
676
|
+
try {
|
|
677
|
+
await initStream(reader);
|
|
678
|
+
} catch (error) {
|
|
679
|
+
try {
|
|
680
|
+
error.entryId = child.id;
|
|
681
|
+
error.cause = {
|
|
682
|
+
entry: child
|
|
683
|
+
};
|
|
684
|
+
} catch (_error) {
|
|
685
|
+
// ignored
|
|
686
|
+
}
|
|
687
|
+
throw error;
|
|
688
|
+
}
|
|
689
|
+
child.uncompressedSize = reader.size;
|
|
690
|
+
}
|
|
691
|
+
}));
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
function detach(entry) {
|
|
696
|
+
if (entry.parent) {
|
|
697
|
+
const children = entry.parent.children;
|
|
698
|
+
children.forEach((child, index) => {
|
|
699
|
+
if (child.id == entry.id) {
|
|
700
|
+
children.splice(index, 1);
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
async function exportZip(zipWriter, entry, totalSize, options) {
|
|
707
|
+
const selectedEntry = entry;
|
|
708
|
+
const entryOffsets = new Map();
|
|
709
|
+
await process(zipWriter, entry);
|
|
710
|
+
|
|
711
|
+
async function process(zipWriter, entry) {
|
|
712
|
+
await exportChild();
|
|
713
|
+
|
|
714
|
+
async function exportChild() {
|
|
715
|
+
if (options.bufferedWrite) {
|
|
716
|
+
await Promise.allSettled(entry.children.map(processChild));
|
|
717
|
+
} else {
|
|
718
|
+
for (const child of entry.children) {
|
|
719
|
+
await processChild(child);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
async function processChild(child) {
|
|
725
|
+
const name = options.relativePath ? child.getRelativeName(selectedEntry) : child.getFullname();
|
|
726
|
+
let childOptions = child.options || {};
|
|
727
|
+
let zipEntryOptions = {};
|
|
728
|
+
if (child.data instanceof Entry) {
|
|
729
|
+
const {
|
|
730
|
+
externalFileAttribute,
|
|
731
|
+
versionMadeBy,
|
|
732
|
+
comment,
|
|
733
|
+
lastModDate,
|
|
734
|
+
creationDate,
|
|
735
|
+
lastAccessDate
|
|
736
|
+
} = child.data;
|
|
737
|
+
zipEntryOptions = {
|
|
738
|
+
externalFileAttribute,
|
|
739
|
+
versionMadeBy,
|
|
740
|
+
comment,
|
|
741
|
+
lastModDate,
|
|
742
|
+
creationDate,
|
|
743
|
+
lastAccessDate
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
await zipWriter.add(name, child.reader, Object.assign({
|
|
747
|
+
directory: child.directory
|
|
748
|
+
}, Object.assign({}, options, zipEntryOptions, childOptions, {
|
|
749
|
+
onprogress: async indexProgress => {
|
|
750
|
+
if (options.onprogress) {
|
|
751
|
+
entryOffsets.set(name, indexProgress);
|
|
752
|
+
try {
|
|
753
|
+
await options.onprogress(Array.from(entryOffsets.values()).reduce((previousValue, currentValue) => previousValue + currentValue), totalSize);
|
|
754
|
+
} catch (_error) {
|
|
755
|
+
// ignored
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
})));
|
|
760
|
+
await process(zipWriter, child);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
async function addFileSystemHandle(zipEntry, handle, options) {
|
|
766
|
+
return addFile(zipEntry, handle, []);
|
|
767
|
+
|
|
768
|
+
async function addFile(parentEntry, handle, addedEntries) {
|
|
769
|
+
if (handle) {
|
|
770
|
+
try {
|
|
771
|
+
if (handle.isFile || handle.isDirectory) {
|
|
772
|
+
handle = await transformToFileSystemhandle(handle);
|
|
773
|
+
}
|
|
774
|
+
if (handle.kind == "file") {
|
|
775
|
+
const file = await handle.getFile();
|
|
776
|
+
addedEntries.push(
|
|
777
|
+
parentEntry.addData(file.name, {
|
|
778
|
+
Reader: function () {
|
|
779
|
+
const readable = file.stream();
|
|
780
|
+
const size = file.size;
|
|
781
|
+
return { readable, size };
|
|
782
|
+
},
|
|
783
|
+
options: Object.assign({}, { lastModDate: new Date(file.lastModified) }, options),
|
|
784
|
+
uncompressedSize: file.size
|
|
785
|
+
})
|
|
786
|
+
);
|
|
787
|
+
} else if (handle.kind == "directory") {
|
|
788
|
+
const directoryEntry = parentEntry.addDirectory(handle.name);
|
|
789
|
+
addedEntries.push(directoryEntry);
|
|
790
|
+
for await (const childHandle of handle.values()) {
|
|
791
|
+
await addFile(directoryEntry, childHandle, addedEntries);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
} catch (error) {
|
|
795
|
+
const message = error.message + (handle ? " (" + handle.name + ")" : "");
|
|
796
|
+
throw new Error(message);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
return addedEntries;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
async function transformToFileSystemhandle(entry) {
|
|
804
|
+
const handle = {
|
|
805
|
+
name: entry.name
|
|
806
|
+
};
|
|
807
|
+
if (entry.isFile) {
|
|
808
|
+
handle.kind = "file";
|
|
809
|
+
handle.getFile = () =>
|
|
810
|
+
new Promise((resolve, reject) => entry.file(resolve, reject));
|
|
811
|
+
}
|
|
812
|
+
if (entry.isDirectory) {
|
|
813
|
+
handle.kind = "directory";
|
|
814
|
+
const handles = await transformToFileSystemhandles(entry);
|
|
815
|
+
handle.values = () => handles;
|
|
816
|
+
}
|
|
817
|
+
return handle;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
async function transformToFileSystemhandles(entry) {
|
|
821
|
+
const entries = [];
|
|
822
|
+
function readEntries(directoryReader, resolve, reject) {
|
|
823
|
+
directoryReader.readEntries(async (entriesPart) => {
|
|
824
|
+
if (!entriesPart.length) {
|
|
825
|
+
resolve(entries);
|
|
826
|
+
} else {
|
|
827
|
+
for (const entry of entriesPart) {
|
|
828
|
+
entries.push(await transformToFileSystemhandle(entry));
|
|
829
|
+
}
|
|
830
|
+
readEntries(directoryReader, resolve, reject);
|
|
831
|
+
}
|
|
832
|
+
}, reject);
|
|
833
|
+
}
|
|
834
|
+
await new Promise((resolve, reject) =>
|
|
835
|
+
readEntries(entry.createReader(), resolve, reject)
|
|
836
|
+
);
|
|
837
|
+
return {
|
|
838
|
+
[Symbol.iterator]() {
|
|
839
|
+
let entryIndex = 0;
|
|
840
|
+
return {
|
|
841
|
+
next() {
|
|
842
|
+
const result = {
|
|
843
|
+
value: entries[entryIndex],
|
|
844
|
+
done: entryIndex === entries.length
|
|
845
|
+
};
|
|
846
|
+
entryIndex++;
|
|
847
|
+
return result;
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
function resetFS(fs) {
|
|
855
|
+
fs.entries = [];
|
|
856
|
+
fs.root = new ZipDirectoryEntry(fs);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
function addChild(parent, name, params, directory) {
|
|
860
|
+
if (parent.directory) {
|
|
861
|
+
return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
|
|
862
|
+
} else {
|
|
863
|
+
throw new Error("Parent entry is not a directory");
|
|
864
|
+
}
|
|
865
|
+
}
|