react-native-compressor 1.18.2 → 2.0.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/android/CMakeLists.txt +27 -0
- package/android/build.gradle +56 -58
- package/android/gradle.properties +5 -5
- package/android/src/main/AndroidManifestNew.xml +3 -0
- package/android/src/main/cpp/cpp-adapter.cpp +8 -0
- package/android/src/main/java/com/margelo/nitro/compressor/HybridCompressor.kt +213 -0
- package/android/src/main/java/com/reactnativecompressor/Image/ImageCompressor.kt +41 -21
- package/android/src/main/java/com/reactnativecompressor/NitroCompressorPackage.kt +30 -0
- package/android/src/main/java/com/reactnativecompressor/NitroPromiseAdapter.kt +55 -0
- package/android/src/main/java/com/reactnativecompressor/Utils/EventEmitterHandler.kt +49 -45
- package/android/src/main/java/com/reactnativecompressor/Utils/Utils.kt +1 -1
- package/android/src/main/java/com/reactnativecompressor/Video/AutoVideoCompression.kt +1 -1
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressionProfile.kt +21 -11
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressor/compressor/Compressor.kt +311 -76
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressor/utils/CompressorUtils.kt +96 -5
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressor/utils/LocationExtractor.kt +397 -0
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressor/videoHelpers/LocationBox.kt +47 -0
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressor/videoHelpers/MP4Builder.kt +39 -7
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressor/videoHelpers/Mp4Movie.kt +7 -0
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressor/videoHelpers/OutputSurface.kt +30 -4
- package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressorHelper.kt +28 -2
- package/ios/Audio/FormatConverter/FormatConverter+Compressed.swift +1 -1
- package/ios/Audio/FormatConverter/FormatConverter+Utilities.swift +1 -1
- package/ios/Audio/FormatConverter/FormatConverter.swift +5 -3
- package/ios/HybridCompressor.swift +247 -0
- package/ios/Image/ImageCompressor.swift +8 -2
- package/ios/Utils/EventEmitterHandler.swift +56 -34
- package/ios/Video/NextLevelSessionExporter.swift +43 -8
- package/ios/Video/VideoMain.swift +44 -14
- package/lib/commonjs/Audio/index.js +1 -1
- package/lib/commonjs/Audio/index.js.map +1 -1
- package/lib/commonjs/Image/index.js +2 -22
- package/lib/commonjs/Image/index.js.map +1 -1
- package/lib/commonjs/Main.js +8 -8
- package/lib/commonjs/Main.js.map +1 -1
- package/lib/commonjs/Video/index.js +25 -65
- package/lib/commonjs/Video/index.js.map +1 -1
- package/lib/commonjs/specs/Compressor.nitro.js +6 -0
- package/lib/commonjs/specs/Compressor.nitro.js.map +1 -0
- package/lib/commonjs/utils/Downloader.js +8 -24
- package/lib/commonjs/utils/Downloader.js.map +1 -1
- package/lib/commonjs/utils/Uploader.js +3 -18
- package/lib/commonjs/utils/Uploader.js.map +1 -1
- package/lib/commonjs/utils/helpers.js +18 -1
- package/lib/commonjs/utils/helpers.js.map +1 -1
- package/lib/commonjs/utils/index.js +13 -13
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/module/Audio/index.js +2 -2
- package/lib/module/Audio/index.js.map +1 -1
- package/lib/module/Image/index.js +3 -23
- package/lib/module/Image/index.js.map +1 -1
- package/lib/module/Main.js +9 -9
- package/lib/module/Main.js.map +1 -1
- package/lib/module/Video/index.js +26 -66
- package/lib/module/Video/index.js.map +1 -1
- package/lib/module/specs/Compressor.nitro.js +4 -0
- package/lib/module/specs/Compressor.nitro.js.map +1 -0
- package/lib/module/utils/Downloader.js +10 -26
- package/lib/module/utils/Downloader.js.map +1 -1
- package/lib/module/utils/Uploader.js +5 -20
- package/lib/module/utils/Uploader.js.map +1 -1
- package/lib/module/utils/helpers.js +16 -0
- package/lib/module/utils/helpers.js.map +1 -1
- package/lib/module/utils/index.js +2 -1
- package/lib/module/utils/index.js.map +1 -1
- package/lib/typescript/src/Image/index.d.ts.map +1 -1
- package/lib/typescript/src/Main.d.ts +2 -1
- package/lib/typescript/src/Main.d.ts.map +1 -1
- package/lib/typescript/src/Video/index.d.ts +1 -1
- package/lib/typescript/src/Video/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/Compressor.nitro.d.ts +44 -0
- package/lib/typescript/src/specs/Compressor.nitro.d.ts.map +1 -0
- package/lib/typescript/src/utils/Downloader.d.ts.map +1 -1
- package/lib/typescript/src/utils/Uploader.d.ts.map +1 -1
- package/lib/typescript/src/utils/helpers.d.ts +7 -0
- package/lib/typescript/src/utils/helpers.d.ts.map +1 -1
- package/lib/typescript/src/utils/index.d.ts.map +1 -1
- package/nitrogen/generated/android/NitroCompressor+autolinking.cmake +81 -0
- package/nitrogen/generated/android/NitroCompressor+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NitroCompressorOnLoad.cpp +60 -0
- package/nitrogen/generated/android/NitroCompressorOnLoad.hpp +34 -0
- package/nitrogen/generated/android/c++/JFunc_void.hpp +75 -0
- package/nitrogen/generated/android/c++/JFunc_void_double.hpp +75 -0
- package/nitrogen/generated/android/c++/JFunc_void_double_double.hpp +75 -0
- package/nitrogen/generated/android/c++/JHybridCompressorSpec.cpp +293 -0
- package/nitrogen/generated/android/c++/JHybridCompressorSpec.hpp +78 -0
- package/nitrogen/generated/android/c++/JVideoThumbnailResult.hpp +73 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/compressor/Func_void.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/compressor/Func_void_double.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/compressor/Func_void_double_double.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/compressor/HybridCompressorSpec.kt +141 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/compressor/NitroCompressorOnLoad.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/compressor/VideoThumbnailResult.kt +71 -0
- package/nitrogen/generated/ios/c++/HybridCompressorSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridCompressorSpecSwift.hpp +204 -0
- package/nitrogen/generated/ios/react_native_compressor+autolinking.rb +62 -0
- package/nitrogen/generated/ios/react_native_compressor-Swift-Cxx-Bridge.cpp +89 -0
- package/nitrogen/generated/ios/react_native_compressor-Swift-Cxx-Bridge.hpp +337 -0
- package/nitrogen/generated/ios/react_native_compressor-Swift-Cxx-Umbrella.hpp +51 -0
- package/nitrogen/generated/ios/react_native_compressorAutolinking.mm +33 -0
- package/nitrogen/generated/ios/react_native_compressorAutolinking.swift +26 -0
- package/nitrogen/generated/ios/swift/Func_void.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_VideoThumbnailResult.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_double.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_double_double.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_AnyMap_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridCompressorSpec.swift +70 -0
- package/nitrogen/generated/ios/swift/HybridCompressorSpec_cxx.swift +493 -0
- package/nitrogen/generated/ios/swift/VideoThumbnailResult.swift +49 -0
- package/nitrogen/generated/shared/c++/HybridCompressorSpec.cpp +36 -0
- package/nitrogen/generated/shared/c++/HybridCompressorSpec.hpp +83 -0
- package/nitrogen/generated/shared/c++/VideoThumbnailResult.hpp +99 -0
- package/package.json +8 -12
- package/react-native-compressor.podspec +6 -24
- package/src/Audio/index.tsx +2 -2
- package/src/Image/index.tsx +3 -26
- package/src/Main.tsx +14 -16
- package/src/Video/index.tsx +25 -77
- package/src/specs/Compressor.nitro.ts +56 -0
- package/src/utils/Downloader.tsx +8 -27
- package/src/utils/Uploader.tsx +12 -24
- package/src/utils/helpers.ts +18 -0
- package/src/utils/index.tsx +3 -2
- package/android/src/main/java/com/reactnativecompressor/CompressorModule.kt +0 -180
- package/android/src/main/java/com/reactnativecompressor/CompressorPackage.kt +0 -34
- package/android/src/newarch/CompressorSpec.kt +0 -5
- package/android/src/oldarch/CompressorSpec.kt +0 -36
- package/ios/Compressor-Bridging-Header.h +0 -6
- package/ios/Compressor.h +0 -5
- package/ios/Compressor.mm +0 -82
- package/ios/CompressorManager.swift +0 -117
- package/lib/commonjs/Spec/NativeCompressor.js +0 -9
- package/lib/commonjs/Spec/NativeCompressor.js.map +0 -1
- package/lib/module/Spec/NativeCompressor.js +0 -5
- package/lib/module/Spec/NativeCompressor.js.map +0 -1
- package/lib/typescript/src/Spec/NativeCompressor.d.ts +0 -30
- package/lib/typescript/src/Spec/NativeCompressor.d.ts.map +0 -1
- package/src/Spec/NativeCompressor.ts +0 -41
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// VideoThumbnailResult.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
|
|
26
|
+
#include <NitroModules/PropNameIDCache.hpp>
|
|
27
|
+
#else
|
|
28
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
#include <string>
|
|
34
|
+
|
|
35
|
+
namespace margelo::nitro::compressor {
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A struct which can be represented as a JavaScript object (VideoThumbnailResult).
|
|
39
|
+
*/
|
|
40
|
+
struct VideoThumbnailResult final {
|
|
41
|
+
public:
|
|
42
|
+
std::string path SWIFT_PRIVATE;
|
|
43
|
+
double size SWIFT_PRIVATE;
|
|
44
|
+
std::string mime SWIFT_PRIVATE;
|
|
45
|
+
double width SWIFT_PRIVATE;
|
|
46
|
+
double height SWIFT_PRIVATE;
|
|
47
|
+
|
|
48
|
+
public:
|
|
49
|
+
VideoThumbnailResult() = default;
|
|
50
|
+
explicit VideoThumbnailResult(std::string path, double size, std::string mime, double width, double height): path(path), size(size), mime(mime), width(width), height(height) {}
|
|
51
|
+
|
|
52
|
+
public:
|
|
53
|
+
friend bool operator==(const VideoThumbnailResult& lhs, const VideoThumbnailResult& rhs) = default;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
} // namespace margelo::nitro::compressor
|
|
57
|
+
|
|
58
|
+
namespace margelo::nitro {
|
|
59
|
+
|
|
60
|
+
// C++ VideoThumbnailResult <> JS VideoThumbnailResult (object)
|
|
61
|
+
template <>
|
|
62
|
+
struct JSIConverter<margelo::nitro::compressor::VideoThumbnailResult> final {
|
|
63
|
+
static inline margelo::nitro::compressor::VideoThumbnailResult fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
64
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
65
|
+
return margelo::nitro::compressor::VideoThumbnailResult(
|
|
66
|
+
JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "path"))),
|
|
67
|
+
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "size"))),
|
|
68
|
+
JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mime"))),
|
|
69
|
+
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width"))),
|
|
70
|
+
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height")))
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::compressor::VideoThumbnailResult& arg) {
|
|
74
|
+
jsi::Object obj(runtime);
|
|
75
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "path"), JSIConverter<std::string>::toJSI(runtime, arg.path));
|
|
76
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "size"), JSIConverter<double>::toJSI(runtime, arg.size));
|
|
77
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "mime"), JSIConverter<std::string>::toJSI(runtime, arg.mime));
|
|
78
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "width"), JSIConverter<double>::toJSI(runtime, arg.width));
|
|
79
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "height"), JSIConverter<double>::toJSI(runtime, arg.height));
|
|
80
|
+
return obj;
|
|
81
|
+
}
|
|
82
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
83
|
+
if (!value.isObject()) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
jsi::Object obj = value.getObject(runtime);
|
|
87
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "path")))) return false;
|
|
91
|
+
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "size")))) return false;
|
|
92
|
+
if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "mime")))) return false;
|
|
93
|
+
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width")))) return false;
|
|
94
|
+
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height")))) return false;
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
} // namespace margelo::nitro
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-compressor",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Compress Image, Video, and Audio same like Whatsapp & Auto/Manual Compression | Background Upload | Download File | Create Video Thumbnail",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"android",
|
|
14
14
|
"ios",
|
|
15
15
|
"cpp",
|
|
16
|
+
"nitrogen",
|
|
16
17
|
"app.plugin.js",
|
|
17
18
|
"*.podspec",
|
|
18
19
|
"!lib/typescript/example",
|
|
@@ -34,7 +35,8 @@
|
|
|
34
35
|
"test:harness:ios": "cd examples/bare && react-native-harness --config ./jest.harness.config.mjs --harnessRunner ios --verbose",
|
|
35
36
|
"typecheck": "tsc --noEmit",
|
|
36
37
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
37
|
-
"
|
|
38
|
+
"nitrogen": "nitrogen",
|
|
39
|
+
"prepack": "nitrogen && bob build",
|
|
38
40
|
"release": "release-it",
|
|
39
41
|
"example:bare": "yarn workspace react-native-compressor-bare-example",
|
|
40
42
|
"example:expo": "yarn workspace react-native-compressor-expo-example",
|
|
@@ -106,18 +108,21 @@
|
|
|
106
108
|
"eslint-plugin-prettier": "^5.5.5",
|
|
107
109
|
"jest": "^30.3.0",
|
|
108
110
|
"lefthook": "^2.1.4",
|
|
111
|
+
"nitrogen": "^0.35.9",
|
|
109
112
|
"prettier": "^3.8.1",
|
|
110
113
|
"react": "19.2.3",
|
|
111
114
|
"react-native": "0.85.0",
|
|
112
115
|
"react-native-builder-bob": "^0.41.0",
|
|
113
116
|
"react-native-harness": "1.1.0",
|
|
117
|
+
"react-native-nitro-modules": "^0.35.9",
|
|
114
118
|
"release-it": "^19.2.4",
|
|
115
119
|
"turbo": "^2.8.21",
|
|
116
120
|
"typescript": "^6.0.2"
|
|
117
121
|
},
|
|
118
122
|
"peerDependencies": {
|
|
119
123
|
"react": "*",
|
|
120
|
-
"react-native": "*"
|
|
124
|
+
"react-native": "*",
|
|
125
|
+
"react-native-nitro-modules": ">=0.35.0"
|
|
121
126
|
},
|
|
122
127
|
"engines": {
|
|
123
128
|
"node": ">= 22.11.0"
|
|
@@ -136,15 +141,6 @@
|
|
|
136
141
|
]
|
|
137
142
|
]
|
|
138
143
|
},
|
|
139
|
-
"codegenConfig": {
|
|
140
|
-
"libraries": [
|
|
141
|
-
{
|
|
142
|
-
"name": "RNCompressorSpec",
|
|
143
|
-
"type": "modules",
|
|
144
|
-
"jsSrcsDir": "src"
|
|
145
|
-
}
|
|
146
|
-
]
|
|
147
|
-
},
|
|
148
144
|
"workspaces": [
|
|
149
145
|
"examples/*"
|
|
150
146
|
],
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
require "json"
|
|
2
2
|
|
|
3
3
|
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
-
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
|
|
5
4
|
|
|
6
5
|
Pod::Spec.new do |s|
|
|
7
6
|
s.name = "react-native-compressor"
|
|
@@ -11,32 +10,15 @@ Pod::Spec.new do |s|
|
|
|
11
10
|
s.license = package["license"]
|
|
12
11
|
s.authors = package["author"]
|
|
13
12
|
|
|
14
|
-
s.platforms = { :ios => "
|
|
13
|
+
s.platforms = { :ios => "13.4" }
|
|
15
14
|
s.source = { :git => "https://github.com/numandev1/react-native-compressor.git", :tag => "#{s.version}" }
|
|
16
15
|
|
|
17
16
|
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if respond_to?(:install_modules_dependencies, true)
|
|
23
|
-
install_modules_dependencies(s)
|
|
24
|
-
else
|
|
25
|
-
s.dependency "React-Core"
|
|
18
|
+
# Add all files generated by Nitrogen + the NitroModules dependency.
|
|
19
|
+
load File.join(__dir__, 'nitrogen', 'generated', 'ios', 'react_native_compressor+autolinking.rb')
|
|
20
|
+
add_nitrogen_files(s)
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
|
|
30
|
-
s.pod_target_xcconfig = {
|
|
31
|
-
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
|
|
32
|
-
"OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
|
|
33
|
-
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
|
|
34
|
-
}
|
|
35
|
-
s.dependency "React-Codegen"
|
|
36
|
-
s.dependency "RCT-Folly"
|
|
37
|
-
s.dependency "RCTRequired"
|
|
38
|
-
s.dependency "RCTTypeSafety"
|
|
39
|
-
s.dependency "ReactCommon/turbomodule/core"
|
|
40
|
-
end
|
|
41
|
-
end
|
|
22
|
+
s.dependency "React-Core"
|
|
23
|
+
install_modules_dependencies(s)
|
|
42
24
|
end
|
package/src/Audio/index.tsx
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Compressor } from '../Main';
|
|
2
2
|
|
|
3
|
-
import { DEFAULT_COMPRESS_AUDIO_OPTIONS } from '../utils';
|
|
3
|
+
import { DEFAULT_COMPRESS_AUDIO_OPTIONS, toNativeOptions } from '../utils';
|
|
4
4
|
import type { AudioType } from '../utils';
|
|
5
5
|
const NativeAudio = Compressor;
|
|
6
6
|
|
|
7
7
|
const Audio: AudioType = {
|
|
8
8
|
compress: async (url, options = DEFAULT_COMPRESS_AUDIO_OPTIONS) => {
|
|
9
9
|
try {
|
|
10
|
-
return NativeAudio.compress_audio(url, options);
|
|
10
|
+
return NativeAudio.compress_audio(url, toNativeOptions(options));
|
|
11
11
|
} catch (error: any) {
|
|
12
12
|
throw error.message;
|
|
13
13
|
}
|
package/src/Image/index.tsx
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { Compressor } from '../Main';
|
|
2
|
-
import {
|
|
2
|
+
import { toNativeOptions } from '../utils';
|
|
3
3
|
const base64UrlRegex = /^data:image\/.*;(?:charset=.{3,5};)?base64,/;
|
|
4
|
-
import type { NativeEventSubscription } from 'react-native';
|
|
5
|
-
import { NativeEventEmitter } from 'react-native';
|
|
6
4
|
|
|
7
5
|
export type InputType = 'base64' | 'uri';
|
|
8
6
|
|
|
@@ -55,8 +53,6 @@ export type CompressorOptions = {
|
|
|
55
53
|
progressDivider?: number;
|
|
56
54
|
};
|
|
57
55
|
|
|
58
|
-
const ImageCompressEventEmitter = new NativeEventEmitter(Compressor);
|
|
59
|
-
|
|
60
56
|
const NativeImage = Compressor;
|
|
61
57
|
|
|
62
58
|
type ImageType = {
|
|
@@ -69,27 +65,8 @@ const Image: ImageType = {
|
|
|
69
65
|
throw new Error('Compression value is empty, please provide a value for compression.');
|
|
70
66
|
}
|
|
71
67
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (options?.downloadProgress) {
|
|
75
|
-
const uuid = uuidv4();
|
|
76
|
-
//@ts-ignore
|
|
77
|
-
options.uuid = uuid;
|
|
78
|
-
subscription = ImageCompressEventEmitter.addListener('downloadProgress', (event: any) => {
|
|
79
|
-
if (event.uuid === uuid) {
|
|
80
|
-
options.downloadProgress && options.downloadProgress(event.data.progress);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const cleanData = value.replace(base64UrlRegex, '');
|
|
86
|
-
return await NativeImage.image_compress(cleanData, options);
|
|
87
|
-
} finally {
|
|
88
|
-
// @ts-ignore
|
|
89
|
-
if (subscription) {
|
|
90
|
-
subscription.remove();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
68
|
+
const cleanData = value.replace(base64UrlRegex, '');
|
|
69
|
+
return await NativeImage.image_compress(cleanData, toNativeOptions(options), options.downloadProgress);
|
|
93
70
|
},
|
|
94
71
|
};
|
|
95
72
|
|
package/src/Main.tsx
CHANGED
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import { NitroModules } from 'react-native-nitro-modules';
|
|
3
|
+
|
|
4
|
+
import type { Compressor as CompressorSpec } from './specs/Compressor.nitro';
|
|
2
5
|
|
|
3
6
|
const LINKING_ERROR =
|
|
4
7
|
`The package 'react-native-compressor' doesn't seem to be linked. Make sure: \n\n` +
|
|
5
8
|
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
|
|
6
9
|
'- You rebuilt the app after installing the package\n' +
|
|
7
|
-
'- You are not using Expo Go\n'
|
|
8
|
-
|
|
9
|
-
// @ts-expect-error
|
|
10
|
-
const isTurboModuleEnabled = global.__turboModuleProxy != null;
|
|
10
|
+
'- You are not using Expo Go\n' +
|
|
11
|
+
'- You have installed `react-native-nitro-modules`\n';
|
|
11
12
|
|
|
12
|
-
const
|
|
13
|
+
const createCompressor = (): CompressorSpec => {
|
|
14
|
+
try {
|
|
15
|
+
return NitroModules.createHybridObject<CompressorSpec>('Compressor');
|
|
16
|
+
} catch {
|
|
17
|
+
throw new Error(LINKING_ERROR);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
13
20
|
|
|
14
|
-
const Compressor =
|
|
15
|
-
? CompressorModule
|
|
16
|
-
: new Proxy(
|
|
17
|
-
{},
|
|
18
|
-
{
|
|
19
|
-
get() {
|
|
20
|
-
throw new Error(LINKING_ERROR);
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
);
|
|
21
|
+
const Compressor = createCompressor();
|
|
24
22
|
|
|
25
23
|
export { Compressor };
|
package/src/Video/index.tsx
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { NativeEventEmitter } from 'react-native';
|
|
2
|
-
import type { NativeEventSubscription } from 'react-native';
|
|
3
1
|
import { Compressor } from '../Main';
|
|
4
|
-
import { uuidv4 } from '../utils';
|
|
2
|
+
import { toNativeOptions, uuidv4 } from '../utils';
|
|
5
3
|
|
|
6
4
|
export type compressionMethod = 'auto' | 'manual';
|
|
7
5
|
type videoCompresssionType = {
|
|
@@ -29,8 +27,6 @@ export type VideoCompressorType = {
|
|
|
29
27
|
deactivateBackgroundTask(): Promise<any>;
|
|
30
28
|
};
|
|
31
29
|
|
|
32
|
-
const VideoCompressEventEmitter = new NativeEventEmitter(Compressor);
|
|
33
|
-
|
|
34
30
|
const NativeVideoCompressor = Compressor;
|
|
35
31
|
|
|
36
32
|
export const cancelCompression = (cancellationId: string) => {
|
|
@@ -40,85 +36,37 @@ export const cancelCompression = (cancellationId: string) => {
|
|
|
40
36
|
const Video: VideoCompressorType = {
|
|
41
37
|
compress: async (fileUrl: string, options?: videoCompresssionType, onProgress?: (progress: number) => void) => {
|
|
42
38
|
const uuid = uuidv4();
|
|
43
|
-
let subscription: NativeEventSubscription;
|
|
44
|
-
let subscription2: NativeEventSubscription;
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
if (onProgress) {
|
|
48
|
-
subscription = VideoCompressEventEmitter.addListener('videoCompressProgress', (event: any) => {
|
|
49
|
-
if (event.uuid === uuid) {
|
|
50
|
-
onProgress(event.data.progress);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (options?.downloadProgress) {
|
|
56
|
-
//@ts-ignore
|
|
57
|
-
subscription2 = VideoCompressEventEmitter.addListener('downloadProgress', (event: any) => {
|
|
58
|
-
if (event.uuid === uuid) {
|
|
59
|
-
options.downloadProgress && options.downloadProgress(event.data.progress);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
39
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
modifiedOptions.compressionMethod = options?.compressionMethod;
|
|
77
|
-
} else {
|
|
78
|
-
modifiedOptions.compressionMethod = 'auto';
|
|
79
|
-
}
|
|
80
|
-
if (options?.maxSize) {
|
|
81
|
-
modifiedOptions.maxSize = options?.maxSize;
|
|
82
|
-
} else {
|
|
83
|
-
modifiedOptions.maxSize = 640;
|
|
84
|
-
}
|
|
85
|
-
if (options?.minimumFileSizeForCompress !== undefined) {
|
|
86
|
-
modifiedOptions.minimumFileSizeForCompress = options?.minimumFileSizeForCompress;
|
|
87
|
-
}
|
|
88
|
-
if (options?.stripAudio) {
|
|
89
|
-
modifiedOptions.stripAudio = options.stripAudio;
|
|
90
|
-
}
|
|
91
|
-
if (options?.getCancellationId) {
|
|
92
|
-
options?.getCancellationId(uuid);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const result = await NativeVideoCompressor.compress(fileUrl, modifiedOptions);
|
|
96
|
-
return result;
|
|
97
|
-
} finally {
|
|
98
|
-
// @ts-ignore
|
|
99
|
-
if (subscription) {
|
|
100
|
-
subscription.remove();
|
|
101
|
-
}
|
|
102
|
-
//@ts-ignore
|
|
103
|
-
if (subscription2) {
|
|
104
|
-
subscription2.remove();
|
|
105
|
-
}
|
|
40
|
+
const modifiedOptions: Record<string, unknown> = { uuid };
|
|
41
|
+
if (options?.progressDivider) modifiedOptions.progressDivider = options?.progressDivider;
|
|
42
|
+
if (options?.bitrate) modifiedOptions.bitrate = options?.bitrate;
|
|
43
|
+
if (options?.compressionMethod) {
|
|
44
|
+
modifiedOptions.compressionMethod = options?.compressionMethod;
|
|
45
|
+
} else {
|
|
46
|
+
modifiedOptions.compressionMethod = 'auto';
|
|
47
|
+
}
|
|
48
|
+
if (options?.maxSize) {
|
|
49
|
+
modifiedOptions.maxSize = options?.maxSize;
|
|
50
|
+
} else {
|
|
51
|
+
modifiedOptions.maxSize = 640;
|
|
106
52
|
}
|
|
53
|
+
if (options?.minimumFileSizeForCompress !== undefined) {
|
|
54
|
+
modifiedOptions.minimumFileSizeForCompress = options?.minimumFileSizeForCompress;
|
|
55
|
+
}
|
|
56
|
+
if (options?.stripAudio) {
|
|
57
|
+
modifiedOptions.stripAudio = options.stripAudio;
|
|
58
|
+
}
|
|
59
|
+
if (options?.getCancellationId) {
|
|
60
|
+
options?.getCancellationId(uuid);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return NativeVideoCompressor.compress(fileUrl, toNativeOptions(modifiedOptions), onProgress, options?.downloadProgress);
|
|
107
64
|
},
|
|
108
65
|
cancelCompression,
|
|
109
66
|
activateBackgroundTask(onExpired?) {
|
|
110
|
-
|
|
111
|
-
const subscription: NativeEventSubscription = VideoCompressEventEmitter.addListener('backgroundTaskExpired', (event: any) => {
|
|
112
|
-
onExpired(event);
|
|
113
|
-
if (subscription) {
|
|
114
|
-
subscription.remove();
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
return NativeVideoCompressor.activateBackgroundTask({});
|
|
67
|
+
return NativeVideoCompressor.activateBackgroundTask({}, onExpired ? () => onExpired(undefined) : undefined);
|
|
119
68
|
},
|
|
120
69
|
deactivateBackgroundTask() {
|
|
121
|
-
VideoCompressEventEmitter.removeAllListeners('backgroundTaskExpired');
|
|
122
70
|
return NativeVideoCompressor.deactivateBackgroundTask({});
|
|
123
71
|
},
|
|
124
72
|
} as VideoCompressorType;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { AnyMap, HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
|
|
3
|
+
export interface VideoThumbnailResult {
|
|
4
|
+
path: string;
|
|
5
|
+
size: number;
|
|
6
|
+
mime: string;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Nitro HybridObject spec for the single native `Compressor` module.
|
|
13
|
+
*
|
|
14
|
+
* Notes on the migration from the old TurboModule spec:
|
|
15
|
+
* - Progress is delivered through callback parameters (`onProgress` / `onDownloadProgress` /
|
|
16
|
+
* `onExpired`) instead of `NativeEventEmitter` events. Callbacks can't live inside an `AnyMap`,
|
|
17
|
+
* so any progress callback that used to be nested in the options object is now a top-level param.
|
|
18
|
+
* - `optionMap`/`options` stay untyped (`AnyMap`) and are parsed natively, exactly as before.
|
|
19
|
+
* - `getImageMetaData` / `getVideoMetaData` / `upload` resolve objects at runtime (EXIF map /
|
|
20
|
+
* metadata map / `{status,headers,body}`), so they return `AnyMap` — the old `Promise<string>`
|
|
21
|
+
* typing was lossy.
|
|
22
|
+
* - `uuid` is still threaded inside the options map for cancellation (`cancelCompression` /
|
|
23
|
+
* `cancelUpload`) and for routing native progress emissions to the registered callback.
|
|
24
|
+
*/
|
|
25
|
+
export interface Compressor extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> {
|
|
26
|
+
// Image
|
|
27
|
+
image_compress(imagePath: string, optionMap: AnyMap, onDownloadProgress?: (progress: number) => void): Promise<string>;
|
|
28
|
+
getImageMetaData(filePath: string): Promise<AnyMap>;
|
|
29
|
+
|
|
30
|
+
// Video
|
|
31
|
+
compress(
|
|
32
|
+
fileUrl: string,
|
|
33
|
+
optionMap: AnyMap,
|
|
34
|
+
onProgress?: (progress: number) => void,
|
|
35
|
+
onDownloadProgress?: (progress: number) => void,
|
|
36
|
+
): Promise<string>;
|
|
37
|
+
cancelCompression(uuid: string): void;
|
|
38
|
+
getVideoMetaData(filePath: string): Promise<AnyMap>;
|
|
39
|
+
activateBackgroundTask(options: AnyMap, onExpired?: () => void): Promise<string>;
|
|
40
|
+
deactivateBackgroundTask(options: AnyMap): Promise<string>;
|
|
41
|
+
|
|
42
|
+
// Audio
|
|
43
|
+
compress_audio(fileUrl: string, optionMap: AnyMap): Promise<string>;
|
|
44
|
+
|
|
45
|
+
// Upload / Download
|
|
46
|
+
upload(fileUrl: string, options: AnyMap, onProgress?: (written: number, total: number) => void): Promise<AnyMap>;
|
|
47
|
+
cancelUpload(uuid: string, shouldCancelAll: boolean): void;
|
|
48
|
+
download(fileUrl: string, options: AnyMap, onProgress?: (progress: number) => void): Promise<string>;
|
|
49
|
+
|
|
50
|
+
// Others
|
|
51
|
+
generateFilePath(fileExtension: string): Promise<string>;
|
|
52
|
+
getRealPath(path: string, type: string): Promise<string>;
|
|
53
|
+
getFileSize(filePath: string): Promise<string>;
|
|
54
|
+
createVideoThumbnail(fileUrl: string, options: AnyMap): Promise<VideoThumbnailResult>;
|
|
55
|
+
clearCache(cacheDir?: string): Promise<string>;
|
|
56
|
+
}
|
package/src/utils/Downloader.tsx
CHANGED
|
@@ -1,31 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { NativeEventSubscription } from 'react-native';
|
|
1
|
+
import { Platform } from 'react-native';
|
|
3
2
|
import { Compressor } from '../Main';
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { toNativeOptions, uuidv4 } from './helpers';
|
|
4
|
+
|
|
6
5
|
export const download = async (fileUrl: string, downloadProgress?: (progress: number) => void, progressDivider?: number): Promise<any> => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (downloadProgress) {
|
|
11
|
-
subscription = CompressEventEmitter.addListener('downloadProgress', (event: any) => {
|
|
12
|
-
if (event.uuid === uuid) {
|
|
13
|
-
downloadProgress(event.data.progress);
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
if (Platform.OS === 'android' && fileUrl.includes('file://')) {
|
|
18
|
-
fileUrl = fileUrl.replace('file://', '');
|
|
19
|
-
}
|
|
20
|
-
const result = await Compressor.download(fileUrl, {
|
|
21
|
-
uuid,
|
|
22
|
-
progressDivider,
|
|
23
|
-
});
|
|
24
|
-
return result;
|
|
25
|
-
} finally {
|
|
26
|
-
// @ts-ignore
|
|
27
|
-
if (subscription) {
|
|
28
|
-
subscription.remove();
|
|
29
|
-
}
|
|
6
|
+
const uuid = uuidv4();
|
|
7
|
+
if (Platform.OS === 'android' && fileUrl.includes('file://')) {
|
|
8
|
+
fileUrl = fileUrl.replace('file://', '');
|
|
30
9
|
}
|
|
10
|
+
const result = await Compressor.download(fileUrl, toNativeOptions({ uuid, progressDivider }), downloadProgress);
|
|
11
|
+
return result;
|
|
31
12
|
};
|
package/src/utils/Uploader.tsx
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { NativeEventSubscription } from 'react-native';
|
|
1
|
+
import { Platform } from 'react-native';
|
|
3
2
|
import { Compressor } from '../Main';
|
|
4
|
-
|
|
5
|
-
import { uuidv4 } from './helpers';
|
|
3
|
+
import { toNativeOptions, uuidv4 } from './helpers';
|
|
6
4
|
export enum UploadType {
|
|
7
5
|
BINARY_CONTENT = 0,
|
|
8
6
|
MULTIPART = 1,
|
|
@@ -51,15 +49,7 @@ export const backgroundUpload = async (
|
|
|
51
49
|
abortSignal?: AbortSignal,
|
|
52
50
|
): Promise<any> => {
|
|
53
51
|
const uuid = uuidv4();
|
|
54
|
-
let subscription: NativeEventSubscription;
|
|
55
52
|
try {
|
|
56
|
-
if (onProgress) {
|
|
57
|
-
subscription = CompressEventEmitter.addListener('uploadProgress', (event: any) => {
|
|
58
|
-
if (event.uuid === uuid) {
|
|
59
|
-
onProgress(event.data.written, event.data.total);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
53
|
if (Platform.OS === 'android' && fileUrl.includes('file://')) {
|
|
64
54
|
fileUrl = fileUrl.replace('file://', '');
|
|
65
55
|
}
|
|
@@ -70,20 +60,18 @@ export const backgroundUpload = async (
|
|
|
70
60
|
|
|
71
61
|
abortSignal?.addEventListener('abort', () => cancelUpload(uuid));
|
|
72
62
|
|
|
73
|
-
const result = await Compressor.upload(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
63
|
+
const result = await Compressor.upload(
|
|
64
|
+
fileUrl,
|
|
65
|
+
toNativeOptions({
|
|
66
|
+
...options,
|
|
67
|
+
uuid,
|
|
68
|
+
method: options.httpMethod,
|
|
69
|
+
url,
|
|
70
|
+
}),
|
|
71
|
+
onProgress,
|
|
72
|
+
);
|
|
81
73
|
return result;
|
|
82
74
|
} finally {
|
|
83
|
-
// @ts-ignore
|
|
84
|
-
if (subscription) {
|
|
85
|
-
subscription.remove();
|
|
86
|
-
}
|
|
87
75
|
abortSignal?.removeEventListener('abort', () => cancelUpload(uuid));
|
|
88
76
|
}
|
|
89
77
|
};
|
package/src/utils/helpers.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { AnyMap } from 'react-native-nitro-modules';
|
|
2
|
+
|
|
1
3
|
export const uuidv4 = () => {
|
|
2
4
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
3
5
|
const r = (parseFloat('0.' + Math.random().toString().replace('0.', '') + new Date().getTime()) * 16) | 0,
|
|
@@ -6,3 +8,19 @@ export const uuidv4 = () => {
|
|
|
6
8
|
return v.toString(16);
|
|
7
9
|
});
|
|
8
10
|
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Build a Nitro-safe options map. Nitro's `AnyMap` converter throws when it
|
|
14
|
+
* encounters a `undefined` or function-valued property, so we drop both —
|
|
15
|
+
* progress callbacks are passed as separate native method parameters now.
|
|
16
|
+
*/
|
|
17
|
+
export const toNativeOptions = (options: Record<string, unknown>): AnyMap => {
|
|
18
|
+
const result: Record<string, unknown> = {};
|
|
19
|
+
for (const key of Object.keys(options)) {
|
|
20
|
+
const value = options[key];
|
|
21
|
+
if (value !== undefined && typeof value !== 'function') {
|
|
22
|
+
result[key] = value;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return result as AnyMap;
|
|
26
|
+
};
|
package/src/utils/index.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Compressor } from '../Main';
|
|
2
2
|
import { Platform } from 'react-native';
|
|
3
|
+
import { toNativeOptions } from './helpers';
|
|
3
4
|
type qualityType = 'low' | 'medium' | 'high';
|
|
4
5
|
const INCORRECT_INPUT_PATH = 'Incorrect input path. Please provide a valid one';
|
|
5
6
|
|
|
@@ -72,7 +73,7 @@ export const getRealPath: getRealPathType = (path, type = 'video') => {
|
|
|
72
73
|
};
|
|
73
74
|
|
|
74
75
|
export const getVideoMetaData: getVideoMetaDataType = (path: string) => {
|
|
75
|
-
return Compressor.getVideoMetaData(path)
|
|
76
|
+
return Compressor.getVideoMetaData(path) as ReturnType<getVideoMetaDataType>;
|
|
76
77
|
};
|
|
77
78
|
|
|
78
79
|
const unifyMetaData = (exifResult: any) => {
|
|
@@ -96,7 +97,7 @@ export const getImageMetaData: getImageMetaDataType = async (path: string) => {
|
|
|
96
97
|
};
|
|
97
98
|
|
|
98
99
|
export const createVideoThumbnail: createVideoThumbnailType = (fileUrl, options = {}) => {
|
|
99
|
-
return Compressor.createVideoThumbnail(fileUrl, options);
|
|
100
|
+
return Compressor.createVideoThumbnail(fileUrl, toNativeOptions(options));
|
|
100
101
|
};
|
|
101
102
|
|
|
102
103
|
export const clearCache: clearCacheType = (cacheDir?: string) => {
|