@neoware_inc/neozipkit 0.5.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 +134 -0
- package/dist/browser/ZipkitBrowser.d.ts +27 -0
- package/dist/browser/ZipkitBrowser.d.ts.map +1 -0
- package/dist/browser/ZipkitBrowser.js +303 -0
- package/dist/browser/ZipkitBrowser.js.map +1 -0
- package/dist/browser/index.d.ts +9 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.esm.d.ts +12 -0
- package/dist/browser/index.esm.d.ts.map +1 -0
- package/dist/browser/index.esm.js +46 -0
- package/dist/browser/index.esm.js.map +1 -0
- package/dist/browser/index.js +38 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser-esm/index.d.ts +9 -0
- package/dist/browser-esm/index.js +50211 -0
- package/dist/browser-esm/index.js.map +7 -0
- package/dist/browser-umd/index.d.ts +9 -0
- package/dist/browser-umd/index.js +50221 -0
- package/dist/browser-umd/index.js.map +7 -0
- package/dist/browser-umd/index.min.js +39 -0
- package/dist/browser.d.ts +9 -0
- package/dist/browser.js +38 -0
- package/dist/core/ZipCompress.d.ts +99 -0
- package/dist/core/ZipCompress.d.ts.map +1 -0
- package/dist/core/ZipCompress.js +287 -0
- package/dist/core/ZipCompress.js.map +1 -0
- package/dist/core/ZipCopy.d.ts +175 -0
- package/dist/core/ZipCopy.d.ts.map +1 -0
- package/dist/core/ZipCopy.js +310 -0
- package/dist/core/ZipCopy.js.map +1 -0
- package/dist/core/ZipDecompress.d.ts +57 -0
- package/dist/core/ZipDecompress.d.ts.map +1 -0
- package/dist/core/ZipDecompress.js +155 -0
- package/dist/core/ZipDecompress.js.map +1 -0
- package/dist/core/ZipEntry.d.ts +138 -0
- package/dist/core/ZipEntry.d.ts.map +1 -0
- package/dist/core/ZipEntry.js +829 -0
- package/dist/core/ZipEntry.js.map +1 -0
- package/dist/core/Zipkit.d.ts +315 -0
- package/dist/core/Zipkit.d.ts.map +1 -0
- package/dist/core/Zipkit.js +647 -0
- package/dist/core/Zipkit.js.map +1 -0
- package/dist/core/ZstdManager.d.ts +56 -0
- package/dist/core/ZstdManager.d.ts.map +1 -0
- package/dist/core/ZstdManager.js +144 -0
- package/dist/core/ZstdManager.js.map +1 -0
- package/dist/core/components/HashCalculator.d.ts +138 -0
- package/dist/core/components/HashCalculator.d.ts.map +1 -0
- package/dist/core/components/HashCalculator.js +360 -0
- package/dist/core/components/HashCalculator.js.map +1 -0
- package/dist/core/components/Logger.d.ts +73 -0
- package/dist/core/components/Logger.d.ts.map +1 -0
- package/dist/core/components/Logger.js +156 -0
- package/dist/core/components/Logger.js.map +1 -0
- package/dist/core/components/ProgressTracker.d.ts +43 -0
- package/dist/core/components/ProgressTracker.d.ts.map +1 -0
- package/dist/core/components/ProgressTracker.js +112 -0
- package/dist/core/components/ProgressTracker.js.map +1 -0
- package/dist/core/components/Support.d.ts +64 -0
- package/dist/core/components/Support.d.ts.map +1 -0
- package/dist/core/components/Support.js +71 -0
- package/dist/core/components/Support.js.map +1 -0
- package/dist/core/components/Util.d.ts +26 -0
- package/dist/core/components/Util.d.ts.map +1 -0
- package/dist/core/components/Util.js +95 -0
- package/dist/core/components/Util.js.map +1 -0
- package/dist/core/constants/Errors.d.ts +52 -0
- package/dist/core/constants/Errors.d.ts.map +1 -0
- package/dist/core/constants/Errors.js +67 -0
- package/dist/core/constants/Errors.js.map +1 -0
- package/dist/core/constants/Headers.d.ts +170 -0
- package/dist/core/constants/Headers.d.ts.map +1 -0
- package/dist/core/constants/Headers.js +194 -0
- package/dist/core/constants/Headers.js.map +1 -0
- package/dist/core/encryption/Manager.d.ts +58 -0
- package/dist/core/encryption/Manager.d.ts.map +1 -0
- package/dist/core/encryption/Manager.js +121 -0
- package/dist/core/encryption/Manager.js.map +1 -0
- package/dist/core/encryption/ZipCrypto.d.ts +172 -0
- package/dist/core/encryption/ZipCrypto.d.ts.map +1 -0
- package/dist/core/encryption/ZipCrypto.js +554 -0
- package/dist/core/encryption/ZipCrypto.js.map +1 -0
- package/dist/core/encryption/index.d.ts +9 -0
- package/dist/core/encryption/index.d.ts.map +1 -0
- package/dist/core/encryption/index.js +17 -0
- package/dist/core/encryption/index.js.map +1 -0
- package/dist/core/encryption/types.d.ts +29 -0
- package/dist/core/encryption/types.d.ts.map +1 -0
- package/dist/core/encryption/types.js +12 -0
- package/dist/core/encryption/types.js.map +1 -0
- package/dist/core/index.d.ts +27 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +59 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/version.d.ts +5 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +31 -0
- package/dist/core/version.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/node/ZipCompressNode.d.ts +123 -0
- package/dist/node/ZipCompressNode.d.ts.map +1 -0
- package/dist/node/ZipCompressNode.js +565 -0
- package/dist/node/ZipCompressNode.js.map +1 -0
- package/dist/node/ZipCopyNode.d.ts +165 -0
- package/dist/node/ZipCopyNode.d.ts.map +1 -0
- package/dist/node/ZipCopyNode.js +347 -0
- package/dist/node/ZipCopyNode.js.map +1 -0
- package/dist/node/ZipDecompressNode.d.ts +197 -0
- package/dist/node/ZipDecompressNode.d.ts.map +1 -0
- package/dist/node/ZipDecompressNode.js +678 -0
- package/dist/node/ZipDecompressNode.js.map +1 -0
- package/dist/node/ZipkitNode.d.ts +466 -0
- package/dist/node/ZipkitNode.d.ts.map +1 -0
- package/dist/node/ZipkitNode.js +1426 -0
- package/dist/node/ZipkitNode.js.map +1 -0
- package/dist/node/index.d.ts +25 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +54 -0
- package/dist/node/index.js.map +1 -0
- package/dist/types/index.d.ts +45 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -0
- package/examples/README.md +261 -0
- package/examples/append-data.json +44 -0
- package/examples/copy-zip-append.ts +139 -0
- package/examples/copy-zip.ts +152 -0
- package/examples/create-zip.ts +172 -0
- package/examples/extract-zip.ts +118 -0
- package/examples/list-zip.ts +161 -0
- package/examples/test-files/data.json +116 -0
- package/examples/test-files/document.md +80 -0
- package/examples/test-files/document.txt +6 -0
- package/examples/test-files/file1.txt +48 -0
- package/examples/test-files/file2.txt +80 -0
- package/examples/tsconfig.json +44 -0
- package/package.json +167 -0
- package/src/browser/ZipkitBrowser.ts +305 -0
- package/src/browser/index.esm.ts +32 -0
- package/src/browser/index.ts +19 -0
- package/src/core/ZipCompress.ts +370 -0
- package/src/core/ZipCopy.ts +434 -0
- package/src/core/ZipDecompress.ts +191 -0
- package/src/core/ZipEntry.ts +917 -0
- package/src/core/Zipkit.ts +794 -0
- package/src/core/ZstdManager.ts +165 -0
- package/src/core/components/HashCalculator.ts +384 -0
- package/src/core/components/Logger.ts +180 -0
- package/src/core/components/ProgressTracker.ts +134 -0
- package/src/core/components/Support.ts +77 -0
- package/src/core/components/Util.ts +91 -0
- package/src/core/constants/Errors.ts +78 -0
- package/src/core/constants/Headers.ts +205 -0
- package/src/core/encryption/Manager.ts +137 -0
- package/src/core/encryption/ZipCrypto.ts +650 -0
- package/src/core/encryption/index.ts +15 -0
- package/src/core/encryption/types.ts +33 -0
- package/src/core/index.ts +42 -0
- package/src/core/version.ts +33 -0
- package/src/index.ts +19 -0
- package/src/node/ZipCompressNode.ts +618 -0
- package/src/node/ZipCopyNode.ts +437 -0
- package/src/node/ZipDecompressNode.ts +793 -0
- package/src/node/ZipkitNode.ts +1706 -0
- package/src/node/index.ts +40 -0
- package/src/types/index.ts +68 -0
- package/src/types/modules.d.ts +22 -0
- package/src/types/opentimestamps.d.ts +1 -0
package/package.json
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@neoware_inc/neozipkit",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"packageManager": "yarn@4.12.0",
|
|
5
|
+
"description": "NeoZipKit - Advanced ZIP file creation, compression, and encryption",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"browser": {
|
|
11
|
+
"types": "./dist/browser.d.ts",
|
|
12
|
+
"default": "./dist/browser.js"
|
|
13
|
+
},
|
|
14
|
+
"node": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./browser": {
|
|
22
|
+
"types": "./dist/browser.d.ts",
|
|
23
|
+
"default": "./dist/browser.js"
|
|
24
|
+
},
|
|
25
|
+
"./browser/*": {
|
|
26
|
+
"types": "./dist/browser/*.d.ts",
|
|
27
|
+
"default": "./dist/browser/*.js"
|
|
28
|
+
},
|
|
29
|
+
"./browser-esm": {
|
|
30
|
+
"types": "./dist/browser-esm/index.d.ts",
|
|
31
|
+
"import": "./dist/browser-esm/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./browser-umd": {
|
|
34
|
+
"types": "./dist/browser-umd/index.d.ts",
|
|
35
|
+
"import": "./dist/browser-umd/index.js",
|
|
36
|
+
"require": "./dist/browser-umd/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./node": {
|
|
39
|
+
"types": "./dist/node/index.d.ts",
|
|
40
|
+
"import": "./dist/node/index.js",
|
|
41
|
+
"require": "./dist/node/index.js",
|
|
42
|
+
"default": "./dist/node/index.js"
|
|
43
|
+
},
|
|
44
|
+
"./node/*": {
|
|
45
|
+
"types": "./dist/node/*.d.ts",
|
|
46
|
+
"default": "./dist/node/*.js"
|
|
47
|
+
},
|
|
48
|
+
"./node/platform/*": {
|
|
49
|
+
"types": "./dist/node/platform/*.d.ts",
|
|
50
|
+
"default": "./dist/node/platform/*.js"
|
|
51
|
+
},
|
|
52
|
+
"./shared": {
|
|
53
|
+
"types": "./dist/shared/index.d.ts",
|
|
54
|
+
"default": "./dist/shared/index.js"
|
|
55
|
+
},
|
|
56
|
+
"./shared/*": {
|
|
57
|
+
"types": "./dist/shared/*.d.ts",
|
|
58
|
+
"default": "./dist/shared/*.js"
|
|
59
|
+
},
|
|
60
|
+
"./shared/components/*": {
|
|
61
|
+
"types": "./dist/shared/components/*.d.ts",
|
|
62
|
+
"default": "./dist/shared/components/*.js"
|
|
63
|
+
},
|
|
64
|
+
"./shared/constants/*": {
|
|
65
|
+
"types": "./dist/shared/constants/*.d.ts",
|
|
66
|
+
"default": "./dist/shared/constants/*.js"
|
|
67
|
+
},
|
|
68
|
+
"./src": {
|
|
69
|
+
"types": "./src/index.ts",
|
|
70
|
+
"default": "./src/index.ts"
|
|
71
|
+
},
|
|
72
|
+
"./src/*": {
|
|
73
|
+
"types": "./src/*.ts",
|
|
74
|
+
"default": "./src/*.ts"
|
|
75
|
+
},
|
|
76
|
+
"./src/node": {
|
|
77
|
+
"types": "./src/node/index.ts",
|
|
78
|
+
"default": "./src/node/index.ts"
|
|
79
|
+
},
|
|
80
|
+
"./src/node/*": {
|
|
81
|
+
"types": "./src/node/*.ts",
|
|
82
|
+
"default": "./src/node/*.ts"
|
|
83
|
+
},
|
|
84
|
+
"./src/components/*": {
|
|
85
|
+
"types": "./src/components/*.ts",
|
|
86
|
+
"default": "./src/components/*.ts"
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"files": [
|
|
90
|
+
"dist/",
|
|
91
|
+
"src/",
|
|
92
|
+
"examples/",
|
|
93
|
+
"README.md"
|
|
94
|
+
],
|
|
95
|
+
"scripts": {
|
|
96
|
+
"clean": "node scripts/clean.js",
|
|
97
|
+
"compile": "tsc",
|
|
98
|
+
"create-browser-entry": "node scripts/create-browser-entry.js",
|
|
99
|
+
"build": "npm run clean && npm run compile && npm run create-browser-entry && npm run build:browser",
|
|
100
|
+
"build:browser": "npm run build:browser:esm && npm run build:browser:umd",
|
|
101
|
+
"build:browser:esm": "node scripts/build-browser-bundle.js --esm",
|
|
102
|
+
"build:browser:umd": "node scripts/build-browser-bundle.js --umd",
|
|
103
|
+
"watch": "tsc --watch",
|
|
104
|
+
"dev:clean": "node scripts/dev-clean.js",
|
|
105
|
+
"dev:compile": "tsc --project tsconfig.dev.json",
|
|
106
|
+
"dev:create-browser-entry": "node scripts/dev-create-browser-entry.js",
|
|
107
|
+
"dev:build": "npm run dev:clean && npm run dev:compile && npm run dev:create-browser-entry",
|
|
108
|
+
"dev:watch": "tsc --project tsconfig.dev.json --watch",
|
|
109
|
+
"build:auto": "node scripts/auto-build.js",
|
|
110
|
+
"build:ci": "node scripts/check-branch.js && npm run clean && npm run compile && npm run create-browser-entry",
|
|
111
|
+
"test": "yarn exec jest",
|
|
112
|
+
"test:unit": "yarn exec jest tests/unit",
|
|
113
|
+
"test:examples": "yarn exec ts-node scripts/test-examples.ts",
|
|
114
|
+
"test:all": "npm run test:unit && npm run test:examples",
|
|
115
|
+
"test:watch": "yarn exec jest --watch",
|
|
116
|
+
"test:coverage": "yarn exec jest --coverage",
|
|
117
|
+
"audit": "yarn npm audit",
|
|
118
|
+
"example:create-zip": "npx ts-node examples/create-zip.ts",
|
|
119
|
+
"example:extract-zip": "npx ts-node examples/extract-zip.ts",
|
|
120
|
+
"example:list-zip": "npx ts-node examples/list-zip.ts",
|
|
121
|
+
"example:copy-zip": "npx ts-node examples/copy-zip.ts",
|
|
122
|
+
"release": "node scripts/ensure-npm-auth.js && yarn build && npm publish --access public",
|
|
123
|
+
"release:login": "npm login",
|
|
124
|
+
"version": "node scripts/update-version.js",
|
|
125
|
+
"version:set": "node scripts/update-version.js",
|
|
126
|
+
"version:patch": "node scripts/update-version.js patch",
|
|
127
|
+
"version:minor": "node scripts/update-version.js minor",
|
|
128
|
+
"version:major": "node scripts/update-version.js major"
|
|
129
|
+
},
|
|
130
|
+
"keywords": [
|
|
131
|
+
"zip",
|
|
132
|
+
"archive",
|
|
133
|
+
"verification",
|
|
134
|
+
"crypto",
|
|
135
|
+
"compression",
|
|
136
|
+
"encryption"
|
|
137
|
+
],
|
|
138
|
+
"author": "NeoWare, Inc.",
|
|
139
|
+
"repository": {
|
|
140
|
+
"type": "git",
|
|
141
|
+
"url": "git+https://github.com/NeoWareInc/neozipkit.git"
|
|
142
|
+
},
|
|
143
|
+
"bugs": {
|
|
144
|
+
"url": "https://github.com/NeoWareInc/neozipkit/issues"
|
|
145
|
+
},
|
|
146
|
+
"homepage": "https://github.com/NeoWareInc/neozipkit#readme",
|
|
147
|
+
"license": "MIT",
|
|
148
|
+
"devDependencies": {
|
|
149
|
+
"@jest/core": "29.7.0",
|
|
150
|
+
"@jest/test-sequencer": "29.7.0",
|
|
151
|
+
"@types/jest": "29.5.12",
|
|
152
|
+
"@types/node": "^24.3.1",
|
|
153
|
+
"@types/pako": "^2.0.3",
|
|
154
|
+
"@types/uuid": "^9.0.0",
|
|
155
|
+
"esbuild": "^0.25.0",
|
|
156
|
+
"jest": "29.7.0",
|
|
157
|
+
"minimatch": "^10.2.1",
|
|
158
|
+
"ts-jest": "29.1.2",
|
|
159
|
+
"typescript": "^5.0.0"
|
|
160
|
+
},
|
|
161
|
+
"dependencies": {
|
|
162
|
+
"@oneidentity/zstd-js": "^1.0.3",
|
|
163
|
+
"buffer": "^6.0.3",
|
|
164
|
+
"pako": "^2.1.0",
|
|
165
|
+
"uuid": "^9.0.0"
|
|
166
|
+
}
|
|
167
|
+
}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
// ======================================
|
|
2
|
+
// ZipkitBrowser.ts
|
|
3
|
+
// Copyright (c) 2025 NeoWare, Inc. All rights reserved.
|
|
4
|
+
// ======================================
|
|
5
|
+
|
|
6
|
+
import Zipkit, { CompressOptions, CreateZipOptions } from '../core';
|
|
7
|
+
import ZipEntry from '../core/ZipEntry';
|
|
8
|
+
import { ZipCompress } from '../core/ZipCompress';
|
|
9
|
+
import Errors from '../core/constants/Errors';
|
|
10
|
+
import * as Headers from '../core/constants/Headers';
|
|
11
|
+
import { TOKENIZED_METADATA, TIMESTAMP_SUBMITTED, TIMESTAMP_METADATA } from '../core/constants/Headers';
|
|
12
|
+
import { sha256, crc32 } from '../core/encryption/ZipCrypto';
|
|
13
|
+
import { DATATYPE, getTypeOf } from '../core/components/Util';
|
|
14
|
+
import type { FileData } from '../types';
|
|
15
|
+
import HashCalculator from '../core/components/HashCalculator';
|
|
16
|
+
|
|
17
|
+
// Re-export everything from Zipkit
|
|
18
|
+
export * from '../core';
|
|
19
|
+
export { ZipEntry, Errors, Headers, sha256, getTypeOf };
|
|
20
|
+
|
|
21
|
+
// ======================================
|
|
22
|
+
// ZipkitBrowser
|
|
23
|
+
// ======================================
|
|
24
|
+
|
|
25
|
+
export default class ZipkitBrowser extends Zipkit {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(); // Call the parent constructor
|
|
28
|
+
|
|
29
|
+
// console.log('Zipkit.support.isNode: ', Zipkit.support.isNode);
|
|
30
|
+
// console.log('Zipkit.support.buffer: ', Zipkit.support.buffer);
|
|
31
|
+
// console.log('Zipkit.support.blob: ', Zipkit.support.blob);
|
|
32
|
+
// console.log('Zipkit.support.streams: ', Zipkit.support.streams);
|
|
33
|
+
// console.log('Zipkit.support.fileReader: ', Zipkit.support.fileReader);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// --------------------------------------
|
|
37
|
+
// Load a ZIP file from a Blob and return the ZipEntry array
|
|
38
|
+
// Always uses loadZip() to ensure proper initialization
|
|
39
|
+
|
|
40
|
+
async loadZipBlob(data: Blob): Promise<ZipEntry[] | null> {
|
|
41
|
+
if (getTypeOf(data) !== DATATYPE.BLOB) {
|
|
42
|
+
throw new Error(Errors.DATATYPE_UNSUPPORTED);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
const reader = new window.FileReader();
|
|
47
|
+
reader.readAsArrayBuffer(data);
|
|
48
|
+
|
|
49
|
+
reader.onload = (e: ProgressEvent<FileReader>) => {
|
|
50
|
+
if (!reader.result) {
|
|
51
|
+
reject(new Error('Failed to read file'));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
// Convert ArrayBuffer to Buffer
|
|
57
|
+
const buffer = Buffer.from(reader.result as ArrayBuffer);
|
|
58
|
+
|
|
59
|
+
// Always use loadZip() which:
|
|
60
|
+
// 1. Resets ZIP data
|
|
61
|
+
// 2. Stores buffer in this.inBuffer
|
|
62
|
+
// 3. Loads EOCD and parses central directory
|
|
63
|
+
// 4. Stores entries in this.zipEntries
|
|
64
|
+
// 5. Returns the entries
|
|
65
|
+
const entries = super.loadZip(buffer);
|
|
66
|
+
resolve(entries);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
reject(error);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
reader.onerror = () => {
|
|
73
|
+
reject(reader.error || new Error('Failed to read file'));
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// --------------------------------------
|
|
79
|
+
// Create a ZipEntry for a File object
|
|
80
|
+
|
|
81
|
+
createZipFileEntry(file: FileData): ZipEntry {
|
|
82
|
+
const entry = super.createZipEntry(file.name);
|
|
83
|
+
entry.fileData = file;
|
|
84
|
+
entry.uncompressedSize = file.size;
|
|
85
|
+
|
|
86
|
+
const fileDate = new Date(file.lastModified);
|
|
87
|
+
entry.timeDateDOS = entry.setDateTime(fileDate);
|
|
88
|
+
entry.cmpMethod = Headers.CMP_METHOD.DEFLATED;
|
|
89
|
+
|
|
90
|
+
return entry;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// --------------------------------------
|
|
94
|
+
// Calculate the SHA256 hash of a File object
|
|
95
|
+
|
|
96
|
+
async hashFile(file: FileData): Promise<string> {
|
|
97
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
98
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
99
|
+
return sha256(buffer);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// --------------------------------------
|
|
103
|
+
// Compress the data and return the compressed data buffer
|
|
104
|
+
// Set the ZipEntry compressSize and CRC32 values
|
|
105
|
+
|
|
106
|
+
async compressDataBlob(entry: ZipEntry, data: Blob, options?: CompressOptions): Promise<Buffer> {
|
|
107
|
+
if (getTypeOf(data) !== DATATYPE.BLOB) {
|
|
108
|
+
throw new Error(Errors.DATATYPE_UNSUPPORTED);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return new Promise(async (resolve, reject) => {
|
|
112
|
+
const _compressData = async (entry: ZipEntry, data: Buffer, options?: CompressOptions): Promise<Buffer> => {
|
|
113
|
+
// Use Zipkit wrapper method
|
|
114
|
+
return await this.compressData(entry, data, options);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const reader = new window.FileReader();
|
|
118
|
+
reader.readAsArrayBuffer(data);
|
|
119
|
+
|
|
120
|
+
reader.onload = async function(this: FileReader, e: ProgressEvent<FileReader>) {
|
|
121
|
+
if (!this.result) {
|
|
122
|
+
reject(new Error('Failed to read file'));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const _inBuf = Buffer.from(this.result as ArrayBuffer);
|
|
127
|
+
const result = await _compressData(entry, _inBuf, options);
|
|
128
|
+
resolve(result);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
reject(error);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
reader.onerror = function(this: FileReader, e: ProgressEvent<FileReader>) {
|
|
135
|
+
reject(this.error || new Error('Failed to read file'));
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// --------------------------------------
|
|
141
|
+
// Extract a Blob from a ZipEntry
|
|
142
|
+
|
|
143
|
+
async extractBlob(entry: ZipEntry, skipHashCheck?: boolean): Promise<Blob | null> {
|
|
144
|
+
try {
|
|
145
|
+
const _outBuf = await this.extract(entry, skipHashCheck);
|
|
146
|
+
if (!_outBuf) return null;
|
|
147
|
+
|
|
148
|
+
// Convert Buffer to Uint8Array for Blob compatibility
|
|
149
|
+
const uint8Array = new Uint8Array(_outBuf);
|
|
150
|
+
return new Blob([uint8Array], { type: 'application/octet-stream' });
|
|
151
|
+
} catch (error) {
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// --------------------------------------
|
|
157
|
+
// Create a ZIP file in memory and return a Blob
|
|
158
|
+
|
|
159
|
+
async createZipBlob(cmpOptions?: CompressOptions, options?: CreateZipOptions): Promise<Blob | null> {
|
|
160
|
+
const _onError = options?.onError || (() => {});
|
|
161
|
+
const _onEntryDone = options?.onEntryDone || (() => {});
|
|
162
|
+
|
|
163
|
+
const zipEntries = super.getDirectory();
|
|
164
|
+
if (!zipEntries) {
|
|
165
|
+
_onError(new Error(Errors.NO_FILES));
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let offset = 0;
|
|
170
|
+
const buffers: Buffer[] = [];
|
|
171
|
+
|
|
172
|
+
for (const entry of zipEntries) {
|
|
173
|
+
if (!entry.isUpdated) {
|
|
174
|
+
// Check for META-INF metadata files even in copy mode
|
|
175
|
+
if (entry.filename === TOKENIZED_METADATA || entry.filename === TIMESTAMP_SUBMITTED || entry.filename === TIMESTAMP_METADATA) {
|
|
176
|
+
// Force this entry to be processed with special handling instead of copied
|
|
177
|
+
entry.isUpdated = true;
|
|
178
|
+
// Don't continue here - let it fall through to special handling below
|
|
179
|
+
} else {
|
|
180
|
+
const inData = await super.copyEntry(entry);
|
|
181
|
+
entry.localHdrOffset = offset;
|
|
182
|
+
offset += inData.length;
|
|
183
|
+
buffers.push(inData);
|
|
184
|
+
_onEntryDone(entry, 'Copied');
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (!entry.fileData) {
|
|
190
|
+
_onError(new Error(Errors.FILE_NOT_FOUND));
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const fileBuffer = await entry.fileData.arrayBuffer();
|
|
195
|
+
|
|
196
|
+
// Special handling for already-compressed entries - use existing compressed data
|
|
197
|
+
if (entry.cmpData && entry.compressedSize && entry.crc) {
|
|
198
|
+
// Entry is already compressed, use the existing compressed data
|
|
199
|
+
const localHdr = entry.createLocalHdr();
|
|
200
|
+
entry.localHdrOffset = offset;
|
|
201
|
+
offset += localHdr.length + entry.cmpData.length;
|
|
202
|
+
|
|
203
|
+
buffers.push(localHdr);
|
|
204
|
+
buffers.push(entry.cmpData);
|
|
205
|
+
_onEntryDone(entry, 'Written (pre-compressed)');
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Special handling for META-INF metadata files - store uncompressed with CRC-32
|
|
210
|
+
if (entry.filename === TOKENIZED_METADATA || entry.filename === TIMESTAMP_SUBMITTED || entry.filename === TIMESTAMP_METADATA) {
|
|
211
|
+
// For metadata files, use STORED compression (no compression)
|
|
212
|
+
const buffer = Buffer.from(fileBuffer);
|
|
213
|
+
|
|
214
|
+
// Calculate CRC-32 for the metadata file (not SHA-256 to avoid Merkle Root interference)
|
|
215
|
+
entry.crc = crc32(buffer);
|
|
216
|
+
|
|
217
|
+
// Set up entry for STORED compression
|
|
218
|
+
entry.cmpMethod = 0; // STORED
|
|
219
|
+
entry.compressedSize = buffer.length;
|
|
220
|
+
entry.uncompressedSize = buffer.length;
|
|
221
|
+
|
|
222
|
+
// Do NOT set SHA-256 hash for metadata files to avoid Merkle Root calculation
|
|
223
|
+
// entry.sha256 should remain undefined for metadata files
|
|
224
|
+
|
|
225
|
+
const localHdr = entry.createLocalHdr();
|
|
226
|
+
entry.localHdrOffset = offset;
|
|
227
|
+
offset += localHdr.length + buffer.length;
|
|
228
|
+
|
|
229
|
+
buffers.push(localHdr);
|
|
230
|
+
buffers.push(buffer);
|
|
231
|
+
_onEntryDone(entry, 'Stored (metadata)');
|
|
232
|
+
} else {
|
|
233
|
+
// Normal file processing with compression
|
|
234
|
+
const cmpData = await this.compressData(entry, Buffer.from(fileBuffer), cmpOptions);
|
|
235
|
+
const localHdr = entry.createLocalHdr();
|
|
236
|
+
|
|
237
|
+
entry.localHdrOffset = offset;
|
|
238
|
+
offset += localHdr.length + cmpData.length;
|
|
239
|
+
|
|
240
|
+
buffers.push(localHdr);
|
|
241
|
+
buffers.push(cmpData);
|
|
242
|
+
_onEntryDone(entry, 'Written');
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const centralDirOffset = offset;
|
|
247
|
+
for (const entry of zipEntries) {
|
|
248
|
+
const centralDirEntry = entry.centralDirEntry();
|
|
249
|
+
offset += centralDirEntry.length;
|
|
250
|
+
buffers.push(centralDirEntry);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const centralDirSize = offset - centralDirOffset;
|
|
254
|
+
const ceBuf = super.centralEndHdr(centralDirSize, centralDirOffset);
|
|
255
|
+
buffers.push(ceBuf);
|
|
256
|
+
|
|
257
|
+
const combinedBuffer = Buffer.concat(buffers);
|
|
258
|
+
// Convert Buffer to Uint8Array for Blob compatibility
|
|
259
|
+
const uint8Array = new Uint8Array(combinedBuffer);
|
|
260
|
+
return new Blob([uint8Array], { type: 'application/zip' });
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Checks if a filename is a metadata file (META-INF) that should be excluded from Merkle Root calculation
|
|
265
|
+
* @param filename - The filename to check
|
|
266
|
+
* @returns boolean - True if the file is a metadata file
|
|
267
|
+
*/
|
|
268
|
+
private isMetadataFile(filename: string): boolean {
|
|
269
|
+
return filename === TIMESTAMP_SUBMITTED ||
|
|
270
|
+
filename === TIMESTAMP_METADATA ||
|
|
271
|
+
filename === TOKENIZED_METADATA;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// --------------------------------------
|
|
275
|
+
// Helper method: Add a file to the ZIP with compression
|
|
276
|
+
// Simplifies the common workflow of creating entry + compressing
|
|
277
|
+
|
|
278
|
+
async addFile(file: FileData, options?: CompressOptions): Promise<ZipEntry> {
|
|
279
|
+
// Create entry
|
|
280
|
+
const entry = this.createZipFileEntry(file);
|
|
281
|
+
|
|
282
|
+
// Compress the file
|
|
283
|
+
// In browser, File objects implement both FileData and Blob interfaces
|
|
284
|
+
// We need to convert FileData to Blob for compressDataBlob
|
|
285
|
+
const fileBlob = file as unknown as Blob;
|
|
286
|
+
const compressedData = await this.compressDataBlob(entry, fileBlob, options);
|
|
287
|
+
entry.cmpData = compressedData;
|
|
288
|
+
|
|
289
|
+
return entry;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// --------------------------------------
|
|
293
|
+
// Verify a ZIP entry by attempting to extract it
|
|
294
|
+
// Returns true if the entry is valid, false otherwise
|
|
295
|
+
|
|
296
|
+
async verifyEntry(entry: ZipEntry, skipHashCheck?: boolean): Promise<boolean> {
|
|
297
|
+
try {
|
|
298
|
+
const blob = await this.extractBlob(entry, skipHashCheck);
|
|
299
|
+
return blob !== null;
|
|
300
|
+
} catch (error) {
|
|
301
|
+
console.error(`Verification failed for ${entry.filename}:`, error);
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// NeoZipkit - Browser ES Module Entry Point
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// This is a clean ES module entry point for browser bundles
|
|
5
|
+
// All exports are named exports for better tree-shaking support
|
|
6
|
+
|
|
7
|
+
// Buffer polyfill for browser
|
|
8
|
+
import { Buffer } from 'buffer';
|
|
9
|
+
if (typeof globalThis !== 'undefined') {
|
|
10
|
+
(globalThis as any).Buffer = Buffer;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Core exports
|
|
14
|
+
export * from '../core';
|
|
15
|
+
|
|
16
|
+
// Browser-specific class
|
|
17
|
+
export { default as ZipkitBrowser } from './ZipkitBrowser';
|
|
18
|
+
|
|
19
|
+
// Re-export ZipEntry as named export for convenience
|
|
20
|
+
export { default as ZipEntry } from '../core/ZipEntry';
|
|
21
|
+
|
|
22
|
+
// Re-export commonly used types and constants
|
|
23
|
+
export type { CompressOptions, CreateZipOptions } from '../core/ZipCompress';
|
|
24
|
+
export type { FileData } from '../types';
|
|
25
|
+
export * from '../core/constants/Headers';
|
|
26
|
+
export * from '../core/constants/Errors';
|
|
27
|
+
|
|
28
|
+
// Platform utilities
|
|
29
|
+
export const PlatformUtils = {
|
|
30
|
+
isBrowser: typeof window !== 'undefined' && typeof document !== 'undefined',
|
|
31
|
+
isNode: typeof process !== 'undefined' && process.versions && process.versions.node,
|
|
32
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// NeoZipkit - Browser-Only Package Exports
|
|
3
|
+
// =============================================================================
|
|
4
|
+
|
|
5
|
+
// Core shared exports (re-exported from core module)
|
|
6
|
+
export * from '../core';
|
|
7
|
+
import Zipkit from '../core';
|
|
8
|
+
export default Zipkit;
|
|
9
|
+
|
|
10
|
+
// Browser-only exports
|
|
11
|
+
export { default as ZipkitBrowser } from './ZipkitBrowser';
|
|
12
|
+
|
|
13
|
+
// Platform-specific conditional exports
|
|
14
|
+
export const PlatformUtils = {
|
|
15
|
+
// Browser detection
|
|
16
|
+
isBrowser: typeof window !== 'undefined' && typeof document !== 'undefined',
|
|
17
|
+
// Node.js detection
|
|
18
|
+
isNode: typeof process !== 'undefined' && process.versions && process.versions.node,
|
|
19
|
+
};
|