switch to separate explicit functions for different kinds of output
This commit is contained in:
parent
be93cdb011
commit
fc02ddd709
|
@ -11,13 +11,14 @@ Stick some text files into a zip file. This library is super simple and small be
|
||||||
## How
|
## How
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import doNotZip from 'do-not-zip';
|
import * as doNotZip from 'do-not-zip';
|
||||||
const output = doNotZip([
|
const output = doNotZip.toArray([
|
||||||
{ path: 'path/to/file1.txt', data: 'Hello' },
|
{ path: 'path/to/file1.txt', data: 'Hello' },
|
||||||
{ path: 'another/file2.txt', data: 'World' },
|
{ path: 'another/file2.txt', data: 'World' },
|
||||||
{ path: 'yet/another/file3.bin', data: [1, 2, 3, 4, 5] },
|
{ path: 'yet/another/file3.bin', data: [1, 2, 3, 4, 5] },
|
||||||
]);
|
]);
|
||||||
// => output will be a Buffer on the server and a Blob on the client
|
// => output will be an array of bytes
|
||||||
|
// use .toBuffer on the server to generate a Buffer, and use .toBlob on the client to generate a Blog
|
||||||
```
|
```
|
||||||
|
|
||||||
## Thanks
|
## Thanks
|
||||||
|
|
|
@ -8,9 +8,8 @@
|
||||||
"archive"
|
"archive"
|
||||||
],
|
],
|
||||||
"main": "./dist/index.cjs.js",
|
"main": "./dist/index.cjs.js",
|
||||||
"module": "./src/index.js",
|
"module": "./dist/index.es.js",
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
|
||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
export default {
|
export default {
|
||||||
input: './src/index.js',
|
input: './src/index.js',
|
||||||
output: [
|
output: [
|
||||||
|
{
|
||||||
|
file: './dist/index.es.js',
|
||||||
|
format: 'es',
|
||||||
|
sourcemap: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
file: './dist/index.cjs.js',
|
file: './dist/index.cjs.js',
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
const table = [];
|
||||||
|
for (let n = 0; n < 256; n++) {
|
||||||
|
let c = n;
|
||||||
|
for (let k = 0; k < 8; k++) {
|
||||||
|
c = c & 1 ? 0xEDB88320 ^ (c >>> 1) : c >>> 1;
|
||||||
|
}
|
||||||
|
table[n] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default bytes => {
|
||||||
|
let sum = -1;
|
||||||
|
for (const byte of bytes) {
|
||||||
|
sum = (sum >>> 8) ^ table[(sum ^ byte) & 0xFF];
|
||||||
|
}
|
||||||
|
return sum ^ -1;
|
||||||
|
};
|
52
src/index.js
52
src/index.js
|
@ -1,49 +1,3 @@
|
||||||
// do-not-zip.js
|
export { default as toArray } from './toArray.js';
|
||||||
// Construct a Buffer or a Blob of a .zip file with no compression, on the server or in the browser
|
export { default as toBlob } from './toBlob.js';
|
||||||
|
export { default as toBuffer } from './toBuffer.js';
|
||||||
const crcTable = [];
|
|
||||||
for (let n = 0; n < 256; n++) {
|
|
||||||
let c = n;
|
|
||||||
for (let k = 0; k < 8; k++) {
|
|
||||||
c = c & 1 ? 0xEDB88320 ^ (c >>> 1) : c >>> 1;
|
|
||||||
}
|
|
||||||
crcTable[n] = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
const crc32 = bytes => {
|
|
||||||
let sum = -1;
|
|
||||||
for (const byte of bytes) {
|
|
||||||
sum = (sum >>> 8) ^ crcTable[(sum ^ byte) & 0xFF];
|
|
||||||
}
|
|
||||||
return sum ^ -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
const int = (n, length) => {
|
|
||||||
const out = [];
|
|
||||||
while (length--) {
|
|
||||||
out.push(n & 0xFF);
|
|
||||||
n >>>= 8;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
const toBytes = data => typeof data === 'string' ? [...data].map(char => char.charCodeAt(0)) : data;
|
|
||||||
|
|
||||||
export default files => {
|
|
||||||
let fileData = [];
|
|
||||||
const centralDirectory = [];
|
|
||||||
for (const { path, data } of files) {
|
|
||||||
const dataBytes = toBytes(data);
|
|
||||||
const pathBytes = toBytes(path);
|
|
||||||
const commonHeader = [0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ...int(crc32(dataBytes), 4), ...int(dataBytes.length, 4), ...int(dataBytes.length, 4), ...int(pathBytes.length, 2), 0x00, 0x00];
|
|
||||||
centralDirectory.push(0x50, 0x4B, 0x01, 0x02, 0x14, 0x00, ...commonHeader, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ...int(fileData.length, 4), ...pathBytes);
|
|
||||||
fileData = [...fileData, 0x50, 0x4B, 0x03, 0x04, ...commonHeader, ...pathBytes, ...dataBytes];
|
|
||||||
}
|
|
||||||
const bytes = [...fileData, ...centralDirectory, 0x50, 0x4B, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, ...int(files.length, 2), ...int(files.length, 2), ...int(centralDirectory.length, 4), ...int(fileData.length, 4), 0x00, 0x00];
|
|
||||||
if (typeof Blob !== 'undefined' && typeof Uint8Array !== 'undefined') {
|
|
||||||
return new Blob([Uint8Array.from(bytes)], { type: 'application/zip' });
|
|
||||||
}
|
|
||||||
if (typeof Buffer !== 'undefined') {
|
|
||||||
return Buffer.from(bytes);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import crc32 from './crc32.js';
|
||||||
|
|
||||||
|
const int = (n, length) => {
|
||||||
|
const out = [];
|
||||||
|
while (length--) {
|
||||||
|
out.push(n & 0xFF);
|
||||||
|
n >>>= 8;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
const toBytes = data => typeof data === 'string' ? [...data].map(char => char.charCodeAt(0)) : data;
|
||||||
|
|
||||||
|
export default files => {
|
||||||
|
let fileData = [];
|
||||||
|
const centralDirectory = [];
|
||||||
|
for (const { path, data } of files) {
|
||||||
|
const dataBytes = toBytes(data);
|
||||||
|
const pathBytes = toBytes(path);
|
||||||
|
const commonHeader = [0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ...int(crc32(dataBytes), 4), ...int(dataBytes.length, 4), ...int(dataBytes.length, 4), ...int(pathBytes.length, 2), 0x00, 0x00];
|
||||||
|
centralDirectory.push(0x50, 0x4B, 0x01, 0x02, 0x14, 0x00, ...commonHeader, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ...int(fileData.length, 4), ...pathBytes);
|
||||||
|
fileData = [...fileData, 0x50, 0x4B, 0x03, 0x04, ...commonHeader, ...pathBytes, ...dataBytes];
|
||||||
|
}
|
||||||
|
return [...fileData, ...centralDirectory, 0x50, 0x4B, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, ...int(files.length, 2), ...int(files.length, 2), ...int(centralDirectory.length, 4), ...int(fileData.length, 4), 0x00, 0x00];
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
import toArray from './toArray.js';
|
||||||
|
|
||||||
|
export default files => new Blob([Uint8Array.from(toArray(files))], { type: 'application/zip' });
|
|
@ -0,0 +1,3 @@
|
||||||
|
import toArray from './toArray.js';
|
||||||
|
|
||||||
|
export default files => Buffer.from(toArray(files));
|
Loading…
Reference in New Issue