From bc3579879d053096a34037d82f198d4c2f912682 Mon Sep 17 00:00:00 2001
From: Tommy Nguyen <4123478+tido64@users.noreply.github.com>
Date: Thu, 25 Apr 2024 00:54:40 +0200
Subject: [PATCH] fix(windows): embed app manifest directly in code (#1984)
---
.github/workflows/build.yml | 7 +-
.vscode/c_cpp_properties.json | 23 --
.../ReactAppTests.vcxproj} | 26 +-
.../ReactAppTests.vcxproj.filters} | 21 +-
example/windows/ReactAppTests/Tests.cpp | 18 ++
.../ReactTestAppTests/ManifestTests.cpp | 145 ----------
.../manifestTestFiles/simpleManifest.json | 10 -
.../withComplexInitialProperties.json | 22 --
.../withMultipleComponents.json | 16 --
example/windows/ReactTestAppTests/pch.cpp | 6 -
example/windows/ReactTestAppTests/pch.h | 13 -
scripts/embed-manifest/cpp.mjs | 213 ++++++++++++++
scripts/embed-manifest/main.mjs | 8 +-
scripts/generate-manifest.mjs | 22 +-
test/embed-manifest/cpp.test.mjs | 266 ++++++++++++++++++
test/embed-manifest/fixtures.mjs | 136 +++++++++
test/embed-manifest/kotlin.test.mjs | 159 +----------
test/pack.test.mjs | 4 +-
windows/Shared/EmbedManifest.targets | 11 +
windows/Shared/JSValueWriterHelper.h | 18 +-
windows/Shared/Manifest.cpp | 108 -------
windows/Shared/Manifest.h | 32 ++-
windows/Shared/Session.h | 6 +-
windows/Shared/ValidateManifest.targets | 11 -
windows/UWP/MainPage.cpp | 65 ++---
windows/UWP/MainPage.h | 7 +-
windows/UWP/ReactTestApp.vcxproj | 7 +-
windows/UWP/ReactTestApp.vcxproj.filters | 1 -
windows/UWP/packages.config | 1 -
windows/Win32/Main.cpp | 10 +-
windows/Win32/ReactApp.vcxproj | 6 +-
windows/Win32/ReactApp.vcxproj.filters | 3 -
windows/test-app.mjs | 5 -
33 files changed, 749 insertions(+), 657 deletions(-)
delete mode 100644 .vscode/c_cpp_properties.json
rename example/windows/{ReactTestAppTests/ReactTestAppTests.vcxproj => ReactAppTests/ReactAppTests.vcxproj} (83%)
rename example/windows/{ReactTestAppTests/ReactTestAppTests.vcxproj.filters => ReactAppTests/ReactAppTests.vcxproj.filters} (58%)
create mode 100644 example/windows/ReactAppTests/Tests.cpp
delete mode 100644 example/windows/ReactTestAppTests/ManifestTests.cpp
delete mode 100644 example/windows/ReactTestAppTests/manifestTestFiles/simpleManifest.json
delete mode 100644 example/windows/ReactTestAppTests/manifestTestFiles/withComplexInitialProperties.json
delete mode 100644 example/windows/ReactTestAppTests/manifestTestFiles/withMultipleComponents.json
delete mode 100644 example/windows/ReactTestAppTests/pch.cpp
delete mode 100644 example/windows/ReactTestAppTests/pch.h
create mode 100644 scripts/embed-manifest/cpp.mjs
create mode 100644 test/embed-manifest/cpp.test.mjs
create mode 100644 test/embed-manifest/fixtures.mjs
create mode 100644 windows/Shared/EmbedManifest.targets
delete mode 100644 windows/Shared/Manifest.cpp
delete mode 100644 windows/Shared/ValidateManifest.targets
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index dc1e2c7ac..2b6ed2e20 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -130,6 +130,7 @@ jobs:
- name: SwiftLint
if: ${{ matrix.platform == 'macos' }}
run: |
+ brew install swiftlint
echo "::add-matcher::.github/swiftlint.json"
swiftlint
echo "::remove-matcher owner=swiftlint::"
@@ -610,9 +611,9 @@ jobs:
- name: Test
if: ${{ steps.affected.outputs.windows != '' && matrix.platform == 'x64' }}
run: |
- ../../../scripts/MSBuild.ps1 -Configuration ${{ matrix.configuration }} -Platform ${{ matrix.platform }} -Target Build ReactTestAppTests.vcxproj
- ../../../scripts/VSTest.ps1 ${{ matrix.platform }}\${{ matrix.configuration }}\ReactTestAppTests.dll
- working-directory: example/windows/ReactTestAppTests
+ ../../../scripts/MSBuild.ps1 -Configuration ${{ matrix.configuration }} -Platform ${{ matrix.platform }} -Target Build ReactAppTests.vcxproj
+ ../../../scripts/VSTest.ps1 ${{ matrix.platform }}\${{ matrix.configuration }}\ReactAppTests.dll
+ working-directory: example/windows/ReactAppTests
timeout-minutes: 60
windows-template:
name: "Windows [template]"
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
deleted file mode 100644
index 84bb8a195..000000000
--- a/.vscode/c_cpp_properties.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "configurations": [
- {
- "name": "Win32",
- "includePath": [
- "${workspaceFolder}/example/node_modules/.generated/windows/ReactTestApp/Generated Files",
- "${workspaceFolder}/example/node_modules/react-native-windows/build/x64/Debug/Microsoft.ReactNative/Generated Files",
- "${workspaceFolder}/example/windows/packages/nlohmann.json.3.9.1/build/native/include"
- ],
- "defines": [
- "_DEBUG",
- "UNICODE",
- "_UNICODE"
- ],
- "windowsSdkVersion": "10.0.18362.0",
- "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64/cl.exe",
- "cStandard": "c11",
- "cppStandard": "c++17",
- "intelliSenseMode": "msvc-x64"
- }
- ],
- "version": 4
-}
diff --git a/example/windows/ReactTestAppTests/ReactTestAppTests.vcxproj b/example/windows/ReactAppTests/ReactAppTests.vcxproj
similarity index 83%
rename from example/windows/ReactTestAppTests/ReactTestAppTests.vcxproj
rename to example/windows/ReactAppTests/ReactAppTests.vcxproj
index 8b4ad854e..8a98c1bcc 100644
--- a/example/windows/ReactTestAppTests/ReactTestAppTests.vcxproj
+++ b/example/windows/ReactAppTests/ReactAppTests.vcxproj
@@ -4,7 +4,7 @@
16.0
{D2B221C0-0781-4D20-8BF1-D88684662A5D}
Win32Proj
- ReactTestAppTests
+ ReactAppTests
NativeUnitTestProject
@@ -67,19 +67,16 @@
- Use
Level4
true
$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)
true
- pch.h
- stdcpp17
+ stdcpp20
true
Windows
$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(ReactAppProjectDir)\$(Platform)\$(Configuration)
- %(AdditionalDependencies);Manifest.obj;pch.obj
@@ -99,24 +96,7 @@
-
- Create
-
-
-
-
-
-
-
-
- true
-
-
- true
-
-
- true
-
+
diff --git a/example/windows/ReactTestAppTests/ReactTestAppTests.vcxproj.filters b/example/windows/ReactAppTests/ReactAppTests.vcxproj.filters
similarity index 58%
rename from example/windows/ReactTestAppTests/ReactTestAppTests.vcxproj.filters
rename to example/windows/ReactAppTests/ReactAppTests.vcxproj.filters
index 5b29fb285..54b8aec73 100644
--- a/example/windows/ReactTestAppTests/ReactTestAppTests.vcxproj.filters
+++ b/example/windows/ReactAppTests/ReactAppTests.vcxproj.filters
@@ -15,27 +15,8 @@
-
+
Source Files
-
- Source Files
-
-
-
-
- Header Files
-
-
-
-
- Resource Files
-
-
- Resource Files
-
-
- Resource Files
-
diff --git a/example/windows/ReactAppTests/Tests.cpp b/example/windows/ReactAppTests/Tests.cpp
new file mode 100644
index 000000000..e27809171
--- /dev/null
+++ b/example/windows/ReactAppTests/Tests.cpp
@@ -0,0 +1,18 @@
+#include
+
+using namespace Microsoft::VisualStudio::CppUnitTestFramework;
+
+// disable clang-format because it doesn't handle macros very well
+// clang-format off
+namespace ReactApp::Tests
+{
+ TEST_CLASS(Tests)
+ {
+ public:
+ TEST_METHOD(Test)
+ {
+ Assert::IsTrue(true);
+ }
+ };
+} // namespace ReactApp::Tests
+// clang-format on
diff --git a/example/windows/ReactTestAppTests/ManifestTests.cpp b/example/windows/ReactTestAppTests/ManifestTests.cpp
deleted file mode 100644
index 5be114c9a..000000000
--- a/example/windows/ReactTestAppTests/ManifestTests.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-#include "pch.h"
-
-#include
-#include
-#include
-#include
-
-#include "Manifest.h"
-
-using namespace Microsoft::VisualStudio::CppUnitTestFramework;
-
-using ReactTestApp::Component;
-using ReactTestApp::Manifest;
-
-std::string readManifest(std::filesystem::path file)
-{
- // Current working directory when running tests (with VSTest.Console.exe)
- // changed between Visual Studio 16.8 and 16.9 and broke our pipelines. To
- // prevent future build failures, we'll use the absolute path to this
- // source file to build the path to the test fixtures.
- //
- // To ensure that `__FILE__` is a full path, we must also enable `/FC` in
- // Properties > C/C++ > Advanced.
- const auto p = std::filesystem::path(__FILE__).replace_filename("manifestTestFiles") / file;
-
- std::FILE *stream = nullptr;
- fopen_s(&stream, p.u8string().c_str(), "rb");
-
- std::string json;
- std::fseek(stream, 0, SEEK_END);
- json.resize(std::ftell(stream));
-
- std::rewind(stream);
- std::fread(json.data(), 1, json.size(), stream);
- std::fclose(stream);
-
- return json;
-}
-
-// disable clang-format because it doesn't handle macros very well
-// clang-format off
-namespace ReactTestAppTests
-{
- TEST_CLASS(ManifestTests)
- {
- public:
- TEST_METHOD(ParseManifestWithOneComponent)
- {
- auto json = readManifest("simpleManifest.json");
- auto result = ReactTestApp::GetManifest(json.c_str());
- if (!result.has_value()) {
- Assert::Fail(L"Couldn't read manifest file");
- }
-
- auto &[manifest, checksum] = result.value();
-
- Assert::AreEqual(manifest.name, {"Example"});
- Assert::AreEqual(manifest.displayName, {"Example"});
- Assert::IsTrue(manifest.components.has_value());
-
- auto &components = manifest.components.value();
- Assert::AreEqual(components[0].appKey, {"Example"});
- Assert::AreEqual(components[0].displayName.value(), {"App"});
- Assert::IsFalse(components[0].initialProperties.has_value());
- }
-
- TEST_METHOD(ParseManifestWithMultipleComponents)
- {
- auto json = readManifest("withMultipleComponents.json");
- auto result = ReactTestApp::GetManifest(json.c_str());
- if (!result.has_value()) {
- Assert::Fail(L"Couldn't read manifest file");
- }
-
- auto &[manifest, checksum] = result.value();
-
- Assert::AreEqual(manifest.name, {"Example"});
- Assert::AreEqual(manifest.displayName, {"Example"});
- Assert::IsTrue(manifest.components.has_value());
-
- auto &components = manifest.components.value();
- Assert::AreEqual(components.size(), {2});
-
- Assert::AreEqual(components[0].appKey, {"0"});
- Assert::IsFalse(components[0].displayName.has_value());
- Assert::IsTrue(components[0].initialProperties.has_value());
- Assert::AreEqual(std::any_cast(
- components[0].initialProperties.value()["key"]),
- {"value"});
-
- Assert::AreEqual(components[1].appKey, {"1"});
- Assert::AreEqual(components[1].displayName.value(), {"1"});
- Assert::IsFalse(components[1].initialProperties.has_value());
- }
-
- TEST_METHOD(ParseManifestWithComplexInitialProperties)
- {
- auto json = readManifest("withComplexInitialProperties.json");
- auto result = ReactTestApp::GetManifest(json.c_str());
- if (!result.has_value()) {
- Assert::Fail(L"Couldn't read manifest file");
- }
-
- auto &[manifest, checksum] = result.value();
-
- Assert::AreEqual(manifest.name, {"Name"});
- Assert::AreEqual(manifest.displayName, {"Display Name"});
- Assert::IsTrue(manifest.components.has_value());
-
- auto &component = manifest.components.value()[0];
- Assert::AreEqual(component.appKey, {"AppKey"});
- Assert::IsFalse(component.displayName.has_value());
- Assert::IsTrue(component.initialProperties.has_value());
-
- auto &initialProps = component.initialProperties.value();
- Assert::IsTrue(std::any_cast(initialProps["boolean"]));
- Assert::AreEqual(std::any_cast(initialProps["number"]), {9000});
- Assert::AreEqual(std::any_cast(initialProps["string"]), {"string"});
-
- auto const &array = std::any_cast>(initialProps["array"]);
- Assert::IsTrue(array[0].type() == typeid(std::nullopt));
- Assert::IsTrue(std::any_cast(array[1]));
- Assert::AreEqual(std::any_cast(array[2]), {9000});
- Assert::AreEqual(std::any_cast(array[3]), {"string"});
- Assert::IsTrue(std::any_cast>(array[4]).empty());
- Assert::IsTrue(std::any_cast>(array[5]).empty());
-
- auto object = std::any_cast>(initialProps["object"]);
- Assert::IsTrue(std::any_cast(object["boolean"]));
- Assert::AreEqual(std::any_cast(object["number"]), {9000});
- Assert::AreEqual(std::any_cast(object["string"]), {"string"});
-
- auto const &innerArray = std::any_cast>(object["array"]);
- Assert::IsTrue(innerArray[0].type() == typeid(std::nullopt));
- Assert::IsTrue(std::any_cast(innerArray[1]));
- Assert::AreEqual(std::any_cast(innerArray[2]), {9000});
- Assert::AreEqual(std::any_cast(innerArray[3]), {"string"});
- Assert::IsTrue(std::any_cast>(innerArray[4]).empty());
- Assert::IsTrue(std::any_cast>(innerArray[5]).empty());
-
- Assert::IsTrue(object["object"].type() == typeid(std::nullopt));
- }
- };
-} // namespace ReactTestAppTests
-// clang-format on
diff --git a/example/windows/ReactTestAppTests/manifestTestFiles/simpleManifest.json b/example/windows/ReactTestAppTests/manifestTestFiles/simpleManifest.json
deleted file mode 100644
index b158a73be..000000000
--- a/example/windows/ReactTestAppTests/manifestTestFiles/simpleManifest.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "Example",
- "displayName": "Example",
- "components": [
- {
- "appKey": "Example",
- "displayName": "App"
- }
- ]
-}
diff --git a/example/windows/ReactTestAppTests/manifestTestFiles/withComplexInitialProperties.json b/example/windows/ReactTestAppTests/manifestTestFiles/withComplexInitialProperties.json
deleted file mode 100644
index daa5cbc83..000000000
--- a/example/windows/ReactTestAppTests/manifestTestFiles/withComplexInitialProperties.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "name": "Name",
- "displayName": "Display Name",
- "components": [
- {
- "appKey": "AppKey",
- "initialProperties": {
- "boolean": true,
- "number": 9000,
- "string": "string",
- "array": [null, true, 9000, "string", [], {}],
- "object": {
- "boolean": true,
- "number": 9000,
- "string": "string",
- "array": [null, true, 9000, "string", [], {}],
- "object": null
- }
- }
- }
- ]
-}
diff --git a/example/windows/ReactTestAppTests/manifestTestFiles/withMultipleComponents.json b/example/windows/ReactTestAppTests/manifestTestFiles/withMultipleComponents.json
deleted file mode 100644
index 20e83bf66..000000000
--- a/example/windows/ReactTestAppTests/manifestTestFiles/withMultipleComponents.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "name": "Example",
- "displayName": "Example",
- "components": [
- {
- "appKey": "0",
- "initialProperties": {
- "key": "value"
- }
- },
- {
- "appKey": "1",
- "displayName": "1"
- }
- ]
-}
diff --git a/example/windows/ReactTestAppTests/pch.cpp b/example/windows/ReactTestAppTests/pch.cpp
deleted file mode 100644
index 6a7dfc882..000000000
--- a/example/windows/ReactTestAppTests/pch.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-// pch.cpp: source file corresponding to the pre-compiled header
-
-#include "pch.h"
-
-// When you are using pre-compiled headers, this source file is necessary for compilation to
-// succeed.
diff --git a/example/windows/ReactTestAppTests/pch.h b/example/windows/ReactTestAppTests/pch.h
deleted file mode 100644
index 75f619469..000000000
--- a/example/windows/ReactTestAppTests/pch.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// pch.h: This is a precompiled header file.
-// Files listed below are compiled only once, improving build performance for future builds.
-// This also affects IntelliSense performance, including code completion and many code browsing
-// features. However, files listed here are ALL re-compiled if any one of them is updated between
-// builds. Do not add files here that you will be updating frequently as this negates the
-// performance advantage.
-
-#ifndef PCH_H
-#define PCH_H
-
-// add headers that you want to pre-compile here
-
-#endif // PCH_H
diff --git a/scripts/embed-manifest/cpp.mjs b/scripts/embed-manifest/cpp.mjs
new file mode 100644
index 000000000..223869b34
--- /dev/null
+++ b/scripts/embed-manifest/cpp.mjs
@@ -0,0 +1,213 @@
+// @ts-check
+import * as nodefs from "node:fs";
+import * as path from "node:path";
+import { findFile, isMain } from "../helpers.js";
+import { main } from "./main.mjs";
+
+const INDENT = " ";
+
+/**
+ * @param {string} message
+ */
+export function warn(message) {
+ console.warn("app.json:", message);
+}
+
+/**
+ * @param {number} i
+ * @returns {string}
+ */
+function num(i) {
+ const value = i.toString();
+ return value.includes(".") ? value : "INT64_C(" + value + ")";
+}
+
+/**
+ * @param {unknown} s
+ * @returns {string}
+ */
+function str(s, literal = "") {
+ return typeof s === "string" ? '"' + s + `"${literal}` : "std::nullopt";
+}
+
+/**
+ * @param {unknown[]} items
+ * @param {number} level
+ * @returns {string}
+ */
+function array(items, level) {
+ if (items.length === 0) {
+ return "std::vector{}";
+ }
+
+ const innerIndent = INDENT.repeat(level + 1);
+
+ const lines = [];
+ for (const value of items) {
+ switch (typeof value) {
+ case "boolean":
+ lines.push(innerIndent + value.toString());
+ break;
+ case "number":
+ lines.push(innerIndent + num(value));
+ break;
+ case "string":
+ lines.push(innerIndent + str(value, "sv"));
+ break;
+ case "object":
+ if (Array.isArray(value)) {
+ lines.push(innerIndent + array(value, level + 1));
+ } else if (value) {
+ lines.push(innerIndent + object(value, level + 1));
+ } else {
+ lines.push(innerIndent + "nullptr");
+ }
+ break;
+ default:
+ warn(`Unexpected JSON type while parsing: ${value}`);
+ break;
+ }
+ }
+ lines.push(INDENT.repeat(level) + "}");
+ return "std::vector{\n" + lines.join(",\n");
+}
+
+/**
+ * @param {unknown} props
+ * @param {number} level
+ * @returns {string}
+ */
+function object(props, level) {
+ if (typeof props !== "object" || !props) {
+ return "std::nullopt";
+ }
+
+ const entries = Object.entries(props);
+ if (entries.length === 0) {
+ return "JSONObject{}";
+ }
+
+ const innerIndent = INDENT.repeat(level + 1);
+
+ const lines = ["JSONObject{"];
+ for (const [key, value] of entries) {
+ switch (typeof value) {
+ case "boolean":
+ lines.push(`${innerIndent}{${str(key)}, ${value}},`);
+ break;
+ case "number":
+ lines.push(`${innerIndent}{${str(key)}, ${num(value)}},`);
+ break;
+ case "string":
+ lines.push(`${innerIndent}{${str(key)}, ${str(value, "sv")}},`);
+ break;
+ case "object":
+ if (Array.isArray(value)) {
+ lines.push(
+ `${innerIndent}{`,
+ `${innerIndent}${INDENT}${str(key)},`,
+ `${innerIndent}${INDENT}${array(value, level + 2)}`,
+ `${innerIndent}},`
+ );
+ } else if (value) {
+ lines.push(
+ `${innerIndent}{`,
+ `${innerIndent}${INDENT}${str(key)},`,
+ `${innerIndent}${INDENT}${object(value, level + 2)}`,
+ `${innerIndent}},`
+ );
+ } else {
+ lines.push(`${innerIndent}{${str(key)}, nullptr},`);
+ }
+ break;
+ default:
+ warn(`Unexpected JSON type while parsing '${key}': ${value}`);
+ break;
+ }
+ }
+ lines.push(INDENT.repeat(level) + "}");
+ return lines.join("\n");
+}
+
+/**
+ * @param {unknown} components
+ * @param {number} level
+ * @returns {string}
+ */
+function components(components, level) {
+ if (!Array.isArray(components) || components.length === 0) {
+ return "std::make_optional>({})";
+ }
+
+ const outerIndent = INDENT.repeat(level + 1);
+ const innerIndent = INDENT.repeat(level + 2);
+
+ const lines = ["std::make_optional>({"];
+ for (const c of components) {
+ lines.push(outerIndent + "Component{");
+ lines.push(innerIndent + str(c.appKey) + ",");
+ lines.push(innerIndent + str(c.displayName ?? c.appKey) + ",");
+ lines.push(innerIndent + object(c.initialProperties, level + 2) + ",");
+ lines.push(innerIndent + str(c.presentationStyle) + ",");
+ lines.push(innerIndent + str(c.slug));
+ lines.push(outerIndent + "},");
+ }
+ lines.push(INDENT.repeat(level) + "})");
+ return lines.join("\n");
+}
+
+/**
+ * @param {Record} json
+ * @param {string} checksum
+ * @returns {string}
+ */
+export function generate(json, checksum, fs = nodefs) {
+ const nodeModulesPath = findFile("node_modules", process.cwd(), fs);
+ if (!nodeModulesPath) {
+ console.error(
+ "Failed to find 'node_modules' — make sure you've installed npm dependencies"
+ );
+ return "";
+ }
+
+ const code = [
+ "// clang-format off",
+ '#include "Manifest.h"',
+ "",
+ "#include ",
+ "",
+ "using ReactApp::Component;",
+ "using ReactApp::JSONObject;",
+ "using ReactApp::Manifest;",
+ "",
+ "Manifest ReactApp::GetManifest()",
+ "{",
+ " using namespace std::literals::string_view_literals;",
+ "",
+ " return Manifest{",
+ " " + str(json.name) + ",",
+ " " + str(json.displayName ?? json.name) + ",",
+ " " + str(json.version) + ",",
+ " " + str(json.bundleRoot) + ",",
+ " " + str(json.singleApp) + ",",
+ " " + components(json.components, 2),
+ " };",
+ "}",
+ "",
+ "std::string_view ReactApp::GetManifestChecksum()",
+ "{",
+ ` return "${checksum}";`,
+ "}",
+ "",
+ ].join("\n");
+
+ const dest = path.join(nodeModulesPath, ".generated", "Manifest.g.cpp");
+ fs.promises
+ .mkdir(path.dirname(dest), { recursive: true, mode: 0o755 })
+ .then(() => fs.promises.writeFile(dest, code));
+ return "app.json -> " + dest;
+}
+
+if (isMain(import.meta.url)) {
+ process.exitCode = main(generate);
+}
diff --git a/scripts/embed-manifest/main.mjs b/scripts/embed-manifest/main.mjs
index 1fbf6dbb3..df32fb510 100644
--- a/scripts/embed-manifest/main.mjs
+++ b/scripts/embed-manifest/main.mjs
@@ -5,7 +5,7 @@ import { findFile } from "../helpers.js";
import { validateManifest } from "../validate-manifest.js";
/**
- * @param {(json: Record, checksum: string) => string} generate
+ * @param {(json: Record, checksum: string, fs?: typeof nodefs) => string} generate
* @param {string} projectRoot
* @returns {number}
*/
@@ -19,7 +19,11 @@ export function main(generate, projectRoot = process.cwd(), fs = nodefs) {
const checksum = createHash("sha256")
.update(JSON.stringify(manifest))
.digest("hex");
- const provider = generate(manifest, checksum);
+ const provider = generate(manifest, checksum, fs);
+ if (!provider) {
+ return 1;
+ }
+
console.log(provider);
return 0;
}
diff --git a/scripts/generate-manifest.mjs b/scripts/generate-manifest.mjs
index c96d5e2ad..952ca649a 100755
--- a/scripts/generate-manifest.mjs
+++ b/scripts/generate-manifest.mjs
@@ -43,17 +43,22 @@ function getLanguage(output) {
"#include ",
"#include
diff --git a/windows/UWP/ReactTestApp.vcxproj.filters b/windows/UWP/ReactTestApp.vcxproj.filters
index b63201820..b35f5defb 100644
--- a/windows/UWP/ReactTestApp.vcxproj.filters
+++ b/windows/UWP/ReactTestApp.vcxproj.filters
@@ -16,7 +16,6 @@
-
diff --git a/windows/UWP/packages.config b/windows/UWP/packages.config
index 8e945056d..9973c1908 100644
--- a/windows/UWP/packages.config
+++ b/windows/UWP/packages.config
@@ -5,6 +5,5 @@
-
diff --git a/windows/Win32/Main.cpp b/windows/Win32/Main.cpp
index 247e8136c..e3f193e9b 100644
--- a/windows/Win32/Main.cpp
+++ b/windows/Win32/Main.cpp
@@ -3,7 +3,7 @@
#include "Main.h"
#include "JSValueWriterHelper.h"
-#include "Manifest.h"
+#include "Manifest.g.cpp"
#include "ReactInstance.h"
namespace winrt
@@ -55,12 +55,12 @@ namespace
rootView.Size(size);
}
- winrt::ReactViewOptions MakeReactViewOptions(ReactTestApp::Component const &component)
+ winrt::ReactViewOptions MakeReactViewOptions(ReactApp::Component const &component)
{
winrt::ReactViewOptions viewOptions;
viewOptions.ComponentName(winrt::to_hstring(component.appKey));
- auto initialProps = component.initialProperties.value_or(std::map{});
+ auto initialProps = component.initialProperties.value_or({});
initialProps["concurrentRoot"] = true;
viewOptions.InitialProps(
[initialProps = std::move(initialProps)](winrt::IJSValueWriter const &writer) {
@@ -81,9 +81,7 @@ _Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE /* instance */,
PSTR /* commandLine */,
int /* showCmd */)
{
- auto result = ::ReactTestApp::GetManifest();
- assert(result.has_value() && "Failed to parse app manifest");
- auto &[manifest, checksum] = *result;
+ auto manifest = ::ReactApp::GetManifest();
assert(manifest.components.has_value() && (*manifest.components).size() > 0 &&
"At least one component must be declared");
diff --git a/windows/Win32/ReactApp.vcxproj b/windows/Win32/ReactApp.vcxproj
index 987846793..e94db6960 100644
--- a/windows/Win32/ReactApp.vcxproj
+++ b/windows/Win32/ReactApp.vcxproj
@@ -116,7 +116,6 @@
-
@@ -138,13 +137,10 @@
-
+
-
-
-
This project references targets in your node_modules\react-native-windows folder. The missing file is {0}.
diff --git a/windows/Win32/ReactApp.vcxproj.filters b/windows/Win32/ReactApp.vcxproj.filters
index 0b1aee467..9293f02ae 100644
--- a/windows/Win32/ReactApp.vcxproj.filters
+++ b/windows/Win32/ReactApp.vcxproj.filters
@@ -47,9 +47,6 @@
Source Files
-
- Source Files
-
Source Files
diff --git a/windows/test-app.mjs b/windows/test-app.mjs
index 9d4bc27ae..aa2f63e47 100755
--- a/windows/test-app.mjs
+++ b/windows/test-app.mjs
@@ -14,7 +14,6 @@ import {
writeTextFile,
} from "../scripts/helpers.js";
import { parseArgs } from "../scripts/parseargs.mjs";
-import { validate } from "../scripts/validate-manifest.js";
import { loadReactNativeConfig, projectInfo } from "./project.mjs";
import { configureForUWP } from "./uwp.mjs";
import { configureForWin32 } from "./win32.mjs";
@@ -144,10 +143,6 @@ export function generateSolution(destPath, options, fs = nodefs) {
return "Could not find 'react-native-windows'";
}
- if (validate("file", destPath) !== 0) {
- return "App manifest validation failed!";
- }
-
const info = projectInfo(options, rnWindowsPath, destPath, fs);
const { projDir, projectFileName, projectFiles, solutionTemplatePath } =
info.useFabric