diff --git a/README.md b/README.md index a35b2ce..b5a863f 100644 --- a/README.md +++ b/README.md @@ -54,12 +54,14 @@ import { MainBundlePath, DocumentDirectoryPath } from 'react-native-fs' ## API -**`zip(source: string | string[], target: string): Promise`** +**`zip(source: string | string[], target: string, compressionLevel?: number): Promise`** > zip source to target ***NOTE: the string version of source is for folder, the string[] version is for file, so if you want to zip a single file, use zip([file]) instead of zip(file)*** +***NOTE: customizing the compression level is not supported on iOS with a files source and will be ignored, use a directory source instead. + Example ```js @@ -75,13 +77,15 @@ zip(sourcePath, targetPath) }) ``` -**`zipWithPassword(source: string | string[], target: string, password: string, encryptionType: string): Promise`** +**`zipWithPassword(source: string | string[], target: string, password: string, encryptionType?: string, compressionLevel?: number): Promise`** > zip source to target ***NOTE: the string version of source is for folder, the string[] version is for file, so if you want to zip a single file, use zip([file]) instead of zip(file)*** -***NOTE: encryptionType is not supported on iOS yet, so it would be igonred on that platform.*** +***NOTE: encryptionType is not supported on iOS yet, so it would be ignored on that platform.*** + +***NOTE: customizing the compression level is not supported on iOS with a files source and will be ignored, use a directory source instead. Example diff --git a/android/src/main/java/com/rnziparchive/RNZipArchiveModule.java b/android/src/main/java/com/rnziparchive/RNZipArchiveModule.java index 54f1955..90638fa 100644 --- a/android/src/main/java/com/rnziparchive/RNZipArchiveModule.java +++ b/android/src/main/java/com/rnziparchive/RNZipArchiveModule.java @@ -283,39 +283,37 @@ public void run() { } @ReactMethod - public void zipFiles(final ReadableArray files, final String destDirectory, final Promise promise) { - zip(files.toArrayList(), destDirectory, promise); + public void zipFiles(final ReadableArray files, final String destDirectory, final double compressionLevel, final Promise promise) { + zip(files.toArrayList(), destDirectory, compressionLevel, promise); } @ReactMethod - public void zipFolder(final String folder, final String destFile, final Promise promise) { + public void zipFolder(final String folder, final String destFile, final double compressionLevel, final Promise promise) { ArrayList folderAsArrayList = new ArrayList<>(); folderAsArrayList.add(folder); - zip(folderAsArrayList, destFile, promise); + zip(folderAsArrayList, destFile, compressionLevel, promise); } @ReactMethod public void zipFilesWithPassword(final ReadableArray files, final String destFile, final String password, - String encryptionMethod, Promise promise) { - zipWithPassword(files.toArrayList(), destFile, password, encryptionMethod, promise); + String encryptionMethod, final double compressionLevel, Promise promise) { + zipWithPassword(files.toArrayList(), destFile, password, encryptionMethod, compressionLevel, promise); } - @ReactMethod public void zipFolderWithPassword(final String folder, final String destFile, final String password, - String encryptionMethod, Promise promise) { + String encryptionMethod, final double compressionLevel, Promise promise) { ArrayList folderAsArrayList = new ArrayList<>(); folderAsArrayList.add(folder); - zipWithPassword(folderAsArrayList, destFile, password, encryptionMethod, promise); + zipWithPassword(folderAsArrayList, destFile, password, encryptionMethod, compressionLevel, promise); } private void zipWithPassword(final ArrayList filesOrDirectory, final String destFile, final String password, - String encryptionMethod, Promise promise) { + String encryptionMethod, final double compressionLevel, Promise promise) { try{ - ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(CompressionMethod.DEFLATE); - parameters.setCompressionLevel(CompressionLevel.NORMAL); + parameters.setCompressionLevel(getCompressionLevel(compressionLevel)); String encParts[] = encryptionMethod.split("-"); @@ -347,15 +345,13 @@ private void zipWithPassword(final ArrayList filesOrDirectory, final Str promise.reject(null, ex.getMessage()); return; } - } - private void zip(final ArrayList filesOrDirectory, final String destFile, final Promise promise) { + private void zip(final ArrayList filesOrDirectory, final String destFile, final double compressionLevel, final Promise promise) { try{ - ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(CompressionMethod.DEFLATE); - parameters.setCompressionLevel(CompressionLevel.NORMAL); + parameters.setCompressionLevel(getCompressionLevel(compressionLevel)); processZip(filesOrDirectory, destFile, parameters, promise, null); @@ -473,6 +469,36 @@ private long getUncompressedSize(String zipFilePath, String charset) { return totalSize; } + private static CompressionLevel getCompressionLevel(double compressionLevel) { + switch (compressionLevel) { + case -1: + return CompressionLevel.NORMAL; + case 0: + return CompressionLevel.NO_COMPRESSION; + case 1: + return CompressionLevel.FASTEST; + case 2: + return CompressionLevel.FASTER; + case 3: + return CompressionLevel.FAST; + case 4: + return CompressionLevel.MEDIUM_FAST; + case 5: + return CompressionLevel.NORMAL; + case 6: + return CompressionLevel.HIGHER; + case 7: + return CompressionLevel.MAXIMUM; + case 8: + return CompressionLevel.PRE_ULTRA; + case 9: + return CompressionLevel.ULTRA; + default: + Log.w(TAG, "Unsupported compression level: " + level + ", defaulting to NORMAL (5)"); + return CompressionLevel.NORMAL; + } + } + /** * Returns the exception stack trace as a string */ @@ -492,5 +518,4 @@ public void addListener(String eventName) { public void removeListeners(Integer count) { // Keep: Required for RN built in Event Emitter Calls. } - } diff --git a/index.d.ts b/index.d.ts index 80111e1..0e6cb0d 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,13 +1,27 @@ -declare module 'react-native-zip-archive' { +declare module "react-native-zip-archive" { enum EncryptionMethods { STANDARD = "STANDARD", AES_128 = "AES-128", - AES_256 = "AES-256" + AES_256 = "AES-256", } - import { NativeEventSubscription } from 'react-native'; + import { NativeEventSubscription } from "react-native"; + export const DEFAULT_COMPRESSION: number; + export const NO_COMPRESSION: number; + export const BEST_SPEED: number; + export const BEST_COMPRESSION: number; export function isPasswordProtected(source: string): Promise; - export function zip(source: string | string[], target: string): Promise; - export function zipWithPassword(source: string | string[], target: string, password: string, encryptionMethod?: encryptionMethods): Promise; + export function zip( + source: string | string[], + target: string, + compressionLevel: number = DEFAULT_COMPRESSION + ): Promise; + export function zipWithPassword( + source: string | string[], + target: string, + password: string, + encryptionMethod?: EncryptionMethods, + compressionLevel: number = DEFAULT_COMPRESSION + ): Promise; export function unzip(source: string, target: string, charset?: string): Promise; export function unzipWithPassword(assetPath: string, target: string, password: string): Promise; export function unzipAssets(assetPath: string, target: string): Promise; diff --git a/index.js b/index.js index bfc9966..f1e46b0 100644 --- a/index.js +++ b/index.js @@ -9,6 +9,11 @@ const rnzaEmitter = new NativeEventEmitter(RNZipArchive); const normalizeFilePath = (path) => path.startsWith("file://") ? path.slice(7) : path; +export const DEFAULT_COMPRESSION = -1; +export const NO_COMPRESSION = 0; +export const BEST_SPEED = 1; +export const BEST_COMPRESSION = 9; + export const unzip = (source, target, charset = "UTF-8") => { return RNZipArchive.unzip( normalizeFilePath(source), @@ -16,6 +21,7 @@ export const unzip = (source, target, charset = "UTF-8") => { charset ); }; + export const isPasswordProtected = (source) => { return RNZipArchive.isPasswordProtected(normalizeFilePath(source)).then( (isEncrypted) => !!isEncrypted @@ -34,32 +40,37 @@ export const zipWithPassword = ( source, target, password, - encryptionMethod = "" + encryptionMethod = "", + compressionLevel = DEFAULT_COMPRESSION, ) => { return Array.isArray(source) ? RNZipArchive.zipFilesWithPassword( source.map(normalizeFilePath), normalizeFilePath(target), password, - encryptionMethod + encryptionMethod, + compressionLevel ) : RNZipArchive.zipFolderWithPassword( normalizeFilePath(source), normalizeFilePath(target), password, - encryptionMethod + encryptionMethod, + compressionLevel ); }; -export const zip = (source, target) => { +export const zip = (source, target, compressionLevel = DEFAULT_COMPRESSION) => { return Array.isArray(source) ? RNZipArchive.zipFiles( source.map(normalizeFilePath), - normalizeFilePath(target) + normalizeFilePath(target), + compressionLevel ) : RNZipArchive.zipFolder( normalizeFilePath(source), - normalizeFilePath(target) + normalizeFilePath(target), + compressionLevel ); }; diff --git a/ios/RNZipArchive.m b/ios/RNZipArchive.m index 51e92ba..e14b143 100644 --- a/ios/RNZipArchive.m +++ b/ios/RNZipArchive.m @@ -97,6 +97,7 @@ -(void)stopObserving { RCT_EXPORT_METHOD(zipFolder:(NSString *)from destinationPath:(NSString *)destinationPath + compressionLevel:(double)compressionLevel resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { self.progress = 0.0; @@ -106,7 +107,13 @@ -(void)stopObserving { BOOL success; [self setProgressHandler]; - success = [SSZipArchive createZipFileAtPath:destinationPath withContentsOfDirectory:from keepParentDirectory:NO withPassword:nil andProgressHandler:self.progressHandler]; + success = [SSZipArchive createZipFileAtPath:destinationPath + withContentsOfDirectory:from + keepParentDirectory:NO + compressionLevel:compressionLevel + password:nil + AES:NO + progressHandler:self.progressHandler]; self.progress = 1.0; [self zipArchiveProgressEvent:1 total:1]; // force 100% @@ -121,6 +128,7 @@ -(void)stopObserving { RCT_EXPORT_METHOD(zipFiles:(NSArray *)from destinationPath:(NSString *)destinationPath + compressionLevel:(double)compressionLevel resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { self.progress = 0.0; @@ -143,11 +151,11 @@ -(void)stopObserving { } } - RCT_EXPORT_METHOD(zipFolderWithPassword:(NSString *)from destinationPath:(NSString *)destinationPath password:(NSString *)password encryptionType:(NSString *)encryptionType + compressionLevel:(double)compressionLevel resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { self.progress = 0.0; @@ -156,7 +164,13 @@ -(void)stopObserving { BOOL success; [self setProgressHandler]; - success = [SSZipArchive createZipFileAtPath:destinationPath withContentsOfDirectory:from keepParentDirectory:NO withPassword:password andProgressHandler:self.progressHandler]; + success = [SSZipArchive createZipFileAtPath:destinationPath + withContentsOfDirectory:from + keepParentDirectory:NO + compressionLevel:compressionLevel + password:password + AES:NO + progressHandler:self.progressHandler]; self.progress = 1.0; [self zipArchiveProgressEvent:1 total:1]; // force 100% @@ -173,6 +187,7 @@ -(void)stopObserving { destinationPath:(NSString *)destinationPath password:(NSString *)password encryptionType:(NSString *)encryptionType + compressionLevel:(double)compressionLevel resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { self.progress = 0.0;