@8ms/helpers 3.2.6 → 3.2.7
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/xlsx/_shared/createXlsx.cjs +12 -22
- package/dist/xlsx/_shared/createXlsx.mjs +12 -22
- package/dist/xlsx/_shared/modifyXlsx.cjs +32 -44
- package/dist/xlsx/_shared/modifyXlsx.mjs +32 -44
- package/dist/xlsx/client/index.cjs +0 -1
- package/dist/xlsx/client/index.mjs +0 -1
- package/dist/xlsx/server/index.cjs +0 -1
- package/dist/xlsx/server/index.mjs +0 -1
- package/dist/zip/_shared/ZipArchive.cjs +49 -0
- package/dist/zip/_shared/ZipArchive.d.cts +24 -0
- package/dist/zip/_shared/ZipArchive.d.mts +24 -0
- package/dist/zip/_shared/ZipArchive.mjs +48 -0
- package/dist/zip/_shared/crc32.cjs +24 -0
- package/dist/zip/_shared/crc32.d.cts +4 -0
- package/dist/zip/_shared/crc32.d.mts +4 -0
- package/dist/zip/_shared/crc32.mjs +23 -0
- package/dist/zip/_shared/deflate.cjs +21 -0
- package/dist/zip/_shared/deflate.d.cts +10 -0
- package/dist/zip/_shared/deflate.d.mts +10 -0
- package/dist/zip/_shared/deflate.mjs +19 -0
- package/dist/zip/_shared/index.cjs +12 -0
- package/dist/zip/_shared/index.d.cts +6 -0
- package/dist/zip/_shared/index.d.mts +6 -0
- package/dist/zip/_shared/index.mjs +6 -0
- package/dist/zip/_shared/readZip.cjs +63 -0
- package/dist/zip/_shared/readZip.d.cts +9 -0
- package/dist/zip/_shared/readZip.d.mts +9 -0
- package/dist/zip/_shared/readZip.mjs +62 -0
- package/dist/zip/_shared/writeZip.cjs +105 -0
- package/dist/zip/_shared/writeZip.d.cts +7 -0
- package/dist/zip/_shared/writeZip.d.mts +7 -0
- package/dist/zip/_shared/writeZip.mjs +104 -0
- package/dist/zip/client/index.cjs +12 -0
- package/dist/zip/client/index.d.cts +6 -0
- package/dist/zip/client/index.d.mts +6 -0
- package/dist/zip/client/index.mjs +6 -0
- package/dist/zip/server/index.cjs +12 -0
- package/dist/zip/server/index.d.cts +6 -0
- package/dist/zip/server/index.d.mts +6 -0
- package/dist/zip/server/index.mjs +6 -0
- package/package.json +33 -6
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/zip/_shared/deflate.ts
|
|
3
|
+
/**
|
|
4
|
+
* Raw DEFLATE via the platform's Compression Streams API, so there is no
|
|
5
|
+
* dependency and the same code runs in the browser, Node and edge runtimes.
|
|
6
|
+
*
|
|
7
|
+
* Requires Node 21.2+, Chrome 103+, Safari 16.4+ or Firefox 113+.
|
|
8
|
+
*/
|
|
9
|
+
const getTransformed = async (bytes, stream) => {
|
|
10
|
+
const written = new Blob([bytes]).stream().pipeThrough(stream);
|
|
11
|
+
return new Uint8Array(await new Response(written).arrayBuffer());
|
|
12
|
+
};
|
|
13
|
+
const getDeflatedRaw = async (bytes) => {
|
|
14
|
+
return getTransformed(bytes, new CompressionStream("deflate-raw"));
|
|
15
|
+
};
|
|
16
|
+
const getInflatedRaw = async (bytes) => {
|
|
17
|
+
return getTransformed(bytes, new DecompressionStream("deflate-raw"));
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
exports.getDeflatedRaw = getDeflatedRaw;
|
|
21
|
+
exports.getInflatedRaw = getInflatedRaw;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/zip/_shared/deflate.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Raw DEFLATE via the platform's Compression Streams API, so there is no
|
|
4
|
+
* dependency and the same code runs in the browser, Node and edge runtimes.
|
|
5
|
+
*
|
|
6
|
+
* Requires Node 21.2+, Chrome 103+, Safari 16.4+ or Firefox 113+.
|
|
7
|
+
*/
|
|
8
|
+
export declare const getDeflatedRaw: (bytes: Uint8Array) => Promise<Uint8Array>;
|
|
9
|
+
export declare const getInflatedRaw: (bytes: Uint8Array) => Promise<Uint8Array>;
|
|
10
|
+
//#endregion
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/zip/_shared/deflate.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Raw DEFLATE via the platform's Compression Streams API, so there is no
|
|
4
|
+
* dependency and the same code runs in the browser, Node and edge runtimes.
|
|
5
|
+
*
|
|
6
|
+
* Requires Node 21.2+, Chrome 103+, Safari 16.4+ or Firefox 113+.
|
|
7
|
+
*/
|
|
8
|
+
export declare const getDeflatedRaw: (bytes: Uint8Array) => Promise<Uint8Array>;
|
|
9
|
+
export declare const getInflatedRaw: (bytes: Uint8Array) => Promise<Uint8Array>;
|
|
10
|
+
//#endregion
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/zip/_shared/deflate.ts
|
|
2
|
+
/**
|
|
3
|
+
* Raw DEFLATE via the platform's Compression Streams API, so there is no
|
|
4
|
+
* dependency and the same code runs in the browser, Node and edge runtimes.
|
|
5
|
+
*
|
|
6
|
+
* Requires Node 21.2+, Chrome 103+, Safari 16.4+ or Firefox 113+.
|
|
7
|
+
*/
|
|
8
|
+
const getTransformed = async (bytes, stream) => {
|
|
9
|
+
const written = new Blob([bytes]).stream().pipeThrough(stream);
|
|
10
|
+
return new Uint8Array(await new Response(written).arrayBuffer());
|
|
11
|
+
};
|
|
12
|
+
const getDeflatedRaw = async (bytes) => {
|
|
13
|
+
return getTransformed(bytes, new CompressionStream("deflate-raw"));
|
|
14
|
+
};
|
|
15
|
+
const getInflatedRaw = async (bytes) => {
|
|
16
|
+
return getTransformed(bytes, new DecompressionStream("deflate-raw"));
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { getDeflatedRaw, getInflatedRaw };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_zip__shared_crc32 = require("./crc32.cjs");
|
|
3
|
+
const require_zip__shared_deflate = require("./deflate.cjs");
|
|
4
|
+
const require_zip__shared_readZip = require("./readZip.cjs");
|
|
5
|
+
const require_zip__shared_writeZip = require("./writeZip.cjs");
|
|
6
|
+
const require_zip__shared_ZipArchive = require("./ZipArchive.cjs");
|
|
7
|
+
exports.ZipArchive = require_zip__shared_ZipArchive.ZipArchive;
|
|
8
|
+
exports.getCrc32 = require_zip__shared_crc32.getCrc32;
|
|
9
|
+
exports.getDeflatedRaw = require_zip__shared_deflate.getDeflatedRaw;
|
|
10
|
+
exports.getInflatedRaw = require_zip__shared_deflate.getInflatedRaw;
|
|
11
|
+
exports.getZipBytes = require_zip__shared_writeZip.getZipBytes;
|
|
12
|
+
exports.getZipEntries = require_zip__shared_readZip.getZipEntries;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ZipArchive } from "./ZipArchive.cjs";
|
|
2
|
+
import { getCrc32 } from "./crc32.cjs";
|
|
3
|
+
import { getDeflatedRaw, getInflatedRaw } from "./deflate.cjs";
|
|
4
|
+
import { getZipEntries } from "./readZip.cjs";
|
|
5
|
+
import { getZipBytes } from "./writeZip.cjs";
|
|
6
|
+
export { ZipArchive, getCrc32, getDeflatedRaw, getInflatedRaw, getZipBytes, getZipEntries };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ZipArchive } from "./ZipArchive.mjs";
|
|
2
|
+
import { getCrc32 } from "./crc32.mjs";
|
|
3
|
+
import { getDeflatedRaw, getInflatedRaw } from "./deflate.mjs";
|
|
4
|
+
import { getZipEntries } from "./readZip.mjs";
|
|
5
|
+
import { getZipBytes } from "./writeZip.mjs";
|
|
6
|
+
export { ZipArchive, getCrc32, getDeflatedRaw, getInflatedRaw, getZipBytes, getZipEntries };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { getCrc32 } from "./crc32.mjs";
|
|
2
|
+
import { getDeflatedRaw, getInflatedRaw } from "./deflate.mjs";
|
|
3
|
+
import { getZipEntries } from "./readZip.mjs";
|
|
4
|
+
import { getZipBytes } from "./writeZip.mjs";
|
|
5
|
+
import { ZipArchive } from "./ZipArchive.mjs";
|
|
6
|
+
export { ZipArchive, getCrc32, getDeflatedRaw, getInflatedRaw, getZipBytes, getZipEntries };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_zip__shared_crc32 = require("./crc32.cjs");
|
|
3
|
+
const require_zip__shared_deflate = require("./deflate.cjs");
|
|
4
|
+
//#region src/zip/_shared/readZip.ts
|
|
5
|
+
const EOCD_SIGNATURE = 101010256;
|
|
6
|
+
const CENTRAL_HEADER_SIGNATURE = 33639248;
|
|
7
|
+
const LOCAL_HEADER_SIGNATURE = 67324752;
|
|
8
|
+
const EOCD_SIZE = 22;
|
|
9
|
+
const CENTRAL_HEADER_SIZE = 46;
|
|
10
|
+
const LOCAL_HEADER_SIZE = 30;
|
|
11
|
+
/** A ZIP comment is a 16-bit length, so the EOCD starts at most this far from the end. */
|
|
12
|
+
const MAX_EOCD_SEARCH = 65557;
|
|
13
|
+
const METHOD_STORED = 0;
|
|
14
|
+
const METHOD_DEFLATE = 8;
|
|
15
|
+
const getEocdOffset = (view) => {
|
|
16
|
+
const earliest = Math.max(0, view.byteLength - MAX_EOCD_SEARCH);
|
|
17
|
+
for (let offset = view.byteLength - EOCD_SIZE; offset >= earliest; offset--) if (EOCD_SIGNATURE === view.getUint32(offset, true)) return offset;
|
|
18
|
+
return -1;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Read every file entry out of a ZIP archive.
|
|
22
|
+
*
|
|
23
|
+
* Entries are keyed by their full path and returned decompressed, in central
|
|
24
|
+
* directory order. Directory entries are skipped.
|
|
25
|
+
*/
|
|
26
|
+
const getZipEntries = async (bytes) => {
|
|
27
|
+
if (bytes.byteLength < EOCD_SIZE) throw new Error("Not a ZIP archive: too short to contain an end of central directory record.");
|
|
28
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
29
|
+
const eocdOffset = getEocdOffset(view);
|
|
30
|
+
if (0 > eocdOffset) throw new Error("Not a ZIP archive: no end of central directory record found.");
|
|
31
|
+
const entryCount = view.getUint16(eocdOffset + 10, true);
|
|
32
|
+
const centralOffset = view.getUint32(eocdOffset + 16, true);
|
|
33
|
+
if (65535 === entryCount || 4294967295 === centralOffset) throw new Error("ZIP64 archives are not supported.");
|
|
34
|
+
const entries = /* @__PURE__ */ new Map();
|
|
35
|
+
const decoder = new TextDecoder();
|
|
36
|
+
let cursor = centralOffset;
|
|
37
|
+
for (let index = 0; index < entryCount; index++) {
|
|
38
|
+
if (CENTRAL_HEADER_SIGNATURE !== view.getUint32(cursor, true)) throw new Error(`Corrupt ZIP archive: bad central directory header at offset ${cursor}.`);
|
|
39
|
+
const method = view.getUint16(cursor + 10, true);
|
|
40
|
+
const expectedCrc = view.getUint32(cursor + 16, true);
|
|
41
|
+
const compressedSize = view.getUint32(cursor + 20, true);
|
|
42
|
+
const nameLength = view.getUint16(cursor + 28, true);
|
|
43
|
+
const extraLength = view.getUint16(cursor + 30, true);
|
|
44
|
+
const commentLength = view.getUint16(cursor + 32, true);
|
|
45
|
+
const localOffset = view.getUint32(cursor + 42, true);
|
|
46
|
+
const name = decoder.decode(bytes.subarray(cursor + CENTRAL_HEADER_SIZE, cursor + CENTRAL_HEADER_SIZE + nameLength));
|
|
47
|
+
cursor += CENTRAL_HEADER_SIZE + nameLength + extraLength + commentLength;
|
|
48
|
+
if (name.endsWith("/")) continue;
|
|
49
|
+
if (LOCAL_HEADER_SIGNATURE !== view.getUint32(localOffset, true)) throw new Error(`Corrupt ZIP archive: bad local header for "${name}".`);
|
|
50
|
+
const localNameLength = view.getUint16(localOffset + 26, true);
|
|
51
|
+
const localExtraLength = view.getUint16(localOffset + 28, true);
|
|
52
|
+
const dataOffset = localOffset + LOCAL_HEADER_SIZE + localNameLength + localExtraLength;
|
|
53
|
+
if (dataOffset + compressedSize > bytes.byteLength) throw new Error(`Corrupt ZIP archive: "${name}" extends past the end of the buffer.`);
|
|
54
|
+
const stored = bytes.subarray(dataOffset, dataOffset + compressedSize);
|
|
55
|
+
if (METHOD_STORED !== method && METHOD_DEFLATE !== method) throw new Error(`Unsupported compression method ${method} for "${name}".`);
|
|
56
|
+
const content = METHOD_DEFLATE === method ? await require_zip__shared_deflate.getInflatedRaw(stored) : stored.slice();
|
|
57
|
+
if (expectedCrc !== require_zip__shared_crc32.getCrc32(content)) throw new Error(`Corrupt ZIP archive: CRC mismatch for "${name}".`);
|
|
58
|
+
entries.set(name, content);
|
|
59
|
+
}
|
|
60
|
+
return entries;
|
|
61
|
+
};
|
|
62
|
+
//#endregion
|
|
63
|
+
exports.getZipEntries = getZipEntries;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/zip/_shared/readZip.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Read every file entry out of a ZIP archive.
|
|
4
|
+
*
|
|
5
|
+
* Entries are keyed by their full path and returned decompressed, in central
|
|
6
|
+
* directory order. Directory entries are skipped.
|
|
7
|
+
*/
|
|
8
|
+
export declare const getZipEntries: (bytes: Uint8Array) => Promise<Map<string, Uint8Array>>;
|
|
9
|
+
//#endregion
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/zip/_shared/readZip.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Read every file entry out of a ZIP archive.
|
|
4
|
+
*
|
|
5
|
+
* Entries are keyed by their full path and returned decompressed, in central
|
|
6
|
+
* directory order. Directory entries are skipped.
|
|
7
|
+
*/
|
|
8
|
+
export declare const getZipEntries: (bytes: Uint8Array) => Promise<Map<string, Uint8Array>>;
|
|
9
|
+
//#endregion
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getCrc32 } from "./crc32.mjs";
|
|
2
|
+
import { getInflatedRaw } from "./deflate.mjs";
|
|
3
|
+
//#region src/zip/_shared/readZip.ts
|
|
4
|
+
const EOCD_SIGNATURE = 101010256;
|
|
5
|
+
const CENTRAL_HEADER_SIGNATURE = 33639248;
|
|
6
|
+
const LOCAL_HEADER_SIGNATURE = 67324752;
|
|
7
|
+
const EOCD_SIZE = 22;
|
|
8
|
+
const CENTRAL_HEADER_SIZE = 46;
|
|
9
|
+
const LOCAL_HEADER_SIZE = 30;
|
|
10
|
+
/** A ZIP comment is a 16-bit length, so the EOCD starts at most this far from the end. */
|
|
11
|
+
const MAX_EOCD_SEARCH = 65557;
|
|
12
|
+
const METHOD_STORED = 0;
|
|
13
|
+
const METHOD_DEFLATE = 8;
|
|
14
|
+
const getEocdOffset = (view) => {
|
|
15
|
+
const earliest = Math.max(0, view.byteLength - MAX_EOCD_SEARCH);
|
|
16
|
+
for (let offset = view.byteLength - EOCD_SIZE; offset >= earliest; offset--) if (EOCD_SIGNATURE === view.getUint32(offset, true)) return offset;
|
|
17
|
+
return -1;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Read every file entry out of a ZIP archive.
|
|
21
|
+
*
|
|
22
|
+
* Entries are keyed by their full path and returned decompressed, in central
|
|
23
|
+
* directory order. Directory entries are skipped.
|
|
24
|
+
*/
|
|
25
|
+
const getZipEntries = async (bytes) => {
|
|
26
|
+
if (bytes.byteLength < EOCD_SIZE) throw new Error("Not a ZIP archive: too short to contain an end of central directory record.");
|
|
27
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
28
|
+
const eocdOffset = getEocdOffset(view);
|
|
29
|
+
if (0 > eocdOffset) throw new Error("Not a ZIP archive: no end of central directory record found.");
|
|
30
|
+
const entryCount = view.getUint16(eocdOffset + 10, true);
|
|
31
|
+
const centralOffset = view.getUint32(eocdOffset + 16, true);
|
|
32
|
+
if (65535 === entryCount || 4294967295 === centralOffset) throw new Error("ZIP64 archives are not supported.");
|
|
33
|
+
const entries = /* @__PURE__ */ new Map();
|
|
34
|
+
const decoder = new TextDecoder();
|
|
35
|
+
let cursor = centralOffset;
|
|
36
|
+
for (let index = 0; index < entryCount; index++) {
|
|
37
|
+
if (CENTRAL_HEADER_SIGNATURE !== view.getUint32(cursor, true)) throw new Error(`Corrupt ZIP archive: bad central directory header at offset ${cursor}.`);
|
|
38
|
+
const method = view.getUint16(cursor + 10, true);
|
|
39
|
+
const expectedCrc = view.getUint32(cursor + 16, true);
|
|
40
|
+
const compressedSize = view.getUint32(cursor + 20, true);
|
|
41
|
+
const nameLength = view.getUint16(cursor + 28, true);
|
|
42
|
+
const extraLength = view.getUint16(cursor + 30, true);
|
|
43
|
+
const commentLength = view.getUint16(cursor + 32, true);
|
|
44
|
+
const localOffset = view.getUint32(cursor + 42, true);
|
|
45
|
+
const name = decoder.decode(bytes.subarray(cursor + CENTRAL_HEADER_SIZE, cursor + CENTRAL_HEADER_SIZE + nameLength));
|
|
46
|
+
cursor += CENTRAL_HEADER_SIZE + nameLength + extraLength + commentLength;
|
|
47
|
+
if (name.endsWith("/")) continue;
|
|
48
|
+
if (LOCAL_HEADER_SIGNATURE !== view.getUint32(localOffset, true)) throw new Error(`Corrupt ZIP archive: bad local header for "${name}".`);
|
|
49
|
+
const localNameLength = view.getUint16(localOffset + 26, true);
|
|
50
|
+
const localExtraLength = view.getUint16(localOffset + 28, true);
|
|
51
|
+
const dataOffset = localOffset + LOCAL_HEADER_SIZE + localNameLength + localExtraLength;
|
|
52
|
+
if (dataOffset + compressedSize > bytes.byteLength) throw new Error(`Corrupt ZIP archive: "${name}" extends past the end of the buffer.`);
|
|
53
|
+
const stored = bytes.subarray(dataOffset, dataOffset + compressedSize);
|
|
54
|
+
if (METHOD_STORED !== method && METHOD_DEFLATE !== method) throw new Error(`Unsupported compression method ${method} for "${name}".`);
|
|
55
|
+
const content = METHOD_DEFLATE === method ? await getInflatedRaw(stored) : stored.slice();
|
|
56
|
+
if (expectedCrc !== getCrc32(content)) throw new Error(`Corrupt ZIP archive: CRC mismatch for "${name}".`);
|
|
57
|
+
entries.set(name, content);
|
|
58
|
+
}
|
|
59
|
+
return entries;
|
|
60
|
+
};
|
|
61
|
+
//#endregion
|
|
62
|
+
export { getZipEntries };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_zip__shared_crc32 = require("./crc32.cjs");
|
|
3
|
+
const require_zip__shared_deflate = require("./deflate.cjs");
|
|
4
|
+
//#region src/zip/_shared/writeZip.ts
|
|
5
|
+
const LOCAL_HEADER_SIGNATURE = 67324752;
|
|
6
|
+
const CENTRAL_HEADER_SIGNATURE = 33639248;
|
|
7
|
+
const EOCD_SIGNATURE = 101010256;
|
|
8
|
+
const LOCAL_HEADER_SIZE = 30;
|
|
9
|
+
const CENTRAL_HEADER_SIZE = 46;
|
|
10
|
+
const EOCD_SIZE = 22;
|
|
11
|
+
const METHOD_STORED = 0;
|
|
12
|
+
const METHOD_DEFLATE = 8;
|
|
13
|
+
const VERSION = 20;
|
|
14
|
+
/** Bit 11 of the general purpose flags marks the filename as UTF-8. */
|
|
15
|
+
const UTF8_FLAG = 2048;
|
|
16
|
+
/**
|
|
17
|
+
* Fixed at the ZIP epoch (1980-01-01 00:00) so the same input always produces the
|
|
18
|
+
* same bytes. No consumer of this library reads entry timestamps.
|
|
19
|
+
*/
|
|
20
|
+
const DOS_TIME = 0;
|
|
21
|
+
const DOS_DATE = 33;
|
|
22
|
+
const getPrepared = async (name, content) => {
|
|
23
|
+
const encodedName = new TextEncoder().encode(name);
|
|
24
|
+
const deflated = 0 === content.length ? content : await require_zip__shared_deflate.getDeflatedRaw(content);
|
|
25
|
+
const useDeflate = deflated.length < content.length;
|
|
26
|
+
return {
|
|
27
|
+
name: encodedName,
|
|
28
|
+
flags: encodedName.length === name.length ? 0 : UTF8_FLAG,
|
|
29
|
+
method: useDeflate ? METHOD_DEFLATE : METHOD_STORED,
|
|
30
|
+
crc: require_zip__shared_crc32.getCrc32(content),
|
|
31
|
+
compressedSize: useDeflate ? deflated.length : content.length,
|
|
32
|
+
size: content.length,
|
|
33
|
+
data: useDeflate ? deflated : content
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Build a ZIP archive from a map of path to file contents, preserving insertion
|
|
38
|
+
* order. Entries are deflated unless that would make them larger.
|
|
39
|
+
*/
|
|
40
|
+
const getZipBytes = async (entries) => {
|
|
41
|
+
if (entries.size > 65535) throw new Error("ZIP archives with more than 65535 entries require ZIP64, which is not supported.");
|
|
42
|
+
const prepared = [];
|
|
43
|
+
let offset = 0;
|
|
44
|
+
for (const [name, content] of entries) {
|
|
45
|
+
const entry = await getPrepared(name, content);
|
|
46
|
+
prepared.push({
|
|
47
|
+
...entry,
|
|
48
|
+
localOffset: offset
|
|
49
|
+
});
|
|
50
|
+
offset += LOCAL_HEADER_SIZE + entry.name.length + entry.compressedSize;
|
|
51
|
+
}
|
|
52
|
+
const centralOffset = offset;
|
|
53
|
+
const centralSize = prepared.reduce((total, entry) => total + CENTRAL_HEADER_SIZE + entry.name.length, 0);
|
|
54
|
+
const output = new Uint8Array(centralOffset + centralSize + EOCD_SIZE);
|
|
55
|
+
const view = new DataView(output.buffer);
|
|
56
|
+
for (const entry of prepared) {
|
|
57
|
+
const start = entry.localOffset;
|
|
58
|
+
view.setUint32(start, LOCAL_HEADER_SIGNATURE, true);
|
|
59
|
+
view.setUint16(start + 4, VERSION, true);
|
|
60
|
+
view.setUint16(start + 6, entry.flags, true);
|
|
61
|
+
view.setUint16(start + 8, entry.method, true);
|
|
62
|
+
view.setUint16(start + 10, DOS_TIME, true);
|
|
63
|
+
view.setUint16(start + 12, DOS_DATE, true);
|
|
64
|
+
view.setUint32(start + 14, entry.crc, true);
|
|
65
|
+
view.setUint32(start + 18, entry.compressedSize, true);
|
|
66
|
+
view.setUint32(start + 22, entry.size, true);
|
|
67
|
+
view.setUint16(start + 26, entry.name.length, true);
|
|
68
|
+
view.setUint16(start + 28, 0, true);
|
|
69
|
+
output.set(entry.name, start + LOCAL_HEADER_SIZE);
|
|
70
|
+
output.set(entry.data, start + LOCAL_HEADER_SIZE + entry.name.length);
|
|
71
|
+
}
|
|
72
|
+
let cursor = centralOffset;
|
|
73
|
+
for (const entry of prepared) {
|
|
74
|
+
view.setUint32(cursor, CENTRAL_HEADER_SIGNATURE, true);
|
|
75
|
+
view.setUint16(cursor + 4, VERSION, true);
|
|
76
|
+
view.setUint16(cursor + 6, VERSION, true);
|
|
77
|
+
view.setUint16(cursor + 8, entry.flags, true);
|
|
78
|
+
view.setUint16(cursor + 10, entry.method, true);
|
|
79
|
+
view.setUint16(cursor + 12, DOS_TIME, true);
|
|
80
|
+
view.setUint16(cursor + 14, DOS_DATE, true);
|
|
81
|
+
view.setUint32(cursor + 16, entry.crc, true);
|
|
82
|
+
view.setUint32(cursor + 20, entry.compressedSize, true);
|
|
83
|
+
view.setUint32(cursor + 24, entry.size, true);
|
|
84
|
+
view.setUint16(cursor + 28, entry.name.length, true);
|
|
85
|
+
view.setUint16(cursor + 30, 0, true);
|
|
86
|
+
view.setUint16(cursor + 32, 0, true);
|
|
87
|
+
view.setUint16(cursor + 34, 0, true);
|
|
88
|
+
view.setUint16(cursor + 36, 0, true);
|
|
89
|
+
view.setUint32(cursor + 38, 0, true);
|
|
90
|
+
view.setUint32(cursor + 42, entry.localOffset, true);
|
|
91
|
+
output.set(entry.name, cursor + CENTRAL_HEADER_SIZE);
|
|
92
|
+
cursor += CENTRAL_HEADER_SIZE + entry.name.length;
|
|
93
|
+
}
|
|
94
|
+
view.setUint32(cursor, EOCD_SIGNATURE, true);
|
|
95
|
+
view.setUint16(cursor + 4, 0, true);
|
|
96
|
+
view.setUint16(cursor + 6, 0, true);
|
|
97
|
+
view.setUint16(cursor + 8, prepared.length, true);
|
|
98
|
+
view.setUint16(cursor + 10, prepared.length, true);
|
|
99
|
+
view.setUint32(cursor + 12, centralSize, true);
|
|
100
|
+
view.setUint32(cursor + 16, centralOffset, true);
|
|
101
|
+
view.setUint16(cursor + 20, 0, true);
|
|
102
|
+
return output;
|
|
103
|
+
};
|
|
104
|
+
//#endregion
|
|
105
|
+
exports.getZipBytes = getZipBytes;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/zip/_shared/writeZip.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Build a ZIP archive from a map of path to file contents, preserving insertion
|
|
4
|
+
* order. Entries are deflated unless that would make them larger.
|
|
5
|
+
*/
|
|
6
|
+
export declare const getZipBytes: (entries: Map<string, Uint8Array>) => Promise<Uint8Array>;
|
|
7
|
+
//#endregion
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/zip/_shared/writeZip.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Build a ZIP archive from a map of path to file contents, preserving insertion
|
|
4
|
+
* order. Entries are deflated unless that would make them larger.
|
|
5
|
+
*/
|
|
6
|
+
export declare const getZipBytes: (entries: Map<string, Uint8Array>) => Promise<Uint8Array>;
|
|
7
|
+
//#endregion
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { getCrc32 } from "./crc32.mjs";
|
|
2
|
+
import { getDeflatedRaw } from "./deflate.mjs";
|
|
3
|
+
//#region src/zip/_shared/writeZip.ts
|
|
4
|
+
const LOCAL_HEADER_SIGNATURE = 67324752;
|
|
5
|
+
const CENTRAL_HEADER_SIGNATURE = 33639248;
|
|
6
|
+
const EOCD_SIGNATURE = 101010256;
|
|
7
|
+
const LOCAL_HEADER_SIZE = 30;
|
|
8
|
+
const CENTRAL_HEADER_SIZE = 46;
|
|
9
|
+
const EOCD_SIZE = 22;
|
|
10
|
+
const METHOD_STORED = 0;
|
|
11
|
+
const METHOD_DEFLATE = 8;
|
|
12
|
+
const VERSION = 20;
|
|
13
|
+
/** Bit 11 of the general purpose flags marks the filename as UTF-8. */
|
|
14
|
+
const UTF8_FLAG = 2048;
|
|
15
|
+
/**
|
|
16
|
+
* Fixed at the ZIP epoch (1980-01-01 00:00) so the same input always produces the
|
|
17
|
+
* same bytes. No consumer of this library reads entry timestamps.
|
|
18
|
+
*/
|
|
19
|
+
const DOS_TIME = 0;
|
|
20
|
+
const DOS_DATE = 33;
|
|
21
|
+
const getPrepared = async (name, content) => {
|
|
22
|
+
const encodedName = new TextEncoder().encode(name);
|
|
23
|
+
const deflated = 0 === content.length ? content : await getDeflatedRaw(content);
|
|
24
|
+
const useDeflate = deflated.length < content.length;
|
|
25
|
+
return {
|
|
26
|
+
name: encodedName,
|
|
27
|
+
flags: encodedName.length === name.length ? 0 : UTF8_FLAG,
|
|
28
|
+
method: useDeflate ? METHOD_DEFLATE : METHOD_STORED,
|
|
29
|
+
crc: getCrc32(content),
|
|
30
|
+
compressedSize: useDeflate ? deflated.length : content.length,
|
|
31
|
+
size: content.length,
|
|
32
|
+
data: useDeflate ? deflated : content
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Build a ZIP archive from a map of path to file contents, preserving insertion
|
|
37
|
+
* order. Entries are deflated unless that would make them larger.
|
|
38
|
+
*/
|
|
39
|
+
const getZipBytes = async (entries) => {
|
|
40
|
+
if (entries.size > 65535) throw new Error("ZIP archives with more than 65535 entries require ZIP64, which is not supported.");
|
|
41
|
+
const prepared = [];
|
|
42
|
+
let offset = 0;
|
|
43
|
+
for (const [name, content] of entries) {
|
|
44
|
+
const entry = await getPrepared(name, content);
|
|
45
|
+
prepared.push({
|
|
46
|
+
...entry,
|
|
47
|
+
localOffset: offset
|
|
48
|
+
});
|
|
49
|
+
offset += LOCAL_HEADER_SIZE + entry.name.length + entry.compressedSize;
|
|
50
|
+
}
|
|
51
|
+
const centralOffset = offset;
|
|
52
|
+
const centralSize = prepared.reduce((total, entry) => total + CENTRAL_HEADER_SIZE + entry.name.length, 0);
|
|
53
|
+
const output = new Uint8Array(centralOffset + centralSize + EOCD_SIZE);
|
|
54
|
+
const view = new DataView(output.buffer);
|
|
55
|
+
for (const entry of prepared) {
|
|
56
|
+
const start = entry.localOffset;
|
|
57
|
+
view.setUint32(start, LOCAL_HEADER_SIGNATURE, true);
|
|
58
|
+
view.setUint16(start + 4, VERSION, true);
|
|
59
|
+
view.setUint16(start + 6, entry.flags, true);
|
|
60
|
+
view.setUint16(start + 8, entry.method, true);
|
|
61
|
+
view.setUint16(start + 10, DOS_TIME, true);
|
|
62
|
+
view.setUint16(start + 12, DOS_DATE, true);
|
|
63
|
+
view.setUint32(start + 14, entry.crc, true);
|
|
64
|
+
view.setUint32(start + 18, entry.compressedSize, true);
|
|
65
|
+
view.setUint32(start + 22, entry.size, true);
|
|
66
|
+
view.setUint16(start + 26, entry.name.length, true);
|
|
67
|
+
view.setUint16(start + 28, 0, true);
|
|
68
|
+
output.set(entry.name, start + LOCAL_HEADER_SIZE);
|
|
69
|
+
output.set(entry.data, start + LOCAL_HEADER_SIZE + entry.name.length);
|
|
70
|
+
}
|
|
71
|
+
let cursor = centralOffset;
|
|
72
|
+
for (const entry of prepared) {
|
|
73
|
+
view.setUint32(cursor, CENTRAL_HEADER_SIGNATURE, true);
|
|
74
|
+
view.setUint16(cursor + 4, VERSION, true);
|
|
75
|
+
view.setUint16(cursor + 6, VERSION, true);
|
|
76
|
+
view.setUint16(cursor + 8, entry.flags, true);
|
|
77
|
+
view.setUint16(cursor + 10, entry.method, true);
|
|
78
|
+
view.setUint16(cursor + 12, DOS_TIME, true);
|
|
79
|
+
view.setUint16(cursor + 14, DOS_DATE, true);
|
|
80
|
+
view.setUint32(cursor + 16, entry.crc, true);
|
|
81
|
+
view.setUint32(cursor + 20, entry.compressedSize, true);
|
|
82
|
+
view.setUint32(cursor + 24, entry.size, true);
|
|
83
|
+
view.setUint16(cursor + 28, entry.name.length, true);
|
|
84
|
+
view.setUint16(cursor + 30, 0, true);
|
|
85
|
+
view.setUint16(cursor + 32, 0, true);
|
|
86
|
+
view.setUint16(cursor + 34, 0, true);
|
|
87
|
+
view.setUint16(cursor + 36, 0, true);
|
|
88
|
+
view.setUint32(cursor + 38, 0, true);
|
|
89
|
+
view.setUint32(cursor + 42, entry.localOffset, true);
|
|
90
|
+
output.set(entry.name, cursor + CENTRAL_HEADER_SIZE);
|
|
91
|
+
cursor += CENTRAL_HEADER_SIZE + entry.name.length;
|
|
92
|
+
}
|
|
93
|
+
view.setUint32(cursor, EOCD_SIGNATURE, true);
|
|
94
|
+
view.setUint16(cursor + 4, 0, true);
|
|
95
|
+
view.setUint16(cursor + 6, 0, true);
|
|
96
|
+
view.setUint16(cursor + 8, prepared.length, true);
|
|
97
|
+
view.setUint16(cursor + 10, prepared.length, true);
|
|
98
|
+
view.setUint32(cursor + 12, centralSize, true);
|
|
99
|
+
view.setUint32(cursor + 16, centralOffset, true);
|
|
100
|
+
view.setUint16(cursor + 20, 0, true);
|
|
101
|
+
return output;
|
|
102
|
+
};
|
|
103
|
+
//#endregion
|
|
104
|
+
export { getZipBytes };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_zip__shared_crc32 = require("../_shared/crc32.cjs");
|
|
3
|
+
const require_zip__shared_deflate = require("../_shared/deflate.cjs");
|
|
4
|
+
const require_zip__shared_readZip = require("../_shared/readZip.cjs");
|
|
5
|
+
const require_zip__shared_writeZip = require("../_shared/writeZip.cjs");
|
|
6
|
+
const require_zip__shared_ZipArchive = require("../_shared/ZipArchive.cjs");
|
|
7
|
+
exports.ZipArchive = require_zip__shared_ZipArchive.ZipArchive;
|
|
8
|
+
exports.getCrc32 = require_zip__shared_crc32.getCrc32;
|
|
9
|
+
exports.getDeflatedRaw = require_zip__shared_deflate.getDeflatedRaw;
|
|
10
|
+
exports.getInflatedRaw = require_zip__shared_deflate.getInflatedRaw;
|
|
11
|
+
exports.getZipBytes = require_zip__shared_writeZip.getZipBytes;
|
|
12
|
+
exports.getZipEntries = require_zip__shared_readZip.getZipEntries;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ZipArchive } from "../_shared/ZipArchive.cjs";
|
|
2
|
+
import { getCrc32 } from "../_shared/crc32.cjs";
|
|
3
|
+
import { getDeflatedRaw, getInflatedRaw } from "../_shared/deflate.cjs";
|
|
4
|
+
import { getZipEntries } from "../_shared/readZip.cjs";
|
|
5
|
+
import { getZipBytes } from "../_shared/writeZip.cjs";
|
|
6
|
+
export { ZipArchive, getCrc32, getDeflatedRaw, getInflatedRaw, getZipBytes, getZipEntries };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ZipArchive } from "../_shared/ZipArchive.mjs";
|
|
2
|
+
import { getCrc32 } from "../_shared/crc32.mjs";
|
|
3
|
+
import { getDeflatedRaw, getInflatedRaw } from "../_shared/deflate.mjs";
|
|
4
|
+
import { getZipEntries } from "../_shared/readZip.mjs";
|
|
5
|
+
import { getZipBytes } from "../_shared/writeZip.mjs";
|
|
6
|
+
export { ZipArchive, getCrc32, getDeflatedRaw, getInflatedRaw, getZipBytes, getZipEntries };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { getCrc32 } from "../_shared/crc32.mjs";
|
|
2
|
+
import { getDeflatedRaw, getInflatedRaw } from "../_shared/deflate.mjs";
|
|
3
|
+
import { getZipEntries } from "../_shared/readZip.mjs";
|
|
4
|
+
import { getZipBytes } from "../_shared/writeZip.mjs";
|
|
5
|
+
import { ZipArchive } from "../_shared/ZipArchive.mjs";
|
|
6
|
+
export { ZipArchive, getCrc32, getDeflatedRaw, getInflatedRaw, getZipBytes, getZipEntries };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_zip__shared_crc32 = require("../_shared/crc32.cjs");
|
|
3
|
+
const require_zip__shared_deflate = require("../_shared/deflate.cjs");
|
|
4
|
+
const require_zip__shared_readZip = require("../_shared/readZip.cjs");
|
|
5
|
+
const require_zip__shared_writeZip = require("../_shared/writeZip.cjs");
|
|
6
|
+
const require_zip__shared_ZipArchive = require("../_shared/ZipArchive.cjs");
|
|
7
|
+
exports.ZipArchive = require_zip__shared_ZipArchive.ZipArchive;
|
|
8
|
+
exports.getCrc32 = require_zip__shared_crc32.getCrc32;
|
|
9
|
+
exports.getDeflatedRaw = require_zip__shared_deflate.getDeflatedRaw;
|
|
10
|
+
exports.getInflatedRaw = require_zip__shared_deflate.getInflatedRaw;
|
|
11
|
+
exports.getZipBytes = require_zip__shared_writeZip.getZipBytes;
|
|
12
|
+
exports.getZipEntries = require_zip__shared_readZip.getZipEntries;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ZipArchive } from "../_shared/ZipArchive.cjs";
|
|
2
|
+
import { getCrc32 } from "../_shared/crc32.cjs";
|
|
3
|
+
import { getDeflatedRaw, getInflatedRaw } from "../_shared/deflate.cjs";
|
|
4
|
+
import { getZipEntries } from "../_shared/readZip.cjs";
|
|
5
|
+
import { getZipBytes } from "../_shared/writeZip.cjs";
|
|
6
|
+
export { ZipArchive, getCrc32, getDeflatedRaw, getInflatedRaw, getZipBytes, getZipEntries };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ZipArchive } from "../_shared/ZipArchive.mjs";
|
|
2
|
+
import { getCrc32 } from "../_shared/crc32.mjs";
|
|
3
|
+
import { getDeflatedRaw, getInflatedRaw } from "../_shared/deflate.mjs";
|
|
4
|
+
import { getZipEntries } from "../_shared/readZip.mjs";
|
|
5
|
+
import { getZipBytes } from "../_shared/writeZip.mjs";
|
|
6
|
+
export { ZipArchive, getCrc32, getDeflatedRaw, getInflatedRaw, getZipBytes, getZipEntries };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { getCrc32 } from "../_shared/crc32.mjs";
|
|
2
|
+
import { getDeflatedRaw, getInflatedRaw } from "../_shared/deflate.mjs";
|
|
3
|
+
import { getZipEntries } from "../_shared/readZip.mjs";
|
|
4
|
+
import { getZipBytes } from "../_shared/writeZip.mjs";
|
|
5
|
+
import { ZipArchive } from "../_shared/ZipArchive.mjs";
|
|
6
|
+
export { ZipArchive, getCrc32, getDeflatedRaw, getInflatedRaw, getZipBytes, getZipEntries };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@8ms/helpers",
|
|
3
3
|
"license": "UNLICENSED",
|
|
4
|
-
"version": "3.2.
|
|
4
|
+
"version": "3.2.7",
|
|
5
5
|
"packageManager": "yarn@4.18.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -72,7 +72,6 @@
|
|
|
72
72
|
"gaxios": "^8.0.0",
|
|
73
73
|
"google-auth-library": "^11.0.0",
|
|
74
74
|
"googleapis-common": "^9.0.0",
|
|
75
|
-
"jszip": "^3.10.1",
|
|
76
75
|
"mysql2": "^3.0.0",
|
|
77
76
|
"next": "^16.0.0",
|
|
78
77
|
"pg": "^8.0.0",
|
|
@@ -172,9 +171,6 @@
|
|
|
172
171
|
"googleapis-common": {
|
|
173
172
|
"optional": true
|
|
174
173
|
},
|
|
175
|
-
"jszip": {
|
|
176
|
-
"optional": true
|
|
177
|
-
},
|
|
178
174
|
"mysql2": {
|
|
179
175
|
"optional": true
|
|
180
176
|
},
|
|
@@ -237,7 +233,6 @@
|
|
|
237
233
|
"google-auth-library": "^11.1.0",
|
|
238
234
|
"googleapis-common": "^9.1.0",
|
|
239
235
|
"jest": "^30.5.2",
|
|
240
|
-
"jszip": "^3.10.2",
|
|
241
236
|
"mysql2": "^3.24.4",
|
|
242
237
|
"next": "^16.3.6",
|
|
243
238
|
"pg": "^8.23.0",
|
|
@@ -1819,6 +1814,38 @@
|
|
|
1819
1814
|
"import": "./dist/xml/server/getXml.mjs",
|
|
1820
1815
|
"require": "./dist/xml/server/getXml.cjs"
|
|
1821
1816
|
},
|
|
1817
|
+
"./zip/_shared": {
|
|
1818
|
+
"import": "./dist/zip/_shared/index.mjs",
|
|
1819
|
+
"require": "./dist/zip/_shared/index.cjs"
|
|
1820
|
+
},
|
|
1821
|
+
"./zip/_shared/crc32": {
|
|
1822
|
+
"import": "./dist/zip/_shared/crc32.mjs",
|
|
1823
|
+
"require": "./dist/zip/_shared/crc32.cjs"
|
|
1824
|
+
},
|
|
1825
|
+
"./zip/_shared/deflate": {
|
|
1826
|
+
"import": "./dist/zip/_shared/deflate.mjs",
|
|
1827
|
+
"require": "./dist/zip/_shared/deflate.cjs"
|
|
1828
|
+
},
|
|
1829
|
+
"./zip/_shared/readZip": {
|
|
1830
|
+
"import": "./dist/zip/_shared/readZip.mjs",
|
|
1831
|
+
"require": "./dist/zip/_shared/readZip.cjs"
|
|
1832
|
+
},
|
|
1833
|
+
"./zip/_shared/writeZip": {
|
|
1834
|
+
"import": "./dist/zip/_shared/writeZip.mjs",
|
|
1835
|
+
"require": "./dist/zip/_shared/writeZip.cjs"
|
|
1836
|
+
},
|
|
1837
|
+
"./zip/_shared/ZipArchive": {
|
|
1838
|
+
"import": "./dist/zip/_shared/ZipArchive.mjs",
|
|
1839
|
+
"require": "./dist/zip/_shared/ZipArchive.cjs"
|
|
1840
|
+
},
|
|
1841
|
+
"./zip/client": {
|
|
1842
|
+
"import": "./dist/zip/client/index.mjs",
|
|
1843
|
+
"require": "./dist/zip/client/index.cjs"
|
|
1844
|
+
},
|
|
1845
|
+
"./zip/server": {
|
|
1846
|
+
"import": "./dist/zip/server/index.mjs",
|
|
1847
|
+
"require": "./dist/zip/server/index.cjs"
|
|
1848
|
+
},
|
|
1822
1849
|
"./package.json": "./package.json"
|
|
1823
1850
|
}
|
|
1824
1851
|
}
|