@appzung/react-native-code-push 6.3.1 → 7.1.1
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/CodePush.js +10 -7
- package/CodePush.podspec +2 -2
- package/README.md +35 -21
- package/SECURITY.md +41 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +10 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java +14 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/FileUtils.java +8 -9
- package/android/app/src/main/java/com/microsoft/codepush/react/TLSSocketFactory.java +72 -0
- package/android/codepush.gradle +11 -8
- package/docs/multi-deployment-testing-android.md +1 -1
- package/docs/multi-deployment-testing-ios.md +1 -1
- package/docs/setup-android.md +7 -6
- package/docs/setup-ios.md +5 -5
- package/docs/setup-windows.md +37 -4
- package/ios/CodePush/CodePush.m +26 -11
- package/ios/CodePush/CodePushUpdateUtils.m +1 -1
- package/ios/CodePush.xcodeproj/project.pbxproj +2 -2
- package/package.json +16 -16
- package/windows/CodePush/CodePush.def +3 -0
- package/windows/CodePush/CodePush.vcxproj +199 -0
- package/windows/CodePush/CodePush.vcxproj.filters +91 -0
- package/windows/CodePush/CodePushConfig.cpp +104 -0
- package/windows/CodePush/CodePushConfig.h +66 -0
- package/windows/CodePush/CodePushConfig.idl +12 -0
- package/windows/CodePush/CodePushDownloadHandler.cpp +73 -0
- package/windows/CodePush/CodePushDownloadHandler.h +32 -0
- package/windows/CodePush/CodePushNativeModule.cpp +934 -0
- package/windows/CodePush/CodePushNativeModule.h +247 -0
- package/windows/CodePush/CodePushPackage.cpp +456 -0
- package/windows/CodePush/CodePushPackage.h +49 -0
- package/windows/CodePush/CodePushTelemetryManager.cpp +213 -0
- package/windows/CodePush/CodePushTelemetryManager.h +29 -0
- package/windows/CodePush/CodePushUpdateUtils.cpp +86 -0
- package/windows/CodePush/CodePushUpdateUtils.h +38 -0
- package/windows/CodePush/CodePushUtils.cpp +29 -0
- package/windows/CodePush/CodePushUtils.h +18 -0
- package/windows/CodePush/FileUtils.cpp +131 -0
- package/windows/CodePush/FileUtils.h +28 -0
- package/windows/CodePush/PropertySheet.props +16 -0
- package/windows/CodePush/ReactPackageProvider.cpp +15 -0
- package/windows/CodePush/ReactPackageProvider.h +22 -0
- package/windows/CodePush/ReactPackageProvider.idl +9 -0
- package/windows/CodePush/miniz/LICENSE +22 -0
- package/windows/CodePush/miniz/miniz.c +7657 -0
- package/windows/CodePush/miniz/miniz.h +1338 -0
- package/windows/CodePush/miniz/readme.md +37 -0
- package/windows/CodePush/packages.config +4 -0
- package/windows/CodePush/pch.cpp +1 -0
- package/windows/CodePush/pch.h +4 -0
- package/{windows → windows-legacy}/CodePush/CodePush.csproj +1 -1
- package/{windows → windows-legacy}/CodePush.Net46/packages.config +1 -1
- package/windows-legacy/CodePush.Net46.Test/ApplicationDataContainerTest.cs +105 -0
- package/windows-legacy/CodePush.Net46.Test/CodePush.Net46.Test.csproj +137 -0
- package/windows-legacy/CodePush.Net46.Test/Properties/AssemblyInfo.cs +36 -0
- package/windows-legacy/CodePush.Net46.Test/TelemetryManagerTest.cs +117 -0
- package/windows-legacy/CodePush.Net46.Test/app.config +11 -0
- package/windows-legacy/CodePush.Net46.Test/packages.config +4 -0
- /package/{windows → windows-legacy}/CodePush/CodePushUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush/FileUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush/Properties/AssemblyInfo.cs +0 -0
- /package/{windows → windows-legacy}/CodePush/Properties/CodePush.rd.xml +0 -0
- /package/{windows → windows-legacy}/CodePush/UpdateManager.cs +0 -0
- /package/{windows → windows-legacy}/CodePush/UpdateUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/Adapters/Http/HttpProgress.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/Adapters/Storage/ApplicationDataContainer.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/CodePush.Net46.csproj +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/CodePushUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/FileUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/Properties/AssemblyInfo.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/UpdateManager.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Net46/UpdateUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePush.Shared.projitems +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePush.Shared.shproj +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePushConstants.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePushNativeModule.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePushReactPackage.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/CodePushUtils.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/InstallMode.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/MinimumBackgroundListener.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/SettingsManager.cs +0 -0
- /package/{windows → windows-legacy}/CodePush.Shared/TelemetryManager.cs +0 -0
- /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,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.
|