@zip.js/zip.js 2.9.0 → 2.10.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/README.md +40 -0
- package/deno.json +1 -1
- package/dist/zip-core-external.js +5 -12
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +5 -12
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +159 -55
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +160 -54
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +159 -55
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +160 -54
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +160 -54
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +5 -12
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-native.js +5 -12
- package/dist/zip-native.min.js +1 -1
- package/dist/zip.js +5 -12
- package/dist/zip.min.js +1 -1
- package/index-native.cjs +160 -54
- package/index-native.min.js +1 -1
- package/index.cjs +160 -54
- package/index.d.cts +87 -7
- package/index.d.ts +87 -7
- package/index.min.js +1 -1
- package/lib/core/util/decode-cp437.js +4 -11
- package/lib/core/version.js +1 -1
- package/lib/core/zip-fs.js +155 -44
- package/package.json +1 -1
|
@@ -26,23 +26,16 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global TextDecoder */
|
|
30
|
-
|
|
31
29
|
const CP437 = "\0\u263A\u263B\u2665\u2666\u2663\u2660\u2022\u25D8\u25CB\u25D9\u2642\u2640\u266A\u266B\u263C\u25BA\u25C4\u2195\u203C\u00B6\u00A7\u25AC\u21A8\u2191\u2193\u2192\u2190\u221F\u2194\u25B2\u25BC !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u2302\u00C7\u00FC\u00E9\u00E2\u00E4\u00E0\u00E5\u00E7\u00EA\u00EB\u00E8\u00EF\u00EE\u00EC\u00C4\u00C5\u00C9\u00E6\u00C6\u00F4\u00F6\u00F2\u00FB\u00F9\u00FF\u00D6\u00DC\u00A2\u00A3\u00A5\u20A7\u0192\u00E1\u00ED\u00F3\u00FA\u00F1\u00D1\u00AA\u00BA\u00BF\u2310\u00AC\u00BD\u00BC\u00A1\u00AB\u00BB\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255D\u255C\u255B\u2510\u2514\u2534\u252C\u251C\u2500\u253C\u255E\u255F\u255A\u2554\u2569\u2566\u2560\u2550\u256C\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256B\u256A\u2518\u250C\u2588\u2584\u258C\u2590\u2580\u03B1\u00DF\u0393\u03C0\u03A3\u03C3\u00B5\u03C4\u03A6\u0398\u03A9\u03B4\u221E\u03C6\u03B5\u2229\u2261\u00B1\u2265\u2264\u2320\u2321\u00F7\u2248\u00B0\u2219\u00B7\u221A\u207F\u00B2\u25A0\u00A0".split("");
|
|
32
|
-
const VALID_CP437 = CP437.length == 256;
|
|
33
30
|
|
|
34
31
|
export {
|
|
35
32
|
decodeCP437
|
|
36
33
|
};
|
|
37
34
|
|
|
38
35
|
function decodeCP437(stringValue) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
result += CP437[stringValue[indexCharacter]];
|
|
43
|
-
}
|
|
44
|
-
return result;
|
|
45
|
-
} else {
|
|
46
|
-
return new TextDecoder().decode(stringValue);
|
|
36
|
+
let result = "";
|
|
37
|
+
for (let indexCharacter = 0; indexCharacter < stringValue.length; indexCharacter++) {
|
|
38
|
+
result += CP437[stringValue[indexCharacter]];
|
|
47
39
|
}
|
|
40
|
+
return result;
|
|
48
41
|
}
|
package/lib/core/version.js
CHANGED
package/lib/core/zip-fs.js
CHANGED
|
@@ -80,7 +80,14 @@ import { toExactUint8Array } from "./util/array.js";
|
|
|
80
80
|
import { toCompatibleReadable, toCompatibleWritable } from "./util/compatible-streams.js";
|
|
81
81
|
|
|
82
82
|
const ERR_ENTRY_EXISTS = "Entry filename already exists";
|
|
83
|
+
const ERR_DUPLICATE_IMPORTED_ENTRY = "Duplicate entry filename in the imported zip file";
|
|
84
|
+
const ERR_INVALID_DUPLICATES = "Invalid duplicates option (must be \"throw\", \"keep-first\" or \"keep-last\")";
|
|
85
|
+
const ERR_ANCESTOR_ENTRY = "Entry is a ancestor of target entry";
|
|
83
86
|
const ERR_READABLE_CONSUMED = "Readable stream already consumed";
|
|
87
|
+
const DUPLICATES_THROW = "throw";
|
|
88
|
+
const DUPLICATES_KEEP_FIRST = "keep-first";
|
|
89
|
+
const DUPLICATES_KEEP_LAST = "keep-last";
|
|
90
|
+
const DUPLICATES_VALUES = new Set([DUPLICATES_THROW, DUPLICATES_KEEP_FIRST, DUPLICATES_KEEP_LAST]);
|
|
84
91
|
const ERR_INVALID_PASS_THROUGH = "Invalid passThrough option (use readerOptions.passThrough or set uncompressedSize for each entry)";
|
|
85
92
|
const ERR_INVALID_READER_OPTIONS = "Invalid readerOptions (must be an object)";
|
|
86
93
|
const ERR_ZIP_CRYPTO_LAST_MOD_DATE = "The last modification date of an entry encrypted with ZipCrypto cannot be changed when passThrough is set";
|
|
@@ -157,12 +164,26 @@ class ZipEntry {
|
|
|
157
164
|
}
|
|
158
165
|
|
|
159
166
|
rename(name) {
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
167
|
+
const zipEntry = this;
|
|
168
|
+
let parent = zipEntry.parent;
|
|
169
|
+
if (parent) {
|
|
170
|
+
const path = splitPath(name);
|
|
171
|
+
if (path) {
|
|
172
|
+
name = path.pop();
|
|
173
|
+
parent = getPathParent(parent, path, zipEntry);
|
|
174
|
+
}
|
|
175
|
+
const existingChild = parent.getChildByName(name);
|
|
176
|
+
if (existingChild && existingChild != zipEntry) {
|
|
177
|
+
throw new Error(ERR_ENTRY_EXISTS);
|
|
178
|
+
}
|
|
179
|
+
if (parent != zipEntry.parent) {
|
|
180
|
+
detach(zipEntry);
|
|
181
|
+
zipEntry.parent = parent;
|
|
182
|
+
parent.children.push(zipEntry);
|
|
183
|
+
registerEntries(zipEntry.fs, zipEntry);
|
|
184
|
+
}
|
|
165
185
|
}
|
|
186
|
+
zipEntry.name = name;
|
|
166
187
|
}
|
|
167
188
|
|
|
168
189
|
setOptions(options) {
|
|
@@ -255,47 +276,47 @@ class ZipFileEntry extends ZipEntry {
|
|
|
255
276
|
}
|
|
256
277
|
|
|
257
278
|
replaceBlob(blob) {
|
|
258
|
-
|
|
279
|
+
replaceContent(this, {
|
|
259
280
|
data: blob,
|
|
260
281
|
Reader: BlobReader,
|
|
261
282
|
Writer: BlobWriter,
|
|
262
|
-
|
|
283
|
+
uncompressedSize: blob.size
|
|
263
284
|
});
|
|
264
285
|
}
|
|
265
286
|
|
|
266
287
|
replaceText(text) {
|
|
267
|
-
|
|
288
|
+
replaceContent(this, {
|
|
268
289
|
data: text,
|
|
269
290
|
Reader: TextReader,
|
|
270
291
|
Writer: TextWriter,
|
|
271
|
-
|
|
292
|
+
uncompressedSize: getTextSize(text)
|
|
272
293
|
});
|
|
273
294
|
}
|
|
274
295
|
|
|
275
296
|
replaceData64URI(dataURI) {
|
|
276
|
-
|
|
297
|
+
replaceContent(this, {
|
|
277
298
|
data: dataURI,
|
|
278
299
|
Reader: Data64URIReader,
|
|
279
300
|
Writer: Data64URIWriter,
|
|
280
|
-
|
|
301
|
+
uncompressedSize: getData64URISize(dataURI)
|
|
281
302
|
});
|
|
282
303
|
}
|
|
283
304
|
|
|
284
305
|
replaceUint8Array(array) {
|
|
285
|
-
|
|
306
|
+
replaceContent(this, {
|
|
286
307
|
data: array,
|
|
287
308
|
Reader: Uint8ArrayReader,
|
|
288
309
|
Writer: Uint8ArrayWriter,
|
|
289
|
-
|
|
310
|
+
uncompressedSize: array.length
|
|
290
311
|
});
|
|
291
312
|
}
|
|
292
313
|
|
|
293
314
|
replaceReadable(readable) {
|
|
294
|
-
|
|
315
|
+
replaceContent(this, {
|
|
295
316
|
data: null,
|
|
296
317
|
Reader: getReadableReader(readable),
|
|
297
318
|
Writer: null,
|
|
298
|
-
|
|
319
|
+
uncompressedSize: UNDEFINED_VALUE
|
|
299
320
|
});
|
|
300
321
|
}
|
|
301
322
|
}
|
|
@@ -345,17 +366,12 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
345
366
|
}
|
|
346
367
|
|
|
347
368
|
addData64URI(name, dataURI, options = {}) {
|
|
348
|
-
let dataEnd = dataURI.length;
|
|
349
|
-
while (dataURI.charAt(dataEnd - 1) == "=") {
|
|
350
|
-
dataEnd--;
|
|
351
|
-
}
|
|
352
|
-
const dataStart = dataURI.indexOf(",") + 1;
|
|
353
369
|
return addChild(this, name, {
|
|
354
370
|
data: dataURI,
|
|
355
371
|
Reader: Data64URIReader,
|
|
356
372
|
Writer: Data64URIWriter,
|
|
357
373
|
options,
|
|
358
|
-
uncompressedSize:
|
|
374
|
+
uncompressedSize: getData64URISize(dataURI)
|
|
359
375
|
});
|
|
360
376
|
}
|
|
361
377
|
|
|
@@ -463,6 +479,7 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
463
479
|
await initStream(reader);
|
|
464
480
|
zipReader = new ZipReader(reader, options);
|
|
465
481
|
}
|
|
482
|
+
const duplicates = checkDuplicatesOption(options.duplicates);
|
|
466
483
|
const importedEntries = [];
|
|
467
484
|
const entries = await zipReader.getEntries(options);
|
|
468
485
|
for (const entry of entries) {
|
|
@@ -470,19 +487,42 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
470
487
|
try {
|
|
471
488
|
const path = entry.filename.split("/").filter(pathPart => pathPart != "" && pathPart != ".");
|
|
472
489
|
const name = path.pop();
|
|
473
|
-
|
|
490
|
+
let skippedEntry = false;
|
|
491
|
+
for (const pathPart of path) {
|
|
474
492
|
const previousParent = parent;
|
|
475
493
|
parent = parent.getChildByName(pathPart);
|
|
476
494
|
if (parent) {
|
|
477
495
|
if (!parent.directory) {
|
|
478
|
-
|
|
496
|
+
if (duplicates == DUPLICATES_KEEP_FIRST) {
|
|
497
|
+
skippedEntry = true;
|
|
498
|
+
break;
|
|
499
|
+
} else if (duplicates == DUPLICATES_KEEP_LAST) {
|
|
500
|
+
this.fs.remove(parent);
|
|
501
|
+
parent = new ZipDirectoryEntry(this.fs, pathPart, { data: null }, previousParent);
|
|
502
|
+
importedEntries.push(parent);
|
|
503
|
+
} else {
|
|
504
|
+
throw new Error(ERR_DUPLICATE_IMPORTED_ENTRY);
|
|
505
|
+
}
|
|
479
506
|
}
|
|
480
507
|
} else {
|
|
481
508
|
parent = new ZipDirectoryEntry(this.fs, pathPart, { data: null }, previousParent);
|
|
482
509
|
importedEntries.push(parent);
|
|
483
510
|
}
|
|
484
|
-
}
|
|
511
|
+
}
|
|
512
|
+
if (skippedEntry) {
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
485
515
|
if (!entry.directory) {
|
|
516
|
+
const existingChild = parent.getChildByName(name);
|
|
517
|
+
if (existingChild) {
|
|
518
|
+
if (duplicates == DUPLICATES_KEEP_FIRST) {
|
|
519
|
+
continue;
|
|
520
|
+
} else if (duplicates == DUPLICATES_KEEP_LAST) {
|
|
521
|
+
this.fs.remove(existingChild);
|
|
522
|
+
} else {
|
|
523
|
+
throw new Error(ERR_DUPLICATE_IMPORTED_ENTRY);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
486
526
|
importedEntries.push(addChild(parent, name, {
|
|
487
527
|
data: entry,
|
|
488
528
|
Reader: getZipBlobReader(Object.assign({}, options)),
|
|
@@ -493,11 +533,17 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
493
533
|
let directoryEntry = parent;
|
|
494
534
|
if (name) {
|
|
495
535
|
directoryEntry = parent.getChildByName(name);
|
|
496
|
-
if (directoryEntry) {
|
|
497
|
-
if (
|
|
498
|
-
|
|
536
|
+
if (directoryEntry && !directoryEntry.directory) {
|
|
537
|
+
if (duplicates == DUPLICATES_KEEP_FIRST) {
|
|
538
|
+
continue;
|
|
539
|
+
} else if (duplicates == DUPLICATES_KEEP_LAST) {
|
|
540
|
+
this.fs.remove(directoryEntry);
|
|
541
|
+
directoryEntry = UNDEFINED_VALUE;
|
|
542
|
+
} else {
|
|
543
|
+
throw new Error(ERR_DUPLICATE_IMPORTED_ENTRY);
|
|
499
544
|
}
|
|
500
|
-
}
|
|
545
|
+
}
|
|
546
|
+
if (!directoryEntry) {
|
|
501
547
|
directoryEntry = new ZipDirectoryEntry(this.fs, name, { data: null }, parent);
|
|
502
548
|
importedEntries.push(directoryEntry);
|
|
503
549
|
}
|
|
@@ -507,6 +553,7 @@ class ZipDirectoryEntry extends ZipEntry {
|
|
|
507
553
|
}
|
|
508
554
|
}
|
|
509
555
|
} catch (error) {
|
|
556
|
+
importedEntries.reverse().forEach(importedEntry => this.fs.remove(importedEntry));
|
|
510
557
|
try {
|
|
511
558
|
error.cause = {
|
|
512
559
|
entry
|
|
@@ -625,7 +672,7 @@ class ZipFS {
|
|
|
625
672
|
}
|
|
626
673
|
}
|
|
627
674
|
} else {
|
|
628
|
-
throw new Error(
|
|
675
|
+
throw new Error(ERR_ANCESTOR_ENTRY);
|
|
629
676
|
}
|
|
630
677
|
} else {
|
|
631
678
|
throw new Error("Target entry is not a directory");
|
|
@@ -637,7 +684,7 @@ class ZipFS {
|
|
|
637
684
|
const path = fullname.split("/");
|
|
638
685
|
let node = this.root;
|
|
639
686
|
for (let index = 0; node && index < path.length; index++) {
|
|
640
|
-
node = node.getChildByName(path[index]);
|
|
687
|
+
node = node.directory ? node.getChildByName(path[index]) : UNDEFINED_VALUE;
|
|
641
688
|
}
|
|
642
689
|
if (!node) {
|
|
643
690
|
node = this.entries.find(entry => entry && (entry == this.root || entry.isDescendantOf(this.root)) &&
|
|
@@ -699,33 +746,27 @@ class ZipFS {
|
|
|
699
746
|
}
|
|
700
747
|
|
|
701
748
|
importBlob(blob, options) {
|
|
702
|
-
|
|
703
|
-
return this.root.importBlob(blob, options);
|
|
749
|
+
return resetAndImport(this, root => root.importBlob(blob, options));
|
|
704
750
|
}
|
|
705
751
|
|
|
706
752
|
importData64URI(dataURI, options) {
|
|
707
|
-
|
|
708
|
-
return this.root.importData64URI(dataURI, options);
|
|
753
|
+
return resetAndImport(this, root => root.importData64URI(dataURI, options));
|
|
709
754
|
}
|
|
710
755
|
|
|
711
756
|
importUint8Array(array, options) {
|
|
712
|
-
|
|
713
|
-
return this.root.importUint8Array(array, options);
|
|
757
|
+
return resetAndImport(this, root => root.importUint8Array(array, options));
|
|
714
758
|
}
|
|
715
759
|
|
|
716
760
|
importHttpContent(url, options) {
|
|
717
|
-
|
|
718
|
-
return this.root.importHttpContent(url, options);
|
|
761
|
+
return resetAndImport(this, root => root.importHttpContent(url, options));
|
|
719
762
|
}
|
|
720
763
|
|
|
721
764
|
importReadable(readable, options) {
|
|
722
|
-
|
|
723
|
-
return this.root.importReadable(readable, options);
|
|
765
|
+
return resetAndImport(this, root => root.importReadable(readable, options));
|
|
724
766
|
}
|
|
725
767
|
|
|
726
768
|
importZip(reader, options) {
|
|
727
|
-
|
|
728
|
-
return this.root.importZip(reader, options);
|
|
769
|
+
return resetAndImport(this, root => root.importZip(reader, options));
|
|
729
770
|
}
|
|
730
771
|
|
|
731
772
|
exportBlob(options) {
|
|
@@ -766,7 +807,7 @@ class ZipFS {
|
|
|
766
807
|
}
|
|
767
808
|
|
|
768
809
|
const fs = { FS: ZipFS, ZipDirectoryEntry, ZipFileEntry };
|
|
769
|
-
export { ZipFS, ZipEntry, ZipFileEntry, ZipDirectoryEntry, fs, ERR_ENTRY_EXISTS, ERR_READABLE_CONSUMED, ERR_INVALID_PASS_THROUGH, ERR_INVALID_READER_OPTIONS, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ABORTED };
|
|
810
|
+
export { ZipFS, ZipEntry, ZipFileEntry, ZipDirectoryEntry, fs, ERR_ENTRY_EXISTS, ERR_DUPLICATE_IMPORTED_ENTRY, ERR_INVALID_DUPLICATES, ERR_READABLE_CONSUMED, ERR_INVALID_PASS_THROUGH, ERR_INVALID_READER_OPTIONS, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ABORTED };
|
|
770
811
|
|
|
771
812
|
function getTotalSize(entries, getEntrySize) {
|
|
772
813
|
let size = 0;
|
|
@@ -1046,6 +1087,25 @@ function checkReaderOptions(readerOptions) {
|
|
|
1046
1087
|
return readerOptions;
|
|
1047
1088
|
}
|
|
1048
1089
|
|
|
1090
|
+
function replaceContent(zipEntry, params) {
|
|
1091
|
+
const { uncompressedSize } = params;
|
|
1092
|
+
Object.assign(zipEntry, params, {
|
|
1093
|
+
reader: null,
|
|
1094
|
+
passThrough: UNDEFINED_VALUE,
|
|
1095
|
+
uncompressedSize: uncompressedSize === UNDEFINED_VALUE ? 0 : uncompressedSize,
|
|
1096
|
+
undeterminedSize: uncompressedSize === UNDEFINED_VALUE
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
function getData64URISize(dataURI) {
|
|
1101
|
+
let dataEnd = dataURI.length;
|
|
1102
|
+
while (dataURI.charAt(dataEnd - 1) == "=") {
|
|
1103
|
+
dataEnd--;
|
|
1104
|
+
}
|
|
1105
|
+
const dataStart = dataURI.indexOf(",") + 1;
|
|
1106
|
+
return Math.floor((dataEnd - dataStart) * 0.75);
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1049
1109
|
function isPassThrough(child, options) {
|
|
1050
1110
|
const { readerOptions } = options;
|
|
1051
1111
|
return Boolean(!child.directory && (child.passThrough || (readerOptions && readerOptions.passThrough)));
|
|
@@ -1335,6 +1395,15 @@ function resetFS(fs) {
|
|
|
1335
1395
|
fs.root = new ZipDirectoryEntry(fs);
|
|
1336
1396
|
}
|
|
1337
1397
|
|
|
1398
|
+
function resetAndImport(fs, importFunction) {
|
|
1399
|
+
const { entries, entryIdCounter, root } = fs;
|
|
1400
|
+
resetFS(fs);
|
|
1401
|
+
return importFunction(fs.root).catch(error => {
|
|
1402
|
+
Object.assign(fs, { entries, entryIdCounter, root });
|
|
1403
|
+
throw error;
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1338
1407
|
function collectChildren(directory, recursive) {
|
|
1339
1408
|
const children = [];
|
|
1340
1409
|
const pendingDirectories = [directory];
|
|
@@ -1363,8 +1432,50 @@ function registerEntries(fs, entry) {
|
|
|
1363
1432
|
|
|
1364
1433
|
function addChild(parent, name, params, directory) {
|
|
1365
1434
|
if (parent.directory) {
|
|
1435
|
+
const path = splitPath(name);
|
|
1436
|
+
if (path) {
|
|
1437
|
+
name = path.pop();
|
|
1438
|
+
parent = getPathParent(parent, path);
|
|
1439
|
+
}
|
|
1366
1440
|
return directory ? new ZipDirectoryEntry(parent.fs, name, params, parent) : new ZipFileEntry(parent.fs, name, params, parent);
|
|
1367
1441
|
} else {
|
|
1368
1442
|
throw new Error("Parent entry is not a directory");
|
|
1369
1443
|
}
|
|
1370
|
-
}
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
function checkDuplicatesOption(duplicates) {
|
|
1447
|
+
if (duplicates === UNDEFINED_VALUE) {
|
|
1448
|
+
return DUPLICATES_THROW;
|
|
1449
|
+
} else if (DUPLICATES_VALUES.has(duplicates)) {
|
|
1450
|
+
return duplicates;
|
|
1451
|
+
} else {
|
|
1452
|
+
throw new Error(ERR_INVALID_DUPLICATES);
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
function splitPath(name) {
|
|
1457
|
+
if (name.includes("/")) {
|
|
1458
|
+
const path = name.split("/").filter(pathPart => pathPart != "" && pathPart != ".");
|
|
1459
|
+
if (path.length) {
|
|
1460
|
+
return path;
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
function getPathParent(parent, path, movedEntry) {
|
|
1466
|
+
path.forEach(pathPart => {
|
|
1467
|
+
const previousParent = parent;
|
|
1468
|
+
parent = parent.getChildByName(pathPart);
|
|
1469
|
+
if (parent) {
|
|
1470
|
+
if (!parent.directory) {
|
|
1471
|
+
throw new Error(ERR_ENTRY_EXISTS);
|
|
1472
|
+
}
|
|
1473
|
+
if (movedEntry && (parent == movedEntry || parent.isDescendantOf(movedEntry))) {
|
|
1474
|
+
throw new Error(ERR_ANCESTOR_ENTRY);
|
|
1475
|
+
}
|
|
1476
|
+
} else {
|
|
1477
|
+
parent = new ZipDirectoryEntry(previousParent.fs, pathPart, { data: null }, previousParent);
|
|
1478
|
+
}
|
|
1479
|
+
});
|
|
1480
|
+
return parent;
|
|
1481
|
+
}
|
package/package.json
CHANGED