neozipkit 0.1.1 → 0.3.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.
Files changed (330) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +371 -200
  3. package/contracts/ABI.txt +889 -0
  4. package/contracts/Bytecode.txt +1 -0
  5. package/contracts/COMPILATION_NOTES.md +59 -0
  6. package/contracts/QUICK_DEPLOY.md +286 -0
  7. package/contracts/README.md +256 -0
  8. package/contracts/VERIFICATION.md +308 -0
  9. package/contracts/deploy-interactive.js +448 -0
  10. package/contracts/deployment-arbitrum-sepolia.json +12 -0
  11. package/contracts/deployment-arbitrum.json +12 -0
  12. package/contracts/deployment-eth-sepolia.json +12 -0
  13. package/contracts/hardhat.config.js +114 -0
  14. package/contracts/package.json +20 -0
  15. package/contracts/scripts/compile-and-extract.js +119 -0
  16. package/contracts/scripts/verify-contract.js +223 -0
  17. package/contracts/src/{NZIP-NFT-Private.sol → NZIP-NFT-v2.0.sol} +66 -151
  18. package/contracts/src/NZIP-NFT.sol +9 -15
  19. package/dist/{browser → blockchain/browser}/TokenVerifierBrowser.d.ts +11 -20
  20. package/dist/blockchain/browser/TokenVerifierBrowser.d.ts.map +1 -0
  21. package/dist/{browser → blockchain/browser}/TokenVerifierBrowser.js +106 -92
  22. package/dist/blockchain/browser/TokenVerifierBrowser.js.map +1 -0
  23. package/dist/blockchain/browser/WalletManagerBrowser.d.ts +98 -0
  24. package/dist/blockchain/browser/WalletManagerBrowser.d.ts.map +1 -0
  25. package/dist/blockchain/browser/WalletManagerBrowser.js +434 -0
  26. package/dist/blockchain/browser/WalletManagerBrowser.js.map +1 -0
  27. package/dist/blockchain/browser/ZipkitMinterBrowser.d.ts +58 -0
  28. package/dist/blockchain/browser/ZipkitMinterBrowser.d.ts.map +1 -0
  29. package/dist/blockchain/browser/ZipkitMinterBrowser.js +317 -0
  30. package/dist/blockchain/browser/ZipkitMinterBrowser.js.map +1 -0
  31. package/dist/blockchain/browser/index.d.ts +11 -0
  32. package/dist/blockchain/browser/index.d.ts.map +1 -0
  33. package/dist/blockchain/browser/index.js +16 -0
  34. package/dist/blockchain/browser/index.js.map +1 -0
  35. package/dist/{server/blockchain/WalletAnalyzer.d.ts → blockchain/core/WalletManager.d.ts} +69 -26
  36. package/dist/blockchain/core/WalletManager.d.ts.map +1 -0
  37. package/dist/{server/blockchain/WalletAnalyzer.js → blockchain/core/WalletManager.js} +172 -160
  38. package/dist/blockchain/core/WalletManager.js.map +1 -0
  39. package/dist/blockchain/core/ZipkitMinter.d.ts +141 -0
  40. package/dist/blockchain/core/ZipkitMinter.d.ts.map +1 -0
  41. package/dist/blockchain/core/ZipkitMinter.js +548 -0
  42. package/dist/blockchain/core/ZipkitMinter.js.map +1 -0
  43. package/dist/blockchain/core/ZipkitOTS.d.ts +126 -0
  44. package/dist/blockchain/core/ZipkitOTS.d.ts.map +1 -0
  45. package/dist/blockchain/core/ZipkitOTS.js +506 -0
  46. package/dist/blockchain/core/ZipkitOTS.js.map +1 -0
  47. package/dist/blockchain/core/ZipkitVerifier.d.ts +177 -0
  48. package/dist/blockchain/core/ZipkitVerifier.d.ts.map +1 -0
  49. package/dist/blockchain/core/ZipkitVerifier.js +632 -0
  50. package/dist/blockchain/core/ZipkitVerifier.js.map +1 -0
  51. package/dist/blockchain/core/contracts.d.ts +83 -0
  52. package/dist/blockchain/core/contracts.d.ts.map +1 -0
  53. package/dist/blockchain/core/contracts.js +341 -0
  54. package/dist/blockchain/core/contracts.js.map +1 -0
  55. package/dist/blockchain/core/index.d.ts +12 -0
  56. package/dist/blockchain/core/index.d.ts.map +1 -0
  57. package/dist/blockchain/core/index.js +59 -0
  58. package/dist/blockchain/core/index.js.map +1 -0
  59. package/dist/blockchain/index.d.ts +11 -0
  60. package/dist/blockchain/index.d.ts.map +1 -0
  61. package/dist/blockchain/index.js +34 -0
  62. package/dist/blockchain/index.js.map +1 -0
  63. package/dist/blockchain/node/WalletManagerNode.d.ts +47 -0
  64. package/dist/blockchain/node/WalletManagerNode.d.ts.map +1 -0
  65. package/dist/blockchain/node/WalletManagerNode.js +203 -0
  66. package/dist/blockchain/node/WalletManagerNode.js.map +1 -0
  67. package/dist/blockchain/node/index.d.ts +12 -0
  68. package/dist/blockchain/node/index.d.ts.map +1 -0
  69. package/dist/blockchain/node/index.js +24 -0
  70. package/dist/blockchain/node/index.js.map +1 -0
  71. package/dist/browser/ZipkitBrowser.d.ts +27 -0
  72. package/dist/browser/ZipkitBrowser.d.ts.map +1 -0
  73. package/dist/browser/{ZipKitBrowser.js → ZipkitBrowser.js} +96 -43
  74. package/dist/browser/ZipkitBrowser.js.map +1 -0
  75. package/dist/browser/index.d.ts +12 -0
  76. package/dist/browser/index.d.ts.map +1 -0
  77. package/dist/browser/index.js +42 -0
  78. package/dist/browser/index.js.map +1 -0
  79. package/dist/browser-esm/index.d.ts +12 -0
  80. package/dist/browser-esm/index.js +59559 -0
  81. package/dist/browser-esm/index.js.map +7 -0
  82. package/dist/browser-umd/index.d.ts +12 -0
  83. package/dist/browser-umd/index.js +59576 -0
  84. package/dist/browser-umd/index.js.map +7 -0
  85. package/dist/browser-umd/index.min.js +63 -0
  86. package/dist/browser.d.ts +8 -17
  87. package/dist/browser.js +13 -29
  88. package/dist/core/ZipCompress.d.ts +99 -0
  89. package/dist/core/ZipCompress.d.ts.map +1 -0
  90. package/dist/core/ZipCompress.js +309 -0
  91. package/dist/core/ZipCompress.js.map +1 -0
  92. package/dist/core/ZipDecompress.d.ts +58 -0
  93. package/dist/core/ZipDecompress.d.ts.map +1 -0
  94. package/dist/core/ZipDecompress.js +172 -0
  95. package/dist/core/ZipDecompress.js.map +1 -0
  96. package/dist/{shared → core}/ZipEntry.d.ts +8 -1
  97. package/dist/core/ZipEntry.d.ts.map +1 -0
  98. package/dist/{shared → core}/ZipEntry.js +224 -81
  99. package/dist/core/ZipEntry.js.map +1 -0
  100. package/dist/core/Zipkit.d.ts +315 -0
  101. package/dist/core/Zipkit.d.ts.map +1 -0
  102. package/dist/core/Zipkit.js +647 -0
  103. package/dist/core/Zipkit.js.map +1 -0
  104. package/dist/core/components/HashCalculator.d.ts +138 -0
  105. package/dist/core/components/HashCalculator.d.ts.map +1 -0
  106. package/dist/core/components/HashCalculator.js +360 -0
  107. package/dist/core/components/HashCalculator.js.map +1 -0
  108. package/dist/core/components/Logger.d.ts +73 -0
  109. package/dist/core/components/Logger.d.ts.map +1 -0
  110. package/dist/core/components/Logger.js +156 -0
  111. package/dist/core/components/Logger.js.map +1 -0
  112. package/dist/core/components/ProgressTracker.d.ts +43 -0
  113. package/dist/core/components/ProgressTracker.d.ts.map +1 -0
  114. package/dist/core/components/ProgressTracker.js +112 -0
  115. package/dist/core/components/ProgressTracker.js.map +1 -0
  116. package/dist/{shared → core}/components/Support.d.ts +1 -0
  117. package/dist/core/components/Support.d.ts.map +1 -0
  118. package/dist/{shared → core}/components/Support.js +1 -0
  119. package/dist/core/components/Support.js.map +1 -0
  120. package/dist/{shared → core}/components/Util.d.ts +7 -2
  121. package/dist/core/components/Util.d.ts.map +1 -0
  122. package/dist/{shared → core}/components/Util.js +14 -34
  123. package/dist/core/components/Util.js.map +1 -0
  124. package/dist/{shared → core}/constants/Errors.d.ts +1 -2
  125. package/dist/core/constants/Errors.d.ts.map +1 -0
  126. package/dist/{shared → core}/constants/Errors.js +1 -3
  127. package/dist/core/constants/Errors.js.map +1 -0
  128. package/dist/{shared → core}/constants/Headers.d.ts +3 -0
  129. package/dist/core/constants/Headers.d.ts.map +1 -0
  130. package/dist/{shared → core}/constants/Headers.js +20 -17
  131. package/dist/core/constants/Headers.js.map +1 -0
  132. package/dist/core/encryption/Manager.d.ts +58 -0
  133. package/dist/core/encryption/Manager.d.ts.map +1 -0
  134. package/dist/core/encryption/Manager.js +121 -0
  135. package/dist/core/encryption/Manager.js.map +1 -0
  136. package/dist/core/encryption/ZipCrypto.d.ts +172 -0
  137. package/dist/core/encryption/ZipCrypto.d.ts.map +1 -0
  138. package/dist/core/encryption/ZipCrypto.js +554 -0
  139. package/dist/core/encryption/ZipCrypto.js.map +1 -0
  140. package/dist/core/encryption/index.d.ts +9 -0
  141. package/dist/core/encryption/index.d.ts.map +1 -0
  142. package/dist/core/encryption/index.js +17 -0
  143. package/dist/core/encryption/index.js.map +1 -0
  144. package/dist/core/encryption/types.d.ts +29 -0
  145. package/dist/core/encryption/types.d.ts.map +1 -0
  146. package/dist/core/encryption/types.js +12 -0
  147. package/dist/core/encryption/types.js.map +1 -0
  148. package/dist/core/index.d.ts +24 -0
  149. package/dist/core/index.d.ts.map +1 -0
  150. package/dist/core/index.js +57 -0
  151. package/dist/core/index.js.map +1 -0
  152. package/dist/{shared → core}/version.d.ts +1 -0
  153. package/dist/core/version.d.ts.map +1 -0
  154. package/dist/core/version.js +31 -0
  155. package/dist/core/version.js.map +1 -0
  156. package/dist/index.d.ts +8 -25
  157. package/dist/index.d.ts.map +1 -0
  158. package/dist/index.js +29 -47
  159. package/dist/index.js.map +1 -0
  160. package/dist/node/ZipCompressNode.d.ts +123 -0
  161. package/dist/node/ZipCompressNode.d.ts.map +1 -0
  162. package/dist/node/ZipCompressNode.js +576 -0
  163. package/dist/node/ZipCompressNode.js.map +1 -0
  164. package/dist/node/ZipDecompressNode.d.ts +120 -0
  165. package/dist/node/ZipDecompressNode.d.ts.map +1 -0
  166. package/dist/node/ZipDecompressNode.js +461 -0
  167. package/dist/node/ZipDecompressNode.js.map +1 -0
  168. package/dist/node/ZipkitNode.d.ts +406 -0
  169. package/dist/node/ZipkitNode.d.ts.map +1 -0
  170. package/dist/node/ZipkitNode.js +1305 -0
  171. package/dist/node/ZipkitNode.js.map +1 -0
  172. package/dist/node/index.d.ts +26 -0
  173. package/dist/node/index.d.ts.map +1 -0
  174. package/dist/node/index.js +65 -0
  175. package/dist/node/index.js.map +1 -0
  176. package/dist/types/index.d.ts +59 -0
  177. package/dist/types/index.d.ts.map +1 -0
  178. package/dist/types/index.js +36 -1
  179. package/dist/types/index.js.map +1 -0
  180. package/examples/README.md +269 -0
  181. package/examples/blockchain-tokenize.ts +354 -0
  182. package/examples/create-zip.ts +172 -0
  183. package/examples/extract-zip.ts +158 -0
  184. package/examples/list-zip.ts +161 -0
  185. package/examples/test-files/data.json +116 -0
  186. package/examples/test-files/document.md +80 -0
  187. package/examples/test-files/document.txt +2 -0
  188. package/examples/test-files/file1.txt +48 -0
  189. package/examples/test-files/file2.txt +80 -0
  190. package/examples/tsconfig.json +44 -0
  191. package/examples/unzip-token.ts +6 -3
  192. package/examples/verify-tokenized-zip.ts +305 -0
  193. package/package.json +117 -23
  194. package/src/blockchain/README.md +222 -0
  195. package/src/{browser → blockchain/browser}/TokenVerifierBrowser.ts +125 -79
  196. package/src/blockchain/browser/WalletManagerBrowser.ts +486 -0
  197. package/src/blockchain/browser/ZipkitMinterBrowser.ts +400 -0
  198. package/src/blockchain/browser/index.ts +13 -0
  199. package/src/blockchain/core/WalletManager.ts +436 -0
  200. package/src/blockchain/core/ZipkitMinter.ts +716 -0
  201. package/src/blockchain/core/ZipkitOTS.ts +588 -0
  202. package/src/blockchain/core/ZipkitVerifier.ts +853 -0
  203. package/src/blockchain/core/contracts.ts +370 -0
  204. package/src/blockchain/core/index.ts +71 -0
  205. package/src/blockchain/index.ts +27 -0
  206. package/src/blockchain/node/WalletManagerNode.ts +171 -0
  207. package/src/blockchain/node/index.ts +40 -0
  208. package/src/browser/{ZipKitBrowser.ts → ZipkitBrowser.ts} +104 -41
  209. package/src/browser/index.esm.ts +37 -0
  210. package/src/browser/index.ts +25 -0
  211. package/src/core/ZipCompress.ts +398 -0
  212. package/src/core/ZipDecompress.ts +212 -0
  213. package/src/{shared → core}/ZipEntry.ts +239 -89
  214. package/src/core/Zipkit.ts +794 -0
  215. package/src/core/components/HashCalculator.ts +384 -0
  216. package/src/core/components/Logger.ts +180 -0
  217. package/src/core/components/ProgressTracker.ts +134 -0
  218. package/src/{shared → core}/components/Util.ts +12 -34
  219. package/src/{shared → core}/constants/Errors.ts +0 -4
  220. package/src/{shared → core}/constants/Headers.ts +19 -17
  221. package/src/core/encryption/Manager.ts +137 -0
  222. package/src/core/encryption/ZipCrypto.ts +650 -0
  223. package/src/core/encryption/index.ts +15 -0
  224. package/src/core/encryption/types.ts +33 -0
  225. package/src/core/index.ts +34 -0
  226. package/src/core/version.ts +33 -0
  227. package/src/index.ts +54 -32
  228. package/src/node/ZipCompressNode.ts +632 -0
  229. package/src/node/ZipDecompressNode.ts +508 -0
  230. package/src/node/ZipkitNode.ts +1559 -0
  231. package/src/node/index.ts +69 -0
  232. package/src/types/index.ts +131 -1
  233. package/src/types/opentimestamps.d.ts +1 -23
  234. package/contracts/Lock.sol +0 -34
  235. package/contracts/bytecode.txt +0 -1
  236. package/contracts/compile-contract.js +0 -168
  237. package/contracts/deploy/deploy-both-contracts.js +0 -286
  238. package/contracts/deploy/deploy-enhanced-contract.js +0 -197
  239. package/contracts/deploy/deploy-private-contract.js +0 -190
  240. package/contracts/deploy/deploy-public-clean.js +0 -1063
  241. package/contracts/deploy/deploy-public-contract.js +0 -1107
  242. package/contracts/deployment.config.example.js +0 -25
  243. package/contracts/remix-compile.js +0 -222
  244. package/contracts/setup-deployment.js +0 -51
  245. package/contracts/src/ZipFileNFT-DEPRECATED-6field.sol +0 -260
  246. package/contracts/src/ZipFileNFT-DEPRECATED-Enhanced.sol +0 -289
  247. package/dist/browser/CertificateGeneratorBrowser.d.ts +0 -75
  248. package/dist/browser/CertificateGeneratorBrowser.js +0 -433
  249. package/dist/browser/ZipKitBrowser.d.ts +0 -18
  250. package/dist/browser/ZipKitStampBrowser.d.ts +0 -2
  251. package/dist/browser/ZipKitStampBrowser.js +0 -12
  252. package/dist/browser-index.d.ts +0 -21
  253. package/dist/browser-index.js +0 -58
  254. package/dist/server/blockchain/CertificateToken.d.ts +0 -48
  255. package/dist/server/blockchain/CertificateToken.js +0 -386
  256. package/dist/server/blockchain/NFTMinter.d.ts +0 -41
  257. package/dist/server/blockchain/NFTMinter.js +0 -323
  258. package/dist/server/blockchain/TokenQuerier.d.ts +0 -31
  259. package/dist/server/blockchain/TokenQuerier.js +0 -259
  260. package/dist/server/blockchain/TokenVerifier.d.ts +0 -20
  261. package/dist/server/blockchain/TokenVerifier.js +0 -395
  262. package/dist/server/blockchain/WalletFormatter.d.ts +0 -39
  263. package/dist/server/blockchain/WalletFormatter.js +0 -196
  264. package/dist/server/blockchain/WalletManager.d.ts +0 -46
  265. package/dist/server/blockchain/WalletManager.js +0 -294
  266. package/dist/server/blockchain/ZipMetadata.d.ts +0 -27
  267. package/dist/server/blockchain/ZipMetadata.js +0 -131
  268. package/dist/server/blockchain/ZipTokenProcessor.d.ts +0 -44
  269. package/dist/server/blockchain/ZipTokenProcessor.js +0 -204
  270. package/dist/server/blockchain/constants.d.ts +0 -102
  271. package/dist/server/blockchain/constants.js +0 -968
  272. package/dist/server/blockchain/index.d.ts +0 -9
  273. package/dist/server/blockchain/index.js +0 -44
  274. package/dist/server/blockchain/test-certificate.d.ts +0 -8
  275. package/dist/server/blockchain/test-certificate.js +0 -100
  276. package/dist/server/blockchain/types.d.ts +0 -69
  277. package/dist/server/blockchain/types.js +0 -51
  278. package/dist/server/platform/server/ZipKitServer.d.ts +0 -105
  279. package/dist/server/platform/server/ZipKitServer.js +0 -437
  280. package/dist/server/platform/servercomponents/ZipKitOTS.d.ts +0 -91
  281. package/dist/server/platform/servercomponents/ZipKitOTS.js +0 -271
  282. package/dist/shared/ZipKit.d.ts +0 -249
  283. package/dist/shared/ZipKit.js +0 -789
  284. package/dist/shared/components/CertificateOTS.d.ts +0 -15
  285. package/dist/shared/components/CertificateOTS.js +0 -116
  286. package/dist/shared/components/FileSys.d.ts +0 -2
  287. package/dist/shared/components/FileSys.js +0 -113
  288. package/dist/shared/components/HashAccumulator.d.ts +0 -55
  289. package/dist/shared/components/HashAccumulator.js +0 -100
  290. package/dist/shared/components/ZipCrypto.d.ts +0 -3
  291. package/dist/shared/components/ZipCrypto.js +0 -78
  292. package/dist/shared/components/merkleTree.d.ts +0 -66
  293. package/dist/shared/components/merkleTree.js +0 -136
  294. package/dist/shared/types/index.d.ts +0 -21
  295. package/dist/shared/types/index.js +0 -3
  296. package/dist/shared/types.d.ts +0 -33
  297. package/dist/shared/types.js +0 -8
  298. package/dist/shared/version.js +0 -7
  299. package/src/browser/CertificateGeneratorBrowser.ts +0 -498
  300. package/src/browser/ZipKitStampBrowser.ts +0 -9
  301. package/src/browser-index.ts +0 -36
  302. package/src/server/blockchain/CertificateToken.ts +0 -444
  303. package/src/server/blockchain/NFTMinter.ts +0 -357
  304. package/src/server/blockchain/TokenQuerier.ts +0 -287
  305. package/src/server/blockchain/TokenVerifier.ts +0 -453
  306. package/src/server/blockchain/WalletAnalyzer.ts +0 -397
  307. package/src/server/blockchain/WalletFormatter.ts +0 -206
  308. package/src/server/blockchain/WalletManager.ts +0 -294
  309. package/src/server/blockchain/ZipMetadata.ts +0 -117
  310. package/src/server/blockchain/ZipTokenProcessor.ts +0 -234
  311. package/src/server/blockchain/constants.ts +0 -969
  312. package/src/server/blockchain/index.ts +0 -42
  313. package/src/server/blockchain/test-certificate.ts +0 -137
  314. package/src/server/blockchain/types.ts +0 -134
  315. package/src/server/platform/server/ZipKitServer.ts +0 -459
  316. package/src/server/platform/servercomponents/ZipKitOTS.ts +0 -313
  317. package/src/server/platform/servercomponents/opentimestamps.d.ts +0 -23
  318. package/src/shared/ZipKit.ts +0 -899
  319. package/src/shared/components/CertificateOTS.ts +0 -132
  320. package/src/shared/components/FileSys.ts +0 -87
  321. package/src/shared/components/HashAccumulator.ts +0 -113
  322. package/src/shared/components/ZipCrypto.ts +0 -91
  323. package/src/shared/components/merkleTree.ts +0 -162
  324. package/src/shared/types/index.ts +0 -25
  325. package/src/shared/types/modules.d.ts +0 -22
  326. package/src/shared/types/opentimestamps.d.ts +0 -23
  327. package/src/shared/types.d.ts +0 -8
  328. package/src/shared/types.ts +0 -43
  329. package/src/shared/version.ts +0 -4
  330. /package/src/{shared → core}/components/Support.ts +0 -0
@@ -1,39 +1,41 @@
1
1
  // ======================================
2
- // ZipKitBrowser.ts
2
+ // ZipkitBrowser.ts
3
3
  // Copyright (c) 2025 NeoWare, Inc. All rights reserved.
4
4
  // ======================================
5
5
 
6
- import ZipKit, { CompressOptions, CreateZipOptions } from '../shared/ZipKit';
7
- import ZipEntry from '../shared/ZipEntry';
8
- import Errors from '../shared/constants/Errors';
9
- import * as Headers from '../shared/constants/Headers';
10
- import { TOKENIZED_METADATA, TIMESTAMP_SUBMITTED, TIMESTAMP_METADATA } from '../shared/constants/Headers';
11
- import { sha256 } from '../shared/components/ZipCrypto';
12
- import { crc32 } from '../shared/components/Util';
13
- import { DATATYPE, getTypeOf } from '../shared/components/Util';
14
- import type { FileData } from '../shared/types';
15
-
16
- // Re-export everything from ZipKit
17
- export * from '../shared/ZipKit';
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';
18
19
  export { ZipEntry, Errors, Headers, sha256, getTypeOf };
19
20
 
20
21
  // ======================================
21
- // ZipKitBrowser
22
+ // ZipkitBrowser
22
23
  // ======================================
23
24
 
24
- export default class ZipKitBrowser extends ZipKit {
25
+ export default class ZipkitBrowser extends Zipkit {
25
26
  constructor() {
26
27
  super(); // Call the parent constructor
27
28
 
28
- // console.log('ZipKit.support.isNode: ', ZipKit.support.isNode);
29
- // console.log('ZipKit.support.buffer: ', ZipKit.support.buffer);
30
- // console.log('ZipKit.support.blob: ', ZipKit.support.blob);
31
- // console.log('ZipKit.support.streams: ', ZipKit.support.streams);
32
- // console.log('ZipKit.support.fileReader: ', ZipKit.support.fileReader);
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);
33
34
  }
34
35
 
35
36
  // --------------------------------------
36
37
  // Load a ZIP file from a Blob and return the ZipEntry array
38
+ // Always uses loadZip() to ensure proper initialization
37
39
 
38
40
  async loadZipBlob(data: Blob): Promise<ZipEntry[] | null> {
39
41
  if (getTypeOf(data) !== DATATYPE.BLOB) {
@@ -41,30 +43,34 @@ export default class ZipKitBrowser extends ZipKit {
41
43
  }
42
44
 
43
45
  return new Promise((resolve, reject) => {
44
- const _readEntries = (data: Buffer): ZipEntry[] | null => {
45
- try {
46
- super.loadZip(data);
47
- return super.getDirectory();
48
- } catch (error) {
49
- reject(error);
50
- return null;
51
- }
52
- };
53
-
54
46
  const reader = new window.FileReader();
55
47
  reader.readAsArrayBuffer(data);
56
48
 
57
- reader.onload = function(this: FileReader, e: ProgressEvent<FileReader>) {
58
- if (!this.result) {
49
+ reader.onload = (e: ProgressEvent<FileReader>) => {
50
+ if (!reader.result) {
59
51
  reject(new Error('Failed to read file'));
60
52
  return;
61
53
  }
62
- const _inBuf = Buffer.from(this.result as ArrayBuffer);
63
- resolve(_readEntries(_inBuf));
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
+ }
64
70
  };
65
71
 
66
- reader.onerror = function(this: FileReader, e: ProgressEvent<FileReader>) {
67
- reject(this.error || new Error('Failed to read file'));
72
+ reader.onerror = () => {
73
+ reject(reader.error || new Error('Failed to read file'));
68
74
  };
69
75
  });
70
76
  }
@@ -104,7 +110,8 @@ export default class ZipKitBrowser extends ZipKit {
104
110
 
105
111
  return new Promise(async (resolve, reject) => {
106
112
  const _compressData = async (entry: ZipEntry, data: Buffer, options?: CompressOptions): Promise<Buffer> => {
107
- return await super.compressData(entry, data, options);
113
+ // Use Zipkit wrapper method
114
+ return await this.compressData(entry, data, options);
108
115
  };
109
116
 
110
117
  const reader = new window.FileReader();
@@ -135,7 +142,7 @@ export default class ZipKitBrowser extends ZipKit {
135
142
 
136
143
  async extractBlob(entry: ZipEntry, skipHashCheck?: boolean): Promise<Blob | null> {
137
144
  try {
138
- const _outBuf = await super.extract(entry, skipHashCheck);
145
+ const _outBuf = await this.extract(entry, skipHashCheck);
139
146
  if (!_outBuf) return null;
140
147
 
141
148
  // Convert Buffer to Uint8Array for Blob compatibility
@@ -170,7 +177,7 @@ export default class ZipKitBrowser extends ZipKit {
170
177
  entry.isUpdated = true;
171
178
  // Don't continue here - let it fall through to special handling below
172
179
  } else {
173
- const inData = super.copyEntry(entry);
180
+ const inData = await super.copyEntry(entry);
174
181
  entry.localHdrOffset = offset;
175
182
  offset += inData.length;
176
183
  buffers.push(inData);
@@ -186,6 +193,19 @@ export default class ZipKitBrowser extends ZipKit {
186
193
 
187
194
  const fileBuffer = await entry.fileData.arrayBuffer();
188
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
+
189
209
  // Special handling for token metadata files - store uncompressed with CRC-32
190
210
  if (entry.filename === TOKENIZED_METADATA || entry.filename === TIMESTAMP_SUBMITTED || entry.filename === TIMESTAMP_METADATA) {
191
211
  // For token metadata, use STORED compression (no compression)
@@ -211,7 +231,7 @@ export default class ZipKitBrowser extends ZipKit {
211
231
  _onEntryDone(entry, 'Stored (metadata)');
212
232
  } else {
213
233
  // Normal file processing with compression
214
- const cmpData = await super.compressData(entry, Buffer.from(fileBuffer), cmpOptions);
234
+ const cmpData = await this.compressData(entry, Buffer.from(fileBuffer), cmpOptions);
215
235
  const localHdr = entry.createLocalHdr();
216
236
 
217
237
  entry.localHdrOffset = offset;
@@ -238,5 +258,48 @@ export default class ZipKitBrowser extends ZipKit {
238
258
  // Convert Buffer to Uint8Array for Blob compatibility
239
259
  const uint8Array = new Uint8Array(combinedBuffer);
240
260
  return new Blob([uint8Array], { type: 'application/zip' });
241
- }
261
+ }
262
+
263
+ /**
264
+ * Checks if a filename is a blockchain metadata file 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
+ }
242
305
  }
@@ -0,0 +1,37 @@
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, TokenMetadata } from '../types';
25
+ export * from '../core/constants/Headers';
26
+ export * from '../core/constants/Errors';
27
+
28
+ // Blockchain exports for browser (if needed)
29
+ export * from '../blockchain/browser';
30
+ export { createTokenVerifier } from '../blockchain/browser';
31
+
32
+ // Platform utilities
33
+ export const PlatformUtils = {
34
+ isBrowser: typeof window !== 'undefined' && typeof document !== 'undefined',
35
+ isNode: typeof process !== 'undefined' && process.versions && process.versions.node,
36
+ };
37
+
@@ -0,0 +1,25 @@
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
+ export { TokenMetadata } from '../types';
13
+
14
+ // Blockchain exports for browser
15
+ export * from '../blockchain/browser';
16
+ export { createTokenVerifier } from '../blockchain/browser';
17
+
18
+ // Platform-specific conditional exports
19
+ export const PlatformUtils = {
20
+ // Browser detection
21
+ isBrowser: typeof window !== 'undefined' && typeof document !== 'undefined',
22
+ // Node.js detection
23
+ isNode: typeof process !== 'undefined' && process.versions && process.versions.node,
24
+ };
25
+
@@ -0,0 +1,398 @@
1
+ // ======================================
2
+ // ZipkitCompress.ts - Compression Module
3
+ // Copyright (c) 2025 NeoWare, Inc. All rights reserved.
4
+ // ======================================
5
+ //
6
+ // LOGGING INSTRUCTIONS:
7
+ // ---------------------
8
+ // To enable/disable logging, set loggingEnabled to true/false in the class:
9
+ // private static loggingEnabled: boolean = true; // Enable logging
10
+ // private static loggingEnabled: boolean = false; // Disable logging
11
+ //
12
+ // Logging respects the global Logger level (debug, info, warn, error, silent).
13
+ // Logger level is automatically set to 'debug' when loggingEnabled is true.
14
+ //
15
+
16
+ const pako = require('pako');
17
+ import { ZstdInit, ZstdSimple } from '@oneidentity/zstd-js';
18
+ import Zipkit from './Zipkit';
19
+ import { Logger } from './components/Logger';
20
+ import ZipEntry from './ZipEntry';
21
+ import Errors from './constants/Errors';
22
+ import { CMP_METHOD, GP_FLAG, ENCRYPT_HDR_SIZE } from './constants/Headers';
23
+ import { HashCalculator } from './components/HashCalculator';
24
+ import { ZipCrypto } from './encryption/ZipCrypto';
25
+
26
+ // We'll initialize zstd when needed
27
+ let zstdCodec: { ZstdSimple: typeof ZstdSimple } | null = null;
28
+
29
+ // Async initialization function for zstd
30
+ async function initZstd(): Promise<{ ZstdSimple: typeof ZstdSimple }> {
31
+ if (!zstdCodec) {
32
+ zstdCodec = await ZstdInit();
33
+ }
34
+ return zstdCodec;
35
+ }
36
+
37
+ /**
38
+ * Options for compressing files in a ZIP archive
39
+ */
40
+ export interface CompressOptions {
41
+ level?: number; // Compression level (1-9, 0=store)
42
+ password?: string | null; // Password for encryption
43
+ useSHA256?: boolean; // Whether to calculate SHA256 hash default is false
44
+ useZstd?: boolean; // Whether to use Zstandard compression default is true
45
+ bufferSize?: number; // Override default buffer size
46
+ }
47
+
48
+ /**
49
+ * Callbacks for ZIP file creation process
50
+ * Buffer-based only - no file I/O operations
51
+ */
52
+ export interface CreateZipOptions {
53
+ onError?: (error: Error) => void; // Called when an error occurs
54
+ onEntryDone?: (entry: ZipEntry, status: string) => void; // Called when entry processing completes
55
+ onOutputBuffer?: (data: Buffer) => Promise<void>; // Called to write output data
56
+ }
57
+
58
+ /**
59
+ * Compression handler for ZIP files
60
+ * Supports Deflate, Zstandard, and Store methods
61
+ */
62
+ export class ZipCompress {
63
+ private zipkit: Zipkit;
64
+ private debug: boolean;
65
+
66
+ // Class-level logging control - set to true to enable logging
67
+ private static loggingEnabled: boolean = false;
68
+
69
+ /**
70
+ * Internal logging method - only logs if class logging is enabled
71
+ */
72
+ private log(...args: any[]): void {
73
+ if (ZipCompress.loggingEnabled) {
74
+ Logger.debug(`[ZipCompress]`, ...args);
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Creates a new ZipCompress instance
80
+ * @param zipkit - Zipkit instance to use for ZIP operations
81
+ */
82
+ constructor(zipkit: Zipkit) {
83
+ this.zipkit = zipkit;
84
+ // Debug disabled by default (controlled by class-level logging)
85
+ this.debug = false;
86
+ // If logging is enabled, ensure Logger level is set to debug
87
+ if (ZipCompress.loggingEnabled) {
88
+ Logger.setLevel('debug');
89
+ }
90
+ this.log(`ZipCompress initialized`);
91
+ }
92
+
93
+ /**
94
+ * Compresses data for a ZIP entry (Buffer-based only)
95
+ * @param entry - ZIP entry to compress
96
+ * @param data - Buffer containing data to compress
97
+ * @param options - Compression options
98
+ * @param onOutputBuffer - Optional callback for streaming output
99
+ * @returns Buffer containing compressed data
100
+ */
101
+ async compressData(entry: ZipEntry, data: Buffer, options?: CompressOptions, onOutputBuffer?: (data: Buffer) => Promise<void>): Promise<Buffer> {
102
+ this.log(`compressData() called for entry: ${entry.filename}`);
103
+
104
+ // Set uncompressed size if not already set
105
+ if (!entry.uncompressedSize || entry.uncompressedSize === 0) {
106
+ entry.uncompressedSize = data.length;
107
+ }
108
+ const totalSize = data.length;
109
+ const bufferSize = options?.bufferSize || this.zipkit.getBufferSize(); // Use Zipkit's bufferSize
110
+
111
+ this.log(`Compressing ${totalSize} bytes for entry: ${entry.filename}`);
112
+ this.log(`Compression options:`, { level: options?.level, useZstd: options?.useZstd, bufferSize });
113
+
114
+ // Determine compression method
115
+ let compressionMethod: number;
116
+
117
+ if (options?.level === 0) {
118
+ compressionMethod = CMP_METHOD.STORED;
119
+ this.log(`Using STORED method (no compression)`);
120
+ } else if (options?.useZstd) {
121
+ // ZSTD fallback to STORED if file too small
122
+ if (totalSize < 100) {
123
+ compressionMethod = CMP_METHOD.STORED;
124
+ this.log(`ZSTD fallback to STORED (file too small: ${totalSize} bytes)`);
125
+ } else {
126
+ compressionMethod = CMP_METHOD.ZSTD;
127
+ this.log(`Using ZSTD method (zstd compression)`);
128
+ }
129
+ } else {
130
+ compressionMethod = CMP_METHOD.DEFLATED;
131
+ this.log(`Using DEFLATED method (default compression)`);
132
+ }
133
+
134
+ entry.cmpMethod = compressionMethod;
135
+
136
+ // Initialize hash calculator
137
+ const needsHashCalculation = (!entry.crc || entry.crc === 0) || (options?.useSHA256 && !entry.sha256);
138
+ const hashCalculator = needsHashCalculation ? new HashCalculator({ useSHA256: options?.useSHA256 && !entry.sha256 || false }) : null;
139
+
140
+ // Calculate hashes if needed
141
+ if (hashCalculator) {
142
+ hashCalculator.update(data);
143
+ if (!entry.crc || entry.crc === 0) {
144
+ entry.crc = hashCalculator.finalizeCRC32();
145
+ }
146
+ if (options?.useSHA256 && !entry.sha256) {
147
+ entry.sha256 = hashCalculator.finalizeSHA256();
148
+ }
149
+ this.log(`Final hashes: CRC32=0x${entry.crc.toString(16).padStart(8, '0')}, SHA256=${entry.sha256 || 'N/A'}`);
150
+ }
151
+
152
+ // Encrypt if password provided
153
+ if (options?.password) {
154
+ this.log(`Encrypting compressed data for entry: ${entry.filename}`);
155
+ (entry as any).gpFlag = ((entry as any).gpFlag || 0) | GP_FLAG.ENCRYPTED;
156
+ (entry as any).isEncrypted = true;
157
+ }
158
+
159
+ // Compress data based on method
160
+ let compressedData: Buffer;
161
+ const methodName = compressionMethod === CMP_METHOD.ZSTD ? 'ZSTD' : compressionMethod === CMP_METHOD.DEFLATED ? 'DEFLATED' : 'STORED';
162
+
163
+ if (compressionMethod === CMP_METHOD.STORED) {
164
+ compressedData = data;
165
+ } else {
166
+ this.log(`Processing sequence for ${methodName}: [HASH] -> [COMPRESS] -> [OUTPUT]`);
167
+ this.log(`Compressing: method=${methodName}, input=${totalSize} bytes, buffer size=${bufferSize} bytes`);
168
+ this.log(`Calculating hashes: CRC32=${!entry.crc || entry.crc === 0}, SHA256=${options?.useSHA256}`);
169
+
170
+ if (compressionMethod === CMP_METHOD.ZSTD) {
171
+ compressedData = await this.zstdCompress(data, options, bufferSize, entry, onOutputBuffer);
172
+ } else {
173
+ compressedData = await this.deflateCompress(data, options, bufferSize, entry, onOutputBuffer);
174
+ }
175
+ }
176
+
177
+ // Encrypt compressed data if password provided
178
+ if (options?.password) {
179
+ compressedData = this.encryptCompressedData(entry, compressedData, options.password);
180
+ }
181
+
182
+ entry.compressedSize = compressedData.length;
183
+
184
+ return compressedData;
185
+ }
186
+
187
+ /**
188
+ * Compress data using deflate algorithm with chunked processing
189
+ * @param data - Data to compress (Buffer or chunked reader)
190
+ * @param options - Compression options
191
+ * @param bufferSize - Buffer size for chunked processing
192
+ * @param entry - ZIP entry being compressed
193
+ * @param onOutputBuffer - Optional callback for streaming output
194
+ * @returns Buffer containing compressed data
195
+ */
196
+ async deflateCompress(
197
+ data: Buffer | { totalSize: number, onReadChunk: (position: number, size: number) => Buffer, onOutChunk: (chunk: Buffer) => void },
198
+ options?: CompressOptions,
199
+ bufferSize?: number,
200
+ entry?: ZipEntry,
201
+ onOutputBuffer?: (data: Buffer) => Promise<void>
202
+ ): Promise<Buffer> {
203
+ this.log(`deflateCompress() called - entry: ${entry?.filename ?? 'unknown'}, bufferSize: ${bufferSize}, level: ${options?.level ?? 6}`);
204
+
205
+ const effectiveBufferSize = bufferSize || this.zipkit.getBufferSize();
206
+ const level = options?.level ?? 6;
207
+
208
+ // Handle chunked reader
209
+ if (typeof data === 'object' && 'totalSize' in data && 'onReadChunk' in data) {
210
+ // Chunked reader mode - not implemented in simplified version
211
+ throw new Error('Chunked reader mode not supported in ZipCompress');
212
+ }
213
+
214
+ // For small data, use synchronous deflate
215
+ if (data.length <= effectiveBufferSize) {
216
+ return this.deflate(data, options);
217
+ }
218
+
219
+ // For large data, use chunked deflate
220
+ const deflator = new pako.Deflate({ level, raw: true });
221
+ const compressedChunks: Buffer[] = [];
222
+ let totalProcessed = 0;
223
+ let totalCompressedSize = 0;
224
+
225
+ try {
226
+ // Process data in chunks
227
+ for (let offset = 0; offset < data.length; offset += effectiveBufferSize) {
228
+ const chunk = data.slice(offset, offset + effectiveBufferSize);
229
+ const isLast = offset + effectiveBufferSize >= data.length;
230
+
231
+ deflator.push(chunk, isLast);
232
+
233
+ // Collect compressed chunks
234
+ if (deflator.result && deflator.result.length > 0) {
235
+ const compressedChunk = Buffer.from(deflator.result);
236
+ compressedChunks.push(compressedChunk);
237
+ totalCompressedSize += compressedChunk.length;
238
+
239
+ // Stream output if callback provided
240
+ if (onOutputBuffer) {
241
+ await onOutputBuffer(compressedChunk);
242
+ }
243
+ }
244
+
245
+ totalProcessed += chunk.length;
246
+ }
247
+
248
+ // Calculate compression ratio
249
+ const ratio = totalProcessed > 0 ? Math.round((totalCompressedSize / totalProcessed) * 100) : 0;
250
+ this.log(`Final hashes: CRC32=0x${entry?.crc?.toString(16).padStart(8, '0')}, SHA256=${entry?.sha256 || 'N/A'}`);
251
+ this.log(`Deflate compression complete: ${totalCompressedSize} bytes from ${totalProcessed} bytes (ratio=${ratio}%)`);
252
+
253
+ return Buffer.concat(compressedChunks);
254
+ } catch (e) {
255
+ throw new Error(`Deflate compression failed: ${e instanceof Error ? e.message : String(e)}`);
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Compress data using deflate algorithm (synchronous, small buffers only)
261
+ * @param inbuf - Buffer containing data to compress
262
+ * @param options - Compression options
263
+ * @returns Buffer containing compressed data
264
+ */
265
+ deflate(inbuf: Buffer, options?: CompressOptions): Buffer {
266
+ this.log(`deflate() called with buffer size: ${inbuf.length}, level: ${options?.level ?? 6}`);
267
+ const level = options?.level ?? 6;
268
+ const result = pako.deflateRaw(inbuf, { level });
269
+ const ratio = inbuf.length > 0 ? Math.round((result.length / inbuf.length) * 100) : 0;
270
+ this.log(`Deflate compression complete: ${result.length} bytes from ${inbuf.length} bytes (ratio=${ratio}%)`);
271
+ return Buffer.from(result.buffer, result.byteOffset, result.byteLength);
272
+ }
273
+
274
+ /**
275
+ * Compress data using Zstandard (zstd) algorithm
276
+ * @param input - Input data to compress (Buffer or chunked reader)
277
+ * @param options - Compression options
278
+ * @param bufferSize - Buffer size for chunked processing
279
+ * @param entry - ZIP entry being compressed
280
+ * @param onOutputBuffer - Optional callback for streaming output
281
+ * @returns Buffer containing compressed data
282
+ */
283
+ async zstdCompress(
284
+ input: Buffer | { totalSize: number, readChunk: (position: number, size: number) => Buffer },
285
+ options?: CompressOptions,
286
+ bufferSize?: number,
287
+ entry?: ZipEntry,
288
+ onOutputBuffer?: (data: Buffer) => Promise<void>
289
+ ): Promise<Buffer> {
290
+ this.log(`zstdCompress() called - entry: ${entry?.filename ?? 'unknown'}, bufferSize: ${bufferSize}, level: ${options?.level ?? 6}`);
291
+
292
+ const effectiveBufferSize = bufferSize || this.zipkit.getBufferSize();
293
+ const level = options?.level ?? 6;
294
+
295
+ // Handle chunked reader
296
+ if (typeof input === 'object' && 'totalSize' in input && 'readChunk' in input) {
297
+ // Chunked reader mode - not implemented in simplified version
298
+ throw new Error('Chunked reader mode not supported in ZipCompress');
299
+ }
300
+
301
+ // Lazy ZSTD initialization
302
+ const zstdCodec = await initZstd();
303
+
304
+ // Validate input
305
+ if (!input || input.length === 0) {
306
+ throw new Error('ZSTD compression: empty input buffer');
307
+ }
308
+
309
+ // Convert Buffer to Uint8Array for WASM module (same fix as decompression)
310
+ const inputArray = new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
311
+
312
+ // For small data, compress in one go
313
+ if (input.length <= effectiveBufferSize) {
314
+ const compressed = zstdCodec.ZstdSimple.compress(inputArray, level);
315
+ const compressedBuffer = Buffer.from(compressed);
316
+
317
+ if (onOutputBuffer) {
318
+ await onOutputBuffer(compressedBuffer);
319
+ }
320
+
321
+ return compressedBuffer;
322
+ }
323
+
324
+ // For large data, compress in chunks (ZSTD supports streaming)
325
+ // Note: ZSTD streaming compression is more complex, so for now we compress the whole buffer
326
+ // This could be optimized in the future for true streaming
327
+ const compressed = zstdCodec.ZstdSimple.compress(inputArray, level);
328
+ const compressedBuffer = Buffer.from(compressed);
329
+
330
+ if (onOutputBuffer) {
331
+ await onOutputBuffer(compressedBuffer);
332
+ }
333
+
334
+ return compressedBuffer;
335
+ }
336
+
337
+ /**
338
+ * Encrypt compressed data using PKZIP encryption
339
+ * @param entry - ZIP entry to encrypt
340
+ * @param compressedData - Compressed data to encrypt
341
+ * @param password - Password for encryption
342
+ * @returns Buffer containing encrypted data (includes 12-byte header)
343
+ */
344
+ encryptCompressedData(entry: ZipEntry, compressedData: Buffer, password: string): Buffer {
345
+ this.log(`encryptCompressedData() called for entry: ${entry.filename}, compressed size: ${compressedData.length}`);
346
+
347
+ const zipCrypto = new ZipCrypto();
348
+ const encryptedData = zipCrypto.encryptBuffer(entry, compressedData, password);
349
+
350
+ this.log(`Encryption complete: ${compressedData.length} bytes compressed -> ${encryptedData.length} bytes encrypted (includes ${ENCRYPT_HDR_SIZE}-byte header)`);
351
+
352
+ return encryptedData;
353
+ }
354
+
355
+ /**
356
+ * Compress file data in memory and return ZIP entry information as Buffer
357
+ * @param entry - ZIP entry to compress
358
+ * @param fileData - File data buffer to compress
359
+ * @param cmpOptions - Compression options
360
+ * @returns Buffer containing local header + compressed data
361
+ */
362
+ async compressFileBuffer(
363
+ entry: ZipEntry,
364
+ fileData: Buffer,
365
+ cmpOptions?: CompressOptions
366
+ ): Promise<Buffer> {
367
+ this.log(`compressFileBuffer() called for entry: ${entry.filename}, size: ${fileData.length}`);
368
+
369
+ // Set uncompressed size
370
+ entry.uncompressedSize = fileData.length;
371
+
372
+ // Initialize hash calculator
373
+ const hashCalculator = new HashCalculator({ useSHA256: cmpOptions?.useSHA256 || false });
374
+ hashCalculator.update(fileData);
375
+
376
+ // Set hashes
377
+ entry.crc = hashCalculator.finalizeCRC32();
378
+ if (cmpOptions?.useSHA256) {
379
+ entry.sha256 = hashCalculator.finalizeSHA256();
380
+ this.log(`SHA-256 calculated: ${entry.sha256}`);
381
+ }
382
+
383
+ // Compress data
384
+ const compressedData = await this.compressData(entry, fileData, cmpOptions);
385
+
386
+ // Encrypt if password provided
387
+ if (cmpOptions?.password) {
388
+ this.log(`Encrypting compressed data for entry: ${entry.filename}`);
389
+ (entry as any).gpFlag = ((entry as any).gpFlag || 0) | GP_FLAG.ENCRYPTED;
390
+ (entry as any).isEncrypted = true;
391
+ const zipCrypto = new ZipCrypto();
392
+ const encryptedData = zipCrypto.encryptBuffer(entry, compressedData, cmpOptions.password);
393
+ return encryptedData;
394
+ }
395
+
396
+ return compressedData;
397
+ }
398
+ }