UNPKG

react-native-test-app

Version:

react-native-test-app provides a test app for all supported platforms as a package

191 lines (175 loc) 5 kB
// @ts-check import { isMain } from "../helpers.js"; import { main, warn } from "./main.mjs"; const INDENT = " "; /** * @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<std::any>{}"; } 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<std::any>{\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<std::vector<Component>>({})"; } const outerIndent = INDENT.repeat(level + 1); const innerIndent = INDENT.repeat(level + 2); const lines = ["std::make_optional<std::vector<Component>>({"]; 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<string, unknown>} json * @param {string} checksum * @returns {string} */ export function generate(json, checksum) { return [ "// clang-format off", '#include "Manifest.h"', "", "#include <cstdint>", "", "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"); } if (isMain(import.meta.url)) { process.exitCode = main(generate); }