Skip to content

Commit

Permalink
Bugfixes and patches
Browse files Browse the repository at this point in the history
  • Loading branch information
101arrowz committed Jan 17, 2022
1 parent e9ebdc2 commit 77fe167
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 37 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 0.7.3
- Fix folder creation for certain operating system
- Create 0-length "files" for each directory specified with "object" syntax"
- Support empty folders
- Add options for folders
- Fix minification in SWC
- Remove instanceof, no-whitespace assumptions in async functions
## 0.7.2
- Fixed TypeScript typing for errors when using `strictNullChecks`
- Fixed failure to compress files above 64kB with `{ level: 0 }`
Expand Down
29 changes: 20 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,26 +243,38 @@ const zipped = fflate.zipSync({
'dir1': {
'nested': {
// You can use Unicode in filenames
'你好.txt': strToU8('Hey there!')
'你好.txt': fflate.strToU8('Hey there!')
},
// You can also manually write out a directory path
'other/tmp.txt': new Uint8Array([97, 98, 99, 100])
},

// You can also provide compression options
'massiveImage.bmp': [aMassiveFile, {
level: 9,
mem: 12,
// ZIP-specific: mtime works here too, defaults to current time
mtime: new Date('10/20/2020')
mem: 12
}],
// PNG is pre-compressed; no need to waste time
'superTinyFile.png': [aPNGFile, { level: 0 }]
'superTinyFile.png': [aPNGFile, { level: 0 }],

// Directories take options too
'exec': [{
'hello.sh': [fflate.strToU8('echo hello world'), {
// ZIP only: Set the operating system to Unix
os: 3,
// ZIP only: Make this file executable on Unix
attrs: 0o755 << 16
}]
}, {
// ZIP and GZIP support mtime (defaults to current time)
mtime: new Date('10/20/2020')
}]
}, {
// These options are the defaults for all files, but file-specific
// options take precedence.
level: 1,
// Obfuscate mtime by default
mtime: 0
// Obfuscate last modified time by default
mtime: new Date('1/1/1980')
});

// If you write the zipped data to myzip.zip and unzip, the folder
Expand Down Expand Up @@ -442,8 +454,7 @@ gzs.terminate();
zip({ f1: aMassiveFile, 'f2.txt': anotherMassiveFile }, {
// The options object is still optional, you can still do just
// zip(archive, callback)
level: 6,
mtime: 0
level: 6
}, (err, data) => {
// Save the ZIP file
});
Expand Down
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ ___

### AsyncZippableFile

Ƭ **AsyncZippableFile**: Uint8Array \| []
Ƭ **AsyncZippableFile**: Uint8Array \| [AsyncZippable](interfaces/asynczippable.md) \| []

A file that can be used to asynchronously create a ZIP archive

Expand Down Expand Up @@ -191,7 +191,7 @@ ___

### ZippableFile

Ƭ **ZippableFile**: Uint8Array \| []
Ƭ **ZippableFile**: Uint8Array \| [Zippable](interfaces/zippable.md) \| []

A file that can be used to create a ZIP archive

Expand Down
6 changes: 4 additions & 2 deletions docs/interfaces/asynczipoptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ rwx = user permissions, rwx = group permissions, rwx = other permissions

A = archive, D = directory, V = volume label, S = system file, H = hidden, R = read-only

If you want to set the Unix permissions, for instance, just bit shift by 16, e.g. 0644 << 16
If you want to set the Unix permissions, for instance, just bit shift by 16, e.g. 0o644 << 16.
Note that attributes usually only work in conjunction with the `os` setting: you must use
`os` = 3 (Unix) if you want to set Unix permissions

___

Expand Down Expand Up @@ -145,4 +147,4 @@ ___

The operating system of origin for this file. The value is defined
by PKZIP's APPNOTE.txt, section 4.4.2.2. For example, 0 (the default)
is MS/DOS, 3 is UNIX, 19 is macOS.
is MS/DOS, 3 is Unix, 19 is macOS.
2 changes: 1 addition & 1 deletion docs/interfaces/asynczippable.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ The complete directory structure of an asynchronously ZIPpable archive

## Indexable

[path: string]: [AsyncZippable](asynczippable.md) \| [AsyncZippableFile](../README.md#asynczippablefile)
[path: string]: [AsyncZippableFile](../README.md#asynczippablefile)

The complete directory structure of an asynchronously ZIPpable archive
6 changes: 4 additions & 2 deletions docs/interfaces/zipattributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ rwx = user permissions, rwx = group permissions, rwx = other permissions

A = archive, D = directory, V = volume label, S = system file, H = hidden, R = read-only

If you want to set the Unix permissions, for instance, just bit shift by 16, e.g. 0644 << 16
If you want to set the Unix permissions, for instance, just bit shift by 16, e.g. 0o644 << 16.
Note that attributes usually only work in conjunction with the `os` setting: you must use
`os` = 3 (Unix) if you want to set Unix permissions

___

Expand Down Expand Up @@ -85,4 +87,4 @@ ___

The operating system of origin for this file. The value is defined
by PKZIP's APPNOTE.txt, section 4.4.2.2. For example, 0 (the default)
is MS/DOS, 3 is UNIX, 19 is macOS.
is MS/DOS, 3 is Unix, 19 is macOS.
6 changes: 4 additions & 2 deletions docs/interfaces/zipinputfile.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ rwx = user permissions, rwx = group permissions, rwx = other permissions

A = archive, D = directory, V = volume label, S = system file, H = hidden, R = read-only

If you want to set the Unix permissions, for instance, just bit shift by 16, e.g. 0644 << 16
If you want to set the Unix permissions, for instance, just bit shift by 16, e.g. 0o644 << 16.
Note that attributes usually only work in conjunction with the `os` setting: you must use
`os` = 3 (Unix) if you want to set Unix permissions

___

Expand Down Expand Up @@ -166,7 +168,7 @@ ___

The operating system of origin for this file. The value is defined
by PKZIP's APPNOTE.txt, section 4.4.2.2. For example, 0 (the default)
is MS/DOS, 3 is UNIX, 19 is macOS.
is MS/DOS, 3 is Unix, 19 is macOS.

___

Expand Down
6 changes: 4 additions & 2 deletions docs/interfaces/zipoptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ rwx = user permissions, rwx = group permissions, rwx = other permissions

A = archive, D = directory, V = volume label, S = system file, H = hidden, R = read-only

If you want to set the Unix permissions, for instance, just bit shift by 16, e.g. 0644 << 16
If you want to set the Unix permissions, for instance, just bit shift by 16, e.g. 0o644 << 16.
Note that attributes usually only work in conjunction with the `os` setting: you must use
`os` = 3 (Unix) if you want to set Unix permissions

___

Expand Down Expand Up @@ -133,4 +135,4 @@ ___

The operating system of origin for this file. The value is defined
by PKZIP's APPNOTE.txt, section 4.4.2.2. For example, 0 (the default)
is MS/DOS, 3 is UNIX, 19 is macOS.
is MS/DOS, 3 is Unix, 19 is macOS.
2 changes: 1 addition & 1 deletion docs/interfaces/zippable.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ The complete directory structure of a ZIPpable archive

## Indexable

[path: string]: [Zippable](zippable.md) \| [ZippableFile](../README.md#zippablefile)
[path: string]: [ZippableFile](../README.md#zippablefile)

The complete directory structure of a ZIPpable archive
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fflate",
"version": "0.7.2",
"version": "0.7.3",
"description": "High performance (de)compression in an 8kB package",
"main": "./lib/index.cjs",
"module": "./esm/browser.js",
Expand Down
37 changes: 22 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ const slc = <T extends Uint8Array | Uint16Array | Uint32Array>(v: T, s: number,
if (s == null || s < 0) s = 0;
if (e == null || e > v.length) e = v.length;
// can't use .constructor in case user-supplied
const n = new (v instanceof u16 ? u16 : v instanceof u32 ? u32 : u8)(e - s) as T;
const n = new (v.BYTES_PER_ELEMENT == 2 ? u16 : v.BYTES_PER_ELEMENT == 4 ? u32 : u8)(e - s) as T;
n.set(v.subarray(s, e));
return n;
}
Expand Down Expand Up @@ -930,7 +930,7 @@ const mrg = <A, B>(a: A, b: B) => {
const wcln = (fn: () => unknown[], fnStr: string, td: Record<string, unknown>) => {
const dt = fn();
const st = fn.toString();
const ks = st.slice(st.indexOf('[') + 1, st.lastIndexOf(']')).replace(/ /g, '').split(',');
const ks = st.slice(st.indexOf('[') + 1, st.lastIndexOf(']')).replace(/\s+/g, '').split(',');
for (let i = 0; i < dt.length; ++i) {
let v = dt[i], k = ks[i];
if (typeof v == 'function') {
Expand Down Expand Up @@ -958,7 +958,9 @@ const ch: CachedWorker[] = [];
const cbfs = (v: Record<string, unknown>) => {
const tl: ArrayBuffer[] = [];
for (const k in v) {
if (v[k] instanceof u8 || v[k] instanceof u16 || v[k] instanceof u32) tl.push((v[k] = new (v[k].constructor as typeof u8)(v[k] as Uint8Array)).buffer);
if ((v[k] as Uint8Array).buffer) {
tl.push((v[k] = new (v[k].constructor as typeof u8)(v[k] as Uint8Array)).buffer);
}
}
return tl;
}
Expand All @@ -977,7 +979,7 @@ const wrkr = <T, R>(fns: (() => unknown[])[], init: (ev: MessageEvent<T>) => voi

// base async inflate fn
const bInflt = () => [u8, u16, u32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, ec, hMap, max, bits, bits16, shft, slc, err, inflt, inflateSync, pbf, gu8];
const bDflt = () => [u8, u16, u32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]
const bDflt = () => [u8, u16, u32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf];

// gzip extra
const gze = () => [gzh, gzhl, wbytes, crc, crct];
Expand Down Expand Up @@ -1967,7 +1969,7 @@ export interface ZipAttributes {
/**
* The operating system of origin for this file. The value is defined
* by PKZIP's APPNOTE.txt, section 4.4.2.2. For example, 0 (the default)
* is MS/DOS, 3 is UNIX, 19 is macOS.
* is MS/DOS, 3 is Unix, 19 is macOS.
*/
os?: number;

Expand All @@ -1988,7 +1990,9 @@ export interface ZipAttributes {
*
* A = archive, D = directory, V = volume label, S = system file, H = hidden, R = read-only
*
* If you want to set the Unix permissions, for instance, just bit shift by 16, e.g. 0644 << 16
* If you want to set the Unix permissions, for instance, just bit shift by 16, e.g. 0o644 << 16.
* Note that attributes usually only work in conjunction with the `os` setting: you must use
* `os` = 3 (Unix) if you want to set Unix permissions
*/
attrs?: number;

Expand Down Expand Up @@ -2043,25 +2047,25 @@ export interface AsyncUnzipOptions extends UnzipOptions {}
/**
* A file that can be used to create a ZIP archive
*/
export type ZippableFile = Uint8Array | [Uint8Array, ZipOptions];
export type ZippableFile = Uint8Array | Zippable | [Uint8Array | Zippable, ZipOptions];

/**
* A file that can be used to asynchronously create a ZIP archive
*/
export type AsyncZippableFile = Uint8Array | [Uint8Array, AsyncZipOptions];
export type AsyncZippableFile = Uint8Array | AsyncZippable | [Uint8Array | AsyncZippable, AsyncZipOptions]

/**
* The complete directory structure of a ZIPpable archive
*/
export interface Zippable {
[path: string]: Zippable | ZippableFile;
[path: string]: ZippableFile;
}

/**
* The complete directory structure of an asynchronously ZIPpable archive
*/
export interface AsyncZippable {
[path: string]: AsyncZippable | AsyncZippableFile;
[path: string]: AsyncZippableFile;
}

/**
Expand Down Expand Up @@ -2096,12 +2100,15 @@ export type UnzipFileHandler = (file: UnzipFile) => void;
type FlatZippable<A extends boolean> = Record<string, [Uint8Array, (A extends true ? AsyncZipOptions : ZipOptions)]>;

// flatten a directory structure
const fltn = <A extends boolean>(d: A extends true ? AsyncZippable : Zippable, p: string, t: FlatZippable<A>, o: ZipOptions) => {
const fltn = <A extends boolean, D = A extends true ? AsyncZippable : Zippable>(d: D, p: string, t: FlatZippable<A>, o: ZipOptions) => {
for (const k in d) {
const val = d[k], n = p + k;
if (val instanceof u8) t[n] = [val, o] as unknown as FlatZippable<A>[string];
else if (Array.isArray(val)) t[n] = [val[0], mrg(o, val[1])] as FlatZippable<A>[string];
else fltn(val as unknown as (A extends true ? AsyncZippable : Zippable), n + '/', t, o);
let val = d[k], n = p + k, op = o;
if (Array.isArray(val)) op = mrg(o, val[1]), val = val[0] as unknown as D[Extract<keyof D, string>];
if (val instanceof u8) t[n] = [val, op] as unknown as FlatZippable<A>[string];
else {
t[n += '/'] = [new u8(0), op] as unknown as FlatZippable<A>[string];
fltn(val as unknown as (A extends true ? AsyncZippable : Zippable), n, t, o);
}
}
}

Expand Down

0 comments on commit 77fe167

Please sign in to comment.