@appzung/react-native-code-push 6.4.2 → 8.3.2

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 (91) hide show
  1. package/.azurepipelines/build-rn-code-push-1es.yml +104 -0
  2. package/.azurepipelines/test-rn-code-push.yml +94 -0
  3. package/.config/CredScanSuppressions.json +14 -0
  4. package/CONTRIBUTING.md +3 -3
  5. package/CodePush.js +26 -28
  6. package/CodePush.podspec +1 -1
  7. package/README.md +8 -7
  8. package/SECURITY.md +41 -0
  9. package/android/app/build.gradle +1 -1
  10. package/android/app/src/main/AndroidManifest.xml +1 -5
  11. package/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +14 -5
  12. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushConstants.java +1 -0
  13. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +19 -1
  14. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +5 -4
  15. package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUtils.java +3 -1
  16. package/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java +8 -9
  17. package/android/build.gradle +3 -2
  18. package/android/codepush.gradle +79 -30
  19. package/docs/api-js.md +1 -1
  20. package/docs/setup-android.md +27 -3
  21. package/docs/setup-ios.md +1 -1
  22. package/docs/setup-windows.md +59 -3
  23. package/ios/CodePush/CodePushPackage.m +4 -0
  24. package/ios/CodePush/CodePushUpdateUtils.m +1 -1
  25. package/ios/CodePush.xcodeproj/project.pbxproj +2 -2
  26. package/package.json +11 -11
  27. package/typings/react-native-code-push.d.ts +1 -1
  28. package/windows/CodePush/CodePush.def +3 -0
  29. package/windows/CodePush/CodePush.vcxproj +198 -0
  30. package/windows/CodePush/CodePush.vcxproj.filters +91 -0
  31. package/windows/CodePush/CodePushConfig.cpp +104 -0
  32. package/windows/CodePush/CodePushConfig.h +66 -0
  33. package/windows/CodePush/CodePushConfig.idl +12 -0
  34. package/windows/CodePush/CodePushDownloadHandler.cpp +73 -0
  35. package/windows/CodePush/CodePushDownloadHandler.h +32 -0
  36. package/windows/CodePush/CodePushNativeModule.cpp +934 -0
  37. package/windows/CodePush/CodePushNativeModule.h +247 -0
  38. package/windows/CodePush/CodePushPackage.cpp +456 -0
  39. package/windows/CodePush/CodePushPackage.h +49 -0
  40. package/windows/CodePush/CodePushTelemetryManager.cpp +213 -0
  41. package/windows/CodePush/CodePushTelemetryManager.h +29 -0
  42. package/windows/CodePush/CodePushUpdateUtils.cpp +86 -0
  43. package/windows/CodePush/CodePushUpdateUtils.h +38 -0
  44. package/windows/CodePush/CodePushUtils.cpp +29 -0
  45. package/windows/CodePush/CodePushUtils.h +18 -0
  46. package/windows/CodePush/FileUtils.cpp +131 -0
  47. package/windows/CodePush/FileUtils.h +28 -0
  48. package/windows/CodePush/PropertySheet.props +16 -0
  49. package/windows/CodePush/ReactPackageProvider.cpp +15 -0
  50. package/windows/CodePush/ReactPackageProvider.h +22 -0
  51. package/windows/CodePush/ReactPackageProvider.idl +9 -0
  52. package/windows/CodePush/miniz/LICENSE +22 -0
  53. package/windows/CodePush/miniz/miniz.c +7657 -0
  54. package/windows/CodePush/miniz/miniz.h +1338 -0
  55. package/windows/CodePush/miniz/readme.md +37 -0
  56. package/windows/CodePush/packages.config +4 -0
  57. package/windows/CodePush/pch.cpp +1 -0
  58. package/windows/CodePush/pch.h +4 -0
  59. package/{windows → windows-legacy}/CodePush/CodePush.csproj +1 -1
  60. package/{windows → windows-legacy}/CodePush.Net46/CodePush.Net46.csproj +2 -2
  61. package/{windows → windows-legacy}/CodePush.Net46/packages.config +1 -1
  62. package/windows-legacy/CodePush.Net46.Test/ApplicationDataContainerTest.cs +105 -0
  63. package/windows-legacy/CodePush.Net46.Test/CodePush.Net46.Test.csproj +137 -0
  64. package/windows-legacy/CodePush.Net46.Test/Properties/AssemblyInfo.cs +36 -0
  65. package/windows-legacy/CodePush.Net46.Test/TelemetryManagerTest.cs +117 -0
  66. package/windows-legacy/CodePush.Net46.Test/app.config +11 -0
  67. package/windows-legacy/CodePush.Net46.Test/packages.config +4 -0
  68. /package/{windows → windows-legacy}/CodePush/CodePushUtils.cs +0 -0
  69. /package/{windows → windows-legacy}/CodePush/FileUtils.cs +0 -0
  70. /package/{windows → windows-legacy}/CodePush/Properties/AssemblyInfo.cs +0 -0
  71. /package/{windows → windows-legacy}/CodePush/Properties/CodePush.rd.xml +0 -0
  72. /package/{windows → windows-legacy}/CodePush/UpdateManager.cs +0 -0
  73. /package/{windows → windows-legacy}/CodePush/UpdateUtils.cs +0 -0
  74. /package/{windows → windows-legacy}/CodePush.Net46/Adapters/Http/HttpProgress.cs +0 -0
  75. /package/{windows → windows-legacy}/CodePush.Net46/Adapters/Storage/ApplicationDataContainer.cs +0 -0
  76. /package/{windows → windows-legacy}/CodePush.Net46/CodePushUtils.cs +0 -0
  77. /package/{windows → windows-legacy}/CodePush.Net46/FileUtils.cs +0 -0
  78. /package/{windows → windows-legacy}/CodePush.Net46/Properties/AssemblyInfo.cs +0 -0
  79. /package/{windows → windows-legacy}/CodePush.Net46/UpdateManager.cs +0 -0
  80. /package/{windows → windows-legacy}/CodePush.Net46/UpdateUtils.cs +0 -0
  81. /package/{windows → windows-legacy}/CodePush.Shared/CodePush.Shared.projitems +0 -0
  82. /package/{windows → windows-legacy}/CodePush.Shared/CodePush.Shared.shproj +0 -0
  83. /package/{windows → windows-legacy}/CodePush.Shared/CodePushConstants.cs +0 -0
  84. /package/{windows → windows-legacy}/CodePush.Shared/CodePushNativeModule.cs +0 -0
  85. /package/{windows → windows-legacy}/CodePush.Shared/CodePushReactPackage.cs +0 -0
  86. /package/{windows → windows-legacy}/CodePush.Shared/CodePushUtils.cs +0 -0
  87. /package/{windows → windows-legacy}/CodePush.Shared/InstallMode.cs +0 -0
  88. /package/{windows → windows-legacy}/CodePush.Shared/MinimumBackgroundListener.cs +0 -0
  89. /package/{windows → windows-legacy}/CodePush.Shared/SettingsManager.cs +0 -0
  90. /package/{windows → windows-legacy}/CodePush.Shared/TelemetryManager.cs +0 -0
  91. /package/{windows → windows-legacy}/CodePush.Shared/UpdateState.cs +0 -0
@@ -0,0 +1,213 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "pch.h"
5
+
6
+ #include "CodePushTelemetryManager.h"
7
+ #include "CodePushNativeModule.h"
8
+
9
+ #include "winrt/Windows.Storage.h"
10
+ #include "winrt/Windows.Data.Json.h"
11
+ #include <string_view>
12
+
13
+ namespace Microsoft::CodePush::ReactNative
14
+ {
15
+ using namespace winrt;
16
+ using namespace Windows::Data::Json;
17
+ using namespace Windows::Storage;
18
+
19
+ static const std::wstring_view AppVersionKey{ L"appVersion" };
20
+ static const std::wstring_view DeploymentFailed{ L"DeploymentFailed" };
21
+ static const std::wstring_view DeploymentKeyKey{ L"deploymentKey" };
22
+ static const std::wstring_view DeploymentSucceeded{ L"DeploymentSucceeded" };
23
+ static const std::wstring_view LabelKey{ L"label" };
24
+ static const std::wstring_view LastDeploymentReportKey{ L"CODE_PUSH_LAST_DEPLOYMENT_REPORT" };
25
+ static const std::wstring_view PackageKey{ L"package" };
26
+ static const std::wstring_view PreviousDeploymentKeyKey{ L"previousDeploymentKey" };
27
+ static const std::wstring_view PreviousLabelOrAppVersionKey{ L"previousLabelOrAppVersion" };
28
+ static const std::wstring_view RetryDeploymentReportKey{ L"CODE_PUSH_RETRY_DEPLOYMENT_REPORT" };
29
+ static const std::wstring_view StatusKey{ L"status" };
30
+
31
+ /*static*/ JsonObject CodePushTelemetryManager::GetBinaryUpdateReport(std::wstring_view appVersion)
32
+ {
33
+ auto previousStatusReportIdentifier{ GetPreviousStatusReportIdentifier() };
34
+ if (previousStatusReportIdentifier.empty())
35
+ {
36
+ ClearRetryStatusReport();
37
+ JsonObject out;
38
+ out.Insert(AppVersionKey, JsonValue::CreateStringValue(appVersion));
39
+ return out;
40
+ }
41
+ else if (previousStatusReportIdentifier != appVersion)
42
+ {
43
+ if (IsStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier))
44
+ {
45
+ auto previousDeploymentKey{ GetDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier) };
46
+ auto previousLabel{ GetVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier) };
47
+ ClearRetryStatusReport();
48
+ JsonObject out;
49
+ out.Insert(AppVersionKey, JsonValue::CreateStringValue(appVersion));
50
+ out.Insert(PreviousDeploymentKeyKey, JsonValue::CreateStringValue(previousDeploymentKey));
51
+ out.Insert(PreviousLabelOrAppVersionKey, JsonValue::CreateStringValue(previousLabel));
52
+ return out;
53
+ }
54
+ else
55
+ {
56
+ ClearRetryStatusReport();
57
+ // Previous status report was with a binary app version.
58
+ JsonObject out;
59
+ out.Insert(AppVersionKey, JsonValue::CreateStringValue(appVersion));
60
+ out.Insert(PreviousLabelOrAppVersionKey, JsonValue::CreateStringValue(previousStatusReportIdentifier));
61
+ return out;
62
+ }
63
+ }
64
+
65
+ return nullptr;
66
+ }
67
+
68
+ /*static*/ JsonObject CodePushTelemetryManager::GetRetryStatusReport()
69
+ {
70
+ auto localSettings{ CodePushNativeModule::GetLocalSettings() };
71
+ auto retryStatusReportData{ localSettings.Values().TryLookup(RetryDeploymentReportKey) };
72
+ if (retryStatusReportData != nullptr)
73
+ {
74
+ auto retryStatusReportString{ unbox_value<hstring>(retryStatusReportData) };
75
+ JsonObject retryStatusReport;
76
+ auto success{ JsonObject::TryParse(retryStatusReportString, retryStatusReport) };
77
+ if (success)
78
+ {
79
+ return retryStatusReport;
80
+ }
81
+ }
82
+ return nullptr;
83
+ }
84
+
85
+ /*static*/ JsonObject CodePushTelemetryManager::GetRollbackReport(const JsonObject& lastFailedPackage)
86
+ {
87
+ JsonObject out;
88
+ out.Insert(PackageKey, lastFailedPackage);
89
+ out.Insert(StatusKey, JsonValue::CreateStringValue(DeploymentFailed));
90
+ return out;
91
+ }
92
+
93
+ /*static*/ JsonObject CodePushTelemetryManager::GetUpdateReport(const JsonObject& currentPackage)
94
+ {
95
+ auto currentPackageIdentifier{ GetPackageStatusReportIdentifier(currentPackage) };
96
+ auto previousStatusReportIdentifier{ GetPreviousStatusReportIdentifier() };
97
+ if (currentPackageIdentifier.empty())
98
+ {
99
+ if (!previousStatusReportIdentifier.empty())
100
+ {
101
+ ClearRetryStatusReport();
102
+ JsonObject out;
103
+ out.Insert(PackageKey, currentPackage);
104
+ out.Insert(StatusKey, JsonValue::CreateStringValue(DeploymentSucceeded));
105
+ return out;
106
+ }
107
+ else if (previousStatusReportIdentifier != currentPackageIdentifier)
108
+ {
109
+ ClearRetryStatusReport();
110
+ if (IsStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier))
111
+ {
112
+ auto previousDeploymentKey{ GetDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier) };
113
+ auto previousLabel{ GetVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier) };
114
+ JsonObject out;
115
+ out.Insert(PackageKey, currentPackage);
116
+ out.Insert(StatusKey, JsonValue::CreateStringValue(DeploymentSucceeded));
117
+ out.Insert(PreviousDeploymentKeyKey, JsonValue::CreateStringValue(previousDeploymentKey));
118
+ out.Insert(PreviousLabelOrAppVersionKey, JsonValue::CreateStringValue(previousLabel));
119
+ return out;
120
+ }
121
+ else
122
+ {
123
+ // Previous status report was with a binary app version.
124
+ JsonObject out;
125
+ out.Insert(PackageKey, currentPackage);
126
+ out.Insert(StatusKey, JsonValue::CreateStringValue(DeploymentSucceeded));
127
+ out.Insert(PreviousLabelOrAppVersionKey, JsonValue::CreateStringValue(previousStatusReportIdentifier));
128
+ return out;
129
+ }
130
+ }
131
+ }
132
+
133
+ return nullptr;
134
+ }
135
+
136
+ /*static*/ void CodePushTelemetryManager::RecordStatusReported(const JsonObject& statusReport)
137
+ {
138
+ // We don't need to record rollback reports, so exit early if that's what was specified.
139
+ auto status{ statusReport.TryLookup(StatusKey) };
140
+ if (status != nullptr && status.ValueType() == JsonValueType::String && status.GetString() == DeploymentFailed)
141
+ {
142
+ return;
143
+ }
144
+
145
+ if (statusReport.HasKey(AppVersionKey))
146
+ {
147
+ SaveStatusReportedForIdentifier(statusReport.GetNamedString(AppVersionKey));
148
+ }
149
+ else if (statusReport.HasKey(PackageKey))
150
+ {
151
+ auto packageIdentifier{ GetPackageStatusReportIdentifier(statusReport.GetNamedObject(PackageKey)) };
152
+ SaveStatusReportedForIdentifier(packageIdentifier);
153
+ }
154
+ }
155
+
156
+ /*static*/ void CodePushTelemetryManager::SaveStatusReportForRetry(const JsonObject& statusReport)
157
+ {
158
+ auto localSettings{ CodePushNativeModule::GetLocalSettings() };
159
+ localSettings.Values().Insert(RetryDeploymentReportKey, box_value(statusReport.Stringify()));
160
+ }
161
+
162
+ /*static*/ void CodePushTelemetryManager::ClearRetryStatusReport()
163
+ {
164
+ auto localSettings{ CodePushNativeModule::GetLocalSettings() };
165
+ localSettings.Values().Remove(RetryDeploymentReportKey);
166
+ }
167
+
168
+ /*static*/ std::wstring_view CodePushTelemetryManager::GetDeploymentKeyFromStatusReportIdentifier(std::wstring_view statusReportIdentifier)
169
+ {
170
+ return statusReportIdentifier.substr(0, statusReportIdentifier.find(':'));
171
+ }
172
+
173
+ /*static*/ hstring CodePushTelemetryManager::GetPackageStatusReportIdentifier(const JsonObject& package)
174
+ {
175
+ // Because deploymentKeys can be dynamically switched, we use a
176
+ // combination of the deploymentKey and label as the packageIdentifier.
177
+ if (package.HasKey(DeploymentKeyKey) && package.HasKey(LabelKey))
178
+ {
179
+ return L"";
180
+ }
181
+ auto deploymentKey{ package.GetNamedString(DeploymentKeyKey) };
182
+ auto label{ package.GetNamedString(LabelKey) };
183
+ return deploymentKey + L":" + label;
184
+ }
185
+
186
+ /*static*/ hstring CodePushTelemetryManager::GetPreviousStatusReportIdentifier()
187
+ {
188
+ auto localSettings{ CodePushNativeModule::GetLocalSettings() };
189
+ auto sentStatusReportIdentifierData{ localSettings.Values().TryLookup(LastDeploymentReportKey) };
190
+ if (sentStatusReportIdentifierData != nullptr)
191
+ {
192
+ auto sentStatusReportIdentifier{ unbox_value<hstring>(sentStatusReportIdentifierData) };
193
+ return sentStatusReportIdentifier;
194
+ }
195
+ return L"";
196
+ }
197
+
198
+ /*static*/ std::wstring_view CodePushTelemetryManager::GetVersionLabelFromStatusReportIdentifier(std::wstring_view statusReportIdentifier)
199
+ {
200
+ return statusReportIdentifier.substr(statusReportIdentifier.rfind(':') + 1);
201
+ }
202
+
203
+ /*static*/ bool CodePushTelemetryManager::IsStatusReportIdentifierCodePushLabel(std::wstring_view statusReportIdentifier)
204
+ {
205
+ return !statusReportIdentifier.empty() && statusReportIdentifier.find(':') != std::wstring_view::npos;
206
+ }
207
+
208
+ /*static*/ void CodePushTelemetryManager::SaveStatusReportedForIdentifier(std::wstring_view appVersionOrPackageIdentifier)
209
+ {
210
+ auto localSettings{ CodePushNativeModule::GetLocalSettings() };
211
+ localSettings.Values().Insert(LastDeploymentReportKey, box_value(appVersionOrPackageIdentifier));
212
+ }
213
+ }
@@ -0,0 +1,29 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include "winrt/Windows.Data.Json.h"
7
+ #include <string_view>
8
+
9
+ namespace Microsoft::CodePush::ReactNative
10
+ {
11
+ struct CodePushTelemetryManager
12
+ {
13
+ static winrt::Windows::Data::Json::JsonObject GetBinaryUpdateReport(std::wstring_view appVersion);
14
+ static winrt::Windows::Data::Json::JsonObject GetRetryStatusReport();
15
+ static winrt::Windows::Data::Json::JsonObject GetRollbackReport(const winrt::Windows::Data::Json::JsonObject& lastFailedPackage);
16
+ static winrt::Windows::Data::Json::JsonObject GetUpdateReport(const winrt::Windows::Data::Json::JsonObject& currentPackage);
17
+ static void RecordStatusReported(const winrt::Windows::Data::Json::JsonObject& statusReport);
18
+ static void SaveStatusReportForRetry(const winrt::Windows::Data::Json::JsonObject& statusReport);
19
+
20
+ private:
21
+ static void ClearRetryStatusReport();
22
+ static std::wstring_view GetDeploymentKeyFromStatusReportIdentifier(std::wstring_view statusReportIdentifier);
23
+ static winrt::hstring GetPackageStatusReportIdentifier(const winrt::Windows::Data::Json::JsonObject& package);
24
+ static winrt::hstring GetPreviousStatusReportIdentifier();
25
+ static std::wstring_view GetVersionLabelFromStatusReportIdentifier(std::wstring_view statusReportIdentifier);
26
+ static bool IsStatusReportIdentifierCodePushLabel(std::wstring_view statusReportIdentifier);
27
+ static void SaveStatusReportedForIdentifier(std::wstring_view appVersionOrPackageIdentifier);
28
+ };
29
+ }
@@ -0,0 +1,86 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "pch.h"
5
+
6
+ #include "winrt/Windows.ApplicationModel.h"
7
+ #include "winrt/Windows.Foundation.h"
8
+ #include "winrt/Windows.Foundation.Collections.h"
9
+ #include "winrt/Windows.Security.Cryptography.h"
10
+ #include "winrt/Windows.Security.Cryptography.Core.h"
11
+ #include "winrt/Windows.Storage.h"
12
+ #include "winrt/Windows.Storage.FileProperties.h"
13
+ #include "winrt/Windows.Storage.Streams.h"
14
+
15
+ #include <algorithm>
16
+ #include <string_view>
17
+ #include <vector>
18
+
19
+ #include "CodePushUpdateUtils.h"
20
+ #include "CodePushUtils.h"
21
+ #include "CodePushNativeModule.h"
22
+
23
+ namespace Microsoft::CodePush::ReactNative
24
+ {
25
+ using namespace winrt;
26
+ using namespace Windows::Foundation;
27
+ using namespace Windows::Foundation::Collections;
28
+ using namespace Windows::Storage;
29
+ using namespace Windows::Security::Cryptography;
30
+ using namespace Windows::Security::Cryptography::Core;
31
+
32
+ /*static*/ IAsyncOperation<bool> CodePushUpdateUtils::CopyEntriesInFolderAsync(StorageFolder& sourceFolder, StorageFolder& destFolder)
33
+ {
34
+ auto entries{ co_await sourceFolder.GetItemsAsync() };
35
+ for (const auto& entry : entries)
36
+ {
37
+ if (entry.IsOfType(StorageItemTypes::File))
38
+ {
39
+ auto file{ entry.try_as<StorageFile>() };
40
+ co_await file.CopyAsync(destFolder, file.Name(), NameCollisionOption::ReplaceExisting);
41
+ }
42
+ else if (entry.IsOfType(StorageItemTypes::Folder))
43
+ {
44
+ auto folder{ entry.try_as<StorageFolder>() };
45
+ auto folderCopy{ co_await destFolder.CreateFolderAsync(folder.Name(), CreationCollisionOption::ReplaceExisting) };
46
+ auto result{ co_await CopyEntriesInFolderAsync(folder, folderCopy) };
47
+ if (!result)
48
+ {
49
+ co_return false;
50
+ }
51
+ }
52
+ }
53
+
54
+ co_return true;
55
+ }
56
+
57
+ /*static*/ IAsyncOperation<StorageFile> CodePushUpdateUtils::GetSignatureFileAsync(const StorageFolder& rootFolder)
58
+ {
59
+ auto manifestFolder{ (co_await rootFolder.TryGetItemAsync(ManifestFolderPrefix)).try_as<StorageFolder>() };
60
+ if (manifestFolder != nullptr)
61
+ {
62
+ auto bundleJWTFile{ (co_await rootFolder.TryGetItemAsync(BundleJWTFile)).try_as<StorageFile>() };
63
+ if (bundleJWTFile != nullptr)
64
+ {
65
+ co_return bundleJWTFile;
66
+ }
67
+ }
68
+ co_return nullptr;
69
+ }
70
+
71
+ /*static*/ IAsyncOperation<hstring> CodePushUpdateUtils::ModifiedDateStringOfFileAsync(const StorageFile& file)
72
+ {
73
+ if (file != nullptr)
74
+ {
75
+ auto basicProperties{ co_await file.GetBasicPropertiesAsync() };
76
+ auto modifiedDate{ basicProperties.DateModified() };
77
+ auto mtime{ clock::to_time_t(modifiedDate) };
78
+ auto modifiedDateString{ to_hstring(mtime) };
79
+ co_return modifiedDateString;
80
+ }
81
+ else
82
+ {
83
+ co_return L"";
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,38 @@
1
+ #pragma once
2
+
3
+ #include "winrt/Windows.Data.Json.h"
4
+ #include "winrt/Windows.Foundation.h"
5
+ #include "winrt/Windows.Storage.h"
6
+
7
+ // Copyright (c) Microsoft Corporation.
8
+ // Licensed under the MIT License.
9
+
10
+ #include <string_view>
11
+
12
+ namespace Microsoft::CodePush::ReactNative
13
+ {
14
+ struct CodePushUpdateUtils
15
+ {
16
+ static constexpr std::wstring_view AssetsFolderName{ L"assets" };
17
+ static constexpr std::wstring_view BinaryHashKey{ L"CodePushBinaryHash" };
18
+ static constexpr std::wstring_view ManifestFolderPrefix{ L"CodePush" };
19
+ static constexpr std::wstring_view BundleJWTFile{ L".codepushrelease" };
20
+
21
+ static winrt::Windows::Foundation::IAsyncOperation<bool> CopyEntriesInFolderAsync(
22
+ winrt::Windows::Storage::StorageFolder& sourceFolder,
23
+ winrt::Windows::Storage::StorageFolder& destFolder);
24
+
25
+ static winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> ModifiedDateStringOfFileAsync(const winrt::Windows::Storage::StorageFile& file);
26
+
27
+ static winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> GetSignatureFileAsync(
28
+ const winrt::Windows::Storage::StorageFolder& rootFolder);
29
+
30
+ private:
31
+ /*
32
+ Ignore list for hashing
33
+ */
34
+ static constexpr std::wstring_view IgnoreMacOSX{ L"__MACOSX/" };
35
+ static constexpr std::wstring_view IgnoreDSStore{ L".DS_Store" };
36
+ static constexpr std::wstring_view IgnoreCodePushMetadata{ L".codepushrelease" };
37
+ };
38
+ }
@@ -0,0 +1,29 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "pch.h"
5
+ #include "CodePushUtils.h"
6
+
7
+ namespace Microsoft::CodePush::ReactNative
8
+ {
9
+ using namespace winrt::Windows::Storage;
10
+
11
+ /*static*/ void CodePushUtils::Log(winrt::hstring message)
12
+ {
13
+ OutputDebugStringW(L"[CodePush] ");
14
+ OutputDebugStringW(message.c_str());
15
+ OutputDebugStringW(L"\n");
16
+ }
17
+
18
+ /*static*/ void CodePushUtils::Log(const winrt::hresult_error& ex)
19
+ {
20
+ OutputDebugStringW(L"[CodePush] Exception ");
21
+ OutputDebugStringW(ex.message().c_str());
22
+ OutputDebugStringW(L"\n");
23
+ }
24
+
25
+ /*static*/ void CodePushUtils::LogBundleUrl(const IStorageFile& bundle)
26
+ {
27
+ CodePushUtils::Log(L"Loading JS bundle from \"" + bundle.Path() + L"\"");
28
+ }
29
+ }
@@ -0,0 +1,18 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include "winrt/base.h"
7
+ #include "winrt/Windows.Storage.h"
8
+ #include <exception>
9
+
10
+ namespace Microsoft::CodePush::ReactNative
11
+ {
12
+ struct CodePushUtils
13
+ {
14
+ static void Log(winrt::hstring message);
15
+ static void Log(const winrt::hresult_error& ex);
16
+ static void LogBundleUrl(const winrt::Windows::Storage::IStorageFile& bundle);
17
+ };
18
+ }
@@ -0,0 +1,131 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "pch.h"
5
+
6
+ #include "miniz/miniz.h"
7
+ #include "winrt/Windows.Foundation.h"
8
+ #include "winrt/Windows.Storage.h"
9
+ #include "winrt/Windows.Storage.Search.h"
10
+ #include "winrt/Windows.Storage.Streams.h"
11
+
12
+ #include <string_view>
13
+ #include <stack>
14
+
15
+ #include "CodePushNativeModule.h"
16
+ #include "FileUtils.h"
17
+
18
+ namespace Microsoft::CodePush::ReactNative
19
+ {
20
+ using namespace winrt;
21
+ using namespace Windows::Foundation;
22
+ using namespace Windows::Storage;
23
+ using namespace Windows::Storage::Search;
24
+ using namespace Windows::Storage::Streams;
25
+
26
+ /*static*/ IAsyncOperation<StorageFile> FileUtils::CreateFileFromPathAsync(StorageFolder rootFolder, const std::filesystem::path& relativePath)
27
+ {
28
+ auto relPath{ relativePath };
29
+
30
+ std::stack<std::string> pathParts;
31
+ pathParts.push(relPath.filename().string());
32
+ while (relPath.has_parent_path())
33
+ {
34
+ relPath = relPath.parent_path();
35
+ pathParts.push(relPath.filename().string());
36
+ }
37
+
38
+ while (pathParts.size() > 1)
39
+ {
40
+ auto itemName{ pathParts.top() };
41
+ rootFolder = co_await rootFolder.CreateFolderAsync(to_hstring(itemName), CreationCollisionOption::OpenIfExists);
42
+ pathParts.pop();
43
+ }
44
+ auto fileName{ pathParts.top() };
45
+ auto file{ co_await rootFolder.CreateFileAsync(to_hstring(fileName), CreationCollisionOption::ReplaceExisting) };
46
+ co_return file;
47
+ }
48
+
49
+ /*static*/ IAsyncOperation<hstring> FileUtils::FindFilePathAsync(const StorageFolder& rootFolder, std::wstring_view fileName)
50
+ {
51
+ try
52
+ {
53
+ std::vector<hstring> fileTypeFilter{};
54
+ fileTypeFilter.push_back(L".bundle");
55
+ QueryOptions queryOptions{ CommonFileQuery::OrderByName, fileTypeFilter };
56
+ queryOptions.IndexerOption(IndexerOption::DoNotUseIndexer);
57
+ queryOptions.ApplicationSearchFilter(L"System.FileName: " + fileName);
58
+ auto queryResult{ rootFolder.CreateFileQueryWithOptions(queryOptions) };
59
+ auto files{ co_await queryResult.GetFilesAsync() };
60
+
61
+ if (files.Size() > 0)
62
+ {
63
+ auto result{ files.GetAt(0) };
64
+ std::wstring_view bundlePath{ result.Path() };
65
+ hstring filePathSub{ bundlePath.substr(rootFolder.Path().size() + 1) };
66
+ co_return filePathSub;
67
+ }
68
+
69
+ co_return L"";
70
+ }
71
+ catch (...)
72
+ {
73
+ throw;
74
+ }
75
+ }
76
+
77
+ /*static*/ IAsyncAction FileUtils::UnzipAsync(const StorageFile& zipFile, const StorageFolder& destination)
78
+ {
79
+ std::string zipName{ to_string(zipFile.Path()) };
80
+
81
+ mz_bool status;
82
+ mz_zip_archive zip_archive;
83
+ mz_zip_zero_struct(&zip_archive);
84
+
85
+ status = mz_zip_reader_init_file(&zip_archive, zipName.c_str(), 0);
86
+ assert(status);
87
+ auto numFiles{ mz_zip_reader_get_num_files(&zip_archive) };
88
+
89
+ for (mz_uint i = 0; i < numFiles; i++)
90
+ {
91
+ mz_zip_archive_file_stat file_stat;
92
+ status = mz_zip_reader_file_stat(&zip_archive, i, &file_stat);
93
+ assert(status);
94
+ if (!mz_zip_reader_is_file_a_directory(&zip_archive, i))
95
+ {
96
+ auto fileName{ file_stat.m_filename };
97
+ auto filePath{ std::filesystem::path(fileName) };
98
+ auto filePathName{ filePath.filename() };
99
+ auto filePathNameString{ filePathName.string() };
100
+
101
+ auto entryFile{ co_await CreateFileFromPathAsync(destination, filePath) };
102
+
103
+ auto stream{ co_await entryFile.OpenAsync(FileAccessMode::ReadWrite) };
104
+ auto os{ stream.GetOutputStreamAt(0) };
105
+ DataWriter dw{ os };
106
+
107
+ const auto arrBufSize = 8 * 1024;
108
+ std::array<uint8_t, arrBufSize> arrBuf;
109
+
110
+ mz_zip_reader_extract_iter_state* pState = mz_zip_reader_extract_iter_new(&zip_archive, i, 0);
111
+ while (size_t bytesRead{ mz_zip_reader_extract_iter_read(pState, static_cast<void*>(arrBuf.data()), arrBuf.size()) })
112
+ {
113
+ array_view<const uint8_t> view{ arrBuf.data(), arrBuf.data() + bytesRead };
114
+ dw.WriteBytes(view);
115
+ }
116
+ status = mz_zip_reader_extract_iter_free(pState);
117
+ assert(status);
118
+
119
+ co_await dw.StoreAsync();
120
+ co_await dw.FlushAsync();
121
+
122
+ dw.Close();
123
+ os.Close();
124
+ stream.Close();
125
+ }
126
+ }
127
+
128
+ status = mz_zip_reader_end(&zip_archive);
129
+ assert(status);
130
+ }
131
+ }
@@ -0,0 +1,28 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include "winrt/Windows.Storage.h"
7
+ #include "winrt/Windows.Foundation.h"
8
+
9
+ #include <filesystem>
10
+ #include <string_view>
11
+
12
+ namespace Microsoft::CodePush::ReactNative
13
+ {
14
+ struct FileUtils
15
+ {
16
+ static winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> CreateFileFromPathAsync(
17
+ winrt::Windows::Storage::StorageFolder rootFolder,
18
+ const std::filesystem::path& relativePath);
19
+
20
+ static winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> FindFilePathAsync(
21
+ const winrt::Windows::Storage::StorageFolder& rootFolder,
22
+ std::wstring_view fileName);
23
+
24
+ static winrt::Windows::Foundation::IAsyncAction UnzipAsync(
25
+ const winrt::Windows::Storage::StorageFile& zipFile,
26
+ const winrt::Windows::Storage::StorageFolder& destination);
27
+ };
28
+ }
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
+ <ImportGroup Label="PropertySheets" />
4
+ <PropertyGroup Label="UserMacros" />
5
+ <!--
6
+ To customize common C++/WinRT project properties:
7
+ * right-click the project node
8
+ * expand the Common Properties item
9
+ * select the C++/WinRT property page
10
+
11
+ For more advanced scenarios, and complete documentation, please see:
12
+ https://github.com/Microsoft/cppwinrt/tree/master/nuget
13
+ -->
14
+ <PropertyGroup />
15
+ <ItemDefinitionGroup />
16
+ </Project>
@@ -0,0 +1,15 @@
1
+ #include "pch.h"
2
+ #include "ReactPackageProvider.h"
3
+ #include "ReactPackageProvider.g.cpp"
4
+
5
+ #include "CodePushNativeModule.h"
6
+
7
+ using namespace winrt::Microsoft::ReactNative;
8
+
9
+ namespace winrt::Microsoft::CodePush::ReactNative::implementation {
10
+
11
+ void ReactPackageProvider::CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept {
12
+ AddAttributedModules(packageBuilder);
13
+ }
14
+
15
+ } // namespace winrt::Microsoft::CodePush::ReactNative::implementation
@@ -0,0 +1,22 @@
1
+ #pragma once
2
+ #include "winrt/Microsoft.CodePush.ReactNative.h"
3
+
4
+ #include "ReactPackageProvider.g.h"
5
+
6
+ using namespace winrt::Microsoft::ReactNative;
7
+
8
+ namespace winrt::Microsoft::CodePush::ReactNative::implementation {
9
+
10
+ struct ReactPackageProvider : ReactPackageProviderT<ReactPackageProvider> {
11
+ ReactPackageProvider() = default;
12
+
13
+ void CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept;
14
+ };
15
+
16
+ } // namespace winrt::RNFS::implementation
17
+
18
+ namespace winrt::Microsoft::CodePush::ReactNative::factory_implementation {
19
+
20
+ struct ReactPackageProvider : ReactPackageProviderT<ReactPackageProvider, implementation::ReactPackageProvider> {};
21
+
22
+ } // namespace winrt::RNFS::factory_implementation
@@ -0,0 +1,9 @@
1
+ namespace Microsoft.CodePush.ReactNative
2
+ {
3
+ [webhosthidden]
4
+ [default_interface]
5
+ runtimeclass ReactPackageProvider
6
+ : Microsoft.ReactNative.IReactPackageProvider {
7
+ ReactPackageProvider();
8
+ };
9
+ } // namespace CppModule
@@ -0,0 +1,22 @@
1
+ Copyright 2013-2014 RAD Game Tools and Valve Software
2
+ Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
3
+
4
+ All Rights Reserved.
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.