@loaders.gl/zip 4.0.0-alpha.9 → 4.0.0-beta.2
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/dist/dist.min.js +5143 -36
- package/dist/es5/filesystems/zip-filesystem.js +372 -0
- package/dist/es5/filesystems/zip-filesystem.js.map +1 -0
- package/dist/es5/hash-file-utility.js +130 -0
- package/dist/es5/hash-file-utility.js.map +1 -0
- package/dist/es5/index.js +80 -3
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/parse-zip/cd-file-header.js +163 -0
- package/dist/es5/parse-zip/cd-file-header.js.map +1 -0
- package/dist/es5/parse-zip/end-of-central-directory.js +98 -0
- package/dist/es5/parse-zip/end-of-central-directory.js.map +1 -0
- package/dist/es5/parse-zip/local-file-header.js +117 -0
- package/dist/es5/parse-zip/local-file-header.js.map +1 -0
- package/dist/es5/parse-zip/search-from-the-end.js +69 -0
- package/dist/es5/parse-zip/search-from-the-end.js.map +1 -0
- package/dist/es5/tar-builder.js +8 -8
- package/dist/es5/tar-builder.js.map +1 -1
- package/dist/es5/zip-loader.js +2 -4
- package/dist/es5/zip-loader.js.map +1 -1
- package/dist/es5/zip-writer.js +19 -10
- package/dist/es5/zip-writer.js.map +1 -1
- package/dist/esm/filesystems/zip-filesystem.js +99 -0
- package/dist/esm/filesystems/zip-filesystem.js.map +1 -0
- package/dist/esm/hash-file-utility.js +55 -0
- package/dist/esm/hash-file-utility.js.map +1 -0
- package/dist/esm/index.js +7 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/parse-zip/cd-file-header.js +54 -0
- package/dist/esm/parse-zip/cd-file-header.js.map +1 -0
- package/dist/esm/parse-zip/end-of-central-directory.js +31 -0
- package/dist/esm/parse-zip/end-of-central-directory.js.map +1 -0
- package/dist/esm/parse-zip/local-file-header.js +41 -0
- package/dist/esm/parse-zip/local-file-header.js.map +1 -0
- package/dist/esm/parse-zip/search-from-the-end.js +16 -0
- package/dist/esm/parse-zip/search-from-the-end.js.map +1 -0
- package/dist/esm/tar-builder.js +2 -2
- package/dist/esm/tar-builder.js.map +1 -1
- package/dist/esm/zip-loader.js +1 -2
- package/dist/esm/zip-loader.js.map +1 -1
- package/dist/esm/zip-writer.js +8 -5
- package/dist/esm/zip-writer.js.map +1 -1
- package/dist/filesystems/zip-filesystem.d.ts +45 -0
- package/dist/filesystems/zip-filesystem.d.ts.map +1 -0
- package/dist/hash-file-utility.d.ts +35 -0
- package/dist/hash-file-utility.d.ts.map +1 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/parse-zip/cd-file-header.d.ts +36 -0
- package/dist/parse-zip/cd-file-header.d.ts.map +1 -0
- package/dist/parse-zip/end-of-central-directory.d.ts +18 -0
- package/dist/parse-zip/end-of-central-directory.d.ts.map +1 -0
- package/dist/parse-zip/local-file-header.d.ts +28 -0
- package/dist/parse-zip/local-file-header.d.ts.map +1 -0
- package/dist/parse-zip/search-from-the-end.d.ts +11 -0
- package/dist/parse-zip/search-from-the-end.d.ts.map +1 -0
- package/dist/tar-builder.d.ts +2 -2
- package/dist/tar-builder.d.ts.map +1 -1
- package/dist/zip-loader.d.ts +0 -1
- package/dist/zip-loader.d.ts.map +1 -1
- package/dist/zip-writer.d.ts +12 -2
- package/dist/zip-writer.d.ts.map +1 -1
- package/package.json +6 -3
- package/src/filesystems/zip-filesystem.ts +142 -0
- package/src/hash-file-utility.ts +101 -0
- package/src/index.ts +20 -1
- package/src/parse-zip/cd-file-header.ts +114 -0
- package/src/parse-zip/end-of-central-directory.ts +71 -0
- package/src/parse-zip/local-file-header.ts +95 -0
- package/src/parse-zip/search-from-the-end.ts +38 -0
- package/src/tar-builder.ts +2 -2
- package/src/zip-loader.ts +2 -3
- package/src/zip-writer.ts +23 -10
- package/dist/bundle.js +0 -5
- package/dist/index.js +0 -12
- package/dist/lib/tar/header.js +0 -99
- package/dist/lib/tar/tar.js +0 -131
- package/dist/lib/tar/types.js +0 -2
- package/dist/lib/tar/utils.js +0 -54
- package/dist/tar-builder.js +0 -38
- package/dist/zip-loader.js +0 -61
- package/dist/zip-writer.js +0 -37
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import {FileProvider} from '@loaders.gl/loader-utils';
|
|
2
|
+
import {parseEoCDRecord} from './end-of-central-directory';
|
|
3
|
+
import {ZipSignature} from './search-from-the-end';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* zip central directory file header info
|
|
7
|
+
* according to https://en.wikipedia.org/wiki/ZIP_(file_format)
|
|
8
|
+
*/
|
|
9
|
+
export type ZipCDFileHeader = {
|
|
10
|
+
/** Compressed size */
|
|
11
|
+
compressedSize: bigint;
|
|
12
|
+
/** Uncompressed size */
|
|
13
|
+
uncompressedSize: bigint;
|
|
14
|
+
/** Extra field size */
|
|
15
|
+
extraFieldLength: number;
|
|
16
|
+
/** File name length */
|
|
17
|
+
fileNameLength: number;
|
|
18
|
+
/** File name */
|
|
19
|
+
fileName: string;
|
|
20
|
+
/** Extra field offset */
|
|
21
|
+
extraOffset: bigint;
|
|
22
|
+
/** Relative offset of local file header */
|
|
23
|
+
localHeaderOffset: bigint;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// offsets accroding to https://en.wikipedia.org/wiki/ZIP_(file_format)
|
|
27
|
+
const CD_COMPRESSED_SIZE_OFFSET = 20n;
|
|
28
|
+
const CD_UNCOMPRESSED_SIZE_OFFSET = 24n;
|
|
29
|
+
const CD_FILE_NAME_LENGTH_OFFSET = 28n;
|
|
30
|
+
const CD_EXTRA_FIELD_LENGTH_OFFSET = 30n;
|
|
31
|
+
const CD_LOCAL_HEADER_OFFSET_OFFSET = 42n;
|
|
32
|
+
const CD_FILE_NAME_OFFSET = 46n;
|
|
33
|
+
|
|
34
|
+
export const signature: ZipSignature = [0x50, 0x4b, 0x01, 0x02];
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Parses central directory file header of zip file
|
|
38
|
+
* @param headerOffset - offset in the archive where header starts
|
|
39
|
+
* @param buffer - buffer containing whole array
|
|
40
|
+
* @returns Info from the header
|
|
41
|
+
*/
|
|
42
|
+
export const parseZipCDFileHeader = async (
|
|
43
|
+
headerOffset: bigint,
|
|
44
|
+
buffer: FileProvider
|
|
45
|
+
): Promise<ZipCDFileHeader | null> => {
|
|
46
|
+
if (
|
|
47
|
+
Buffer.from(await buffer.slice(headerOffset, headerOffset + 4n)).compare(
|
|
48
|
+
Buffer.from(signature)
|
|
49
|
+
) !== 0
|
|
50
|
+
) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let compressedSize = BigInt(await buffer.getUint32(headerOffset + CD_COMPRESSED_SIZE_OFFSET));
|
|
55
|
+
|
|
56
|
+
let uncompressedSize = BigInt(await buffer.getUint32(headerOffset + CD_UNCOMPRESSED_SIZE_OFFSET));
|
|
57
|
+
|
|
58
|
+
const extraFieldLength = await buffer.getUint16(headerOffset + CD_EXTRA_FIELD_LENGTH_OFFSET);
|
|
59
|
+
|
|
60
|
+
const fileNameLength = await buffer.getUint16(headerOffset + CD_FILE_NAME_LENGTH_OFFSET);
|
|
61
|
+
|
|
62
|
+
const fileName = new TextDecoder().decode(
|
|
63
|
+
await buffer.slice(
|
|
64
|
+
headerOffset + CD_FILE_NAME_OFFSET,
|
|
65
|
+
headerOffset + CD_FILE_NAME_OFFSET + BigInt(fileNameLength)
|
|
66
|
+
)
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const extraOffset = headerOffset + CD_FILE_NAME_OFFSET + BigInt(fileNameLength);
|
|
70
|
+
|
|
71
|
+
const oldFormatOffset = await buffer.getUint32(headerOffset + CD_LOCAL_HEADER_OFFSET_OFFSET);
|
|
72
|
+
|
|
73
|
+
let fileDataOffset = BigInt(oldFormatOffset);
|
|
74
|
+
let offsetInZip64Data = 4n;
|
|
75
|
+
// looking for info that might be also be in zip64 extra field
|
|
76
|
+
if (uncompressedSize === BigInt(0xffffffff)) {
|
|
77
|
+
uncompressedSize = await buffer.getBigUint64(extraOffset + offsetInZip64Data);
|
|
78
|
+
offsetInZip64Data += 8n;
|
|
79
|
+
}
|
|
80
|
+
if (compressedSize === BigInt(0xffffffff)) {
|
|
81
|
+
compressedSize = await buffer.getBigUint64(extraOffset + offsetInZip64Data);
|
|
82
|
+
offsetInZip64Data += 8n;
|
|
83
|
+
}
|
|
84
|
+
if (fileDataOffset === BigInt(0xffffffff)) {
|
|
85
|
+
fileDataOffset = await buffer.getBigUint64(extraOffset + offsetInZip64Data); // setting it to the one from zip64
|
|
86
|
+
}
|
|
87
|
+
const localHeaderOffset = fileDataOffset;
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
compressedSize,
|
|
91
|
+
uncompressedSize,
|
|
92
|
+
extraFieldLength,
|
|
93
|
+
fileNameLength,
|
|
94
|
+
fileName,
|
|
95
|
+
extraOffset,
|
|
96
|
+
localHeaderOffset
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Create iterator over files of zip archive
|
|
102
|
+
* @param fileProvider - file provider that provider random access to the file
|
|
103
|
+
*/
|
|
104
|
+
export async function* zipCDFileHeaderGenerator(fileProvider: FileProvider) {
|
|
105
|
+
const {cdStartOffset} = await parseEoCDRecord(fileProvider);
|
|
106
|
+
let cdHeader = await parseZipCDFileHeader(cdStartOffset, fileProvider);
|
|
107
|
+
while (cdHeader) {
|
|
108
|
+
yield cdHeader;
|
|
109
|
+
cdHeader = await parseZipCDFileHeader(
|
|
110
|
+
cdHeader.extraOffset + BigInt(cdHeader.extraFieldLength),
|
|
111
|
+
fileProvider
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {FileProvider} from '@loaders.gl/loader-utils';
|
|
2
|
+
import {ZipSignature, searchFromTheEnd} from './search-from-the-end';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* End of central directory info
|
|
6
|
+
* according to https://en.wikipedia.org/wiki/ZIP_(file_format)
|
|
7
|
+
*/
|
|
8
|
+
export type ZipEoCDRecord = {
|
|
9
|
+
/** Relative offset of local file header */
|
|
10
|
+
cdStartOffset: bigint;
|
|
11
|
+
/** Relative offset of local file header */
|
|
12
|
+
cdRecordsNumber: bigint;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const eoCDSignature: ZipSignature = [0x50, 0x4b, 0x05, 0x06];
|
|
16
|
+
const zip64EoCDLocatorSignature = [0x50, 0x4b, 0x06, 0x07];
|
|
17
|
+
const zip64EoCDSignature = [0x50, 0x4b, 0x06, 0x06];
|
|
18
|
+
|
|
19
|
+
// offsets accroding to https://en.wikipedia.org/wiki/ZIP_(file_format)
|
|
20
|
+
const CD_RECORDS_NUMBER_OFFSET = 8n;
|
|
21
|
+
const CD_START_OFFSET_OFFSET = 16n;
|
|
22
|
+
const ZIP64_EOCD_START_OFFSET_OFFSET = 8n;
|
|
23
|
+
const ZIP64_CD_RECORDS_NUMBER_OFFSET = 24n;
|
|
24
|
+
const ZIP64_CD_START_OFFSET_OFFSET = 48n;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Parses end of central directory record of zip file
|
|
28
|
+
* @param fileProvider - FileProvider instance
|
|
29
|
+
* @returns Info from the header
|
|
30
|
+
*/
|
|
31
|
+
export const parseEoCDRecord = async (fileProvider: FileProvider): Promise<ZipEoCDRecord> => {
|
|
32
|
+
const zipEoCDOffset = await searchFromTheEnd(fileProvider, eoCDSignature);
|
|
33
|
+
|
|
34
|
+
let cdRecordsNumber = BigInt(
|
|
35
|
+
await fileProvider.getUint16(zipEoCDOffset + CD_RECORDS_NUMBER_OFFSET)
|
|
36
|
+
);
|
|
37
|
+
let cdStartOffset = BigInt(await fileProvider.getUint32(zipEoCDOffset + CD_START_OFFSET_OFFSET));
|
|
38
|
+
|
|
39
|
+
if (cdStartOffset === BigInt(0xffffffff) || cdRecordsNumber === BigInt(0xffffffff)) {
|
|
40
|
+
const zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
|
|
41
|
+
|
|
42
|
+
if (
|
|
43
|
+
Buffer.from(
|
|
44
|
+
await fileProvider.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n)
|
|
45
|
+
).compare(Buffer.from(zip64EoCDLocatorSignature)) !== 0
|
|
46
|
+
) {
|
|
47
|
+
throw new Error('zip64 EoCD locator not found');
|
|
48
|
+
}
|
|
49
|
+
const zip64EoCDOffset = await fileProvider.getBigUint64(
|
|
50
|
+
zip64EoCDLocatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
if (
|
|
54
|
+
Buffer.from(await fileProvider.slice(zip64EoCDOffset, zip64EoCDOffset + 4n)).compare(
|
|
55
|
+
Buffer.from(zip64EoCDSignature)
|
|
56
|
+
) !== 0
|
|
57
|
+
) {
|
|
58
|
+
throw new Error('zip64 EoCD not found');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
cdRecordsNumber = await fileProvider.getBigUint64(
|
|
62
|
+
zip64EoCDOffset + ZIP64_CD_RECORDS_NUMBER_OFFSET
|
|
63
|
+
);
|
|
64
|
+
cdStartOffset = await fileProvider.getBigUint64(zip64EoCDOffset + ZIP64_CD_START_OFFSET_OFFSET);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
cdRecordsNumber,
|
|
69
|
+
cdStartOffset
|
|
70
|
+
};
|
|
71
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import {FileProvider} from '@loaders.gl/loader-utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* zip local file header info
|
|
5
|
+
* according to https://en.wikipedia.org/wiki/ZIP_(file_format)
|
|
6
|
+
*/
|
|
7
|
+
export type ZipLocalFileHeader = {
|
|
8
|
+
/** File name length */
|
|
9
|
+
fileNameLength: number;
|
|
10
|
+
/** File name */
|
|
11
|
+
fileName: string;
|
|
12
|
+
/** Extra field length */
|
|
13
|
+
extraFieldLength: number;
|
|
14
|
+
/** Offset of the file data */
|
|
15
|
+
fileDataOffset: bigint;
|
|
16
|
+
/** Compressed size */
|
|
17
|
+
compressedSize: bigint;
|
|
18
|
+
/** Compression method */
|
|
19
|
+
compressionMethod: number;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// offsets accroding to https://en.wikipedia.org/wiki/ZIP_(file_format)
|
|
23
|
+
const COMPRESSION_METHOD_OFFSET = 8n;
|
|
24
|
+
const COMPRESSED_SIZE_OFFSET = 18n;
|
|
25
|
+
const UNCOMPRESSED_SIZE_OFFSET = 22n;
|
|
26
|
+
const FILE_NAME_LENGTH_OFFSET = 26n;
|
|
27
|
+
const EXTRA_FIELD_LENGTH_OFFSET = 28n;
|
|
28
|
+
const FILE_NAME_OFFSET = 30n;
|
|
29
|
+
|
|
30
|
+
export const signature = [0x50, 0x4b, 0x03, 0x04];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parses local file header of zip file
|
|
34
|
+
* @param headerOffset - offset in the archive where header starts
|
|
35
|
+
* @param buffer - buffer containing whole array
|
|
36
|
+
* @returns Info from the header
|
|
37
|
+
*/
|
|
38
|
+
export const parseZipLocalFileHeader = async (
|
|
39
|
+
headerOffset: bigint,
|
|
40
|
+
buffer: FileProvider
|
|
41
|
+
): Promise<ZipLocalFileHeader | null> => {
|
|
42
|
+
if (
|
|
43
|
+
Buffer.from(await buffer.slice(headerOffset, headerOffset + 4n)).compare(
|
|
44
|
+
Buffer.from(signature)
|
|
45
|
+
) !== 0
|
|
46
|
+
) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const fileNameLength = await buffer.getUint16(headerOffset + FILE_NAME_LENGTH_OFFSET);
|
|
51
|
+
|
|
52
|
+
const fileName = new TextDecoder()
|
|
53
|
+
.decode(
|
|
54
|
+
await buffer.slice(
|
|
55
|
+
headerOffset + FILE_NAME_OFFSET,
|
|
56
|
+
headerOffset + FILE_NAME_OFFSET + BigInt(fileNameLength)
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
.split('\\')
|
|
60
|
+
.join('/');
|
|
61
|
+
const extraFieldLength = await buffer.getUint16(headerOffset + EXTRA_FIELD_LENGTH_OFFSET);
|
|
62
|
+
|
|
63
|
+
let fileDataOffset = headerOffset + FILE_NAME_OFFSET + BigInt(fileNameLength + extraFieldLength);
|
|
64
|
+
|
|
65
|
+
const compressionMethod = await buffer.getUint16(headerOffset + COMPRESSION_METHOD_OFFSET);
|
|
66
|
+
|
|
67
|
+
let compressedSize = BigInt(await buffer.getUint32(headerOffset + COMPRESSED_SIZE_OFFSET)); // add zip 64 logic
|
|
68
|
+
|
|
69
|
+
let uncompressedSize = BigInt(await buffer.getUint32(headerOffset + UNCOMPRESSED_SIZE_OFFSET)); // add zip 64 logic
|
|
70
|
+
|
|
71
|
+
const extraOffset = headerOffset + FILE_NAME_OFFSET + BigInt(fileNameLength);
|
|
72
|
+
|
|
73
|
+
let offsetInZip64Data = 4n;
|
|
74
|
+
// looking for info that might be also be in zip64 extra field
|
|
75
|
+
if (uncompressedSize === BigInt(0xffffffff)) {
|
|
76
|
+
uncompressedSize = await buffer.getBigUint64(extraOffset + offsetInZip64Data);
|
|
77
|
+
offsetInZip64Data += 8n;
|
|
78
|
+
}
|
|
79
|
+
if (compressedSize === BigInt(0xffffffff)) {
|
|
80
|
+
compressedSize = await buffer.getBigUint64(extraOffset + offsetInZip64Data);
|
|
81
|
+
offsetInZip64Data += 8n;
|
|
82
|
+
}
|
|
83
|
+
if (fileDataOffset === BigInt(0xffffffff)) {
|
|
84
|
+
fileDataOffset = await buffer.getBigUint64(extraOffset + offsetInZip64Data); // setting it to the one from zip64
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
fileNameLength,
|
|
89
|
+
fileName,
|
|
90
|
+
extraFieldLength,
|
|
91
|
+
fileDataOffset,
|
|
92
|
+
compressedSize,
|
|
93
|
+
compressionMethod
|
|
94
|
+
};
|
|
95
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {FileProvider} from '@loaders.gl/loader-utils';
|
|
2
|
+
|
|
3
|
+
/** Description of zip signature type */
|
|
4
|
+
export type ZipSignature = [number, number, number, number];
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* looking for the last occurrence of the provided
|
|
8
|
+
* @param file
|
|
9
|
+
* @param target
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
export const searchFromTheEnd = async (
|
|
13
|
+
file: FileProvider,
|
|
14
|
+
target: ZipSignature
|
|
15
|
+
): Promise<bigint> => {
|
|
16
|
+
const searchWindow = [
|
|
17
|
+
await file.getUint8(file.length - 1n),
|
|
18
|
+
await file.getUint8(file.length - 2n),
|
|
19
|
+
await file.getUint8(file.length - 3n),
|
|
20
|
+
undefined
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
let targetOffset = 0n;
|
|
24
|
+
|
|
25
|
+
// looking for the last record in the central directory
|
|
26
|
+
for (let i = file.length - 4n; i > -1; i--) {
|
|
27
|
+
searchWindow[3] = searchWindow[2];
|
|
28
|
+
searchWindow[2] = searchWindow[1];
|
|
29
|
+
searchWindow[1] = searchWindow[0];
|
|
30
|
+
searchWindow[0] = await file.getUint8(i);
|
|
31
|
+
if (searchWindow.every((val, index) => val === target[index])) {
|
|
32
|
+
targetOffset = i;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return targetOffset;
|
|
38
|
+
};
|
package/src/tar-builder.ts
CHANGED
|
@@ -11,14 +11,14 @@ type TarBuilderOptions = {
|
|
|
11
11
|
/**
|
|
12
12
|
* Build a tar file by adding files
|
|
13
13
|
*/
|
|
14
|
-
export
|
|
14
|
+
export class TarBuilder {
|
|
15
15
|
static get properties() {
|
|
16
16
|
return {
|
|
17
17
|
id: 'tar',
|
|
18
18
|
name: 'TAR',
|
|
19
19
|
extensions: ['tar'],
|
|
20
20
|
mimeTypes: ['application/x-tar'],
|
|
21
|
-
builder:
|
|
21
|
+
builder: TarBuilder,
|
|
22
22
|
options: TAR_BUILDER_OPTIONS
|
|
23
23
|
};
|
|
24
24
|
}
|
package/src/zip-loader.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
//
|
|
1
|
+
// loaders.gl, MIT license
|
|
2
|
+
|
|
2
3
|
import type {LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';
|
|
3
4
|
import JSZip from 'jszip';
|
|
4
5
|
|
|
@@ -64,5 +65,3 @@ async function loadZipEntry(jsZip: any, subFilename: string, options: any = {})
|
|
|
64
65
|
return error;
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
|
-
|
|
68
|
-
export const _typecheckZipLoader: LoaderWithParser = ZipLoader;
|
package/src/zip-writer.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// loaders.gl, MIT license
|
|
2
|
+
|
|
3
|
+
import type {Writer, WriterOptions} from '@loaders.gl/loader-utils';
|
|
4
|
+
import JSZip, {JSZipGeneratorOptions} from 'jszip';
|
|
5
|
+
|
|
6
|
+
export type ZipWriterOptions = WriterOptions & {
|
|
7
|
+
zip?: {
|
|
8
|
+
onUpdate?: (metadata: {percent: number}) => void;
|
|
9
|
+
};
|
|
10
|
+
/** Passthrough options to jszip */
|
|
11
|
+
jszip?: JSZipGeneratorOptions;
|
|
12
|
+
};
|
|
3
13
|
|
|
4
14
|
/**
|
|
5
15
|
* Zip exporter
|
|
6
16
|
*/
|
|
7
|
-
export const ZipWriter: Writer = {
|
|
17
|
+
export const ZipWriter: Writer<FileReaderEventMap, never, ZipWriterOptions> = {
|
|
8
18
|
name: 'Zip Archive',
|
|
9
19
|
extensions: ['zip'],
|
|
10
20
|
category: 'archive',
|
|
@@ -13,7 +23,10 @@ export const ZipWriter: Writer = {
|
|
|
13
23
|
encode: encodeZipAsync
|
|
14
24
|
};
|
|
15
25
|
|
|
16
|
-
async function encodeZipAsync(
|
|
26
|
+
async function encodeZipAsync(
|
|
27
|
+
fileMap: Record<string, ArrayBuffer>,
|
|
28
|
+
options: ZipWriterOptions = {}
|
|
29
|
+
) {
|
|
17
30
|
const jsZip = new JSZip();
|
|
18
31
|
// add files to the zip
|
|
19
32
|
for (const subFileName in fileMap) {
|
|
@@ -21,17 +34,17 @@ async function encodeZipAsync(fileMap: any, options: any = {}) {
|
|
|
21
34
|
|
|
22
35
|
// jszip supports both arraybuffer and string data (the main loaders.gl types)
|
|
23
36
|
// https://stuk.github.io/jszip/documentation/api_zipobject/async.html
|
|
24
|
-
jsZip.file(subFileName, subFileData, options);
|
|
37
|
+
jsZip.file(subFileName, subFileData, options?.jszip || {});
|
|
25
38
|
}
|
|
26
39
|
|
|
27
40
|
// always generate the full zip as an arraybuffer
|
|
28
|
-
|
|
29
|
-
type: 'arraybuffer'
|
|
30
|
-
});
|
|
41
|
+
const jszipOptions: JSZipGeneratorOptions = {...options?.jszip, type: 'arraybuffer'};
|
|
31
42
|
const {onUpdate = () => {}} = options;
|
|
32
43
|
|
|
33
|
-
|
|
44
|
+
try {
|
|
45
|
+
return await jsZip.generateAsync(jszipOptions, onUpdate);
|
|
46
|
+
} catch (error) {
|
|
34
47
|
options.log.error(`Unable to write zip archive: ${error}`);
|
|
35
48
|
throw error;
|
|
36
|
-
}
|
|
49
|
+
}
|
|
37
50
|
}
|
package/dist/bundle.js
DELETED
package/dist/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.TarBuilder = exports.ZipWriter = exports.ZipLoader = void 0;
|
|
7
|
-
var zip_loader_1 = require("./zip-loader");
|
|
8
|
-
Object.defineProperty(exports, "ZipLoader", { enumerable: true, get: function () { return zip_loader_1.ZipLoader; } });
|
|
9
|
-
var zip_writer_1 = require("./zip-writer");
|
|
10
|
-
Object.defineProperty(exports, "ZipWriter", { enumerable: true, get: function () { return zip_writer_1.ZipWriter; } });
|
|
11
|
-
var tar_builder_1 = require("./tar-builder");
|
|
12
|
-
Object.defineProperty(exports, "TarBuilder", { enumerable: true, get: function () { return __importDefault(tar_builder_1).default; } });
|
package/dist/lib/tar/header.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.format = void 0;
|
|
27
|
-
// This file is derived from the tar-js code base under MIT license
|
|
28
|
-
// See https://github.com/beatgammit/tar-js/blob/master/LICENSE
|
|
29
|
-
/*
|
|
30
|
-
* tar-js
|
|
31
|
-
* MIT (c) 2011 T. Jameson Little
|
|
32
|
-
*/
|
|
33
|
-
/* eslint-disable */
|
|
34
|
-
const utils = __importStar(require("./utils"));
|
|
35
|
-
/*
|
|
36
|
-
struct posix_header { // byte offset
|
|
37
|
-
char name[100]; // 0
|
|
38
|
-
char mode[8]; // 100
|
|
39
|
-
char uid[8]; // 108
|
|
40
|
-
char gid[8]; // 116
|
|
41
|
-
char size[12]; // 124
|
|
42
|
-
char mtime[12]; // 136
|
|
43
|
-
char chksum[8]; // 148
|
|
44
|
-
char typeflag; // 156
|
|
45
|
-
char linkname[100]; // 157
|
|
46
|
-
char magic[6]; // 257
|
|
47
|
-
char version[2]; // 263
|
|
48
|
-
char uname[32]; // 265
|
|
49
|
-
char gname[32]; // 297
|
|
50
|
-
char devmajor[8]; // 329
|
|
51
|
-
char devminor[8]; // 337
|
|
52
|
-
char prefix[155]; // 345
|
|
53
|
-
// 500
|
|
54
|
-
};
|
|
55
|
-
*/
|
|
56
|
-
const structure = {
|
|
57
|
-
fileName: 100,
|
|
58
|
-
fileMode: 8,
|
|
59
|
-
uid: 8,
|
|
60
|
-
gid: 8,
|
|
61
|
-
fileSize: 12,
|
|
62
|
-
mtime: 12,
|
|
63
|
-
checksum: 8,
|
|
64
|
-
type: 1,
|
|
65
|
-
linkName: 100,
|
|
66
|
-
ustar: 8,
|
|
67
|
-
owner: 32,
|
|
68
|
-
group: 32,
|
|
69
|
-
majorNumber: 8,
|
|
70
|
-
minorNumber: 8,
|
|
71
|
-
filenamePrefix: 155,
|
|
72
|
-
padding: 12
|
|
73
|
-
};
|
|
74
|
-
/**
|
|
75
|
-
* Getting the header
|
|
76
|
-
* @param data
|
|
77
|
-
* @param [cb]
|
|
78
|
-
* @returns {Uint8Array} | Array
|
|
79
|
-
*/
|
|
80
|
-
function format(data, cb) {
|
|
81
|
-
const buffer = utils.clean(512);
|
|
82
|
-
let offset = 0;
|
|
83
|
-
Object.entries(structure).forEach(([field, length]) => {
|
|
84
|
-
const str = data[field] || '';
|
|
85
|
-
let i;
|
|
86
|
-
let fieldLength;
|
|
87
|
-
for (i = 0, fieldLength = str.length; i < fieldLength; i += 1) {
|
|
88
|
-
buffer[offset] = str.charCodeAt(i);
|
|
89
|
-
offset += 1;
|
|
90
|
-
}
|
|
91
|
-
// space it out with nulls
|
|
92
|
-
offset += length - i;
|
|
93
|
-
});
|
|
94
|
-
if (typeof cb === 'function') {
|
|
95
|
-
return cb(buffer, offset);
|
|
96
|
-
}
|
|
97
|
-
return buffer;
|
|
98
|
-
}
|
|
99
|
-
exports.format = format;
|
package/dist/lib/tar/tar.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// This file is derived from the tar-js code base under MIT license
|
|
3
|
-
// See https://github.com/beatgammit/tar-js/blob/master/LICENSE
|
|
4
|
-
/*
|
|
5
|
-
* tar-js
|
|
6
|
-
* MIT (c) 2011 T. Jameson Little
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
const utils_1 = require("./utils");
|
|
10
|
-
const header_1 = require("./header");
|
|
11
|
-
let blockSize;
|
|
12
|
-
let headerLength;
|
|
13
|
-
let inputLength;
|
|
14
|
-
const recordSize = 512;
|
|
15
|
-
class Tar {
|
|
16
|
-
/**
|
|
17
|
-
* @param [recordsPerBlock]
|
|
18
|
-
*/
|
|
19
|
-
constructor(recordsPerBlock) {
|
|
20
|
-
this.blocks = [];
|
|
21
|
-
this.written = 0;
|
|
22
|
-
blockSize = (recordsPerBlock || 20) * recordSize;
|
|
23
|
-
this.out = (0, utils_1.clean)(blockSize);
|
|
24
|
-
this.blocks = [];
|
|
25
|
-
this.length = 0;
|
|
26
|
-
this.save = this.save.bind(this);
|
|
27
|
-
this.clear = this.clear.bind(this);
|
|
28
|
-
this.append = this.append.bind(this);
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Append a file to the tar archive
|
|
32
|
-
* @param filepath
|
|
33
|
-
* @param input
|
|
34
|
-
* @param [opts]
|
|
35
|
-
*/
|
|
36
|
-
// eslint-disable-next-line complexity
|
|
37
|
-
append(filepath, input, opts) {
|
|
38
|
-
let checksum;
|
|
39
|
-
if (typeof input === 'string') {
|
|
40
|
-
input = (0, utils_1.stringToUint8)(input);
|
|
41
|
-
}
|
|
42
|
-
else if (input.constructor && input.constructor !== Uint8Array.prototype.constructor) {
|
|
43
|
-
// @ts-ignore
|
|
44
|
-
const errorInputMatch = /function\s*([$A-Za-z_][0-9A-Za-z_]*)\s*\(/.exec(input.constructor.toString());
|
|
45
|
-
const errorInput = errorInputMatch && errorInputMatch[1];
|
|
46
|
-
const errorMessage = `Invalid input type. You gave me: ${errorInput}`;
|
|
47
|
-
throw errorMessage;
|
|
48
|
-
}
|
|
49
|
-
opts = opts || {};
|
|
50
|
-
const mode = opts.mode || parseInt('777', 8) & 0xfff;
|
|
51
|
-
const mtime = opts.mtime || Math.floor(Number(new Date()) / 1000);
|
|
52
|
-
const uid = opts.uid || 0;
|
|
53
|
-
const gid = opts.gid || 0;
|
|
54
|
-
const data = {
|
|
55
|
-
fileName: filepath,
|
|
56
|
-
fileMode: (0, utils_1.pad)(mode, 7),
|
|
57
|
-
uid: (0, utils_1.pad)(uid, 7),
|
|
58
|
-
gid: (0, utils_1.pad)(gid, 7),
|
|
59
|
-
fileSize: (0, utils_1.pad)(input.length, 11),
|
|
60
|
-
mtime: (0, utils_1.pad)(mtime, 11),
|
|
61
|
-
checksum: ' ',
|
|
62
|
-
// 0 = just a file
|
|
63
|
-
type: '0',
|
|
64
|
-
ustar: 'ustar ',
|
|
65
|
-
owner: opts.owner || '',
|
|
66
|
-
group: opts.group || ''
|
|
67
|
-
};
|
|
68
|
-
// calculate the checksum
|
|
69
|
-
checksum = 0;
|
|
70
|
-
Object.keys(data).forEach((key) => {
|
|
71
|
-
let i;
|
|
72
|
-
const value = data[key];
|
|
73
|
-
let length;
|
|
74
|
-
for (i = 0, length = value.length; i < length; i += 1) {
|
|
75
|
-
checksum += value.charCodeAt(i);
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
data.checksum = `${(0, utils_1.pad)(checksum, 6)}\u0000 `;
|
|
79
|
-
const headerArr = (0, header_1.format)(data);
|
|
80
|
-
headerLength = Math.ceil(headerArr.length / recordSize) * recordSize;
|
|
81
|
-
inputLength = Math.ceil(input.length / recordSize) * recordSize;
|
|
82
|
-
this.blocks.push({
|
|
83
|
-
header: headerArr,
|
|
84
|
-
input,
|
|
85
|
-
headerLength,
|
|
86
|
-
inputLength
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Compiling data to a Blob object
|
|
91
|
-
* @returns {Blob}
|
|
92
|
-
*/
|
|
93
|
-
save() {
|
|
94
|
-
const buffers = [];
|
|
95
|
-
const chunks = new Array();
|
|
96
|
-
let length = 0;
|
|
97
|
-
const max = Math.pow(2, 20);
|
|
98
|
-
let chunk = new Array();
|
|
99
|
-
this.blocks.forEach((b = []) => {
|
|
100
|
-
if (length + b.headerLength + b.inputLength > max) {
|
|
101
|
-
chunks.push({ blocks: chunk, length });
|
|
102
|
-
chunk = [];
|
|
103
|
-
length = 0;
|
|
104
|
-
}
|
|
105
|
-
chunk.push(b);
|
|
106
|
-
length += b.headerLength + b.inputLength;
|
|
107
|
-
});
|
|
108
|
-
chunks.push({ blocks: chunk, length });
|
|
109
|
-
chunks.forEach((c = []) => {
|
|
110
|
-
const buffer = new Uint8Array(c.length);
|
|
111
|
-
let written = 0;
|
|
112
|
-
c.blocks.forEach((b = []) => {
|
|
113
|
-
buffer.set(b.header, written);
|
|
114
|
-
written += b.headerLength;
|
|
115
|
-
buffer.set(b.input, written);
|
|
116
|
-
written += b.inputLength;
|
|
117
|
-
});
|
|
118
|
-
buffers.push(buffer);
|
|
119
|
-
});
|
|
120
|
-
buffers.push(new Uint8Array(2 * recordSize));
|
|
121
|
-
return new Blob(buffers, { type: 'octet/stream' });
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Clear the data by its blocksize
|
|
125
|
-
*/
|
|
126
|
-
clear() {
|
|
127
|
-
this.written = 0;
|
|
128
|
-
this.out = (0, utils_1.clean)(blockSize);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
exports.default = Tar;
|
package/dist/lib/tar/types.js
DELETED